diff --git a/src/Select.tsx b/src/Select.tsx index f278d6c3..97617329 100644 --- a/src/Select.tsx +++ b/src/Select.tsx @@ -56,6 +56,7 @@ import type { FlattenOptionData } from './interface'; import { hasValue, isComboNoValue, toArray } from './utils/commonUtil'; import { fillFieldNames, flattenOptions, injectPropsWithOption } from './utils/valueUtil'; import warningProps, { warningNullOptions } from './utils/warningPropsUtil'; +import useSearchConfig from './hooks/useSearchConfig'; const OMIT_DOM_PROPS = ['inputValue']; @@ -110,8 +111,18 @@ type ArrayElementType = T extends (infer E)[] ? E : T; export type SemanticName = BaseSelectSemanticName; export type PopupSemantic = 'listItem' | 'list'; +export interface SearchConfig { + searchValue?: string; + autoClearSearchValue?: boolean; + onSearch?: (value: string) => void; + tokenSeparators?: string[]; + filterOption?: boolean | FilterFunc; + filterSort?: (optionA: OptionType, optionB: OptionType, info: { searchValue: string }) => number; + optionFilterProp?: string; + optionLabelProp?: string; +} export interface SelectProps - extends BaseSelectPropsWithoutPrivate { + extends Omit { prefixCls?: string; id?: string; @@ -119,25 +130,33 @@ export interface SelectProps>> Field Names fieldNames?: FieldNames; - - searchValue?: string; - onSearch?: (value: string) => void; + showSearch?: boolean | SearchConfig; + /** @deprecated pleace use SearchConfig.searchValue */ + searchValue?: SearchConfig['searchValue']; + /** @deprecated pleace use SearchConfig.autoClearSearchValue */ autoClearSearchValue?: boolean; - - // >>> Select - onSelect?: SelectHandler, OptionType>; - onDeselect?: SelectHandler, OptionType>; - + /** @deprecated pleace use SearchConfig.onSearch */ + onSearch?: SearchConfig['onSearch']; + /** @deprecated pleace use SearchConfig.tokenSeparators */ + tokenSeparators?: string[]; // >>> Options /** * In Select, `false` means do nothing. * In TreeSelect, `false` will highlight match item. * It's by design. */ - filterOption?: boolean | FilterFunc; - filterSort?: (optionA: OptionType, optionB: OptionType, info: { searchValue: string }) => number; + /** @deprecated pleace use SearchConfig.filterOption */ + filterOption?: SearchConfig['filterOption']; + /** @deprecated pleace use SearchConfig.filterSort */ + filterSort?: SearchConfig['filterSort']; + /** @deprecated pleace use SearchConfig.optionFilterProp */ optionFilterProp?: string; + /** @deprecated pleace use SearchConfig.optionLabelProp */ optionLabelProp?: string; + // >>> Select + onSelect?: SelectHandler, OptionType>; + onDeselect?: SelectHandler, OptionType>; + children?: React.ReactNode; options?: OptionType[]; optionRender?: ( @@ -176,22 +195,12 @@ const Select = React.forwardRef>> Trigger direction={direction} // >>> Search + showSearch={mergedShowSearch} searchValue={mergedSearchValue} onSearch={onInternalSearch} autoClearSearchValue={autoClearSearchValue} onSearchSplit={onInternalSearchSplit} + tokenSeparators={tokenSeparators} popupMatchSelectWidth={popupMatchSelectWidth} // >>> OptionList OptionList={OptionList} diff --git a/src/hooks/useSearchConfig.ts b/src/hooks/useSearchConfig.ts new file mode 100644 index 00000000..ec36b3a0 --- /dev/null +++ b/src/hooks/useSearchConfig.ts @@ -0,0 +1,40 @@ +import type { SearchConfig, DefaultOptionType } from '@/Select'; +import * as React from 'react'; +const legacySearchProps = [ + 'filterOption', + 'searchValue', + 'optionFilterProp', + 'optionLabelProp', + 'filterSort', + 'onSearch', + 'autoClearSearchValue', + 'tokenSeparators', +]; +// Convert `showSearch` to unique config +export default function useSearchConfig(showSearch, props) { + return React.useMemo<[boolean, SearchConfig]>(() => { + const legacyShowSearch: SearchConfig = {}; + legacySearchProps.forEach((propsName) => { + legacyShowSearch[propsName] = props?.[propsName]; + }); + const searchConfig: SearchConfig = + typeof showSearch === 'object' ? showSearch : legacyShowSearch; + if (showSearch === undefined) { + return [undefined, searchConfig]; + } + if (!showSearch) { + return [false, {}]; + } + return [true, searchConfig]; + }, [ + showSearch, + props?.filterOption, + props?.searchValue, + props?.optionFilterProp, + props?.optionLabelProp, + props?.filterSort, + props?.onSearch, + props?.autoClearSearchValue, + props?.tokenSeparators, + ]); +}