import React from 'react'; import { Menu, Empty, Spin, Icon, Input, Dropdown } from 'antd'; import { findDOMNode } from 'react-dom'; import lodash from 'lodash'; import styles from './styles.less'; /* * 此空间用于数据选择及输入控制,若不选择只传入输入框数据 */ interface Props { initDataType?: undefined | 'onfocus'; // 初始化请求方式 request?: Function; selfCom?: any; dataSource?: []; onChange: Function; value?: any; autoFocus?: boolean; mode?: 'multiple' | 'tags' | undefined; fieldNames?: { value: any; label: string; }; placeholder?: string; width?: number; disabled?: boolean; } interface State { searchStr: string; list: any[]; loading: boolean; selected: any[] | undefined; tempSelected: any[] | undefined; tempVisible: boolean; } class TextSelect extends React.Component { container: any; input: any; width: number = 320; constructor(props) { super(props); this.state = { searchStr: '', list: [], loading: false, selected: undefined, tempSelected: undefined, tempVisible: false, }; this.container = React.createRef(); this.input = React.createRef(); this.fetch = lodash.debounce(this.fetch, 400); } static getDerivedStateFromProps(nextProps, prevState) { if (JSON.stringify(nextProps.value) !== JSON.stringify(prevState.tempSelected)) { const [first] = nextProps.value || []; const searchStr = first ? first.label || first.text : ''; return { tempSelected: nextProps.value || [], selected: nextProps.value, searchStr, }; } return null; } componentDidMount() { setTimeout(this.getInputWidth, 10); } getInputWidth = () => { if (this.input.current) { const dom = findDOMNode(this.input.current); if (dom) { // @ts-ignore this.width = dom.offsetWidth; } } }; fetch = async (val) => { const { request } = this.props; if (!request) return; await this.setState({ loading: true, list: [] }); const result = await request(val); if (result && result.success) { const data = result.data || {}; let list = Array.isArray(data.list) ? data.list : []; list = this.formatData(list); this.setState({ list }); } await this.setState({ loading: false }); }; formatData = (data) => { const { fieldNames = { label: 'name', value: 'id' } } = this.props || {}; const { label, value } = fieldNames; return data.map((item) => { return { ...item, _label: item[label], _value: item[value], }; }); }; onResetValue = (searchStr) => { return [{ value: '', label: searchStr }]; }; onSearch = (e) => { const searchStr = e.currentTarget.value; const selected = this.onResetValue(searchStr); this.setState({ searchStr, selected }, () => { this.fetch(searchStr); this.onChange(selected); }); }; onFocus = () => { const { searchStr } = this.state; this.fetch(searchStr); }; onClickMenu = ({ item, key }) => { const { props } = item || {}; const { title } = props || {}; const selected = [{ label: title, value: key }]; this.setState({ selected, searchStr: title }); this.onVisibleChange(false); this.onChange(selected); }; onChange = (obj) => { const { onChange } = this.props; if (typeof onChange === 'function') { onChange(obj); } }; onClear = () => { const { tempVisible } = this.state; const searchStr = ''; const selected = this.onResetValue(searchStr); this.setState({ searchStr, selected }, () => { if (tempVisible) { this.fetch(searchStr); } this.onChange(selected); }); }; onVisibleChange = (tempVisible) => { this.setState({ tempVisible }); }; renderList = () => { const { list, loading, selected } = this.state; const { width } = this.props; return ( {list.map((item) => { return ( // eslint-disable-next-line no-underscore-dangle {/* eslint-disable-next-line no-underscore-dangle */} {item._label} ); })} {loading ? ( ) : null} {list.length === 0 ? ( ) : null} ); }; getContainer = () => { return this.container.current; }; render() { const { placeholder, disabled } = this.props; const { searchStr } = this.state; return ( ); } } export default TextSelect;