@findify/react-components
Version:
Findify react UI components
40 lines (39 loc) • 2.12 kB
JSX
/**
* @module components/Dropdown
*/
import cx from 'classnames';
import Downshift from 'downshift';
import MapArray from 'components/common/MapArray';
import Icon from 'components/Icon';
import Button from 'components/Button';
import Text from 'components/Text';
import { fromJS, isImmutable } from 'immutable';
import styles from 'components/Dropdown/styles.css';
import { useMemo, useRef } from 'react';
const Item = ({ item, index, getItemProps, highlighted, theme = styles, }) => (<li className={cx(theme.option, highlighted === index && theme.highlighted)} {...getItemProps({ item })}>
<Text primary lowercase>
{item.get('label')}
</Text>
</li>);
export default ({ onChange, selectedItem, className, items: _items, theme = styles, itemToString = (i) => i.get('label'), }) => {
const items = useMemo(() => (isImmutable(_items) ? _items : fromJS(_items)), [
_items,
]);
const id = useRef(`dropdown-${items.hashCode()}`);
return (<Downshift onChange={onChange} selectedItem={selectedItem || items.get(0)} itemToString={itemToString}>
{({ isOpen, selectedItem, getToggleButtonProps, getRootProps, getItemProps, getMenuProps, getLabelProps, highlightedIndex, }) => (<div {...getRootProps({}, { suppressRefError: true })} role="group" className={cx(theme.root, className)}>
<label {...getLabelProps()} className={theme.label}>
{selectedItem.get('label')}
</label>
<Button {...getToggleButtonProps()} className={theme.select}>
<Text primary lowercase>
{selectedItem.get('label')}
</Text>
<Icon name={isOpen ? 'ArrowUp' : 'ArrowDown'} className={theme.arrow} title="Expand list" aria-hidden="true" focusable="false" role="presentation"/>
</Button>
<ul {...getMenuProps()} className={cx(theme.dropdown, { [theme.open]: isOpen })}>
<MapArray theme={theme} parentId={id} highlighted={highlightedIndex} getItemProps={getItemProps} array={items.filter((i) => !i.equals(selectedItem))} factory={Item}/>
</ul>
</div>)}
</Downshift>);
};