searchPicker.jsx 2.7 KB
import { Popup, SearchBar, PickerView, Button } from 'antd-mobile';
import { List,} from 'antd-mobile-v2';
import { useState, useMemo } from 'react';
import styles from "./selectInput.less";
export default function SearchablePicker(props) {
  const {  onConfirm, initialValue, data, sTitle, onChange, value:newValue } = props;

  const [searchValue, setSearchValue] = useState('');
  const [visible, setVisible] = useState(false)

  // 安全初始化 values
  const initialVal = useMemo(() => {
    if (!initialValue || !Array.isArray(data)) return [];
    const exists = data.some(item => item?.value === initialValue);
    return exists ? [initialValue] : [];
  }, [initialValue, data]);

  const [values, setValues] = useState(initialVal);

  // 安全过滤选项
  const filteredOptions = useMemo(() => {
    const options = Array.isArray(data) ? data : [];

    if (!searchValue.trim()) {
      return options;
    }

    return options.filter(item =>
      item &&
      typeof item.label === 'string' &&
      item.label.toLowerCase().includes(searchValue.toLowerCase())
    );
  }, [searchValue, data]); // ✅ 必须包含 data
  const label = filteredOptions?.find(x=>x.value === newValue[0])?.label || ''
  const handleConfirm = () => {
    onChange(values);
    setVisible(false);
  };

  const handleCancel = () => {
    setVisible(false);
  };

  const changeOption = (val) => {
    setValues(val);
  };

  return (
    <div>
      <List.Item arrow="horizontal" className={styles.searchPickerList} onClick={() => {
        setVisible(true)
      }} extra={label}>
        {props.iconSettingShow ?
          // eslint-disable-next-line jsx-a11y/alt-text
          <img src={iconSetting} style={{ verticalAlign: 'sub', marginRight: '15px' }} alt="" /> : ''}
        {sTitle}
      </List.Item>
      <Popup
        visible={visible}
        onMaskClick={handleCancel}
        onClose={handleCancel}
        bodyStyle={{ height: '50vh' }}
      >
        <div style={{ display: 'flex', justifyContent: 'space-between', padding: '0 1.5rem', marginTop: '1rem' }}>
          <Button onClick={handleCancel} color="primary" fill="none">
            取消
          </Button>
          <Button onClick={handleConfirm} color="primary" fill="none">
            确认
          </Button>
        </div>

        <div style={{ padding: '0 1.5rem', marginTop: '1rem' }}>
          <SearchBar
            placeholder="请输入内容"
            value={searchValue}
            onChange={setSearchValue}
          />
        </div>

        <PickerView
          columns={[filteredOptions]}
          value={values}
          onChange={changeOption}
          style={{ '--height': '200px', '--item-height': '2.8rem' }}
        />
      </Popup>
    </div>

  );
}