import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { Map, List, fromJS } from 'immutable'; import { find } from 'lodash'; import Select from 'react-select'; import { colors } from 'netlify-cms-ui-default'; const styles = { control: styles => ({ ...styles, border: 0, boxShadow: 'none', padding: '9px 0 9px 12px', }), option: (styles, state) => ({ ...styles, backgroundColor: state.isSelected ? `${colors.active}` : state.isFocused ? `${colors.activeBackground}` : 'transparent', paddingLeft: '22px', }), menu: styles => ({ ...styles, right: 0, zIndex: 2 }), container: styles => ({ ...styles, padding: '0 !important' }), indicatorSeparator: (styles, state) => state.hasValue && state.selectProps.isClearable ? { ...styles, backgroundColor: `${colors.textFieldBorder}` } : { display: 'none' }, dropdownIndicator: styles => ({ ...styles, color: `${colors.controlLabel}` }), clearIndicator: styles => ({ ...styles, color: `${colors.controlLabel}` }), multiValue: styles => ({ ...styles, backgroundColor: colors.background, }), multiValueLabel: styles => ({ ...styles, color: colors.textLead, fontWeight: 500, }), multiValueRemove: styles => ({ ...styles, color: colors.controlLabel, ':hover': { color: colors.errorText, backgroundColor: colors.errorBackground, }, }), }; function optionToString(option) { return option && option.value ? option.value : null; } function convertToOption(raw) { if (typeof raw === 'string') { return { label: raw, value: raw }; } return Map.isMap(raw) ? raw.toJS() : raw; } export default class SelectControl extends React.Component { static propTypes = { onChange: PropTypes.func.isRequired, value: PropTypes.node, forID: PropTypes.string.isRequired, classNameWrapper: PropTypes.string.isRequired, setActiveStyle: PropTypes.func.isRequired, setInactiveStyle: PropTypes.func.isRequired, field: ImmutablePropTypes.contains({ options: ImmutablePropTypes.listOf( PropTypes.oneOfType([ PropTypes.string, ImmutablePropTypes.contains({ label: PropTypes.string.isRequired, value: PropTypes.string.isRequired, }), ]), ).isRequired, }), }; handleChange = selectedOption => { const { onChange, field } = this.props; const isMultiple = field.get('multiple', false); if (Array.isArray(selectedOption)) { if (!isMultiple && selectedOption.length === 0) { onChange(null); } else { onChange(fromJS(selectedOption.map(optionToString))); } } else { onChange(optionToString(selectedOption)); } }; getSelectedValue = ({ value, options, isMultiple }) => { if (isMultiple) { const selectedOptions = List.isList(value) ? value.toJS() : value; if (!selectedOptions || !Array.isArray(selectedOptions)) { return null; } return selectedOptions .map(i => options.find(o => o.value === (i.value || i))) .filter(Boolean) .map(convertToOption); } else { return find(options, ['value', value]) || null; } }; render() { const { field, value, forID, classNameWrapper, setActiveStyle, setInactiveStyle } = this.props; const fieldOptions = field.get('options'); const isMultiple = field.get('multiple', false); const isClearable = !field.get('required', true) || isMultiple; if (!fieldOptions) { return