import React from 'react'; import { OptionsControl, OptionsControlProps, Option, FormOptionsControl } from './Options'; import Downshift from 'downshift'; import find from 'lodash/find'; import {findDOMNode} from 'react-dom'; import ResultBox from '../../components/ResultBox'; import {autobind, filterTree} from '../../utils/helper'; import Spinner from '../../components/Spinner'; import Overlay from '../../components/Overlay'; import PopOver from '../../components/PopOver'; import ListMenu from '../../components/ListMenu'; /** * Tag 输入框 * 文档:https://baidu.gitee.io/amis/docs/components/form/tag */ export interface TagControlSchema extends FormOptionsControl { type: 'input-tag'; /** * 选项提示信息 */ optionsTip?: string; /** * 是否为下拉模式 */ dropdown?: boolean; } // declare function matchSorter(items:Array, input:any, options:any): Array; export interface TagProps extends OptionsControlProps { placeholder?: string; clearable: boolean; resetValue?: any; optionsTip: string; dropdown?: boolean; } export interface TagState { inputValue: string; isFocused?: boolean; isOpened?: boolean; } export default class TagControl extends React.PureComponent< TagProps, TagState > { input: React.RefObject = React.createRef(); static defaultProps = { resetValue: '', labelField: 'label', valueField: 'value', multiple: true, placeholder: 'Tag.placeholder', optionsTip: 'Tag.tip' }; state = { isOpened: false, inputValue: '', isFocused: false }; componentWillReceiveProps(nextProps: TagProps) { const props = this.props; if (props.value !== nextProps.value) { this.setState({ inputValue: '' }); } } addItem(option: Option) { const { selectedOptions, onChange, joinValues, extractValue, delimiter, valueField } = this.props; const newValue = selectedOptions.concat(); if (find(newValue, item => item.value == option.value)) { return; } newValue.push(option); onChange( joinValues ? newValue .map(item => item[valueField || 'value']) .join(delimiter || ',') : extractValue ? newValue.map(item => item[valueField || 'value']) : newValue ); } @autobind handleFocus(e: any) { this.setState({ isFocused: true, isOpened: true }); this.props.onFocus?.(e); } @autobind handleBlur(e: any) { const { selectedOptions, onChange, joinValues, extractValue, delimiter, valueField } = this.props; const value = this.state.inputValue.trim(); this.props.onBlur?.(e); this.setState( { isFocused: false, isOpened: false, inputValue: '' }, value ? () => { const newValue = selectedOptions.concat(); if (!find(newValue, item => item.value === value)) { const option = { label: value, value: value }; newValue.push(option); onChange( joinValues ? newValue .map(item => item[valueField || 'value']) .join(delimiter || ',') : extractValue ? newValue.map(item => item[valueField || 'value']) : newValue ); } } : undefined ); } @autobind close() { this.setState({ isOpened: false }); } @autobind handleInputChange(text: string) { this.setState({ inputValue: text }); } @autobind handleChange(value: Array