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,138 @@
1
+ import React from "react"
2
+ import { Case, Default, SwitchCase } from "@components/switch-case"
3
+ import { SpinnerGradientIcon } from "@icons/spinner-gradient-icon"
4
+ import { SpinnerSolidIcon } from "@icons/spinner-solid-icon"
5
+ import { SpinnerSolidNeutralIcon } from "@icons/spinner-solid-neutral-icon"
6
+ import { cn } from "@lib/utils"
7
+
8
+ interface CircularLoaderProps {
9
+ variant?: "v1" | "v2" | "v3"
10
+ className?: string
11
+ text?: string
12
+ classes?: {
13
+ text?: string
14
+ root?: string
15
+ loader?: string
16
+ }
17
+ /** Accessible label for screen readers when no text is provided */
18
+ "aria-label"?: string
19
+ /** ID for the loading region */
20
+ id?: string
21
+ /** Whether to announce the loading state to screen readers */
22
+ "aria-live"?: "polite" | "assertive" | "off"
23
+ /** Custom loading message for screen readers */
24
+ loadingMessage?: string
25
+ /** Size variant for the loader */
26
+ size?: "sm" | "md" | "lg" | "xl"
27
+ }
28
+
29
+ const sizeVariants = {
30
+ sm: "h-4 w-4",
31
+ md: "h-6 w-6",
32
+ lg: "h-8 w-8",
33
+ xl: "h-12 w-12",
34
+ }
35
+
36
+ const CircularLoader = ({
37
+ variant = "v1",
38
+ className,
39
+ text,
40
+ classes,
41
+ "aria-label": ariaLabel,
42
+ id,
43
+ "aria-live": ariaLive = "polite",
44
+ loadingMessage,
45
+ size = "md",
46
+ ...props
47
+ }: React.JSX.IntrinsicAttributes &
48
+ React.HTMLAttributes<HTMLDivElement> &
49
+ CircularLoaderProps) => {
50
+ // Determine the accessible label
51
+ const accessibleLabel = text || loadingMessage || ariaLabel || "Loading"
52
+
53
+ // Determine if we should show visual text
54
+ const showVisualText = text !== undefined
55
+
56
+ return (
57
+ <div
58
+ className={cn(
59
+ "flex flex-col items-center justify-center gap-2",
60
+ classes?.root
61
+ )}
62
+ role="status"
63
+ aria-live={ariaLive}
64
+ aria-label={!showVisualText ? accessibleLabel : undefined}
65
+ id={id}
66
+ {...props}
67
+ >
68
+ <SwitchCase value={variant}>
69
+ <Case value="v1">
70
+ <SpinnerGradientIcon
71
+ className={cn(
72
+ "animate-spin",
73
+ sizeVariants[size],
74
+ className,
75
+ classes?.loader
76
+ )}
77
+ aria-hidden="true"
78
+ focusable="false"
79
+ />
80
+ </Case>
81
+ <Case value="v2">
82
+ <SpinnerSolidIcon
83
+ className={cn(
84
+ "animate-spin",
85
+ sizeVariants[size],
86
+ className,
87
+ classes?.loader
88
+ )}
89
+ aria-hidden="true"
90
+ focusable="false"
91
+ />
92
+ </Case>
93
+ <Case value="v3">
94
+ <SpinnerSolidNeutralIcon
95
+ className={cn(
96
+ "animate-spin",
97
+ sizeVariants[size],
98
+ className,
99
+ classes?.loader
100
+ )}
101
+ aria-hidden="true"
102
+ focusable="false"
103
+ />
104
+ </Case>
105
+ <Default>
106
+ <SpinnerGradientIcon
107
+ className={cn(
108
+ "animate-spin",
109
+ sizeVariants[size],
110
+ className,
111
+ classes?.loader
112
+ )}
113
+ aria-hidden="true"
114
+ focusable="false"
115
+ />
116
+ </Default>
117
+ </SwitchCase>
118
+
119
+ {/* Screen reader text - always present for accessibility */}
120
+ {!showVisualText && <span className="sr-only">{accessibleLabel}</span>}
121
+
122
+ {/* Visual text when provided */}
123
+ {showVisualText && (
124
+ <span
125
+ className={cn(
126
+ "text-fm-sm font-fm-brand leading-fm-sm mt-2",
127
+ classes?.text
128
+ )}
129
+ aria-live={ariaLive}
130
+ >
131
+ {text}
132
+ </span>
133
+ )}
134
+ </div>
135
+ )
136
+ }
137
+
138
+ export default CircularLoader
@@ -0,0 +1,11 @@
1
+ export const meta = {
2
+ dependencies: {},
3
+ devDependencies: {},
4
+ internalDependencies: [
5
+ "spinner-gradient-icon",
6
+ "spinner-solid-icon",
7
+ "switch-case",
8
+ "spinner-solid-neutral-icon",
9
+ ],
10
+ tokens: [],
11
+ }
@@ -0,0 +1,319 @@
1
+ import React from "react"
2
+ import { AngleDownIcon } from "@icons/angle-down-icon"
3
+ import type { Meta, StoryObj } from "@storybook/react"
4
+
5
+ import { IconButton } from "../icon-button"
6
+ import {
7
+ Collapsible,
8
+ CollapsibleContent,
9
+ CollapsibleHeader,
10
+ CollapsibleTitle,
11
+ CollapsibleTrigger,
12
+ } from "./index"
13
+
14
+ const meta: Meta<typeof Collapsible> = {
15
+ title: "Components/UI/Collapsible",
16
+ component: Collapsible,
17
+ parameters: {
18
+ layout: "centered",
19
+ docs: {
20
+ description: {
21
+ component:
22
+ "A collapsible component built on Radix UI that can expand and collapse content.",
23
+ },
24
+ },
25
+ },
26
+ tags: ["autodocs"],
27
+ argTypes: {
28
+ defaultOpen: {
29
+ control: "boolean",
30
+ description: "Whether the collapsible is open by default",
31
+ },
32
+ disabled: {
33
+ control: "boolean",
34
+ description: "Whether the collapsible is disabled",
35
+ },
36
+ },
37
+ }
38
+
39
+ export default meta
40
+ type Story = StoryObj<typeof Collapsible>
41
+
42
+ export const Default: Story = {
43
+ render: (args) => (
44
+ <div className="w-[800px]">
45
+ <Collapsible {...args}>
46
+ <CollapsibleHeader title="Frequently Asked Questions" />
47
+ <CollapsibleContent>
48
+ <div className="pt-4">
49
+ <p>
50
+ This is the collapsible content area. You can put any content here
51
+ including text, images, forms, or other components. The content
52
+ will smoothly animate when the collapsible is opened or closed.
53
+ </p>
54
+ </div>
55
+ </CollapsibleContent>
56
+ </Collapsible>
57
+ </div>
58
+ ),
59
+ args: {
60
+ defaultOpen: false,
61
+ },
62
+ }
63
+
64
+ export const DefaultOpen: Story = {
65
+ render: () => (
66
+ <div className="w-[800px]">
67
+ <Collapsible defaultOpen>
68
+ <CollapsibleHeader title="Settings Panel" />
69
+ <CollapsibleContent>
70
+ <div className="space-y-3 pt-4">
71
+ <div className="flex items-center justify-between">
72
+ <span>Enable notifications</span>
73
+ <input type="checkbox" defaultChecked />
74
+ </div>
75
+ <div className="flex items-center justify-between">
76
+ <span>Dark mode</span>
77
+ <input type="checkbox" />
78
+ </div>
79
+ <div className="flex items-center justify-between">
80
+ <span>Auto-save</span>
81
+ <input type="checkbox" defaultChecked />
82
+ </div>
83
+ </div>
84
+ </CollapsibleContent>
85
+ </Collapsible>
86
+ </div>
87
+ ),
88
+ }
89
+
90
+ export const Disabled: Story = {
91
+ render: () => (
92
+ <div className="w-[800px]">
93
+ <Collapsible disabled>
94
+ <CollapsibleHeader title="Disabled Section" />
95
+ <CollapsibleContent>
96
+ <div className="pt-4">
97
+ <p>
98
+ This content cannot be accessed because the collapsible is
99
+ disabled.
100
+ </p>
101
+ </div>
102
+ </CollapsibleContent>
103
+ </Collapsible>
104
+ </div>
105
+ ),
106
+ }
107
+
108
+ export const CustomTrigger: Story = {
109
+ render: () => (
110
+ <div className="w-[800px]">
111
+ <Collapsible>
112
+ <div className="flex items-center justify-between gap-2">
113
+ <CollapsibleTitle>Advanced Settings</CollapsibleTitle>
114
+ <CollapsibleTrigger asChild>
115
+ <IconButton
116
+ variant="ghost"
117
+ size="small"
118
+ icon={
119
+ <AngleDownIcon className="toggle-icon" height={32} width={32} />
120
+ }
121
+ label="Toggle Settings"
122
+ className="text-fm-icon-active disabled:text-fm-icon-inactive flex [&>.toggle-icon]:transition-transform [&>.toggle-icon]:duration-50 data-[state=open]:[&>.toggle-icon]:-rotate-180"
123
+ />
124
+ </CollapsibleTrigger>
125
+ </div>
126
+ <CollapsibleContent>
127
+ <div className="pt-4">
128
+ <p>
129
+ Custom trigger button with settings icon that rotates 45 degrees
130
+ when opened.
131
+ </p>
132
+ </div>
133
+ </CollapsibleContent>
134
+ </Collapsible>
135
+ </div>
136
+ ),
137
+ }
138
+
139
+ export const MultipleCollapsibles: Story = {
140
+ render: () => (
141
+ <div className="w-[800px] space-y-4">
142
+ <Collapsible>
143
+ <CollapsibleHeader title="Section 1: Getting Started" />
144
+ <CollapsibleContent>
145
+ <div className="pt-4">
146
+ <p>
147
+ Learn the basics of using our platform. This section covers
148
+ initial setup, account creation, and basic navigation.
149
+ </p>
150
+ </div>
151
+ </CollapsibleContent>
152
+ </Collapsible>
153
+
154
+ <Collapsible>
155
+ <CollapsibleHeader title="Section 2: Advanced Features" />
156
+ <CollapsibleContent>
157
+ <div className="pt-4">
158
+ <p>
159
+ Explore advanced functionality including custom integrations, API
160
+ usage, and automation tools.
161
+ </p>
162
+ </div>
163
+ </CollapsibleContent>
164
+ </Collapsible>
165
+
166
+ <Collapsible>
167
+ <CollapsibleHeader title="Section 3: Troubleshooting" />
168
+ <CollapsibleContent>
169
+ <div className="pt-4">
170
+ <p>
171
+ Common issues and their solutions. Find answers to frequently
172
+ encountered problems.
173
+ </p>
174
+ </div>
175
+ </CollapsibleContent>
176
+ </Collapsible>
177
+ </div>
178
+ ),
179
+ }
180
+
181
+ export const RichContent: Story = {
182
+ render: () => (
183
+ <div className="w-[800px]">
184
+ <Collapsible>
185
+ <CollapsibleHeader title="Product Features" />
186
+ <CollapsibleContent>
187
+ <div className="space-y-4 pt-4">
188
+ <div>
189
+ <h4 className="mb-2 font-semibold">Key Benefits:</h4>
190
+ <ul className="list-inside list-disc space-y-1">
191
+ <li>Easy to use interface</li>
192
+ <li>Powerful automation tools</li>
193
+ <li>24/7 customer support</li>
194
+ <li>Enterprise-grade security</li>
195
+ </ul>
196
+ </div>
197
+ <div>
198
+ <h4 className="mb-2 font-semibold">Pricing:</h4>
199
+ <div className="rounded bg-gray-50 p-3">
200
+ <p className="text-sm">Starting at $29/month for basic plan</p>
201
+ </div>
202
+ </div>
203
+ </div>
204
+ </CollapsibleContent>
205
+ </Collapsible>
206
+ </div>
207
+ ),
208
+ }
209
+
210
+ export const WithCustomStyling: Story = {
211
+ render: () => (
212
+ <div className="w-[800px]">
213
+ <Collapsible className="rounded-lg border-2 border-blue-200 bg-blue-50 p-4">
214
+ <div className="flex items-center justify-between gap-2">
215
+ <CollapsibleTitle className="font-bold text-blue-800">
216
+ Important Notice
217
+ </CollapsibleTitle>
218
+ <CollapsibleTrigger asChild>
219
+ <IconButton
220
+ variant="ghost"
221
+ size="small"
222
+ className="text-blue-600 hover:bg-blue-100"
223
+ icon={
224
+ <AngleDownIcon className="transition-transform duration-200 data-[state=open]:rotate-180" />
225
+ }
226
+ label="Toggle Notice"
227
+ />
228
+ </CollapsibleTrigger>
229
+ </div>
230
+ <CollapsibleContent className="text-blue-700">
231
+ <div className="pt-4">
232
+ <p>
233
+ This is an important system notification with custom styling. The
234
+ entire collapsible has a blue theme to draw attention to critical
235
+ information.
236
+ </p>
237
+ </div>
238
+ </CollapsibleContent>
239
+ </Collapsible>
240
+ </div>
241
+ ),
242
+ }
243
+
244
+ export const LongContent: Story = {
245
+ render: () => (
246
+ <div className="w-[800px]">
247
+ <Collapsible>
248
+ <CollapsibleHeader title="Terms and Conditions" />
249
+ <CollapsibleContent>
250
+ <div className="max-h-60 overflow-y-auto pt-4">
251
+ <div className="space-y-4 text-sm">
252
+ <p>
253
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
254
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
255
+ enim ad minim veniam, quis nostrud exercitation ullamco laboris.
256
+ </p>
257
+ <p>
258
+ Duis aute irure dolor in reprehenderit in voluptate velit esse
259
+ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
260
+ cupidatat non proident, sunt in culpa qui officia deserunt
261
+ mollit anim id est laborum.
262
+ </p>
263
+ <p>
264
+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem
265
+ accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
266
+ quae ab illo inventore veritatis et quasi architecto beatae
267
+ vitae dicta sunt explicabo.
268
+ </p>
269
+ <p>
270
+ Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit
271
+ aut fugit, sed quia consequuntur magni dolores eos qui ratione
272
+ voluptatem sequi nesciunt.
273
+ </p>
274
+ <p>
275
+ At vero eos et accusamus et iusto odio dignissimos ducimus qui
276
+ blanditiis praesentium voluptatum deleniti atque corrupti quos
277
+ dolores et quas molestias excepturi sint occaecati cupiditate
278
+ non provident.
279
+ </p>
280
+ </div>
281
+ </div>
282
+ </CollapsibleContent>
283
+ </Collapsible>
284
+ </div>
285
+ ),
286
+ }
287
+
288
+ export const NestedCollapsibles: Story = {
289
+ render: () => (
290
+ <div className="w-[800px]">
291
+ <Collapsible>
292
+ <CollapsibleHeader title="Main Category" />
293
+ <CollapsibleContent>
294
+ <div className="space-y-2 pt-4">
295
+ <p className="mb-4">This section contains nested collapsibles:</p>
296
+
297
+ <Collapsible className="ml-4">
298
+ <CollapsibleHeader title="Subcategory A" />
299
+ <CollapsibleContent>
300
+ <div className="pt-4">
301
+ <p>Content for subcategory A with detailed information.</p>
302
+ </div>
303
+ </CollapsibleContent>
304
+ </Collapsible>
305
+
306
+ <Collapsible className="ml-4">
307
+ <CollapsibleHeader title="Subcategory B" />
308
+ <CollapsibleContent>
309
+ <div className="pt-4">
310
+ <p>Content for subcategory B with additional details.</p>
311
+ </div>
312
+ </CollapsibleContent>
313
+ </Collapsible>
314
+ </div>
315
+ </CollapsibleContent>
316
+ </Collapsible>
317
+ </div>
318
+ ),
319
+ }
@@ -0,0 +1,158 @@
1
+ import React, { forwardRef } from "react"
2
+ import { IconButton } from "@components/icon-button"
3
+ import { AngleDownIcon } from "@icons/angle-down-icon"
4
+ import { cn } from "@lib/utils"
5
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
6
+ import { Slot } from "@radix-ui/react-slot"
7
+
8
+ const Collapsible = forwardRef<
9
+ HTMLDivElement,
10
+ React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Collapsible>
11
+ >((props, ref) => {
12
+ const { className, children, ...rest } = props
13
+ return (
14
+ <CollapsiblePrimitive.Collapsible
15
+ ref={ref}
16
+ className={cn(
17
+ "border-fm-divider-secondary pb-fm-2xl w-full border-b border-solid",
18
+ className
19
+ )}
20
+ {...rest}
21
+ >
22
+ {children}
23
+ </CollapsiblePrimitive.Collapsible>
24
+ )
25
+ })
26
+ Collapsible.displayName = "Collapsible"
27
+
28
+ type CollapsibleTitleProps = React.HTMLAttributes<HTMLHeadingElement> & {
29
+ asChild?: boolean
30
+ }
31
+
32
+ const CollapsibleTitle = forwardRef<HTMLHeadingElement, CollapsibleTitleProps>(
33
+ (props, ref) => {
34
+ const { asChild, children, className, ...rest } = props
35
+ const Component = asChild ? Slot : "h2"
36
+ return (
37
+ <Component
38
+ ref={ref}
39
+ className={cn(
40
+ "text-fm-primary font-fm-text leading-fm-3xl [font-size:var(--text-fm-3xl)] tracking-wide",
41
+ className
42
+ )}
43
+ {...rest}
44
+ >
45
+ {children}
46
+ </Component>
47
+ )
48
+ }
49
+ )
50
+ CollapsibleTitle.displayName = "CollapsibleTitle"
51
+
52
+ const CollapsibleTrigger = forwardRef<
53
+ HTMLButtonElement,
54
+ React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.CollapsibleTrigger>
55
+ >((props, ref) => {
56
+ const { className, children, asChild, ...rest } = props
57
+ return (
58
+ <CollapsiblePrimitive.CollapsibleTrigger
59
+ ref={ref}
60
+ asChild={asChild}
61
+ {...rest}
62
+ >
63
+ {React.isValidElement(children) ? (
64
+ children
65
+ ) : (
66
+ <IconButton
67
+ className={cn(
68
+ "text-fm-icon-active disabled:text-fm-icon-inactive [&>.toggle-icon]:transition-transform [&>.toggle-icon]:duration-50 data-[state=open]:[&>.toggle-icon]:-rotate-180",
69
+ className
70
+ )}
71
+ variant="ghost"
72
+ size="small"
73
+ icon={
74
+ <AngleDownIcon className="toggle-icon" height={32} width={32} />
75
+ }
76
+ label="Toggle Collapsible"
77
+ />
78
+ )}
79
+ </CollapsiblePrimitive.CollapsibleTrigger>
80
+ )
81
+ })
82
+ CollapsibleTrigger.displayName = "CollapsibleTrigger"
83
+
84
+ type CollapsibleHeaderProps = React.HTMLAttributes<HTMLDivElement> & {
85
+ title: React.ReactNode
86
+ classes?: {
87
+ root?: string
88
+ trigger?: string
89
+ title?: string
90
+ icon?: string
91
+ }
92
+ }
93
+
94
+ const CollapsibleHeader = forwardRef<HTMLDivElement, CollapsibleHeaderProps>(
95
+ (props, ref) => {
96
+ const { className, title, classes, ...rest } = props
97
+ return (
98
+ <div
99
+ ref={ref}
100
+ className={cn(
101
+ "flex items-center justify-between gap-2",
102
+ className,
103
+ classes?.root
104
+ )}
105
+ {...rest}
106
+ >
107
+ <CollapsibleTrigger asChild>
108
+ <button
109
+ className={cn(
110
+ "text-fm-icon-active disabled:text-fm-icon-inactive focus-visible:ring-fm-primary focus-visible:ring-offset-fm-contrast disabled:[&>.collapsible-title]:text-fm-inactive flex flex-1 cursor-pointer items-center justify-between text-left outline-none focus-visible:ring-2 focus-visible:ring-offset-2 [&>.toggle-icon]:transition-transform [&>.toggle-icon]:duration-50 data-[state=open]:[&>.toggle-icon]:-rotate-180",
111
+ classes?.trigger
112
+ )}
113
+ >
114
+ <CollapsibleTitle
115
+ className={cn("collapsible-title", classes?.title)}
116
+ >
117
+ {title}
118
+ </CollapsibleTitle>
119
+ <AngleDownIcon
120
+ className={cn("toggle-icon", classes?.icon)}
121
+ height={32}
122
+ width={32}
123
+ />
124
+ </button>
125
+ </CollapsibleTrigger>
126
+ </div>
127
+ )
128
+ }
129
+ )
130
+ CollapsibleHeader.displayName = "CollapsibleHeader"
131
+
132
+ const CollapsibleContent = forwardRef<
133
+ HTMLDivElement,
134
+ React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.CollapsibleContent>
135
+ >((props, ref) => {
136
+ const { className, children, ...rest } = props
137
+ return (
138
+ <CollapsiblePrimitive.CollapsibleContent
139
+ ref={ref}
140
+ className={cn(
141
+ "text-fm-tertiary leading-fm-xl [font-size:var(--text-fm-xl)] tracking-wider",
142
+ className
143
+ )}
144
+ {...rest}
145
+ >
146
+ {children}
147
+ </CollapsiblePrimitive.CollapsibleContent>
148
+ )
149
+ })
150
+ CollapsibleContent.displayName = "CollapsibleContent"
151
+
152
+ export {
153
+ Collapsible,
154
+ CollapsibleTrigger,
155
+ CollapsibleContent,
156
+ CollapsibleTitle,
157
+ CollapsibleHeader,
158
+ }
@@ -0,0 +1,22 @@
1
+ export const meta = {
2
+ dependencies: {
3
+ "@radix-ui/react-collapsible": "^1.1.11",
4
+ },
5
+ devDependencies: {},
6
+ internalDependencies: ["icon-button", "angle-down-icon"],
7
+ tokens: [
8
+ "--color-fm-contrast",
9
+ "--color-fm-divider-secondary",
10
+ "--color-fm-icon-active",
11
+ "--color-fm-icon-inactive",
12
+ "--color-fm-inactive",
13
+ "--color-fm-primary",
14
+ "--color-fm-tertiary",
15
+ "--font-fm-text",
16
+ "--leading-fm-3xl",
17
+ "--leading-fm-xl",
18
+ "--spacing-fm-2xl",
19
+ "--text-fm-3xl",
20
+ "--text-fm-xl",
21
+ ],
22
+ }