Styled virtualized list for large datasets, built on the @foldkit/ui VirtualList submodel.
Add this component to your project:
npx shadcn@latest add @foldcn/virtual-listThe component ships as plain source โ no build step, no wrapper. Copy it and make it yours.
registry/default/ui/virtual-list.ts43 linesimport { VirtualList as FoldkitVirtualList } from '@foldkit/ui'
import type { Html } from 'foldkit/html'
import { cn } from '@/lib/utils'
// Re-export the @foldkit/ui VirtualList submodel surface.
export const init = FoldkitVirtualList.init
export const update = FoldkitVirtualList.update
export const view = FoldkitVirtualList.view
export const Model = FoldkitVirtualList.Model
export type Model = typeof Model.Type
export const Message = FoldkitVirtualList.Message
export type Message = typeof Message.Type
export type InitConfig = FoldkitVirtualList.InitConfig
export type ViewInputs<Item> = FoldkitVirtualList.ViewInputs<Item>
export const virtualListContainerClass =
'h-96 w-full overflow-auto overscroll-none rounded-lg border border-border bg-card shadow-sm'
export const virtualListRowClass =
'grid grid-cols-[2rem_1fr_5rem] items-center gap-3 border-b border-border px-4 py-3'
export type StyledViewInputs<Item> = Readonly<{
items: ReadonlyArray<Item>
itemToKey: (item: Item, index: number) => string
itemToView: (item: Item, index: number) => Html
itemToRowHeightPx?: (item: Item, index: number) => number
overscan?: number
containerClass?: string
}>
/** Build styled `VirtualList.ViewInputs` with foldcn's container classes. */
export const styledViewInputs = <Item>(viewInputs: StyledViewInputs<Item>): ViewInputs<Item> => ({
items: viewInputs.items,
itemToKey: viewInputs.itemToKey,
itemToView: viewInputs.itemToView,
itemToRowHeightPx: viewInputs.itemToRowHeightPx,
overscan: viewInputs.overscan,
containerClassName: cn(virtualListContainerClass, viewInputs.containerClass),
})