UNPKG

@wix/design-system

Version:

@wix/design-system

174 lines 6.29 kB
import React from 'react'; import InputWithOptions from '../InputWithOptions'; import Input from '../Input'; import { classes } from './MultiSelectCheckbox.st.css.js'; import { listItemSelectBuilder } from '../ListItemSelect'; import { listItemSectionBuilder } from '../ListItemSection'; const OPEN_DROPDOWN_CHARS = ['Enter', 'ArrowDown', 'Space', ' ']; class MultiSelectCheckbox extends InputWithOptions { createOptions(options) { return options.map(option => { if (this._isUsingCustomRenderFunction(option)) { return this._patchOptionWithSelectionMechanism(option); } else if (this._isDivider(option)) { return listItemSectionBuilder({ type: 'divider', ...option, }); } else { const builder = listItemSelectBuilder({ ...option, checkbox: true, title: option.value, label: option.label, }); return this._patchOptionWithSelectionMechanism(builder); } }); } _patchOptionWithSelectionMechanism(option) { const value = option.value; return { ...option, value: props => value({ ...props, selected: this.isSelectedId(option.id), }), }; } _isUsingCustomRenderFunction({ value }) { return typeof value === 'function'; } _isDivider({ value }) { return value === '-'; } isSelectedId(optionId) { return this.props.selectedOptions.indexOf(optionId) !== -1; } dropdownAdditionalProps() { const { predicate, emptyStateMessage, enableSearch } = this.props; const filterFunc = this.state.isEditing ? predicate : () => true; let options = enableSearch ? this.createOptions(this.props.options.filter(filterFunc)) : this.createOptions(this.props.options); if (options.length === 0 && emptyStateMessage) { options = [ { id: 'empty-state-message', value: emptyStateMessage, disabled: true, }, ]; } return { options, closeOnSelect: false, selectedHighlight: false, }; } selectedOptionsToText() { return this.props.selectedOptions .map(selectedOption => this.props.options.find(option => option.id === selectedOption)) .filter(selectedOption => selectedOption) .map(this.props.valueParser) .join(this.props.delimiter); } inputAdditionalProps() { if (this.props.enableSearch) { const { selectedOptions, getSelectedOptionsText } = this.props; const selectedOptionsText = !!getSelectedOptionsText ? getSelectedOptionsText(selectedOptions.length) : this.selectedOptionsToText(); const value = !this._focused && selectedOptions.length > 0 ? selectedOptionsText : this.props.value; return { readOnly: this.props.readOnly, disableEditing: false, value, placeholder: selectedOptions.length > 0 ? selectedOptionsText : this.props.placeholder, }; } else { const value = this.props.value !== undefined ? this.props.value : this.selectedOptionsToText(); return { readOnly: this.props.readOnly, disableEditing: this.props.disableEditing, inputElement: this.props.inputElement ?? (React.createElement(Input, { textOverflow: "ellipsis", disableEditing: this.props.disableEditing })), value, }; } } inputClasses() { return this.props.enableSearch ? '' : classes.showPointer; } _onSelect(option) { this.showOptions(); if (this.closeOnSelect()) { this.setState({ showOptions: false }); } // The option object is not the original since it was injected a checkbox const originalOption = this.props.options.find(op => option.id === op.id); if (this.isSelectedId(originalOption.id)) { this.props.onDeselect && this.props.onDeselect(originalOption.id, originalOption); } else { this.props.onSelect && this.props.onSelect(originalOption.id, originalOption); } if (this.props.enableSearch && this.props.onChange) { this.props.onChange({ target: { value: '' } }); this.setState({ isEditing: false }); } } _onOpenChange(event) { if (!this.props.readOnly) { this.state.showOptions ? this.hideOptions() : this.showOptions(); } } _onKeyDown(event) { if (OPEN_DROPDOWN_CHARS.includes(event.key) && !(this.state.isEditing && event.key === ' ')) { event.preventDefault(); this.showOptions(); } else if (this.props.enableSearch && event.key !== 'ArrowDown' && event.key !== 'ArrowUp') { this.setState({ isEditing: true }); } this.dropdownLayout && this.dropdownLayout._onSelectListKeyDown(event); } _onFocus(e) { if (this.props.disabled) { return; } this._focused = true; if (this.props.onFocus) { this.props.onFocus(e); this.setState({ isEditing: false }); } } } MultiSelectCheckbox.displayName = 'MultiSelectCheckbox'; MultiSelectCheckbox.defaultProps = { ...InputWithOptions.defaultProps, delimiter: ', ', selectedOptions: [], closeOnSelect: false, valueParser: option => option.label || option.value, readOnly: false, disableEditing: true, clearOnBlur: true, predicate: () => true, enableSearch: false, }; export default MultiSelectCheckbox; //# sourceMappingURL=MultiSelectCheckbox.js.map