@fpkit/acss 0.5.13 → 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 (280) hide show
  1. package/libs/{chunk-PQ2K3BM6.cjs → chunk-2NRIP6RB.cjs} +3 -3
  2. package/libs/chunk-33PNJ4LO.cjs +15 -0
  3. package/libs/chunk-33PNJ4LO.cjs.map +1 -0
  4. package/libs/chunk-4BZKFPEC.cjs +17 -0
  5. package/libs/chunk-4BZKFPEC.cjs.map +1 -0
  6. package/libs/{chunk-772NRB75.js → chunk-5QD3DWFI.js} +2 -2
  7. package/libs/chunk-6SAHIYCZ.js +7 -0
  8. package/libs/chunk-6SAHIYCZ.js.map +1 -0
  9. package/libs/{chunk-3MKLDCKQ.cjs → chunk-6WTC4JXH.cjs} +3 -3
  10. package/libs/chunk-75QHTLFO.js +7 -0
  11. package/libs/chunk-75QHTLFO.js.map +1 -0
  12. package/libs/{chunk-ZANSFMTD.js → chunk-7XPFW7CB.js} +3 -3
  13. package/libs/chunk-BFK62VX5.js +5 -0
  14. package/libs/chunk-BFK62VX5.js.map +1 -0
  15. package/libs/{chunk-ROZI23GS.cjs → chunk-DKTHCQ5P.cjs} +4 -4
  16. package/libs/chunk-E2AJURUW.cjs +13 -0
  17. package/libs/chunk-E2AJURUW.cjs.map +1 -0
  18. package/libs/{chunk-L75OQKEI.cjs → chunk-ENTCUJ3A.cjs} +3 -3
  19. package/libs/chunk-ENTCUJ3A.cjs.map +1 -0
  20. package/libs/chunk-F5EYMVQM.js +10 -0
  21. package/libs/chunk-F5EYMVQM.js.map +1 -0
  22. package/libs/chunk-FVROL3V5.js +9 -0
  23. package/libs/chunk-FVROL3V5.js.map +1 -0
  24. package/libs/chunk-GT77BX4L.cjs +17 -0
  25. package/libs/chunk-GT77BX4L.cjs.map +1 -0
  26. package/libs/chunk-GUJSMQ3V.cjs +16 -0
  27. package/libs/chunk-GUJSMQ3V.cjs.map +1 -0
  28. package/libs/chunk-HHLNOC5T.js +7 -0
  29. package/libs/chunk-HHLNOC5T.js.map +1 -0
  30. package/libs/chunk-HRRHPLER.js +8 -0
  31. package/libs/chunk-HRRHPLER.js.map +1 -0
  32. package/libs/chunk-IEB64SWY.js +8 -0
  33. package/libs/chunk-IEB64SWY.js.map +1 -0
  34. package/libs/{chunk-NGTJDDFO.js → chunk-IQ76HGVP.js} +2 -2
  35. package/libs/chunk-IRLFZ3OL.js +9 -0
  36. package/libs/chunk-IRLFZ3OL.js.map +1 -0
  37. package/libs/{chunk-JJ43O4Y5.js → chunk-KK47SYZI.js} +2 -2
  38. package/libs/chunk-O3JIHC5M.cjs +15 -0
  39. package/libs/chunk-O3JIHC5M.cjs.map +1 -0
  40. package/libs/chunk-O5XAJ7BY.cjs +18 -0
  41. package/libs/chunk-O5XAJ7BY.cjs.map +1 -0
  42. package/libs/chunk-OVWLQYMK.js +10 -0
  43. package/libs/chunk-OVWLQYMK.js.map +1 -0
  44. package/libs/chunk-PNWIRCG3.cjs +7 -0
  45. package/libs/chunk-PNWIRCG3.cjs.map +1 -0
  46. package/libs/{chunk-D4YLRWAO.cjs → chunk-QVW6W76L.cjs} +6 -6
  47. package/libs/chunk-T4T6GWYQ.cjs +17 -0
  48. package/libs/chunk-T4T6GWYQ.cjs.map +1 -0
  49. package/libs/chunk-TON2YGMD.cjs +9 -0
  50. package/libs/chunk-TON2YGMD.cjs.map +1 -0
  51. package/libs/chunk-UEPAWMDF.js +8 -0
  52. package/libs/chunk-UEPAWMDF.js.map +1 -0
  53. package/libs/{chunk-LT5KZ2QW.cjs → chunk-US2I5GI7.cjs} +3 -3
  54. package/libs/{chunk-B7F5FS6D.cjs → chunk-W2UIN7EV.cjs} +3 -3
  55. package/libs/{chunk-P2DC76ZZ.cjs → chunk-W5TKWBFC.cjs} +3 -3
  56. package/libs/chunk-WXBFBWYF.cjs +16 -0
  57. package/libs/chunk-WXBFBWYF.cjs.map +1 -0
  58. package/libs/{chunk-VUH3FXGJ.js → chunk-X3JCTEPD.js} +5 -5
  59. package/libs/chunk-X5LGFCWG.js +9 -0
  60. package/libs/chunk-X5LGFCWG.js.map +1 -0
  61. package/libs/{chunk-5M57K4SW.js → chunk-Y2PFDELK.js} +2 -2
  62. package/libs/{chunk-ETFLFC2S.js → chunk-ZFJ4U45S.js} +2 -2
  63. package/libs/{component-props-a8a2f97e.d.ts → component-props-67d978a2.d.ts} +4 -4
  64. package/libs/components/alert/alert.css +1 -1
  65. package/libs/components/alert/alert.css.map +1 -1
  66. package/libs/components/alert/alert.min.css +2 -2
  67. package/libs/components/breadcrumbs/breadcrumb.cjs +6 -6
  68. package/libs/components/breadcrumbs/breadcrumb.d.cts +11 -11
  69. package/libs/components/breadcrumbs/breadcrumb.d.ts +11 -11
  70. package/libs/components/breadcrumbs/breadcrumb.js +3 -3
  71. package/libs/components/button.cjs +6 -4
  72. package/libs/components/button.d.cts +97 -4
  73. package/libs/components/button.d.ts +97 -4
  74. package/libs/components/button.js +4 -2
  75. package/libs/components/card.cjs +7 -7
  76. package/libs/components/card.d.cts +14 -14
  77. package/libs/components/card.d.ts +14 -14
  78. package/libs/components/card.js +2 -2
  79. package/libs/components/dialog/dialog.cjs +9 -7
  80. package/libs/components/dialog/dialog.d.cts +3 -3
  81. package/libs/components/dialog/dialog.d.ts +3 -3
  82. package/libs/components/dialog/dialog.js +7 -5
  83. package/libs/components/form/fields.cjs +4 -4
  84. package/libs/components/form/fields.d.cts +16 -7
  85. package/libs/components/form/fields.d.ts +16 -7
  86. package/libs/components/form/fields.js +2 -2
  87. package/libs/components/form/inputs.cjs +6 -4
  88. package/libs/components/form/inputs.d.cts +50 -2
  89. package/libs/components/form/inputs.d.ts +50 -2
  90. package/libs/components/form/inputs.js +4 -2
  91. package/libs/components/form/textarea.cjs +5 -4
  92. package/libs/components/form/textarea.d.cts +32 -23
  93. package/libs/components/form/textarea.d.ts +32 -23
  94. package/libs/components/form/textarea.js +3 -2
  95. package/libs/components/heading/heading.cjs +3 -3
  96. package/libs/components/heading/heading.d.cts +2 -2
  97. package/libs/components/heading/heading.d.ts +2 -2
  98. package/libs/components/heading/heading.js +2 -2
  99. package/libs/components/icons/icon.cjs +4 -4
  100. package/libs/components/icons/icon.d.cts +38 -38
  101. package/libs/components/icons/icon.d.ts +38 -38
  102. package/libs/components/icons/icon.js +2 -2
  103. package/libs/components/link/link.cjs +4 -4
  104. package/libs/components/link/link.css +1 -1
  105. package/libs/components/link/link.css.map +1 -1
  106. package/libs/components/link/link.d.cts +3 -19
  107. package/libs/components/link/link.d.ts +3 -19
  108. package/libs/components/link/link.js +2 -2
  109. package/libs/components/link/link.min.css +2 -2
  110. package/libs/components/list/list.cjs +5 -5
  111. package/libs/components/list/list.css +1 -0
  112. package/libs/components/list/list.css.map +1 -0
  113. package/libs/components/list/list.d.cts +120 -33
  114. package/libs/components/list/list.d.ts +120 -33
  115. package/libs/components/list/list.js +2 -2
  116. package/libs/components/list/list.min.css +3 -0
  117. package/libs/components/modal.cjs +6 -4
  118. package/libs/components/modal.d.cts +8 -8
  119. package/libs/components/modal.d.ts +8 -8
  120. package/libs/components/modal.js +5 -3
  121. package/libs/components/nav/nav.cjs +7 -7
  122. package/libs/components/nav/nav.css +1 -1
  123. package/libs/components/nav/nav.css.map +1 -1
  124. package/libs/components/nav/nav.d.cts +550 -34
  125. package/libs/components/nav/nav.d.ts +550 -34
  126. package/libs/components/nav/nav.js +3 -3
  127. package/libs/components/nav/nav.min.css +2 -2
  128. package/libs/components/popover/popover.d.cts +5 -5
  129. package/libs/components/popover/popover.d.ts +5 -5
  130. package/libs/components/tables/table.cjs +5 -5
  131. package/libs/components/tables/table.d.cts +8 -8
  132. package/libs/components/tables/table.d.ts +8 -8
  133. package/libs/components/tables/table.js +2 -2
  134. package/libs/components/tag/tag.css +1 -1
  135. package/libs/components/tag/tag.css.map +1 -1
  136. package/libs/components/tag/tag.min.css +2 -2
  137. package/libs/components/text/text.cjs +5 -5
  138. package/libs/components/text/text.d.cts +5 -5
  139. package/libs/components/text/text.d.ts +5 -5
  140. package/libs/components/text/text.js +2 -2
  141. package/libs/form.types-d25ebfac.d.ts +233 -0
  142. package/libs/{heading-3648c538.d.ts → heading-7446cb46.d.ts} +8 -8
  143. package/libs/hooks.cjs +9 -4
  144. package/libs/hooks.d.cts +137 -3
  145. package/libs/hooks.d.ts +137 -3
  146. package/libs/hooks.js +4 -3
  147. package/libs/icons.cjs +3 -3
  148. package/libs/icons.d.cts +2 -2
  149. package/libs/icons.d.ts +2 -2
  150. package/libs/icons.js +2 -2
  151. package/libs/index.cjs +53 -51
  152. package/libs/index.cjs.map +1 -1
  153. package/libs/index.css +1 -1
  154. package/libs/index.css.map +1 -1
  155. package/libs/index.d.cts +338 -49
  156. package/libs/index.d.ts +338 -49
  157. package/libs/index.js +24 -22
  158. package/libs/index.js.map +1 -1
  159. package/libs/link-5192f411.d.ts +323 -0
  160. package/libs/list.types-d26de310.d.ts +245 -0
  161. package/libs/{ui-645f95b5.d.ts → ui-d01b50d4.d.ts} +16 -12
  162. package/package.json +4 -6
  163. package/src/components/alert/alert.scss +1 -4
  164. package/src/components/breadcrumbs/breadcrumb.tsx +4 -1
  165. package/src/components/buttons/README.mdx +102 -1
  166. package/src/components/buttons/button.stories.tsx +106 -0
  167. package/src/components/buttons/button.tsx +82 -52
  168. package/src/components/dialog/dialog-a11y-review.md +653 -0
  169. package/src/components/form/README.mdx +725 -43
  170. package/src/components/form/WCAG-REVIEW.md +654 -0
  171. package/src/components/form/fields.tsx +10 -1
  172. package/src/components/form/form.stories.tsx +604 -23
  173. package/src/components/form/form.tsx +204 -63
  174. package/src/components/form/form.types.ts +378 -0
  175. package/src/components/form/input.stories.tsx +71 -3
  176. package/src/components/form/inputs.tsx +159 -67
  177. package/src/components/form/select.tsx +122 -66
  178. package/src/components/form/textarea.tsx +120 -73
  179. package/src/components/fp.tsx +86 -11
  180. package/src/components/link/README.mdx +923 -0
  181. package/src/components/link/link.scss +79 -26
  182. package/src/components/link/link.stories.tsx +383 -30
  183. package/src/components/link/link.test.tsx +677 -0
  184. package/src/components/link/link.tsx +163 -57
  185. package/src/components/link/link.types.ts +261 -0
  186. package/src/components/list/README.mdx +764 -0
  187. package/src/components/list/list.scss +285 -0
  188. package/src/components/list/list.stories.tsx +514 -27
  189. package/src/components/list/list.test.tsx +554 -0
  190. package/src/components/list/list.tsx +153 -51
  191. package/src/components/list/list.types.ts +255 -0
  192. package/src/components/nav/ACCESSIBILITY.md +649 -0
  193. package/src/components/nav/README.mdx +782 -0
  194. package/src/components/nav/nav.scss +32 -1
  195. package/src/components/nav/nav.stories.tsx +44 -6
  196. package/src/components/nav/nav.tsx +302 -51
  197. package/src/components/nav/nav.types.ts +308 -0
  198. package/src/components/tag/README.mdx +426 -0
  199. package/src/components/tag/tag.scss +101 -27
  200. package/src/components/tag/tag.stories.tsx +384 -10
  201. package/src/components/tag/tag.test.tsx +210 -0
  202. package/src/components/tag/tag.tsx +106 -9
  203. package/src/components/tag/tag.types.ts +107 -0
  204. package/src/components/ui.tsx +8 -3
  205. package/src/hooks/use-disabled-state.test.tsx +536 -0
  206. package/src/hooks/use-disabled-state.ts +246 -0
  207. package/src/hooks/useDisabledState.md +393 -0
  208. package/src/hooks.ts +6 -0
  209. package/src/index.scss +2 -0
  210. package/src/index.ts +2 -1
  211. package/src/sass/_globals.scss +2 -7
  212. package/src/styles/alert/alert.css +1 -3
  213. package/src/styles/alert/alert.css.map +1 -1
  214. package/src/styles/index.css +450 -76
  215. package/src/styles/index.css.map +1 -1
  216. package/src/styles/link/link.css +45 -28
  217. package/src/styles/link/link.css.map +1 -1
  218. package/src/styles/list/list.css +214 -0
  219. package/src/styles/list/list.css.map +1 -0
  220. package/src/styles/nav/nav.css +21 -1
  221. package/src/styles/nav/nav.css.map +1 -1
  222. package/src/styles/tag/tag.css +113 -35
  223. package/src/styles/tag/tag.css.map +1 -1
  224. package/src/styles/utilities/_disabled.scss +58 -0
  225. package/src/types/shared.ts +43 -6
  226. package/src/utils/accessibility.ts +109 -0
  227. package/libs/chunk-2LTJ7HHX.cjs +0 -18
  228. package/libs/chunk-2LTJ7HHX.cjs.map +0 -1
  229. package/libs/chunk-2Y7W75TT.js +0 -9
  230. package/libs/chunk-2Y7W75TT.js.map +0 -1
  231. package/libs/chunk-5S4ORA4C.cjs +0 -15
  232. package/libs/chunk-5S4ORA4C.cjs.map +0 -1
  233. package/libs/chunk-AHDJGCG5.cjs +0 -15
  234. package/libs/chunk-AHDJGCG5.cjs.map +0 -1
  235. package/libs/chunk-BHRQBJRY.js +0 -8
  236. package/libs/chunk-BHRQBJRY.js.map +0 -1
  237. package/libs/chunk-GZ4QFPRY.js +0 -9
  238. package/libs/chunk-GZ4QFPRY.js.map +0 -1
  239. package/libs/chunk-IYUN2EW3.cjs +0 -15
  240. package/libs/chunk-IYUN2EW3.cjs.map +0 -1
  241. package/libs/chunk-J32EZPYD.cjs +0 -15
  242. package/libs/chunk-J32EZPYD.cjs.map +0 -1
  243. package/libs/chunk-KUKIVRC2.js +0 -7
  244. package/libs/chunk-KUKIVRC2.js.map +0 -1
  245. package/libs/chunk-L75OQKEI.cjs.map +0 -1
  246. package/libs/chunk-M5RRNTVX.cjs +0 -15
  247. package/libs/chunk-M5RRNTVX.cjs.map +0 -1
  248. package/libs/chunk-OK5QEIMD.cjs +0 -17
  249. package/libs/chunk-OK5QEIMD.cjs.map +0 -1
  250. package/libs/chunk-P7TTEYCD.js +0 -7
  251. package/libs/chunk-P7TTEYCD.js.map +0 -1
  252. package/libs/chunk-QLZWHAMK.js +0 -8
  253. package/libs/chunk-QLZWHAMK.js.map +0 -1
  254. package/libs/chunk-RIVUMPOG.js +0 -8
  255. package/libs/chunk-RIVUMPOG.js.map +0 -1
  256. package/libs/chunk-S7BABR7Z.cjs +0 -13
  257. package/libs/chunk-S7BABR7Z.cjs.map +0 -1
  258. package/libs/chunk-SMYRLO3E.js +0 -8
  259. package/libs/chunk-SMYRLO3E.js.map +0 -1
  260. package/libs/chunk-TYRCEX2L.js +0 -8
  261. package/libs/chunk-TYRCEX2L.js.map +0 -1
  262. package/libs/chunk-XBA562WW.js +0 -8
  263. package/libs/chunk-XBA562WW.js.map +0 -1
  264. package/libs/chunk-XTQKWY7W.cjs +0 -32
  265. package/libs/chunk-XTQKWY7W.cjs.map +0 -1
  266. package/libs/inputs-f3a216db.d.ts +0 -45
  267. /package/libs/{chunk-PQ2K3BM6.cjs.map → chunk-2NRIP6RB.cjs.map} +0 -0
  268. /package/libs/{chunk-772NRB75.js.map → chunk-5QD3DWFI.js.map} +0 -0
  269. /package/libs/{chunk-3MKLDCKQ.cjs.map → chunk-6WTC4JXH.cjs.map} +0 -0
  270. /package/libs/{chunk-ZANSFMTD.js.map → chunk-7XPFW7CB.js.map} +0 -0
  271. /package/libs/{chunk-ROZI23GS.cjs.map → chunk-DKTHCQ5P.cjs.map} +0 -0
  272. /package/libs/{chunk-NGTJDDFO.js.map → chunk-IQ76HGVP.js.map} +0 -0
  273. /package/libs/{chunk-JJ43O4Y5.js.map → chunk-KK47SYZI.js.map} +0 -0
  274. /package/libs/{chunk-D4YLRWAO.cjs.map → chunk-QVW6W76L.cjs.map} +0 -0
  275. /package/libs/{chunk-LT5KZ2QW.cjs.map → chunk-US2I5GI7.cjs.map} +0 -0
  276. /package/libs/{chunk-B7F5FS6D.cjs.map → chunk-W2UIN7EV.cjs.map} +0 -0
  277. /package/libs/{chunk-P2DC76ZZ.cjs.map → chunk-W5TKWBFC.cjs.map} +0 -0
  278. /package/libs/{chunk-VUH3FXGJ.js.map → chunk-X3JCTEPD.js.map} +0 -0
  279. /package/libs/{chunk-5M57K4SW.js.map → chunk-Y2PFDELK.js.map} +0 -0
  280. /package/libs/{chunk-ETFLFC2S.js.map → chunk-ZFJ4U45S.js.map} +0 -0
@@ -1,87 +1,134 @@
1
1
  import React from 'react'
2
2
  import UI from '../ui'
3
+ import { useDisabledState } from '../../hooks/use-disabled-state'
3
4
 
4
- export type TextareaProps = React.ComponentProps<'textarea'> &
5
- React.ComponentProps<typeof UI>
5
+ export type { TextareaProps } from './form.types'
6
+ import type { TextareaProps } from './form.types'
6
7
 
7
8
  /**
8
- * Textarea component.
9
+ * Textarea component - Accessible multi-line text input with validation support
9
10
  *
10
- * @param value - The value of the textarea.
11
- * @param rows - The number of rows.
12
- * @param cols - The number of columns.
13
- * @param id - The id of the textarea.
14
- * @param name - The name of the textarea.
15
- * @param required - Whether the textarea is required.
16
- * @param disabled - Whether the textarea is disabled.
17
- * @param readOnly - Whether the textarea is read only.
18
- * @param onBlur - Blur event handler.
19
- * @param onPointerDown - Pointer down event handler.
20
- * @param onChange - Change event handler.
21
- * @param ref - Ref for the textarea.
22
- * @param styles - Styles object for the textarea.
23
- * @param textareaRef - Ref specifically for the textarea element.
24
- * @param props - Other props.
11
+ * A flexible textarea component that supports validation states, proper ARIA attributes
12
+ * for accessibility, and an onEnter handler for keyboard interactions. The onEnter handler
13
+ * fires only on Enter without Shift, allowing Shift+Enter to create new lines as expected.
14
+ *
15
+ * @component
16
+ * @example
17
+ * // Basic textarea
18
+ * <Textarea
19
+ * id="message"
20
+ * name="message"
21
+ * placeholder="Enter your message"
22
+ * required
23
+ * />
24
+ *
25
+ * @example
26
+ * // Textarea with Enter key handler for quick submission
27
+ * <Textarea
28
+ * id="comment"
29
+ * name="comment"
30
+ * onEnter={(e) => handleSubmit()}
31
+ * placeholder="Press Enter to submit, Shift+Enter for new line"
32
+ * />
33
+ *
34
+ * @param {TextareaProps} props - Component props
35
+ * @returns {JSX.Element} Textarea element with proper accessibility attributes
36
+ *
37
+ * @see {@link https://www.w3.org/WAI/WCAG21/Understanding/keyboard.html|WCAG 2.1.1 Keyboard}
38
+ * @see {@link https://www.w3.org/WAI/WCAG21/Understanding/name-role-value.html|WCAG 4.1.2 Name, Role, Value}
25
39
  */
26
- export const Textarea = ({
27
- id,
28
- classes,
29
- value,
30
- rows = 5,
31
- cols = 25,
32
- name,
33
- required,
34
- disabled,
35
- readOnly,
36
- onBlur,
37
- onPointerDown,
38
- onChange,
39
- ref,
40
- styles,
41
- placeholder,
42
- ...props
43
- }: TextareaProps) => {
44
- const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
45
- if (onChange && !disabled) {
46
- onChange?.(e)
47
- }
48
- }
40
+ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
41
+ (
42
+ {
43
+ id,
44
+ classes,
45
+ value,
46
+ rows = 5,
47
+ cols = 25,
48
+ name,
49
+ required,
50
+ disabled,
51
+ readOnly,
52
+ validationState = 'none',
53
+ errorMessage,
54
+ hintText,
55
+ onBlur,
56
+ onPointerDown,
57
+ onChange,
58
+ onKeyDown,
59
+ onEnter,
60
+ styles,
61
+ placeholder,
62
+ ...props
63
+ },
64
+ ref
65
+ ) => {
66
+ // Use the disabled state hook with enhanced API for automatic className merging
67
+ const { disabledProps, handlers } = useDisabledState<HTMLTextAreaElement>(
68
+ disabled,
69
+ {
70
+ handlers: {
71
+ onChange,
72
+ onBlur,
73
+ onPointerDown,
74
+ onKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
75
+ // Handle Enter key press for accessibility
76
+ // Only triggers onEnter when Enter is pressed WITHOUT Shift modifier
77
+ // This allows Shift+Enter to create new lines as expected
78
+ if (e.key === 'Enter' && !e.shiftKey && onEnter) {
79
+ onEnter(e)
80
+ }
81
+ // Always call consumer's onKeyDown if provided
82
+ if (onKeyDown) {
83
+ onKeyDown(e)
84
+ }
85
+ },
86
+ },
87
+ // Automatic className merging - hook combines disabled class with user classes
88
+ className: classes,
89
+ }
90
+ )
49
91
 
50
- const handleBlur = (e: React.FocusEvent<HTMLTextAreaElement>) => {
51
- if (onBlur && !disabled) {
52
- onBlur?.(e)
53
- }
54
- }
92
+ // Determine aria-invalid based on validation state
93
+ const isInvalid = validationState === 'invalid'
55
94
 
56
- const handlePointerDown = (e: React.PointerEvent<HTMLTextAreaElement>) => {
57
- if (onPointerDown && !disabled) {
58
- onPointerDown?.(e)
95
+ // Generate describedby IDs for error and hint text
96
+ const describedByIds: string[] = []
97
+ if (errorMessage && id) {
98
+ describedByIds.push(`${id}-error`)
99
+ }
100
+ if (hintText && id) {
101
+ describedByIds.push(`${id}-hint`)
59
102
  }
103
+ const ariaDescribedBy =
104
+ describedByIds.length > 0 ? describedByIds.join(' ') : undefined
105
+
106
+ return (
107
+ <UI
108
+ as="textarea"
109
+ id={id}
110
+ name={name}
111
+ rows={rows}
112
+ cols={cols}
113
+ styles={styles}
114
+ className={disabledProps.className}
115
+ data-style="textarea"
116
+ required={required}
117
+ value={value}
118
+ aria-disabled={disabledProps['aria-disabled']}
119
+ aria-required={required}
120
+ aria-invalid={isInvalid}
121
+ aria-describedby={ariaDescribedBy}
122
+ readOnly={readOnly}
123
+ {...handlers}
124
+ ref={ref}
125
+ placeholder={placeholder || `${required ? '*' : ''} Message`}
126
+ {...props}
127
+ />
128
+ )
60
129
  }
130
+ )
61
131
 
62
- return (
63
- <UI
64
- as="textarea"
65
- id={id}
66
- name={name}
67
- rows={rows}
68
- cols={cols}
69
- styles={styles}
70
- className={classes}
71
- data-style="textarea"
72
- required={required}
73
- value={value}
74
- aria-disabled={disabled}
75
- readOnly={readOnly}
76
- onChange={handleChange}
77
- onBlur={handleBlur}
78
- onPointerDown={handlePointerDown}
79
- ref={ref}
80
- placeholder={placeholder || `${required ? '*' : ''} Message`}
81
- {...props}
82
- />
83
- )
84
- }
132
+ Textarea.displayName = 'Textarea'
85
133
 
86
134
  export default Textarea
87
- Textarea.displayName = 'Textarea'
@@ -1,28 +1,55 @@
1
1
  import React from 'react'
2
2
  import { ComponentProps } from '../types'
3
3
 
4
- type PolymorphicRef<C extends React.ElementType> =
5
- React.ComponentPropsWithRef<C>['ref']
4
+ /**
5
+ * @deprecated This type is deprecated. Use `PolymorphicRef` from './ui.tsx' instead.
6
+ * The UI component provides better type safety and accessibility features.
7
+ */
8
+ type PolymorphicRef<C extends React.ElementType> = React.Ref<
9
+ React.ElementRef<C>
10
+ >
6
11
 
12
+ /**
13
+ * @deprecated This type is deprecated. Use `AsProp` from './ui.tsx' instead.
14
+ * The UI component provides better type safety and accessibility features.
15
+ */
7
16
  type AsProp<C extends React.ElementType> = {
8
17
  as?: C
9
18
  }
10
19
 
20
+ /**
21
+ * @deprecated This type is deprecated. Use `PropsToOmit` from './ui.tsx' instead.
22
+ * The UI component provides better type safety and accessibility features.
23
+ */
11
24
  type PropsToOmit<C extends React.ElementType, P> = keyof (AsProp<C> & P)
12
25
 
26
+ /**
27
+ * @deprecated This type is deprecated. Use `PolymorphicComponentProp` from './ui.tsx' instead.
28
+ * The UI component provides better type safety and accessibility features.
29
+ */
13
30
  type PolymorphicComponentProp<
14
31
  C extends React.ElementType,
32
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
15
33
  Props = {},
16
34
  > = React.PropsWithChildren<Props & AsProp<C>> &
17
35
  Omit<React.ComponentPropsWithoutRef<C>, PropsToOmit<C, Props>>
18
36
 
37
+ /**
38
+ * @deprecated This type is deprecated. Use `PolymorphicComponentPropWithRef` from './ui.tsx' instead.
39
+ * The UI component provides better type safety and accessibility features.
40
+ */
19
41
  type PolymorphicComponentPropWithRef<
20
42
  C extends React.ElementType,
43
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
21
44
  Props = {},
22
45
  > = PolymorphicComponentProp<C, Props> & {
23
- ref?: PolymorphicRef<C>
46
+ ref?: PolymorphicRef<C> | React.ForwardedRef<React.ElementRef<C>>
24
47
  }
25
48
 
49
+ /**
50
+ * @deprecated This type is deprecated. Use `UIProps` from './ui.tsx' instead.
51
+ * The UI component provides better type safety and accessibility features.
52
+ */
26
53
  type FPProps<C extends React.ElementType> = PolymorphicComponentPropWithRef<
27
54
  C,
28
55
  {
@@ -32,21 +59,62 @@ type FPProps<C extends React.ElementType> = PolymorphicComponentPropWithRef<
32
59
  }
33
60
  >
34
61
 
35
- /*
62
+ /**
36
63
  * FPComponent type definition
37
64
  *
38
- * Defines the component function signature for the FP component.
65
+ * @deprecated This type is deprecated. Use the `UI` component from './ui.tsx' instead.
66
+ * The UI component provides enhanced accessibility documentation, better type safety,
67
+ * and comprehensive WCAG 2.1 AA compliance guidance.
39
68
  *
40
69
  * @typeParam C - The HTML element type to render
41
70
  * @param props - The component props
42
71
  * @returns React component
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * // Migration from FP to UI
76
+ * // Before:
77
+ * import FP from '@fpkit/acss/components/fp';
78
+ * <FP as="button" styles={{ padding: '1rem' }}>Click me</FP>
79
+ *
80
+ * // After:
81
+ * import UI from '@fpkit/acss/components/ui';
82
+ * <UI as="button" styles={{ padding: '1rem' }}>Click me</UI>
83
+ * ```
43
84
  */
44
- type FPComponent = <C extends React.ElementType = 'span'>(
45
- props: FPProps<C>,
46
- ) => React.ReactElement | any
85
+ type FPComponent = {
86
+ <C extends React.ElementType = 'span'>(
87
+ props: FPProps<C>,
88
+ ): React.ReactElement | null
89
+ displayName?: string
90
+ }
47
91
 
48
92
  /**
49
- * FP component is a polymorphic component that renders an HTML element with optional styles.
93
+ * @deprecated **DEPRECATED:** This component is deprecated and will be removed in a future version.
94
+ * Please use the `UI` component from `./ui.tsx` instead.
95
+ *
96
+ * The UI component is a drop-in replacement with the same API but provides:
97
+ * - Enhanced accessibility documentation and WCAG 2.1 AA compliance guidance
98
+ * - Better TypeScript type safety with detailed JSDoc comments
99
+ * - Comprehensive examples for accessible component patterns
100
+ * - More robust style merging with defaultStyles support
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * // Migration Guide
105
+ * // Before:
106
+ * import FP from '@fpkit/acss/components/fp';
107
+ * <FP as="button" styles={{ padding: '1rem' }} classes="btn">
108
+ * Click me
109
+ * </FP>
110
+ *
111
+ * // After:
112
+ * import UI from '@fpkit/acss/components/ui';
113
+ * <UI as="button" styles={{ padding: '1rem' }} classes="btn">
114
+ * Click me
115
+ * </UI>
116
+ * ```
117
+ *
50
118
  * @param {Object} props - Component props
51
119
  * @param {React.ElementType} props.as - The HTML element to render. Defaults to 'div'.
52
120
  * @param {boolean} props.renderStyles - Whether to render styles or not. Defaults to true.
@@ -55,7 +123,7 @@ type FPComponent = <C extends React.ElementType = 'span'>(
55
123
  * @param {React.ReactNode} props.children - The children to render inside the component.
56
124
  * @returns {React.ReactElement} - A React component that renders an HTML element with optional styles.
57
125
  */
58
- const FP: FPComponent = React.forwardRef(
126
+ const FP = React.forwardRef(
59
127
  <C extends React.ElementType>(
60
128
  { as, styles, classes, children, defaultStyles, ...props }: FPProps<C>,
61
129
  ref?: PolymorphicRef<C>,
@@ -70,7 +138,14 @@ const FP: FPComponent = React.forwardRef(
70
138
  </Component>
71
139
  )
72
140
  },
73
- )
141
+ ) as FPComponent
142
+
143
+ FP.displayName = 'FP'
144
+
145
+ /**
146
+ * @deprecated This interface is deprecated. Use the `UI` component from './ui.tsx' instead.
147
+ * The UI component provides better type safety and accessibility features.
148
+ */
74
149
  export interface BoxProps extends ComponentProps {
75
150
  renderStyles: true
76
151
  }