import * as React from 'react'; import { Option, OptGroup } from 'rc-select'; import classNames from 'classnames'; import InputElement from './InputElement'; import Input, { InputProps } from '../input'; import Select, { AbstractSelectProps, SelectValue, OptionProps, OptGroupProps } from '../select'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; export interface DataSourceItemObject { value: string; text: string; } export type DataSourceItemType = | string | DataSourceItemObject | React.ReactElement | React.ReactElement; export interface AutoCompleteInputProps { onChange?: React.FormEventHandler; value: any; } export type ValidInputElement = | HTMLInputElement | HTMLTextAreaElement | React.ReactElement; export interface AutoCompleteProps extends AbstractSelectProps { value?: SelectValue; defaultValue?: SelectValue; dataSource?: DataSourceItemType[]; autoFocus?: boolean; backfill?: boolean; optionLabelProp?: string; onChange?: (value: SelectValue) => void; onSelect?: (value: SelectValue, option: Object) => any; onBlur?: (value: SelectValue) => void; onFocus?: () => void; children?: | ValidInputElement | React.ReactElement | React.ReactElement | Array>; } function isSelectOptionOrSelectOptGroup(child: any): Boolean { return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup); } export default class AutoComplete extends React.Component { static Option = Option as React.ClassicComponentClass; static OptGroup = OptGroup as React.ClassicComponentClass; static defaultProps = { transitionName: 'slide-up', optionLabelProp: 'children', choiceTransitionName: 'zoom', showSearch: false, filterOption: false, }; private select: any; getInputElement = () => { const { children } = this.props; const element = children && React.isValidElement(children) && children.type !== Option ? ( React.Children.only(this.props.children) ) : ( ); const elementProps = { ...element.props }; // https://github.com/ant-design/ant-design/pull/7742 delete elementProps.children; return {element}; }; focus() { this.select.focus(); } blur() { this.select.blur(); } saveSelect = (node: any) => { this.select = node; }; renderAutoComplete = ({ getPrefixCls }: ConfigConsumerProps) => { const { prefixCls: customizePrefixCls, size, className = '', notFoundContent, optionLabelProp, dataSource, children, } = this.props; const prefixCls = getPrefixCls('select', customizePrefixCls); const cls = classNames({ [`${prefixCls}-lg`]: size === 'large', [`${prefixCls}-sm`]: size === 'small', [className]: !!className, [`${prefixCls}-show-search`]: true, [`${prefixCls}-auto-complete`]: true, }); let options; const childArray = React.Children.toArray(children); if (childArray.length && isSelectOptionOrSelectOptGroup(childArray[0])) { options = children; } else { options = dataSource ? dataSource.map(item => { if (React.isValidElement(item)) { return item; } switch (typeof item) { case 'string': return ; case 'object': return ( ); default: throw new Error( 'AutoComplete[dataSource] only supports type `string[] | Object[]`.', ); } }) : []; } return ( ); }; render() { return {this.renderAutoComplete}; } }