From 01ed4acce23c8a8ac3703e22fb0470738d97fa06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl-Gerhard=20Lindesva=CC=88rd?= Date: Fri, 12 Jul 2024 00:01:31 +0200 Subject: [PATCH] add virtual list for combobox --- apps/dashboard/package.json | 1 + .../src/components/ui/combobox-advanced.tsx | 53 +++++++++++-------- apps/dashboard/src/components/ui/combobox.tsx | 53 ++++++++++--------- pnpm-lock.yaml | 52 ++++++++++++++++++ 4 files changed, 113 insertions(+), 46 deletions(-) diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 2781fbb3..d002a0fb 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -81,6 +81,7 @@ "pushmodal": "^1.0.3", "ramda": "^0.29.1", "random-animal-name": "^0.1.1", + "rc-virtual-list": "^3.14.5", "react": "18.2.0", "react-animate-height": "^3.2.3", "react-animated-numbers": "^0.18.0", diff --git a/apps/dashboard/src/components/ui/combobox-advanced.tsx b/apps/dashboard/src/components/ui/combobox-advanced.tsx index 11905048..0c791421 100644 --- a/apps/dashboard/src/components/ui/combobox-advanced.tsx +++ b/apps/dashboard/src/components/ui/combobox-advanced.tsx @@ -1,13 +1,9 @@ import * as React from 'react'; import { Badge } from '@/components/ui/badge'; -import { - Command, - CommandGroup, - CommandInput, - CommandItem, - CommandList, -} from '@/components/ui/command'; +import { Command, CommandInput, CommandItem } from '@/components/ui/command'; +import { cn } from '@/utils/cn'; import { ChevronsUpDownIcon } from 'lucide-react'; +import VirtualList from 'rc-virtual-list'; import { useOnClickOutside } from 'usehooks-ts'; import { Button } from './button'; @@ -71,10 +67,31 @@ export function ComboboxAdvanced({ ); }; - const renderUnknownItem = (value: IValue) => { - const item = items.find((item) => item.value === value); - return item ? renderItem(item) : renderItem({ value, label: value }); - }; + const data = React.useMemo(() => { + return [ + ...(inputValue === '' + ? [] + : [ + { + value: inputValue, + label: `Pick '${inputValue}'`, + }, + ]), + ...value.map((val) => { + const item = items.find((item) => item.value === val); + return item + ? { + value: val, + label: item.label, + } + : { + value: val, + label: val, + }; + }), + ...selectables, + ].filter((item) => item.value); + }, [inputValue, selectables, items]); return ( @@ -82,7 +99,7 @@ export function ComboboxAdvanced({