UNPKG

@findify/react-components

Version:
40 lines (39 loc) 2.12 kB
/** * @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>); };