@wix/design-system
Version:
@wix/design-system
99 lines • 3.37 kB
JavaScript
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