import React, { useRef } from 'react'; import { Select, SelectArrow, SelectItem, SelectItemCheck, SelectLabel, SelectPopover, SelectProvider, } from '@ariakit/react'; import { cn } from '~/utils'; interface MultiSelectProps { items: T[]; label?: string; placeholder?: string; onSelectedValuesChange?: (values: T[]) => void; renderSelectedValues?: (values: T[], placeholder?: string) => React.ReactNode; className?: string; itemClassName?: string; labelClassName?: string; selectClassName?: string; selectIcon?: React.ReactNode; popoverClassName?: string; selectItemsClassName?: string; selectedValues: T[]; setSelectedValues: (values: T[]) => void; renderItemContent?: ( value: T, defaultContent: React.ReactNode, isSelected: boolean, ) => React.ReactNode; } function defaultRender(values: T[], placeholder?: string) { if (values.length === 0) { return placeholder || 'Select...'; } if (values.length === 1) { return values[0]; } return `${values.length} items selected`; } export default function MultiSelect({ items, label, placeholder = 'Select...', onSelectedValuesChange, renderSelectedValues = defaultRender, className, selectIcon, itemClassName, labelClassName, selectClassName, popoverClassName, selectItemsClassName, selectedValues = [], setSelectedValues, renderItemContent, }: MultiSelectProps) { const selectRef = useRef(null); const handleValueChange = (values: T[]) => { setSelectedValues(values); if (onSelectedValuesChange) { onSelectedValuesChange(values); } }; return (
{label && ( {label} )} {items.map((value) => { const defaultContent = ( <> {value} ); const isCurrentItemSelected = selectedValues.includes(value); return ( {renderItemContent ? (renderItemContent( value, defaultContent, isCurrentItemSelected, ) as React.JSX.Element) : (defaultContent as React.JSX.Element)} ); })}
); }