React + Antd + Ts Customize the Select selection box to select all functions (two different styles)

React + Antd + Ts Customize the Select selection box to select all functions (two different styles)

  • The first default style

Insert image description here

import React from 'react';
import {
    
     Select, Checkbox } from 'antd';

const {
    
     Option } = Select;

interface Option {
    
    
  label: string;
  value: string;
}

interface SelectProps {
    
    
  options: Option[];
}

const SelectWithCheckbox: React.FC<SelectProps> = ({
     
      options }) => {
    
    
  const [selectedValues, setSelectedValues] = React.useState<string[]>([]);

  const handleSelectChange = (values: string[]) => {
    
    
    setSelectedValues(values);
  };

  return (
    <Select
      style={
    
    {
    
     width: 400 }}
      mode="multiple"
      onChange={
    
    handleSelectChange}
      maxTagCount={
    
    3}
      value={
    
    selectedValues}
      dropdownRender={
    
    (menu) => (
        <div>
          <div onClick={
    
    (e) => e.stopPropagation()}>
        	//  因为option.value可能为undefined,但是这里不允许undefined,所以加!
            <a
              onClick={
    
    () =>
                handleSelectChange(options.map((option) => option.value!))
              }
              style={
    
    {
    
     display: 'block', margin: '10px 10px' }}
            >
              选择所有
            </a>
          </div>
          {
    
    menu}
        </div>
      )}
    >
      {
    
    options.map((option) => (
        <Option key={
    
    option.value} value={
    
    option.value}>
          {
    
    option.label}
        </Option>
      ))}
    </Select>
  );
};

export default SelectWithCheckbox;

  • The second type of selection box with checkbox (with search)
    Insert image description here

    import React , {
          
          useState} from 'react';
    import {
          
           Select, Checkbox,Empty } from 'antd';
    import './index.less';
    const {
          
           Option } = Select;
    interface Option {
          
          
      label: string;
      value: string;
    }
    
    interface SelectProps {
          
          
      options: Option[];
      style?: React.CSSProperties;
      placeholder?: string;
      onChange?: (values: string[]) => void;
    }
    
    const SelectWithCheckbox: React.FC<SelectProps> = ({
           
           
    	  options,
    	  style,
    	  placeholder,
    	  onChange,
    	}) => {
          
          
      const [selectedValues, setSelectedValues] = useState<string[]>([]);
      const [searchKeyword, setSearchKeyword] = useState('');
      const [isSearchEmpty, setIsSearchEmpty] = useState(false);
    
      const handleSelectChange = (values: string[]) => {
          
          
        setSelectedValues(values);
        searchKeyword && setSearchKeyword('');
        onChange && onChange(values);
      };
      const handleSearch = (value: string) => {
          
          
        setSearchKeyword(value);
        setIsSearchEmpty(
          options.filter((option) =>
            option.label.toLowerCase().includes(value.toLowerCase()),
          ).length === 0,
        );
      };
    
      const handleAllOptionSelect = (
        event: React.ChangeEvent<HTMLInputElement>,
      ) => {
          
          
        if (event.target.checked) {
          
          
          handleSelectChange(options.map((option) => option.value!));
        } else {
          
          
          handleSelectChange([]);
        }
      };
    
      const isAllOptionSelected = () => {
          
          
        const selectedOptions = options
          .filter(
            (option) =>
              option.value !== undefined &&
              option.value !== null &&
              option.value !== '',
          )
          .map((option) => option.value!);
        return (
          selectedOptions.length > 0 &&
          selectedOptions.every((value) => selectedValues.indexOf(value) !== -1)
        );
      };
    
      return (
        <Select
          style={
          
          {
          
           width: '100%', ...style }}
          placeholder={
          
          placeholder}
          className="select-with-checkbox"
          mode="multiple"
          onChange={
          
          handleSelectChange}
          value={
          
          selectedValues}
          onSearch={
          
          (value) => handleSearch(value)}
          maxTagCount={
          
          3}
          getPopupContainer={
          
          (triggerNode) => triggerNode.parentNode}
          maxTagPlaceholder={
          
          (omittedValues) => `+ ${
            
            omittedValues.length}`}
          dropdownRender={
          
          (menu) => (
            <div className="my-select-wrapper">
              {
          
          !searchKeyword && (
                <div onClick={
          
          (e) => e.stopPropagation()} className="my-menu-all">
                  <Checkbox
                    checked={
          
          isAllOptionSelected()}
                    onChange={
          
          handleAllOptionSelect as any}
                    style={
          
          {
          
           width: '100%', padding: '5px 20px' }}
                  >
                    全部
                  </Checkbox>
                </div>
              )}
              {
          
          isSearchEmpty ? (
                <div className="my-empty">
                  <Empty image={
          
          Empty.PRESENTED_IMAGE_SIMPLE} />
                </div>
              ) : (
                options
                  .filter((option) =>
                    option.label
                      .toLowerCase()
                      .includes(searchKeyword.toLowerCase()),
                  )
                  .map((option) => (
                    <div
                      key={
          
          option.value}
                      onClick={
          
          (e) => e.stopPropagation()}
                      className="my-menu-item"
                    >
                      <Checkbox
                        checked={
          
          selectedValues.indexOf(option.value) !== -1}
                        onChange={
          
          (e) => {
          
          
                          const nextSelectedValues = e.target.checked
                            ? [...selectedValues, option.value]
                            : selectedValues.filter(
                                (value) => value !== option.value,
                              );
                          handleSelectChange(nextSelectedValues);
                        }}
                        style={
          
          {
          
           width: '100%', padding: '5px 20px' }}
                      >
                        {
          
          option.label}
                      </Checkbox>
                    </div>
                  ))
              )}
            </div>
          )}
        >
          {
          
          options.map((option) => (
            <Option key={
          
          option.value} value={
          
          option.value}>
              {
          
          option.label}
            </Option>
          ))}
        </Select>
      );
    };
    
    export default SelectWithCheckbox;
    

    index.less style file

    .select-with-checkbox {
          
          
      .ant-select-selector {
          
          
        height: 36px;
        border: 1px solid #ebebeb !important;
        border-radius: 6px !important;
        .ant-select-selection-item {
          
          
          height: 25px;
          background: #f2f9ff;
          border-radius: 4px 4px 4px 4px;
          border: 1px solid #a0d1ff;
          .ant-select-selection-item-content {
          
          
            display: flex;
            align-items: center;
            color: #1f91fc;
          }
          .ant-select-selection-item-remove {
          
          
            font-size: 12px;
            &:hover {
          
          
              color: #1e91fe;
            }
          }
        }
      }
    }
    .my-select-wrapper {
          
          
      max-height: 320px;
      overflow-y: auto;
    }
    .my-menu-all {
          
          
      cursor: pointer;
      &:hover {
          
          
        font-weight: 600;
        background-color: #f5f5f5;
      }
      .ant-checkbox-wrapper-checked {
          
          
        font-weight: 600;
        background-color: #e6f7ff;
      }
    }
    .my-menu-item {
          
          
      cursor: pointer;
      &:hover {
          
          
        font-weight: 600;
        background-color: #f5f5f5;
      }
      .ant-checkbox-wrapper-checked {
          
          
        font-weight: 600;
        background-color: #e6f7ff;
      }
    }
    
    

Guess you like

Origin blog.csdn.net/qq_41620887/article/details/129985339