feat: select弹框本地搜索支持自定义过滤函数

This commit is contained in:
ranqirong 2023-05-16 11:41:21 +08:00
parent be640ac18a
commit fe472304fd
2 changed files with 51 additions and 9 deletions

View File

@ -16,7 +16,6 @@ import {PopOver} from 'amis-core';
import TooltipWrapper from './TooltipWrapper';
import Downshift, {ControllerStateAndHelpers} from 'downshift';
import {closeIcon, Icon} from './icons';
// @ts-ignore
import {matchSorter} from 'match-sorter';
import {
noop,
@ -47,6 +46,15 @@ import type {TooltipObject} from '../components/TooltipWrapper';
export {Option, Options};
export const defaultFilterOption = (
options: Option[],
inputValue: string,
option: {keys: string[]},
matchFn = matchSorter
): Option[] => matchFn(options, inputValue, option);
export type FilterOption = typeof defaultFilterOption;
export interface OptionProps {
className?: string;
multi?: boolean;
@ -375,6 +383,11 @@ interface SelectProps
* Popover配置
*/
overflowTagPopover?: TooltipObject;
/**
*
*/
filterOption?: FilterOption;
}
interface SelectState {
@ -573,15 +586,22 @@ export class Select extends React.Component<SelectProps, SelectState> {
simpleValue,
checkAllBySearch,
labelField,
valueField
valueField,
filterOption = defaultFilterOption
} = this.props;
const inputValue = this.state.inputValue;
let {selection} = this.state;
let filtedOptions: Array<Option> =
inputValue && checkAllBySearch !== false
? matchSorter(options, inputValue, {
keys: [labelField || 'label', valueField || 'value']
})
? filterOption(
options,
inputValue,
{
keys: [labelField || 'label', valueField || 'value']
},
matchSorter
)
: options.concat();
const optionsValues = filtedOptions.map(option => option.value);
const selectionValues = selection.map(select => select.value);
@ -973,6 +993,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
mobileClassName,
virtualThreshold = 100,
useMobileUI = false,
filterOption = defaultFilterOption,
overlay
} = this.props;
const {selection} = this.state;
@ -981,9 +1002,14 @@ export class Select extends React.Component<SelectProps, SelectState> {
let checkedPartial = false;
let filtedOptions: Array<Option> = (
inputValue && isOpen && !loadOptions
? matchSorter(options, inputValue, {
keys: [labelField || 'label', valueField || 'value']
})
? filterOption(
options,
inputValue,
{
keys: [labelField || 'label', valueField || 'value']
},
matchSorter
)
: options.concat()
).filter((option: Option) => !option.hidden && option.visible !== false);
const enableVirtualRender =

View File

@ -5,7 +5,8 @@ import {
OptionsControlProps,
Option,
FormOptionsControl,
resolveEventData
resolveEventData,
str2function
} from 'amis-core';
import {normalizeOptions} from 'amis-core';
import find from 'lodash/find';
@ -23,6 +24,7 @@ import type {SchemaClassName} from '../../Schema';
import type {TooltipObject} from 'amis-ui/lib/components/TooltipWrapper';
import type {PopOverOverlay} from 'amis-ui/lib/components/PopOverContainer';
import {supportStatic} from './StaticHoc';
import type {FilterOption} from 'amis-ui/src/components/Select';
/**
* Select
@ -149,6 +151,8 @@ export interface SelectControlSchema
* Popover
*/
align?: 'left' | 'center' | 'right';
filterOption?: 'string' | FilterOption;
};
}
@ -460,6 +464,7 @@ export default class SelectControl extends React.Component<SelectProps, any> {
env,
useMobileUI,
overlay,
filterOption,
...rest
} = this.props;
@ -492,6 +497,17 @@ export default class SelectControl extends React.Component<SelectProps, any> {
ref={this.inputRef}
value={selectedOptions}
options={options}
filterOption={
typeof filterOption === 'string'
? str2function(
filterOption,
'options',
'inputValue',
'option',
'matchFn'
)
: filterOption
}
loadOptions={
isEffectiveApi(autoComplete) ? this.lazyloadRemote : undefined
}