feat: 移动端单选select支持搜索

This commit is contained in:
zhangtao07 2024-04-01 15:19:48 +08:00
parent d1dd59cc8a
commit 433806957b
3 changed files with 54 additions and 41 deletions

View File

@ -23,6 +23,7 @@ export interface PickerProps extends ThemeProps, LocaleProps {
value?: PickerValue[];
swipeDuration?: number;
visibleItemCount?: number;
highlightTxt?: string;
itemHeight?: number;
columns: PickerColumnItem[] | PickerColumnItem;
onChange?: (value?: PickerValue[], index?: number, confirm?: boolean) => void;
@ -49,6 +50,7 @@ const Picker = memo<PickerProps>(props => {
itemHeight = 48,
showToolbar = true,
className = '',
highlightTxt = '',
classnames: cx,
classPrefix: ns,
translate: __
@ -93,6 +95,7 @@ const Picker = memo<PickerProps>(props => {
return (
<Column
{...item}
highlightTxt={highlightTxt}
classnames={cx}
classPrefix={ns}
labelField={labelField || item.labelField}

View File

@ -12,7 +12,7 @@ import React, {
} from 'react';
import isObject from 'lodash/isObject';
import cloneDeep from 'lodash/cloneDeep';
import {uncontrollable} from 'amis-core';
import {uncontrollable, highlight} from 'amis-core';
import {useSetState, useUpdateEffect} from '../hooks';
import {range} from 'amis-core';
@ -28,6 +28,7 @@ export interface PickerColumnItem {
visibleItemCount?: number;
itemHeight?: number;
options?: PickerOption[];
highlightTxt?: string;
optionRender?: (...params: any) => React.ReactNode;
onChange?: (
value?: PickerOption | string,
@ -74,6 +75,7 @@ const PickerColumn = forwardRef<{}, PickerColumnProps>((props, ref) => {
valueField = 'value',
swipeDuration = 1000,
labelField = 'text',
highlightTxt = '',
options = [],
classnames: cx
} = props;
@ -294,7 +296,7 @@ const PickerColumn = forwardRef<{}, PickerColumnProps>((props, ref) => {
lineHeight: `${itemHeight}px`
};
return state.options.map((option, index: number) => {
const text: string | PickerOption = getOptionText(option);
const text: string = getOptionText(option);
const disabled = isOptionDisabled(option);
const data = {
@ -313,7 +315,9 @@ const PickerColumn = forwardRef<{}, PickerColumnProps>((props, ref) => {
const childData = {
className: 'text-ellipsis',
children: text as React.ReactNode
children: (highlightTxt
? highlight(text, highlightTxt, cx('Select-option-hl'))
: text) as React.ReactNode
};
return (

View File

@ -420,6 +420,31 @@ export default class SelectMobile extends React.Component<Props, SelectState> {
);
};
const searchInput = (
<div
className={cx(`Select-input`, {
'is-focused': this.state.isFocused
})}
>
<Icon icon="search" className="icon" />
<Input
{...getInputProps({
onFocus: this.onFocus,
onBlur: this.onBlur,
disabled: disabled,
placeholder: __(searchPromptText),
onChange: this.handleInputChange,
ref: this.inputRef
})}
/>
{inputValue?.length ? (
<a onClick={this.clearSearchValue} className={cx('Select-clear')}>
<Icon icon="close" className="icon" />
</a>
) : null}
</div>
);
const menu = (
<div
className={cx('Select-menu', {
@ -427,30 +452,7 @@ export default class SelectMobile extends React.Component<Props, SelectState> {
'is-mobile': true
})}
>
{searchable ? (
<div
className={cx(`Select-input`, {
'is-focused': this.state.isFocused
})}
>
<Icon icon="search" className="icon" />
<Input
{...getInputProps({
onFocus: this.onFocus,
onBlur: this.onBlur,
disabled: disabled,
placeholder: __(searchPromptText),
onChange: this.handleInputChange,
ref: this.inputRef
})}
/>
{inputValue?.length ? (
<a onClick={this.clearSearchValue} className={cx('Select-clear')}>
<Icon icon="close" className="icon" />
</a>
) : null}
</div>
) : null}
{searchable ? searchInput : null}
{multiple && valuesNoWrap ? (
<div className={cx('Select-option')}>
({selectionValues.length})
@ -504,20 +506,24 @@ export default class SelectMobile extends React.Component<Props, SelectState> {
{multiple ? (
menu
) : (
<Picker
className={'Select-picker'}
columns={{
options: filtedOptions as Option[],
optionRender: renderMenu
}}
onChange={item => this.handleChange(item as any)}
showToolbar={false}
labelField={labelField}
valueField={valueField}
itemHeight={40}
visibleItemCount={visibleItemCount}
value={[selection[0]?.[valueField]]}
/>
<div className={cx(`Select-popup-inner`)}>
{searchable ? searchInput : null}
<Picker
className={'Select-picker'}
columns={{
options: filtedOptions as Option[],
optionRender: renderMenu
}}
highlightTxt={inputValue}
onChange={item => this.handleChange(item as any)}
showToolbar={false}
labelField={labelField}
valueField={valueField}
itemHeight={40}
visibleItemCount={visibleItemCount}
value={[selection[0]?.[valueField]]}
/>
</div>
)}
</PopUp>
);