import React from 'react'; import { findDOMNode } from 'react-dom'; import Select, { AbstractSelectProps, OptionProps, OptGroupProps } from '../select'; import Input from '../input'; import { Option, OptGroup } from 'rc-select'; import classNames from 'classnames'; export interface SelectedValue { key: string; label: React.ReactNode; } export interface DataSourceItemObject { value: string; text: string; }; export type DataSourceItemType = string | DataSourceItemObject; export interface InputProps { onChange?: React.FormEventHandler; value: any; } export type ValidInputElement = HTMLInputElement | HTMLTextAreaElement | React.ReactElement; export interface AutoCompleteProps extends AbstractSelectProps { size?: 'large' | 'small' | 'default'; className?: string; notFoundContent?: Element; dataSource: DataSourceItemType[]; defaultValue?: string | Array | SelectedValue | Array; value?: string | Array | SelectedValue | Array; onChange?: (value: string | Array | SelectedValue | Array) => void; onSelect?: (value: string | Array | SelectedValue | Array, option: Object) => any; disabled?: boolean; children?: ValidInputElement | React.ReactElement | Array>; } class InputElement extends React.Component { private ele: HTMLInputElement; focus = () => { this.ele.focus ? this.ele.focus() : (findDOMNode(this.ele) as HTMLInputElement).focus(); } blur = () => { this.ele.blur ? this.ele.blur() : (findDOMNode(this.ele) as HTMLInputElement).blur(); } render() { return React.cloneElement(this.props.children, { ...this.props, ref: ele => this.ele = (ele as HTMLInputElement), }, null); } } 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 = { prefixCls: 'ant-select', transitionName: 'slide-up', optionLabelProp: 'children', choiceTransitionName: 'zoom', showSearch: false, }; static contextTypes = { antLocale: React.PropTypes.object, }; getInputElement = () => { const { children } = this.props; const element = children && React.isValidElement(children) && children.type !== Option ? React.Children.only(this.props.children) : ; return {element}; } render() { let { size, className = '', notFoundContent, prefixCls, optionLabelProp, dataSource, children, } = this.props; 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 ( ); } }