import React, { PureComponent } from 'react'; import classnames from 'classnames'; import DropdownShell from './DropdownShell'; interface Props { value: T | undefined; options: T[]; ariaLabel: string; label?: string; extra?: any; size?: string; color?: string; menuAlign?: string; formatTitle?(option: T): any; onChange?(value: T): void; } interface State { search: string; } export default class DropdownComponent extends PureComponent, State> { public state = { search: '' }; private dropdownShell: DropdownShell | null; public render() { const { ariaLabel, color, size } = this.props; return ( (this.dropdownShell = el)} /> ); } private renderLabel = () => { const { value } = this.props; const labelStr = this.props.label ? `${this.props.label}:` : ''; return ( {labelStr} {this.formatTitle(value)} ); }; private renderOptions = () => { const { options, value, menuAlign, extra } = this.props; const { search } = this.state; const searchable = options.length > 20; const menuClass = classnames({ 'dropdown-menu': true, [`dropdown-menu-${menuAlign || ''}`]: !!menuAlign }); const searchableStyle = { maxHeight: '300px', overflowY: 'auto' }; const searchRegex = new RegExp(search, 'gi'); const onSearchChange = (e: React.FormEvent) => { this.setState({ search: e.currentTarget.value }); }; return ( ); }; private formatTitle = (option: any) => { if (this.props.formatTitle) { return this.props.formatTitle(option); } else { return option; } }; private onChange = (value: any) => { if (this.props.onChange) { this.props.onChange(value); } if (this.dropdownShell) { this.dropdownShell.close(); } }; }