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,996 @@
1
+ import React from "react"
2
+ import { Badge } from "@components/badge"
3
+ import { Button } from "@components/button"
4
+ import {
5
+ ArrowRightIcon,
6
+ BubbleCheckIcon,
7
+ BubbleSparkleIcon,
8
+ ChevronLeftIcon,
9
+ ChevronUpIcon,
10
+ CommandIcon,
11
+ CrossCircleIcon,
12
+ EditBigIcon,
13
+ EyeOpenIcon,
14
+ FeatureShineIcon,
15
+ FileChartIcon,
16
+ ImageIcon,
17
+ ImportFolderIcon,
18
+ LightBulbSimpleIcon,
19
+ MagicBookIcon,
20
+ MaintenanceIcon,
21
+ SearchIcon,
22
+ TickIcon,
23
+ TrashIcon,
24
+ UploadIcon,
25
+ } from "@icons/index"
26
+ import type { Meta, StoryObj } from "@storybook/react"
27
+
28
+ import {
29
+ Command,
30
+ CommandDialog,
31
+ CommandEmpty,
32
+ CommandGroup,
33
+ CommandInput,
34
+ CommandItem,
35
+ CommandLabel,
36
+ CommandList,
37
+ CommandSeparator,
38
+ CommandShortcut,
39
+ } from "."
40
+
41
+ const meta: Meta<typeof Command> = {
42
+ title: "Components/UI/Command",
43
+ component: Command,
44
+ parameters: {
45
+ layout: "fullscreen",
46
+ backgrounds: {
47
+ default: "dark",
48
+ values: [
49
+ { name: "dark", value: "#0a0a0a" },
50
+ { name: "light", value: "#ffffff" },
51
+ ],
52
+ },
53
+ docs: {
54
+ description: {
55
+ component: `
56
+ # Command Component
57
+
58
+ A fast, unstyled command menu component built on top of CMDK with integration to our design system's List components. Perfect for creating command palettes, search interfaces, and quick action menus.
59
+
60
+ ## Features
61
+
62
+ - **Fast Fuzzy Search**: Built-in fuzzy search with instant results
63
+ - **Keyboard Navigation**: Full keyboard support with arrow keys and Enter
64
+ - **Grouping**: Organize commands into logical groups with labels
65
+ - **Shortcuts**: Display keyboard shortcuts for commands
66
+ - **Icon Support**: Rich icon support for visual command identification
67
+ - **Customizable**: Extensive theming and styling options
68
+ - **Accessible**: ARIA compliant with screen reader support
69
+ - **Dialog Mode**: Can be used as a modal command palette
70
+ - **Empty States**: Customizable empty state when no results found
71
+
72
+ ## Usage Examples
73
+
74
+ ### Basic Command Menu
75
+ \`\`\`tsx
76
+ <Command>
77
+ <CommandInput placeholder="Type a command..." />
78
+ <CommandList>
79
+ <CommandEmpty>No results found.</CommandEmpty>
80
+ <CommandGroup>
81
+ <CommandLabel>Suggestions</CommandLabel>
82
+ <CommandItem>
83
+ <FileChartIcon />
84
+ New File
85
+ <CommandShortcut>⌘N</CommandShortcut>
86
+ </CommandItem>
87
+ </CommandGroup>
88
+ </CommandList>
89
+ </Command>
90
+ \`\`\`
91
+
92
+ ### Command Dialog
93
+ \`\`\`tsx
94
+ <CommandDialog open={open} onOpenChange={setOpen}>
95
+ <CommandInput placeholder="Search commands..." />
96
+ <CommandList>
97
+ <CommandEmpty>No commands found.</CommandEmpty>
98
+ <CommandGroup>
99
+ <CommandLabel>Actions</CommandLabel>
100
+ <CommandItem>Save File</CommandItem>
101
+ <CommandItem>Export</CommandItem>
102
+ </CommandGroup>
103
+ </CommandList>
104
+ </CommandDialog>
105
+ \`\`\`
106
+
107
+ ### With Custom Styling
108
+ \`\`\`tsx
109
+ <Command
110
+ listProps={{ variant: "elevated", size: "lg" }}
111
+ classes={{ list: "custom-command-list" }}
112
+ >
113
+ <CommandInput />
114
+ <CommandList>
115
+ <CommandItem variant="destructive">Delete</CommandItem>
116
+ </CommandList>
117
+ </Command>
118
+ \`\`\`
119
+ `,
120
+ },
121
+ },
122
+ },
123
+ tags: ["autodocs"],
124
+ }
125
+
126
+ export default meta
127
+ type Story = StoryObj<typeof Command>
128
+
129
+ // 1. Basic Command
130
+ export const BasicCommand: Story = {
131
+ render: () => (
132
+ <div className="mx-auto max-w-lg p-8">
133
+ <h3 className="mb-4 text-lg font-medium text-white">
134
+ Basic Command Menu
135
+ </h3>
136
+ <Command className="rounded-lg border border-white/10">
137
+ <CommandInput placeholder="Type a command or search..." />
138
+ <CommandList>
139
+ <CommandEmpty>No results found.</CommandEmpty>
140
+ <CommandGroup>
141
+ <CommandLabel>Suggestions</CommandLabel>
142
+ <CommandItem>
143
+ <SearchIcon />
144
+ Search Files
145
+ </CommandItem>
146
+ <CommandItem>
147
+ <ImageIcon />
148
+ View Images
149
+ </CommandItem>
150
+ <CommandItem>
151
+ <FileChartIcon />
152
+ Open Reports
153
+ </CommandItem>
154
+ </CommandGroup>
155
+ <CommandSeparator />
156
+ <CommandGroup>
157
+ <CommandLabel>Settings</CommandLabel>
158
+ <CommandItem shortcut="⌘P">
159
+ <EyeOpenIcon />
160
+ View Profile
161
+ </CommandItem>
162
+ <CommandItem shortcut="⌘,">
163
+ <MaintenanceIcon />
164
+ Settings
165
+ </CommandItem>
166
+ </CommandGroup>
167
+ </CommandList>
168
+ </Command>
169
+ </div>
170
+ ),
171
+ parameters: {
172
+ docs: {
173
+ description: {
174
+ story:
175
+ "A basic command menu with search input, grouped items, icons, and keyboard shortcuts.",
176
+ },
177
+ },
178
+ },
179
+ }
180
+
181
+ // 2. Command Dialog
182
+ export const CommandDialogExample: Story = {
183
+ render: () => {
184
+ const [open, setOpen] = React.useState(false)
185
+
186
+ React.useEffect(() => {
187
+ const down = (e: KeyboardEvent) => {
188
+ if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
189
+ e.preventDefault()
190
+ setOpen((open) => !open)
191
+ }
192
+ }
193
+
194
+ document.addEventListener("keydown", down)
195
+ return () => document.removeEventListener("keydown", down)
196
+ }, [])
197
+
198
+ return (
199
+ <div className="space-y-8 p-8">
200
+ <div className="text-center">
201
+ <h3 className="mb-2 text-lg font-medium text-white">
202
+ Command Dialog
203
+ </h3>
204
+ <p className="text-sm text-white/60">
205
+ Press{" "}
206
+ <kbd className="bg-muted text-muted-foreground pointer-events-none inline-flex h-5 items-center gap-1 rounded border px-1.5 font-mono text-[10px] font-medium opacity-100 select-none">
207
+ <span className="text-xs">⌘</span>K
208
+ </kbd>{" "}
209
+ to open the command dialog
210
+ </p>
211
+ </div>
212
+
213
+ <div className="flex justify-center">
214
+ <Button
215
+ variant="outline"
216
+ onClick={() => setOpen(true)}
217
+ className="relative w-80"
218
+ innerClassName="flex items-center justify-between gap-2"
219
+ >
220
+ <span className="flex items-center gap-2">
221
+ <SearchIcon className="mr-2 h-4 w-4" />
222
+ Search commands...
223
+ </span>
224
+ <kbd className="font-fm-brand text-fm-xs pointer-events-none hidden h-5 items-center gap-1 rounded border px-1.5 font-medium opacity-100 select-none sm:flex">
225
+ <span className="text-xs">⌘</span>K
226
+ </kbd>
227
+ </Button>
228
+ </div>
229
+
230
+ <CommandDialog
231
+ open={open}
232
+ onOpenChange={setOpen}
233
+ title="Command Palette"
234
+ description="Search for commands and actions"
235
+ >
236
+ <CommandInput placeholder="Type a command or search..." />
237
+ <CommandList>
238
+ <CommandEmpty>No results found.</CommandEmpty>
239
+ <CommandGroup>
240
+ <CommandLabel>Quick Actions</CommandLabel>
241
+ <CommandItem onSelect={() => setOpen(false)}>
242
+ <FileChartIcon />
243
+ New File
244
+ <CommandShortcut>⌘N</CommandShortcut>
245
+ </CommandItem>
246
+ <CommandItem onSelect={() => setOpen(false)}>
247
+ <ImportFolderIcon />
248
+ Import Folder
249
+ <CommandShortcut>⌘⇧N</CommandShortcut>
250
+ </CommandItem>
251
+ <CommandItem onSelect={() => setOpen(false)}>
252
+ <UploadIcon />
253
+ Upload
254
+ <CommandShortcut>⌘U</CommandShortcut>
255
+ </CommandItem>
256
+ <CommandItem onSelect={() => setOpen(false)}>
257
+ <ImageIcon />
258
+ Add Image
259
+ <CommandShortcut>⌘I</CommandShortcut>
260
+ </CommandItem>
261
+ </CommandGroup>
262
+ <CommandSeparator />
263
+ <CommandGroup>
264
+ <CommandLabel>Navigation</CommandLabel>
265
+ <CommandItem onSelect={() => setOpen(false)}>
266
+ <ArrowRightIcon />
267
+ Go Forward
268
+ <CommandShortcut>⌘→</CommandShortcut>
269
+ </CommandItem>
270
+ <CommandItem onSelect={() => setOpen(false)}>
271
+ <ChevronLeftIcon />
272
+ Go Back
273
+ <CommandShortcut>⌘←</CommandShortcut>
274
+ </CommandItem>
275
+ <CommandItem onSelect={() => setOpen(false)}>
276
+ <ChevronUpIcon />
277
+ Go Up
278
+ <CommandShortcut>⌘↑</CommandShortcut>
279
+ </CommandItem>
280
+ </CommandGroup>
281
+ <CommandSeparator />
282
+ <CommandGroup>
283
+ <CommandLabel>Dangerous Actions</CommandLabel>
284
+ <CommandItem
285
+ variant="destructive"
286
+ onSelect={() => setOpen(false)}
287
+ >
288
+ <TrashIcon />
289
+ Delete
290
+ <CommandShortcut>⌘⌫</CommandShortcut>
291
+ </CommandItem>
292
+ </CommandGroup>
293
+ </CommandList>
294
+ </CommandDialog>
295
+ </div>
296
+ )
297
+ },
298
+ parameters: {
299
+ docs: {
300
+ description: {
301
+ story:
302
+ "A command dialog that can be opened with ⌘K. Includes multiple command groups and keyboard shortcuts.",
303
+ },
304
+ },
305
+ },
306
+ }
307
+
308
+ // 3. File Management Commands
309
+ export const FileManagementCommands: Story = {
310
+ render: () => (
311
+ <div className="mx-auto max-w-lg space-y-8 p-8">
312
+ <h3 className="text-lg font-medium text-white">File Management</h3>
313
+ <Command className="rounded-lg border border-white/10">
314
+ <CommandInput placeholder="Search files and actions..." />
315
+ <CommandList>
316
+ <CommandEmpty>
317
+ <div className="py-6 text-center">
318
+ <SearchIcon className="mx-auto h-8 w-8 text-white/30" />
319
+ <p className="mt-2 text-sm text-white/60">
320
+ No files or actions found.
321
+ </p>
322
+ </div>
323
+ </CommandEmpty>
324
+
325
+ <CommandGroup>
326
+ <CommandLabel>Create</CommandLabel>
327
+ <CommandItem>
328
+ <FileChartIcon />
329
+ New Document
330
+ <CommandShortcut>⌘N</CommandShortcut>
331
+ </CommandItem>
332
+ <CommandItem>
333
+ <ImportFolderIcon />
334
+ New Folder
335
+ <CommandShortcut>⌘⇧N</CommandShortcut>
336
+ </CommandItem>
337
+ <CommandItem>
338
+ <EditBigIcon />
339
+ New Template
340
+ <CommandShortcut>⌘T</CommandShortcut>
341
+ </CommandItem>
342
+ </CommandGroup>
343
+
344
+ <CommandSeparator />
345
+
346
+ <CommandGroup>
347
+ <CommandLabel>Actions</CommandLabel>
348
+ <CommandItem>
349
+ <BubbleCheckIcon />
350
+ Approve
351
+ <CommandShortcut>⌘A</CommandShortcut>
352
+ </CommandItem>
353
+ <CommandItem>
354
+ <EditBigIcon />
355
+ Edit
356
+ <CommandShortcut>⌘E</CommandShortcut>
357
+ </CommandItem>
358
+ <CommandItem>
359
+ <BubbleSparkleIcon />
360
+ Share
361
+ <CommandShortcut>⌘⇧S</CommandShortcut>
362
+ </CommandItem>
363
+ <CommandItem>
364
+ <TickIcon />
365
+ Mark Complete
366
+ <CommandShortcut>⌘⇧F</CommandShortcut>
367
+ </CommandItem>
368
+ </CommandGroup>
369
+
370
+ <CommandSeparator />
371
+
372
+ <CommandGroup>
373
+ <CommandLabel>Import/Export</CommandLabel>
374
+ <CommandItem>
375
+ <UploadIcon />
376
+ Import Files
377
+ <CommandShortcut>⌘I</CommandShortcut>
378
+ </CommandItem>
379
+ <CommandItem>
380
+ <ArrowRightIcon />
381
+ Export Selection
382
+ <CommandShortcut>⌘E</CommandShortcut>
383
+ </CommandItem>
384
+ <CommandItem>
385
+ <MaintenanceIcon />
386
+ Sync
387
+ <CommandShortcut>⌘R</CommandShortcut>
388
+ </CommandItem>
389
+ </CommandGroup>
390
+
391
+ <CommandSeparator />
392
+
393
+ <CommandGroup>
394
+ <CommandLabel>Danger Zone</CommandLabel>
395
+ <CommandItem variant="destructive">
396
+ <TrashIcon />
397
+ Move to Trash
398
+ <CommandShortcut>⌘⌫</CommandShortcut>
399
+ </CommandItem>
400
+ </CommandGroup>
401
+ </CommandList>
402
+ </Command>
403
+ </div>
404
+ ),
405
+ parameters: {
406
+ docs: {
407
+ description: {
408
+ story:
409
+ "File management command palette with create, action, import/export, and destructive commands organized in groups.",
410
+ },
411
+ },
412
+ },
413
+ }
414
+
415
+ // 4. Search and Filter Commands
416
+ export const SearchAndFilterCommands: Story = {
417
+ render: () => {
418
+ const [searchTerm, setSearchTerm] = React.useState("")
419
+
420
+ const allItems = [
421
+ {
422
+ id: "recent",
423
+ label: "Recent Files",
424
+ icon: <FileChartIcon />,
425
+ group: "Quick Access",
426
+ },
427
+ {
428
+ id: "images",
429
+ label: "Images",
430
+ icon: <ImageIcon />,
431
+ group: "Quick Access",
432
+ },
433
+ {
434
+ id: "uploads",
435
+ label: "Uploads",
436
+ icon: <UploadIcon />,
437
+ group: "Quick Access",
438
+ },
439
+ {
440
+ id: "magic",
441
+ label: "Magic Book",
442
+ icon: <MagicBookIcon />,
443
+ group: "Quick Access",
444
+ },
445
+ {
446
+ id: "charts",
447
+ label: "Charts",
448
+ icon: <FileChartIcon />,
449
+ group: "Apps",
450
+ },
451
+ {
452
+ id: "search",
453
+ label: "Search",
454
+ icon: <SearchIcon />,
455
+ group: "Apps",
456
+ },
457
+ {
458
+ id: "maintenance",
459
+ label: "Maintenance",
460
+ icon: <MaintenanceIcon />,
461
+ group: "Apps",
462
+ },
463
+ {
464
+ id: "profile",
465
+ label: "Profile",
466
+ icon: <EyeOpenIcon />,
467
+ group: "Account",
468
+ },
469
+ {
470
+ id: "features",
471
+ label: "Features",
472
+ icon: <FeatureShineIcon />,
473
+ group: "Account",
474
+ },
475
+ ]
476
+
477
+ const filteredItems = searchTerm
478
+ ? allItems.filter((item) =>
479
+ item.label.toLowerCase().includes(searchTerm.toLowerCase())
480
+ )
481
+ : allItems
482
+
483
+ const groupedItems = filteredItems.reduce(
484
+ (acc, item) => {
485
+ if (!acc[item.group]) {
486
+ acc[item.group] = []
487
+ }
488
+ acc[item.group].push(item)
489
+ return acc
490
+ },
491
+ {} as Record<string, typeof allItems>
492
+ )
493
+
494
+ return (
495
+ <div className="mx-auto max-w-lg space-y-8 p-8">
496
+ <div className="space-y-2">
497
+ <h3 className="text-lg font-medium text-white">Search and Filter</h3>
498
+ <p className="text-sm text-white/60">
499
+ Dynamic filtering based on search input
500
+ </p>
501
+ </div>
502
+
503
+ <Command className="rounded-lg border border-white/10">
504
+ <CommandInput
505
+ placeholder="Search apps, files, and more..."
506
+ value={searchTerm}
507
+ onValueChange={setSearchTerm}
508
+ />
509
+ <CommandList>
510
+ <CommandEmpty>
511
+ <div className="py-6 text-center">
512
+ <SearchIcon className="mx-auto h-8 w-8 text-white/30" />
513
+ <p className="mt-2 text-sm text-white/60">
514
+ No results for "{searchTerm}"
515
+ </p>
516
+ <p className="text-xs text-white/40">
517
+ Try searching for something else
518
+ </p>
519
+ </div>
520
+ </CommandEmpty>
521
+
522
+ {Object.entries(groupedItems).map(([group, items]) => (
523
+ <React.Fragment key={group}>
524
+ <CommandGroup>
525
+ <CommandLabel>{group}</CommandLabel>
526
+ {items.map((item) => (
527
+ <CommandItem key={item.id}>
528
+ {item.icon}
529
+ {item.label}
530
+ </CommandItem>
531
+ ))}
532
+ </CommandGroup>
533
+ {Object.keys(groupedItems).indexOf(group) <
534
+ Object.keys(groupedItems).length - 1 && <CommandSeparator />}
535
+ </React.Fragment>
536
+ ))}
537
+ </CommandList>
538
+ </Command>
539
+
540
+ {searchTerm && (
541
+ <div className="rounded-lg border border-white/10 bg-white/5 p-4">
542
+ <h4 className="text-sm font-medium text-white">Search Stats</h4>
543
+ <div className="mt-2 space-y-1 text-xs text-white/60">
544
+ <p>Search term: "{searchTerm}"</p>
545
+ <p>Results found: {filteredItems.length}</p>
546
+ <p>Groups: {Object.keys(groupedItems).length}</p>
547
+ </div>
548
+ </div>
549
+ )}
550
+ </div>
551
+ )
552
+ },
553
+ parameters: {
554
+ docs: {
555
+ description: {
556
+ story:
557
+ "Dynamic command menu that filters results based on search input with real-time statistics.",
558
+ },
559
+ },
560
+ },
561
+ }
562
+
563
+ // 5. Custom Styling Variants
564
+ export const CustomStylingVariants: Story = {
565
+ render: () => (
566
+ <div className="space-y-8 p-8">
567
+ <h3 className="text-center text-lg font-medium text-white">
568
+ Custom Styling Variants
569
+ </h3>
570
+
571
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
572
+ {/* Elevated Command */}
573
+ <div className="space-y-4">
574
+ <h4 className="text-sm font-medium text-white/70">Elevated Style</h4>
575
+ <Command
576
+ className="rounded-lg border border-white/10"
577
+ listProps={{ variant: "elevated", size: "lg" }}
578
+ >
579
+ <CommandInput placeholder="Elevated command menu..." />
580
+ <CommandList>
581
+ <CommandEmpty>No results found.</CommandEmpty>
582
+ <CommandGroup>
583
+ <CommandLabel>Premium Actions</CommandLabel>
584
+ <CommandItem>
585
+ <FeatureShineIcon />
586
+ Premium Feature
587
+ <Badge color="positive" className="ml-auto">
588
+ Pro
589
+ </Badge>
590
+ </CommandItem>
591
+ <CommandItem>
592
+ <BubbleSparkleIcon />
593
+ Favorite
594
+ </CommandItem>
595
+ </CommandGroup>
596
+ </CommandList>
597
+ </Command>
598
+ </div>
599
+
600
+ {/* Compact Command */}
601
+ <div className="space-y-4">
602
+ <h4 className="text-sm font-medium text-white/70">Compact Style</h4>
603
+ <Command
604
+ className="rounded-lg border border-white/10"
605
+ listProps={{ size: "sm" }}
606
+ >
607
+ <CommandInput
608
+ placeholder="Compact menu..."
609
+ classes={{ input: "text-xs" }}
610
+ />
611
+ <CommandList>
612
+ <CommandEmpty>No results found.</CommandEmpty>
613
+ <CommandGroup>
614
+ <CommandLabel>Quick Actions</CommandLabel>
615
+ <CommandItem>
616
+ <FileChartIcon />
617
+ New
618
+ <CommandShortcut>⌘N</CommandShortcut>
619
+ </CommandItem>
620
+ <CommandItem>
621
+ <SearchIcon />
622
+ Find
623
+ <CommandShortcut>⌘F</CommandShortcut>
624
+ </CommandItem>
625
+ <CommandItem>
626
+ <MaintenanceIcon />
627
+ Refresh
628
+ <CommandShortcut>⌘R</CommandShortcut>
629
+ </CommandItem>
630
+ </CommandGroup>
631
+ </CommandList>
632
+ </Command>
633
+ </div>
634
+
635
+ {/* Flat Style */}
636
+ <div className="space-y-4">
637
+ <h4 className="text-sm font-medium text-white/70">Flat Style</h4>
638
+ <Command
639
+ className="rounded-lg border border-white/10"
640
+ listProps={{ variant: "flat", rounded: "lg" }}
641
+ >
642
+ <CommandInput placeholder="Flat design menu..." />
643
+ <CommandList>
644
+ <CommandEmpty>No results found.</CommandEmpty>
645
+ <CommandGroup>
646
+ <CommandLabel>Interface</CommandLabel>
647
+ <CommandItem>
648
+ <MaintenanceIcon />
649
+ Settings
650
+ </CommandItem>
651
+ <CommandItem>
652
+ <EyeOpenIcon />
653
+ Account
654
+ </CommandItem>
655
+ </CommandGroup>
656
+ </CommandList>
657
+ </Command>
658
+ </div>
659
+
660
+ {/* Custom Classes */}
661
+ <div className="space-y-4">
662
+ <h4 className="text-sm font-medium text-white/70">Custom Classes</h4>
663
+ <Command
664
+ className="rounded-lg border border-purple-500/30 bg-purple-900/10"
665
+ classes={{
666
+ list: "bg-purple-900/20",
667
+ }}
668
+ >
669
+ <CommandInput
670
+ placeholder="Purple themed menu..."
671
+ classes={{
672
+ wrapper: "border-purple-500/30",
673
+ icon: "text-purple-400",
674
+ }}
675
+ />
676
+ <CommandList>
677
+ <CommandEmpty>No results found.</CommandEmpty>
678
+ <CommandGroup>
679
+ <CommandLabel>Custom Theme</CommandLabel>
680
+ <CommandItem classes={{ root: "hover:bg-purple-500/20" }}>
681
+ <FeatureShineIcon />
682
+ Special Action
683
+ </CommandItem>
684
+ <CommandItem classes={{ root: "hover:bg-purple-500/20" }}>
685
+ <BubbleSparkleIcon />
686
+ Another Action
687
+ </CommandItem>
688
+ </CommandGroup>
689
+ </CommandList>
690
+ </Command>
691
+ </div>
692
+ </div>
693
+ </div>
694
+ ),
695
+ parameters: {
696
+ docs: {
697
+ description: {
698
+ story:
699
+ "Various styling options including elevated, compact, flat styles and custom theming with purple color scheme.",
700
+ },
701
+ },
702
+ },
703
+ }
704
+
705
+ // 6. Complex Command Structure
706
+ export const ComplexCommandStructure: Story = {
707
+ render: () => (
708
+ <div className="mx-auto max-w-lg space-y-8 p-8">
709
+ <h3 className="text-lg font-medium text-white">
710
+ Complex Command Structure
711
+ </h3>
712
+
713
+ <Command className="rounded-lg border border-white/10">
714
+ <CommandInput placeholder="Search all commands..." />
715
+ <CommandList>
716
+ <CommandEmpty>
717
+ <div className="py-8 text-center">
718
+ <SearchIcon className="mx-auto h-12 w-12 text-white/20" />
719
+ <h4 className="mt-2 text-sm font-medium text-white">
720
+ No commands found
721
+ </h4>
722
+ <p className="mt-1 text-xs text-white/60">
723
+ Try adjusting your search to find what you're looking for.
724
+ </p>
725
+ </div>
726
+ </CommandEmpty>
727
+
728
+ <CommandGroup>
729
+ <CommandLabel>
730
+ <FileChartIcon className="mr-2" />
731
+ File Operations
732
+ </CommandLabel>
733
+ <CommandItem>
734
+ <FileChartIcon />
735
+ New Document
736
+ <Badge color="info" className="ml-auto">
737
+ Ctrl+N
738
+ </Badge>
739
+ </CommandItem>
740
+ <CommandItem>
741
+ <ImportFolderIcon />
742
+ Open Folder
743
+ <CommandShortcut>⌘O</CommandShortcut>
744
+ </CommandItem>
745
+ <CommandItem>
746
+ <EditBigIcon />
747
+ Recent Files
748
+ <Badge color="neutral" className="ml-auto">
749
+ 5
750
+ </Badge>
751
+ </CommandItem>
752
+ </CommandGroup>
753
+
754
+ <CommandSeparator />
755
+
756
+ <CommandGroup>
757
+ <CommandLabel>
758
+ <EyeOpenIcon className="mr-2" />
759
+ User Management
760
+ </CommandLabel>
761
+ <CommandItem>
762
+ <EyeOpenIcon />
763
+ View Profile
764
+ <CommandShortcut>⌘P</CommandShortcut>
765
+ </CommandItem>
766
+ <CommandItem>
767
+ <MaintenanceIcon />
768
+ User Settings
769
+ <CommandShortcut>⌘,</CommandShortcut>
770
+ </CommandItem>
771
+ <CommandItem>
772
+ <BubbleSparkleIcon />
773
+ Share Profile
774
+ <Badge color="warning" className="ml-auto">
775
+ Beta
776
+ </Badge>
777
+ </CommandItem>
778
+ </CommandGroup>
779
+
780
+ <CommandSeparator />
781
+
782
+ <CommandGroup>
783
+ <CommandLabel>
784
+ <UploadIcon className="mr-2" />
785
+ Data Management
786
+ </CommandLabel>
787
+ <CommandItem>
788
+ <ArrowRightIcon />
789
+ Export Data
790
+ <CommandShortcut>⌘E</CommandShortcut>
791
+ </CommandItem>
792
+ <CommandItem>
793
+ <UploadIcon />
794
+ Import Data
795
+ <CommandShortcut>⌘I</CommandShortcut>
796
+ </CommandItem>
797
+ <CommandItem>
798
+ <MaintenanceIcon />
799
+ Sync Data
800
+ <Badge color="positive" className="ml-auto">
801
+ Auto
802
+ </Badge>
803
+ </CommandItem>
804
+ </CommandGroup>
805
+
806
+ <CommandSeparator />
807
+
808
+ <CommandGroup>
809
+ <CommandLabel>
810
+ <FeatureShineIcon className="mr-2" />
811
+ Features
812
+ </CommandLabel>
813
+ <CommandItem>
814
+ <MagicBookIcon />
815
+ Magic Features
816
+ <Badge color="neutral" className="ml-auto">
817
+ 12
818
+ </Badge>
819
+ </CommandItem>
820
+ <CommandItem>
821
+ <LightBulbSimpleIcon />
822
+ Ideas
823
+ <Badge color="positive" className="ml-auto">
824
+ New
825
+ </Badge>
826
+ </CommandItem>
827
+ <CommandItem>
828
+ <FeatureShineIcon />
829
+ Special Features
830
+ <CommandShortcut>⌘⇧S</CommandShortcut>
831
+ </CommandItem>
832
+ </CommandGroup>
833
+
834
+ <CommandSeparator />
835
+
836
+ <CommandGroup>
837
+ <CommandLabel>
838
+ <TrashIcon className="mr-2" />
839
+ Dangerous Actions
840
+ </CommandLabel>
841
+ <CommandItem variant="destructive">
842
+ <TrashIcon />
843
+ Delete Account
844
+ <Badge color="negative" className="ml-auto">
845
+ !
846
+ </Badge>
847
+ </CommandItem>
848
+ <CommandItem variant="destructive">
849
+ <CrossCircleIcon />
850
+ Reset All Data
851
+ <CommandShortcut>⌘⇧R</CommandShortcut>
852
+ </CommandItem>
853
+ </CommandGroup>
854
+ </CommandList>
855
+ </Command>
856
+ </div>
857
+ ),
858
+ parameters: {
859
+ docs: {
860
+ description: {
861
+ story:
862
+ "Complex command structure with multiple groups, icons in labels, badges for additional context, and both regular and destructive actions.",
863
+ },
864
+ },
865
+ },
866
+ }
867
+
868
+ // 7. Performance Demo
869
+ export const PerformanceDemo: Story = {
870
+ render: () => {
871
+ const [itemCount, setItemCount] = React.useState(100)
872
+
873
+ const generateItems = (count: number) => {
874
+ const categories = ["Files", "Actions", "Settings", "Images", "Tools"]
875
+ const icons = [
876
+ FileChartIcon,
877
+ EditBigIcon,
878
+ MaintenanceIcon,
879
+ ImageIcon,
880
+ CommandIcon,
881
+ ]
882
+ const items = []
883
+
884
+ for (let i = 0; i < count; i++) {
885
+ const categoryIndex = i % categories.length
886
+ items.push({
887
+ id: i,
888
+ label: `${categories[categoryIndex]} Item ${i + 1}`,
889
+ icon: icons[categoryIndex],
890
+ category: categories[categoryIndex],
891
+ shortcut: i % 10 === 0 ? `⌘${i / 10}` : undefined,
892
+ })
893
+ }
894
+
895
+ return items
896
+ }
897
+
898
+ const items = React.useMemo(() => generateItems(itemCount), [itemCount])
899
+ const groupedItems = React.useMemo(() => {
900
+ return items.reduce(
901
+ (acc, item) => {
902
+ if (!acc[item.category]) {
903
+ acc[item.category] = []
904
+ }
905
+ acc[item.category].push(item)
906
+ return acc
907
+ },
908
+ {} as Record<string, typeof items>
909
+ )
910
+ }, [items])
911
+
912
+ return (
913
+ <div className="space-y-8 p-8">
914
+ <div className="space-y-4 text-center">
915
+ <h3 className="text-lg font-medium text-white">Performance Demo</h3>
916
+ <p className="text-sm text-white/60">
917
+ Test command menu performance with large datasets
918
+ </p>
919
+
920
+ <div className="flex items-center justify-center gap-4">
921
+ <label className="text-sm text-white/70">Items:</label>
922
+ <select
923
+ value={itemCount}
924
+ onChange={(e) => setItemCount(Number(e.target.value))}
925
+ className="rounded border border-white/20 bg-white/10 px-3 py-1 text-white"
926
+ >
927
+ <option value={50}>50</option>
928
+ <option value={100}>100</option>
929
+ <option value={500}>500</option>
930
+ <option value={1000}>1000</option>
931
+ </select>
932
+ <Badge color="info">{itemCount} items</Badge>
933
+ </div>
934
+ </div>
935
+
936
+ <div className="mx-auto max-w-lg">
937
+ <Command className="rounded-lg border border-white/10">
938
+ <CommandInput placeholder={`Search ${itemCount} items...`} />
939
+ <CommandList>
940
+ <CommandEmpty>
941
+ No results found in {itemCount} items.
942
+ </CommandEmpty>
943
+
944
+ {Object.entries(groupedItems).map(([category, categoryItems]) => (
945
+ <React.Fragment key={category}>
946
+ <CommandGroup>
947
+ <CommandLabel>
948
+ {category} ({categoryItems.length})
949
+ </CommandLabel>
950
+ {categoryItems.map((item) => {
951
+ const IconComponent = item.icon
952
+ return (
953
+ <CommandItem key={item.id}>
954
+ <IconComponent />
955
+ {item.label}
956
+ {item.shortcut && (
957
+ <CommandShortcut>{item.shortcut}</CommandShortcut>
958
+ )}
959
+ </CommandItem>
960
+ )
961
+ })}
962
+ </CommandGroup>
963
+ {Object.keys(groupedItems).indexOf(category) <
964
+ Object.keys(groupedItems).length - 1 && (
965
+ <CommandSeparator />
966
+ )}
967
+ </React.Fragment>
968
+ ))}
969
+ </CommandList>
970
+ </Command>
971
+ </div>
972
+
973
+ <div className="mx-auto max-w-lg rounded-lg border border-white/10 bg-white/5 p-4">
974
+ <h4 className="text-sm font-medium text-white">Performance Info</h4>
975
+ <div className="mt-2 grid grid-cols-2 gap-4 text-xs text-white/60">
976
+ <div>Total Items: {itemCount}</div>
977
+ <div>Categories: {Object.keys(groupedItems).length}</div>
978
+ <div>
979
+ Avg per Category:{" "}
980
+ {Math.round(itemCount / Object.keys(groupedItems).length)}
981
+ </div>
982
+ <div>With Shortcuts: {items.filter((i) => i.shortcut).length}</div>
983
+ </div>
984
+ </div>
985
+ </div>
986
+ )
987
+ },
988
+ parameters: {
989
+ docs: {
990
+ description: {
991
+ story:
992
+ "Performance demonstration with configurable item counts to test search and rendering performance with large datasets.",
993
+ },
994
+ },
995
+ },
996
+ }