-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(hybridDropdown): add HybridSelect and HybridOption components (#704
) * feat(hybridDropdown): add HybridSelect and HybridOption components * feat(hybridDropdown): add test cases * remove Fragment * refactor function hybridselectexample * documentation: grammatical fix * feat(hybridDropDown): seperate style file
- Loading branch information
1 parent
bcce254
commit 06df37f
Showing
10 changed files
with
1,744 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,59 @@ | ||
// this components was created for hybrid dropdown demonstration purpose | ||
import React, { Component } from "react"; | ||
import styled from "styled-components"; | ||
import { | ||
Select, | ||
DropDownGroup, | ||
DropDownOption, | ||
DropDownLabel | ||
DropDownLabel, | ||
HybridSelect, | ||
HybridOption | ||
} from "../../../src/components/Input"; | ||
|
||
const HybridSelectWrapper = styled.div` | ||
position: relative; | ||
`; | ||
|
||
export default class HybridSelectExample extends Component { | ||
state = { | ||
showNativeSelect: true, | ||
selectedValue: [], | ||
isOpen: false, | ||
mouseOnDropdown: false | ||
}; | ||
|
||
// onChange function called when value of dropdown is changed | ||
onChange = value => { | ||
this.setState({ selectedValue: value }); | ||
}; | ||
|
||
// update function called when value of native select is changed | ||
updateValue = e => { | ||
this.setState({ selectedValue: [e.target.value] }); // saving value in array to match dropdown's format | ||
}; | ||
|
||
// To show native select | ||
showNativeSelect = () => { | ||
// Updating value when we know mouse left dropdown | ||
this.setState({ mouseOnDropdown: false }); | ||
if (!this.state.isOpen) { | ||
this.setState({ showNativeSelect: true }); | ||
} | ||
value: [] | ||
}; | ||
|
||
// To hide native select - called when mouse enters native select | ||
hideNativeSelect = () => { | ||
this.setState({ showNativeSelect: false, mouseOnDropdown: true }); | ||
}; | ||
|
||
// Set isOpen state to true when dropdown menu opens | ||
dropdownMenuOpen = () => { | ||
this.setState({ isOpen: true }); | ||
}; | ||
|
||
// Set isOpen state to false when dropdown menu closes | ||
dropdownMenuClose = () => { | ||
this.setState({ isOpen: false }, () => { | ||
if (!this.state.mouseOnDropdown) { | ||
this.showNativeSelect(); | ||
} | ||
}); | ||
}; | ||
onChange = value => this.setState({ value }); | ||
|
||
render() { | ||
const { showNativeSelect, selectedValue } = this.state; | ||
const { value } = this.state; | ||
return ( | ||
<HybridSelectWrapper> | ||
<DropDownLabel id="selectLabel" htmlFor="selectElement" size="large"> | ||
<> | ||
<DropDownLabel id="selectLabel" htmlFor="demoSelect" size="large"> | ||
Hybrid Select | ||
</DropDownLabel> | ||
<Select | ||
id="selectElement" | ||
size="large" | ||
hybrid | ||
fullWidth | ||
showSelect={showNativeSelect} | ||
value={selectedValue[0]} | ||
onChange={this.updateValue} | ||
onMouseEnter={this.hideNativeSelect} | ||
aria-label="Select an option" | ||
> | ||
<option value="" aria-label=""> | ||
Select an option | ||
</option> | ||
<option value="0">Option One</option> | ||
<option value="1">Option Two</option> | ||
<option value="2">Option Three</option> | ||
<option value="3">Option Four</option> | ||
<option value="4">Option Five</option> | ||
</Select> | ||
<DropDownGroup | ||
<HybridSelect | ||
size="large" | ||
placeholder="Select an option" | ||
hybrid | ||
fullWidth | ||
value={selectedValue} | ||
valueOverride={selectedValue} | ||
hideDropdown={showNativeSelect} | ||
fullWidth // for hybrid select use fullWidth true and control width using hybridWrapperProps | ||
value={value} | ||
onChange={this.onChange} | ||
dropdownMenuOpen={this.dropdownMenuOpen} | ||
dropdownMenuClose={this.dropdownMenuClose} | ||
onMouseLeave={this.showNativeSelect} | ||
aria-describedby="selectLabel" | ||
selectProps={{ id: "demoSelect" }} | ||
> | ||
<DropDownOption value="0" index={0}> | ||
<HybridOption | ||
value="0" | ||
index={0} | ||
optionText="Option One" | ||
optionProps={{ className: "classOnSelectOption" }} | ||
> | ||
Option One | ||
</DropDownOption> | ||
<DropDownOption value="1" index={1}> | ||
</HybridOption> | ||
<HybridOption | ||
value="1" | ||
index={1} | ||
dropdownOptionProps={{ className: "classOnDropdownOption" }} | ||
> | ||
Option Two | ||
</DropDownOption> | ||
<DropDownOption value="2" index={2}> | ||
Option Three | ||
</DropDownOption> | ||
<DropDownOption value="3" index={3}> | ||
</HybridOption> | ||
<HybridOption value="2" index={2} optionText="Option Three"> | ||
{/* Add prop optionText while children is not plain text */} | ||
<div>Option Three</div> | ||
</HybridOption> | ||
<HybridOption value="3" index={3}> | ||
Option Four | ||
</DropDownOption> | ||
<DropDownOption value="4" index={4}> | ||
</HybridOption> | ||
<HybridOption value="4" index={4}> | ||
Option Five | ||
</DropDownOption> | ||
</DropDownGroup> | ||
</HybridSelectWrapper> | ||
</HybridOption> | ||
</HybridSelect> | ||
</> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import styled from "styled-components"; | ||
|
||
const HybridSelectWrapper = styled.div` | ||
position: relative; | ||
`; | ||
|
||
export default HybridSelectWrapper; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React, { PureComponent } from "react"; | ||
import PropTypes from "prop-types"; | ||
import DropDownOption from "../DropDown/DropDownOption"; | ||
|
||
class HybridOption extends PureComponent { | ||
renderNativeOption = (optionText, children, props) => ( | ||
<option {...props}> {optionText || children} </option> | ||
); | ||
|
||
renderDropDownOption = (children, props) => ( | ||
<DropDownOption {...props}> {children} </DropDownOption> | ||
); | ||
|
||
render() { | ||
const { | ||
optionFor, | ||
optionText, | ||
optionProps, | ||
dropdownOptionProps, | ||
children, | ||
...props | ||
} = this.props; | ||
if (optionFor === "select") { | ||
return this.renderNativeOption(optionText, children, { | ||
...props, | ||
...optionProps | ||
}); | ||
} | ||
return this.renderDropDownOption(children, { | ||
...props, | ||
...dropdownOptionProps | ||
}); | ||
} | ||
} | ||
HybridOption.propTypes = { | ||
value: PropTypes.string.isRequired, | ||
children: PropTypes.node.isRequired, | ||
optionText: PropTypes.string, | ||
optionFor: PropTypes.string, | ||
/* eslint-disable react/forbid-prop-types */ | ||
optionProps: PropTypes.object, | ||
dropdownOptionProps: PropTypes.object | ||
/* eslint-enable react/forbid-prop-types */ | ||
}; | ||
HybridOption.defaultProps = { | ||
optionText: "", | ||
optionFor: "select", | ||
optionProps: {}, | ||
dropdownOptionProps: {} | ||
}; | ||
|
||
export default HybridOption; |
Oops, something went wrong.