@octanejs/aria 0.0.1 → 0.0.4

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 (500) hide show
  1. package/package.json +6 -3
  2. package/src/breadcrumbs/useBreadcrumbItem.ts +95 -0
  3. package/src/breadcrumbs/useBreadcrumbs.ts +51 -0
  4. package/src/button/useButton.ts +273 -0
  5. package/src/button/useToggleButton.ts +131 -0
  6. package/src/button/useToggleButtonGroup.ts +131 -0
  7. package/src/checkbox/useCheckbox.ts +114 -0
  8. package/src/checkbox/useCheckboxGroup.ts +107 -0
  9. package/src/checkbox/useCheckboxGroupItem.ts +132 -0
  10. package/src/checkbox/utils.ts +15 -0
  11. package/src/combobox/useComboBox.ts +602 -0
  12. package/src/dialog/useDialog.ts +147 -0
  13. package/src/disclosure/useDisclosure.ts +180 -0
  14. package/src/focus/FocusRing.ts +69 -0
  15. package/src/focus/FocusScope.ts +1205 -0
  16. package/src/focus/useFocusRing.ts +125 -0
  17. package/src/focus/useHasTabbableChild.ts +82 -0
  18. package/src/focus/virtualFocus.ts +38 -0
  19. package/src/form/useFormValidation.ts +205 -0
  20. package/src/grid/useGridSelectionAnnouncement.ts +177 -0
  21. package/src/grid/useGridSelectionCheckbox.ts +86 -0
  22. package/src/grid/useHighlightSelectionDescription.ts +81 -0
  23. package/src/gridlist/useGridList.ts +236 -0
  24. package/src/gridlist/useGridListItem.ts +512 -0
  25. package/src/gridlist/useGridListSection.ts +78 -0
  26. package/src/gridlist/useGridListSelectionCheckbox.ts +47 -0
  27. package/src/gridlist/utils.ts +36 -0
  28. package/src/i18n/I18nProvider.ts +97 -0
  29. package/src/i18n/server.ts +115 -0
  30. package/src/i18n/useCollator.ts +42 -0
  31. package/src/i18n/useDateFormatter.ts +64 -0
  32. package/src/i18n/useDefaultLocale.ts +93 -0
  33. package/src/i18n/useFilter.ts +107 -0
  34. package/src/i18n/useListFormatter.ts +33 -0
  35. package/src/i18n/useLocalizedStringFormatter.ts +90 -0
  36. package/src/i18n/useNumberFormatter.ts +33 -0
  37. package/src/i18n/utils.ts +67 -0
  38. package/src/index.ts +268 -0
  39. package/src/intl/breadcrumbs/ar-AE.json +3 -0
  40. package/src/intl/breadcrumbs/bg-BG.json +3 -0
  41. package/src/intl/breadcrumbs/cs-CZ.json +3 -0
  42. package/src/intl/breadcrumbs/da-DK.json +3 -0
  43. package/src/intl/breadcrumbs/de-DE.json +3 -0
  44. package/src/intl/breadcrumbs/el-GR.json +3 -0
  45. package/src/intl/breadcrumbs/en-US.json +3 -0
  46. package/src/intl/breadcrumbs/es-ES.json +3 -0
  47. package/src/intl/breadcrumbs/et-EE.json +3 -0
  48. package/src/intl/breadcrumbs/fi-FI.json +3 -0
  49. package/src/intl/breadcrumbs/fr-FR.json +3 -0
  50. package/src/intl/breadcrumbs/he-IL.json +3 -0
  51. package/src/intl/breadcrumbs/hr-HR.json +3 -0
  52. package/src/intl/breadcrumbs/hu-HU.json +3 -0
  53. package/src/intl/breadcrumbs/index.ts +75 -0
  54. package/src/intl/breadcrumbs/it-IT.json +3 -0
  55. package/src/intl/breadcrumbs/ja-JP.json +3 -0
  56. package/src/intl/breadcrumbs/ko-KR.json +3 -0
  57. package/src/intl/breadcrumbs/lt-LT.json +3 -0
  58. package/src/intl/breadcrumbs/lv-LV.json +3 -0
  59. package/src/intl/breadcrumbs/nb-NO.json +3 -0
  60. package/src/intl/breadcrumbs/nl-NL.json +3 -0
  61. package/src/intl/breadcrumbs/pl-PL.json +3 -0
  62. package/src/intl/breadcrumbs/pt-BR.json +3 -0
  63. package/src/intl/breadcrumbs/pt-PT.json +3 -0
  64. package/src/intl/breadcrumbs/ro-RO.json +3 -0
  65. package/src/intl/breadcrumbs/ru-RU.json +3 -0
  66. package/src/intl/breadcrumbs/sk-SK.json +3 -0
  67. package/src/intl/breadcrumbs/sl-SI.json +3 -0
  68. package/src/intl/breadcrumbs/sr-SP.json +3 -0
  69. package/src/intl/breadcrumbs/sv-SE.json +3 -0
  70. package/src/intl/breadcrumbs/tr-TR.json +3 -0
  71. package/src/intl/breadcrumbs/uk-UA.json +3 -0
  72. package/src/intl/breadcrumbs/zh-CN.json +3 -0
  73. package/src/intl/breadcrumbs/zh-TW.json +3 -0
  74. package/src/intl/combobox/ar-AE.json +7 -0
  75. package/src/intl/combobox/bg-BG.json +7 -0
  76. package/src/intl/combobox/cs-CZ.json +7 -0
  77. package/src/intl/combobox/da-DK.json +7 -0
  78. package/src/intl/combobox/de-DE.json +7 -0
  79. package/src/intl/combobox/el-GR.json +7 -0
  80. package/src/intl/combobox/en-US.json +7 -0
  81. package/src/intl/combobox/es-ES.json +7 -0
  82. package/src/intl/combobox/et-EE.json +7 -0
  83. package/src/intl/combobox/fi-FI.json +7 -0
  84. package/src/intl/combobox/fr-FR.json +7 -0
  85. package/src/intl/combobox/he-IL.json +7 -0
  86. package/src/intl/combobox/hr-HR.json +7 -0
  87. package/src/intl/combobox/hu-HU.json +7 -0
  88. package/src/intl/combobox/index.ts +75 -0
  89. package/src/intl/combobox/it-IT.json +7 -0
  90. package/src/intl/combobox/ja-JP.json +7 -0
  91. package/src/intl/combobox/ko-KR.json +7 -0
  92. package/src/intl/combobox/lt-LT.json +7 -0
  93. package/src/intl/combobox/lv-LV.json +7 -0
  94. package/src/intl/combobox/nb-NO.json +7 -0
  95. package/src/intl/combobox/nl-NL.json +7 -0
  96. package/src/intl/combobox/pl-PL.json +7 -0
  97. package/src/intl/combobox/pt-BR.json +7 -0
  98. package/src/intl/combobox/pt-PT.json +7 -0
  99. package/src/intl/combobox/ro-RO.json +7 -0
  100. package/src/intl/combobox/ru-RU.json +7 -0
  101. package/src/intl/combobox/sk-SK.json +7 -0
  102. package/src/intl/combobox/sl-SI.json +7 -0
  103. package/src/intl/combobox/sr-SP.json +7 -0
  104. package/src/intl/combobox/sv-SE.json +7 -0
  105. package/src/intl/combobox/tr-TR.json +7 -0
  106. package/src/intl/combobox/uk-UA.json +7 -0
  107. package/src/intl/combobox/zh-CN.json +7 -0
  108. package/src/intl/combobox/zh-TW.json +7 -0
  109. package/src/intl/grid/ar-AE.json +8 -0
  110. package/src/intl/grid/bg-BG.json +8 -0
  111. package/src/intl/grid/cs-CZ.json +8 -0
  112. package/src/intl/grid/da-DK.json +8 -0
  113. package/src/intl/grid/de-DE.json +8 -0
  114. package/src/intl/grid/el-GR.json +8 -0
  115. package/src/intl/grid/en-US.json +8 -0
  116. package/src/intl/grid/es-ES.json +8 -0
  117. package/src/intl/grid/et-EE.json +8 -0
  118. package/src/intl/grid/fi-FI.json +8 -0
  119. package/src/intl/grid/fr-FR.json +8 -0
  120. package/src/intl/grid/he-IL.json +8 -0
  121. package/src/intl/grid/hr-HR.json +8 -0
  122. package/src/intl/grid/hu-HU.json +8 -0
  123. package/src/intl/grid/index.ts +75 -0
  124. package/src/intl/grid/it-IT.json +8 -0
  125. package/src/intl/grid/ja-JP.json +8 -0
  126. package/src/intl/grid/ko-KR.json +8 -0
  127. package/src/intl/grid/lt-LT.json +8 -0
  128. package/src/intl/grid/lv-LV.json +8 -0
  129. package/src/intl/grid/nb-NO.json +8 -0
  130. package/src/intl/grid/nl-NL.json +8 -0
  131. package/src/intl/grid/pl-PL.json +8 -0
  132. package/src/intl/grid/pt-BR.json +8 -0
  133. package/src/intl/grid/pt-PT.json +8 -0
  134. package/src/intl/grid/ro-RO.json +8 -0
  135. package/src/intl/grid/ru-RU.json +8 -0
  136. package/src/intl/grid/sk-SK.json +8 -0
  137. package/src/intl/grid/sl-SI.json +8 -0
  138. package/src/intl/grid/sr-SP.json +8 -0
  139. package/src/intl/grid/sv-SE.json +8 -0
  140. package/src/intl/grid/tr-TR.json +8 -0
  141. package/src/intl/grid/uk-UA.json +8 -0
  142. package/src/intl/grid/zh-CN.json +8 -0
  143. package/src/intl/grid/zh-TW.json +8 -0
  144. package/src/intl/gridlist/ar-AE.json +4 -0
  145. package/src/intl/gridlist/bg-BG.json +4 -0
  146. package/src/intl/gridlist/cs-CZ.json +4 -0
  147. package/src/intl/gridlist/da-DK.json +4 -0
  148. package/src/intl/gridlist/de-DE.json +4 -0
  149. package/src/intl/gridlist/el-GR.json +4 -0
  150. package/src/intl/gridlist/en-US.json +4 -0
  151. package/src/intl/gridlist/es-ES.json +4 -0
  152. package/src/intl/gridlist/et-EE.json +4 -0
  153. package/src/intl/gridlist/fi-FI.json +4 -0
  154. package/src/intl/gridlist/fr-FR.json +4 -0
  155. package/src/intl/gridlist/he-IL.json +4 -0
  156. package/src/intl/gridlist/hr-HR.json +4 -0
  157. package/src/intl/gridlist/hu-HU.json +4 -0
  158. package/src/intl/gridlist/index.ts +75 -0
  159. package/src/intl/gridlist/it-IT.json +4 -0
  160. package/src/intl/gridlist/ja-JP.json +4 -0
  161. package/src/intl/gridlist/ko-KR.json +4 -0
  162. package/src/intl/gridlist/lt-LT.json +4 -0
  163. package/src/intl/gridlist/lv-LV.json +4 -0
  164. package/src/intl/gridlist/nb-NO.json +4 -0
  165. package/src/intl/gridlist/nl-NL.json +4 -0
  166. package/src/intl/gridlist/pl-PL.json +4 -0
  167. package/src/intl/gridlist/pt-BR.json +4 -0
  168. package/src/intl/gridlist/pt-PT.json +4 -0
  169. package/src/intl/gridlist/ro-RO.json +4 -0
  170. package/src/intl/gridlist/ru-RU.json +4 -0
  171. package/src/intl/gridlist/sk-SK.json +4 -0
  172. package/src/intl/gridlist/sl-SI.json +4 -0
  173. package/src/intl/gridlist/sr-SP.json +4 -0
  174. package/src/intl/gridlist/sv-SE.json +4 -0
  175. package/src/intl/gridlist/tr-TR.json +4 -0
  176. package/src/intl/gridlist/uk-UA.json +4 -0
  177. package/src/intl/gridlist/zh-CN.json +4 -0
  178. package/src/intl/gridlist/zh-TW.json +4 -0
  179. package/src/intl/menu/ar-AE.json +3 -0
  180. package/src/intl/menu/bg-BG.json +3 -0
  181. package/src/intl/menu/cs-CZ.json +3 -0
  182. package/src/intl/menu/da-DK.json +3 -0
  183. package/src/intl/menu/de-DE.json +3 -0
  184. package/src/intl/menu/el-GR.json +3 -0
  185. package/src/intl/menu/en-US.json +3 -0
  186. package/src/intl/menu/es-ES.json +3 -0
  187. package/src/intl/menu/et-EE.json +3 -0
  188. package/src/intl/menu/fi-FI.json +3 -0
  189. package/src/intl/menu/fr-FR.json +3 -0
  190. package/src/intl/menu/he-IL.json +3 -0
  191. package/src/intl/menu/hr-HR.json +3 -0
  192. package/src/intl/menu/hu-HU.json +3 -0
  193. package/src/intl/menu/index.ts +75 -0
  194. package/src/intl/menu/it-IT.json +3 -0
  195. package/src/intl/menu/ja-JP.json +3 -0
  196. package/src/intl/menu/ko-KR.json +3 -0
  197. package/src/intl/menu/lt-LT.json +3 -0
  198. package/src/intl/menu/lv-LV.json +3 -0
  199. package/src/intl/menu/nb-NO.json +3 -0
  200. package/src/intl/menu/nl-NL.json +3 -0
  201. package/src/intl/menu/pl-PL.json +3 -0
  202. package/src/intl/menu/pt-BR.json +3 -0
  203. package/src/intl/menu/pt-PT.json +3 -0
  204. package/src/intl/menu/ro-RO.json +3 -0
  205. package/src/intl/menu/ru-RU.json +3 -0
  206. package/src/intl/menu/sk-SK.json +3 -0
  207. package/src/intl/menu/sl-SI.json +3 -0
  208. package/src/intl/menu/sr-SP.json +3 -0
  209. package/src/intl/menu/sv-SE.json +3 -0
  210. package/src/intl/menu/tr-TR.json +3 -0
  211. package/src/intl/menu/uk-UA.json +3 -0
  212. package/src/intl/menu/zh-CN.json +3 -0
  213. package/src/intl/menu/zh-TW.json +3 -0
  214. package/src/intl/numberfield/ar-AE.json +5 -0
  215. package/src/intl/numberfield/bg-BG.json +5 -0
  216. package/src/intl/numberfield/cs-CZ.json +5 -0
  217. package/src/intl/numberfield/da-DK.json +5 -0
  218. package/src/intl/numberfield/de-DE.json +5 -0
  219. package/src/intl/numberfield/el-GR.json +5 -0
  220. package/src/intl/numberfield/en-US.json +5 -0
  221. package/src/intl/numberfield/es-ES.json +5 -0
  222. package/src/intl/numberfield/et-EE.json +5 -0
  223. package/src/intl/numberfield/fi-FI.json +5 -0
  224. package/src/intl/numberfield/fr-FR.json +5 -0
  225. package/src/intl/numberfield/he-IL.json +5 -0
  226. package/src/intl/numberfield/hr-HR.json +5 -0
  227. package/src/intl/numberfield/hu-HU.json +5 -0
  228. package/src/intl/numberfield/index.ts +75 -0
  229. package/src/intl/numberfield/it-IT.json +5 -0
  230. package/src/intl/numberfield/ja-JP.json +5 -0
  231. package/src/intl/numberfield/ko-KR.json +5 -0
  232. package/src/intl/numberfield/lt-LT.json +5 -0
  233. package/src/intl/numberfield/lv-LV.json +5 -0
  234. package/src/intl/numberfield/nb-NO.json +5 -0
  235. package/src/intl/numberfield/nl-NL.json +5 -0
  236. package/src/intl/numberfield/pl-PL.json +5 -0
  237. package/src/intl/numberfield/pt-BR.json +5 -0
  238. package/src/intl/numberfield/pt-PT.json +5 -0
  239. package/src/intl/numberfield/ro-RO.json +5 -0
  240. package/src/intl/numberfield/ru-RU.json +5 -0
  241. package/src/intl/numberfield/sk-SK.json +5 -0
  242. package/src/intl/numberfield/sl-SI.json +5 -0
  243. package/src/intl/numberfield/sr-SP.json +5 -0
  244. package/src/intl/numberfield/sv-SE.json +5 -0
  245. package/src/intl/numberfield/tr-TR.json +5 -0
  246. package/src/intl/numberfield/uk-UA.json +5 -0
  247. package/src/intl/numberfield/zh-CN.json +5 -0
  248. package/src/intl/numberfield/zh-TW.json +5 -0
  249. package/src/intl/overlays/ar-AE.json +3 -0
  250. package/src/intl/overlays/bg-BG.json +3 -0
  251. package/src/intl/overlays/cs-CZ.json +3 -0
  252. package/src/intl/overlays/da-DK.json +3 -0
  253. package/src/intl/overlays/de-DE.json +3 -0
  254. package/src/intl/overlays/el-GR.json +3 -0
  255. package/src/intl/overlays/en-US.json +3 -0
  256. package/src/intl/overlays/es-ES.json +3 -0
  257. package/src/intl/overlays/et-EE.json +3 -0
  258. package/src/intl/overlays/fi-FI.json +3 -0
  259. package/src/intl/overlays/fr-FR.json +3 -0
  260. package/src/intl/overlays/he-IL.json +3 -0
  261. package/src/intl/overlays/hr-HR.json +3 -0
  262. package/src/intl/overlays/hu-HU.json +3 -0
  263. package/src/intl/overlays/index.ts +75 -0
  264. package/src/intl/overlays/it-IT.json +3 -0
  265. package/src/intl/overlays/ja-JP.json +3 -0
  266. package/src/intl/overlays/ko-KR.json +3 -0
  267. package/src/intl/overlays/lt-LT.json +3 -0
  268. package/src/intl/overlays/lv-LV.json +3 -0
  269. package/src/intl/overlays/nb-NO.json +3 -0
  270. package/src/intl/overlays/nl-NL.json +3 -0
  271. package/src/intl/overlays/pl-PL.json +3 -0
  272. package/src/intl/overlays/pt-BR.json +3 -0
  273. package/src/intl/overlays/pt-PT.json +3 -0
  274. package/src/intl/overlays/ro-RO.json +3 -0
  275. package/src/intl/overlays/ru-RU.json +3 -0
  276. package/src/intl/overlays/sk-SK.json +3 -0
  277. package/src/intl/overlays/sl-SI.json +3 -0
  278. package/src/intl/overlays/sr-SP.json +3 -0
  279. package/src/intl/overlays/sv-SE.json +3 -0
  280. package/src/intl/overlays/tr-TR.json +3 -0
  281. package/src/intl/overlays/uk-UA.json +3 -0
  282. package/src/intl/overlays/zh-CN.json +3 -0
  283. package/src/intl/overlays/zh-TW.json +3 -0
  284. package/src/intl/searchfield/ar-AE.json +3 -0
  285. package/src/intl/searchfield/bg-BG.json +3 -0
  286. package/src/intl/searchfield/cs-CZ.json +3 -0
  287. package/src/intl/searchfield/da-DK.json +3 -0
  288. package/src/intl/searchfield/de-DE.json +3 -0
  289. package/src/intl/searchfield/el-GR.json +3 -0
  290. package/src/intl/searchfield/en-US.json +3 -0
  291. package/src/intl/searchfield/es-ES.json +3 -0
  292. package/src/intl/searchfield/et-EE.json +3 -0
  293. package/src/intl/searchfield/fi-FI.json +3 -0
  294. package/src/intl/searchfield/fr-FR.json +3 -0
  295. package/src/intl/searchfield/he-IL.json +3 -0
  296. package/src/intl/searchfield/hr-HR.json +3 -0
  297. package/src/intl/searchfield/hu-HU.json +3 -0
  298. package/src/intl/searchfield/index.ts +75 -0
  299. package/src/intl/searchfield/it-IT.json +3 -0
  300. package/src/intl/searchfield/ja-JP.json +3 -0
  301. package/src/intl/searchfield/ko-KR.json +3 -0
  302. package/src/intl/searchfield/lt-LT.json +3 -0
  303. package/src/intl/searchfield/lv-LV.json +3 -0
  304. package/src/intl/searchfield/nb-NO.json +3 -0
  305. package/src/intl/searchfield/nl-NL.json +3 -0
  306. package/src/intl/searchfield/pl-PL.json +3 -0
  307. package/src/intl/searchfield/pt-BR.json +3 -0
  308. package/src/intl/searchfield/pt-PT.json +3 -0
  309. package/src/intl/searchfield/ro-RO.json +3 -0
  310. package/src/intl/searchfield/ru-RU.json +3 -0
  311. package/src/intl/searchfield/sk-SK.json +3 -0
  312. package/src/intl/searchfield/sl-SI.json +3 -0
  313. package/src/intl/searchfield/sr-SP.json +3 -0
  314. package/src/intl/searchfield/sv-SE.json +3 -0
  315. package/src/intl/searchfield/tr-TR.json +3 -0
  316. package/src/intl/searchfield/uk-UA.json +3 -0
  317. package/src/intl/searchfield/zh-CN.json +3 -0
  318. package/src/intl/searchfield/zh-TW.json +3 -0
  319. package/src/intl/spinbutton/ar-AE.json +3 -0
  320. package/src/intl/spinbutton/bg-BG.json +3 -0
  321. package/src/intl/spinbutton/cs-CZ.json +3 -0
  322. package/src/intl/spinbutton/da-DK.json +3 -0
  323. package/src/intl/spinbutton/de-DE.json +3 -0
  324. package/src/intl/spinbutton/el-GR.json +3 -0
  325. package/src/intl/spinbutton/en-US.json +3 -0
  326. package/src/intl/spinbutton/es-ES.json +3 -0
  327. package/src/intl/spinbutton/et-EE.json +3 -0
  328. package/src/intl/spinbutton/fi-FI.json +3 -0
  329. package/src/intl/spinbutton/fr-FR.json +3 -0
  330. package/src/intl/spinbutton/he-IL.json +3 -0
  331. package/src/intl/spinbutton/hr-HR.json +3 -0
  332. package/src/intl/spinbutton/hu-HU.json +3 -0
  333. package/src/intl/spinbutton/index.ts +75 -0
  334. package/src/intl/spinbutton/it-IT.json +3 -0
  335. package/src/intl/spinbutton/ja-JP.json +3 -0
  336. package/src/intl/spinbutton/ko-KR.json +3 -0
  337. package/src/intl/spinbutton/lt-LT.json +3 -0
  338. package/src/intl/spinbutton/lv-LV.json +3 -0
  339. package/src/intl/spinbutton/nb-NO.json +3 -0
  340. package/src/intl/spinbutton/nl-NL.json +3 -0
  341. package/src/intl/spinbutton/pl-PL.json +3 -0
  342. package/src/intl/spinbutton/pt-BR.json +3 -0
  343. package/src/intl/spinbutton/pt-PT.json +3 -0
  344. package/src/intl/spinbutton/ro-RO.json +3 -0
  345. package/src/intl/spinbutton/ru-RU.json +3 -0
  346. package/src/intl/spinbutton/sk-SK.json +3 -0
  347. package/src/intl/spinbutton/sl-SI.json +3 -0
  348. package/src/intl/spinbutton/sr-SP.json +3 -0
  349. package/src/intl/spinbutton/sv-SE.json +3 -0
  350. package/src/intl/spinbutton/tr-TR.json +3 -0
  351. package/src/intl/spinbutton/uk-UA.json +3 -0
  352. package/src/intl/spinbutton/zh-CN.json +3 -0
  353. package/src/intl/spinbutton/zh-TW.json +3 -0
  354. package/src/intl/tag/ar-AE.json +4 -0
  355. package/src/intl/tag/bg-BG.json +4 -0
  356. package/src/intl/tag/cs-CZ.json +4 -0
  357. package/src/intl/tag/da-DK.json +4 -0
  358. package/src/intl/tag/de-DE.json +4 -0
  359. package/src/intl/tag/el-GR.json +4 -0
  360. package/src/intl/tag/en-US.json +4 -0
  361. package/src/intl/tag/es-ES.json +4 -0
  362. package/src/intl/tag/et-EE.json +4 -0
  363. package/src/intl/tag/fi-FI.json +4 -0
  364. package/src/intl/tag/fr-FR.json +4 -0
  365. package/src/intl/tag/he-IL.json +4 -0
  366. package/src/intl/tag/hr-HR.json +4 -0
  367. package/src/intl/tag/hu-HU.json +4 -0
  368. package/src/intl/tag/index.ts +75 -0
  369. package/src/intl/tag/it-IT.json +4 -0
  370. package/src/intl/tag/ja-JP.json +4 -0
  371. package/src/intl/tag/ko-KR.json +4 -0
  372. package/src/intl/tag/lt-LT.json +4 -0
  373. package/src/intl/tag/lv-LV.json +4 -0
  374. package/src/intl/tag/nb-NO.json +4 -0
  375. package/src/intl/tag/nl-NL.json +4 -0
  376. package/src/intl/tag/pl-PL.json +4 -0
  377. package/src/intl/tag/pt-BR.json +4 -0
  378. package/src/intl/tag/pt-PT.json +4 -0
  379. package/src/intl/tag/ro-RO.json +4 -0
  380. package/src/intl/tag/ru-RU.json +4 -0
  381. package/src/intl/tag/sk-SK.json +4 -0
  382. package/src/intl/tag/sl-SI.json +4 -0
  383. package/src/intl/tag/sr-SP.json +4 -0
  384. package/src/intl/tag/sv-SE.json +4 -0
  385. package/src/intl/tag/tr-TR.json +4 -0
  386. package/src/intl/tag/uk-UA.json +4 -0
  387. package/src/intl/tag/zh-CN.json +4 -0
  388. package/src/intl/tag/zh-TW.json +4 -0
  389. package/src/label/useField.ts +67 -0
  390. package/src/label/useLabel.ts +78 -0
  391. package/src/link/useLink.ts +108 -0
  392. package/src/listbox/useListBox.ts +224 -0
  393. package/src/listbox/useListBoxSection.ts +74 -0
  394. package/src/listbox/useOption.ts +212 -0
  395. package/src/listbox/utils.ts +38 -0
  396. package/src/live-announcer/LiveAnnouncer.ts +172 -0
  397. package/src/menu/useMenu.ts +139 -0
  398. package/src/menu/useMenuItem.ts +453 -0
  399. package/src/menu/useMenuSection.ts +70 -0
  400. package/src/menu/useMenuTrigger.ts +189 -0
  401. package/src/menu/useSafelyMouseToSubmenu.ts +236 -0
  402. package/src/menu/useSubmenuTrigger.ts +357 -0
  403. package/src/menu/utils.ts +16 -0
  404. package/src/meter/useMeter.ts +43 -0
  405. package/src/numberfield/useNumberField.ts +572 -0
  406. package/src/overlays/DismissButton.ts +50 -0
  407. package/src/overlays/Overlay.ts +106 -0
  408. package/src/overlays/PortalProvider.ts +37 -0
  409. package/src/overlays/ariaHideOutside.ts +299 -0
  410. package/src/overlays/calculatePosition.ts +856 -0
  411. package/src/overlays/useCloseOnScroll.ts +75 -0
  412. package/src/overlays/useModal.ts +224 -0
  413. package/src/overlays/useModalOverlay.ts +103 -0
  414. package/src/overlays/useOverlay.ts +199 -0
  415. package/src/overlays/useOverlayPosition.ts +462 -0
  416. package/src/overlays/useOverlayTrigger.ts +94 -0
  417. package/src/overlays/usePopover.ts +170 -0
  418. package/src/overlays/usePreventScroll.ts +316 -0
  419. package/src/progress/useProgressBar.ts +115 -0
  420. package/src/radio/useRadio.ts +219 -0
  421. package/src/radio/useRadioGroup.ts +184 -0
  422. package/src/radio/utils.ts +15 -0
  423. package/src/searchfield/useSearchField.ts +156 -0
  424. package/src/select/HiddenSelect.ts +261 -0
  425. package/src/select/useSelect.ts +332 -0
  426. package/src/selection/DOMLayoutDelegate.ts +51 -0
  427. package/src/selection/ListKeyboardDelegate.ts +392 -0
  428. package/src/selection/useSelectableCollection.ts +750 -0
  429. package/src/selection/useSelectableItem.ts +499 -0
  430. package/src/selection/useSelectableList.ts +132 -0
  431. package/src/selection/useTypeSelect.ts +192 -0
  432. package/src/selection/utils.ts +50 -0
  433. package/src/separator/useSeparator.ts +41 -0
  434. package/src/slider/useSlider.ts +277 -0
  435. package/src/slider/useSliderThumb.ts +375 -0
  436. package/src/slider/utils.ts +20 -0
  437. package/src/spinbutton/useSpinButton.ts +380 -0
  438. package/src/stately/checkbox/useCheckboxGroupState.ts +177 -0
  439. package/src/stately/collections/CollectionBuilder.ts +332 -0
  440. package/src/stately/collections/Item.ts +78 -0
  441. package/src/stately/collections/Section.ts +52 -0
  442. package/src/stately/collections/getChildNodes.ts +94 -0
  443. package/src/stately/collections/getItemCount.ts +29 -0
  444. package/src/stately/collections/types.ts +20 -0
  445. package/src/stately/collections/useCollection.ts +54 -0
  446. package/src/stately/combobox/useComboBoxState.ts +763 -0
  447. package/src/stately/disclosure/useDisclosureGroupState.ts +108 -0
  448. package/src/stately/disclosure/useDisclosureState.ts +84 -0
  449. package/src/stately/form/useFormValidationState.ts +331 -0
  450. package/src/stately/index.ts +111 -0
  451. package/src/stately/list/ListCollection.ts +104 -0
  452. package/src/stately/list/useListState.ts +178 -0
  453. package/src/stately/list/useSingleSelectListState.ts +101 -0
  454. package/src/stately/menu/useMenuTriggerState.ts +120 -0
  455. package/src/stately/menu/useSubmenuTriggerState.ts +116 -0
  456. package/src/stately/numberfield/useNumberFieldState.ts +430 -0
  457. package/src/stately/overlays/useOverlayTriggerState.ts +85 -0
  458. package/src/stately/radio/useRadioGroupState.ts +150 -0
  459. package/src/stately/searchfield/useSearchFieldState.ts +79 -0
  460. package/src/stately/select/useSelectState.ts +322 -0
  461. package/src/stately/selection/Selection.ts +23 -0
  462. package/src/stately/selection/SelectionManager.ts +541 -0
  463. package/src/stately/selection/types.ts +117 -0
  464. package/src/stately/selection/useMultipleSelectionState.ts +178 -0
  465. package/src/stately/slider/useSliderState.ts +458 -0
  466. package/src/stately/tabs/useTabListState.ts +149 -0
  467. package/src/stately/toggle/useToggleGroupState.ts +109 -0
  468. package/src/stately/toggle/useToggleState.ts +100 -0
  469. package/src/stately/tooltip/useTooltipTriggerState.ts +218 -0
  470. package/src/stately/tree/TreeCollection.ts +92 -0
  471. package/src/stately/tree/useTreeState.ts +121 -0
  472. package/src/stately/utils/useControlledState.ts +7 -0
  473. package/src/switch/useSwitch.ts +77 -0
  474. package/src/tabs/TabsKeyboardDelegate.ts +99 -0
  475. package/src/tabs/useTab.ts +117 -0
  476. package/src/tabs/useTabList.ts +105 -0
  477. package/src/tabs/useTabPanel.ts +75 -0
  478. package/src/tabs/utils.ts +32 -0
  479. package/src/tag/useTag.ts +162 -0
  480. package/src/tag/useTagGroup.ts +192 -0
  481. package/src/textfield/useFormattedTextField.ts +203 -0
  482. package/src/textfield/useTextField.ts +248 -0
  483. package/src/toggle/useToggle.ts +265 -0
  484. package/src/toolbar/useToolbar.ts +147 -0
  485. package/src/tooltip/useTooltip.ts +64 -0
  486. package/src/tooltip/useTooltipTrigger.ts +187 -0
  487. package/src/utils/filterDOMProps.ts +121 -0
  488. package/src/utils/getScrollParent.ts +16 -0
  489. package/src/utils/getScrollParents.ts +20 -0
  490. package/src/utils/keyboard.ts +38 -0
  491. package/src/utils/scrollIntoView.ts +178 -0
  492. package/src/utils/useDeepMemo.ts +30 -0
  493. package/src/utils/useFormReset.ts +54 -0
  494. package/src/utils/useId.ts +5 -0
  495. package/src/utils/useLabels.ts +53 -0
  496. package/src/utils/useResizeObserver.ts +70 -0
  497. package/src/utils/useSlot.ts +78 -0
  498. package/src/utils/useUpdateEffect.ts +54 -0
  499. package/src/utils/useUpdateLayoutEffect.ts +58 -0
  500. package/src/visually-hidden/VisuallyHidden.ts +100 -0
@@ -0,0 +1,219 @@
1
+ // Ported from react-aria (source: .react-spectrum/packages/react-aria/src/radio/useRadio.ts).
2
+ // octane adaptations:
3
+ // - onChange→onInput DOM wiring (octane has no synthetic onChange; native `input` fires
4
+ // on radio selection with identical timing) — the selection handler is `onInput` and
5
+ // reads state off the native event.
6
+ // - `FocusableProps` is the ported native-event version; label handlers receive native
7
+ // MouseEvents; ReactNode → any; per-element attribute types → structural bags.
8
+ // - The dev-only missing-label console.warn is not ported (repo policy).
9
+ // - Public-hook slot threading.
10
+ import type { AriaLabelingProps, DOMProps, PressEvents, RefObject } from '@react-types/shared';
11
+ import { useMemo } from 'octane';
12
+
13
+ import type { FocusableProps } from '../interactions/useFocusable';
14
+ import { S, splitSlot, subSlot } from '../internal';
15
+ import { filterDOMProps } from '../utils/filterDOMProps';
16
+ import { getEventTarget } from '../utils/shadowdom/DOMFunctions';
17
+ import { mergeProps } from '../utils/mergeProps';
18
+ import { radioGroupData } from './utils';
19
+ import type { RadioGroupState } from '../stately/radio/useRadioGroupState';
20
+ import { useFocusable } from '../interactions/useFocusable';
21
+ import { useFormReset } from '../utils/useFormReset';
22
+ import { useFormValidation } from '../form/useFormValidation';
23
+ import { usePress } from '../interactions/usePress';
24
+ import { useSlotId2 } from '../utils/useSlot';
25
+
26
+ type DOMAttributes = Record<string, any>;
27
+
28
+ export interface RadioProps extends FocusableProps {
29
+ /**
30
+ * The value of the radio button, used when submitting an HTML form.
31
+ * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio#Value).
32
+ */
33
+ value: string;
34
+ /**
35
+ * The label for the Radio. Accepts any renderable node.
36
+ */
37
+ children?: any;
38
+ /**
39
+ * Whether the radio button is disabled or not.
40
+ * Shows that a selection exists, but is not available in that circumstance.
41
+ */
42
+ isDisabled?: boolean;
43
+ }
44
+
45
+ export interface AriaRadioProps
46
+ extends RadioProps, DOMProps, AriaLabelingProps, Omit<PressEvents, 'onClick'> {
47
+ /** Handler called on the native click event (octane native MouseEvent). */
48
+ onClick?: (e: MouseEvent) => void;
49
+ }
50
+
51
+ export interface RadioAria {
52
+ /** Props for the label wrapper element. */
53
+ labelProps: DOMAttributes;
54
+ /** Props for the input element. */
55
+ inputProps: DOMAttributes;
56
+ /** Props for the checkbox description element, if any. */
57
+ descriptionProps: DOMAttributes;
58
+ /** Whether the radio is disabled. */
59
+ isDisabled: boolean;
60
+ /** Whether the radio is currently selected. */
61
+ isSelected: boolean;
62
+ /** Whether the radio is in a pressed state. */
63
+ isPressed: boolean;
64
+ }
65
+
66
+ export function useRadio(
67
+ props: AriaRadioProps,
68
+ state: RadioGroupState,
69
+ ref: RefObject<HTMLInputElement | null>,
70
+ ): RadioAria;
71
+ // Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
72
+ export function useRadio(
73
+ props: AriaRadioProps,
74
+ state: RadioGroupState,
75
+ ref: RefObject<HTMLInputElement | null>,
76
+ slot: symbol | undefined,
77
+ ): RadioAria;
78
+ export function useRadio(...args: any[]): RadioAria {
79
+ const [user, slotArg] = splitSlot(args);
80
+ const slot = slotArg ?? S('useRadio');
81
+ const props = user[0] as AriaRadioProps;
82
+ const state = user[1] as RadioGroupState;
83
+ const ref = user[2] as RefObject<HTMLInputElement | null>;
84
+
85
+ let {
86
+ value,
87
+ 'aria-label': ariaLabel,
88
+ 'aria-labelledby': ariaLabelledby,
89
+ onPressStart,
90
+ onPressEnd,
91
+ onPressChange,
92
+ onPress,
93
+ onPressUp,
94
+ onClick,
95
+ } = props;
96
+ const isDisabled = props.isDisabled || state.isDisabled;
97
+
98
+ let checked = state.selectedValue === value;
99
+
100
+ // octane adaptation: native `input` fires on radio selection — same timing as React's
101
+ // synthetic onChange for radios.
102
+ let onInput = (e: Event) => {
103
+ e.stopPropagation();
104
+ state.setSelectedValue(value);
105
+ };
106
+
107
+ // Handle press state for keyboard interactions and cases where labelProps is not used.
108
+ let { pressProps, isPressed } = usePress(
109
+ {
110
+ onPressStart,
111
+ onPressEnd,
112
+ onPressChange,
113
+ onPress,
114
+ onPressUp,
115
+ onClick,
116
+ isDisabled,
117
+ },
118
+ subSlot(slot, 'press'),
119
+ );
120
+
121
+ // Handle press state on the label.
122
+ let { pressProps: labelProps, isPressed: isLabelPressed } = usePress(
123
+ {
124
+ onPressStart,
125
+ onPressEnd,
126
+ onPressChange,
127
+ onPressUp,
128
+ onClick,
129
+ isDisabled,
130
+ onPress(e: any) {
131
+ onPress?.(e);
132
+ state.setSelectedValue(value);
133
+ ref.current?.focus();
134
+ },
135
+ },
136
+ subSlot(slot, 'labelPress'),
137
+ );
138
+
139
+ let { focusableProps } = useFocusable(
140
+ mergeProps(props, {
141
+ onFocus: () => state.setLastFocusedValue(value),
142
+ }),
143
+ ref,
144
+ subSlot(slot, 'focusable'),
145
+ );
146
+ let interactions = mergeProps(pressProps, focusableProps);
147
+ let domProps = filterDOMProps(props, { labelable: true });
148
+ let tabIndex: number | undefined = -1;
149
+ if (state.selectedValue != null) {
150
+ if (state.selectedValue === value) {
151
+ tabIndex = 0;
152
+ }
153
+ } else if (state.lastFocusedValue === value || state.lastFocusedValue == null) {
154
+ tabIndex = 0;
155
+ }
156
+ if (isDisabled) {
157
+ tabIndex = undefined;
158
+ }
159
+
160
+ let { name, form, descriptionId, errorMessageId, validationBehavior } =
161
+ radioGroupData.get(state)!;
162
+ useFormReset(ref, state.defaultSelectedValue, state.setSelectedValue, subSlot(slot, 'reset'));
163
+ useFormValidation({ validationBehavior }, state, ref, subSlot(slot, 'validation'));
164
+
165
+ let descriptionProps = useSlotId2(undefined, subSlot(slot, 'description'));
166
+
167
+ return {
168
+ labelProps: mergeProps(
169
+ labelProps,
170
+ useMemo(
171
+ () => ({
172
+ // octane adaptation: upstream preventDefaults ALL label clicks to stop the
173
+ // label's built-in click-forwarding (a doubled activation). Input-targeted
174
+ // clicks normally never get here — the input-level press stops their
175
+ // propagation — but press handlers are public props, so a consumer calling
176
+ // continuePropagation() lets them through. React's synthetic onChange fires
177
+ // regardless; with native events an unconditional preventDefault would cancel
178
+ // the input's own activation (no `input` event), so scope it to clicks that
179
+ // do NOT target the input. Same adaptation as useToggle's labelProps.
180
+ onClick: (e: MouseEvent) => {
181
+ if (getEventTarget(e) !== ref.current) {
182
+ e.preventDefault();
183
+ }
184
+ },
185
+ // Prevent label from being focused when mouse down on it.
186
+ // Note, this does not prevent the input from being focused in the `click` event.
187
+ onMouseDown: (e: MouseEvent) => e.preventDefault(),
188
+ }),
189
+ [],
190
+ subSlot(slot, 'labelHandlers'),
191
+ ),
192
+ ),
193
+ inputProps: mergeProps(domProps, {
194
+ ...interactions,
195
+ type: 'radio',
196
+ name,
197
+ form,
198
+ tabIndex,
199
+ disabled: isDisabled,
200
+ required: state.isRequired && validationBehavior === 'native',
201
+ checked,
202
+ value,
203
+ onInput,
204
+ 'aria-describedby':
205
+ [
206
+ props['aria-describedby'],
207
+ descriptionProps.id,
208
+ state.isInvalid ? errorMessageId : null,
209
+ descriptionId,
210
+ ]
211
+ .filter(Boolean)
212
+ .join(' ') || undefined,
213
+ }),
214
+ descriptionProps,
215
+ isDisabled,
216
+ isSelected: checked,
217
+ isPressed: isPressed || isLabelPressed,
218
+ };
219
+ }
@@ -0,0 +1,184 @@
1
+ // Ported from react-aria (source: .react-spectrum/packages/react-aria/src/radio/useRadioGroup.ts).
2
+ // octane adaptations: the keyboard/focus handlers receive native events; public-hook
3
+ // slot threading.
4
+ import type {
5
+ AriaLabelingProps,
6
+ AriaValidationProps,
7
+ DOMProps,
8
+ InputDOMProps,
9
+ ValidationResult,
10
+ } from '@react-types/shared';
11
+
12
+ // octane adaptation: structural prop bag (upstream's DOMAttributes drags React handler
13
+ // types; the keyboard handler here is a native KeyboardEvent handler).
14
+ type DOMAttributes = Record<string, any>;
15
+
16
+ import { S, splitSlot, subSlot } from '../internal';
17
+ import { filterDOMProps } from '../utils/filterDOMProps';
18
+ import { getEventTarget } from '../utils/shadowdom/DOMFunctions';
19
+ import { getFocusableTreeWalker } from '../focus/FocusScope';
20
+ import { getOwnerWindow } from '../utils/domHelpers';
21
+ import { mergeProps } from '../utils/mergeProps';
22
+ import { radioGroupData } from './utils';
23
+ import type { RadioGroupProps, RadioGroupState } from '../stately/radio/useRadioGroupState';
24
+ import { useField } from '../label/useField';
25
+ import { useFocusWithin } from '../interactions/useFocusWithin';
26
+ import { useId } from '../utils/useId';
27
+ import { useLocale } from '../i18n/I18nProvider';
28
+
29
+ export interface AriaRadioGroupProps
30
+ extends RadioGroupProps, InputDOMProps, DOMProps, AriaLabelingProps, AriaValidationProps {}
31
+
32
+ export interface RadioGroupAria extends ValidationResult {
33
+ /** Props for the radio group wrapper element. */
34
+ radioGroupProps: DOMAttributes;
35
+ /** Props for the radio group's visible label (if any). */
36
+ labelProps: DOMAttributes;
37
+ /** Props for the radio group description element, if any. */
38
+ descriptionProps: DOMAttributes;
39
+ /** Props for the radio group error message element, if any. */
40
+ errorMessageProps: DOMAttributes;
41
+ }
42
+
43
+ export function useRadioGroup(props: AriaRadioGroupProps, state: RadioGroupState): RadioGroupAria;
44
+ // Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
45
+ export function useRadioGroup(
46
+ props: AriaRadioGroupProps,
47
+ state: RadioGroupState,
48
+ slot: symbol | undefined,
49
+ ): RadioGroupAria;
50
+ export function useRadioGroup(...args: any[]): RadioGroupAria {
51
+ const [user, slotArg] = splitSlot(args);
52
+ const slot = slotArg ?? S('useRadioGroup');
53
+ const props = user[0] as AriaRadioGroupProps;
54
+ const state = user[1] as RadioGroupState;
55
+
56
+ let {
57
+ name,
58
+ form,
59
+ isReadOnly,
60
+ isRequired,
61
+ isDisabled,
62
+ orientation = 'vertical',
63
+ validationBehavior = 'aria',
64
+ } = props;
65
+ let { direction } = useLocale(subSlot(slot, 'locale'));
66
+
67
+ let { isInvalid, validationErrors, validationDetails } = state.displayValidation;
68
+ let { labelProps, fieldProps, descriptionProps, errorMessageProps } = useField(
69
+ {
70
+ ...props,
71
+ // Radio group is not an HTML input element so it
72
+ // shouldn't be labeled by a <label> element.
73
+ labelElementType: 'span',
74
+ isInvalid: state.isInvalid,
75
+ errorMessage: props.errorMessage || validationErrors,
76
+ },
77
+ subSlot(slot, 'field'),
78
+ );
79
+
80
+ let domProps = filterDOMProps(props, { labelable: true });
81
+
82
+ // When the radio group loses focus, reset the focusable radio to null if
83
+ // there is no selection. This allows tabbing into the group from either
84
+ // direction to go to the first or last radio.
85
+ let { focusWithinProps } = useFocusWithin(
86
+ {
87
+ onBlurWithin(e: FocusEvent) {
88
+ (props as any).onBlur?.(e);
89
+ if (!state.selectedValue) {
90
+ state.setLastFocusedValue(null);
91
+ }
92
+ },
93
+ onFocusWithin: (props as any).onFocus,
94
+ onFocusWithinChange: (props as any).onFocusChange,
95
+ },
96
+ subSlot(slot, 'focusWithin'),
97
+ );
98
+
99
+ let onKeyDown = (e: KeyboardEvent) => {
100
+ let nextDir;
101
+ switch (e.key) {
102
+ case 'ArrowRight':
103
+ if (direction === 'rtl' && orientation !== 'vertical') {
104
+ nextDir = 'prev';
105
+ } else {
106
+ nextDir = 'next';
107
+ }
108
+ break;
109
+ case 'ArrowLeft':
110
+ if (direction === 'rtl' && orientation !== 'vertical') {
111
+ nextDir = 'next';
112
+ } else {
113
+ nextDir = 'prev';
114
+ }
115
+ break;
116
+ case 'ArrowDown':
117
+ nextDir = 'next';
118
+ break;
119
+ case 'ArrowUp':
120
+ nextDir = 'prev';
121
+ break;
122
+ default:
123
+ return;
124
+ }
125
+ e.preventDefault();
126
+ let walker = getFocusableTreeWalker(e.currentTarget as Element, {
127
+ from: getEventTarget(e) as Element,
128
+ accept: (node: Element) =>
129
+ node instanceof getOwnerWindow(node).HTMLInputElement &&
130
+ (node as HTMLInputElement).type === 'radio',
131
+ });
132
+ let nextElem;
133
+ if (nextDir === 'next') {
134
+ nextElem = walker.nextNode();
135
+ if (!nextElem) {
136
+ walker.currentNode = e.currentTarget as Node;
137
+ nextElem = walker.firstChild();
138
+ }
139
+ } else {
140
+ nextElem = walker.previousNode();
141
+ if (!nextElem) {
142
+ walker.currentNode = e.currentTarget as Node;
143
+ nextElem = walker.lastChild();
144
+ }
145
+ }
146
+
147
+ if (nextElem) {
148
+ // Call focus on nextElem so that keyboard navigation scrolls the radio into view
149
+ (nextElem as HTMLInputElement).focus();
150
+ state.setSelectedValue((nextElem as HTMLInputElement).value);
151
+ }
152
+ };
153
+
154
+ let groupName = useId(name, subSlot(slot, 'name'));
155
+ radioGroupData.set(state, {
156
+ name: groupName,
157
+ form,
158
+ descriptionId: (descriptionProps as any).id,
159
+ errorMessageId: (errorMessageProps as any).id,
160
+ validationBehavior,
161
+ });
162
+
163
+ return {
164
+ radioGroupProps: mergeProps(domProps, {
165
+ // https://www.w3.org/TR/wai-aria-1.2/#radiogroup
166
+ role: 'radiogroup',
167
+ onKeyDown,
168
+ 'aria-invalid': state.isInvalid || undefined,
169
+ 'aria-errormessage': props['aria-errormessage'],
170
+ 'aria-readonly': isReadOnly || undefined,
171
+ 'aria-required': isRequired || undefined,
172
+ 'aria-disabled': isDisabled || undefined,
173
+ 'aria-orientation': orientation,
174
+ ...fieldProps,
175
+ ...focusWithinProps,
176
+ }),
177
+ labelProps,
178
+ descriptionProps,
179
+ errorMessageProps,
180
+ isInvalid,
181
+ validationErrors,
182
+ validationDetails,
183
+ };
184
+ }
@@ -0,0 +1,15 @@
1
+ // Ported from react-aria (source: .react-spectrum/packages/react-aria/src/radio/utils.ts).
2
+ import type { RadioGroupState } from '../stately/radio/useRadioGroupState';
3
+
4
+ interface RadioGroupData {
5
+ name: string;
6
+ form: string | undefined;
7
+ descriptionId: string | undefined;
8
+ errorMessageId: string | undefined;
9
+ validationBehavior: 'aria' | 'native';
10
+ }
11
+
12
+ export const radioGroupData: WeakMap<RadioGroupState, RadioGroupData> = new WeakMap<
13
+ RadioGroupState,
14
+ RadioGroupData
15
+ >();
@@ -0,0 +1,156 @@
1
+ // Ported from react-aria (source: .react-spectrum/packages/react-aria/src/searchfield/useSearchField.ts).
2
+ // octane adaptations: the Parcel glob intl import becomes the generated
3
+ // src/intl/searchfield index (verbatim dictionaries); per-element attribute types →
4
+ // structural bags; the keydown handler receives the wrapped BaseEvent from the ported
5
+ // useKeyboard (so `continuePropagation()` works); public-hook slot threading.
6
+ import type { RefObject, ValidationResult } from '@react-types/shared';
7
+
8
+ import type { AriaButtonProps } from '../button/useButton';
9
+ import { AriaTextFieldProps, useTextField } from '../textfield/useTextField';
10
+ import { S, splitSlot, subSlot } from '../internal';
11
+ import { chain } from '../utils/chain';
12
+ import intlMessages from '../intl/searchfield';
13
+ import type {
14
+ SearchFieldProps,
15
+ SearchFieldState,
16
+ } from '../stately/searchfield/useSearchFieldState';
17
+ import { useLocalizedStringFormatter } from '../i18n/useLocalizedStringFormatter';
18
+
19
+ type DOMAttributes = Record<string, any>;
20
+
21
+ export interface AriaSearchFieldProps extends SearchFieldProps, Omit<AriaTextFieldProps, 'type'> {
22
+ /**
23
+ * An enumerated attribute that defines what action label or icon to preset for the enter key on
24
+ * virtual keyboards. See
25
+ * [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint).
26
+ */
27
+ enterKeyHint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
28
+ /**
29
+ * The type of input to render. See
30
+ * [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdeftype).
31
+ *
32
+ * @default 'search'
33
+ */
34
+ type?: 'text' | 'search' | 'url' | 'tel' | 'email' | 'password' | (string & {});
35
+ }
36
+
37
+ export interface SearchFieldAria extends ValidationResult {
38
+ /** Props for the text field's visible label element (if any). */
39
+ labelProps: DOMAttributes;
40
+ /** Props for the input element. */
41
+ inputProps: DOMAttributes;
42
+ /** Props for the clear button. */
43
+ clearButtonProps: AriaButtonProps;
44
+ /** Props for the searchfield's description element, if any. */
45
+ descriptionProps: DOMAttributes;
46
+ /** Props for the searchfield's error message element, if any. */
47
+ errorMessageProps: DOMAttributes;
48
+ }
49
+
50
+ /**
51
+ * Provides the behavior and accessibility implementation for a search field.
52
+ */
53
+ export function useSearchField(
54
+ props: AriaSearchFieldProps,
55
+ state: SearchFieldState,
56
+ inputRef: RefObject<HTMLInputElement | null>,
57
+ ): SearchFieldAria;
58
+ // Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
59
+ export function useSearchField(
60
+ props: AriaSearchFieldProps,
61
+ state: SearchFieldState,
62
+ inputRef: RefObject<HTMLInputElement | null>,
63
+ slot: symbol | undefined,
64
+ ): SearchFieldAria;
65
+ export function useSearchField(...args: any[]): SearchFieldAria {
66
+ const [user, slotArg] = splitSlot(args);
67
+ const slot = slotArg ?? S('useSearchField');
68
+ const props = user[0] as AriaSearchFieldProps;
69
+ const state = user[1] as SearchFieldState;
70
+ const inputRef = user[2] as RefObject<HTMLInputElement | null>;
71
+
72
+ let stringFormatter = useLocalizedStringFormatter(
73
+ intlMessages,
74
+ '@react-aria/searchfield',
75
+ subSlot(slot, 'strings'),
76
+ );
77
+ let { isDisabled, isReadOnly, onSubmit, onClear, type = 'search' } = props;
78
+ let onKeyDown = (e: any) => {
79
+ const key = e.key;
80
+
81
+ if (key === 'Enter' && (isDisabled || isReadOnly)) {
82
+ e.preventDefault();
83
+ }
84
+
85
+ if (isDisabled || isReadOnly) {
86
+ return;
87
+ }
88
+
89
+ // for backward compatibility;
90
+ // otherwise, "Enter" on an input would trigger a form submit, the default browser behavior
91
+ if (key === 'Enter' && onSubmit) {
92
+ e.preventDefault();
93
+ onSubmit(state.value);
94
+ }
95
+
96
+ if (key === 'Escape') {
97
+ // Also check the inputRef value for the case where the value was set directly on the input element instead of going through
98
+ // the hook
99
+ if (state.value === '' && (!inputRef.current || inputRef.current.value === '')) {
100
+ e.continuePropagation();
101
+ } else {
102
+ e.preventDefault();
103
+ state.setValue('');
104
+ if (onClear) {
105
+ onClear();
106
+ }
107
+ }
108
+ }
109
+ };
110
+
111
+ let onClearButtonClick = () => {
112
+ state.setValue('');
113
+
114
+ if (onClear) {
115
+ onClear();
116
+ }
117
+ };
118
+
119
+ let onPressStart = () => {
120
+ // this is in PressStart for mobile so that touching the clear button doesn't remove focus from
121
+ // the input and close the keyboard
122
+ inputRef.current?.focus();
123
+ };
124
+
125
+ let { labelProps, inputProps, descriptionProps, errorMessageProps, ...validation } = useTextField(
126
+ {
127
+ ...props,
128
+ value: state.value,
129
+ onChange: state.setValue,
130
+ onKeyDown: !isReadOnly ? chain(onKeyDown, props.onKeyDown) : props.onKeyDown,
131
+ type,
132
+ } as any,
133
+ inputRef,
134
+ subSlot(slot, 'textField'),
135
+ );
136
+
137
+ return {
138
+ labelProps,
139
+ inputProps: {
140
+ ...inputProps,
141
+ // already handled by useSearchFieldState
142
+ defaultValue: undefined,
143
+ },
144
+ clearButtonProps: {
145
+ 'aria-label': stringFormatter.format('Clear search'),
146
+ excludeFromTabOrder: true,
147
+ preventFocusOnPress: true,
148
+ isDisabled: isDisabled || isReadOnly,
149
+ onPress: onClearButtonClick,
150
+ onPressStart,
151
+ },
152
+ descriptionProps,
153
+ errorMessageProps,
154
+ ...validation,
155
+ };
156
+ }