import { Box, ButtonProps, Checkbox, Flex, Menu, MenuButton, MenuItem, MenuItemProps, MenuList, useDisclosure } from '@chakra-ui/react'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import MyTag from '../Tag/index'; import MyIcon from '../Icon'; import MyAvatar from '../Avatar'; import { useTranslation } from 'next-i18next'; import { useScrollPagination } from '../../../hooks/useScrollPagination'; import MyDivider from '../MyDivider'; export type SelectProps = { list: { icon?: string; label: string | React.ReactNode; value: T; }[]; value: T[]; isSelectAll: boolean; setIsSelectAll: React.Dispatch>; placeholder?: string; maxH?: number; itemWrap?: boolean; onSelect: (val: T[]) => void; closeable?: boolean; ScrollData?: ReturnType['ScrollData']; } & Omit; const MultipleSelect = ({ value = [], placeholder, list = [], maxH = 400, onSelect, closeable = false, itemWrap = true, ScrollData, isSelectAll, setIsSelectAll, ...props }: SelectProps) => { const ref = useRef(null); const { t } = useTranslation(); const { isOpen, onOpen, onClose } = useDisclosure(); const menuItemStyles: MenuItemProps = { borderRadius: 'sm', py: 2, display: 'flex', alignItems: 'center', _hover: { backgroundColor: 'myGray.100' }, _notLast: { mb: 2 } }; const onclickItem = useCallback( (val: T) => { // 全选状态下,value 实际上上空。 if (isSelectAll) { onSelect(list.map((item) => item.value).filter((i) => i !== val)); setIsSelectAll(false); return; } if (value.includes(val)) { onSelect(value.filter((i) => i !== val)); } else { onSelect([...value, val]); } }, [value, isSelectAll, onSelect, setIsSelectAll] ); const onSelectAll = useCallback(() => { const hasSelected = isSelectAll || value.length > 0; onSelect(hasSelected ? [] : list.map((item) => item.value)); setIsSelectAll((state) => !state); }, [value, list, setIsSelectAll, onSelect]); const ListRender = useMemo(() => { return ( <> {list.map((item, i) => { const isSelected = isSelectAll || value.includes(item.value); return ( { e.stopPropagation(); e.preventDefault(); onclickItem(item.value); }} whiteSpace={'pre-wrap'} fontSize={'sm'} gap={2} > {item.icon && } {item.label} ); })} ); }, [value, list, isSelectAll]); return ( {value.length === 0 && placeholder ? ( {placeholder} ) : ( {isSelectAll ? ( {t('common:common.All')} ) : ( list .filter((item) => value.includes(item.value)) .map((item, i) => ( {item.label} {closeable && ( { e.stopPropagation(); onclickItem(item.value); }} /> )} )) )} )} { e.stopPropagation(); e.preventDefault(); onSelectAll(); }} whiteSpace={'pre-wrap'} fontSize={'sm'} gap={2} mb={1} > {t('common:common.All')} {ScrollData ? {ListRender} : ListRender} ); }; export default MultipleSelect; export const useMultipleSelect = (defaultValue: T[] = [], defaultSelectAll = false) => { const [value, setValue] = useState(defaultValue); const [isSelectAll, setIsSelectAll] = useState(defaultSelectAll); return { value, setValue, isSelectAll, setIsSelectAll }; };