UNPKG

@wix/design-system

Version:

@wix/design-system

99 lines 3.37 kB
import defaultTo from 'lodash/defaultTo'; import isEqual from 'lodash/isEqual'; import sortBy from 'lodash/sortBy'; import InputWithOptions from '../InputWithOptions'; import { st, classes } from './Dropdown.st.css.js'; const NO_SELECTED_ID = null; const DROPDOWN_DOUBLE_CLICK_THRESHOLD = 200; const OPEN_KEYS = ['Enter', 'Spacebar', ' ', 'ArrowUp', 'ArrowDown']; class Dropdown extends InputWithOptions { constructor(props) { super(props); this.state = { value: '', selectedId: NO_SELECTED_ID, ...Dropdown.getNextState(props, defaultTo(props.selectedId, props.initialSelectedId)), }; } isSelectedIdControlled() { return typeof this.props.selectedId !== 'undefined'; } static isOptionsEqual(optionsA, optionsB) { return isEqual(sortBy(optionsA, 'id'), sortBy(optionsB, 'id')); } getSelectedId() { return this.isSelectedIdControlled() ? this.props.selectedId : this.state.selectedId; } shouldOpenDropdown(key) { return OPEN_KEYS.includes(key); } _onOpenChange(open, reason) { super._onOpenChange(open, reason, DROPDOWN_DOUBLE_CLICK_THRESHOLD); } /** * Updates the value by the selectedId. * If selectedId is not found in options, then value is NOT changed. */ static getNextState(props, selectedId) { if (typeof selectedId !== 'undefined') { const option = props.options.find(_option => { return _option.id === selectedId; }); if (option) { const value = props.valueParser(option) || ''; return { value, selectedId }; } } return { value: '', selectedId: NO_SELECTED_ID }; } UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.selectedId !== this.props.selectedId || !Dropdown.isOptionsEqual(this.props.options, nextProps.options)) { this.setState(Dropdown.getNextState(nextProps, nextProps.selectedId, this.state.selectedId)); } } inputClasses() { const { noBorder, allowTextSelection } = this.props; return st(classes.showPointer, { noBorder, allowTextSelection }); } dropdownAdditionalProps() { return { selectedId: this.getSelectedId(), value: this.state.value, tabIndex: -1, withArrow: false, size: ['tiny', 'small'].includes(this.props.size) ? 'small' : 'medium', }; } inputAdditionalProps() { return { disableEditing: true, readOnly: this.props.readOnly, value: this.state.value, role: 'combobox', ariaHaspopup: 'listbox', }; } _onSelect(option) { if (!this.isSelectedIdControlled()) { this.setState({ value: this.props.valueParser(option), selectedId: option.id, }); } super._onSelect(option); } _onChange(event) { this.setState({ value: event.target.value }); super._onChange(event); } } Dropdown.defaultProps = { allowTextSelection: true, ...InputWithOptions.defaultProps, }; Dropdown.displayName = 'Dropdown'; export default Dropdown; //# sourceMappingURL=Dropdown.js.map