@fpkit/acss 0.5.11 → 0.5.13

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 (312) hide show
  1. package/README.md +514 -18
  2. package/libs/chunk-23ANBDCR.js +8 -0
  3. package/libs/chunk-23ANBDCR.js.map +1 -0
  4. package/libs/chunk-2LTJ7HHX.cjs +18 -0
  5. package/libs/chunk-2LTJ7HHX.cjs.map +1 -0
  6. package/libs/chunk-2Y7W75TT.js +9 -0
  7. package/libs/chunk-2Y7W75TT.js.map +1 -0
  8. package/libs/chunk-3MKLDCKQ.cjs +31 -0
  9. package/libs/chunk-3MKLDCKQ.cjs.map +1 -0
  10. package/libs/chunk-5M57K4SW.js +8 -0
  11. package/libs/chunk-5M57K4SW.js.map +1 -0
  12. package/libs/chunk-5S4ORA4C.cjs +15 -0
  13. package/libs/chunk-5S4ORA4C.cjs.map +1 -0
  14. package/libs/chunk-772NRB75.js +9 -0
  15. package/libs/chunk-772NRB75.js.map +1 -0
  16. package/libs/chunk-AHDJGCG5.cjs +15 -0
  17. package/libs/chunk-AHDJGCG5.cjs.map +1 -0
  18. package/libs/chunk-B7F5FS6D.cjs +16 -0
  19. package/libs/chunk-B7F5FS6D.cjs.map +1 -0
  20. package/libs/chunk-BHRQBJRY.js +8 -0
  21. package/libs/chunk-BHRQBJRY.js.map +1 -0
  22. package/libs/chunk-D4YLRWAO.cjs +18 -0
  23. package/libs/chunk-D4YLRWAO.cjs.map +1 -0
  24. package/libs/chunk-ETFLFC2S.js +10 -0
  25. package/libs/chunk-ETFLFC2S.js.map +1 -0
  26. package/libs/chunk-G55UJ53G.cjs +16 -0
  27. package/libs/chunk-G55UJ53G.cjs.map +1 -0
  28. package/libs/chunk-GZ4QFPRY.js +9 -0
  29. package/libs/chunk-GZ4QFPRY.js.map +1 -0
  30. package/libs/chunk-IYUN2EW3.cjs +15 -0
  31. package/libs/chunk-IYUN2EW3.cjs.map +1 -0
  32. package/libs/chunk-J32EZPYD.cjs +15 -0
  33. package/libs/chunk-J32EZPYD.cjs.map +1 -0
  34. package/libs/chunk-JJ43O4Y5.js +8 -0
  35. package/libs/chunk-JJ43O4Y5.js.map +1 -0
  36. package/libs/chunk-KUKIVRC2.js +7 -0
  37. package/libs/chunk-KUKIVRC2.js.map +1 -0
  38. package/libs/chunk-L75OQKEI.cjs +13 -0
  39. package/libs/chunk-L75OQKEI.cjs.map +1 -0
  40. package/libs/chunk-LT5KZ2QW.cjs +22 -0
  41. package/libs/chunk-LT5KZ2QW.cjs.map +1 -0
  42. package/libs/chunk-M5RRNTVX.cjs +15 -0
  43. package/libs/chunk-M5RRNTVX.cjs.map +1 -0
  44. package/libs/chunk-NGTJDDFO.js +8 -0
  45. package/libs/chunk-NGTJDDFO.js.map +1 -0
  46. package/libs/chunk-OK5QEIMD.cjs +17 -0
  47. package/libs/chunk-OK5QEIMD.cjs.map +1 -0
  48. package/libs/chunk-P2DC76ZZ.cjs +18 -0
  49. package/libs/chunk-P2DC76ZZ.cjs.map +1 -0
  50. package/libs/chunk-P7TTEYCD.js +7 -0
  51. package/libs/chunk-P7TTEYCD.js.map +1 -0
  52. package/libs/chunk-PQ2K3BM6.cjs +17 -0
  53. package/libs/chunk-PQ2K3BM6.cjs.map +1 -0
  54. package/libs/chunk-QLZWHAMK.js +8 -0
  55. package/libs/chunk-QLZWHAMK.js.map +1 -0
  56. package/libs/chunk-RIVUMPOG.js +8 -0
  57. package/libs/chunk-RIVUMPOG.js.map +1 -0
  58. package/libs/chunk-ROZI23GS.cjs +15 -0
  59. package/libs/chunk-ROZI23GS.cjs.map +1 -0
  60. package/libs/chunk-S7BABR7Z.cjs +13 -0
  61. package/libs/chunk-S7BABR7Z.cjs.map +1 -0
  62. package/libs/chunk-SMYRLO3E.js +8 -0
  63. package/libs/chunk-SMYRLO3E.js.map +1 -0
  64. package/libs/chunk-TYRCEX2L.js +8 -0
  65. package/libs/chunk-TYRCEX2L.js.map +1 -0
  66. package/libs/chunk-VUH3FXGJ.js +11 -0
  67. package/libs/chunk-VUH3FXGJ.js.map +1 -0
  68. package/libs/chunk-XBA562WW.js +8 -0
  69. package/libs/chunk-XBA562WW.js.map +1 -0
  70. package/libs/chunk-XTQKWY7W.cjs +32 -0
  71. package/libs/chunk-XTQKWY7W.cjs.map +1 -0
  72. package/libs/chunk-ZANSFMTD.js +9 -0
  73. package/libs/chunk-ZANSFMTD.js.map +1 -0
  74. package/libs/component-props-a8a2f97e.d.ts +38 -0
  75. package/libs/components/alert/alert.css +1 -1
  76. package/libs/components/alert/alert.css.map +1 -1
  77. package/libs/components/alert/alert.min.css +2 -2
  78. package/libs/components/badge/badge.css +1 -1
  79. package/libs/components/badge/badge.css.map +1 -1
  80. package/libs/components/badge/badge.min.css +2 -2
  81. package/libs/components/breadcrumbs/breadcrumb.cjs +24 -0
  82. package/libs/components/breadcrumbs/breadcrumb.cjs.map +1 -0
  83. package/libs/components/breadcrumbs/breadcrumb.d.cts +290 -0
  84. package/libs/components/breadcrumbs/breadcrumb.d.ts +290 -0
  85. package/libs/components/breadcrumbs/breadcrumb.js +5 -0
  86. package/libs/components/breadcrumbs/breadcrumb.js.map +1 -0
  87. package/libs/components/button.cjs +19 -0
  88. package/libs/components/button.cjs.map +1 -0
  89. package/libs/components/button.d.cts +16 -0
  90. package/libs/components/button.d.ts +16 -0
  91. package/libs/components/button.js +4 -0
  92. package/libs/components/button.js.map +1 -0
  93. package/libs/components/buttons/button.css +1 -1
  94. package/libs/components/buttons/button.css.map +1 -1
  95. package/libs/components/buttons/button.min.css +2 -2
  96. package/libs/components/card.cjs +31 -0
  97. package/libs/components/card.cjs.map +1 -0
  98. package/libs/components/card.d.cts +302 -0
  99. package/libs/components/card.d.ts +302 -0
  100. package/libs/components/card.js +4 -0
  101. package/libs/components/card.js.map +1 -0
  102. package/libs/components/cards/card.css +1 -1
  103. package/libs/components/cards/card.css.map +1 -1
  104. package/libs/components/cards/card.min.css +2 -2
  105. package/libs/components/details/details.css +1 -1
  106. package/libs/components/details/details.css.map +1 -1
  107. package/libs/components/details/details.min.css +2 -2
  108. package/libs/components/dialog/dialog.cjs +22 -0
  109. package/libs/components/dialog/dialog.cjs.map +1 -0
  110. package/libs/components/dialog/dialog.css +1 -1
  111. package/libs/components/dialog/dialog.css.map +1 -1
  112. package/libs/components/dialog/dialog.d.cts +105 -0
  113. package/libs/components/dialog/dialog.d.ts +105 -0
  114. package/libs/components/dialog/dialog.js +7 -0
  115. package/libs/components/dialog/dialog.js.map +1 -0
  116. package/libs/components/dialog/dialog.min.css +2 -2
  117. package/libs/components/form/fields.cjs +19 -0
  118. package/libs/components/form/fields.cjs.map +1 -0
  119. package/libs/components/form/fields.d.cts +24 -0
  120. package/libs/components/form/fields.d.ts +24 -0
  121. package/libs/components/form/fields.js +4 -0
  122. package/libs/components/form/fields.js.map +1 -0
  123. package/libs/components/form/inputs.cjs +19 -0
  124. package/libs/components/form/inputs.cjs.map +1 -0
  125. package/libs/components/form/inputs.d.cts +2 -0
  126. package/libs/components/form/inputs.d.ts +2 -0
  127. package/libs/components/form/inputs.js +4 -0
  128. package/libs/components/form/inputs.js.map +1 -0
  129. package/libs/components/form/textarea.cjs +19 -0
  130. package/libs/components/form/textarea.cjs.map +1 -0
  131. package/libs/components/form/textarea.d.cts +29 -0
  132. package/libs/components/form/textarea.d.ts +29 -0
  133. package/libs/components/form/textarea.js +4 -0
  134. package/libs/components/form/textarea.js.map +1 -0
  135. package/libs/components/heading/heading.cjs +10 -0
  136. package/libs/components/heading/heading.cjs.map +1 -0
  137. package/libs/components/heading/heading.d.cts +3 -0
  138. package/libs/components/heading/heading.d.ts +3 -0
  139. package/libs/components/heading/heading.js +4 -0
  140. package/libs/components/heading/heading.js.map +1 -0
  141. package/libs/components/icons/icon.cjs +19 -0
  142. package/libs/components/icons/icon.cjs.map +1 -0
  143. package/libs/{icons-31ace3de.d.ts → components/icons/icon.d.cts} +151 -61
  144. package/libs/components/icons/icon.d.ts +445 -0
  145. package/libs/components/icons/icon.js +4 -0
  146. package/libs/components/icons/icon.js.map +1 -0
  147. package/libs/components/images/img.css +1 -1
  148. package/libs/components/images/img.css.map +1 -1
  149. package/libs/components/images/img.min.css +2 -2
  150. package/libs/components/link/link.cjs +19 -0
  151. package/libs/components/link/link.cjs.map +1 -0
  152. package/libs/components/link/link.d.cts +19 -0
  153. package/libs/components/link/link.d.ts +19 -0
  154. package/libs/components/link/link.js +4 -0
  155. package/libs/components/link/link.js.map +1 -0
  156. package/libs/components/list/list.cjs +23 -0
  157. package/libs/components/list/list.cjs.map +1 -0
  158. package/libs/components/list/list.d.cts +39 -0
  159. package/libs/components/list/list.d.ts +39 -0
  160. package/libs/components/list/list.js +4 -0
  161. package/libs/components/list/list.js.map +1 -0
  162. package/libs/components/modal.cjs +14 -0
  163. package/libs/components/modal.cjs.map +1 -0
  164. package/libs/components/modal.d.cts +35 -0
  165. package/libs/components/modal.d.ts +35 -0
  166. package/libs/components/modal.js +5 -0
  167. package/libs/components/modal.js.map +1 -0
  168. package/libs/components/nav/nav.cjs +28 -0
  169. package/libs/components/nav/nav.cjs.map +1 -0
  170. package/libs/components/nav/nav.d.cts +44 -0
  171. package/libs/components/nav/nav.d.ts +44 -0
  172. package/libs/components/nav/nav.js +5 -0
  173. package/libs/components/nav/nav.js.map +1 -0
  174. package/libs/components/popover/popover.cjs +23 -0
  175. package/libs/components/popover/popover.cjs.map +1 -0
  176. package/libs/components/popover/popover.d.cts +40 -0
  177. package/libs/components/popover/popover.d.ts +40 -0
  178. package/libs/components/popover/popover.js +4 -0
  179. package/libs/components/popover/popover.js.map +1 -0
  180. package/libs/components/tables/table.cjs +21 -0
  181. package/libs/components/tables/table.cjs.map +1 -0
  182. package/libs/components/tables/table.d.cts +36 -0
  183. package/libs/components/tables/table.d.ts +36 -0
  184. package/libs/components/tables/table.js +4 -0
  185. package/libs/components/tables/table.js.map +1 -0
  186. package/libs/components/text/text.cjs +23 -0
  187. package/libs/components/text/text.cjs.map +1 -0
  188. package/libs/components/text/text.d.cts +30 -0
  189. package/libs/components/text/text.d.ts +30 -0
  190. package/libs/components/text/text.js +4 -0
  191. package/libs/components/text/text.js.map +1 -0
  192. package/libs/heading-3648c538.d.ts +250 -0
  193. package/libs/hooks.cjs +7 -0
  194. package/libs/hooks.d.cts +5 -0
  195. package/libs/hooks.d.ts +5 -0
  196. package/libs/hooks.js +3 -0
  197. package/libs/icons.cjs +3 -2
  198. package/libs/icons.d.cts +3 -1
  199. package/libs/icons.d.ts +3 -1
  200. package/libs/icons.js +2 -1
  201. package/libs/index.cjs +174 -62
  202. package/libs/index.cjs.map +1 -1
  203. package/libs/index.css +1 -1
  204. package/libs/index.css.map +1 -1
  205. package/libs/index.d.cts +529 -446
  206. package/libs/index.d.ts +529 -446
  207. package/libs/index.js +36 -7
  208. package/libs/index.js.map +1 -1
  209. package/libs/inputs-f3a216db.d.ts +45 -0
  210. package/libs/ui-645f95b5.d.ts +285 -0
  211. package/package.json +2 -2
  212. package/src/components/README-UI.mdx +416 -0
  213. package/src/components/alert/ACCESSIBILITY.md +319 -0
  214. package/src/components/alert/README.mdx +475 -19
  215. package/src/components/alert/alert.scss +113 -6
  216. package/src/components/alert/alert.stories.tsx +372 -0
  217. package/src/components/alert/alert.test.tsx +762 -0
  218. package/src/components/alert/alert.tsx +331 -66
  219. package/src/components/alert/views/alert-actions.tsx +13 -0
  220. package/src/components/alert/views/alert-content.tsx +17 -0
  221. package/src/components/alert/views/alert-icon.tsx +53 -0
  222. package/src/components/alert/views/alert-screen-reader-text.tsx +30 -0
  223. package/src/components/alert/views/alert-title.tsx +23 -0
  224. package/src/components/alert/views/alert-view.tsx +158 -0
  225. package/src/components/alert/views/index.ts +12 -0
  226. package/src/components/badge/badge.mdx +186 -49
  227. package/src/components/badge/badge.scss +20 -2
  228. package/src/components/badge/badge.stories.tsx +160 -14
  229. package/src/components/badge/badge.test.tsx +179 -0
  230. package/src/components/badge/badge.tsx +97 -4
  231. package/src/components/breadcrumbs/README.mdx +364 -45
  232. package/src/components/breadcrumbs/__snapshots__/breadcrumb.test.tsx.snap +152 -0
  233. package/src/components/breadcrumbs/breadcrumb.stories.tsx +7 -3
  234. package/src/components/breadcrumbs/breadcrumb.test.tsx +490 -0
  235. package/src/components/breadcrumbs/breadcrumb.tsx +427 -170
  236. package/src/components/button.ts +2 -0
  237. package/src/components/buttons/button.scss +34 -31
  238. package/src/components/buttons/button.stories.tsx +35 -0
  239. package/src/components/card.ts +2 -0
  240. package/src/components/cards/README.mdx +657 -0
  241. package/src/components/cards/card.scss +22 -0
  242. package/src/components/cards/card.stories.tsx +167 -5
  243. package/src/components/cards/card.test.tsx +360 -20
  244. package/src/components/cards/card.tsx +200 -79
  245. package/src/components/cards/card.types.ts +135 -0
  246. package/src/components/cards/card.utils.ts +79 -0
  247. package/src/components/details/ACCESSIBILITY-REVIEW-LIVE.md +1050 -0
  248. package/src/components/details/ACCESSIBILITY-REVIEW.md +502 -0
  249. package/src/components/details/README.mdx +437 -69
  250. package/src/components/details/details.scss +16 -0
  251. package/src/components/details/details.test.tsx +385 -0
  252. package/src/components/details/details.tsx +101 -69
  253. package/src/components/details/details.types.ts +76 -0
  254. package/src/components/dialog/README.mdx +513 -110
  255. package/src/components/dialog/dialog-modal.tsx +79 -56
  256. package/src/components/dialog/dialog.scss +53 -3
  257. package/src/components/dialog/dialog.stories.tsx +10 -7
  258. package/src/components/dialog/dialog.test.tsx +450 -0
  259. package/src/components/dialog/dialog.tsx +69 -59
  260. package/src/components/dialog/dialog.types.ts +133 -0
  261. package/src/components/dialog/views/dialog-footer.tsx +54 -11
  262. package/src/components/dialog/views/dialog-header.tsx +20 -15
  263. package/src/components/heading/heading.stories.tsx +44 -4
  264. package/src/components/heading/heading.tsx +89 -23
  265. package/src/components/icons/README.mdx +332 -0
  266. package/src/components/icons/icon.stories.tsx +74 -1
  267. package/src/components/icons/icon.tsx +89 -1
  268. package/src/components/icons/types.ts +47 -0
  269. package/src/components/images/README.mdx +340 -24
  270. package/src/components/images/img.scss +19 -3
  271. package/src/components/images/img.stories.tsx +424 -15
  272. package/src/components/images/img.test.tsx +354 -25
  273. package/src/components/images/img.tsx +186 -63
  274. package/src/components/images/img.types.ts +211 -0
  275. package/src/components/modal.ts +1 -0
  276. package/src/components/title/MIGRATION.md +199 -0
  277. package/src/components/title/README.md +326 -0
  278. package/src/components/title/README.mdx +452 -0
  279. package/src/components/title/title.stories.tsx +393 -0
  280. package/src/components/title/title.test.tsx +251 -0
  281. package/src/components/title/title.tsx +219 -0
  282. package/src/components/ui.stories.tsx +894 -0
  283. package/src/components/ui.test.tsx +559 -0
  284. package/src/components/ui.tsx +266 -15
  285. package/src/components/word-count/README.md +240 -0
  286. package/src/hooks.ts +1 -0
  287. package/src/index.ts +51 -19
  288. package/src/sass/_properties.scss +1 -0
  289. package/src/styles/alert/alert.css +94 -4
  290. package/src/styles/alert/alert.css.map +1 -1
  291. package/src/styles/badge/badge.css +20 -2
  292. package/src/styles/badge/badge.css.map +1 -1
  293. package/src/styles/buttons/button.css +31 -31
  294. package/src/styles/buttons/button.css.map +1 -1
  295. package/src/styles/cards/card.css +16 -0
  296. package/src/styles/cards/card.css.map +1 -1
  297. package/src/styles/details/details.css +19 -0
  298. package/src/styles/details/details.css.map +1 -1
  299. package/src/styles/dialog/dialog.css +43 -2
  300. package/src/styles/dialog/dialog.css.map +1 -1
  301. package/src/styles/images/img.css +15 -3
  302. package/src/styles/images/img.css.map +1 -1
  303. package/src/styles/index.css +240 -43
  304. package/src/styles/index.css.map +1 -1
  305. package/src/test/setup.d.ts +9 -0
  306. package/src/test/setup.ts +53 -1
  307. package/libs/chunk-PWVRDQ3R.js +0 -8
  308. package/libs/chunk-PWVRDQ3R.js.map +0 -1
  309. package/libs/chunk-SVS4MX3U.cjs +0 -31
  310. package/libs/chunk-SVS4MX3U.cjs.map +0 -1
  311. package/src/components/cards/README.md +0 -80
  312. package/src/components/dialog/hooks/useClickOutside.ts +0 -33
@@ -1,61 +1,57 @@
1
- // Dialog.tsx
2
- import React from "react";
1
+ import React, { useState, useRef, useCallback, useEffect } from "react";
3
2
  import Dialog from "./dialog";
4
3
  import Button from "#components/buttons/button.jsx";
4
+ import type { DialogModalProps } from "./dialog.types";
5
5
 
6
6
  /**
7
- * Additional props for the DialogModal component, extending the props of the Dialog component.
7
+ * DialogModal - A wrapper component that manages dialog state and provides a trigger button.
8
8
  *
9
- * @property {string} [className] - Optional className for the dialog content wrapper.
10
- * @property {string} [btnLabel] - Label for the button that opens the dialog.
11
- * @property {() => void} [btnOnClick] - Callback function to be called when the button is clicked.
12
- * @property {"sm" | "md" | "lg"} [btnSize] - Size of the button that opens the dialog.
13
- */
14
- interface DialogModalProps extends React.ComponentProps<typeof Dialog> {
15
- /** Optional className for the dialog content wrapper */
16
- className?: string;
17
- btnLabel?: string;
18
- btnOnClick?: () => void;
19
- btnSize?: "sm" | "md" | "lg";
20
- btnProps?: React.ComponentProps<typeof Button>;
21
- }
22
-
23
- /**
24
- * A modal dialog component that provides an accessible overlay with an optional trigger button.
25
- * Extends the base Dialog component with additional button control functionality.
9
+ * This is an **uncontrolled** component wrapper around the controlled Dialog component.
10
+ * It manages the dialog's open/closed state internally and provides a button to trigger it.
11
+ *
12
+ * **Use this when:**
13
+ * - You want a simple dialog with a trigger button
14
+ * - You don't need to control the dialog state externally
15
+ * - You want automatic focus restoration to the trigger button
16
+ *
17
+ * **Use the base Dialog component instead when:**
18
+ * - You need to control dialog state from parent component
19
+ * - You have a custom trigger mechanism
20
+ * - You need to open dialog programmatically from multiple places
26
21
  *
27
22
  * @component
28
- * @param {Object} props - Component props
29
- * @param {boolean} [props.isAlertDialog] - Whether this is an alert dialog requiring user action
30
- * @param {() => void} [props.onClose] - Callback when dialog is closed
31
- * @param {string} [props.dialogTitle] - Title displayed in dialog header
32
- * @param {string} [props.dialogLabel] - Accessible label for the dialog
23
+ * @param {DialogModalProps} props - Component props
24
+ * @param {string} props.dialogTitle - Title displayed in dialog header
25
+ * @param {ReactNode} props.children - Content to display inside the dialog
33
26
  * @param {string} [props.btnLabel="Open Dialog"] - Text label for the trigger button
34
- * @param {"sm" | "md" | "lg"} [props.btnSize="md"] - Size of the trigger button
35
- * @param {() => void} [props.btnOnClick] - Callback when trigger button is clicked
36
- * @param {React.ReactNode} props.children - Content to display inside the dialog
37
- * @param {() => void} [props.onConfirm] - Callback when confirm button is clicked (for alert dialogs)
38
- * @param {string} [props.confirmLabel="Confirm"] - Text for the confirm button
39
- * @param {string} [props.cancelLabel="Cancel"] - Text for the cancel button
40
- * @param {string} [props.className] - Additional CSS class for the dialog wrapper
41
- * @param {React.ComponentProps<typeof Button>} [props.btnProps] - Additional props for the trigger button
42
- * @returns {JSX.Element} A dialog component with a trigger button
27
+ * @param {"sm" | "md" | "lg"} [props.btnSize="sm"] - Size variant for the trigger button
28
+ * @param {() => void} [props.btnOnClick] - Callback fired when trigger button is clicked (before opening)
29
+ * @param {boolean} [props.isAlertDialog=false] - If true, renders as non-modal inline alert
30
+ * @param {() => void} [props.onClose] - Callback fired when dialog is closed
31
+ * @param {() => void | Promise<void>} [props.onConfirm] - Callback when confirm button is clicked
32
+ * @param {string} [props.confirmLabel="Confirm"] - Text label for confirm button
33
+ * @param {string} [props.cancelLabel="Cancel"] - Text label for cancel button
34
+ * @param {boolean} [props.hideFooter=false] - If true, hides the footer with action buttons
35
+ * @param {string} [props.className] - Additional CSS classes for the dialog
36
+ * @param {string} [props.dialogLabel] - Optional aria-label for the dialog
37
+ * @returns {JSX.Element} A dialog with trigger button and automatic state management
43
38
  *
44
39
  * @example
45
- * ```jsx
40
+ * ```tsx
46
41
  * <DialogModal
47
- * dialogTitle="Confirm Action"
48
- * btnLabel="Open Modal"
49
- * btnSize="lg"
50
- * onClose={() => console.log('Dialog closed')}
42
+ * dialogTitle="Confirm Delete"
43
+ * btnLabel="Delete Item"
44
+ * btnSize="md"
45
+ * onConfirm={async () => await deleteItem()}
46
+ * confirmLabel="Delete"
47
+ * cancelLabel="Cancel"
51
48
  * >
52
- * <p>Dialog content goes here</p>
49
+ * Are you sure you want to delete this item? This action cannot be undone.
53
50
  * </DialogModal>
54
51
  * ```
55
52
  */
56
-
57
53
  export const DialogModal: React.FC<DialogModalProps> = ({
58
- isAlertDialog,
54
+ isAlertDialog = false,
59
55
  onClose,
60
56
  dialogTitle,
61
57
  dialogLabel,
@@ -67,21 +63,48 @@ export const DialogModal: React.FC<DialogModalProps> = ({
67
63
  confirmLabel = "Confirm",
68
64
  cancelLabel = "Cancel",
69
65
  className,
66
+ hideFooter = false,
70
67
  btnProps,
71
68
  }) => {
72
- const [isOpen, setIsOpen] = React.useState(false);
69
+ const [isOpen, setIsOpen] = useState(false);
70
+ const lastFocusedElement = useRef<HTMLElement | null>(null);
73
71
 
74
- const handleClose = () => {
75
- setIsOpen(false);
76
- onClose?.();
77
- };
78
- const handleButtonClick = () => {
72
+ // Handle dialog state changes
73
+ const handleOpenChange = useCallback(
74
+ (open: boolean) => {
75
+ setIsOpen(open);
76
+ // If closing, call the onClose callback
77
+ if (!open && onClose) {
78
+ onClose();
79
+ }
80
+ },
81
+ [onClose]
82
+ );
83
+
84
+ // Handle trigger button click
85
+ const handleButtonClick = useCallback(() => {
86
+ // Store the currently focused element (should be the trigger button)
87
+ lastFocusedElement.current = document.activeElement as HTMLElement;
79
88
  setIsOpen(true);
80
- btnOnClick?.();
81
- };
89
+ // Call optional pre-open callback
90
+ if (btnOnClick) {
91
+ btnOnClick();
92
+ }
93
+ }, [btnOnClick]);
94
+
95
+ // Restore focus to trigger button when dialog closes
96
+ useEffect(() => {
97
+ if (!isOpen && lastFocusedElement.current) {
98
+ // Small delay to ensure dialog has fully closed
99
+ const timeoutId = setTimeout(() => {
100
+ lastFocusedElement.current?.focus();
101
+ }, 100);
102
+ return () => clearTimeout(timeoutId);
103
+ }
104
+ }, [isOpen]);
82
105
 
83
- const dialogBtnProps = {
84
- type: "button" as "button" | "submit" | "reset",
106
+ const triggerButtonProps = {
107
+ type: "button" as const,
85
108
  onClick: handleButtonClick,
86
109
  "data-btn": btnSize,
87
110
  ...btnProps,
@@ -89,18 +112,18 @@ export const DialogModal: React.FC<DialogModalProps> = ({
89
112
 
90
113
  return (
91
114
  <>
92
- <Button {...dialogBtnProps}>{btnLabel}</Button>
115
+ <Button {...triggerButtonProps}>{btnLabel}</Button>
93
116
  <Dialog
94
- showDialog={isOpen}
117
+ isOpen={isOpen}
118
+ onOpenChange={handleOpenChange}
95
119
  dialogTitle={dialogTitle}
96
- onClose={handleClose}
97
- title={dialogTitle}
98
120
  dialogLabel={dialogLabel}
99
121
  className={className}
100
122
  isAlertDialog={isAlertDialog}
101
123
  onConfirm={onConfirm}
102
124
  confirmLabel={confirmLabel}
103
125
  cancelLabel={cancelLabel}
126
+ hideFooter={hideFooter}
104
127
  >
105
128
  {children}
106
129
  </Dialog>
@@ -13,6 +13,23 @@
13
13
  --dialog-button-hover-bg: whitesmoke;
14
14
  --dialog-display: flex;
15
15
  --dialog-flex-direction: column;
16
+
17
+ /* Focus and accessibility */
18
+ --dialog-focus-color: #0066cc;
19
+ --dialog-focus-width: 0.125rem;
20
+ --dialog-focus-offset: 0.125rem;
21
+ --dialog-focus-outline: var(--dialog-focus-width) solid var(--dialog-focus-color);
22
+ }
23
+
24
+ /* High contrast mode support */
25
+ @media (prefers-contrast: high) {
26
+ :root {
27
+ --dialog-border-color: currentColor;
28
+ --dialog-border-width: 0.125rem;
29
+ --dialog-close-color: currentColor;
30
+ --dialog-button-border: currentColor 0.125rem solid;
31
+ --dialog-focus-width: 0.1875rem;
32
+ }
16
33
  }
17
34
 
18
35
  dialog {
@@ -22,13 +39,20 @@ dialog {
22
39
  border: var(--dialog-border-color) var(--dialog-border-width) solid;
23
40
  border-radius: var(--dialog-border-radius);
24
41
  padding: var(--dialog-padding);
25
- padding-block-start: calc(var(--dialog-padding) - 0rem);
42
+ padding-block-start: var(--dialog-padding);
43
+
44
+ /* Focus visible for keyboard navigation */
45
+ &:focus-visible {
46
+ outline: var(--dialog-focus-outline);
47
+ outline-offset: var(--dialog-focus-offset);
48
+ }
26
49
 
27
50
  &[open] {
28
51
  display: var(--dialog-display);
29
52
  flex-direction: var(--dialog-flex-direction);
30
53
  gap: var(--dialog-gap);
31
54
  }
55
+
32
56
  section {
33
57
  width: 100%;
34
58
  display: flex;
@@ -46,22 +70,38 @@ dialog {
46
70
  align-items: center;
47
71
  width: 100%;
48
72
  min-width: 100%;
73
+
49
74
  h3 {
50
75
  margin-block-start: 0;
51
76
  margin-block-end: 0;
52
77
  }
78
+
53
79
  .dialog-close {
54
80
  margin-block-end: 0;
55
81
  }
82
+
56
83
  button[type="button"] {
57
84
  background-color: var(--dialog-button-bg);
58
85
  border: var(--dialog-button-border);
59
86
  cursor: pointer;
60
- &:hover,
61
- &:focus {
87
+
88
+ &:hover {
62
89
  border-color: var(--dialog-close-color);
63
90
  background-color: var(--dialog-button-hover-bg);
64
91
  }
92
+
93
+ /* Keyboard focus indicator */
94
+ &:focus-visible {
95
+ outline: var(--dialog-focus-outline);
96
+ outline-offset: var(--dialog-focus-offset);
97
+ border-color: var(--dialog-focus-color);
98
+ background-color: var(--dialog-button-hover-bg);
99
+ }
100
+
101
+ /* Remove default focus for mouse users */
102
+ &:focus:not(:focus-visible) {
103
+ outline: none;
104
+ }
65
105
  }
66
106
  }
67
107
 
@@ -73,4 +113,14 @@ dialog {
73
113
  justify-content: var(--dialog-footer-justify, flex-end);
74
114
  gap: var(--dialog-gap);
75
115
  width: 100%;
116
+
117
+ /* Focus styles for footer buttons */
118
+ button:focus-visible {
119
+ outline: var(--dialog-focus-outline);
120
+ outline-offset: var(--dialog-focus-offset);
121
+ }
122
+
123
+ button:focus:not(:focus-visible) {
124
+ outline: none;
125
+ }
76
126
  }
@@ -15,8 +15,8 @@ const buttonDecorator = [
15
15
  <button onClick={() => setIsOpen(true)}>Open Dialog</button>
16
16
  <Story
17
17
  args={{
18
- showDialog: isOpen,
19
- onClose: () => setIsOpen(false),
18
+ isOpen: isOpen,
19
+ onOpenChange: setIsOpen,
20
20
  dialogTitle: "Dialog Button",
21
21
  children: content,
22
22
  }}
@@ -67,18 +67,20 @@ type Story = StoryObj<typeof Dialog>;
67
67
  export const BasicDialog: Story = {
68
68
  args: {
69
69
  isAlertDialog: false,
70
- showDialog: true,
70
+ isOpen: true,
71
+ onOpenChange: () => {},
71
72
  dialogTitle: "Basic Dialog",
72
73
  },
73
74
  } as Story;
74
75
 
75
76
  /**
76
- * Show the dialog by default
77
- * set the showDialog prop to true
77
+ * Non-modal inline alert dialog
78
+ * Uses dialog.show() instead of dialog.showModal()
78
79
  */
79
80
  export const NonModalDialog: Story = {
80
81
  args: {
81
- showDialog: true,
82
+ isOpen: true,
83
+ onOpenChange: () => {},
82
84
  isAlertDialog: true,
83
85
  dialogTitle: "Non Modal Dialog",
84
86
  },
@@ -95,7 +97,8 @@ export const DialogWithButton: Story = {
95
97
  export const DialogInteractions: Story = {
96
98
  args: {
97
99
  isAlertDialog: false,
98
- showDialog: true,
100
+ isOpen: true,
101
+ onOpenChange: () => {},
99
102
  dialogTitle: "Dialog Interactions",
100
103
  },
101
104
  play: async ({ canvasElement, step }) => {