export default function SelectOptionPopover(props: SelectOptionPopoverProps) { const { children, clearOptionClassname, clearOptionsPlaceholder = "Clear option", clearable, containerClassname, data, mode = "single", noOptionPlaceholder = "No option found", noOptionClassName, onOpenChange, onOptionChange, open, optionClassname, searchPlaceholder = "Search option...", searchIcon, setValue, value, } = props; const LIST_ITEM_HEIGHT = 36; const virtualizerRef = useRef(null); const virtualizer = useVirtualizer({ count: data.length, getScrollElement: () => virtualizerRef.current, estimateSize: () => LIST_ITEM_HEIGHT, overscan: 5, }); const virtualOptions = virtualizer.getVirtualItems(); console.log("virtualOptions:", virtualOptions); const handleCommandItemSelect = (currentValue: SelectOption) => { if (onOptionChange) onOptionChange(currentValue); setValue(currentValue); if (onOpenChange) onOpenChange(false); }; const handleCommandMultiItemSelect = (currentValue: SelectOption) => { let newOptionSelected: SelectOption[] | undefined = undefined; const isSelected = (value as SelectOption[])?.find((option) => option.value === currentValue.value); if (isSelected) { const filteredOptions = (value as SelectOption[])?.filter((option) => option.value !== currentValue.value); if (filteredOptions.length > 0) { newOptionSelected = filteredOptions; } } else { if (value) { newOptionSelected = [...(value as SelectOption[]), currentValue]; } else { newOptionSelected = [currentValue]; } } setValue(newOptionSelected); if (onOptionChange) onOptionChange(newOptionSelected); }; const handleClearOptions = () => { if (!clearable) return; setValue(undefined); if (onOptionChange) onOptionChange(undefined); if (onOpenChange) onOpenChange(false); }; return ( {children} {noOptionPlaceholder}
{virtualOptions.map((virtualOption) => { const option = data[virtualOption.index]; const selected = mode === "single" ? (value as SelectOption)?.value === option.value : !!(value as SelectOption[])?.find((filteredOption) => filteredOption.value === option.value); return ( mode === "single" ? handleCommandItemSelect(option) : handleCommandMultiItemSelect(option) } style={{ position: "absolute", top: 0, left: 0, width: "100%", height: virtualOption.size, transform: `translateY(${virtualOption.start}px)`, }} className={cn( "flex gap-2 text-base", selected && "text-primary data-[selected=true]:text-primary", optionClassname, )} > {mode === "single" ? ( ) : ( )}
{option.label}
); })}
{clearable && ( {clearOptionsPlaceholder} )}
);