@fpkit/acss 0.5.12 → 0.6.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 (398) hide show
  1. package/README.md +89 -0
  2. package/libs/chunk-2NRIP6RB.cjs +17 -0
  3. package/libs/chunk-2NRIP6RB.cjs.map +1 -0
  4. package/libs/chunk-33PNJ4LO.cjs +15 -0
  5. package/libs/chunk-33PNJ4LO.cjs.map +1 -0
  6. package/libs/chunk-4BZKFPEC.cjs +17 -0
  7. package/libs/chunk-4BZKFPEC.cjs.map +1 -0
  8. package/libs/{chunk-O6QZBB6G.js → chunk-5QD3DWFI.js} +5 -5
  9. package/libs/chunk-5QD3DWFI.js.map +1 -0
  10. package/libs/chunk-6SAHIYCZ.js +7 -0
  11. package/libs/chunk-6SAHIYCZ.js.map +1 -0
  12. package/libs/{chunk-KKLTUJFB.cjs → chunk-6WTC4JXH.cjs} +5 -5
  13. package/libs/chunk-6WTC4JXH.cjs.map +1 -0
  14. package/libs/chunk-75QHTLFO.js +7 -0
  15. package/libs/chunk-75QHTLFO.js.map +1 -0
  16. package/libs/{chunk-YWOYVRFT.js → chunk-7XPFW7CB.js} +3 -3
  17. package/libs/chunk-BFK62VX5.js +5 -0
  18. package/libs/chunk-BFK62VX5.js.map +1 -0
  19. package/libs/{chunk-ICCKQ2GC.cjs → chunk-DKTHCQ5P.cjs} +4 -4
  20. package/libs/{chunk-6TE5QEVE.cjs → chunk-E2AJURUW.cjs} +3 -3
  21. package/libs/chunk-E2AJURUW.cjs.map +1 -0
  22. package/libs/chunk-ENTCUJ3A.cjs +13 -0
  23. package/libs/chunk-ENTCUJ3A.cjs.map +1 -0
  24. package/libs/chunk-F5EYMVQM.js +10 -0
  25. package/libs/chunk-F5EYMVQM.js.map +1 -0
  26. package/libs/chunk-FVROL3V5.js +9 -0
  27. package/libs/chunk-FVROL3V5.js.map +1 -0
  28. package/libs/chunk-GT77BX4L.cjs +17 -0
  29. package/libs/chunk-GT77BX4L.cjs.map +1 -0
  30. package/libs/chunk-GUJSMQ3V.cjs +16 -0
  31. package/libs/chunk-GUJSMQ3V.cjs.map +1 -0
  32. package/libs/chunk-HHLNOC5T.js +7 -0
  33. package/libs/chunk-HHLNOC5T.js.map +1 -0
  34. package/libs/chunk-HRRHPLER.js +8 -0
  35. package/libs/chunk-HRRHPLER.js.map +1 -0
  36. package/libs/chunk-IEB64SWY.js +8 -0
  37. package/libs/chunk-IEB64SWY.js.map +1 -0
  38. package/libs/{chunk-LIQJ7ZZR.js → chunk-IQ76HGVP.js} +2 -2
  39. package/libs/chunk-IRLFZ3OL.js +9 -0
  40. package/libs/chunk-IRLFZ3OL.js.map +1 -0
  41. package/libs/chunk-KK47SYZI.js +8 -0
  42. package/libs/chunk-KK47SYZI.js.map +1 -0
  43. package/libs/chunk-O3JIHC5M.cjs +15 -0
  44. package/libs/chunk-O3JIHC5M.cjs.map +1 -0
  45. package/libs/chunk-O5XAJ7BY.cjs +18 -0
  46. package/libs/chunk-O5XAJ7BY.cjs.map +1 -0
  47. package/libs/chunk-OVWLQYMK.js +10 -0
  48. package/libs/chunk-OVWLQYMK.js.map +1 -0
  49. package/libs/chunk-PNWIRCG3.cjs +7 -0
  50. package/libs/chunk-PNWIRCG3.cjs.map +1 -0
  51. package/libs/chunk-QVW6W76L.cjs +18 -0
  52. package/libs/chunk-QVW6W76L.cjs.map +1 -0
  53. package/libs/chunk-T4T6GWYQ.cjs +17 -0
  54. package/libs/chunk-T4T6GWYQ.cjs.map +1 -0
  55. package/libs/chunk-TON2YGMD.cjs +9 -0
  56. package/libs/chunk-TON2YGMD.cjs.map +1 -0
  57. package/libs/chunk-UEPAWMDF.js +8 -0
  58. package/libs/chunk-UEPAWMDF.js.map +1 -0
  59. package/libs/{chunk-LT5KZ2QW.cjs → chunk-US2I5GI7.cjs} +3 -3
  60. package/libs/{chunk-E3XP6BEX.cjs → chunk-W2UIN7EV.cjs} +3 -3
  61. package/libs/chunk-W5TKWBFC.cjs +18 -0
  62. package/libs/chunk-W5TKWBFC.cjs.map +1 -0
  63. package/libs/chunk-WXBFBWYF.cjs +16 -0
  64. package/libs/chunk-WXBFBWYF.cjs.map +1 -0
  65. package/libs/chunk-X3JCTEPD.js +11 -0
  66. package/libs/chunk-X3JCTEPD.js.map +1 -0
  67. package/libs/chunk-X5LGFCWG.js +9 -0
  68. package/libs/chunk-X5LGFCWG.js.map +1 -0
  69. package/libs/{chunk-5M57K4SW.js → chunk-Y2PFDELK.js} +2 -2
  70. package/libs/chunk-ZFJ4U45S.js +10 -0
  71. package/libs/chunk-ZFJ4U45S.js.map +1 -0
  72. package/libs/{component-props-a8a2f97e.d.ts → component-props-67d978a2.d.ts} +4 -4
  73. package/libs/components/alert/alert.css +1 -1
  74. package/libs/components/alert/alert.css.map +1 -1
  75. package/libs/components/alert/alert.min.css +2 -2
  76. package/libs/components/badge/badge.css +1 -1
  77. package/libs/components/badge/badge.css.map +1 -1
  78. package/libs/components/badge/badge.min.css +2 -2
  79. package/libs/components/breadcrumbs/breadcrumb.cjs +9 -5
  80. package/libs/components/breadcrumbs/breadcrumb.d.cts +275 -36
  81. package/libs/components/breadcrumbs/breadcrumb.d.ts +275 -36
  82. package/libs/components/breadcrumbs/breadcrumb.js +3 -3
  83. package/libs/components/button.cjs +6 -4
  84. package/libs/components/button.d.cts +97 -4
  85. package/libs/components/button.d.ts +97 -4
  86. package/libs/components/button.js +4 -2
  87. package/libs/components/buttons/button.css +1 -1
  88. package/libs/components/buttons/button.css.map +1 -1
  89. package/libs/components/buttons/button.min.css +2 -2
  90. package/libs/components/card.cjs +7 -7
  91. package/libs/components/card.d.cts +278 -34
  92. package/libs/components/card.d.ts +278 -34
  93. package/libs/components/card.js +2 -2
  94. package/libs/components/cards/card.css +1 -1
  95. package/libs/components/cards/card.css.map +1 -1
  96. package/libs/components/cards/card.min.css +2 -2
  97. package/libs/components/details/details.css +1 -1
  98. package/libs/components/details/details.css.map +1 -1
  99. package/libs/components/details/details.min.css +2 -2
  100. package/libs/components/dialog/dialog.cjs +9 -7
  101. package/libs/components/dialog/dialog.css +1 -1
  102. package/libs/components/dialog/dialog.css.map +1 -1
  103. package/libs/components/dialog/dialog.d.cts +88 -34
  104. package/libs/components/dialog/dialog.d.ts +88 -34
  105. package/libs/components/dialog/dialog.js +7 -5
  106. package/libs/components/dialog/dialog.min.css +2 -2
  107. package/libs/components/form/fields.cjs +4 -4
  108. package/libs/components/form/fields.d.cts +16 -7
  109. package/libs/components/form/fields.d.ts +16 -7
  110. package/libs/components/form/fields.js +2 -2
  111. package/libs/components/form/inputs.cjs +6 -4
  112. package/libs/components/form/inputs.d.cts +50 -2
  113. package/libs/components/form/inputs.d.ts +50 -2
  114. package/libs/components/form/inputs.js +4 -2
  115. package/libs/components/form/textarea.cjs +5 -4
  116. package/libs/components/form/textarea.d.cts +32 -23
  117. package/libs/components/form/textarea.d.ts +32 -23
  118. package/libs/components/form/textarea.js +3 -2
  119. package/libs/components/heading/heading.cjs +3 -3
  120. package/libs/components/heading/heading.d.cts +3 -14
  121. package/libs/components/heading/heading.d.ts +3 -14
  122. package/libs/components/heading/heading.js +2 -2
  123. package/libs/components/icons/icon.cjs +4 -4
  124. package/libs/components/icons/icon.d.cts +183 -39
  125. package/libs/components/icons/icon.d.ts +183 -39
  126. package/libs/components/icons/icon.js +2 -2
  127. package/libs/components/images/img.css +1 -1
  128. package/libs/components/images/img.css.map +1 -1
  129. package/libs/components/images/img.min.css +2 -2
  130. package/libs/components/link/link.cjs +4 -4
  131. package/libs/components/link/link.css +1 -1
  132. package/libs/components/link/link.css.map +1 -1
  133. package/libs/components/link/link.d.cts +3 -19
  134. package/libs/components/link/link.d.ts +3 -19
  135. package/libs/components/link/link.js +2 -2
  136. package/libs/components/link/link.min.css +2 -2
  137. package/libs/components/list/list.cjs +5 -5
  138. package/libs/components/list/list.css +1 -0
  139. package/libs/components/list/list.css.map +1 -0
  140. package/libs/components/list/list.d.cts +120 -33
  141. package/libs/components/list/list.d.ts +120 -33
  142. package/libs/components/list/list.js +2 -2
  143. package/libs/components/list/list.min.css +3 -0
  144. package/libs/components/modal.cjs +6 -4
  145. package/libs/components/modal.d.cts +8 -8
  146. package/libs/components/modal.d.ts +8 -8
  147. package/libs/components/modal.js +5 -3
  148. package/libs/components/nav/nav.cjs +7 -7
  149. package/libs/components/nav/nav.css +1 -1
  150. package/libs/components/nav/nav.css.map +1 -1
  151. package/libs/components/nav/nav.d.cts +550 -34
  152. package/libs/components/nav/nav.d.ts +550 -34
  153. package/libs/components/nav/nav.js +3 -3
  154. package/libs/components/nav/nav.min.css +2 -2
  155. package/libs/components/popover/popover.d.cts +5 -5
  156. package/libs/components/popover/popover.d.ts +5 -5
  157. package/libs/components/tables/table.cjs +5 -5
  158. package/libs/components/tables/table.d.cts +8 -8
  159. package/libs/components/tables/table.d.ts +8 -8
  160. package/libs/components/tables/table.js +2 -2
  161. package/libs/components/tag/tag.css +1 -1
  162. package/libs/components/tag/tag.css.map +1 -1
  163. package/libs/components/tag/tag.min.css +2 -2
  164. package/libs/components/text/text.cjs +5 -5
  165. package/libs/components/text/text.d.cts +5 -5
  166. package/libs/components/text/text.d.ts +5 -5
  167. package/libs/components/text/text.js +2 -2
  168. package/libs/form.types-d25ebfac.d.ts +233 -0
  169. package/libs/heading-7446cb46.d.ts +250 -0
  170. package/libs/hooks.cjs +12 -0
  171. package/libs/hooks.d.cts +140 -1
  172. package/libs/hooks.d.ts +140 -1
  173. package/libs/hooks.js +4 -0
  174. package/libs/icons.cjs +3 -3
  175. package/libs/icons.d.cts +2 -2
  176. package/libs/icons.d.ts +2 -2
  177. package/libs/icons.js +2 -2
  178. package/libs/index.cjs +117 -94
  179. package/libs/index.cjs.map +1 -1
  180. package/libs/index.css +1 -1
  181. package/libs/index.css.map +1 -1
  182. package/libs/index.d.cts +834 -61
  183. package/libs/index.d.ts +834 -61
  184. package/libs/index.js +36 -22
  185. package/libs/index.js.map +1 -1
  186. package/libs/link-5192f411.d.ts +323 -0
  187. package/libs/list.types-d26de310.d.ts +245 -0
  188. package/libs/ui-d01b50d4.d.ts +289 -0
  189. package/package.json +4 -87
  190. package/src/components/README-UI.mdx +416 -0
  191. package/src/components/alert/ACCESSIBILITY.md +319 -0
  192. package/src/components/alert/README.mdx +475 -19
  193. package/src/components/alert/alert.scss +110 -6
  194. package/src/components/alert/alert.stories.tsx +372 -0
  195. package/src/components/alert/alert.test.tsx +762 -0
  196. package/src/components/alert/alert.tsx +331 -66
  197. package/src/components/alert/views/alert-actions.tsx +13 -0
  198. package/src/components/alert/views/alert-content.tsx +17 -0
  199. package/src/components/alert/views/alert-icon.tsx +53 -0
  200. package/src/components/alert/views/alert-screen-reader-text.tsx +30 -0
  201. package/src/components/alert/views/alert-title.tsx +23 -0
  202. package/src/components/alert/views/alert-view.tsx +158 -0
  203. package/src/components/alert/views/index.ts +12 -0
  204. package/src/components/badge/badge.mdx +186 -49
  205. package/src/components/badge/badge.scss +20 -2
  206. package/src/components/badge/badge.stories.tsx +160 -14
  207. package/src/components/badge/badge.test.tsx +179 -0
  208. package/src/components/badge/badge.tsx +97 -4
  209. package/src/components/breadcrumbs/README.mdx +364 -45
  210. package/src/components/breadcrumbs/__snapshots__/breadcrumb.test.tsx.snap +152 -0
  211. package/src/components/breadcrumbs/breadcrumb.stories.tsx +7 -3
  212. package/src/components/breadcrumbs/breadcrumb.test.tsx +490 -0
  213. package/src/components/breadcrumbs/breadcrumb.tsx +430 -170
  214. package/src/components/buttons/README.mdx +102 -1
  215. package/src/components/buttons/button.scss +34 -31
  216. package/src/components/buttons/button.stories.tsx +141 -0
  217. package/src/components/buttons/button.tsx +82 -52
  218. package/src/components/cards/README.mdx +657 -0
  219. package/src/components/cards/card.scss +22 -0
  220. package/src/components/cards/card.stories.tsx +167 -5
  221. package/src/components/cards/card.test.tsx +360 -20
  222. package/src/components/cards/card.tsx +200 -79
  223. package/src/components/cards/card.types.ts +135 -0
  224. package/src/components/cards/card.utils.ts +79 -0
  225. package/src/components/details/ACCESSIBILITY-REVIEW-LIVE.md +1050 -0
  226. package/src/components/details/ACCESSIBILITY-REVIEW.md +502 -0
  227. package/src/components/details/README.mdx +437 -69
  228. package/src/components/details/details.scss +16 -7
  229. package/src/components/details/details.test.tsx +385 -0
  230. package/src/components/details/details.tsx +101 -69
  231. package/src/components/details/details.types.ts +76 -0
  232. package/src/components/dialog/README.mdx +513 -110
  233. package/src/components/dialog/dialog-a11y-review.md +653 -0
  234. package/src/components/dialog/dialog-modal.tsx +79 -56
  235. package/src/components/dialog/dialog.scss +53 -3
  236. package/src/components/dialog/dialog.stories.tsx +10 -7
  237. package/src/components/dialog/dialog.test.tsx +450 -0
  238. package/src/components/dialog/dialog.tsx +69 -59
  239. package/src/components/dialog/dialog.types.ts +133 -0
  240. package/src/components/dialog/views/dialog-footer.tsx +54 -11
  241. package/src/components/dialog/views/dialog-header.tsx +20 -15
  242. package/src/components/form/README.mdx +725 -43
  243. package/src/components/form/WCAG-REVIEW.md +654 -0
  244. package/src/components/form/fields.tsx +10 -1
  245. package/src/components/form/form.stories.tsx +604 -23
  246. package/src/components/form/form.tsx +204 -63
  247. package/src/components/form/form.types.ts +378 -0
  248. package/src/components/form/input.stories.tsx +71 -3
  249. package/src/components/form/inputs.tsx +159 -67
  250. package/src/components/form/select.tsx +122 -66
  251. package/src/components/form/textarea.tsx +120 -73
  252. package/src/components/fp.tsx +86 -11
  253. package/src/components/heading/heading.stories.tsx +44 -4
  254. package/src/components/heading/heading.tsx +89 -23
  255. package/src/components/icons/README.mdx +332 -0
  256. package/src/components/icons/icon.stories.tsx +74 -1
  257. package/src/components/icons/icon.tsx +89 -1
  258. package/src/components/icons/types.ts +47 -0
  259. package/src/components/images/README.mdx +340 -24
  260. package/src/components/images/img.scss +19 -3
  261. package/src/components/images/img.stories.tsx +424 -15
  262. package/src/components/images/img.test.tsx +354 -25
  263. package/src/components/images/img.tsx +186 -63
  264. package/src/components/images/img.types.ts +211 -0
  265. package/src/components/link/README.mdx +923 -0
  266. package/src/components/link/link.scss +79 -26
  267. package/src/components/link/link.stories.tsx +383 -30
  268. package/src/components/link/link.test.tsx +677 -0
  269. package/src/components/link/link.tsx +163 -57
  270. package/src/components/link/link.types.ts +261 -0
  271. package/src/components/list/README.mdx +764 -0
  272. package/src/components/list/list.scss +285 -0
  273. package/src/components/list/list.stories.tsx +514 -27
  274. package/src/components/list/list.test.tsx +554 -0
  275. package/src/components/list/list.tsx +153 -51
  276. package/src/components/list/list.types.ts +255 -0
  277. package/src/components/nav/ACCESSIBILITY.md +649 -0
  278. package/src/components/nav/README.mdx +782 -0
  279. package/src/components/nav/nav.scss +32 -1
  280. package/src/components/nav/nav.stories.tsx +44 -6
  281. package/src/components/nav/nav.tsx +302 -51
  282. package/src/components/nav/nav.types.ts +308 -0
  283. package/src/components/tag/README.mdx +426 -0
  284. package/src/components/tag/tag.scss +101 -27
  285. package/src/components/tag/tag.stories.tsx +384 -10
  286. package/src/components/tag/tag.test.tsx +210 -0
  287. package/src/components/tag/tag.tsx +106 -9
  288. package/src/components/tag/tag.types.ts +107 -0
  289. package/src/components/title/MIGRATION.md +199 -0
  290. package/src/components/title/README.md +326 -0
  291. package/src/components/title/README.mdx +452 -0
  292. package/src/components/title/title.stories.tsx +393 -0
  293. package/src/components/title/title.test.tsx +251 -0
  294. package/src/components/title/title.tsx +219 -0
  295. package/src/components/ui.stories.tsx +894 -0
  296. package/src/components/ui.test.tsx +559 -0
  297. package/src/components/ui.tsx +274 -18
  298. package/src/components/word-count/README.md +240 -0
  299. package/src/hooks/use-disabled-state.test.tsx +536 -0
  300. package/src/hooks/use-disabled-state.ts +246 -0
  301. package/src/hooks/useDisabledState.md +393 -0
  302. package/src/hooks.ts +7 -0
  303. package/src/index.scss +2 -0
  304. package/src/index.ts +12 -3
  305. package/src/sass/_globals.scss +2 -7
  306. package/src/sass/_properties.scss +1 -0
  307. package/src/styles/alert/alert.css +92 -4
  308. package/src/styles/alert/alert.css.map +1 -1
  309. package/src/styles/badge/badge.css +20 -2
  310. package/src/styles/badge/badge.css.map +1 -1
  311. package/src/styles/buttons/button.css +31 -31
  312. package/src/styles/buttons/button.css.map +1 -1
  313. package/src/styles/cards/card.css +16 -0
  314. package/src/styles/cards/card.css.map +1 -1
  315. package/src/styles/details/details.css +19 -8
  316. package/src/styles/details/details.css.map +1 -1
  317. package/src/styles/dialog/dialog.css +43 -2
  318. package/src/styles/dialog/dialog.css.map +1 -1
  319. package/src/styles/images/img.css +15 -3
  320. package/src/styles/images/img.css.map +1 -1
  321. package/src/styles/index.css +691 -128
  322. package/src/styles/index.css.map +1 -1
  323. package/src/styles/link/link.css +45 -28
  324. package/src/styles/link/link.css.map +1 -1
  325. package/src/styles/list/list.css +214 -0
  326. package/src/styles/list/list.css.map +1 -0
  327. package/src/styles/nav/nav.css +21 -1
  328. package/src/styles/nav/nav.css.map +1 -1
  329. package/src/styles/tag/tag.css +113 -35
  330. package/src/styles/tag/tag.css.map +1 -1
  331. package/src/styles/utilities/_disabled.scss +58 -0
  332. package/src/test/setup.d.ts +9 -0
  333. package/src/test/setup.ts +53 -1
  334. package/src/types/shared.ts +43 -6
  335. package/src/utils/accessibility.ts +109 -0
  336. package/libs/chunk-5ZM4XL44.js +0 -8
  337. package/libs/chunk-5ZM4XL44.js.map +0 -1
  338. package/libs/chunk-6BVXFW7U.cjs +0 -15
  339. package/libs/chunk-6BVXFW7U.cjs.map +0 -1
  340. package/libs/chunk-6TE5QEVE.cjs.map +0 -1
  341. package/libs/chunk-7K76RW2A.cjs +0 -18
  342. package/libs/chunk-7K76RW2A.cjs.map +0 -1
  343. package/libs/chunk-BHRQBJRY.js +0 -8
  344. package/libs/chunk-BHRQBJRY.js.map +0 -1
  345. package/libs/chunk-BIP2NY53.js +0 -8
  346. package/libs/chunk-BIP2NY53.js.map +0 -1
  347. package/libs/chunk-BSPKFLO4.js +0 -8
  348. package/libs/chunk-BSPKFLO4.js.map +0 -1
  349. package/libs/chunk-BV5CLH44.cjs +0 -18
  350. package/libs/chunk-BV5CLH44.cjs.map +0 -1
  351. package/libs/chunk-DKGJHKGW.js +0 -9
  352. package/libs/chunk-DKGJHKGW.js.map +0 -1
  353. package/libs/chunk-DV56L5YX.cjs +0 -18
  354. package/libs/chunk-DV56L5YX.cjs.map +0 -1
  355. package/libs/chunk-ECLD37WN.cjs +0 -16
  356. package/libs/chunk-ECLD37WN.cjs.map +0 -1
  357. package/libs/chunk-EQ67LF46.js +0 -9
  358. package/libs/chunk-EQ67LF46.js.map +0 -1
  359. package/libs/chunk-HYBZBN4G.js +0 -8
  360. package/libs/chunk-HYBZBN4G.js.map +0 -1
  361. package/libs/chunk-IYUN2EW3.cjs +0 -15
  362. package/libs/chunk-IYUN2EW3.cjs.map +0 -1
  363. package/libs/chunk-KKLTUJFB.cjs.map +0 -1
  364. package/libs/chunk-LHVJKDMA.cjs +0 -15
  365. package/libs/chunk-LHVJKDMA.cjs.map +0 -1
  366. package/libs/chunk-LL7HTLMS.cjs +0 -15
  367. package/libs/chunk-LL7HTLMS.cjs.map +0 -1
  368. package/libs/chunk-M5QL5TAE.cjs +0 -14
  369. package/libs/chunk-M5QL5TAE.cjs.map +0 -1
  370. package/libs/chunk-NE6YXTMC.js +0 -7
  371. package/libs/chunk-NE6YXTMC.js.map +0 -1
  372. package/libs/chunk-NHYXGV3L.js +0 -8
  373. package/libs/chunk-NHYXGV3L.js.map +0 -1
  374. package/libs/chunk-O6QZBB6G.js.map +0 -1
  375. package/libs/chunk-P7TTEYCD.js +0 -7
  376. package/libs/chunk-P7TTEYCD.js.map +0 -1
  377. package/libs/chunk-PPOOBUOS.js +0 -8
  378. package/libs/chunk-PPOOBUOS.js.map +0 -1
  379. package/libs/chunk-QCMV4VQZ.js +0 -8
  380. package/libs/chunk-QCMV4VQZ.js.map +0 -1
  381. package/libs/chunk-QVV34QEH.cjs +0 -32
  382. package/libs/chunk-QVV34QEH.cjs.map +0 -1
  383. package/libs/chunk-S7BABR7Z.cjs +0 -13
  384. package/libs/chunk-S7BABR7Z.cjs.map +0 -1
  385. package/libs/chunk-SXVZSWX6.js +0 -11
  386. package/libs/chunk-SXVZSWX6.js.map +0 -1
  387. package/libs/chunk-X3EVB7VS.cjs +0 -15
  388. package/libs/chunk-X3EVB7VS.cjs.map +0 -1
  389. package/libs/inputs-f3a216db.d.ts +0 -45
  390. package/libs/ui-9a6f9f8d.d.ts +0 -24
  391. package/src/components/cards/README.md +0 -80
  392. package/src/components/dialog/hooks/useClickOutside.ts +0 -33
  393. /package/libs/{chunk-YWOYVRFT.js.map → chunk-7XPFW7CB.js.map} +0 -0
  394. /package/libs/{chunk-ICCKQ2GC.cjs.map → chunk-DKTHCQ5P.cjs.map} +0 -0
  395. /package/libs/{chunk-LIQJ7ZZR.js.map → chunk-IQ76HGVP.js.map} +0 -0
  396. /package/libs/{chunk-LT5KZ2QW.cjs.map → chunk-US2I5GI7.cjs.map} +0 -0
  397. /package/libs/{chunk-E3XP6BEX.cjs.map → chunk-W2UIN7EV.cjs.map} +0 -0
  398. /package/libs/{chunk-5M57K4SW.js.map → chunk-Y2PFDELK.js.map} +0 -0
@@ -1,92 +1,145 @@
1
1
  @use '../../sass/mixins';
2
2
 
3
+ /**
4
+ * Link Component Styles
5
+ *
6
+ * Provides accessible, customizable link styles using CSS custom properties.
7
+ * Supports standard text links, button-styled links, and pill variants.
8
+ *
9
+ * WCAG 2.1 AA Compliance:
10
+ * - Focus indicators meet 2.4.7 (3:1 contrast minimum)
11
+ * - Color contrast meets 1.4.3 (4.5:1 for normal text)
12
+ * - Uses :focus-visible for better UX (keyboard vs mouse)
13
+ */
14
+
3
15
  a[href] {
4
- --link-decoration: none;
16
+ // Color & Typography
5
17
  --link-color: #085ab7;
18
+ --link-weight: 400;
19
+ --link-fs: 1rem;
20
+
21
+ // Text Decoration
22
+ --link-decoration: none;
23
+ --link-decoration-offset: 0.09375rem; // 1.5px converted to rem
24
+ --link-decoration-thickness: 0.0625rem; // 1px converted to rem
25
+ --link-skip-ink: auto;
26
+
27
+ // Background & Border
6
28
  --link-bg: transparent;
29
+ --link-radius: 0.25rem;
30
+
31
+ // Spacing (for button variants)
7
32
  --link-px: 0;
8
33
  --link-py: 0;
34
+
35
+ // Transitions
9
36
  --link-transition: all 0.75s ease-in-out;
10
- --link-fs: 1rem;
11
- --link-radius: 0.25rem;
12
- --link-skip-ink: auto;
13
- --link-decoration-offset: 1.5px;
14
- --link-decoration-thickness: 3px;
15
- --link-decoration: color: var(--link-color) var(--link-decoration-offset)
16
- var(--link-decoration-thickness) var(--link-skip-ink);
17
- --link-decoration-thickness: 3px;
18
- --link-decoration: color: var(--link-color) var(--link-decoration-offset)
19
- var(--link-decoration-thickness) var(--link-skip-ink);
20
37
 
38
+ // Focus Indicator (WCAG 2.4.7 - 3:1 contrast minimum)
39
+ --link-focus-color: currentColor;
40
+ --link-focus-width: 0.125rem; // 2px
41
+ --link-focus-offset: 0.125rem; // 2px
42
+ --link-focus-style: solid;
43
+
44
+ // Apply base styles
21
45
  color: var(--link-color);
22
46
  font-size: var(--link-fs);
47
+ font-weight: var(--link-weight);
23
48
  text-decoration: var(--link-decoration);
24
49
  text-underline-offset: var(--link-decoration-offset);
50
+ text-decoration-thickness: var(--link-decoration-thickness);
25
51
  text-decoration-skip-ink: var(--link-skip-ink);
26
52
  background-color: var(--link-bg);
27
53
  border-radius: var(--link-radius);
28
- background-color: var(--link-bg);
29
- border-radius: var(--link-radius);
30
- font-weight: var(--link-weight);
54
+ transition: var(--link-transition);
31
55
 
56
+ // Ensure child elements inherit weight/style
32
57
  > i,
33
58
  > b {
34
59
  font-weight: var(--link-weight);
35
60
  font-style: normal;
36
61
  }
37
62
 
63
+ // Hover state - add underline for clarity
38
64
  &:hover {
39
65
  --link-decoration: underline;
40
66
  }
41
67
 
68
+ // Focus state - WCAG 2.4.7 compliant focus indicator
42
69
  &:focus {
43
- outline: none;
70
+ outline: var(--link-focus-width) var(--link-focus-style)
71
+ var(--link-focus-color);
72
+ outline-offset: var(--link-focus-offset);
44
73
  --link-decoration: underline;
45
74
  }
46
75
 
76
+ // Focus-visible for better UX (only show outline on keyboard focus)
77
+ &:focus-visible {
78
+ outline: var(--link-focus-width) var(--link-focus-style)
79
+ var(--link-focus-color);
80
+ outline-offset: var(--link-focus-offset);
81
+ }
82
+
83
+ // Visited and active states
47
84
  &:visited,
48
85
  &:active {
49
86
  --link-color: currentColor;
50
87
  }
51
88
 
89
+ // Button-styled links (via <b> wrapper, data-btn attribute, or <i> for pill)
52
90
  &:has(> b),
53
- &[data-link~='btn'],
91
+ &[data-btn],
54
92
  &:has(> i) {
55
93
  --link-button-color: var(--link-color);
56
94
  --link-bg: transparent;
57
95
  --link-decoration: none;
58
- --link-border: 2px currentColor solid;
96
+ --link-border-width: 0.125rem; // 2px
97
+ --link-border-color: currentColor;
98
+ --link-border-style: solid;
59
99
  --link-fs: 0.9rem;
100
+
101
+ color: var(--link-button-color);
60
102
  background-color: var(--link-bg);
61
103
  font-style: normal;
62
104
  font-size: var(--link-fs);
63
- color: var(--link-button-color);
64
105
  padding-inline: var(--link-fs);
65
106
  padding-block: calc(var(--link-fs) - 0.4rem);
66
107
  border-radius: var(--link-radius, 99rem);
67
108
  display: inline-flex;
68
- outline: var(--link-border);
69
- &:focus {
70
- outline: var(--link-border);
109
+ align-items: center;
110
+ justify-content: center;
111
+ outline: var(--link-border-width) var(--link-border-color)
112
+ var(--link-border-style);
113
+
114
+ // Focus state for button links
115
+ &:focus,
116
+ &:focus-visible {
117
+ outline: var(--link-border-width) var(--link-border-color)
118
+ var(--link-border-style);
119
+ outline-offset: var(--link-focus-offset);
71
120
  --link-decoration: none;
72
121
  }
122
+
123
+ // Hover state for button links
73
124
  &:hover {
74
125
  --link-decoration: none;
75
126
  }
127
+
128
+ // Apply scale transition from mixins
76
129
  @include mixins.scale-transitions;
77
130
  }
131
+
132
+ // Pill variant (rounded corners)
78
133
  &[data-link~='pill'],
79
134
  &:has(> i) {
80
135
  --link-radius: 99rem;
81
136
  --link-decoration: none;
82
137
  font-style: normal;
138
+
83
139
  &:hover,
84
- &:focus {
140
+ &:focus,
141
+ &:focus-visible {
85
142
  --link-decoration: none;
86
143
  }
87
144
  }
88
145
  }
89
-
90
- header > section {
91
- width: auto;
92
- }
@@ -1,71 +1,424 @@
1
1
  import { StoryObj, Meta } from "@storybook/react-vite";
2
-
3
- import { within, expect } from "storybook/test";
4
-
2
+ import { within, expect, userEvent, fn } from "storybook/test";
3
+ import { useRef, useEffect } from "react";
5
4
  import Link from "./link";
5
+ import type { LinkProps } from "./link.types";
6
6
  import "../../styles/link/link.css";
7
7
 
8
- const meta: Meta<typeof Link> = {
8
+ const meta = {
9
9
  title: "FP.React Components/Links",
10
- tags: ["version:1.0.0"],
10
+ tags: ["version:1.0.0", "autodocs"],
11
11
  component: Link,
12
12
  args: {
13
13
  href: "/",
14
14
  children: "Link",
15
15
  },
16
- } as Meta;
16
+ argTypes: {
17
+ href: {
18
+ control: "text",
19
+ description: "The URL the link points to",
20
+ },
21
+ target: {
22
+ control: "select",
23
+ options: ["_self", "_blank", "_parent", "_top"],
24
+ description: "Where to open the linked URL",
25
+ },
26
+ rel: {
27
+ control: "text",
28
+ description: "Relationship between current and linked document",
29
+ },
30
+ prefetch: {
31
+ control: "boolean",
32
+ description: "Hint to browser to prefetch the resource",
33
+ },
34
+ btnStyle: {
35
+ control: "text",
36
+ description: "Apply button styling to the link",
37
+ },
38
+ },
39
+ parameters: {
40
+ docs: {
41
+ description: {
42
+ component:
43
+ "A semantic, accessible anchor component with enhanced security for external links and flexible styling variants.",
44
+ },
45
+ },
46
+ },
47
+ } as Meta<typeof Link>;
17
48
 
18
49
  export default meta;
19
- type Story = StoryObj<typeof Link>;
50
+ type Story = StoryObj<LinkProps>;
20
51
 
21
- export const LinkComponent: Story = {
22
- args: {},
23
- play: async ({ canvasElement }) => {
52
+ /**
53
+ * Basic link component with default styling.
54
+ * Links should have descriptive text that makes sense out of context.
55
+ */
56
+ export const Default: Story = {
57
+ args: {
58
+ href: "/about",
59
+ children: "About Us",
60
+ },
61
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
24
62
  const canvas = within(canvasElement);
25
63
  const link = canvas.getByRole("link");
64
+
65
+ // Verify basic rendering
26
66
  expect(link).toBeInTheDocument();
27
- expect(link).toHaveTextContent("Link");
67
+ expect(link).toHaveTextContent("About Us");
68
+ expect(link).toHaveAttribute("href", "/about");
69
+
70
+ // Verify accessibility
71
+ expect(link).toBeVisible();
72
+ expect(link.tagName).toBe("A");
28
73
  },
29
74
  };
30
75
 
76
+ /**
77
+ * External link with automatic security attributes.
78
+ * The component automatically adds rel="noopener noreferrer" for target="_blank".
79
+ */
31
80
  export const ExternalLink: Story = {
32
81
  args: {
33
82
  href: "https://www.google.com",
34
83
  target: "_blank",
35
- rel: "noopener noreferrer",
36
- prefetch: true,
37
- children: "Google",
84
+ children: "Visit Google",
38
85
  },
39
- play: async ({ canvasElement }) => {
86
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
40
87
  const canvas = within(canvasElement);
41
88
  const link = canvas.getByRole("link");
89
+
90
+ // Verify external link attributes
42
91
  expect(link).toBeInTheDocument();
43
- expect(link).toHaveTextContent("Google");
92
+ expect(link).toHaveTextContent("Visit Google");
44
93
  expect(link).toHaveAttribute("href", "https://www.google.com");
45
94
  expect(link).toHaveAttribute("target", "_blank");
46
- expect(link).toHaveAttribute("rel", "noopener noreferrer prefetch");
95
+
96
+ // Verify automatic security attributes
97
+ const rel = link.getAttribute("rel");
98
+ expect(rel).toContain("noopener");
99
+ expect(rel).toContain("noreferrer");
47
100
  },
48
- } as Story;
101
+ };
49
102
 
50
- export const ButtonLink: Story = {
103
+ /**
104
+ * External link with prefetch hint.
105
+ * Combines security attributes with performance optimization.
106
+ */
107
+ export const ExternalLinkWithPrefetch: Story = {
51
108
  args: {
52
- ...LinkComponent.args,
53
- children: <b>Button Link</b>,
109
+ href: "https://example.com/next-page",
110
+ target: "_blank",
111
+ prefetch: true,
112
+ children: "Prefetch Example",
113
+ },
114
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
115
+ const canvas = within(canvasElement);
116
+ const link = canvas.getByRole("link");
117
+
118
+ // Verify prefetch is included with security
119
+ const rel = link.getAttribute("rel");
120
+ expect(rel).toContain("noopener");
121
+ expect(rel).toContain("noreferrer");
122
+ expect(rel).toContain("prefetch");
54
123
  },
55
- } as Story;
124
+ };
56
125
 
57
- export const ButtonPill: Story = {
126
+ /**
127
+ * External link with custom rel attributes.
128
+ * Custom rel values are merged with security defaults, not overwritten.
129
+ */
130
+ export const ExternalLinkWithCustomRel: Story = {
58
131
  args: {
59
- ...LinkComponent.args,
60
- children: <i>Button Link</i>,
132
+ href: "https://example.com",
133
+ target: "_blank",
134
+ rel: "nofollow author",
135
+ children: "External Link with Custom Rel",
61
136
  },
62
- } as Story;
137
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
138
+ const canvas = within(canvasElement);
139
+ const link = canvas.getByRole("link");
63
140
 
64
- export const ButtonRounded: Story = {
141
+ // Verify all rel tokens are present (merged, not replaced)
142
+ const rel = link.getAttribute("rel");
143
+ expect(rel).toContain("noopener");
144
+ expect(rel).toContain("noreferrer");
145
+ expect(rel).toContain("nofollow");
146
+ expect(rel).toContain("author");
147
+ },
148
+ };
149
+
150
+ /**
151
+ * Button-styled link using <b> wrapper.
152
+ * Maintains semantic <a> element while applying button appearance.
153
+ */
154
+ export const ButtonStyled: Story = {
155
+ args: {
156
+ href: "/signup",
157
+ children: <b>Sign Up Now</b>,
158
+ },
159
+ parameters: {
160
+ docs: {
161
+ description: {
162
+ story:
163
+ "Wrapping link text in `<b>` automatically applies button styling. This is useful for call-to-action links.",
164
+ },
165
+ },
166
+ },
167
+ };
168
+
169
+ /**
170
+ * Pill-styled button link using <i> wrapper.
171
+ * Applies rounded pill styling with button appearance.
172
+ */
173
+ export const PillStyled: Story = {
174
+ args: {
175
+ href: "/get-started",
176
+ children: <i>Get Started</i>,
177
+ },
178
+ parameters: {
179
+ docs: {
180
+ description: {
181
+ story:
182
+ "Wrapping link text in `<i>` applies pill (fully rounded) button styling.",
183
+ },
184
+ },
185
+ },
186
+ };
187
+
188
+ /**
189
+ * Button-styled link with custom border radius.
190
+ * Demonstrates CSS custom property override.
191
+ */
192
+ export const ButtonWithCustomRadius: Story = {
65
193
  args: {
66
- ...ButtonLink.args,
194
+ href: "/action",
195
+ children: <b>Custom Radius</b>,
67
196
  styles: {
68
- "--link-radius": "initial",
197
+ "--link-radius": "0.5rem",
198
+ } as React.CSSProperties,
199
+ },
200
+ };
201
+
202
+ /**
203
+ * Link with custom color using CSS variables.
204
+ * All styling is controlled via CSS custom properties.
205
+ */
206
+ export const CustomColor: Story = {
207
+ args: {
208
+ href: "/products",
209
+ children: "Browse Products",
210
+ styles: {
211
+ "--link-color": "#d63384",
212
+ "--link-decoration": "underline",
213
+ } as React.CSSProperties,
214
+ },
215
+ };
216
+
217
+ /**
218
+ * Keyboard navigation test.
219
+ * Verifies link is keyboard accessible with proper focus indicators.
220
+ */
221
+ export const KeyboardNavigation: Story = {
222
+ args: {
223
+ href: "/keyboard-test",
224
+ children: "Keyboard Accessible Link",
225
+ },
226
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
227
+ const canvas = within(canvasElement);
228
+ const link = canvas.getByRole("link");
229
+
230
+ // Tab to the link
231
+ await userEvent.tab();
232
+
233
+ // Verify focus
234
+ expect(link).toHaveFocus();
235
+
236
+ // Verify the link is announced by screen readers
237
+ expect(link).toHaveAccessibleName("Keyboard Accessible Link");
238
+ },
239
+ };
240
+
241
+ /**
242
+ * Icon-only link with aria-label.
243
+ * Demonstrates accessible pattern for icon-only links.
244
+ */
245
+ export const IconOnlyWithAriaLabel: Story = {
246
+ args: {
247
+ href: "/settings",
248
+ "aria-label": "Open settings",
249
+ children: (
250
+ <svg
251
+ aria-hidden="true"
252
+ width="16"
253
+ height="16"
254
+ viewBox="0 0 16 16"
255
+ fill="currentColor"
256
+ >
257
+ <path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z" />
258
+ <path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319z" />
259
+ </svg>
260
+ ),
261
+ },
262
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
263
+ const canvas = within(canvasElement);
264
+ const link = canvas.getByRole("link");
265
+
266
+ // Verify accessible name from aria-label
267
+ expect(link).toHaveAccessibleName("Open settings");
268
+
269
+ // Verify SVG is hidden from screen readers
270
+ const svg = link.querySelector("svg");
271
+ expect(svg).toHaveAttribute("aria-hidden", "true");
272
+ },
273
+ };
274
+
275
+ /**
276
+ * Skip link pattern with ref forwarding.
277
+ * Demonstrates programmatic focus management for accessibility.
278
+ */
279
+ export const SkipLink: Story = {
280
+ render: () => {
281
+ const SkipLinkExample = () => {
282
+ const mainRef = useRef<HTMLAnchorElement>(null);
283
+
284
+ useEffect(() => {
285
+ // Simulate focus on mount (for demonstration)
286
+ const timer = setTimeout(() => {
287
+ mainRef.current?.focus();
288
+ }, 100);
289
+
290
+ return () => clearTimeout(timer);
291
+ }, []);
292
+
293
+ return (
294
+ <div style={{ padding: "1rem" }}>
295
+ <Link ref={mainRef} href="#main-content">
296
+ Skip to main content
297
+ </Link>
298
+ <p id="main-content" style={{ marginTop: "1rem" }}>
299
+ Main content starts here
300
+ </p>
301
+ </div>
302
+ );
303
+ };
304
+
305
+ return <SkipLinkExample />;
306
+ },
307
+ parameters: {
308
+ docs: {
309
+ description: {
310
+ story:
311
+ "Demonstrates ref forwarding for programmatic focus management. Useful for skip links and keyboard navigation patterns.",
312
+ },
69
313
  },
70
314
  },
71
- } as Story;
315
+ };
316
+
317
+ /**
318
+ * Email link (mailto:).
319
+ * Demonstrates non-HTTP URL schemes.
320
+ */
321
+ export const EmailLink: Story = {
322
+ args: {
323
+ href: "mailto:hello@example.com",
324
+ children: "Contact us via email",
325
+ },
326
+ };
327
+
328
+ /**
329
+ * Phone link (tel:).
330
+ * Demonstrates telephone URL scheme.
331
+ */
332
+ export const PhoneLink: Story = {
333
+ args: {
334
+ href: "tel:+1234567890",
335
+ children: "Call us: +1 (234) 567-890",
336
+ },
337
+ };
338
+
339
+ /**
340
+ * Link with onClick event handler (RECOMMENDED).
341
+ * onClick fires for all activation methods including keyboard.
342
+ */
343
+ export const WithOnClick: Story = {
344
+ args: {
345
+ href: "/products",
346
+ children: "Track All Activations",
347
+ onClick: fn(),
348
+ },
349
+ parameters: {
350
+ docs: {
351
+ description: {
352
+ story:
353
+ "**Recommended**: Use `onClick` for analytics and tracking. It captures mouse clicks, touch events, AND keyboard activation (Enter key).",
354
+ },
355
+ },
356
+ },
357
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
358
+ const canvas = within(canvasElement);
359
+ const link = canvas.getByRole("link");
360
+
361
+ // Click with mouse
362
+ await userEvent.click(link);
363
+
364
+ // Also works with keyboard
365
+ link.focus();
366
+ await userEvent.keyboard("{Enter}");
367
+
368
+ // Check console for both events
369
+ },
370
+ };
371
+
372
+ /**
373
+ * Link with onPointerDown event handler.
374
+ * Only fires for pointer events (mouse, touch, pen) - NOT keyboard.
375
+ */
376
+ export const WithOnPointerDown: Story = {
377
+ args: {
378
+ href: "/products",
379
+ children: "Track Pointer Only",
380
+ onPointerDown: fn(),
381
+ },
382
+ parameters: {
383
+ docs: {
384
+ description: {
385
+ story:
386
+ "⚠️ **Accessibility Note**: `onPointerDown` does NOT fire for keyboard activation (Enter key). Use `onClick` if you need to track keyboard users.",
387
+ },
388
+ },
389
+ },
390
+ play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
391
+ const canvas = within(canvasElement);
392
+ const link = canvas.getByRole("link");
393
+
394
+ // Click with mouse - handler fires
395
+ await userEvent.click(link);
396
+
397
+ // Keyboard activation - handler does NOT fire
398
+ link.focus();
399
+ await userEvent.keyboard("{Enter}");
400
+
401
+ // Check console - only one event logged (mouse click)
402
+ },
403
+ };
404
+
405
+ /**
406
+ * Link with both onClick and onPointerDown.
407
+ * Demonstrates using both handlers together for comprehensive tracking.
408
+ */
409
+ export const WithBothHandlers: Story = {
410
+ args: {
411
+ href: "/products",
412
+ children: "Track Both Ways",
413
+ onClick: fn(),
414
+ onPointerDown: fn(),
415
+ },
416
+ parameters: {
417
+ docs: {
418
+ description: {
419
+ story:
420
+ "Use both handlers when you need comprehensive tracking: `onClick` captures all activations, while `onPointerDown` provides pointer-specific data.",
421
+ },
422
+ },
423
+ },
424
+ };