Icon Picker Virtualized
ui-components/icon-picker-tanstackFreeBlock
A simple icon picker component with virtualization.
Install it
npx shadcn@latest add https://ui.raulcarini.dev/r/icon-picker-tanstack.jsonSource
1"use client";23import * as React from "react";4import { icons } from "lucide-react";5import { useVirtualizer } from "@tanstack/react-virtual";67import { cn } from "@/lib/utils";8import { Input } from "@/components/ui/input";9import { useDebounce } from "@/hooks/use-debounce";1011const IconItem = React.memo(12 ({13 iconName,14 setSelectedIcon,15 selectedIcon,16 }: {17 iconName: string;18 setSelectedIcon?: (iconName: string) => void;19 selectedIcon?: string | null;20 }) => {21 const Icon = icons[iconName as keyof typeof icons];2223 const handleClick = React.useCallback(() => {24 setSelectedIcon?.(iconName);25 }, [iconName, setSelectedIcon]);2627 return (28 <button29 className={cn(30 "flex items-center justify-center size-7 rounded-md cursor-pointer text-popover-foreground/70 hover:bg-muted hover:text-popover-foreground transition-colors",31 selectedIcon === iconName &&32 "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground",33 )}34 onClick={handleClick}35 title={iconName}36 aria-label={`Select ${iconName} icon`}37 aria-pressed={selectedIcon === iconName}38 >39 <Icon size={16} />40 </button>41 );42 },43);4445IconItem.displayName = "IconItem";4647const IconPicker = React.memo(48 ({49 setSelectedIcon,50 selectedIcon,51 className,52 ...props53 }: {54 setSelectedIcon?: (iconName: string) => void;55 selectedIcon?: string | null;56 } & React.ComponentProps<"div">) => {57 const [searchQuery, setSearchQuery] = React.useState("");58 const debouncedSearchQuery = useDebounce(searchQuery, 200);5960 const iconsMap = React.useMemo(() => Object.keys(icons), []);6162 const filteredIcons = React.useMemo(() => {63 if (!debouncedSearchQuery.trim()) return iconsMap;64 return iconsMap.filter((iconName) =>65 iconName.toLowerCase().includes(debouncedSearchQuery.toLowerCase()),66 );67 }, [iconsMap, debouncedSearchQuery]);6869 const handleSearchChange = React.useCallback(70 (e: React.ChangeEvent<HTMLInputElement>) => {71 setSearchQuery(e.target.value);72 },73 [],74 );7576 const parentRef = React.useRef<HTMLDivElement>(null);7778 const ITEMS_PER_ROW = 9;79 const totalRows = Math.ceil(filteredIcons.length / ITEMS_PER_ROW);8081 const rowVirtualizerForGrid = useVirtualizer({82 count: totalRows,83 getScrollElement: () => parentRef.current,84 estimateSize: () => 28,85 overscan: 10,86// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from UI Components
All 25 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| GitHub Contributionsgithub-contributions | UI Components | Blocks | Free | no deps | |
| GitHub Contributions Advancedgithub-contributions-advanced | UI Components | Blocks | Free | no deps | |
| GitHub Contributions Advanced Fetchergithub-contributions-advanced-fetcher | UI Components | Blocks | Free | no deps | |
| GitHub Contributions Fetchergithub-contributions-fetcher | UI Components | Blocks | Free | no deps | |
| GitHub Forksgithub-forks | UI Components | Blocks | Free | 1 dep | |
| GitHub Issuesgithub-issues | UI Components | Blocks | Free | 1 dep | |
| GitHub Pull Requestsgithub-pr | UI Components | Blocks | Free | 1 dep | |
| GitHub Starsgithub-stars | UI Components | Blocks | Free | 1 dep |
