@cdx-ui/primitives 0.0.1-alpha.9 → 0.0.1-beta.2

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 (478) hide show
  1. package/README.md +35 -0
  2. package/lib/commonjs/avatar/context.js +11 -0
  3. package/lib/commonjs/avatar/context.js.map +1 -0
  4. package/lib/commonjs/avatar/createAvatarBadge.js +20 -0
  5. package/lib/commonjs/avatar/createAvatarBadge.js.map +1 -0
  6. package/lib/commonjs/avatar/createAvatarIcon.js +30 -0
  7. package/lib/commonjs/avatar/createAvatarIcon.js.map +1 -0
  8. package/lib/commonjs/avatar/createAvatarImage.js +51 -0
  9. package/lib/commonjs/avatar/createAvatarImage.js.map +1 -0
  10. package/lib/commonjs/avatar/createAvatarRoot.js +34 -0
  11. package/lib/commonjs/avatar/createAvatarRoot.js.map +1 -0
  12. package/lib/commonjs/avatar/createAvatarText.js +42 -0
  13. package/lib/commonjs/avatar/createAvatarText.js.map +1 -0
  14. package/lib/commonjs/avatar/index.js +30 -0
  15. package/lib/commonjs/avatar/index.js.map +1 -0
  16. package/lib/commonjs/avatar/types.js +6 -0
  17. package/lib/commonjs/avatar/types.js.map +1 -0
  18. package/lib/commonjs/button/index.js +25 -19
  19. package/lib/commonjs/button/index.js.map +1 -1
  20. package/lib/commonjs/checkbox/createCheckboxIcon.js +3 -2
  21. package/lib/commonjs/checkbox/createCheckboxIcon.js.map +1 -1
  22. package/lib/commonjs/checkbox/createCheckboxRoot.web.js +2 -0
  23. package/lib/commonjs/checkbox/createCheckboxRoot.web.js.map +1 -1
  24. package/lib/commonjs/checkbox/index.js +19 -21
  25. package/lib/commonjs/checkbox/index.js.map +1 -1
  26. package/lib/commonjs/dialog/context.js +11 -0
  27. package/lib/commonjs/dialog/context.js.map +1 -0
  28. package/lib/commonjs/dialog/createDialogBody.js +21 -0
  29. package/lib/commonjs/dialog/createDialogBody.js.map +1 -0
  30. package/lib/commonjs/dialog/createDialogClose.js +37 -0
  31. package/lib/commonjs/dialog/createDialogClose.js.map +1 -0
  32. package/lib/commonjs/dialog/createDialogContent.js +141 -0
  33. package/lib/commonjs/dialog/createDialogContent.js.map +1 -0
  34. package/lib/commonjs/dialog/createDialogDescription.js +30 -0
  35. package/lib/commonjs/dialog/createDialogDescription.js.map +1 -0
  36. package/lib/commonjs/dialog/createDialogFooter.js +21 -0
  37. package/lib/commonjs/dialog/createDialogFooter.js.map +1 -0
  38. package/lib/commonjs/dialog/createDialogHeader.js +21 -0
  39. package/lib/commonjs/dialog/createDialogHeader.js.map +1 -0
  40. package/lib/commonjs/dialog/createDialogRoot.js +54 -0
  41. package/lib/commonjs/dialog/createDialogRoot.js.map +1 -0
  42. package/lib/commonjs/dialog/createDialogTitle.js +21 -0
  43. package/lib/commonjs/dialog/createDialogTitle.js.map +1 -0
  44. package/lib/commonjs/dialog/createDialogTrigger.js +37 -0
  45. package/lib/commonjs/dialog/createDialogTrigger.js.map +1 -0
  46. package/lib/commonjs/dialog/index.js +60 -0
  47. package/lib/commonjs/dialog/index.js.map +1 -0
  48. package/lib/commonjs/dialog/types.js +6 -0
  49. package/lib/commonjs/dialog/types.js.map +1 -0
  50. package/lib/commonjs/field/createFieldError.js +41 -0
  51. package/lib/commonjs/field/createFieldError.js.map +1 -0
  52. package/lib/commonjs/field/createFieldErrorIcon.js +18 -0
  53. package/lib/commonjs/field/createFieldErrorIcon.js.map +1 -0
  54. package/lib/commonjs/field/createFieldErrorText.js +18 -0
  55. package/lib/commonjs/field/createFieldErrorText.js.map +1 -0
  56. package/lib/commonjs/field/createFieldHelper.js +41 -0
  57. package/lib/commonjs/field/createFieldHelper.js.map +1 -0
  58. package/lib/commonjs/field/createFieldHelperText.js +18 -0
  59. package/lib/commonjs/field/createFieldHelperText.js.map +1 -0
  60. package/lib/commonjs/field/createFieldLabel.js +36 -0
  61. package/lib/commonjs/field/createFieldLabel.js.map +1 -0
  62. package/lib/commonjs/field/createFieldRoot.js +35 -0
  63. package/lib/commonjs/field/createFieldRoot.js.map +1 -0
  64. package/lib/commonjs/field/index.js +46 -0
  65. package/lib/commonjs/field/index.js.map +1 -0
  66. package/lib/commonjs/field/types.js +6 -0
  67. package/lib/commonjs/field/types.js.map +1 -0
  68. package/lib/commonjs/form/createFormRoot.js +21 -0
  69. package/lib/commonjs/form/createFormRoot.js.map +1 -0
  70. package/lib/commonjs/form/index.js +15 -0
  71. package/lib/commonjs/form/index.js.map +1 -0
  72. package/lib/commonjs/form/types.js +6 -0
  73. package/lib/commonjs/form/types.js.map +1 -0
  74. package/lib/commonjs/index.js +93 -1
  75. package/lib/commonjs/index.js.map +1 -1
  76. package/lib/commonjs/input/createInputField.js +7 -2
  77. package/lib/commonjs/input/createInputField.js.map +1 -1
  78. package/lib/commonjs/input/index.js +13 -19
  79. package/lib/commonjs/input/index.js.map +1 -1
  80. package/lib/commonjs/link/LinkProvider.js +28 -0
  81. package/lib/commonjs/link/LinkProvider.js.map +1 -0
  82. package/lib/commonjs/link/createLink.js +74 -0
  83. package/lib/commonjs/link/createLink.js.map +1 -0
  84. package/lib/commonjs/link/index.js +27 -0
  85. package/lib/commonjs/link/index.js.map +1 -0
  86. package/lib/commonjs/link/types.js +6 -0
  87. package/lib/commonjs/link/types.js.map +1 -0
  88. package/lib/commonjs/link/useLink.js +56 -0
  89. package/lib/commonjs/link/useLink.js.map +1 -0
  90. package/lib/commonjs/otp-input/context.js +14 -0
  91. package/lib/commonjs/otp-input/context.js.map +1 -0
  92. package/lib/commonjs/otp-input/createOtpInputCell.js +29 -0
  93. package/lib/commonjs/otp-input/createOtpInputCell.js.map +1 -0
  94. package/lib/commonjs/otp-input/createOtpInputField.js +104 -0
  95. package/lib/commonjs/otp-input/createOtpInputField.js.map +1 -0
  96. package/lib/commonjs/otp-input/createOtpInputRoot.js +136 -0
  97. package/lib/commonjs/otp-input/createOtpInputRoot.js.map +1 -0
  98. package/lib/commonjs/otp-input/index.js +48 -0
  99. package/lib/commonjs/otp-input/index.js.map +1 -0
  100. package/lib/commonjs/otp-input/types.js +6 -0
  101. package/lib/commonjs/otp-input/types.js.map +1 -0
  102. package/lib/commonjs/otp-input/utils/applyValueChange.js +73 -0
  103. package/lib/commonjs/otp-input/utils/applyValueChange.js.map +1 -0
  104. package/lib/commonjs/otp-input/utils/filterValue.js +46 -0
  105. package/lib/commonjs/otp-input/utils/filterValue.js.map +1 -0
  106. package/lib/commonjs/overlay/OverlayContainer.js +8 -11
  107. package/lib/commonjs/overlay/OverlayContainer.js.map +1 -1
  108. package/lib/commonjs/overlay/index.js +7 -0
  109. package/lib/commonjs/overlay/index.js.map +1 -1
  110. package/lib/commonjs/overlay/useEscapeKey.js +14 -0
  111. package/lib/commonjs/overlay/useEscapeKey.js.map +1 -0
  112. package/lib/commonjs/overlay/useEscapeKey.web.js +30 -0
  113. package/lib/commonjs/overlay/useEscapeKey.web.js.map +1 -0
  114. package/lib/commonjs/progress/context.js +11 -0
  115. package/lib/commonjs/progress/context.js.map +1 -0
  116. package/lib/commonjs/progress/createProgressIndicator.js +42 -0
  117. package/lib/commonjs/progress/createProgressIndicator.js.map +1 -0
  118. package/lib/commonjs/progress/createProgressRoot.js +96 -0
  119. package/lib/commonjs/progress/createProgressRoot.js.map +1 -0
  120. package/lib/commonjs/progress/index.js +25 -0
  121. package/lib/commonjs/progress/index.js.map +1 -0
  122. package/lib/commonjs/progress/types.js +6 -0
  123. package/lib/commonjs/progress/types.js.map +1 -0
  124. package/lib/commonjs/select/context.js +8 -43
  125. package/lib/commonjs/select/context.js.map +1 -1
  126. package/lib/commonjs/select/createSelectItem.js +1 -1
  127. package/lib/commonjs/select/createSelectItem.js.map +1 -1
  128. package/lib/commonjs/select/createSelectRoot.js +9 -6
  129. package/lib/commonjs/select/createSelectRoot.js.map +1 -1
  130. package/lib/commonjs/select/createSelectTrigger.js +53 -12
  131. package/lib/commonjs/select/createSelectTrigger.js.map +1 -1
  132. package/lib/commonjs/utils/createPortal.js +23 -0
  133. package/lib/commonjs/utils/createPortal.js.map +1 -0
  134. package/lib/commonjs/utils/dataAttributes.web.js +1 -4
  135. package/lib/commonjs/utils/dataAttributes.web.js.map +1 -1
  136. package/lib/module/avatar/context.js +5 -0
  137. package/lib/module/avatar/context.js.map +1 -0
  138. package/lib/module/{input/createInputIcon.js → avatar/createAvatarBadge.js} +3 -3
  139. package/lib/module/avatar/createAvatarBadge.js.map +1 -0
  140. package/lib/module/avatar/createAvatarIcon.js +25 -0
  141. package/lib/module/avatar/createAvatarIcon.js.map +1 -0
  142. package/lib/module/avatar/createAvatarImage.js +46 -0
  143. package/lib/module/avatar/createAvatarImage.js.map +1 -0
  144. package/lib/module/avatar/createAvatarRoot.js +29 -0
  145. package/lib/module/avatar/createAvatarRoot.js.map +1 -0
  146. package/lib/module/avatar/createAvatarText.js +37 -0
  147. package/lib/module/avatar/createAvatarText.js.map +1 -0
  148. package/lib/module/avatar/index.js +26 -0
  149. package/lib/module/avatar/index.js.map +1 -0
  150. package/lib/module/avatar/types.js +4 -0
  151. package/lib/module/avatar/types.js.map +1 -0
  152. package/lib/module/button/index.js +19 -19
  153. package/lib/module/button/index.js.map +1 -1
  154. package/lib/module/checkbox/createCheckboxIcon.js +3 -2
  155. package/lib/module/checkbox/createCheckboxIcon.js.map +1 -1
  156. package/lib/module/checkbox/createCheckboxRoot.web.js +2 -0
  157. package/lib/module/checkbox/createCheckboxRoot.web.js.map +1 -1
  158. package/lib/module/checkbox/index.js +18 -19
  159. package/lib/module/checkbox/index.js.map +1 -1
  160. package/lib/module/dialog/context.js +5 -0
  161. package/lib/module/dialog/context.js.map +1 -0
  162. package/lib/module/dialog/createDialogBody.js +15 -0
  163. package/lib/module/dialog/createDialogBody.js.map +1 -0
  164. package/lib/module/dialog/createDialogClose.js +31 -0
  165. package/lib/module/dialog/createDialogClose.js.map +1 -0
  166. package/lib/module/dialog/createDialogContent.js +136 -0
  167. package/lib/module/dialog/createDialogContent.js.map +1 -0
  168. package/lib/module/dialog/createDialogDescription.js +24 -0
  169. package/lib/module/dialog/createDialogDescription.js.map +1 -0
  170. package/lib/module/dialog/createDialogFooter.js +15 -0
  171. package/lib/module/dialog/createDialogFooter.js.map +1 -0
  172. package/lib/module/dialog/createDialogHeader.js +15 -0
  173. package/lib/module/dialog/createDialogHeader.js.map +1 -0
  174. package/lib/module/dialog/createDialogRoot.js +49 -0
  175. package/lib/module/dialog/createDialogRoot.js.map +1 -0
  176. package/lib/module/dialog/createDialogTitle.js +15 -0
  177. package/lib/module/dialog/createDialogTitle.js.map +1 -0
  178. package/lib/module/dialog/createDialogTrigger.js +31 -0
  179. package/lib/module/dialog/createDialogTrigger.js.map +1 -0
  180. package/lib/module/dialog/index.js +45 -0
  181. package/lib/module/dialog/index.js.map +1 -0
  182. package/lib/module/dialog/types.js +4 -0
  183. package/lib/module/dialog/types.js.map +1 -0
  184. package/lib/module/field/createFieldError.js +35 -0
  185. package/lib/module/field/createFieldError.js.map +1 -0
  186. package/lib/module/field/createFieldErrorIcon.js +13 -0
  187. package/lib/module/field/createFieldErrorIcon.js.map +1 -0
  188. package/lib/module/field/createFieldErrorText.js +13 -0
  189. package/lib/module/field/createFieldErrorText.js.map +1 -0
  190. package/lib/module/field/createFieldHelper.js +35 -0
  191. package/lib/module/field/createFieldHelper.js.map +1 -0
  192. package/lib/module/field/createFieldHelperText.js +13 -0
  193. package/lib/module/field/createFieldHelperText.js.map +1 -0
  194. package/lib/module/field/createFieldLabel.js +31 -0
  195. package/lib/module/field/createFieldLabel.js.map +1 -0
  196. package/lib/module/field/createFieldRoot.js +29 -0
  197. package/lib/module/field/createFieldRoot.js.map +1 -0
  198. package/lib/module/field/index.js +42 -0
  199. package/lib/module/field/index.js.map +1 -0
  200. package/lib/module/field/types.js +4 -0
  201. package/lib/module/field/types.js.map +1 -0
  202. package/lib/module/form/createFormRoot.js +15 -0
  203. package/lib/module/form/createFormRoot.js.map +1 -0
  204. package/lib/module/form/index.js +11 -0
  205. package/lib/module/form/index.js.map +1 -0
  206. package/lib/module/form/types.js +4 -0
  207. package/lib/module/form/types.js.map +1 -0
  208. package/lib/module/index.js +8 -0
  209. package/lib/module/index.js.map +1 -1
  210. package/lib/module/input/createInputField.js +8 -3
  211. package/lib/module/input/createInputField.js.map +1 -1
  212. package/lib/module/input/index.js +12 -17
  213. package/lib/module/input/index.js.map +1 -1
  214. package/lib/module/link/LinkProvider.js +23 -0
  215. package/lib/module/link/LinkProvider.js.map +1 -0
  216. package/lib/module/link/createLink.js +68 -0
  217. package/lib/module/link/createLink.js.map +1 -0
  218. package/lib/module/link/index.js +6 -0
  219. package/lib/module/link/index.js.map +1 -0
  220. package/lib/module/link/types.js +4 -0
  221. package/lib/module/link/types.js.map +1 -0
  222. package/lib/module/link/useLink.js +52 -0
  223. package/lib/module/link/useLink.js.map +1 -0
  224. package/lib/module/otp-input/context.js +6 -0
  225. package/lib/module/otp-input/context.js.map +1 -0
  226. package/lib/module/otp-input/createOtpInputCell.js +24 -0
  227. package/lib/module/otp-input/createOtpInputCell.js.map +1 -0
  228. package/lib/module/otp-input/createOtpInputField.js +99 -0
  229. package/lib/module/otp-input/createOtpInputField.js.map +1 -0
  230. package/lib/module/otp-input/createOtpInputRoot.js +131 -0
  231. package/lib/module/otp-input/createOtpInputRoot.js.map +1 -0
  232. package/lib/module/otp-input/index.js +20 -0
  233. package/lib/module/otp-input/index.js.map +1 -0
  234. package/lib/module/otp-input/types.js +4 -0
  235. package/lib/module/otp-input/types.js.map +1 -0
  236. package/lib/module/otp-input/utils/applyValueChange.js +69 -0
  237. package/lib/module/otp-input/utils/applyValueChange.js.map +1 -0
  238. package/lib/module/otp-input/utils/filterValue.js +40 -0
  239. package/lib/module/otp-input/utils/filterValue.js.map +1 -0
  240. package/lib/module/overlay/OverlayContainer.js +8 -11
  241. package/lib/module/overlay/OverlayContainer.js.map +1 -1
  242. package/lib/module/overlay/index.js +1 -0
  243. package/lib/module/overlay/index.js.map +1 -1
  244. package/lib/module/overlay/useEscapeKey.js +10 -0
  245. package/lib/module/overlay/useEscapeKey.js.map +1 -0
  246. package/lib/module/overlay/useEscapeKey.web.js +27 -0
  247. package/lib/module/overlay/useEscapeKey.web.js.map +1 -0
  248. package/lib/module/progress/context.js +5 -0
  249. package/lib/module/progress/context.js.map +1 -0
  250. package/lib/module/progress/createProgressIndicator.js +37 -0
  251. package/lib/module/progress/createProgressIndicator.js.map +1 -0
  252. package/lib/module/progress/createProgressRoot.js +91 -0
  253. package/lib/module/progress/createProgressRoot.js.map +1 -0
  254. package/lib/module/progress/index.js +15 -0
  255. package/lib/module/progress/index.js.map +1 -0
  256. package/lib/module/progress/types.js +4 -0
  257. package/lib/module/progress/types.js.map +1 -0
  258. package/lib/module/select/context.js +4 -42
  259. package/lib/module/select/context.js.map +1 -1
  260. package/lib/module/select/createSelectItem.js +2 -2
  261. package/lib/module/select/createSelectItem.js.map +1 -1
  262. package/lib/module/select/createSelectRoot.js +10 -7
  263. package/lib/module/select/createSelectRoot.js.map +1 -1
  264. package/lib/module/select/createSelectTrigger.js +56 -15
  265. package/lib/module/select/createSelectTrigger.js.map +1 -1
  266. package/lib/module/utils/createPortal.js +19 -0
  267. package/lib/module/utils/createPortal.js.map +1 -0
  268. package/lib/module/utils/dataAttributes.web.js +1 -4
  269. package/lib/module/utils/dataAttributes.web.js.map +1 -1
  270. package/lib/typescript/avatar/context.d.ts +6 -0
  271. package/lib/typescript/avatar/context.d.ts.map +1 -0
  272. package/lib/typescript/avatar/createAvatarBadge.d.ts +4 -0
  273. package/lib/typescript/avatar/createAvatarBadge.d.ts.map +1 -0
  274. package/lib/typescript/avatar/createAvatarIcon.d.ts +4 -0
  275. package/lib/typescript/avatar/createAvatarIcon.d.ts.map +1 -0
  276. package/lib/typescript/avatar/createAvatarImage.d.ts +4 -0
  277. package/lib/typescript/avatar/createAvatarImage.d.ts.map +1 -0
  278. package/lib/typescript/avatar/createAvatarRoot.d.ts +4 -0
  279. package/lib/typescript/avatar/createAvatarRoot.d.ts.map +1 -0
  280. package/lib/typescript/avatar/createAvatarText.d.ts +4 -0
  281. package/lib/typescript/avatar/createAvatarText.d.ts.map +1 -0
  282. package/lib/typescript/avatar/index.d.ts +11 -0
  283. package/lib/typescript/avatar/index.d.ts.map +1 -0
  284. package/lib/typescript/avatar/types.d.ts +33 -0
  285. package/lib/typescript/avatar/types.d.ts.map +1 -0
  286. package/lib/typescript/button/index.d.ts +2 -1
  287. package/lib/typescript/button/index.d.ts.map +1 -1
  288. package/lib/typescript/checkbox/context.d.ts +2 -2
  289. package/lib/typescript/checkbox/createCheckboxRoot.web.d.ts.map +1 -1
  290. package/lib/typescript/checkbox/index.d.ts +3 -2
  291. package/lib/typescript/checkbox/index.d.ts.map +1 -1
  292. package/lib/typescript/checkbox/useCheckboxRoot.d.ts +8 -3
  293. package/lib/typescript/checkbox/useCheckboxRoot.d.ts.map +1 -1
  294. package/lib/typescript/dialog/context.d.ts +6 -0
  295. package/lib/typescript/dialog/context.d.ts.map +1 -0
  296. package/lib/typescript/dialog/createDialogBody.d.ts +4 -0
  297. package/lib/typescript/dialog/createDialogBody.d.ts.map +1 -0
  298. package/lib/typescript/dialog/createDialogClose.d.ts +4 -0
  299. package/lib/typescript/dialog/createDialogClose.d.ts.map +1 -0
  300. package/lib/typescript/dialog/createDialogContent.d.ts +4 -0
  301. package/lib/typescript/dialog/createDialogContent.d.ts.map +1 -0
  302. package/lib/typescript/dialog/createDialogDescription.d.ts +4 -0
  303. package/lib/typescript/dialog/createDialogDescription.d.ts.map +1 -0
  304. package/lib/typescript/dialog/createDialogFooter.d.ts +4 -0
  305. package/lib/typescript/dialog/createDialogFooter.d.ts.map +1 -0
  306. package/lib/typescript/dialog/createDialogHeader.d.ts +4 -0
  307. package/lib/typescript/dialog/createDialogHeader.d.ts.map +1 -0
  308. package/lib/typescript/dialog/createDialogRoot.d.ts +4 -0
  309. package/lib/typescript/dialog/createDialogRoot.d.ts.map +1 -0
  310. package/lib/typescript/dialog/createDialogTitle.d.ts +4 -0
  311. package/lib/typescript/dialog/createDialogTitle.d.ts.map +1 -0
  312. package/lib/typescript/dialog/createDialogTrigger.d.ts +4 -0
  313. package/lib/typescript/dialog/createDialogTrigger.d.ts.map +1 -0
  314. package/lib/typescript/dialog/index.d.ts +18 -0
  315. package/lib/typescript/dialog/index.d.ts.map +1 -0
  316. package/lib/typescript/dialog/types.d.ts +52 -0
  317. package/lib/typescript/dialog/types.d.ts.map +1 -0
  318. package/lib/typescript/field/createFieldError.d.ts +5 -0
  319. package/lib/typescript/field/createFieldError.d.ts.map +1 -0
  320. package/lib/typescript/field/createFieldErrorIcon.d.ts +5 -0
  321. package/lib/typescript/field/createFieldErrorIcon.d.ts.map +1 -0
  322. package/lib/typescript/field/createFieldErrorText.d.ts +5 -0
  323. package/lib/typescript/field/createFieldErrorText.d.ts.map +1 -0
  324. package/lib/typescript/field/createFieldHelper.d.ts +5 -0
  325. package/lib/typescript/field/createFieldHelper.d.ts.map +1 -0
  326. package/lib/typescript/field/createFieldHelperText.d.ts +5 -0
  327. package/lib/typescript/field/createFieldHelperText.d.ts.map +1 -0
  328. package/lib/typescript/field/createFieldLabel.d.ts +6 -0
  329. package/lib/typescript/field/createFieldLabel.d.ts.map +1 -0
  330. package/lib/typescript/field/createFieldRoot.d.ts +6 -0
  331. package/lib/typescript/field/createFieldRoot.d.ts.map +1 -0
  332. package/lib/typescript/field/index.d.ts +13 -0
  333. package/lib/typescript/field/index.d.ts.map +1 -0
  334. package/lib/typescript/field/types.d.ts +63 -0
  335. package/lib/typescript/field/types.d.ts.map +1 -0
  336. package/lib/typescript/form/createFormRoot.d.ts +4 -0
  337. package/lib/typescript/form/createFormRoot.d.ts.map +1 -0
  338. package/lib/typescript/form/index.d.ts +6 -0
  339. package/lib/typescript/form/index.d.ts.map +1 -0
  340. package/lib/typescript/form/types.d.ts +14 -0
  341. package/lib/typescript/form/types.d.ts.map +1 -0
  342. package/lib/typescript/index.d.ts +8 -0
  343. package/lib/typescript/index.d.ts.map +1 -1
  344. package/lib/typescript/input/createInputField.d.ts.map +1 -1
  345. package/lib/typescript/input/index.d.ts +3 -3
  346. package/lib/typescript/input/index.d.ts.map +1 -1
  347. package/lib/typescript/input/types.d.ts +1 -2
  348. package/lib/typescript/input/types.d.ts.map +1 -1
  349. package/lib/typescript/link/LinkProvider.d.ts +36 -0
  350. package/lib/typescript/link/LinkProvider.d.ts.map +1 -0
  351. package/lib/typescript/link/createLink.d.ts +6 -0
  352. package/lib/typescript/link/createLink.d.ts.map +1 -0
  353. package/lib/typescript/link/index.d.ts +6 -0
  354. package/lib/typescript/link/index.d.ts.map +1 -0
  355. package/lib/typescript/link/types.d.ts +45 -0
  356. package/lib/typescript/link/types.d.ts.map +1 -0
  357. package/lib/typescript/link/useLink.d.ts +9 -0
  358. package/lib/typescript/link/useLink.d.ts.map +1 -0
  359. package/lib/typescript/otp-input/context.d.ts +10 -0
  360. package/lib/typescript/otp-input/context.d.ts.map +1 -0
  361. package/lib/typescript/otp-input/createOtpInputCell.d.ts +4 -0
  362. package/lib/typescript/otp-input/createOtpInputCell.d.ts.map +1 -0
  363. package/lib/typescript/otp-input/createOtpInputField.d.ts +4 -0
  364. package/lib/typescript/otp-input/createOtpInputField.d.ts.map +1 -0
  365. package/lib/typescript/otp-input/createOtpInputRoot.d.ts +4 -0
  366. package/lib/typescript/otp-input/createOtpInputRoot.d.ts.map +1 -0
  367. package/lib/typescript/otp-input/index.d.ts +11 -0
  368. package/lib/typescript/otp-input/index.d.ts.map +1 -0
  369. package/lib/typescript/otp-input/types.d.ts +75 -0
  370. package/lib/typescript/otp-input/types.d.ts.map +1 -0
  371. package/lib/typescript/otp-input/utils/applyValueChange.d.ts +10 -0
  372. package/lib/typescript/otp-input/utils/applyValueChange.d.ts.map +1 -0
  373. package/lib/typescript/otp-input/utils/filterValue.d.ts +7 -0
  374. package/lib/typescript/otp-input/utils/filterValue.d.ts.map +1 -0
  375. package/lib/typescript/overlay/OverlayContainer.d.ts +5 -1
  376. package/lib/typescript/overlay/OverlayContainer.d.ts.map +1 -1
  377. package/lib/typescript/overlay/index.d.ts +1 -0
  378. package/lib/typescript/overlay/index.d.ts.map +1 -1
  379. package/lib/typescript/overlay/useEscapeKey.d.ts +6 -0
  380. package/lib/typescript/overlay/useEscapeKey.d.ts.map +1 -0
  381. package/lib/typescript/overlay/useEscapeKey.web.d.ts +6 -0
  382. package/lib/typescript/overlay/useEscapeKey.web.d.ts.map +1 -0
  383. package/lib/typescript/progress/context.d.ts +13 -0
  384. package/lib/typescript/progress/context.d.ts.map +1 -0
  385. package/lib/typescript/progress/createProgressIndicator.d.ts +3 -0
  386. package/lib/typescript/progress/createProgressIndicator.d.ts.map +1 -0
  387. package/lib/typescript/progress/createProgressRoot.d.ts +4 -0
  388. package/lib/typescript/progress/createProgressRoot.d.ts.map +1 -0
  389. package/lib/typescript/progress/index.d.ts +10 -0
  390. package/lib/typescript/progress/index.d.ts.map +1 -0
  391. package/lib/typescript/progress/types.d.ts +25 -0
  392. package/lib/typescript/progress/types.d.ts.map +1 -0
  393. package/lib/typescript/select/context.d.ts +14 -7
  394. package/lib/typescript/select/context.d.ts.map +1 -1
  395. package/lib/typescript/select/createSelectRoot.d.ts.map +1 -1
  396. package/lib/typescript/select/createSelectTrigger.d.ts +2 -7
  397. package/lib/typescript/select/createSelectTrigger.d.ts.map +1 -1
  398. package/lib/typescript/select/types.d.ts +4 -1
  399. package/lib/typescript/select/types.d.ts.map +1 -1
  400. package/lib/typescript/utils/createPortal.d.ts +11 -0
  401. package/lib/typescript/utils/createPortal.d.ts.map +1 -0
  402. package/lib/typescript/utils/dataAttributes.web.d.ts.map +1 -1
  403. package/package.json +8 -3
  404. package/src/avatar/context.tsx +5 -0
  405. package/src/avatar/createAvatarBadge.tsx +12 -0
  406. package/src/avatar/createAvatarIcon.tsx +16 -0
  407. package/src/avatar/createAvatarImage.tsx +40 -0
  408. package/src/avatar/createAvatarRoot.tsx +23 -0
  409. package/src/avatar/createAvatarText.tsx +30 -0
  410. package/src/avatar/index.ts +43 -0
  411. package/src/avatar/types.ts +77 -0
  412. package/src/button/index.tsx +19 -19
  413. package/src/checkbox/createCheckboxIcon.tsx +2 -2
  414. package/src/checkbox/createCheckboxRoot.web.tsx +2 -0
  415. package/src/checkbox/index.ts +20 -20
  416. package/src/dialog/context.tsx +4 -0
  417. package/src/dialog/createDialogBody.tsx +11 -0
  418. package/src/dialog/createDialogClose.tsx +27 -0
  419. package/src/dialog/createDialogContent.tsx +122 -0
  420. package/src/dialog/createDialogDescription.tsx +20 -0
  421. package/src/dialog/createDialogFooter.tsx +11 -0
  422. package/src/dialog/createDialogHeader.tsx +11 -0
  423. package/src/dialog/createDialogRoot.tsx +66 -0
  424. package/src/dialog/createDialogTitle.tsx +11 -0
  425. package/src/dialog/createDialogTrigger.tsx +27 -0
  426. package/src/dialog/index.tsx +93 -0
  427. package/src/dialog/types.ts +88 -0
  428. package/src/field/createFieldError.tsx +32 -0
  429. package/src/field/createFieldErrorIcon.tsx +9 -0
  430. package/src/field/createFieldErrorText.tsx +9 -0
  431. package/src/field/createFieldHelper.tsx +28 -0
  432. package/src/field/createFieldHelperText.tsx +9 -0
  433. package/src/field/createFieldLabel.tsx +30 -0
  434. package/src/field/createFieldRoot.tsx +27 -0
  435. package/src/field/index.tsx +68 -0
  436. package/src/field/types.tsx +78 -0
  437. package/src/form/createFormRoot.tsx +13 -0
  438. package/src/form/index.tsx +12 -0
  439. package/src/form/types.tsx +16 -0
  440. package/src/index.ts +8 -0
  441. package/src/input/createInputField.tsx +13 -3
  442. package/src/input/index.tsx +15 -28
  443. package/src/input/types.ts +0 -4
  444. package/src/link/LinkProvider.tsx +50 -0
  445. package/src/link/createLink.tsx +71 -0
  446. package/src/link/index.tsx +5 -0
  447. package/src/link/types.ts +47 -0
  448. package/src/link/useLink.ts +54 -0
  449. package/src/otp-input/context.tsx +8 -0
  450. package/src/otp-input/createOtpInputCell.tsx +22 -0
  451. package/src/otp-input/createOtpInputField.tsx +98 -0
  452. package/src/otp-input/createOtpInputRoot.tsx +179 -0
  453. package/src/otp-input/index.tsx +34 -0
  454. package/src/otp-input/types.ts +92 -0
  455. package/src/otp-input/utils/applyValueChange.ts +56 -0
  456. package/src/otp-input/utils/filterValue.ts +37 -0
  457. package/src/overlay/OverlayContainer.tsx +9 -18
  458. package/src/overlay/index.ts +1 -0
  459. package/src/overlay/useEscapeKey.ts +7 -0
  460. package/src/overlay/useEscapeKey.web.ts +27 -0
  461. package/src/progress/context.tsx +13 -0
  462. package/src/progress/createProgressIndicator.tsx +35 -0
  463. package/src/progress/createProgressRoot.tsx +109 -0
  464. package/src/progress/index.ts +28 -0
  465. package/src/progress/types.ts +37 -0
  466. package/src/select/context.tsx +9 -44
  467. package/src/select/createSelectItem.tsx +3 -3
  468. package/src/select/createSelectRoot.tsx +10 -6
  469. package/src/select/createSelectTrigger.tsx +62 -36
  470. package/src/select/types.ts +4 -1
  471. package/src/utils/createPortal.ts +20 -0
  472. package/src/utils/dataAttributes.web.ts +2 -4
  473. package/lib/commonjs/input/createInputIcon.js +0 -20
  474. package/lib/commonjs/input/createInputIcon.js.map +0 -1
  475. package/lib/module/input/createInputIcon.js.map +0 -1
  476. package/lib/typescript/input/createInputIcon.d.ts +0 -4
  477. package/lib/typescript/input/createInputIcon.d.ts.map +0 -1
  478. package/src/input/createInputIcon.tsx +0 -12
@@ -0,0 +1,37 @@
1
+ /** Strip to digits (default OTP behavior). */
2
+ export function filterDigits(input: string): string {
3
+ return input.replace(/\D/g, '');
4
+ }
5
+
6
+ /** Keep only characters present in `allowed` (treat as a set of UTF-16 code units). */
7
+ export function filterAllowedCharacters(allowed: string) {
8
+ const allowedSet = new Set<string>();
9
+ for (let i = 0; i < allowed.length; i++) {
10
+ allowedSet.add(allowed.charAt(i));
11
+ }
12
+ return (input: string) => {
13
+ let out = '';
14
+ for (let i = 0; i < input.length; i++) {
15
+ const ch = input.charAt(i);
16
+ if (allowedSet.has(ch)) {
17
+ out += ch;
18
+ }
19
+ }
20
+ return out;
21
+ };
22
+ }
23
+
24
+ /** Keep only characters matching `re` (tested per UTF-16 code unit). */
25
+ export function filterByRegExp(re: RegExp) {
26
+ return (input: string) => {
27
+ let out = '';
28
+ for (let i = 0; i < input.length; i++) {
29
+ const ch = input.charAt(i);
30
+ re.lastIndex = 0;
31
+ if (re.test(ch)) {
32
+ out += ch;
33
+ }
34
+ }
35
+ return out;
36
+ };
37
+ }
@@ -3,20 +3,13 @@ import {
3
3
  Modal,
4
4
  Platform,
5
5
  Pressable,
6
- type StyleProp,
7
6
  StyleSheet,
7
+ View,
8
+ type StyleProp,
8
9
  type ViewStyle,
9
10
  } from 'react-native';
10
11
  import Animated, { type EntryOrExitLayoutType } from 'react-native-reanimated';
11
-
12
- let createPortalFn:
13
- | ((children: React.ReactNode, container: Element) => React.ReactPortal)
14
- | undefined;
15
- if (Platform.OS === 'web') {
16
- try {
17
- createPortalFn = require('react-dom').createPortal;
18
- } catch {}
19
- }
12
+ import { createPortalFn } from '../utils/createPortal';
20
13
 
21
14
  export interface OverlayContainerProps {
22
15
  onDismiss: () => void;
@@ -30,7 +23,11 @@ export interface OverlayContainerProps {
30
23
  * Cross-platform overlay container.
31
24
  *
32
25
  * - Web: renders children into a `createPortal` at `document.body` with
33
- * `position: fixed` and `zIndex: 50`.
26
+ * `position: fixed` and `zIndex: 50`. Uses a plain `View` rather than
27
+ * Reanimated's `Animated.View` because Reanimated's layout animations
28
+ * (`entering`/`exiting`) rely on `require()` calls that break silently
29
+ * in Vite production bundles, leaving elements stuck at opacity 0.
30
+ * See: https://github.com/software-mansion/react-native-reanimated/issues/6775
34
31
  * - Native: renders children inside a transparent `<Modal>` with a
35
32
  * backdrop `<Pressable>` that calls `onDismiss` on press.
36
33
  *
@@ -46,13 +43,7 @@ export function OverlayContainer({
46
43
  }: Readonly<OverlayContainerProps>) {
47
44
  if (Platform.OS === 'web' && createPortalFn) {
48
45
  return createPortalFn(
49
- <Animated.View
50
- entering={entering}
51
- exiting={exiting}
52
- style={[{ position: 'fixed' as any, zIndex: 50 }, style]}
53
- >
54
- {children}
55
- </Animated.View>,
46
+ <View style={[{ position: 'fixed' as any, zIndex: 50 }, style]}>{children}</View>,
56
47
  document.body,
57
48
  );
58
49
  }
@@ -2,6 +2,7 @@ export { OverlayContainer } from './OverlayContainer';
2
2
  export type { OverlayContainerProps } from './OverlayContainer';
3
3
  export { useAnchorPosition, type AnchorLayout } from './useAnchorPosition';
4
4
  export { useDismissOverlay } from './useDismissOverlay';
5
+ export { useEscapeKey } from './useEscapeKey';
5
6
  export {
6
7
  useOverlayPosition,
7
8
  type OverlayPosition,
@@ -0,0 +1,7 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+
3
+ /**
4
+ * No-op on native — Escape key dismissal is not applicable.
5
+ * Native uses the system back gesture / hardware button via Modal.
6
+ */
7
+ export function useEscapeKey(_open: boolean, _onEscape: () => void) {}
@@ -0,0 +1,27 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ /**
4
+ * Closes an overlay when the user presses the Escape key.
5
+ * Web-only — native platforms use Modal's `onRequestClose` for back/dismiss.
6
+ */
7
+ export function useEscapeKey(open: boolean, onEscape: () => void) {
8
+ const onEscapeRef = useRef(onEscape);
9
+ onEscapeRef.current = onEscape;
10
+
11
+ useEffect(() => {
12
+ if (!open) {
13
+ return;
14
+ }
15
+
16
+ const handleKeyDown = (e: KeyboardEvent) => {
17
+ if (e.key === 'Escape') {
18
+ onEscapeRef.current();
19
+ }
20
+ };
21
+
22
+ document.addEventListener('keydown', handleKeyDown);
23
+ return () => {
24
+ document.removeEventListener('keydown', handleKeyDown);
25
+ };
26
+ }, [open]);
27
+ }
@@ -0,0 +1,13 @@
1
+ import { createContext } from '@cdx-ui/utils';
2
+ import type { ProgressDataState } from './types';
3
+
4
+ export interface ProgressContextValue {
5
+ /** Clamped value in [0, max], or null when indeterminate */
6
+ readonly value: number | null;
7
+ readonly max: number;
8
+ readonly percent: number;
9
+ readonly state: ProgressDataState;
10
+ }
11
+
12
+ export const [ProgressProvider, useProgressContext] =
13
+ createContext<ProgressContextValue>('ProgressContext');
@@ -0,0 +1,35 @@
1
+ import type React from 'react';
2
+ import { forwardRef, useMemo, type PropsWithoutRef } from 'react';
3
+ import type { ViewStyle } from 'react-native';
4
+ import { dataAttributes } from '../utils/dataAttributes';
5
+ import { useProgressContext } from './context';
6
+
7
+ type PercentString = `${number}%`;
8
+
9
+ export const createProgressIndicator = <T, R = unknown>(BaseIndicator: React.ComponentType<T>) =>
10
+ forwardRef<R, PropsWithoutRef<T>>((props, ref) => {
11
+ const { style, ...rest } = props as PropsWithoutRef<T> & { style?: object };
12
+ const { percent, state, max, value } = useProgressContext();
13
+
14
+ const filledStyle = useMemo((): ViewStyle => {
15
+ const pct = `${String(percent)}%` as PercentString;
16
+ return { width: pct, height: '100%' };
17
+ }, [percent]);
18
+
19
+ const dataAttrs = dataAttributes({
20
+ state,
21
+ value: value === null ? undefined : String(value),
22
+ max: String(max),
23
+ });
24
+
25
+ return (
26
+ <BaseIndicator
27
+ ref={ref as React.Ref<R>}
28
+ {...({
29
+ ...rest,
30
+ ...dataAttrs,
31
+ style: [filledStyle, style],
32
+ } as T)}
33
+ />
34
+ );
35
+ });
@@ -0,0 +1,109 @@
1
+ import type React from 'react';
2
+ import { forwardRef, useMemo, type PropsWithoutRef } from 'react';
3
+ import { dataAttributes } from '../utils/dataAttributes';
4
+ import { ProgressProvider } from './context';
5
+ import type { InterfaceProgressProps, ProgressDataState } from './types';
6
+
7
+ function clamp(n: number, min: number, max: number): number {
8
+ return Math.min(max, Math.max(min, n));
9
+ }
10
+
11
+ function resolveState(
12
+ value: number | null,
13
+ max: number,
14
+ clamped: number | null,
15
+ ): ProgressDataState {
16
+ if (value === null) {
17
+ return 'indeterminate';
18
+ }
19
+ if (max <= 0) {
20
+ return 'complete';
21
+ }
22
+ if (clamped !== null && clamped >= max) {
23
+ return 'complete';
24
+ }
25
+ return 'loading';
26
+ }
27
+
28
+ function defaultGetValueLabel(value: number, max: number): string {
29
+ if (max <= 0) {
30
+ return '0%';
31
+ }
32
+ return `${String(Math.round((value / max) * 100))}%`;
33
+ }
34
+
35
+ export const createProgressRoot = <T, R = unknown>(BaseRoot: React.ComponentType<T>) =>
36
+ forwardRef<R, PropsWithoutRef<T> & InterfaceProgressProps>((props, ref) => {
37
+ const {
38
+ value: valueProp = 0,
39
+ max: maxProp = 100,
40
+ getValueLabel = defaultGetValueLabel,
41
+ children,
42
+ accessibilityRole = 'progressbar',
43
+ accessibilityValue: accessibilityValueProp,
44
+ role = 'progressbar',
45
+ ...restProps
46
+ } = props;
47
+ const max = maxProp > 0 ? maxProp : 0;
48
+ const isIndeterminate = valueProp === null;
49
+ const clampedValue =
50
+ valueProp === null ? null : clamp(Number.isFinite(valueProp) ? valueProp : 0, 0, max);
51
+
52
+ const percent = useMemo(() => {
53
+ if (clampedValue === null || max <= 0) {
54
+ return 0;
55
+ }
56
+ return (clampedValue / max) * 100;
57
+ }, [clampedValue, max]);
58
+
59
+ const state = useMemo(
60
+ () => resolveState(valueProp, max, clampedValue),
61
+ [valueProp, max, clampedValue],
62
+ );
63
+
64
+ const contextValue = useMemo(
65
+ () => ({
66
+ value: clampedValue,
67
+ max,
68
+ percent,
69
+ state,
70
+ }),
71
+ [clampedValue, max, percent, state],
72
+ );
73
+
74
+ const dataAttrs = dataAttributes({
75
+ state,
76
+ value: clampedValue === null ? undefined : String(clampedValue),
77
+ max: String(max),
78
+ });
79
+
80
+ const accessibilityValue = useMemo(() => {
81
+ if (accessibilityValueProp !== undefined) {
82
+ return accessibilityValueProp;
83
+ }
84
+ if (isIndeterminate || clampedValue === null) {
85
+ return { min: 0, max, text: 'Indeterminate' };
86
+ }
87
+ return {
88
+ min: 0,
89
+ max,
90
+ now: clampedValue,
91
+ text: getValueLabel(clampedValue, max),
92
+ };
93
+ }, [accessibilityValueProp, isIndeterminate, clampedValue, max, getValueLabel]);
94
+
95
+ return (
96
+ <ProgressProvider value={contextValue}>
97
+ <BaseRoot
98
+ ref={ref as React.Ref<R>}
99
+ {...(restProps as T)}
100
+ role={role}
101
+ accessibilityRole={accessibilityRole}
102
+ accessibilityValue={accessibilityValue}
103
+ {...dataAttrs}
104
+ >
105
+ {children}
106
+ </BaseRoot>
107
+ </ProgressProvider>
108
+ );
109
+ });
@@ -0,0 +1,28 @@
1
+ import type React from 'react';
2
+ import { createProgressIndicator } from './createProgressIndicator';
3
+ import { createProgressRoot } from './createProgressRoot';
4
+ import type { IProgressComponentType } from './types';
5
+
6
+ export type { IProgressProps, IProgressComponentType, ProgressDataState } from './types';
7
+ export type { ProgressContextValue } from './context';
8
+ export { useProgressContext } from './context';
9
+
10
+ export function createProgress<
11
+ RootProps,
12
+ IndicatorProps,
13
+ RootRef = unknown,
14
+ IndicatorRef = unknown,
15
+ >(components: {
16
+ Root: React.ComponentType<RootProps>;
17
+ Indicator: React.ComponentType<IndicatorProps>;
18
+ }) {
19
+ const Progress = createProgressRoot<RootProps, RootRef>(components.Root);
20
+ const Indicator = createProgressIndicator<IndicatorProps, IndicatorRef>(components.Indicator);
21
+
22
+ Progress.displayName = 'ProgressPrimitive';
23
+ Indicator.displayName = 'ProgressPrimitive.Indicator';
24
+
25
+ return Object.assign(Progress, {
26
+ Indicator,
27
+ }) as IProgressComponentType<RootProps, IndicatorProps, RootRef, IndicatorRef>;
28
+ }
@@ -0,0 +1,37 @@
1
+ import type { ForwardRefExoticComponent, PropsWithoutRef, ReactNode, RefAttributes } from 'react';
2
+ import type { ViewProps } from 'react-native';
3
+
4
+ export type ProgressDataState = 'complete' | 'indeterminate' | 'loading';
5
+
6
+ export interface InterfaceProgressProps extends Omit<ViewProps, 'children'> {
7
+ /**
8
+ * Current value in the range [0, max], or `null` for indeterminate progress.
9
+ * Omit or use a number for determinate progress; default is `0`.
10
+ */
11
+ readonly value?: number | null;
12
+ /**
13
+ * Maximum value (minimum is always 0).
14
+ * @default 100
15
+ */
16
+ readonly max?: number;
17
+ /**
18
+ * Optional label for `accessibilityValue.text` when determinate.
19
+ */
20
+ readonly getValueLabel?: (value: number, max: number) => string;
21
+ readonly children?: ReactNode;
22
+ }
23
+
24
+ export type IProgressComponentType<
25
+ RootProps,
26
+ IndicatorProps,
27
+ RootRef = unknown,
28
+ IndicatorRef = unknown,
29
+ > = ForwardRefExoticComponent<
30
+ PropsWithoutRef<RootProps & InterfaceProgressProps> & RefAttributes<RootRef>
31
+ > & {
32
+ Indicator: ForwardRefExoticComponent<
33
+ PropsWithoutRef<IndicatorProps> & RefAttributes<IndicatorRef>
34
+ >;
35
+ };
36
+
37
+ export type IProgressProps = InterfaceProgressProps;
@@ -1,56 +1,21 @@
1
- import { createContext, useContext } from 'react';
2
- import type { InteractionState, SelectContextValue, SelectItemInteractionState } from './types';
1
+ import { createContext } from '@cdx-ui/utils';
2
+ import type { InteractionState } from '../types';
3
+ import type { SelectContextValue, SelectItemInteractionState } from './types';
3
4
 
4
- const defaultContextValue: SelectContextValue = {
5
- open: false,
6
- items: [],
7
- setOpen: () => {},
8
- value: undefined,
9
- onValueChange: () => {},
10
- disabled: false,
11
- required: false,
12
- invalid: false,
13
- readOnly: false,
14
- native: false,
15
- triggerRef: { current: null },
16
- contentId: '',
17
- triggerId: '',
18
- activeValue: undefined,
19
- setActiveValue: () => {}, // TODO: Is this needed? At the very least it could be moved to SelectContent
20
- accessibilityLabel: undefined,
21
- };
22
-
23
- export const SelectContext = createContext<SelectContextValue>(defaultContextValue);
24
-
25
- export const useSelectContext = () => useContext(SelectContext);
5
+ export const [SelectProvider, useSelectContext] =
6
+ createContext<SelectContextValue>('SelectContext');
26
7
 
27
8
  /**
28
9
  * Propagates the trigger's interaction state (hover, focus, active, etc.) to
29
10
  * child components like SelectValue and SelectIcon so they can apply matching
30
11
  * data-attribute styles.
31
12
  */
32
- export const SelectTriggerContext = createContext<InteractionState>({
33
- hover: false,
34
- focus: false,
35
- active: false,
36
- disabled: false,
37
- focusVisible: false,
38
- });
39
-
40
- export const useSelectTriggerContext = () => useContext(SelectTriggerContext);
13
+ export const [SelectTriggerProvider, useSelectTriggerContext] =
14
+ createContext<InteractionState>('SelectTriggerContext');
41
15
 
42
16
  /**
43
17
  * Propagates the item's interaction and selection state (hover, focus, active,
44
18
  * highlighted, checked, etc.) to child components like SelectItemLabel.
45
19
  */
46
- export const SelectItemContext = createContext<SelectItemInteractionState>({
47
- hover: false,
48
- focus: false,
49
- active: false,
50
- disabled: false,
51
- focusVisible: false,
52
- highlighted: false,
53
- checked: false,
54
- });
55
-
56
- export const useSelectItemContext = () => useContext(SelectItemContext);
20
+ export const [SelectItemProvider, useSelectItemContext] =
21
+ createContext<SelectItemInteractionState>('SelectItemContext');
@@ -4,7 +4,7 @@ import { composeEventHandlers } from '@cdx-ui/utils';
4
4
  import { useFocus, useFocusRing } from '@react-native-aria/focus';
5
5
  import { useHover, usePress } from '@react-native-aria/interactions';
6
6
  import { dataAttributes } from '../utils/dataAttributes';
7
- import { SelectItemContext, useSelectContext } from './context';
7
+ import { SelectItemProvider, useSelectContext } from './context';
8
8
  import type { ISelectItemProps } from './types';
9
9
 
10
10
  export const createSelectItem = <T,>(BaseItem: React.ComponentType<T>) =>
@@ -74,7 +74,7 @@ export const createSelectItem = <T,>(BaseItem: React.ComponentType<T>) =>
74
74
  );
75
75
 
76
76
  return (
77
- <SelectItemContext.Provider value={interactionState}>
77
+ <SelectItemProvider value={interactionState}>
78
78
  <BaseItem
79
79
  ref={ref}
80
80
  role="option"
@@ -115,7 +115,7 @@ export const createSelectItem = <T,>(BaseItem: React.ComponentType<T>) =>
115
115
  >
116
116
  {children}
117
117
  </BaseItem>
118
- </SelectItemContext.Provider>
118
+ </SelectItemProvider>
119
119
  );
120
120
  },
121
121
  );
@@ -2,7 +2,7 @@ import type React from 'react';
2
2
  import { forwardRef, useCallback, useId, useMemo, useRef, useState } from 'react';
3
3
  import { useControllableState, useFormControl } from '@cdx-ui/utils';
4
4
  import { dataAttributes } from '../utils/dataAttributes';
5
- import { SelectContext } from './context';
5
+ import { SelectProvider } from './context';
6
6
  import type { ISelectProps } from './types';
7
7
 
8
8
  export const createSelectRoot = <T,>(BaseRoot: React.ComponentType<T>) =>
@@ -68,9 +68,11 @@ export const createSelectRoot = <T,>(BaseRoot: React.ComponentType<T>) =>
68
68
  const [activeValue, setActiveValue] = useState<string | undefined>(undefined);
69
69
 
70
70
  const triggerRef = useRef<any>(null);
71
- const id = useId();
72
- const triggerId = `select-trigger-${id}`;
73
- const contentId = `select-content-${id}`;
71
+ const reactId = useId();
72
+ /** Align with `useFormControl` default id (`${field.id}-input`) when inside `Form.Field`. */
73
+ const triggerId = formControlProps.id ?? `select-trigger-${reactId}`;
74
+ const contentId = `select-content-${reactId}`;
75
+ const ariaDescribedBy = formControlProps['aria-describedby'];
74
76
 
75
77
  const contextValue = useMemo(
76
78
  () => ({
@@ -90,6 +92,7 @@ export const createSelectRoot = <T,>(BaseRoot: React.ComponentType<T>) =>
90
92
  activeValue,
91
93
  setActiveValue,
92
94
  accessibilityLabel,
95
+ ariaDescribedBy,
93
96
  }),
94
97
  [
95
98
  open,
@@ -106,11 +109,12 @@ export const createSelectRoot = <T,>(BaseRoot: React.ComponentType<T>) =>
106
109
  triggerId,
107
110
  activeValue,
108
111
  accessibilityLabel,
112
+ ariaDescribedBy,
109
113
  ],
110
114
  );
111
115
 
112
116
  return (
113
- <SelectContext.Provider value={contextValue}>
117
+ <SelectProvider value={contextValue}>
114
118
  <BaseRoot
115
119
  ref={ref}
116
120
  {...(props as T)}
@@ -124,7 +128,7 @@ export const createSelectRoot = <T,>(BaseRoot: React.ComponentType<T>) =>
124
128
  >
125
129
  {children}
126
130
  </BaseRoot>
127
- </SelectContext.Provider>
131
+ </SelectProvider>
128
132
  );
129
133
  },
130
134
  );
@@ -1,11 +1,12 @@
1
1
  import type React from 'react';
2
- import { forwardRef, useCallback, useMemo } from 'react';
2
+ import { forwardRef, useCallback, useLayoutEffect, useMemo, useRef } from 'react';
3
3
  import { type GestureResponderEvent, Platform } from 'react-native';
4
- import { composeEventHandlers, mergeRefs } from '@cdx-ui/utils';
4
+ import { composeEventHandlers, mergeRefs, useFormControlContext } from '@cdx-ui/utils';
5
5
  import { useFocus, useFocusRing } from '@react-native-aria/focus';
6
6
  import { useHover, usePress } from '@react-native-aria/interactions';
7
+ import type { InteractionState } from '../types';
7
8
  import { dataAttributes } from '../utils/dataAttributes';
8
- import { SelectTriggerContext, useSelectContext } from './context';
9
+ import { SelectTriggerProvider, useSelectContext } from './context';
9
10
  import type { ISelectTriggerProps } from './types';
10
11
 
11
12
  export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
@@ -18,23 +19,10 @@ export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
18
19
  isFocused: isFocusedProp,
19
20
  isFocusVisible: isFocusVisibleProp,
20
21
  isDisabled: isDisabledProp,
22
+ 'aria-describedby': ariaDescribedByProp,
21
23
  ...props
22
24
  }: Omit<ISelectTriggerProps, 'children'> & {
23
- children?:
24
- | (({
25
- hovered,
26
- pressed,
27
- focused,
28
- focusVisible,
29
- disabled,
30
- }: {
31
- hovered?: boolean;
32
- pressed?: boolean;
33
- focused?: boolean;
34
- focusVisible?: boolean;
35
- disabled?: boolean;
36
- }) => React.ReactNode)
37
- | React.ReactNode;
25
+ children?: ((state: InteractionState) => React.ReactNode) | React.ReactNode;
38
26
  },
39
27
  ref?: any,
40
28
  ) => {
@@ -50,8 +38,11 @@ export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
50
38
  triggerRef,
51
39
  activeValue,
52
40
  accessibilityLabel,
41
+ ariaDescribedBy: ariaDescribedByFromField,
53
42
  } = useSelectContext();
54
43
 
44
+ const field = useFormControlContext();
45
+
55
46
  const disabled = contextDisabled || !!isDisabledProp;
56
47
 
57
48
  const { isFocusVisible, focusProps: focusRingProps }: any = useFocusRing();
@@ -63,7 +54,7 @@ export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
63
54
 
64
55
  const handlePress = useCallback(
65
56
  (e: GestureResponderEvent | KeyboardEvent) => {
66
- if (e.type === 'keyup' && (e as KeyboardEvent).key === 'Enter') {
57
+ if (e?.type === 'keyup' && (e as KeyboardEvent).key === 'Enter') {
67
58
  return;
68
59
  }
69
60
  if (!disabled) {
@@ -114,7 +105,53 @@ export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
114
105
  ],
115
106
  );
116
107
 
117
- const mergedRef = mergeRefs(ref, triggerRef);
108
+ /**
109
+ * Native: `Pressable` has no usable programmatic `.focus()` (unlike `TextInput`).
110
+ * `Form.Label` calls `focusInput()` → we register a bridge on `field.inputRef` that tries
111
+ * native focus, then opens the list (expected “tap label” behavior for a select).
112
+ */
113
+ const labelFocusGateRef = useRef({ disabled: false, readOnly: false });
114
+ labelFocusGateRef.current = {
115
+ disabled: !!disabled,
116
+ readOnly: !!contextReadOnly,
117
+ };
118
+
119
+ const labelFocusBridge = useMemo(
120
+ () => ({
121
+ focus() {
122
+ const { disabled: isOff, readOnly: isRO } = labelFocusGateRef.current;
123
+ if (isOff || isRO) {
124
+ return;
125
+ }
126
+ const node = triggerRef.current as { focus?: () => void } | null;
127
+ if (node != null && typeof node.focus === 'function') {
128
+ node.focus();
129
+ }
130
+ setOpen(true);
131
+ },
132
+ }),
133
+ [setOpen],
134
+ );
135
+
136
+ useLayoutEffect(() => {
137
+ if (Platform.OS === 'web' || !field.inputRef) {
138
+ return;
139
+ }
140
+ const r = field.inputRef;
141
+ r.current = labelFocusBridge as unknown as typeof r.current;
142
+ return () => {
143
+ if (r.current === labelFocusBridge) {
144
+ r.current = null;
145
+ }
146
+ };
147
+ }, [field.inputRef, labelFocusBridge]);
148
+
149
+ const mergedRef =
150
+ Platform.OS === 'web' ? mergeRefs(ref, triggerRef) : mergeRefs(ref, triggerRef);
151
+
152
+ const ariaDescribedBy = [ariaDescribedByFromField, ariaDescribedByProp]
153
+ .filter(Boolean)
154
+ .join(' ');
118
155
 
119
156
  const webKeyboardProps =
120
157
  Platform.OS === 'web'
@@ -122,7 +159,7 @@ export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
122
159
  : {};
123
160
 
124
161
  return (
125
- <SelectTriggerContext.Provider value={interactionState}>
162
+ <SelectTriggerProvider value={interactionState}>
126
163
  <BaseTrigger
127
164
  ref={mergedRef}
128
165
  role="combobox"
@@ -136,7 +173,7 @@ export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
136
173
  aria-required={contextRequired || undefined}
137
174
  aria-invalid={contextInvalid || undefined}
138
175
  aria-readonly={contextReadOnly || undefined}
139
- id={triggerId}
176
+ aria-describedby={ariaDescribedBy || undefined}
140
177
  {...dataAttributes({
141
178
  hover: interactionState.hover,
142
179
  focus: interactionState.focus,
@@ -151,6 +188,7 @@ export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
151
188
  })}
152
189
  disabled={disabled}
153
190
  {...(props as T)}
191
+ id={triggerId}
154
192
  onPress={composeEventHandlers(props?.onPress, handlePress)}
155
193
  onPressIn={composeEventHandlers(props?.onPressIn, pressProps.onPressIn)}
156
194
  onPressOut={composeEventHandlers(props?.onPressOut, pressProps.onPressOut)}
@@ -172,21 +210,9 @@ export const createSelectTrigger = <T,>(BaseTrigger: React.ComponentType<T>) =>
172
210
  )}
173
211
  {...webKeyboardProps}
174
212
  >
175
- {/* TODO: Align render-function children convention with Button — Button
176
- passes raw hook values (isHovered, isFocused, etc.) while this
177
- passes merged interaction state (isHoveredProp || isHovered). Pick
178
- one convention and apply to both. */}
179
- {typeof children === 'function'
180
- ? children({
181
- hovered: interactionState.hover,
182
- focused: interactionState.focus,
183
- pressed: interactionState.active,
184
- disabled: interactionState.disabled,
185
- focusVisible: interactionState.focusVisible,
186
- })
187
- : children}
213
+ {typeof children === 'function' ? children(interactionState) : children}
188
214
  </BaseTrigger>
189
- </SelectTriggerContext.Provider>
215
+ </SelectTriggerProvider>
190
216
  );
191
217
  },
192
218
  );