import React, { useRef, useCallback, useState, useMemo } from 'react'; import { Button, useDisclosure, Box, Flex, useOutsideClick, Checkbox } from '@chakra-ui/react'; import { ListItemType, MultipleArraySelectProps, MultipleSelectProps } from './type'; import EmptyTip from '../EmptyTip'; import { useTranslation } from 'next-i18next'; import MyIcon from '../../common/Icon'; export const MultipleRowSelect = ({ placeholder, label, value = [], list, emptyTip, maxH = 300, onSelect, popDirection = 'bottom', styles }: MultipleSelectProps) => { const { t } = useTranslation(); const ref = useRef(null); const { isOpen, onOpen, onClose } = useDisclosure(); const [cloneValue, setCloneValue] = useState(value); useOutsideClick({ ref: ref, handler: onClose }); const RenderList = useCallback( ({ index, list }: { index: number; list: MultipleSelectProps['list'] }) => { const selectedValue = cloneValue[index]; const selectedIndex = list.findIndex((item) => item.value === selectedValue); const children = list[selectedIndex]?.children || []; const hasChildren = list.some((item) => item.children && item.children?.length > 0); return ( <> {list.map((item) => ( { const newValue = [...cloneValue]; if (item.value === selectedValue) { newValue[index] = undefined; setCloneValue(newValue); onSelect(newValue); } else { newValue[index] = item.value; setCloneValue(newValue); if (!hasChildren) { onSelect(newValue); onClose(); } } }} {...(item.value === selectedValue ? { color: 'primary.600' } : {})} > {item.label} ))} {list.length === 0 && ( )} {children.length > 0 && } ); }, [cloneValue] ); const onOpenSelect = useCallback(() => { setCloneValue(value); onOpen(); }, [value, onOpen]); return ( {isOpen && ( )} ); }; export const MultipleRowArraySelect = ({ placeholder, label, value = [], list, emptyTip, maxH = 300, onSelect, popDirection = 'bottom', styles }: MultipleArraySelectProps) => { const { t } = useTranslation(); const ref = useRef(null); const { isOpen, onOpen, onClose } = useDisclosure(); const [navigationPath, setNavigationPath] = useState([]); const formatValue = useMemo(() => { return Array.isArray(value) ? value : []; }, [value]); // Close when clicking outside useOutsideClick({ ref: ref, handler: onClose }); const RenderList = useCallback( ({ index, list }: { index: number; list: MultipleSelectProps['list'] }) => { const currentNavValue = navigationPath[index]; const selectedIndex = list.findIndex((item) => item.value === currentNavValue); const children = list[selectedIndex]?.children || []; const hasChildren = list.some((item) => item.children && item.children?.length > 0); const handleSelect = (item: ListItemType) => { // Has children, set parent value if (hasChildren) { const newPath = [...navigationPath]; newPath[index] = item.value; setNavigationPath(newPath); } else { const parentValue = navigationPath[0]; const newValues = [...formatValue]; const newValue = [parentValue, item.value]; if (newValues.some((v) => v[0] === parentValue && v[1] === item.value)) { onSelect(newValues.filter((v) => !(v[0] === parentValue && v[1] === item.value))); } else { onSelect([...newValues, newValue]); } } }; return ( <> {list.map((item) => { const isSelected = item.value === currentNavValue; const showCheckbox = !hasChildren; const isChecked = showCheckbox && formatValue.some((v) => v[1] === item.value && v[0] === navigationPath[0]); return ( handleSelect(item)} {...(isSelected ? { color: 'primary.600' } : {})} > {showCheckbox && } {item.label} ); })} {list.length === 0 && ( )} {children.length > 0 && } ); }, [navigationPath, formatValue, onSelect] ); const onOpenSelect = useCallback(() => { setNavigationPath([]); onOpen(); }, []); return ( {isOpen && ( )} ); }; export default React.memo(MultipleRowSelect);