@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
318 lines (317 loc) • 15.1 kB
TypeScript
import React, { MouseEvent } from 'react';
import PropTypes from 'prop-types';
import { ContextValue } from '../configProvider/context';
import SelectFoundation, { SelectAdapter } from '@douyinfe/semi-foundation/lib/cjs/select/foundation';
import BaseComponent, { ValidateStatus } from '../_base/baseComponent';
import { PopoverProps } from '../popover/index';
import Event from '@douyinfe/semi-foundation/lib/cjs/utils/Event';
import { InputProps } from '../input/index';
import Option, { OptionProps } from './option';
import OptionGroup from './optionGroup';
import '@douyinfe/semi-foundation/lib/cjs/select/select.css';
import type { Position, TooltipProps } from '../tooltip';
import type { Subtract } from 'utility-types';
export type { OptionProps } from './option';
export type { OptionGroupProps } from './optionGroup';
export type { VirtualRowProps } from './virtualRow';
type ExcludeInputType = {
value?: InputProps['value'];
onFocus?: InputProps['onFocus'];
onChange?: InputProps['onChange'];
};
export interface optionRenderProps {
key?: any;
label?: React.ReactNode;
value?: string | number;
style?: React.CSSProperties;
className?: string;
selected?: boolean;
focused?: boolean;
show?: boolean;
disabled?: boolean;
onMouseEnter?: (e: React.MouseEvent) => any;
onClick?: (e: React.MouseEvent) => any;
[x: string]: any;
}
export interface SelectedItemProps {
value: OptionProps['value'];
label: OptionProps['label'];
_show?: boolean;
_selected: boolean;
_scrollIndex?: number;
}
export interface TriggerRenderProps {
value: SelectedItemProps[];
inputValue: string;
onSearch: (inputValue: string) => void;
onClear: () => void;
onRemove: (option: OptionProps) => void;
disabled: boolean;
placeholder: string;
componentProps: Record<string, any>;
}
export interface selectMethod {
clearInput?: () => void;
selectAll?: () => void;
deselectAll?: () => void;
focus?: () => void;
close?: () => void;
open?: () => void;
}
export type SelectSize = 'small' | 'large' | 'default';
export interface virtualListProps {
itemSize?: number;
height?: number;
width?: string | number;
}
export type RenderSingleSelectedItemFn = (optionNode: Record<string, any>) => React.ReactNode;
export type RenderMultipleSelectedItemFn = (optionNode: Record<string, any>, multipleProps: {
index: number;
disabled: boolean;
onClose: (tagContent: React.ReactNode, e: MouseEvent) => void;
}) => {
isRenderInTag: boolean;
content: React.ReactNode;
};
export type RenderSelectedItemFn = RenderSingleSelectedItemFn | RenderMultipleSelectedItemFn;
export type SelectProps = {
'aria-describedby'?: React.AriaAttributes['aria-describedby'];
'aria-errormessage'?: React.AriaAttributes['aria-errormessage'];
'aria-invalid'?: React.AriaAttributes['aria-invalid'];
'aria-labelledby'?: React.AriaAttributes['aria-labelledby'];
'aria-required'?: React.AriaAttributes['aria-required'];
id?: string;
autoFocus?: boolean;
autoClearSearchValue?: boolean;
arrowIcon?: React.ReactNode;
borderless?: boolean;
clearIcon?: React.ReactNode;
defaultValue?: string | number | any[] | Record<string, any>;
value?: string | number | any[] | Record<string, any>;
placeholder?: React.ReactNode;
onChange?: (value: SelectProps['value']) => void;
multiple?: boolean;
filter?: boolean | ((inpueValue: string, option: OptionProps) => boolean);
max?: number;
maxTagCount?: number;
maxHeight?: string | number;
style?: React.CSSProperties;
className?: string;
size?: SelectSize;
disabled?: boolean;
emptyContent?: React.ReactNode;
expandRestTagsOnClick?: boolean;
onDropdownVisibleChange?: (visible: boolean) => void;
zIndex?: number;
position?: Position;
onSearch?: (value: string, event: React.KeyboardEvent | React.MouseEvent) => void;
dropdownClassName?: string;
dropdownStyle?: React.CSSProperties;
dropdownMargin?: PopoverProps['margin'];
ellipsisTrigger?: boolean;
outerTopSlot?: React.ReactNode;
innerTopSlot?: React.ReactNode;
outerBottomSlot?: React.ReactNode;
innerBottomSlot?: React.ReactNode;
optionList?: OptionProps[];
dropdownMatchSelectWidth?: boolean;
loading?: boolean;
defaultOpen?: boolean;
validateStatus?: ValidateStatus;
defaultActiveFirstOption?: boolean;
onChangeWithObject?: boolean;
suffix?: React.ReactNode;
searchPosition?: string;
searchPlaceholder?: string;
prefix?: React.ReactNode;
insetLabel?: React.ReactNode;
insetLabelId?: string;
inputProps?: Subtract<InputProps, ExcludeInputType>;
showClear?: boolean;
showArrow?: boolean;
renderSelectedItem?: RenderSelectedItemFn;
renderCreateItem?: (inputValue: OptionProps['value'], focus: boolean, style?: React.CSSProperties) => React.ReactNode;
renderOptionItem?: (props: optionRenderProps) => React.ReactNode;
onMouseEnter?: (e: React.MouseEvent) => any;
onMouseLeave?: (e: React.MouseEvent) => any;
clickToHide?: boolean;
onExceed?: (option: OptionProps) => void;
onCreate?: (option: OptionProps) => void;
remote?: boolean;
onDeselect?: (value: SelectProps['value'], option: Record<string, any>) => void;
onSelect?: (value: SelectProps['value'], option: Record<string, any>) => void;
allowCreate?: boolean;
triggerRender?: (props: TriggerRenderProps) => React.ReactNode;
onClear?: () => void;
virtualize?: virtualListProps;
onFocus?: (e: React.FocusEvent) => void;
onBlur?: (e: React.FocusEvent) => void;
onListScroll?: (e: React.UIEvent<HTMLDivElement>) => void;
children?: React.ReactNode;
preventScroll?: boolean;
showRestTagsPopover?: boolean;
restTagsPopoverProps?: PopoverProps;
} & Pick<TooltipProps, 'spacing' | 'getPopupContainer' | 'motion' | 'autoAdjustOverflow' | 'mouseLeaveDelay' | 'mouseEnterDelay' | 'stopPropagation'> & React.RefAttributes<any>;
export interface SelectState {
isOpen: boolean;
isFocus: boolean;
options: Array<OptionProps>;
selections: Map<OptionProps['label'], any>;
dropdownMinWidth: number;
optionKey: number;
inputValue: string;
showInput: boolean;
focusIndex: number;
keyboardEventSet: any;
optionGroups: Array<any>;
isHovering: boolean;
isFocusInContainer: boolean;
isFullTags: boolean;
overflowItemCount: number;
}
declare class Select extends BaseComponent<SelectProps, SelectState> {
static contextType: React.Context<ContextValue>;
static Option: typeof Option;
static OptGroup: typeof OptionGroup;
static propTypes: {
'aria-describedby': PropTypes.Requireable<string>;
'aria-errormessage': PropTypes.Requireable<string>;
'aria-invalid': PropTypes.Requireable<boolean>;
'aria-labelledby': PropTypes.Requireable<string>;
'aria-required': PropTypes.Requireable<boolean>;
autoFocus: PropTypes.Requireable<boolean>;
autoClearSearchValue: PropTypes.Requireable<boolean>;
borderless: PropTypes.Requireable<boolean>;
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
clearIcon: PropTypes.Requireable<PropTypes.ReactNodeLike>;
defaultValue: PropTypes.Requireable<NonNullable<string | number | object>>;
ellipsisTrigger: PropTypes.Requireable<boolean>;
value: PropTypes.Requireable<NonNullable<string | number | object>>;
placeholder: PropTypes.Requireable<PropTypes.ReactNodeLike>;
onChange: PropTypes.Requireable<(...args: any[]) => any>;
multiple: PropTypes.Requireable<boolean>;
filter: PropTypes.Requireable<NonNullable<boolean | ((...args: any[]) => any)>>;
max: PropTypes.Requireable<number>;
maxTagCount: PropTypes.Requireable<number>;
maxHeight: PropTypes.Requireable<NonNullable<string | number>>;
style: PropTypes.Requireable<object>;
className: PropTypes.Requireable<string>;
size: PropTypes.Requireable<SelectSize>;
disabled: PropTypes.Requireable<boolean>;
emptyContent: PropTypes.Requireable<PropTypes.ReactNodeLike>;
expandRestTagsOnClick: PropTypes.Requireable<boolean>;
onDropdownVisibleChange: PropTypes.Requireable<(...args: any[]) => any>;
zIndex: PropTypes.Requireable<number>;
position: PropTypes.Requireable<"left" | "top" | "right" | "bottom" | "topLeft" | "topRight" | "leftTop" | "leftBottom" | "rightTop" | "rightBottom" | "bottomLeft" | "bottomRight" | "leftTopOver" | "rightTopOver" | "leftBottomOver" | "rightBottomOver">;
onSearch: PropTypes.Requireable<(...args: any[]) => any>;
getPopupContainer: PropTypes.Requireable<(...args: any[]) => any>;
dropdownClassName: PropTypes.Requireable<string>;
dropdownStyle: PropTypes.Requireable<object>;
dropdownMargin: PropTypes.Requireable<NonNullable<number | object>>;
outerTopSlot: PropTypes.Requireable<PropTypes.ReactNodeLike>;
innerTopSlot: PropTypes.Requireable<PropTypes.ReactNodeLike>;
inputProps: PropTypes.Requireable<object>;
outerBottomSlot: PropTypes.Requireable<PropTypes.ReactNodeLike>;
innerBottomSlot: PropTypes.Requireable<PropTypes.ReactNodeLike>;
optionList: PropTypes.Requireable<any[]>;
dropdownMatchSelectWidth: PropTypes.Requireable<boolean>;
loading: PropTypes.Requireable<boolean>;
defaultOpen: PropTypes.Requireable<boolean>;
validateStatus: PropTypes.Requireable<"default" | "error" | "warning" | "success">;
defaultActiveFirstOption: PropTypes.Requireable<boolean>;
triggerRender: PropTypes.Requireable<(...args: any[]) => any>;
stopPropagation: PropTypes.Requireable<boolean>;
searchPosition: PropTypes.Requireable<string>;
motion: PropTypes.Requireable<boolean>;
onChangeWithObject: PropTypes.Requireable<boolean>;
suffix: PropTypes.Requireable<PropTypes.ReactNodeLike>;
prefix: PropTypes.Requireable<PropTypes.ReactNodeLike>;
insetLabel: PropTypes.Requireable<PropTypes.ReactNodeLike>;
insetLabelId: PropTypes.Requireable<string>;
showClear: PropTypes.Requireable<boolean>;
showArrow: PropTypes.Requireable<boolean>;
renderSelectedItem: PropTypes.Requireable<(...args: any[]) => any>;
allowCreate: PropTypes.Requireable<boolean>;
renderCreateItem: PropTypes.Requireable<(...args: any[]) => any>;
onMouseEnter: PropTypes.Requireable<(...args: any[]) => any>;
onMouseLeave: PropTypes.Requireable<(...args: any[]) => any>;
clickToHide: PropTypes.Requireable<boolean>;
onExceed: PropTypes.Requireable<(...args: any[]) => any>;
onCreate: PropTypes.Requireable<(...args: any[]) => any>;
remote: PropTypes.Requireable<boolean>;
onDeselect: PropTypes.Requireable<(...args: any[]) => any>;
onSelect: PropTypes.Requireable<(...args: any[]) => any>;
autoAdjustOverflow: PropTypes.Requireable<boolean>;
mouseEnterDelay: PropTypes.Requireable<number>;
mouseLeaveDelay: PropTypes.Requireable<number>;
spacing: PropTypes.Requireable<NonNullable<number | object>>;
onBlur: PropTypes.Requireable<(...args: any[]) => any>;
onFocus: PropTypes.Requireable<(...args: any[]) => any>;
onClear: PropTypes.Requireable<(...args: any[]) => any>;
virtualize: PropTypes.Requireable<object>;
renderOptionItem: PropTypes.Requireable<(...args: any[]) => any>;
onListScroll: PropTypes.Requireable<(...args: any[]) => any>;
arrowIcon: PropTypes.Requireable<PropTypes.ReactNodeLike>;
preventScroll: PropTypes.Requireable<boolean>;
};
static __SemiComponentName__: string;
static defaultProps: Partial<SelectProps>;
inputRef: React.RefObject<HTMLInputElement>;
dropdownInputRef: React.RefObject<HTMLInputElement>;
triggerRef: React.RefObject<HTMLDivElement>;
optionContainerEl: React.RefObject<HTMLDivElement>;
optionsRef: React.RefObject<any>;
virtualizeListRef: React.RefObject<any>;
selectOptionListID: string;
selectID: string;
clickOutsideHandler: (e: MouseEvent) => void;
foundation: SelectFoundation;
context: ContextValue;
eventManager: Event;
constructor(props: SelectProps);
setOptionContainerEl: (node: HTMLDivElement) => {
current: HTMLDivElement;
};
get adapter(): SelectAdapter<SelectProps, SelectState>;
componentDidMount(): void;
componentWillUnmount(): void;
componentDidUpdate(prevProps: SelectProps, prevState: SelectState): void;
handleInputChange: (value: string, event: React.ChangeEvent<HTMLInputElement>) => void;
renderTriggerInput(): React.JSX.Element;
renderDropdownInput(): React.JSX.Element;
close(): void;
open(): void;
clearInput(): void;
selectAll(): void;
deselectAll(): void;
focus(): void;
onSelect(option: OptionProps, optionIndex: number, e: any): void;
onClear(e: React.MouseEvent): void;
search(value: string, event: React.ChangeEvent<HTMLInputElement>): void;
renderEmpty(): React.JSX.Element;
renderLoading(): React.JSX.Element;
renderOption(option: OptionProps, optionIndex: number, style?: React.CSSProperties): any;
renderCreateOption(option: OptionProps, isFocused: boolean, optionIndex: number, style: React.CSSProperties): React.JSX.Element;
onOptionHover(optionIndex: number): void;
renderWithGroup(visibleOptions: OptionProps[]): JSX.Element[];
renderVirtualizeList(visibleOptions: OptionProps[]): React.JSX.Element;
renderOptions(children?: React.ReactNode): React.JSX.Element;
renderSingleSelection(selections: Map<OptionProps['label'], any>, filterable: boolean): React.JSX.Element;
getTagItem: (item: any, i: number, renderSelectedItem: RenderSelectedItemFn) => React.JSX.Element;
renderTag(item: [React.ReactNode, any], i: number, isCollapseItem?: boolean): React.JSX.Element;
renderNTag(n: number, restTags: [React.ReactNode, any][]): React.JSX.Element;
renderOverflow(items: [React.ReactNode, any][], index: number): React.JSX.Element;
handleOverflow(items: [React.ReactNode, any][]): void;
renderCollapsedTags(selections: [React.ReactNode, any][], length: number | undefined): React.ReactElement;
renderOneLineTags(selectedItems: [React.ReactNode, any][], n: number | undefined): React.ReactElement;
renderMultipleSelection(selections: Map<OptionProps['label'], any>, filterable: boolean): React.JSX.Element;
onMouseEnter(e: MouseEvent): void;
onMouseLeave(e: MouseEvent): void;
onKeyPress(e: React.KeyboardEvent): void;
handlePopoverVisibleChange(status: any): void;
renderSuffix(): React.JSX.Element;
renderPrefix(): React.JSX.Element;
renderSelection(): React.JSX.Element;
render(): React.JSX.Element;
}
export default Select;