{
  "name": "combobox-virtualized-demo",
  "type": "registry:example",
  "dependencies": [
    "@tanstack/react-virtual",
    "lucide-react"
  ],
  "registryDependencies": [
    "combobox"
  ],
  "files": [
    {
      "path": "examples/combobox-virtualized-demo.tsx",
      "type": "registry:example",
      "content": "\"use client\";\n\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { ChevronDown } from \"lucide-react\";\nimport * as React from \"react\";\nimport { useDeferredValue } from \"react\";\n\nimport {\n  Combobox,\n  ComboboxAnchor,\n  ComboboxContent,\n  ComboboxEmpty,\n  ComboboxInput,\n  ComboboxItem,\n  ComboboxLabel,\n  ComboboxTrigger,\n} from \"@/registry/bases/radix/ui/combobox\";\n\ninterface Option {\n  label: string;\n  value: string;\n}\n\nconst categories = [\n  \"Flip\",\n  \"Grind\",\n  \"Slide\",\n  \"Grab\",\n  \"Manual\",\n  \"Transition\",\n  \"Old School\",\n] as const;\n\nconst variations = [\n  \"Regular\",\n  \"Switch\",\n  \"Nollie\",\n  \"Fakie\",\n  \"360\",\n  \"Double\",\n  \"Late\",\n] as const;\n\ntype Category = (typeof categories)[number];\ntype Variation = (typeof variations)[number];\n\nconst generateItems = (count: number): Option[] => {\n  return Array.from({ length: count }, (_, i) => {\n    const category: Category = categories[i % categories.length] ?? \"Flip\";\n    const variation: Variation = variations[i % variations.length] ?? \"Regular\";\n    const trickNumber = Math.floor(i / categories.length) + 1;\n\n    return {\n      label: `${variation} ${category} ${trickNumber}`,\n      value: `trick-${i + 1}`,\n    };\n  });\n};\n\nconst items = generateItems(10000);\n\nexport default function ComboboxVirtualizedDemo() {\n  const [content, setContent] =\n    React.useState<React.ComponentRef<\"div\"> | null>(null);\n  const [value, setValue] = React.useState(\"\");\n  const [inputValue, setInputValue] = React.useState(\"\");\n  const deferredInputValue = useDeferredValue(inputValue);\n\n  const filteredTricks = React.useMemo(() => {\n    if (!deferredInputValue) return items;\n    const normalized = deferredInputValue.toLowerCase();\n    return items.filter((item) =>\n      item.label.toLowerCase().includes(normalized),\n    );\n  }, [deferredInputValue]);\n\n  const virtualizer = useVirtualizer({\n    count: filteredTricks.length,\n    getScrollElement: () => content,\n    estimateSize: () => 32,\n    overscan: 20,\n  });\n\n  const onInputValueChange = React.useCallback(\n    (value: string) => {\n      setInputValue(value);\n      if (content) {\n        content.scrollTop = 0; // Reset scroll position\n        virtualizer.measure();\n      }\n    },\n    [content, virtualizer],\n  );\n\n  // Re-measure virtualizer when filteredItems changes\n  React.useEffect(() => {\n    if (content) {\n      virtualizer.measure();\n    }\n  }, [content, virtualizer]);\n\n  return (\n    <Combobox\n      value={value}\n      onValueChange={setValue}\n      inputValue={inputValue}\n      onInputValueChange={onInputValueChange}\n      manualFiltering\n    >\n      <ComboboxLabel>Trick</ComboboxLabel>\n      <ComboboxAnchor>\n        <ComboboxInput placeholder=\"Search tricks...\" />\n        <ComboboxTrigger>\n          <ChevronDown className=\"h-4 w-4\" />\n        </ComboboxTrigger>\n      </ComboboxAnchor>\n      <ComboboxContent\n        ref={(node) => setContent(node)}\n        className=\"relative max-h-[300px] overflow-x-hidden overflow-y-auto\"\n      >\n        <ComboboxEmpty>No tricks found.</ComboboxEmpty>\n        <div\n          className=\"relative w-full\"\n          style={{\n            height: `${virtualizer.getTotalSize()}px`,\n          }}\n        >\n          {virtualizer.getVirtualItems().map((virtualItem) => {\n            const trick = filteredTricks[virtualItem.index];\n            if (!trick) return null;\n\n            return (\n              <ComboboxItem\n                key={virtualItem.key}\n                value={trick.value}\n                className=\"absolute top-0 left-0 w-full\"\n                style={{\n                  height: `${virtualItem.size}px`,\n                  transform: `translateY(${virtualItem.start}px)`,\n                }}\n                outset\n              >\n                {trick.label}\n              </ComboboxItem>\n            );\n          })}\n        </div>\n      </ComboboxContent>\n    </Combobox>\n  );\n}\n",
      "target": ""
    }
  ]
}