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,963 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React, { useState } from "react"
3
+ import { Button } from "@components/button"
4
+ import { Checkbox } from "@components/checkbox"
5
+ import Input from "@components/input"
6
+ import { Label } from "@components/label"
7
+ import Textarea from "@components/textarea"
8
+ import { AlertIcon } from "@icons/alert-icon"
9
+ import { EditBigIcon } from "@icons/edit-big-icon"
10
+ import { LightBulbSimpleIcon } from "@icons/light-bulb-simple-icon"
11
+ import { TickIcon } from "@icons/tick-icon"
12
+ import { TrashIcon } from "@icons/trash-icon"
13
+ import type { Meta, StoryObj } from "@storybook/react"
14
+
15
+ import {
16
+ Dialog,
17
+ DialogClose,
18
+ DialogContent,
19
+ DialogDescription,
20
+ DialogFooter,
21
+ DialogHeader,
22
+ DialogTitle,
23
+ DialogTrigger,
24
+ useDialogCleanup,
25
+ } from "."
26
+
27
+ const meta: Meta<typeof DialogContent> = {
28
+ title: "Components/UI/Dialog",
29
+ component: Dialog,
30
+ parameters: {
31
+ layout: "centered",
32
+ backgrounds: {
33
+ default: "dark",
34
+ values: [
35
+ { name: "dark", value: "#0a0a0a" },
36
+ { name: "light", value: "#ffffff" },
37
+ ],
38
+ },
39
+ docs: {
40
+ description: {
41
+ component: `
42
+ # Dialog Component
43
+
44
+ A modal dialog component built on Radix UI primitives with customizable overlays, animations, and variant styling. Includes React 18 compatibility fixes for pointer-events issues.
45
+
46
+ ## Features
47
+
48
+ - **Multiple Variants**: Neutral, positive, negative, warning, and info styles
49
+ - **Custom Overlays**: Configurable opacity, glass effect, and noise texture
50
+ - **Smooth Animations**: Zoom in/out animations with duration control
51
+ - **Accessible**: Full keyboard navigation and screen reader support
52
+ - **Flexible Content**: Header, footer, and body sections with custom styling
53
+ - **Close Button**: Positioned close button with icon
54
+ - **Portal Rendering**: Renders outside normal DOM hierarchy
55
+ - **Focus Management**: Automatic focus trapping and restoration
56
+ - **React 18 Fix**: Includes \`useDialogCleanup\` hook for pointer-events issues
57
+
58
+ ## Component Structure
59
+
60
+ - **Dialog**: Root component that manages dialog state
61
+ - **DialogTrigger**: Button or element that opens the dialog
62
+ - **DialogContent**: Main dialog container with overlay and content
63
+ - **DialogHeader**: Header section for title and description
64
+ - **DialogFooter**: Footer section for action buttons
65
+ - **DialogTitle**: Accessible title element
66
+ - **DialogDescription**: Optional description text
67
+ - **DialogClose**: Close button component
68
+ - **useDialogCleanup**: Hook to fix React 18 pointer-events issues
69
+
70
+ ## Usage Examples
71
+
72
+ ### Basic Dialog
73
+ \`\`\`tsx
74
+ import { Dialog, DialogContent, DialogTrigger, useDialogCleanup } from '@/components/dialog'
75
+
76
+ function MyComponent() {
77
+ const { handleDialogClose } = useDialogCleanup({ threshold: 100 })
78
+
79
+ return (
80
+ <Dialog>
81
+ <DialogTrigger asChild>
82
+ <Button>Open Dialog</Button>
83
+ </DialogTrigger>
84
+ <DialogContent onEscapeKeyDown={handleDialogClose}>
85
+ <DialogHeader>
86
+ <DialogTitle>Dialog Title</DialogTitle>
87
+ <DialogDescription>Dialog description text.</DialogDescription>
88
+ </DialogHeader>
89
+ <div>Dialog content goes here.</div>
90
+ <DialogFooter>
91
+ <DialogClose asChild>
92
+ <Button variant="outline" onClick={handleDialogClose}>Cancel</Button>
93
+ </DialogClose>
94
+ <Button>Confirm</Button>
95
+ </DialogFooter>
96
+ </DialogContent>
97
+ </Dialog>
98
+ )
99
+ }
100
+ \`\`\`
101
+
102
+ ### Variant Styling
103
+ \`\`\`tsx
104
+ <DialogContent variant="negative">
105
+ {/* Negative variant with red shadow */}
106
+ </DialogContent>
107
+ \`\`\`
108
+
109
+ ### Custom Overlay
110
+ \`\`\`tsx
111
+ <DialogContent opacity="high" glass="high" noise="low">
112
+ {/* High opacity overlay with glass effect and subtle noise */}
113
+ </DialogContent>
114
+ \`\`\`
115
+
116
+ ### React 18 Compatibility
117
+ \`\`\`tsx
118
+ function DialogWithCleanup() {
119
+ const { handleDialogClose } = useDialogCleanup({ threshold: 150 })
120
+
121
+ return (
122
+ <DialogContent
123
+ onInteractOutside={handleDialogClose}
124
+ onPointerDownOutside={handleDialogClose}
125
+ >
126
+ {/* Dialog content */}
127
+ </DialogContent>
128
+ )
129
+ }
130
+ \`\`\`
131
+ `,
132
+ },
133
+ },
134
+ },
135
+ argTypes: {
136
+ variant: {
137
+ control: { type: "select" },
138
+ options: ["neutral", "positive", "negative", "warning", "info"],
139
+ description: "Dialog variant for different use cases",
140
+ },
141
+ opacity: {
142
+ control: { type: "select" },
143
+ options: ["high", "medium", "low", "none"],
144
+ description: "Overlay opacity level",
145
+ },
146
+ glass: {
147
+ control: { type: "select" },
148
+ options: ["high", "medium", "low", "none"],
149
+ description: "Glass blur effect intensity",
150
+ },
151
+ noise: {
152
+ control: { type: "select" },
153
+ options: ["high", "medium", "low", "none"],
154
+ description: "Noise texture intensity",
155
+ },
156
+ showCloseButton: {
157
+ control: "boolean",
158
+ description: "Show/hide the close button",
159
+ },
160
+ },
161
+ tags: ["autodocs"],
162
+ }
163
+
164
+ export default meta
165
+ type Story = StoryObj<typeof Dialog>
166
+
167
+ // 1. Dialog Cleanup Example - React 18 Compatibility
168
+ export const DialogCleanupExample: Story = {
169
+ render: () => {
170
+ const DialogWithCleanup = () => {
171
+ const { handleDialogClose } = useDialogCleanup({ threshold: 100 })
172
+ const [isOpen, setIsOpen] = useState(false)
173
+
174
+ const handleClose = () => {
175
+ handleDialogClose()
176
+ setIsOpen(false)
177
+ }
178
+
179
+ return (
180
+ <Dialog open={isOpen} onOpenChange={setIsOpen}>
181
+ <DialogTrigger asChild>
182
+ <Button>Open Dialog with Cleanup</Button>
183
+ </DialogTrigger>
184
+ <DialogContent
185
+ //@ts-expect-error onEscapeKeyDown available in Radix v2.0.0
186
+ onEscapeKeyDown={handleClose}
187
+ onPointerDownOutside={handleClose}
188
+ >
189
+ <DialogHeader>
190
+ <DialogTitle>Dialog with React 18 Fix</DialogTitle>
191
+ <DialogDescription>
192
+ This dialog uses useDialogCleanup to prevent pointer-events
193
+ issues in React 18.
194
+ </DialogDescription>
195
+ </DialogHeader>
196
+ <div className="py-4">
197
+ <div className="rounded-lg border border-blue-500/20 bg-blue-500/10 p-3">
198
+ <p className="text-sm text-blue-200">
199
+ The useDialogCleanup hook ensures that pointer-events: none
200
+ doesn't get stuck on the body element when the dialog closes,
201
+ which was a common issue in React 18.
202
+ </p>
203
+ </div>
204
+ </div>
205
+ <DialogFooter>
206
+ <DialogClose asChild>
207
+ <Button variant="outline" onClick={handleClose}>
208
+ Cancel
209
+ </Button>
210
+ </DialogClose>
211
+ <Button onClick={handleClose}>Confirm</Button>
212
+ </DialogFooter>
213
+ </DialogContent>
214
+ </Dialog>
215
+ )
216
+ }
217
+
218
+ return (
219
+ <div className="space-y-8">
220
+ <div className="text-center">
221
+ <h3 className="mb-2 font-medium text-white">Dialog Cleanup Hook</h3>
222
+ <p className="text-sm text-white/60">
223
+ Demonstrates useDialogCleanup hook for React 18 compatibility
224
+ </p>
225
+ </div>
226
+ <div className="flex justify-center">
227
+ <DialogWithCleanup />
228
+ </div>
229
+ <div className="text-center">
230
+ <div className="inline-block max-w-lg rounded-lg border border-white/10 bg-white/5 p-4">
231
+ <h4 className="mb-2 text-sm font-medium text-white">
232
+ React 18 Compatibility
233
+ </h4>
234
+ <p className="text-xs leading-relaxed text-white/60">
235
+ The useDialogCleanup hook prevents the pointer-events: none style
236
+ from persisting on the body element after dialog close, which
237
+ could make the page uninteractive in React 18.
238
+ </p>
239
+ </div>
240
+ </div>
241
+ </div>
242
+ )
243
+ },
244
+ parameters: {
245
+ docs: {
246
+ description: {
247
+ story:
248
+ "Example showing how to use useDialogCleanup hook to fix React 18 pointer-events issues.",
249
+ },
250
+ },
251
+ },
252
+ }
253
+
254
+ // 2. Basic Dialog Variants with Cleanup
255
+ export const BasicVariants: Story = {
256
+ render: () => {
257
+ const DialogWithCleanupVariant = ({
258
+ variant,
259
+ title,
260
+ description,
261
+ children,
262
+ }: any) => {
263
+ const { handleDialogClose } = useDialogCleanup({ threshold: 100 })
264
+
265
+ return (
266
+ <Dialog>
267
+ <DialogTrigger asChild>
268
+ <Button variant="outline">{title}</Button>
269
+ </DialogTrigger>
270
+ <DialogContent
271
+ variant={variant}
272
+ //@ts-expect-error onEscapeKeyDown available in Radix v2.0.0
273
+ onEscapeKeyDown={handleDialogClose}
274
+ onPointerDownOutside={handleDialogClose}
275
+ >
276
+ <DialogHeader>
277
+ <DialogTitle>{title}</DialogTitle>
278
+ <DialogDescription>{description}</DialogDescription>
279
+ </DialogHeader>
280
+ <div className="py-4">{children}</div>
281
+ <DialogFooter>
282
+ <DialogClose asChild>
283
+ <Button variant="outline" onClick={handleDialogClose}>
284
+ Cancel
285
+ </Button>
286
+ </DialogClose>
287
+ <Button onClick={handleDialogClose}>Continue</Button>
288
+ </DialogFooter>
289
+ </DialogContent>
290
+ </Dialog>
291
+ )
292
+ }
293
+
294
+ return (
295
+ <div className="space-y-8">
296
+ <div className="text-center">
297
+ <h3 className="mb-2 font-medium text-white">
298
+ Dialog Variants with Cleanup
299
+ </h3>
300
+ <p className="text-sm text-white/60">
301
+ Different dialog variants with React 18 compatibility fixes
302
+ </p>
303
+ </div>
304
+
305
+ <div className="flex flex-wrap justify-center gap-4">
306
+ <DialogWithCleanupVariant
307
+ variant="neutral"
308
+ title="Neutral Dialog"
309
+ description="This is a neutral dialog with standard styling."
310
+ >
311
+ <p className="text-sm text-white/80">
312
+ Neutral dialogs are perfect for general information, settings, or
313
+ any content that doesn't require specific emotional context.
314
+ </p>
315
+ </DialogWithCleanupVariant>
316
+
317
+ <DialogWithCleanupVariant
318
+ variant="positive"
319
+ title="Success Dialog"
320
+ description="Operation completed successfully!"
321
+ >
322
+ <div className="mb-2 flex items-center gap-2">
323
+ <TickIcon className="h-5 w-5 text-green-400" />
324
+ <span className="font-medium text-green-400">Success!</span>
325
+ </div>
326
+ <p className="text-sm text-white/80">
327
+ Your changes have been saved and are now live. Users will see the
328
+ updates immediately.
329
+ </p>
330
+ </DialogWithCleanupVariant>
331
+
332
+ <DialogWithCleanupVariant
333
+ variant="warning"
334
+ title="Warning Dialog"
335
+ description="Please review the following before proceeding."
336
+ >
337
+ <div className="rounded-lg border border-yellow-500/20 bg-yellow-500/10 p-3">
338
+ <div className="mb-2 flex items-center gap-2">
339
+ <AlertIcon className="h-4 w-4 text-yellow-400" />
340
+ <span className="font-medium text-yellow-400">Warning</span>
341
+ </div>
342
+ <p className="text-sm text-yellow-200">
343
+ This action will modify existing data. Make sure you have a
344
+ backup before continuing.
345
+ </p>
346
+ </div>
347
+ </DialogWithCleanupVariant>
348
+
349
+ <DialogWithCleanupVariant
350
+ variant="negative"
351
+ title="Error Dialog"
352
+ description="An error occurred that requires your attention."
353
+ >
354
+ <div className="rounded-lg border border-red-500/20 bg-red-500/10 p-3">
355
+ <div className="mb-2 flex items-center gap-2">
356
+ <AlertIcon className="h-4 w-4 text-red-400" />
357
+ <span className="font-medium text-red-400">Error</span>
358
+ </div>
359
+ <p className="text-sm text-red-200">
360
+ Failed to save changes. Please check your connection and try
361
+ again.
362
+ </p>
363
+ </div>
364
+ </DialogWithCleanupVariant>
365
+
366
+ <DialogWithCleanupVariant
367
+ variant="info"
368
+ title="Information Dialog"
369
+ description="Here's some important information for you."
370
+ >
371
+ <div className="rounded-lg border border-blue-500/20 bg-blue-500/10 p-3">
372
+ <div className="mb-2 flex items-center gap-2">
373
+ <LightBulbSimpleIcon className="h-4 w-4 text-blue-400" />
374
+ <span className="font-medium text-blue-400">Information</span>
375
+ </div>
376
+ <p className="text-sm text-blue-200">
377
+ The new features will be available starting next week. Check
378
+ your email for detailed release notes.
379
+ </p>
380
+ </div>
381
+ </DialogWithCleanupVariant>
382
+ </div>
383
+ </div>
384
+ )
385
+ },
386
+ parameters: {
387
+ docs: {
388
+ description: {
389
+ story:
390
+ "Different dialog variants with useDialogCleanup hook for React 18 compatibility.",
391
+ },
392
+ },
393
+ },
394
+ }
395
+
396
+ // 3. Nested Modal with Cleanup
397
+ export const NestedModalWithCleanup: Story = {
398
+ render: () => {
399
+ const NestedDialogComponent = () => {
400
+ const { handleDialogClose } = useDialogCleanup({ threshold: 150 })
401
+ const [isEditOpen, setIsEditOpen] = useState(false)
402
+ const [isDeleteOpen, setIsDeleteOpen] = useState(false)
403
+
404
+ const handleEditClose = () => {
405
+ handleDialogClose()
406
+ setIsEditOpen(false)
407
+ }
408
+
409
+ const handleDeleteClose = () => {
410
+ handleDialogClose()
411
+ setIsDeleteOpen(false)
412
+ }
413
+
414
+ const handleDelete = () => {
415
+ console.log("User deleted")
416
+ handleDeleteClose()
417
+ handleEditClose()
418
+ }
419
+
420
+ return (
421
+ <>
422
+ <Dialog open={isEditOpen} onOpenChange={setIsEditOpen}>
423
+ <DialogTrigger asChild>
424
+ <Button className="gap-2">
425
+ <EditBigIcon className="h-4 w-4" />
426
+ Edit with Cleanup
427
+ </Button>
428
+ </DialogTrigger>
429
+ <DialogContent
430
+ className="max-w-md"
431
+ //@ts-expect-error onEscapeKeyDown available in Radix v2.0.0
432
+ onEscapeKeyDown={handleEditClose}
433
+ onPointerDownOutside={handleEditClose}
434
+ >
435
+ <DialogHeader>
436
+ <DialogTitle>Edit User Profile</DialogTitle>
437
+ <DialogDescription>
438
+ Update user information or delete the account.
439
+ </DialogDescription>
440
+ </DialogHeader>
441
+
442
+ <div className="space-y-4">
443
+ <Input placeholder="User name" />
444
+ <Input placeholder="Email address" type="email" />
445
+ <Textarea placeholder="Bio" rows={3} />
446
+ </div>
447
+
448
+ <DialogFooter className="flex-col space-y-2 sm:flex-col sm:space-y-2 sm:space-x-0">
449
+ <div className="flex gap-2 sm:order-2">
450
+ <Button
451
+ variant="outline"
452
+ onClick={handleEditClose}
453
+ className="flex-1"
454
+ >
455
+ Cancel
456
+ </Button>
457
+ <Button className="flex-1">Save Changes</Button>
458
+ </div>
459
+ <div className="sm:order-1">
460
+ <Button
461
+ size="sm"
462
+ className="mb-4 w-full gap-2"
463
+ onClick={() => setIsDeleteOpen(true)}
464
+ >
465
+ <TrashIcon className="h-4 w-4" />
466
+ Delete Account
467
+ </Button>
468
+ </div>
469
+ </DialogFooter>
470
+ </DialogContent>
471
+ </Dialog>
472
+
473
+ <Dialog open={isDeleteOpen} onOpenChange={setIsDeleteOpen}>
474
+ <DialogContent
475
+ variant="negative"
476
+ classes={{
477
+ root: "max-w-sm",
478
+ overlay: "z-60",
479
+ content: "z-70",
480
+ }}
481
+ //@ts-expect-error onEscapeKeyDown available in Radix v2.0.0
482
+ onEscapeKeyDown={handleDeleteClose}
483
+ onPointerDownOutside={handleDeleteClose}
484
+ >
485
+ <DialogHeader>
486
+ <DialogTitle className="flex items-center gap-2">
487
+ <AlertIcon className="h-5 w-5 text-red-400" />
488
+ Delete Account
489
+ </DialogTitle>
490
+ <DialogDescription>
491
+ This action cannot be undone.
492
+ </DialogDescription>
493
+ </DialogHeader>
494
+
495
+ <div className="py-4">
496
+ <div className="rounded-lg border border-red-500/20 bg-red-500/10 p-3">
497
+ <p className="text-sm text-red-200">
498
+ Are you absolutely sure you want to delete this account?
499
+ This will permanently remove all associated data.
500
+ </p>
501
+ </div>
502
+ </div>
503
+
504
+ <DialogFooter>
505
+ <Button variant="outline" onClick={handleDeleteClose}>
506
+ Cancel
507
+ </Button>
508
+ <Button onClick={handleDelete} className="gap-2">
509
+ <TrashIcon className="h-4 w-4" />
510
+ Delete Forever
511
+ </Button>
512
+ </DialogFooter>
513
+ </DialogContent>
514
+ </Dialog>
515
+ </>
516
+ )
517
+ }
518
+
519
+ return (
520
+ <div className="space-y-8">
521
+ <div className="text-center">
522
+ <h3 className="mb-2 font-medium text-white">
523
+ Nested Modal with Cleanup
524
+ </h3>
525
+ <p className="text-sm text-white/60">
526
+ Modal-on-modal with proper cleanup handling
527
+ </p>
528
+ </div>
529
+ <div className="flex justify-center">
530
+ <NestedDialogComponent />
531
+ </div>
532
+ <div className="text-center">
533
+ <div className="inline-block max-w-lg rounded-lg border border-white/10 bg-white/5 p-4">
534
+ <h4 className="mb-2 text-sm font-medium text-white">
535
+ Modal Stacking
536
+ </h4>
537
+ <p className="text-xs leading-relaxed text-white/60">
538
+ This example demonstrates proper modal stacking where a delete
539
+ confirmation dialog opens on top of an edit form dialog with
540
+ proper cleanup handling for React 18.
541
+ </p>
542
+ </div>
543
+ </div>
544
+ </div>
545
+ )
546
+ },
547
+ parameters: {
548
+ docs: {
549
+ description: {
550
+ story:
551
+ "Nested modal example with useDialogCleanup hook to handle multiple modal layers properly.",
552
+ },
553
+ },
554
+ },
555
+ }
556
+
557
+ // 4. Form Dialog with Cleanup
558
+ export const FormDialog: Story = {
559
+ render: () => {
560
+ const FormDialogComponent = () => {
561
+ const { handleDialogClose } = useDialogCleanup({ threshold: 100 })
562
+ const [formData, setFormData] = useState({
563
+ name: "",
564
+ email: "",
565
+ message: "",
566
+ newsletter: false,
567
+ })
568
+
569
+ const handleClose = () => {
570
+ handleDialogClose()
571
+ // Reset form data on close
572
+ setFormData({
573
+ name: "",
574
+ email: "",
575
+ message: "",
576
+ newsletter: false,
577
+ })
578
+ }
579
+
580
+ return (
581
+ <Dialog>
582
+ <DialogTrigger asChild>
583
+ <Button className="gap-2">
584
+ <EditBigIcon className="h-4 w-4" />
585
+ Contact Form
586
+ </Button>
587
+ </DialogTrigger>
588
+ <DialogContent
589
+ className="max-w-md"
590
+ //@ts-expect-error onEscapeKeyDown available in Radix v2.0.0
591
+ onEscapeKeyDown={handleClose}
592
+ onPointerDownOutside={handleClose}
593
+ >
594
+ <DialogHeader>
595
+ <DialogTitle>Contact Us</DialogTitle>
596
+ <DialogDescription>
597
+ Send us a message and we'll get back to you soon.
598
+ </DialogDescription>
599
+ </DialogHeader>
600
+
601
+ <div className="space-y-4">
602
+ <div className="space-y-2">
603
+ <Label htmlFor="name">Name</Label>
604
+ <Input
605
+ id="name"
606
+ placeholder="Your name"
607
+ value={formData.name}
608
+ onChange={(e) =>
609
+ setFormData((prev) => ({ ...prev, name: e.target.value }))
610
+ }
611
+ />
612
+ </div>
613
+
614
+ <div className="space-y-2">
615
+ <Label htmlFor="email">Email</Label>
616
+ <Input
617
+ id="email"
618
+ type="email"
619
+ placeholder="your.email@example.com"
620
+ value={formData.email}
621
+ onChange={(e) =>
622
+ setFormData((prev) => ({
623
+ ...prev,
624
+ email: e.target.value,
625
+ }))
626
+ }
627
+ />
628
+ </div>
629
+
630
+ <div className="space-y-2">
631
+ <Label htmlFor="message">Message</Label>
632
+ <Textarea
633
+ id="message"
634
+ placeholder="Your message..."
635
+ rows={4}
636
+ value={formData.message}
637
+ onChange={(e) =>
638
+ setFormData((prev) => ({
639
+ ...prev,
640
+ message: e.target.value,
641
+ }))
642
+ }
643
+ />
644
+ </div>
645
+
646
+ <div className="flex items-center space-x-2">
647
+ <Checkbox
648
+ id="newsletter"
649
+ checked={formData.newsletter}
650
+ onCheckedChange={(checked) =>
651
+ setFormData((prev) => ({
652
+ ...prev,
653
+ newsletter: !!checked,
654
+ }))
655
+ }
656
+ />
657
+ <Label htmlFor="newsletter" className="text-sm">
658
+ Subscribe to newsletter
659
+ </Label>
660
+ </div>
661
+ </div>
662
+
663
+ <DialogFooter>
664
+ <DialogClose asChild>
665
+ <Button variant="outline" onClick={handleClose}>
666
+ Cancel
667
+ </Button>
668
+ </DialogClose>
669
+ <Button
670
+ disabled={
671
+ !formData.name || !formData.email || !formData.message
672
+ }
673
+ onClick={() => {
674
+ console.log("Form submitted:", formData)
675
+ handleClose()
676
+ }}
677
+ >
678
+ Send Message
679
+ </Button>
680
+ </DialogFooter>
681
+ </DialogContent>
682
+ </Dialog>
683
+ )
684
+ }
685
+
686
+ return (
687
+ <div className="space-y-8">
688
+ <div className="text-center">
689
+ <h3 className="mb-2 font-medium text-white">Form Dialog</h3>
690
+ <p className="text-sm text-white/60">
691
+ Dialog containing form elements with cleanup handling
692
+ </p>
693
+ </div>
694
+ <div className="flex justify-center">
695
+ <FormDialogComponent />
696
+ </div>
697
+ </div>
698
+ )
699
+ },
700
+ parameters: {
701
+ docs: {
702
+ description: {
703
+ story:
704
+ "Form dialog with validation and cleanup handling for React 18 compatibility.",
705
+ },
706
+ },
707
+ },
708
+ }
709
+
710
+ // 5. Overlay Variations
711
+ export const OverlayVariations: Story = {
712
+ render: () => {
713
+ const OverlayDialog = ({
714
+ opacity,
715
+ glass,
716
+ noise,
717
+ title,
718
+ description,
719
+ }: any) => {
720
+ const { handleDialogClose } = useDialogCleanup({ threshold: 100 })
721
+
722
+ return (
723
+ <Dialog>
724
+ <DialogTrigger asChild>
725
+ <Button variant="outline">{title}</Button>
726
+ </DialogTrigger>
727
+ <DialogContent opacity={opacity} glass={glass} noise={noise}>
728
+ <DialogHeader>
729
+ <DialogTitle>{title}</DialogTitle>
730
+ <DialogDescription>{description}</DialogDescription>
731
+ </DialogHeader>
732
+ <div className="py-4">
733
+ <div className="grid grid-cols-2 gap-2 text-xs text-white/60">
734
+ <div>
735
+ Opacity:{" "}
736
+ <span className="text-white">{opacity || "default"}</span>
737
+ </div>
738
+ <div>
739
+ Glass:{" "}
740
+ <span className="text-white">{glass || "default"}</span>
741
+ </div>
742
+ <div>
743
+ Noise: <span className="text-white">{noise || "none"}</span>
744
+ </div>
745
+ </div>
746
+ </div>
747
+ <DialogFooter>
748
+ <DialogClose asChild>
749
+ <Button onClick={handleDialogClose}>Close</Button>
750
+ </DialogClose>
751
+ </DialogFooter>
752
+ </DialogContent>
753
+ </Dialog>
754
+ )
755
+ }
756
+
757
+ return (
758
+ <div className="space-y-8">
759
+ <div className="text-center">
760
+ <h3 className="mb-2 font-medium text-white">Overlay Variations</h3>
761
+ <p className="text-sm text-white/60">
762
+ Different overlay effects with cleanup handling
763
+ </p>
764
+ </div>
765
+
766
+ <div className="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4">
767
+ <OverlayDialog
768
+ opacity="low"
769
+ title="Low Opacity"
770
+ description="Subtle background dimming (40%)"
771
+ />
772
+ <OverlayDialog
773
+ opacity="medium"
774
+ title="Medium Opacity"
775
+ description="Balanced background dimming (60%)"
776
+ />
777
+ <OverlayDialog
778
+ opacity="high"
779
+ title="High Opacity"
780
+ description="Strong background dimming (80%)"
781
+ />
782
+ <OverlayDialog
783
+ opacity="none"
784
+ title="Full Opacity"
785
+ description="Complete background coverage (100%)"
786
+ />
787
+ <OverlayDialog
788
+ glass="low"
789
+ title="Low Glass"
790
+ description="Subtle backdrop blur effect"
791
+ />
792
+ <OverlayDialog
793
+ glass="medium"
794
+ title="Medium Glass"
795
+ description="Balanced backdrop blur effect"
796
+ />
797
+ <OverlayDialog
798
+ glass="high"
799
+ title="High Glass"
800
+ description="Strong backdrop blur effect"
801
+ />
802
+ <OverlayDialog
803
+ noise="low"
804
+ title="Low Noise"
805
+ description="Subtle texture pattern"
806
+ />
807
+ <OverlayDialog
808
+ noise="medium"
809
+ title="Medium Noise"
810
+ description="Balanced texture pattern"
811
+ />
812
+ <OverlayDialog
813
+ noise="high"
814
+ title="High Noise"
815
+ description="Strong texture pattern"
816
+ />
817
+ <OverlayDialog
818
+ opacity="high"
819
+ glass="high"
820
+ title="High + Glass"
821
+ description="Maximum focus with glass effect"
822
+ />
823
+ <OverlayDialog
824
+ opacity="medium"
825
+ glass="medium"
826
+ noise="low"
827
+ title="Balanced Mix"
828
+ description="Balanced combination of effects"
829
+ />
830
+ </div>
831
+ </div>
832
+ )
833
+ },
834
+ parameters: {
835
+ docs: {
836
+ description: {
837
+ story:
838
+ "Showcase of different overlay configurations including opacity, glass, and noise effects.",
839
+ },
840
+ },
841
+ },
842
+ }
843
+
844
+ // 6. Accessibility Example
845
+ export const AccessibilityExample: Story = {
846
+ render: () => {
847
+ const AccessibleDialog = () => {
848
+ const { handleDialogClose } = useDialogCleanup({ threshold: 100 })
849
+
850
+ return (
851
+ <Dialog>
852
+ <DialogTrigger asChild>
853
+ <Button>Accessible Dialog Demo</Button>
854
+ </DialogTrigger>
855
+ <DialogContent
856
+ //@ts-expect-error onEscapeKeyDown available in Radix v2.0.0
857
+ onEscapeKeyDown={handleDialogClose}
858
+ onPointerDownOutside={handleDialogClose}
859
+ >
860
+ <DialogHeader>
861
+ <DialogTitle>Accessibility Features</DialogTitle>
862
+ <DialogDescription>
863
+ This dialog demonstrates proper accessibility implementation.
864
+ </DialogDescription>
865
+ </DialogHeader>
866
+
867
+ <div className="space-y-4">
868
+ <div className="rounded-lg border border-white/10 bg-white/5 p-4">
869
+ <h4 className="mb-2 font-medium text-white">
870
+ Keyboard Navigation
871
+ </h4>
872
+ <ul className="space-y-1 text-sm text-white/80">
873
+ <li>
874
+ • <kbd className="rounded bg-white/10 px-1">Tab</kbd> -
875
+ Navigate between elements
876
+ </li>
877
+ <li>
878
+ • <kbd className="rounded bg-white/10 px-1">Escape</kbd> -
879
+ Close dialog
880
+ </li>
881
+ <li>
882
+ • <kbd className="rounded bg-white/10 px-1">Enter</kbd> -
883
+ Activate buttons
884
+ </li>
885
+ <li>
886
+ • <kbd className="rounded bg-white/10 px-1">Space</kbd> -
887
+ Activate buttons
888
+ </li>
889
+ </ul>
890
+ </div>
891
+
892
+ <div className="rounded-lg border border-white/10 bg-white/5 p-4">
893
+ <h4 className="mb-2 font-medium text-white">
894
+ Screen Reader Support
895
+ </h4>
896
+ <ul className="space-y-1 text-sm text-white/80">
897
+ <li>• Proper ARIA labels and roles</li>
898
+ <li>• Focus management and trapping</li>
899
+ <li>• Descriptive close button</li>
900
+ <li>• Semantic heading structure</li>
901
+ </ul>
902
+ </div>
903
+
904
+ <div className="rounded-lg border border-white/10 bg-white/5 p-4">
905
+ <h4 className="mb-2 font-medium text-white">
906
+ React 18 Compatibility
907
+ </h4>
908
+ <ul className="space-y-1 text-sm text-white/80">
909
+ <li>• Cleanup hook prevents pointer-events issues</li>
910
+ <li>• Proper modal stacking support</li>
911
+ <li>• Body scroll restoration</li>
912
+ <li>• Focus restoration on close</li>
913
+ </ul>
914
+ </div>
915
+ </div>
916
+
917
+ <DialogFooter>
918
+ <DialogClose asChild>
919
+ <Button onClick={handleDialogClose}>Close Dialog</Button>
920
+ </DialogClose>
921
+ </DialogFooter>
922
+ </DialogContent>
923
+ </Dialog>
924
+ )
925
+ }
926
+
927
+ return (
928
+ <div className="space-y-8">
929
+ <div className="text-center">
930
+ <h3 className="mb-2 font-medium text-white">
931
+ Accessibility Features
932
+ </h3>
933
+ <p className="text-sm text-white/60">
934
+ Dialog with comprehensive accessibility and React 18 compatibility
935
+ </p>
936
+ </div>
937
+ <div className="flex justify-center">
938
+ <AccessibleDialog />
939
+ </div>
940
+ <div className="text-center">
941
+ <div className="inline-block max-w-lg rounded-lg border border-white/10 bg-white/5 p-4">
942
+ <h4 className="mb-2 text-sm font-medium text-white">
943
+ Accessibility Best Practices
944
+ </h4>
945
+ <p className="text-xs leading-relaxed text-white/60">
946
+ The Dialog component follows WCAG guidelines with proper focus
947
+ management, keyboard navigation, screen reader support, semantic
948
+ HTML structure, and React 18 compatibility fixes.
949
+ </p>
950
+ </div>
951
+ </div>
952
+ </div>
953
+ )
954
+ },
955
+ parameters: {
956
+ docs: {
957
+ description: {
958
+ story:
959
+ "Comprehensive accessibility example with React 18 compatibility features.",
960
+ },
961
+ },
962
+ },
963
+ }