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,678 @@
1
+ import React, { useState } from "react"
2
+ import { Button } from "@components/button"
3
+ import type { Meta, StoryObj } from "@storybook/react"
4
+
5
+ import Search, { SearchResult } from "."
6
+
7
+ const meta: Meta<typeof Search> = {
8
+ title: "Components/UI/Search",
9
+ component: Search,
10
+ parameters: {
11
+ layout: "centered",
12
+ backgrounds: {
13
+ default: "dark",
14
+ values: [
15
+ { name: "dark", value: "#0a0a0a" },
16
+ { name: "light", value: "#ffffff" },
17
+ ],
18
+ },
19
+ docs: {
20
+ description: {
21
+ component: `
22
+ # Search Component
23
+
24
+ A comprehensive search input component with both controlled and uncontrolled modes, built with dark theme optimization and flexible content rendering.
25
+
26
+ ## Features
27
+
28
+ - **Dual Mode Support**: Works as both controlled and uncontrolled component
29
+ - **Search Icon**: Built-in search icon with proper theming
30
+ - **Clear Functionality**: X button to clear search input
31
+ - **Flexible Results**: Custom children rendering for search results
32
+ - **Dark Theme Optimized**: Default styling for dark interfaces
33
+ - **Accessibility**: Full keyboard navigation and screen reader support
34
+ - **Event Handling**: Separate onChange and onSearch callbacks
35
+
36
+ ## Component Modes
37
+
38
+ ### Controlled Component
39
+ Use \`value\`, \`onChange\`, and \`onSearch\` for external state management:
40
+
41
+ \`\`\`tsx
42
+ const [searchValue, setSearchValue] = useState("")
43
+
44
+ <Search
45
+ value={searchValue}
46
+ onChange={setSearchValue}
47
+ onSearch={(query) => handleSearch(query)}
48
+ />
49
+ \`\`\`
50
+
51
+ ### Uncontrolled Component
52
+ Use \`initialValue\` and \`onSearch\` for internal state management:
53
+
54
+ \`\`\`tsx
55
+ <Search
56
+ initialValue="initial search"
57
+ onSearch={(query) => handleSearch(query)}
58
+ />
59
+ \`\`\`
60
+
61
+ ## Props Overview
62
+
63
+ - **value**: Current value (controlled mode)
64
+ - **onChange**: Value change handler (controlled mode)
65
+ - **initialValue**: Initial value (uncontrolled mode)
66
+ - **onSearch**: Search handler (both modes)
67
+ - **results**: Array of search results
68
+ - **children**: Custom content for rendering results
69
+ - **placeholder**: Input placeholder text
70
+ - **className**: Additional CSS classes
71
+ `,
72
+ },
73
+ },
74
+ },
75
+ tags: ["autodocs"],
76
+ }
77
+
78
+ export default meta
79
+ type Story = StoryObj<typeof Search>
80
+
81
+ // 1. Basic Search Component Examples
82
+ export const BasicSearch: Story = {
83
+ render: () => (
84
+ <div className="space-y-6">
85
+ <div className="text-center">
86
+ <h3 className="mb-2 font-medium text-white">Basic Search Component</h3>
87
+ <p className="text-sm text-white/60">
88
+ Simple search input with different placeholder examples
89
+ </p>
90
+ </div>
91
+
92
+ <div className="space-y-4">
93
+ {/* Default Placeholder */}
94
+ <div className="space-y-2">
95
+ <label className="text-sm font-medium text-white/80">Default</label>
96
+ <Search placeholder="Search episodes" />
97
+ </div>
98
+
99
+ {/* Custom Placeholders */}
100
+ <div className="space-y-2">
101
+ <label className="text-sm font-medium text-white/80">
102
+ Custom Placeholders
103
+ </label>
104
+ <div className="space-y-3">
105
+ <Search placeholder="Search podcasts..." />
106
+ <Search placeholder="Find your favorite shows" />
107
+ <Search placeholder="Type to search music" />
108
+ </div>
109
+ </div>
110
+
111
+ {/* With Initial Value */}
112
+ <div className="space-y-2">
113
+ <label className="text-sm font-medium text-white/80">
114
+ With Initial Value
115
+ </label>
116
+ <Search placeholder="Search episodes" initialValue="The Daily" />
117
+ </div>
118
+ </div>
119
+ </div>
120
+ ),
121
+ parameters: {
122
+ docs: {
123
+ description: {
124
+ story:
125
+ "Basic search component examples with different placeholder text and initial values.",
126
+ },
127
+ },
128
+ },
129
+ }
130
+
131
+ // 2. Controlled Component Examples
132
+ export const ControlledSearch: Story = {
133
+ render: () => {
134
+ const [searchValue1, setSearchValue1] = useState("")
135
+ const [searchValue2, setSearchValue2] = useState("Controlled")
136
+ const [searchValue3, setSearchValue3] = useState("")
137
+
138
+ return (
139
+ <div className="space-y-6">
140
+ <div className="text-center">
141
+ <h3 className="mb-2 font-medium text-white">Controlled Search</h3>
142
+ <p className="text-sm text-white/60">
143
+ Search components with external state control
144
+ </p>
145
+ </div>
146
+
147
+ <div className="space-y-6">
148
+ {/* Basic Controlled */}
149
+ <div className="space-y-3">
150
+ <div className="flex items-center justify-between">
151
+ <label className="text-sm font-medium text-white/80">
152
+ Basic Controlled
153
+ </label>
154
+ <div className="text-xs text-white/60">
155
+ Value: "{searchValue1}"
156
+ </div>
157
+ </div>
158
+ <Search
159
+ placeholder="Type something..."
160
+ value={searchValue1}
161
+ onChange={setSearchValue1}
162
+ />
163
+ <div className="flex gap-2">
164
+ <Button
165
+ size="sm"
166
+ variant="outline"
167
+ onClick={() => setSearchValue1("Preset Value")}
168
+ >
169
+ Set Value
170
+ </Button>
171
+ <Button
172
+ size="sm"
173
+ variant="outline"
174
+ onClick={() => setSearchValue1("")}
175
+ >
176
+ Clear
177
+ </Button>
178
+ </div>
179
+ </div>
180
+
181
+ {/* Pre-filled Controlled */}
182
+ <div className="space-y-3">
183
+ <div className="flex items-center justify-between">
184
+ <label className="text-sm font-medium text-white/80">
185
+ Pre-filled Controlled
186
+ </label>
187
+ <div className="text-xs text-white/60">
188
+ Value: "{searchValue2}"
189
+ </div>
190
+ </div>
191
+ <Search
192
+ placeholder="Search with preset value"
193
+ value={searchValue2}
194
+ onChange={setSearchValue2}
195
+ />
196
+ </div>
197
+
198
+ {/* Controlled with Validation */}
199
+ <div className="space-y-3">
200
+ <div className="flex items-center justify-between">
201
+ <label className="text-sm font-medium text-white/80">
202
+ With Validation
203
+ </label>
204
+ <div className="text-xs text-white/60">
205
+ Length: {searchValue3.length}/20
206
+ </div>
207
+ </div>
208
+ <Search
209
+ placeholder="Max 20 characters"
210
+ value={searchValue3}
211
+ onChange={(value) => {
212
+ if (value.length <= 20) {
213
+ setSearchValue3(value)
214
+ }
215
+ }}
216
+ />
217
+ {searchValue3.length >= 20 && (
218
+ <p className="text-xs text-red-400">Maximum length reached</p>
219
+ )}
220
+ </div>
221
+ </div>
222
+ </div>
223
+ )
224
+ },
225
+ parameters: {
226
+ docs: {
227
+ description: {
228
+ story:
229
+ "Controlled search component examples showing external state management, pre-filled values, and validation.",
230
+ },
231
+ },
232
+ },
233
+ }
234
+
235
+ // 3. Uncontrolled Component Examples
236
+ export const UncontrolledSearch: Story = {
237
+ render: () => {
238
+ const [lastSearch1, setLastSearch1] = useState("")
239
+ const [lastSearch2, setLastSearch2] = useState("")
240
+
241
+ return (
242
+ <div className="space-y-6">
243
+ <div className="text-center">
244
+ <h3 className="mb-2 font-medium text-white">Uncontrolled Search</h3>
245
+ <p className="text-sm text-white/60">
246
+ Search components with internal state management
247
+ </p>
248
+ </div>
249
+
250
+ <div className="space-y-6">
251
+ {/* Basic Uncontrolled */}
252
+ <div className="space-y-3">
253
+ <div className="flex items-center justify-between">
254
+ <label className="text-sm font-medium text-white/80">
255
+ Basic Uncontrolled
256
+ </label>
257
+ <div className="text-xs text-white/60">
258
+ Last search: "{lastSearch1}"
259
+ </div>
260
+ </div>
261
+ <Search
262
+ placeholder="Search internally managed"
263
+ onSearch={setLastSearch1}
264
+ />
265
+ </div>
266
+
267
+ {/* With Initial Value */}
268
+ <div className="space-y-3">
269
+ <div className="flex items-center justify-between">
270
+ <label className="text-sm font-medium text-white/80">
271
+ With Initial Value
272
+ </label>
273
+ <div className="text-xs text-white/60">
274
+ Last search: "{lastSearch2}"
275
+ </div>
276
+ </div>
277
+ <Search
278
+ placeholder="Search with initial value"
279
+ initialValue="Initial Search"
280
+ onSearch={setLastSearch2}
281
+ />
282
+ </div>
283
+
284
+ {/* Multiple Independent */}
285
+ <div className="space-y-3">
286
+ <label className="text-sm font-medium text-white/80">
287
+ Multiple Independent
288
+ </label>
289
+ <div className="grid grid-cols-2 gap-3">
290
+ <Search placeholder="Search A" />
291
+ <Search placeholder="Search B" />
292
+ </div>
293
+ <p className="text-xs text-white/60">
294
+ Each search maintains its own independent state
295
+ </p>
296
+ </div>
297
+ </div>
298
+ </div>
299
+ )
300
+ },
301
+ parameters: {
302
+ docs: {
303
+ description: {
304
+ story:
305
+ "Uncontrolled search component examples with internal state management and initial values.",
306
+ },
307
+ },
308
+ },
309
+ }
310
+
311
+ // 4. Interactive Search with Results
312
+ export const InteractiveSearch: Story = {
313
+ render: () => {
314
+ const [query, setQuery] = useState("")
315
+ const [results, setResults] = useState<SearchResult[]>([])
316
+ const [selectedResult, setSelectedResult] = useState<string | null>(null)
317
+
318
+ // Mock search data
319
+ const allPodcasts = [
320
+ { id: "1", text: "The Joe Rogan Experience" },
321
+ { id: "2", text: "Serial" },
322
+ { id: "3", text: "This American Life" },
323
+ { id: "4", text: "Stuff You Should Know" },
324
+ { id: "5", text: "The Daily" },
325
+ { id: "6", text: "Crime Junkie" },
326
+ { id: "7", text: "The Michelle Obama Podcast" },
327
+ { id: "8", text: "Call Her Daddy" },
328
+ { id: "9", text: "My Favorite Murder" },
329
+ { id: "10", text: "The Tim Ferriss Show" },
330
+ { id: "11", text: "Conan O'Brien Needs a Friend" },
331
+ { id: "12", text: "The Ben Shapiro Show" },
332
+ ]
333
+
334
+ const handleSearch = (searchQuery: string) => {
335
+ setQuery(searchQuery)
336
+
337
+ if (!searchQuery.trim()) {
338
+ setResults([])
339
+ return
340
+ }
341
+
342
+ // Filter podcasts based on query
343
+ const filteredResults = allPodcasts.filter((podcast) =>
344
+ podcast.text.toLowerCase().includes(searchQuery.toLowerCase())
345
+ )
346
+
347
+ setResults(filteredResults)
348
+ }
349
+
350
+ return (
351
+ <div className="w-96 space-y-4">
352
+ <div className="text-center">
353
+ <h3 className="mb-2 font-medium text-white">Interactive Search</h3>
354
+ <p className="text-sm text-white/60">
355
+ Real-time search with custom results rendering
356
+ </p>
357
+ </div>
358
+
359
+ <Search
360
+ placeholder="Search podcasts..."
361
+ value={query}
362
+ onChange={setQuery}
363
+ onSearch={handleSearch}
364
+ results={results}
365
+ >
366
+ {/* Custom Results Rendering */}
367
+ {results.length > 0 && (
368
+ <div className="mt-2 rounded-lg border border-white/10 bg-gray-800/90 shadow-xl">
369
+ <div className="p-3">
370
+ <div className="mb-2 flex items-center justify-between">
371
+ <span className="text-xs font-medium text-white/80">
372
+ Search Results
373
+ </span>
374
+ <span className="text-xs text-white/60">
375
+ {results.length} found
376
+ </span>
377
+ </div>
378
+ <div className="max-h-64 space-y-1 overflow-y-auto">
379
+ {results.map((result) => (
380
+ <button
381
+ key={result.id}
382
+ onClick={() => {
383
+ setSelectedResult(result.text)
384
+ setQuery(result.text)
385
+ setResults([])
386
+ }}
387
+ className="w-full rounded px-3 py-2 text-left text-sm text-white hover:bg-white/10"
388
+ >
389
+ {result.text}
390
+ </button>
391
+ ))}
392
+ </div>
393
+ </div>
394
+ </div>
395
+ )}
396
+ </Search>
397
+
398
+ {/* Search Info */}
399
+ <div className="rounded-lg border border-white/10 bg-white/5 p-4">
400
+ <h4 className="mb-2 text-sm font-medium text-white">Search Info</h4>
401
+ <div className="space-y-1 text-xs text-white/60">
402
+ <div>Query: "{query || "(empty)"}"</div>
403
+ <div>Results: {results.length}</div>
404
+ <div>Selected: {selectedResult || "(none)"}</div>
405
+ </div>
406
+ </div>
407
+ </div>
408
+ )
409
+ },
410
+ parameters: {
411
+ docs: {
412
+ description: {
413
+ story:
414
+ "Interactive search example with real-time filtering, custom results rendering, and selection handling.",
415
+ },
416
+ },
417
+ },
418
+ }
419
+
420
+ // 5. Search with Different States
421
+ export const SearchStates: Story = {
422
+ render: () => {
423
+ const [loadingQuery, setLoadingQuery] = useState("")
424
+ const [errorQuery, setErrorQuery] = useState("")
425
+ const [emptyQuery, setEmptyQuery] = useState("nonexistent")
426
+
427
+ return (
428
+ <div className="space-y-6">
429
+ <div className="text-center">
430
+ <h3 className="mb-2 font-medium text-white">Search States</h3>
431
+ <p className="text-sm text-white/60">
432
+ Different search states and feedback
433
+ </p>
434
+ </div>
435
+
436
+ <div className="grid gap-6">
437
+ {/* Loading State */}
438
+ <div className="space-y-3">
439
+ <label className="text-sm font-medium text-white/80">
440
+ Loading State
441
+ </label>
442
+ <Search
443
+ placeholder="Search with loading..."
444
+ value={loadingQuery}
445
+ onChange={setLoadingQuery}
446
+ onSearch={setLoadingQuery}
447
+ >
448
+ {loadingQuery && (
449
+ <div className="mt-2 rounded-lg border border-white/10 bg-gray-800/90 p-4 text-center">
450
+ <div className="flex items-center justify-center gap-2">
451
+ <div className="h-4 w-4 animate-spin rounded-full border-2 border-white/20 border-t-white"></div>
452
+ <span className="text-sm text-white/80">Searching...</span>
453
+ </div>
454
+ </div>
455
+ )}
456
+ </Search>
457
+ </div>
458
+
459
+ {/* Error State */}
460
+ <div className="space-y-3">
461
+ <label className="text-sm font-medium text-white/80">
462
+ Error State
463
+ </label>
464
+ <Search
465
+ placeholder="Search with error..."
466
+ value={errorQuery}
467
+ onChange={setErrorQuery}
468
+ onSearch={setErrorQuery}
469
+ >
470
+ {errorQuery && (
471
+ <div className="mt-2 rounded-lg border border-red-500/30 bg-red-900/30 p-4">
472
+ <div className="flex items-center gap-2">
473
+ <svg
474
+ className="h-4 w-4 text-red-400"
475
+ fill="none"
476
+ stroke="currentColor"
477
+ viewBox="0 0 24 24"
478
+ >
479
+ <path
480
+ strokeLinecap="round"
481
+ strokeLinejoin="round"
482
+ strokeWidth={2}
483
+ d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
484
+ />
485
+ </svg>
486
+ <span className="text-sm text-red-400">
487
+ Search failed. Please try again.
488
+ </span>
489
+ </div>
490
+ </div>
491
+ )}
492
+ </Search>
493
+ </div>
494
+
495
+ {/* Empty State */}
496
+ <div className="space-y-3">
497
+ <label className="text-sm font-medium text-white/80">
498
+ Empty Results
499
+ </label>
500
+ <Search
501
+ placeholder="Search with no results..."
502
+ value={emptyQuery}
503
+ onChange={setEmptyQuery}
504
+ onSearch={setEmptyQuery}
505
+ >
506
+ {emptyQuery && (
507
+ <div className="mt-2 rounded-lg border border-white/10 bg-gray-800/90 p-4 text-center">
508
+ <div className="space-y-2">
509
+ <svg
510
+ className="mx-auto h-8 w-8 text-white/40"
511
+ fill="none"
512
+ stroke="currentColor"
513
+ viewBox="0 0 24 24"
514
+ >
515
+ <path
516
+ strokeLinecap="round"
517
+ strokeLinejoin="round"
518
+ strokeWidth={2}
519
+ d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
520
+ />
521
+ </svg>
522
+ <div>
523
+ <p className="text-sm font-medium text-white">
524
+ No results found
525
+ </p>
526
+ <p className="text-xs text-white/60">
527
+ Try different keywords or check your spelling
528
+ </p>
529
+ </div>
530
+ </div>
531
+ </div>
532
+ )}
533
+ </Search>
534
+ </div>
535
+ </div>
536
+ </div>
537
+ )
538
+ },
539
+ parameters: {
540
+ docs: {
541
+ description: {
542
+ story:
543
+ "Search component examples showing different states: loading, error, and empty results with appropriate feedback.",
544
+ },
545
+ },
546
+ },
547
+ }
548
+
549
+ // 6. Advanced Search Features
550
+ export const AdvancedFeatures: Story = {
551
+ render: () => {
552
+ const [searchHistory, setSearchHistory] = useState<string[]>([
553
+ "The Daily",
554
+ "Serial",
555
+ "This American Life",
556
+ ])
557
+ const [currentSearch, setCurrentSearch] = useState("")
558
+ const [showHistory, setShowHistory] = useState(false)
559
+
560
+ const addToHistory = (query: string) => {
561
+ if (query.trim() && !searchHistory.includes(query)) {
562
+ setSearchHistory((prev) => [query, ...prev.slice(0, 4)])
563
+ }
564
+ }
565
+
566
+ return (
567
+ <div className="w-96 space-y-6">
568
+ <div className="text-center">
569
+ <h3 className="mb-2 font-medium text-white">Advanced Features</h3>
570
+ <p className="text-sm text-white/60">
571
+ Search with history, suggestions, and shortcuts
572
+ </p>
573
+ </div>
574
+
575
+ <div className="space-y-6">
576
+ {/* Search with History */}
577
+ <div className="space-y-3">
578
+ <label className="text-sm font-medium text-white/80">
579
+ Search with History
580
+ </label>
581
+ <Search
582
+ placeholder="Search with history..."
583
+ value={currentSearch}
584
+ onChange={setCurrentSearch}
585
+ onSearch={(query) => {
586
+ addToHistory(query)
587
+ setShowHistory(false)
588
+ }}
589
+ >
590
+ {(showHistory ||
591
+ (!currentSearch && searchHistory.length > 0)) && (
592
+ <div className="mt-2 rounded-lg border border-white/10 bg-gray-800/90 shadow-xl">
593
+ <div className="p-3">
594
+ <div className="mb-2 text-xs font-medium text-white/80">
595
+ Recent Searches
596
+ </div>
597
+ <div className="space-y-1">
598
+ {searchHistory.map((item, index) => (
599
+ <button
600
+ key={index}
601
+ onClick={() => {
602
+ setCurrentSearch(item)
603
+ setShowHistory(false)
604
+ }}
605
+ className="flex w-full items-center gap-2 rounded px-3 py-2 text-left text-sm text-white hover:bg-white/10"
606
+ >
607
+ <svg
608
+ className="h-3 w-3 text-white/40"
609
+ fill="none"
610
+ stroke="currentColor"
611
+ viewBox="0 0 24 24"
612
+ >
613
+ <path
614
+ strokeLinecap="round"
615
+ strokeLinejoin="round"
616
+ strokeWidth={2}
617
+ d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
618
+ />
619
+ </svg>
620
+ {item}
621
+ </button>
622
+ ))}
623
+ </div>
624
+ </div>
625
+ </div>
626
+ )}
627
+ </Search>
628
+ <div className="flex gap-2">
629
+ <Button
630
+ size="sm"
631
+ variant="outline"
632
+ onClick={() => setShowHistory(!showHistory)}
633
+ >
634
+ {showHistory ? "Hide" : "Show"} History
635
+ </Button>
636
+ <Button
637
+ size="sm"
638
+ variant="outline"
639
+ onClick={() => setSearchHistory([])}
640
+ >
641
+ Clear History
642
+ </Button>
643
+ </div>
644
+ </div>
645
+
646
+ {/* Keyboard Shortcuts Info */}
647
+ <div className="rounded-lg border border-white/10 bg-white/5 p-4">
648
+ <h4 className="mb-2 text-sm font-medium text-white">
649
+ Keyboard Shortcuts
650
+ </h4>
651
+ <div className="space-y-1 text-xs text-white/60">
652
+ <div className="flex justify-between">
653
+ <span>Focus search:</span>
654
+ <kbd className="rounded bg-white/10 px-1 font-mono">Cmd+K</kbd>
655
+ </div>
656
+ <div className="flex justify-between">
657
+ <span>Clear search:</span>
658
+ <kbd className="rounded bg-white/10 px-1 font-mono">Esc</kbd>
659
+ </div>
660
+ <div className="flex justify-between">
661
+ <span>Navigate results:</span>
662
+ <kbd className="rounded bg-white/10 px-1 font-mono">↑↓</kbd>
663
+ </div>
664
+ </div>
665
+ </div>
666
+ </div>
667
+ </div>
668
+ )
669
+ },
670
+ parameters: {
671
+ docs: {
672
+ description: {
673
+ story:
674
+ "Advanced search features including search history, keyboard shortcuts, and enhanced user experience patterns.",
675
+ },
676
+ },
677
+ },
678
+ }