'use client'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { ChevronLeftIcon, ChevronRightIcon, SquareCheckIcon, SquareIcon, } from 'lucide-react'; import React, { ReactNode, memo, useCallback, useEffect } from 'react'; export type TransferListItemType = { key: string; label: string; selected?: boolean; disabled?: boolean; }; export enum TransferListMoveDirection { Left = 'left', Right = 'right', } export type TransferListProps = { items: TransferListItemType[]; targetKeys?: string[]; onChange?( targetKeys: string[], direction: TransferListMoveDirection, moveKeys: string[], ): void; } & { children?(item: TransferListItemType): ReactNode; }; export const TransferList = memo(function ({ items, onChange, targetKeys, children, }: TransferListProps) { const [leftList, setLeftList] = React.useState([]); const [rightList, setRightList] = React.useState([]); const [leftSearch, setLeftSearch] = React.useState(''); const [rightSearch, setRightSearch] = React.useState(''); const moveToRight = useCallback(() => { const selectedItems = leftList.filter((item) => item.selected); const rightItems = [...rightList, ...selectedItems]; setRightList(rightItems); setLeftList(leftList.filter((item) => !item.selected)); onChange?.( rightItems.map((x) => x.key), TransferListMoveDirection.Right, selectedItems.map((x) => x.key), ); }, [leftList, onChange, rightList]); const moveToLeft = useCallback(() => { const selectedItems = rightList.filter((item) => item.selected); setLeftList((list) => [...list, ...selectedItems]); const rightItems = rightList.filter((item) => !item.selected); setRightList(rightItems); onChange?.( rightItems.map((x) => x.key), TransferListMoveDirection.Left, selectedItems.map((x) => x.key), ); }, [onChange, rightList]); const toggleSelection = useCallback( ( list: TransferListItemType[], setList: React.Dispatch>, key: string, ) => { const updatedList = list.map((item) => { if (item.key === key) { return { ...item, selected: !item.selected }; } return item; }); setList(updatedList); }, [], ); useEffect(() => { const leftItems = items.filter( (x) => !targetKeys?.some((y) => y === x.key), ); setLeftList(leftItems); const rightItems = items.filter((x) => targetKeys?.some((y) => y === x.key), ); setRightList(rightItems); }, [items, targetKeys]); return (
setLeftSearch(e.target.value)} />
    {leftList .filter((item) => item.label.toLowerCase().includes(leftSearch.toLowerCase()), ) .map((item) => (
  • ))}
setRightSearch(e.target.value)} />
    {rightList .filter((item) => item.label.toLowerCase().includes(rightSearch.toLowerCase()), ) .map((item) => (
  • {children?.(item)}
  • ))}
); }); TransferList.displayName = 'TransferList';