aural-ui 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (308) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +456 -0
  3. package/dist/components/aspect-ratio/AspectRatio.stories.tsx +1327 -0
  4. package/dist/components/aspect-ratio/index.tsx +10 -0
  5. package/dist/components/aspect-ratio/meta.ts +8 -0
  6. package/dist/components/avatar/Avatar.stories.tsx +645 -0
  7. package/dist/components/avatar/index.tsx +50 -0
  8. package/dist/components/avatar/meta.ts +8 -0
  9. package/dist/components/badge/Badge.stories.tsx +169 -0
  10. package/dist/components/badge/index.tsx +28 -0
  11. package/dist/components/badge/meta.ts +6 -0
  12. package/dist/components/banner/Banner.stories.tsx +475 -0
  13. package/dist/components/banner/index.tsx +256 -0
  14. package/dist/components/banner/meta.ts +36 -0
  15. package/dist/components/button/Button.stories.tsx +74 -0
  16. package/dist/components/button/index.tsx +158 -0
  17. package/dist/components/button/meta.ts +33 -0
  18. package/dist/components/card/Card.stories.tsx +377 -0
  19. package/dist/components/card/index.tsx +85 -0
  20. package/dist/components/card/meta.ts +14 -0
  21. package/dist/components/char-count/CharCount.stories.tsx +334 -0
  22. package/dist/components/char-count/index.tsx +51 -0
  23. package/dist/components/char-count/meta.ts +13 -0
  24. package/dist/components/checkbox/Checkbox.stories.tsx +209 -0
  25. package/dist/components/checkbox/index.tsx +34 -0
  26. package/dist/components/checkbox/meta.ts +19 -0
  27. package/dist/components/chip/Chip.stories.tsx +207 -0
  28. package/dist/components/chip/index.tsx +92 -0
  29. package/dist/components/chip/meta.ts +17 -0
  30. package/dist/components/circular-loader/CircularLoader.stories.tsx +741 -0
  31. package/dist/components/circular-loader/index.tsx +138 -0
  32. package/dist/components/circular-loader/meta.ts +11 -0
  33. package/dist/components/collapsible/Collapsible.stories.tsx +319 -0
  34. package/dist/components/collapsible/index.tsx +158 -0
  35. package/dist/components/collapsible/meta.ts +22 -0
  36. package/dist/components/command/Command.stories.tsx +996 -0
  37. package/dist/components/command/index.tsx +324 -0
  38. package/dist/components/command/meta.ts +18 -0
  39. package/dist/components/dialog/Dialog.stories.tsx +963 -0
  40. package/dist/components/dialog/index.tsx +250 -0
  41. package/dist/components/dialog/meta.ts +28 -0
  42. package/dist/components/divider/Divider.stories.tsx +633 -0
  43. package/dist/components/divider/index.tsx +181 -0
  44. package/dist/components/divider/meta.ts +12 -0
  45. package/dist/components/dot-loader/DotLoader.stories.tsx +352 -0
  46. package/dist/components/dot-loader/index.tsx +78 -0
  47. package/dist/components/dot-loader/meta.ts +14 -0
  48. package/dist/components/dropdown/Dropdown.stories.tsx +1210 -0
  49. package/dist/components/dropdown/index.tsx +479 -0
  50. package/dist/components/dropdown/meta.ts +21 -0
  51. package/dist/components/form/Form.stories.tsx +320 -0
  52. package/dist/components/form/index.tsx +183 -0
  53. package/dist/components/form/meta.ts +11 -0
  54. package/dist/components/helper-text/HelperText.stories.tsx +254 -0
  55. package/dist/components/helper-text/index.tsx +102 -0
  56. package/dist/components/helper-text/meta.ts +18 -0
  57. package/dist/components/hover-card/HoverCard.stories.tsx +1328 -0
  58. package/dist/components/hover-card/index.tsx +42 -0
  59. package/dist/components/hover-card/meta.ts +12 -0
  60. package/dist/components/icon-button/IconButton.stories.tsx +252 -0
  61. package/dist/components/icon-button/index.tsx +130 -0
  62. package/dist/components/icon-button/meta.ts +20 -0
  63. package/dist/components/if-else/if-else.stories.tsx +100 -0
  64. package/dist/components/if-else/index.tsx +56 -0
  65. package/dist/components/if-else/meta.ts +6 -0
  66. package/dist/components/index.ts +70 -0
  67. package/dist/components/input/Input.stories.tsx +431 -0
  68. package/dist/components/input/index.tsx +487 -0
  69. package/dist/components/input/meta.ts +28 -0
  70. package/dist/components/label/Label.stories.tsx +200 -0
  71. package/dist/components/label/index.tsx +43 -0
  72. package/dist/components/label/meta.ts +14 -0
  73. package/dist/components/list/List.stories.tsx +963 -0
  74. package/dist/components/list/index.tsx +567 -0
  75. package/dist/components/list/meta.ts +24 -0
  76. package/dist/components/marquee/Marquee.stories.tsx +819 -0
  77. package/dist/components/marquee/index.tsx +107 -0
  78. package/dist/components/marquee/meta.ts +6 -0
  79. package/dist/components/overlay/Overlay.stories.tsx +954 -0
  80. package/dist/components/overlay/index.tsx +58 -0
  81. package/dist/components/overlay/meta.ts +10 -0
  82. package/dist/components/pagination/Pagination.stories.tsx +354 -0
  83. package/dist/components/pagination/index.tsx +455 -0
  84. package/dist/components/pagination/meta.ts +29 -0
  85. package/dist/components/popover/Popover.stories.tsx +1037 -0
  86. package/dist/components/popover/index.tsx +67 -0
  87. package/dist/components/popover/meta.ts +12 -0
  88. package/dist/components/radio/Radio.stories.tsx +146 -0
  89. package/dist/components/radio/index.tsx +41 -0
  90. package/dist/components/radio/meta.ts +19 -0
  91. package/dist/components/resizable/Resizable.stories.tsx +866 -0
  92. package/dist/components/resizable/index.tsx +55 -0
  93. package/dist/components/resizable/meta.ts +12 -0
  94. package/dist/components/scroll-area/ScrollArea.stories.tsx +1104 -0
  95. package/dist/components/scroll-area/index.tsx +55 -0
  96. package/dist/components/scroll-area/meta.ts +8 -0
  97. package/dist/components/search/Search.stories.tsx +678 -0
  98. package/dist/components/search/index.tsx +141 -0
  99. package/dist/components/search/meta.ts +6 -0
  100. package/dist/components/select/Select.stories.tsx +962 -0
  101. package/dist/components/select/index.tsx +512 -0
  102. package/dist/components/select/meta.ts +40 -0
  103. package/dist/components/sheet/Sheet.stories.tsx +1060 -0
  104. package/dist/components/sheet/index.tsx +440 -0
  105. package/dist/components/sheet/meta.ts +38 -0
  106. package/dist/components/skelton/Skelton.stories.tsx +859 -0
  107. package/dist/components/skelton/index.tsx +17 -0
  108. package/dist/components/skelton/meta.ts +6 -0
  109. package/dist/components/slider/Slider.stories.tsx +876 -0
  110. package/dist/components/slider/index.tsx +156 -0
  111. package/dist/components/slider/meta.ts +29 -0
  112. package/dist/components/stepper/Stepper.stories.tsx +639 -0
  113. package/dist/components/stepper/index.tsx +650 -0
  114. package/dist/components/stepper/meta.ts +19 -0
  115. package/dist/components/switch/Switch.stories.tsx +85 -0
  116. package/dist/components/switch/index.tsx +37 -0
  117. package/dist/components/switch/meta.ts +24 -0
  118. package/dist/components/switch-case/SwitchCase.stories.tsx +209 -0
  119. package/dist/components/switch-case/index.tsx +89 -0
  120. package/dist/components/switch-case/meta.ts +6 -0
  121. package/dist/components/table/Table.stories.tsx +1095 -0
  122. package/dist/components/table/index.tsx +113 -0
  123. package/dist/components/table/meta.ts +20 -0
  124. package/dist/components/tabs/Tabs.stories.tsx +1379 -0
  125. package/dist/components/tabs/index.tsx +186 -0
  126. package/dist/components/tabs/meta.ts +25 -0
  127. package/dist/components/tag/Tag.stories.tsx +625 -0
  128. package/dist/components/tag/index.tsx +320 -0
  129. package/dist/components/tag/meta.ts +52 -0
  130. package/dist/components/textarea/TextArea.stories.tsx +723 -0
  131. package/dist/components/textarea/index.tsx +480 -0
  132. package/dist/components/textarea/meta.ts +23 -0
  133. package/dist/components/toast/Toast.stories.tsx +1427 -0
  134. package/dist/components/toast/index.tsx +26 -0
  135. package/dist/components/toast/meta.ts +19 -0
  136. package/dist/components/toggle/Toggle.stories.tsx +1093 -0
  137. package/dist/components/toggle/index.tsx +44 -0
  138. package/dist/components/toggle/meta.ts +19 -0
  139. package/dist/components/tooltip/Tooltip.stories.tsx +1548 -0
  140. package/dist/components/tooltip/index.tsx +304 -0
  141. package/dist/components/tooltip/meta.ts +21 -0
  142. package/dist/components/typography/Typography.stories.tsx +197 -0
  143. package/dist/components/typography/index.tsx +184 -0
  144. package/dist/components/typography/meta.ts +38 -0
  145. package/dist/fonts/LabGrotesque-Regular.ttf +0 -0
  146. package/dist/fonts/LabGrotesqueTRIAL-Bold.otf +0 -0
  147. package/dist/fonts/LabGrotesqueTRIAL-Light.otf +0 -0
  148. package/dist/fonts/LabGrotesqueTRIAL-Medium.otf +0 -0
  149. package/dist/fonts/LabGrotesqueTRIAL-Regular.otf +0 -0
  150. package/dist/fonts/PPSupplySans-Regular (1).otf +0 -0
  151. package/dist/fonts/PPSupplySans-Regular.otf +0 -0
  152. package/dist/fonts/PPSupplySans-Ultralight.otf +0 -0
  153. package/dist/hooks/index.ts +3 -0
  154. package/dist/hooks/use-previous/UsePrevious.stories.tsx +997 -0
  155. package/dist/hooks/use-previous/index.ts +15 -0
  156. package/dist/hooks/use-previous/meta.ts +6 -0
  157. package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +983 -0
  158. package/dist/hooks/use-standalone-pagination/index.ts +146 -0
  159. package/dist/hooks/use-standalone-pagination/meta.ts +6 -0
  160. package/dist/icons/Icons.stories.tsx +29 -0
  161. package/dist/icons/alert-icon/AlertIcon.stories.tsx +991 -0
  162. package/dist/icons/alert-icon/index.tsx +48 -0
  163. package/dist/icons/alert-icon/meta.ts +8 -0
  164. package/dist/icons/all-icons.tsx +738 -0
  165. package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +1031 -0
  166. package/dist/icons/angle-down-icon/index.tsx +25 -0
  167. package/dist/icons/angle-down-icon/meta.ts +8 -0
  168. package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +1080 -0
  169. package/dist/icons/arrow-box-left-icon/index.tsx +24 -0
  170. package/dist/icons/arrow-box-left-icon/meta.ts +8 -0
  171. package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +1151 -0
  172. package/dist/icons/arrow-right-icon/index.tsx +26 -0
  173. package/dist/icons/arrow-right-icon/meta.ts +8 -0
  174. package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +1273 -0
  175. package/dist/icons/arrow-right-up-icon/index.tsx +24 -0
  176. package/dist/icons/arrow-right-up-icon/meta.ts +8 -0
  177. package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +670 -0
  178. package/dist/icons/art-board-icon/index.tsx +24 -0
  179. package/dist/icons/art-board-icon/meta.ts +7 -0
  180. package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +1244 -0
  181. package/dist/icons/audio-bar-icon/index.tsx +19 -0
  182. package/dist/icons/audio-bar-icon/meta.ts +8 -0
  183. package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +1239 -0
  184. package/dist/icons/bubble-check-icon/index.tsx +24 -0
  185. package/dist/icons/bubble-check-icon/meta.ts +8 -0
  186. package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +1228 -0
  187. package/dist/icons/bubble-crossed-icon/index.tsx +24 -0
  188. package/dist/icons/bubble-crossed-icon/meta.ts +8 -0
  189. package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +912 -0
  190. package/dist/icons/bubble-sparkle-icon/index.tsx +26 -0
  191. package/dist/icons/bubble-sparkle-icon/meta.ts +8 -0
  192. package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +1021 -0
  193. package/dist/icons/chevron-double-left-icon/index.tsx +34 -0
  194. package/dist/icons/chevron-double-left-icon/meta.ts +8 -0
  195. package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +1021 -0
  196. package/dist/icons/chevron-double-right-icon/index.tsx +34 -0
  197. package/dist/icons/chevron-double-right-icon/meta.ts +8 -0
  198. package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +1001 -0
  199. package/dist/icons/chevron-down-icon/index.tsx +27 -0
  200. package/dist/icons/chevron-down-icon/meta.ts +8 -0
  201. package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +1029 -0
  202. package/dist/icons/chevron-left-icon/index.tsx +27 -0
  203. package/dist/icons/chevron-left-icon/meta.ts +8 -0
  204. package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +1021 -0
  205. package/dist/icons/chevron-right-icon/index.tsx +27 -0
  206. package/dist/icons/chevron-right-icon/meta.ts +8 -0
  207. package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +1036 -0
  208. package/dist/icons/chevron-up-icon/index.tsx +27 -0
  209. package/dist/icons/chevron-up-icon/meta.ts +8 -0
  210. package/dist/icons/command-icon/CommandIcon.stories.tsx +1098 -0
  211. package/dist/icons/command-icon/index.tsx +24 -0
  212. package/dist/icons/command-icon/meta.ts +8 -0
  213. package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +1061 -0
  214. package/dist/icons/cross-circle-icon/index.tsx +23 -0
  215. package/dist/icons/cross-circle-icon/meta.ts +8 -0
  216. package/dist/icons/cross-icon/CrossIcon.stories.tsx +1027 -0
  217. package/dist/icons/cross-icon/index.tsx +24 -0
  218. package/dist/icons/cross-icon/meta.ts +8 -0
  219. package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +1092 -0
  220. package/dist/icons/edit-big-icon/index.tsx +22 -0
  221. package/dist/icons/edit-big-icon/meta.ts +8 -0
  222. package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +1090 -0
  223. package/dist/icons/eye-close-icon/index.tsx +26 -0
  224. package/dist/icons/eye-close-icon/meta.ts +8 -0
  225. package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +1098 -0
  226. package/dist/icons/eye-open-icon/index.tsx +24 -0
  227. package/dist/icons/eye-open-icon/meta.ts +8 -0
  228. package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +1071 -0
  229. package/dist/icons/feature-shine-icon/index.tsx +29 -0
  230. package/dist/icons/feature-shine-icon/meta.ts +8 -0
  231. package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +1115 -0
  232. package/dist/icons/file-chart-icon/index.tsx +24 -0
  233. package/dist/icons/file-chart-icon/meta.ts +8 -0
  234. package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +668 -0
  235. package/dist/icons/file-text-icon/index.tsx +24 -0
  236. package/dist/icons/file-text-icon/meta.ts +8 -0
  237. package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +1239 -0
  238. package/dist/icons/grip-vertical-icon/index.tsx +28 -0
  239. package/dist/icons/grip-vertical-icon/meta.ts +8 -0
  240. package/dist/icons/image-icon/ImageIcon.stories.tsx +1181 -0
  241. package/dist/icons/image-icon/index.tsx +24 -0
  242. package/dist/icons/image-icon/meta.ts +8 -0
  243. package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +1248 -0
  244. package/dist/icons/import-folder-icon/index.tsx +22 -0
  245. package/dist/icons/import-folder-icon/meta.ts +8 -0
  246. package/dist/icons/index.ts +46 -0
  247. package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +1272 -0
  248. package/dist/icons/light-bulb-simple-icon/index.tsx +24 -0
  249. package/dist/icons/light-bulb-simple-icon/meta.ts +8 -0
  250. package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +1245 -0
  251. package/dist/icons/magic-book-icon/index.tsx +32 -0
  252. package/dist/icons/magic-book-icon/meta.ts +8 -0
  253. package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +1251 -0
  254. package/dist/icons/maintenance-icon/index.tsx +23 -0
  255. package/dist/icons/maintenance-icon/meta.ts +8 -0
  256. package/dist/icons/message-icon/MessageIcon.stories.tsx +595 -0
  257. package/dist/icons/message-icon/index.tsx +30 -0
  258. package/dist/icons/message-icon/meta.ts +8 -0
  259. package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +1245 -0
  260. package/dist/icons/move-horizontal-icon/index.tsx +23 -0
  261. package/dist/icons/move-horizontal-icon/meta.ts +8 -0
  262. package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +1196 -0
  263. package/dist/icons/move-vertical-icon/index.tsx +23 -0
  264. package/dist/icons/move-vertical-icon/meta.ts +8 -0
  265. package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +1167 -0
  266. package/dist/icons/page-search-icon/index.tsx +21 -0
  267. package/dist/icons/page-search-icon/meta.ts +8 -0
  268. package/dist/icons/pencil-icon/PencilIcon.stories.tsx +1131 -0
  269. package/dist/icons/pencil-icon/index.tsx +21 -0
  270. package/dist/icons/pencil-icon/meta.ts +8 -0
  271. package/dist/icons/plus-icon/PlusIcon.stories.tsx +1151 -0
  272. package/dist/icons/plus-icon/index.tsx +24 -0
  273. package/dist/icons/plus-icon/meta.ts +8 -0
  274. package/dist/icons/search-icon/SearchIcon.stories.tsx +1181 -0
  275. package/dist/icons/search-icon/index.tsx +24 -0
  276. package/dist/icons/search-icon/meta.ts +8 -0
  277. package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +1167 -0
  278. package/dist/icons/site-logo-icon/index.tsx +79 -0
  279. package/dist/icons/site-logo-icon/meta.ts +8 -0
  280. package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +637 -0
  281. package/dist/icons/spinner-gradient-icon/index.tsx +53 -0
  282. package/dist/icons/spinner-gradient-icon/meta.ts +8 -0
  283. package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +644 -0
  284. package/dist/icons/spinner-solid-icon/index.tsx +59 -0
  285. package/dist/icons/spinner-solid-icon/meta.ts +8 -0
  286. package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +736 -0
  287. package/dist/icons/spinner-solid-neutral-icon/index.tsx +53 -0
  288. package/dist/icons/spinner-solid-neutral-icon/meta.ts +8 -0
  289. package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +1204 -0
  290. package/dist/icons/tick-circle-icon/index.tsx +23 -0
  291. package/dist/icons/tick-circle-icon/meta.ts +8 -0
  292. package/dist/icons/tick-icon/TickIcon.stories.tsx +1340 -0
  293. package/dist/icons/tick-icon/index.tsx +24 -0
  294. package/dist/icons/tick-icon/meta.ts +8 -0
  295. package/dist/icons/trash-icon/TrashIcon.stories.tsx +996 -0
  296. package/dist/icons/trash-icon/index.tsx +24 -0
  297. package/dist/icons/trash-icon/meta.ts +8 -0
  298. package/dist/icons/upload-icon/UploadIcon.stories.tsx +947 -0
  299. package/dist/icons/upload-icon/index.tsx +24 -0
  300. package/dist/icons/upload-icon/meta.ts +8 -0
  301. package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +1045 -0
  302. package/dist/icons/vertical-menu-icon/index.tsx +27 -0
  303. package/dist/icons/vertical-menu-icon/meta.ts +8 -0
  304. package/dist/index.d.ts +6 -0
  305. package/dist/index.js +206 -0
  306. package/dist/lib/utils.ts +6 -0
  307. package/dist/styles/aural-theme.css +1008 -0
  308. package/package.json +142 -0
@@ -0,0 +1,738 @@
1
+ import React, { useMemo, useState } from "react"
2
+ import { Button } from "@components/button"
3
+ import {
4
+ Dialog,
5
+ DialogContent,
6
+ DialogHeader,
7
+ DialogTitle,
8
+ } from "@components/dialog"
9
+ import * as IconSet from "@icons/index"
10
+
11
+ // Icon Usage Modal
12
+ const IconUsageModal: React.FC<{
13
+ isOpen: boolean
14
+ onClose: () => void
15
+ iconName: string
16
+ IconComponent: React.ComponentType<React.SVGProps<SVGSVGElement>>
17
+ }> = ({ isOpen, onClose, iconName, IconComponent }) => {
18
+ const [copiedIndex, setCopiedIndex] = useState<number | null>(null)
19
+
20
+ const usageExamples = [
21
+ {
22
+ title: "Basic Usage",
23
+ code: `import { ${iconName} } from "@icons/index"
24
+
25
+ function MyComponent() {
26
+ return (
27
+ <div className="flex items-center gap-2">
28
+ <${iconName} className="h-5 w-5 text-white" />
29
+ <span>Icon with text</span>
30
+ </div>
31
+ )
32
+ }`,
33
+ },
34
+ {
35
+ title: "Custom Size & Color",
36
+ code: `import { ${iconName} } from "@icons/index"
37
+
38
+ function CustomIcon() {
39
+ return (
40
+ <${iconName}
41
+ width={32}
42
+ height={32}
43
+ className="text-blue-500"
44
+ />
45
+ )
46
+ }`,
47
+ },
48
+ {
49
+ title: "In Button",
50
+ code: `import { ${iconName} } from "@icons/index"
51
+ import { Button } from "@components/button"
52
+
53
+ function IconButton() {
54
+ return (
55
+ <Button className="flex items-center gap-2">
56
+ <${iconName} className="h-4 w-4" />
57
+ Click me
58
+ </Button>
59
+ )
60
+ }`,
61
+ },
62
+ {
63
+ title: "Interactive States",
64
+ code: `import { ${iconName} } from "@icons/index"
65
+
66
+ function InteractiveIcon() {
67
+ return (
68
+ <${iconName} className="h-6 w-6 text-gray-400 transition-colors hover:text-white" />
69
+ )
70
+ }`,
71
+ },
72
+ ]
73
+
74
+ const copyToClipboard = async (text: string, index: number) => {
75
+ try {
76
+ await navigator.clipboard.writeText(text)
77
+ setCopiedIndex(index)
78
+ setTimeout(() => setCopiedIndex(null), 2000)
79
+ } catch (err) {
80
+ console.error("Failed to copy text: ", err)
81
+ }
82
+ }
83
+
84
+ return (
85
+ <Dialog open={isOpen} onOpenChange={onClose}>
86
+ <DialogContent
87
+ classes={{
88
+ content: "max-w-4xl",
89
+ root: "bg-gray-900 text-white",
90
+ }}
91
+ >
92
+ <DialogHeader className="border-b border-white/10 pb-4">
93
+ <div className="flex items-center gap-4">
94
+ <div className="rounded-lg bg-white/5 p-3">
95
+ <IconComponent className="h-8 w-8 text-white" />
96
+ </div>
97
+ <div>
98
+ <DialogTitle className="text-xl font-semibold text-white">
99
+ {iconName}
100
+ </DialogTitle>
101
+ <p className="text-sm text-white/60">
102
+ Usage examples and implementation
103
+ </p>
104
+ </div>
105
+ </div>
106
+ </DialogHeader>
107
+
108
+ <div className="max-h-[calc(90vh-200px)] space-y-6 overflow-y-auto">
109
+ {/* Usage Examples */}
110
+ {usageExamples.map((example, index) => (
111
+ <div key={index} className="space-y-3">
112
+ <h3 className="text-lg font-medium text-white">
113
+ {example.title}
114
+ </h3>
115
+ <div className="relative">
116
+ <pre className="overflow-x-auto rounded-lg border border-white/10 bg-black/40 p-4 text-sm text-gray-300">
117
+ <code>{example.code}</code>
118
+ </pre>
119
+ <Button
120
+ onClick={() => copyToClipboard(example.code, index)}
121
+ className="absolute top-2 right-2"
122
+ size="sm"
123
+ variant="outline"
124
+ >
125
+ {copiedIndex === index ? "Copied!" : "Copy"}
126
+ </Button>
127
+ </div>
128
+ </div>
129
+ ))}
130
+
131
+ {/* Live Preview */}
132
+ <div className="rounded-lg border border-white/10 bg-white/5 p-6">
133
+ <h3 className="mb-4 text-lg font-medium text-white">
134
+ Live Preview
135
+ </h3>
136
+ <div className="flex flex-wrap items-center gap-6">
137
+ <div className="text-center">
138
+ <IconComponent className="mb-2 h-6 w-6 text-white" />
139
+ <span className="text-xs text-white/60">Default</span>
140
+ </div>
141
+ <div className="text-center">
142
+ <IconComponent className="mb-2 h-8 w-8 text-blue-400" />
143
+ <span className="text-xs text-white/60">Large Blue</span>
144
+ </div>
145
+ <div className="text-center">
146
+ <IconComponent className="mb-2 h-4 w-4 text-green-400" />
147
+ <span className="text-xs text-white/60">Small Green</span>
148
+ </div>
149
+ <div className="text-center">
150
+ <IconComponent className="mb-2 h-6 w-6 text-red-400" />
151
+ <span className="text-xs text-white/60">Red</span>
152
+ </div>
153
+ <div className="text-center">
154
+ <IconComponent className="mb-2 h-6 w-6 text-yellow-400" />
155
+ <span className="text-xs text-white/60">Yellow</span>
156
+ </div>
157
+ </div>
158
+ </div>
159
+
160
+ {/* Icon Properties */}
161
+ <div className="rounded-lg border border-white/10 bg-white/5 p-6">
162
+ <h3 className="mb-4 text-lg font-medium text-white">
163
+ Icon Properties
164
+ </h3>
165
+ <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
166
+ <div className="space-y-2">
167
+ <h4 className="text-sm font-medium text-white/80">
168
+ Common Props
169
+ </h4>
170
+ <ul className="space-y-1 text-sm text-white/60">
171
+ <li>
172
+ <code className="rounded bg-black/20 px-1">className</code>{" "}
173
+ - CSS classes
174
+ </li>
175
+ <li>
176
+ <code className="rounded bg-black/20 px-1">width</code> -
177
+ Icon width
178
+ </li>
179
+ <li>
180
+ <code className="rounded bg-black/20 px-1">height</code> -
181
+ Icon height
182
+ </li>
183
+ </ul>
184
+ </div>
185
+ <div className="space-y-2">
186
+ <h4 className="text-sm font-medium text-white/80">SVG Props</h4>
187
+ <ul className="space-y-1 text-sm text-white/60">
188
+ <li>
189
+ <code className="rounded bg-black/20 px-1">stroke</code> -
190
+ Stroke color
191
+ </li>
192
+ <li>
193
+ <code className="rounded bg-black/20 px-1">
194
+ strokeWidth
195
+ </code>{" "}
196
+ - Stroke width
197
+ </li>
198
+ <li>
199
+ <code className="rounded bg-black/20 px-1">fill</code> -
200
+ Fill color
201
+ </li>
202
+ </ul>
203
+ </div>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </DialogContent>
208
+ </Dialog>
209
+ )
210
+ }
211
+
212
+ interface IconCategoryProps {
213
+ category: string
214
+ children: React.ReactNode
215
+ }
216
+
217
+ const IconCategory: React.FC<IconCategoryProps> = ({ category, children }) => {
218
+ return (
219
+ <div className="space-y-8">
220
+ <div className="flex items-center gap-4">
221
+ <div className="h-px flex-1 bg-gradient-to-r from-purple-500/50 to-transparent" />
222
+ <h2 className="rounded-full border border-purple-500/20 bg-purple-500/10 px-4 py-2 text-lg font-semibold text-purple-300">
223
+ {category}
224
+ </h2>
225
+ <div className="h-px flex-1 bg-gradient-to-l from-purple-500/50 to-transparent" />
226
+ </div>
227
+ <div className="space-y-12">{children}</div>
228
+ </div>
229
+ )
230
+ }
231
+
232
+ interface IconGridProps {
233
+ title: string
234
+ description?: string
235
+ icons: {
236
+ name: string
237
+ component: React.ComponentType<React.SVGProps<SVGSVGElement>>
238
+ category?: string
239
+ description?: string
240
+ }[]
241
+ onIconClick?: (
242
+ name: string,
243
+ component: React.ComponentType<React.SVGProps<SVGSVGElement>>
244
+ ) => void
245
+ }
246
+
247
+ const IconGrid: React.FC<IconGridProps> = ({
248
+ title,
249
+ description,
250
+ icons,
251
+ onIconClick,
252
+ }) => {
253
+ return (
254
+ <div className="space-y-6">
255
+ <div className="space-y-2">
256
+ <h3 className="text-2xl font-bold text-white">{title}</h3>
257
+ {description && (
258
+ <p className="text-sm leading-relaxed text-white/70">{description}</p>
259
+ )}
260
+ </div>
261
+ <div className="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8">
262
+ {icons.map(({ name, component: IconComponent, category }) => (
263
+ <div
264
+ key={name}
265
+ onClick={() => onIconClick?.(name, IconComponent)}
266
+ className="group relative cursor-pointer overflow-hidden rounded-lg border border-white/10 bg-white/5 transition-all duration-200 hover:scale-105 hover:border-white/20 hover:bg-white/10"
267
+ >
268
+ {/* Icon Display */}
269
+ <div className="flex h-24 items-center justify-center bg-gradient-to-br from-white/5 to-white/10 transition-all duration-200 group-hover:from-white/10 group-hover:to-white/15">
270
+ <IconComponent className="h-8 w-8 text-white transition-all duration-200 group-hover:scale-110 group-hover:text-blue-400" />
271
+ </div>
272
+
273
+ {/* Icon Info */}
274
+ <div className="space-y-2 p-3">
275
+ <h4 className="truncate text-xs font-medium text-white">
276
+ {name}
277
+ </h4>
278
+ {category && (
279
+ <span className="inline-block rounded-full bg-purple-500/20 px-2 py-1 text-xs text-purple-300">
280
+ {category}
281
+ </span>
282
+ )}
283
+ </div>
284
+
285
+ {/* Hover overlay */}
286
+ <div className="absolute inset-0 flex flex-col items-center justify-center bg-black/80 opacity-0 backdrop-blur-sm transition-opacity duration-200 group-hover:opacity-100">
287
+ <IconComponent className="mb-2 h-8 w-8 text-white" />
288
+ <p className="px-2 text-center text-xs font-medium text-white">
289
+ {name}
290
+ </p>
291
+ <p className="mt-1 text-xs text-blue-300">Click for usage</p>
292
+ </div>
293
+ </div>
294
+ ))}
295
+ </div>
296
+ </div>
297
+ )
298
+ }
299
+
300
+ export const Icons: React.FC = () => {
301
+ const [searchTerm, setSearchTerm] = useState("")
302
+ const [selectedCategory, setSelectedCategory] = useState("all")
303
+ const [selectedIcon, setSelectedIcon] = useState<{
304
+ name: string
305
+ component: React.ComponentType<React.SVGProps<SVGSVGElement>>
306
+ } | null>(null)
307
+
308
+ const categories = [
309
+ "all",
310
+ "navigation",
311
+ "actions",
312
+ "interface",
313
+ "content",
314
+ "status",
315
+ "social",
316
+ ]
317
+
318
+ // Get all icon components and categorize them
319
+ const allIcons = useMemo(() => {
320
+ return Object.entries(IconSet)
321
+ .filter(([name]) => name.endsWith("Icon"))
322
+ .map(([name, component]) => ({
323
+ name,
324
+ component: component as React.ComponentType<
325
+ React.SVGProps<SVGSVGElement>
326
+ >,
327
+ category: categorizeIcon(name),
328
+ description: getIconDescription(name),
329
+ }))
330
+ .sort((a, b) => a.name.localeCompare(b.name))
331
+ }, [])
332
+
333
+ // Categorize icons based on their names
334
+ function categorizeIcon(iconName: string): string {
335
+ const name = iconName.toLowerCase()
336
+
337
+ if (name.includes("chevron") || name.includes("arrow")) {
338
+ return "navigation"
339
+ }
340
+ if (
341
+ name.includes("cross") ||
342
+ name.includes("tick") ||
343
+ name.includes("plus") ||
344
+ name.includes("edit") ||
345
+ name.includes("trash")
346
+ ) {
347
+ return "actions"
348
+ }
349
+ if (
350
+ name.includes("eye") ||
351
+ name.includes("search") ||
352
+ name.includes("command") ||
353
+ name.includes("menu")
354
+ ) {
355
+ return "interface"
356
+ }
357
+ if (
358
+ name.includes("file") ||
359
+ name.includes("image") ||
360
+ name.includes("bubble") ||
361
+ name.includes("import")
362
+ ) {
363
+ return "content"
364
+ }
365
+ if (
366
+ name.includes("alert") ||
367
+ name.includes("maintenance") ||
368
+ name.includes("bulb")
369
+ ) {
370
+ return "status"
371
+ }
372
+
373
+ return "interface"
374
+ }
375
+
376
+ // Get icon description based on name
377
+ function getIconDescription(iconName: string): string {
378
+ const descriptions: Record<string, string> = {
379
+ ChevronRightIcon: "Navigate forward or expand",
380
+ ChevronLeftIcon: "Navigate back or collapse",
381
+ CrossIcon: "Close or cancel action",
382
+ TickIcon: "Confirm or success state",
383
+ SearchIcon: "Search functionality",
384
+ EyeOpenIcon: "Show or visible state",
385
+ EyeCloseIcon: "Hide or invisible state",
386
+ AlertIcon: "Warning or attention",
387
+ PlusIcon: "Add or create new",
388
+ EditIcon: "Edit or modify",
389
+ TrashIcon: "Delete or remove",
390
+ ImageIcon: "Image content",
391
+ FileChartIcon: "Chart or analytics",
392
+ CommandIcon: "Keyboard shortcut",
393
+ VerticalMenuIcon: "More options menu",
394
+ }
395
+
396
+ return descriptions[iconName] || "UI icon component"
397
+ }
398
+
399
+ // Filter icons based on search term and category
400
+ const filteredIcons = useMemo(() => {
401
+ let filtered = allIcons
402
+
403
+ // Filter by category
404
+ if (selectedCategory !== "all") {
405
+ filtered = filtered.filter((icon) => icon.category === selectedCategory)
406
+ }
407
+
408
+ // Filter by search term
409
+ if (searchTerm) {
410
+ filtered = filtered.filter(
411
+ (icon) =>
412
+ icon.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
413
+ icon.description?.toLowerCase().includes(searchTerm.toLowerCase())
414
+ )
415
+ }
416
+
417
+ return filtered
418
+ }, [allIcons, selectedCategory, searchTerm])
419
+
420
+ // Group icons by category for display
421
+ const iconsByCategory = useMemo(() => {
422
+ const grouped: Record<string, typeof filteredIcons> = {}
423
+
424
+ filteredIcons.forEach((icon) => {
425
+ if (!grouped[icon.category]) {
426
+ grouped[icon.category] = []
427
+ }
428
+ grouped[icon.category].push(icon)
429
+ })
430
+
431
+ return grouped
432
+ }, [filteredIcons])
433
+
434
+ const handleIconClick = (
435
+ name: string,
436
+ component: React.ComponentType<React.SVGProps<SVGSVGElement>>
437
+ ) => {
438
+ setSelectedIcon({ name, component })
439
+ }
440
+
441
+ // Calculate stats
442
+ const totalIcons = allIcons.length
443
+ const categoryCount = Object.keys(iconsByCategory).length
444
+
445
+ return (
446
+ <div className="min-h-screen bg-gradient-to-br from-gray-900 via-purple-900/20 to-gray-900">
447
+ {/* Header */}
448
+ <div className="relative overflow-hidden border-b border-white/10 bg-black/20 backdrop-blur-xl">
449
+ <div className="absolute inset-0 bg-gradient-to-r from-purple-500/10 via-transparent to-blue-500/10" />
450
+ <div className="relative mx-auto max-w-7xl px-6 py-16">
451
+ <div className="space-y-6 text-center">
452
+ <h1 className="bg-gradient-to-r from-white via-purple-200 to-white bg-clip-text text-5xl font-bold text-transparent">
453
+ Icon Library
454
+ </h1>
455
+ <p className="mx-auto max-w-3xl text-xl leading-relaxed text-white/70">
456
+ A comprehensive collection of carefully crafted icons built with
457
+ accessibility in mind. Each icon is optimized for clarity and
458
+ consistency across your interface.
459
+ </p>
460
+
461
+ {/* Stats */}
462
+ <div className="flex items-center justify-center gap-8 pt-8">
463
+ <div className="text-center">
464
+ <div className="text-3xl font-bold text-purple-300">
465
+ {totalIcons}+
466
+ </div>
467
+ <div className="text-sm text-white/60">Total icons</div>
468
+ </div>
469
+ <div className="h-8 w-px bg-white/20" />
470
+ <div className="text-center">
471
+ <div className="text-3xl font-bold text-blue-300">
472
+ {categoryCount}
473
+ </div>
474
+ <div className="text-sm text-white/60">Categories</div>
475
+ </div>
476
+ <div className="h-8 w-px bg-white/20" />
477
+ <div className="text-center">
478
+ <div className="text-3xl font-bold text-green-300">
479
+ Accessible
480
+ </div>
481
+ <div className="text-sm text-white/60">Radix UI</div>
482
+ </div>
483
+ </div>
484
+ </div>
485
+ </div>
486
+ </div>
487
+
488
+ {/* Controls */}
489
+ <div className="sticky top-0 z-40 border-b border-white/10 bg-black/80 backdrop-blur-xl">
490
+ <div className="mx-auto max-w-7xl px-6 py-4">
491
+ <div className="flex flex-col items-center justify-between gap-4 sm:flex-row">
492
+ <div className="flex flex-wrap gap-2">
493
+ {categories.map((category) => (
494
+ <button
495
+ key={category}
496
+ onClick={() => setSelectedCategory(category)}
497
+ className={`rounded-full px-4 py-2 text-sm font-medium transition-all duration-200 ${
498
+ selectedCategory === category
499
+ ? "bg-purple-500 text-white shadow-lg shadow-purple-500/25"
500
+ : "bg-white/5 text-white/70 hover:bg-white/10 hover:text-white"
501
+ }`}
502
+ >
503
+ {category.charAt(0).toUpperCase() + category.slice(1)}
504
+ </button>
505
+ ))}
506
+ </div>
507
+
508
+ <div className="relative">
509
+ <input
510
+ type="text"
511
+ placeholder="Search icons..."
512
+ value={searchTerm}
513
+ onChange={(e) => setSearchTerm(e.target.value)}
514
+ className="w-64 rounded-lg border border-white/10 bg-white/5 py-2 pr-10 pl-4 text-white placeholder-white/50 focus:border-purple-500/50 focus:ring-2 focus:ring-purple-500/50 focus:outline-none"
515
+ />
516
+ <div className="absolute top-1/2 right-3 -translate-y-1/2 text-white/50">
517
+ {searchTerm ? (
518
+ <button
519
+ onClick={() => setSearchTerm("")}
520
+ className="hover:text-white"
521
+ >
522
+ <svg
523
+ className="h-4 w-4"
524
+ fill="none"
525
+ stroke="currentColor"
526
+ viewBox="0 0 24 24"
527
+ >
528
+ <path
529
+ strokeLinecap="round"
530
+ strokeLinejoin="round"
531
+ strokeWidth={2}
532
+ d="M6 18L18 6M6 6l12 12"
533
+ />
534
+ </svg>
535
+ </button>
536
+ ) : (
537
+ <svg
538
+ className="h-4 w-4"
539
+ fill="none"
540
+ stroke="currentColor"
541
+ viewBox="0 0 24 24"
542
+ >
543
+ <path
544
+ strokeLinecap="round"
545
+ strokeLinejoin="round"
546
+ strokeWidth={2}
547
+ d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
548
+ />
549
+ </svg>
550
+ )}
551
+ </div>
552
+ </div>
553
+ </div>
554
+
555
+ {/* Search Results Indicator */}
556
+ {searchTerm && (
557
+ <div className="mt-4 text-center">
558
+ <p className="text-sm text-white/70">
559
+ {filteredIcons.length > 0 ? (
560
+ <>
561
+ Found{" "}
562
+ <span className="font-medium text-purple-300">
563
+ {filteredIcons.length}
564
+ </span>{" "}
565
+ icons matching "{searchTerm}"
566
+ </>
567
+ ) : (
568
+ <>
569
+ No icons found matching "
570
+ <span className="font-medium text-red-300">
571
+ {searchTerm}
572
+ </span>
573
+ "
574
+ </>
575
+ )}
576
+ </p>
577
+ </div>
578
+ )}
579
+ </div>
580
+ </div>
581
+
582
+ {/* Content */}
583
+ <div className="mx-auto max-w-7xl space-y-16 px-6 py-12">
584
+ {/* No Results Message */}
585
+ {searchTerm && filteredIcons.length === 0 && (
586
+ <div className="py-16 text-center">
587
+ <div className="mx-auto max-w-md space-y-4">
588
+ <div className="text-6xl">🔍</div>
589
+ <h3 className="text-xl font-medium text-white">No icons found</h3>
590
+ <p className="text-white/60">
591
+ Try searching for a different term or clear your search to see
592
+ all icons.
593
+ </p>
594
+ <button
595
+ onClick={() => setSearchTerm("")}
596
+ className="mt-4 rounded-full bg-purple-500 px-6 py-2 text-sm font-medium text-white transition-colors hover:bg-purple-600"
597
+ >
598
+ Clear Search
599
+ </button>
600
+ </div>
601
+ </div>
602
+ )}
603
+
604
+ {/* Show all icons when no category filter is applied and no search */}
605
+ {selectedCategory === "all" && !searchTerm && (
606
+ <IconCategory category="All Icons">
607
+ <IconGrid
608
+ title="Complete Icon Collection"
609
+ description={`Browse all ${totalIcons} icons in our library. Click any icon to see usage examples and copy code.`}
610
+ icons={allIcons}
611
+ onIconClick={handleIconClick}
612
+ />
613
+ </IconCategory>
614
+ )}
615
+
616
+ {/* Show icons by category */}
617
+ {Object.entries(iconsByCategory).map(([category, icons]) => {
618
+ if (icons.length === 0) return null
619
+
620
+ const categoryDisplayName =
621
+ category.charAt(0).toUpperCase() + category.slice(1)
622
+ const categoryDescriptions: Record<string, string> = {
623
+ navigation:
624
+ "Icons for navigation, directional movement, and flow control.",
625
+ actions:
626
+ "Icons for user actions like adding, editing, deleting, and confirming.",
627
+ interface:
628
+ "Icons for interface elements like menus, search, and controls.",
629
+ content: "Icons for content types like files, images, and media.",
630
+ status: "Icons for states, alerts, and status indicators.",
631
+ social: "Icons for social features and sharing functionality.",
632
+ }
633
+
634
+ return (
635
+ <IconCategory
636
+ key={category}
637
+ category={`${categoryDisplayName} Icons`}
638
+ >
639
+ <IconGrid
640
+ title={`${categoryDisplayName} (${icons.length})`}
641
+ description={categoryDescriptions[category]}
642
+ icons={icons}
643
+ onIconClick={handleIconClick}
644
+ />
645
+ </IconCategory>
646
+ )
647
+ })}
648
+
649
+ {/* Featured Icons Section - only show when no filters applied */}
650
+ {selectedCategory === "all" && !searchTerm && (
651
+ <IconCategory category="Featured Icons">
652
+ <div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
653
+ {/* Most Used Icons */}
654
+ <div className="space-y-6">
655
+ <h3 className="text-xl font-bold text-white">Most Used</h3>
656
+ <div className="grid grid-cols-4 gap-4">
657
+ {allIcons
658
+ .filter((icon) =>
659
+ [
660
+ "ChevronRightIcon",
661
+ "ChevronLeftIcon",
662
+ "CrossIcon",
663
+ "TickIcon",
664
+ "SearchIcon",
665
+ "PlusIcon",
666
+ "EditIcon",
667
+ "TrashIcon",
668
+ ].includes(icon.name)
669
+ )
670
+ .map(({ name, component: IconComponent }) => (
671
+ <div
672
+ key={name}
673
+ onClick={() => handleIconClick(name, IconComponent)}
674
+ className="group cursor-pointer rounded-lg border border-white/10 bg-white/5 p-4 text-center transition-all hover:scale-105 hover:bg-white/10"
675
+ >
676
+ <IconComponent className="mx-auto mb-2 h-8 w-8 text-white transition-colors group-hover:text-blue-400" />
677
+ <p className="text-xs text-white/70">
678
+ {name.replace("Icon", "")}
679
+ </p>
680
+ </div>
681
+ ))}
682
+ </div>
683
+ </div>
684
+
685
+ {/* Recently Added */}
686
+ <div className="space-y-6">
687
+ <h3 className="text-xl font-bold text-white">Recently Added</h3>
688
+ <div className="grid grid-cols-4 gap-4">
689
+ {allIcons
690
+ .slice(-8)
691
+ .map(({ name, component: IconComponent }) => (
692
+ <div
693
+ key={name}
694
+ onClick={() => handleIconClick(name, IconComponent)}
695
+ className="group cursor-pointer rounded-lg border border-white/10 bg-white/5 p-4 text-center transition-all hover:scale-105 hover:bg-white/10"
696
+ >
697
+ <IconComponent className="mx-auto mb-2 h-8 w-8 text-white transition-colors group-hover:text-blue-400" />
698
+ <p className="text-xs text-white/70">
699
+ {name.replace("Icon", "")}
700
+ </p>
701
+ </div>
702
+ ))}
703
+ </div>
704
+ </div>
705
+ </div>
706
+ </IconCategory>
707
+ )}
708
+ </div>
709
+
710
+ {/* Footer */}
711
+ <div className="border-t border-white/10 bg-black/20 backdrop-blur-xl">
712
+ <div className="mx-auto max-w-7xl px-6 py-8">
713
+ <div className="space-y-4 text-center">
714
+ <p className="text-white/60">
715
+ All icons are built with Radix UI's AccessibleIcon for screen
716
+ reader compatibility.
717
+ </p>
718
+ <p className="text-sm text-white/40">
719
+ Click any icon to see usage examples and copy implementation code.
720
+ </p>
721
+ </div>
722
+ </div>
723
+ </div>
724
+
725
+ {/* Usage Modal */}
726
+ {selectedIcon && (
727
+ <IconUsageModal
728
+ isOpen={!!selectedIcon}
729
+ onClose={() => setSelectedIcon(null)}
730
+ iconName={selectedIcon.name}
731
+ IconComponent={selectedIcon.component}
732
+ />
733
+ )}
734
+ </div>
735
+ )
736
+ }
737
+
738
+ export default Icons