UNPKG

react-select-module

Version:
129 lines (121 loc) 3.65 kB
import React, { Component } from 'react'; import { cleanValue } from './utils'; import manageState from './stateManager'; import Select from './Select'; const compareOption = (inputValue = '', option) => { const candidate = String(inputValue).toLowerCase(); const optionValue = String(option.value).toLowerCase(); const optionLabel = String(option.label).toLowerCase(); return optionValue === candidate || optionLabel === candidate; }; const builtins = { formatCreateLabel: inputValue => `Create "${inputValue}"`, isValidNewOption: (inputValue, selectValue, selectOptions) => !( !inputValue || selectValue.some(option => compareOption(inputValue, option)) || selectOptions.some(option => compareOption(inputValue, option)) ), getNewOptionData: (inputValue, optionLabel) => ({ label: optionLabel, value: inputValue, __isNew__: true, }), }; export const defaultProps = { allowCreateWhileLoading: false, createOptionPosition: 'last', ...builtins, }; export const makeCreatableSelect = SelectComponent => class Creatable extends Component { static defaultProps = defaultProps; select; constructor(props) { super(props); const options = props.options || []; this.state = { newOption: undefined, options: options, }; } UNSAFE_componentWillReceiveProps(nextProps) { const { allowCreateWhileLoading, createOptionPosition, formatCreateLabel, getNewOptionData, inputValue, isLoading, isValidNewOption, value, } = nextProps; const options = nextProps.options || []; let { newOption } = this.state; if (isValidNewOption(inputValue, cleanValue(value), options)) { newOption = getNewOptionData(inputValue, formatCreateLabel(inputValue)); } else { newOption = undefined; } this.setState({ newOption: newOption, options: (allowCreateWhileLoading || !isLoading) && newOption ? createOptionPosition === 'first' ? [newOption, ...options] : [...options, newOption] : options, }); } onChange = (newValue, actionMeta) => { const { getNewOptionData, inputValue, isMulti, onChange, onCreateOption, value, name, } = this.props; if (actionMeta.action !== 'select-option') { return onChange(newValue, actionMeta); } const { newOption } = this.state; const valueArray = Array.isArray(newValue) ? newValue : [newValue]; if (valueArray[valueArray.length - 1] === newOption) { if (onCreateOption) onCreateOption(inputValue); else { const newOptionData = getNewOptionData(inputValue, inputValue); const newActionMeta = { action: 'create-option', name }; if (isMulti) { onChange([...cleanValue(value), newOptionData], newActionMeta); } else { onChange(newOptionData, newActionMeta); } } return; } onChange(newValue, actionMeta); }; focus() { this.select.focus(); } blur() { this.select.blur(); } render() { const { options } = this.state; return ( <SelectComponent {...this.props} ref={ref => { this.select = ref; }} options={options} onChange={this.onChange} /> ); } }; const SelectCreatable = makeCreatableSelect(Select); export default manageState(SelectCreatable);