MoleculeSelect
is a customized select
created from a combination of AtomInput
, MoleculeInputTags
, MoleculeDropdownList
and MoleculeDropdownOption
It allows Single and Multiple Selection
$ npm install @s-ui/react-molecule-select --save
import MoleculeSelect, {
moleculeSelectDropdownListSizes
} from '@s-ui/react-molecule-select'
import MoleculeSelectOption from '@s-ui/react-molecule-dropdown-option'
const IconCloseTag = () => <span>x</span>
const IconArrowDown = () => <span>▼</span>
const options = ['John', 'Paul', 'George', 'Ringo']
<MoleculeSelect
placeholder="Select a Country..."
onChange={(_, {value}) => console.log(value)}
iconArrowDown={<IconArrowDown />}
>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelect>
<MoleculeSelect
placeholder="Select a Country..."
onChange={(_, {value}) => console.log(value)}
iconArrowDown={<IconArrowDown />}
value="John"
>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelect>
<MoleculeSelect
placeholder="Select a Country..."
onChange={(_, {value}) => console.log(value)}
iconArrowDown={<IconArrowDown />}
size={moleculeSelectDropdownListSizes.LARGE}
>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelect>
<MoleculeSelect
placeholder="Select a Country..."
onChange={(_, {value}) => console.log(value)}
iconArrowDown={<IconArrowDown />}
hasSearch
onSearch={({value}) => console.log(value)}
searchPlaceholder="Search a country..."
noResults={
<div>
No results found...
</div>
}
size={moleculeSelectDropdownListSizes.LARGE}
>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelect>
Can be success
, error
or alert
.
<MoleculeSelect
placeholder="Select a Country..."
onChange={(_, {value}) => console.log(value)}
iconArrowDown={<IconArrowDown />}
state="success"
>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelect>
<MoleculeSelect
iconCloseTag={<IconCloseTag />}
iconArrowDown={<IconArrowDown />}
multiselection
value={['John', 'Paul']}
>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelect>
<MoleculeSelect
iconCloseTag={<IconCloseTag />}
iconArrowDown={<IconArrowDown />}
multiselection
value={['John', 'Paul']}
max={2}
>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelect>
MoleculeSelect
is a stateless component, so to manage dynamic options we need to create a wrapper component that manages this and pass proper props
and proper children (MoleculeSelectOption
) to MoleculeSelect
Example:
import React, {Component} from 'react'
import MoleculeSelect from '@s-ui/react-molecule-select'
import MoleculeSelectOption from '@s-ui/react-molecule-dropdown-option'
const options = ['John', 'Paul', 'George', 'Ringo']
export default class SelectSingleWithAsyncOptions extends Component {
state = {value: ''}
onChange = async (e, {value}) => {
this.setState({value})
}
render() {
const {value} = this.state
const {onChange, props} = this
return (
<MoleculeSelect {...props} value={value} onChange={onChange}>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelect>
)
}
}
so then, the SelectSingleWithAsyncOptions
can used in this way...
<SelectSingleWithAsyncOptions iconClear={<IconClear />} />
There's a hoc called withStateValue
available at @s-ui/hoc
that can be used to simplify the use of this component with internal state
import MoleculeSelect from '@s-ui/react-molecule-select'
import MoleculeSelectOption from '@s-ui/react-molecule-dropdown-option'
import withDynamicOptions from './hoc/withDynamicOptions'
import {withStateValue} from '@s-ui/hoc'
const MoleculeSelectWithState = withStateValue(MoleculeSelect)
const options = ['John', 'Paul', 'George', 'Ringo']
so then, the MoleculeSelectWithState
can be used in this way...
<MoleculeSelectWithState
placeholder="Type a Country name..."
onChange={(_, {value}) => console.log(value)}
iconClear={<IconClear />}
>
{options.map((option, i) => (
<MoleculeSelectOption key={i} value={option}>
{option}
</MoleculeSelectOption>
))}
</MoleculeSelectWithState>
If you need an option that cannot be customized from MoleculeDropdownOption
you can create your own option compatible w/ MoleculeSelect
y MoleculeSelect
by using the handlersFactory
method available in MoleculeDropdownOption
that you can use to create proper handlers needed to work properly along w/ MoleculeSelect
y MoleculeSelect
import React from 'react'
import {handlersFactory} from '@s-ui/react-molecule-dropdown-option'
const BASE_CLASS = 'AlternativeOption'
const AlternativeOption = ({children, onSelect, innerRef, value}) => {
const {handleClick, handleKeyDown, handleFocus} = handlersFactory({
value,
onSelect
})
return (
<div
className={BASE_CLASS}
ref={innerRef}
tabIndex="0"
onFocus={handleFocus}
onClick={handleClick}
onKeyDown={handleKeyDown}
>
{children}
</div>
)
}
AlternativeOption.displayName = 'AlternativeOption'
AlternativeOption.defaultProps = {
onSelect: () => {},
innerRef: React.createRef()
}
export default AlternativeOption
so then you can do something like...
<MoleculeSelect
placeholder="Select an Option..."
onChange={(_, {value}) => console.log(value)}
iconArrowDown={<IconArrowDown />}
>
{options.map((option, i) => (
<AlternativeOption key={i} value={option}>
{option}
</AlternativeOption>
))}
</MoleculeSelect>
Find full description and more examples in the demo page.