Icon Picker Virtualized
ui-components/icon-picker-virtualizedFreeBlock
A simple icon picker component with virtualization.
Install it
npx shadcn@latest add https://ui.raulcarini.dev/r/icon-picker-virtualized.jsonSource
1"use client";23import * as React from "react";4import { icons } from "lucide-react";5import { Grid, AutoSizer } from "react-virtualized";67import { cn } from "@/lib/utils";8import { useDebounce } from "@/hooks/use-debounce";910import { Input } from "@/components/ui/input";1112const IconItem = React.memo(13 ({14 iconName,15 setSelectedIcon,16 selectedIcon,17 }: {18 iconName: string;19 setSelectedIcon?: (iconName: string) => void;20 selectedIcon?: string | null;21 }) => {22 const Icon = icons[iconName as keyof typeof icons];2324 const handleClick = React.useCallback(() => {25 setSelectedIcon?.(iconName);26 }, [iconName, setSelectedIcon]);2728 return (29 <button30 className={cn(31 "flex items-center justify-center size-7 rounded-md cursor-pointer text-popover-foreground/70 hover:bg-muted hover:text-popover-foreground transition-colors",32 selectedIcon === iconName &&33 "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground",34 )}35 onClick={handleClick}36 title={iconName}37 aria-label={`Select ${iconName} icon`}38 aria-pressed={selectedIcon === iconName}39 >40 <Icon size={16} />41 </button>42 );43 },44);4546IconItem.displayName = "IconItem";4748const IconPicker = React.memo(49 ({50 setSelectedIcon,51 selectedIcon,52 className,53 ...props54 }: {55 setSelectedIcon?: (iconName: string) => void;56 selectedIcon?: string | null;57 } & React.ComponentProps<"div">) => {58 const [searchQuery, setSearchQuery] = React.useState("");59 const debouncedSearchQuery = useDebounce(searchQuery, 200);60 const gridRef = React.useRef<Grid | null>(null);6162 const iconsMap = React.useMemo(() => Object.keys(icons), []);6364 const filteredIcons = React.useMemo(() => {65 if (!debouncedSearchQuery.trim()) return iconsMap;66 return iconsMap.filter((iconName) =>67 iconName.toLowerCase().includes(debouncedSearchQuery.toLowerCase()),68 );69 }, [iconsMap, debouncedSearchQuery]);7071 React.useEffect(() => {72 if (gridRef.current) {73 gridRef.current.recomputeGridSize();74 }75 }, [filteredIcons]);7677 const handleSearchChange = React.useCallback(78 (e: React.ChangeEvent<HTMLInputElement>) => {79 setSearchQuery(e.target.value);80 },81 [],82 );8384 const ICON_CELL_SIZE = 28;85 const COLUMNS = 9;8687 const cellRenderer = React.useCallback(88 ({89 columnIndex,90 rowIndex,91// … 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 |
