/** * To match accessibility requirement, we always provide an input in the component. * Other element will not set `tabIndex` to avoid `onBlur` sequence problem. * For focused select, we set `aria-live="polite"` to update the accessibility content. * * ref: * - keyboard: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role#Keyboard_interactions */ import * as React from 'react'; import { ScrollTo } from '../../virtual-list/List'; import { RenderNode, Mode, RenderDOMFunc } from './interface'; import { GetLabeledValue, FilterOptions, FilterFunc, DefaultValueType, RawValueType, LabelValueType, Key, ExpandKey, DefaultExpandKey, FlattenOptionsType, SingleType, OnClear, SelectSource, CustomTagProps } from './interface/generator'; import { OptionProps } from './Option'; import { OptionListProps, RefOptionListProps } from './OptionList'; export interface RefSelectProps { focus: () => void; blur: () => void; scrollTo?: ScrollTo; } export interface SelectProps extends React.AriaAttributes { prefixCls?: string; id?: string; className?: string; style?: React.CSSProperties; options?: OptionsType; children?: React.ReactNode; mode?: Mode; value?: ValueType; defaultValue?: ValueType; labelInValue?: boolean; /** Config max length of input. This is only work when `mode` is `combobox` */ maxLength?: number; inputValue?: string; searchValue?: string; optionFilterProp?: string; /** * In Select, `false` means do nothing. * In TreeSelect, `false` will highlight match item. * It's by design. */ filterOption?: boolean | FilterFunc; filterSort?: (optionA: OptionsType[number], optionB: OptionsType[number]) => number; showSearch?: boolean; autoClearSearchValue?: boolean; onSearch?: (value: string) => void; onClear?: OnClear; suffixIconPre?: React.ReactNode; allowClear?: boolean; clearIcon?: React.ReactNode | ((props: any) => React.ReactNode); showArrow?: boolean; showTitle?: boolean; showSelectAll?: boolean; inputIcon?: RenderNode; removeIcon?: React.ReactNode; menuItemSelectedIcon?: RenderNode; showAllSelected?: boolean; open?: boolean; defaultOpen?: boolean; listHeight?: number; listItemHeight?: number; dropdownStyle?: React.CSSProperties; dropdownClassName?: string; dropdownMatchSelectWidth?: boolean | number; virtual?: boolean; dropdownRender?: (menu: React.ReactElement) => React.ReactElement; dropdownAlign?: any; animation?: string; transitionName?: string; getPopupContainer?: RenderDOMFunc; direction?: string; disabled?: boolean; loading?: boolean; autoFocus?: boolean; defaultActiveFirstOption?: boolean; notFoundContent?: React.ReactNode; placeholder?: React.ReactNode; placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight'; backfill?: boolean; getInputElement?: () => JSX.Element; optionLabelProp?: string; maxTagTextLength?: number; maxTagCount?: number | 'responsive'; maxTagPlaceholder?: React.ReactNode | ((omittedValues: LabelValueType[]) => React.ReactNode); tokenSeparators?: string[]; groupSelectorRender?: (groupLabel: string, value: string | number) => React.ReactElement; tagRender?: (props: CustomTagProps) => React.ReactElement; optionRender?: (label: React.ReactNode, option?: OptionProps) => React.ReactNode; showAction?: ('focus' | 'click')[]; tabIndex?: number; renderEmpty?: (componentName?: string, des?: string | undefined) => React.ReactNode; keepExpand?: boolean; defaultExpandGroupKey?: DefaultExpandKey; popupOverflow?: 'viewport' | 'scroll'; onKeyUp?: React.KeyboardEventHandler; onKeyDown?: React.KeyboardEventHandler; onPopupScroll?: React.UIEventHandler; onDropdownVisibleChange?: (open: boolean) => void; onSelect?: (value: SingleType, option: OptionsType[number]) => void; onDeselect?: (value: SingleType, option: OptionsType[number]) => void; onInputKeyDown?: React.KeyboardEventHandler; onClick?: React.MouseEventHandler; onChange?: (value: ValueType, option: OptionsType[number] | OptionsType) => void; onBlur?: React.FocusEventHandler; onFocus?: React.FocusEventHandler; onMouseDown?: React.MouseEventHandler; onMouseEnter?: React.MouseEventHandler; onMouseLeave?: React.MouseEventHandler; onExpandChange?: (key: ExpandKey) => void; choiceTransitionName?: string; /** * Only used in current version for internal event process. * Do not use in production environment. */ internalProps?: { mark?: string; onClear?: OnClear; skipTriggerChange?: boolean; skipTriggerSelect?: boolean; onRawSelect?: (value: RawValueType, option: OptionsType[number], source: SelectSource) => void; onRawDeselect?: (value: RawValueType, option: OptionsType[number], source: SelectSource) => void; }; } export interface GenerateConfig { prefixCls: string; components: { optionList: React.ForwardRefExoticComponent, 'options'> & { options: OptionsType; }> & React.RefAttributes>; }; /** Convert jsx tree into `OptionsType` */ convertChildrenToData: (children: React.ReactNode) => OptionsType; /** Flatten nest options into raw option list */ flattenOptions: (options: OptionsType, props: any) => FlattenOptionsType; /** Convert single raw value into { label, value } format. Will be called by each value */ getLabeledValue: GetLabeledValue>; filterOptions: FilterOptions; findValueOption: ((values: RawValueType[], options: FlattenOptionsType) => OptionsType) | ((values: RawValueType[], options: FlattenOptionsType, info?: { prevValueOptions?: OptionsType[]; }) => OptionsType); /** Check if a value is disabled */ isValueDisabled: (value: RawValueType, options: FlattenOptionsType) => boolean; warningProps?: (props: any) => void; fillOptionsWithMissingValue?: (options: OptionsType, value: DefaultValueType, optionLabelProp: string, labelInValue: boolean) => OptionsType; omitDOMProps?: (props: object) => { [index: string]: any; }; } /** * This function is in internal usage. * Do not use it in your prod env since we may refactor this. */ export default function generateSelector(config: GenerateConfig): React.ForwardRefExoticComponent & React.RefAttributes>;