@octanejs/aria 0.0.1 → 0.0.3

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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/aria",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "engines": {
@@ -38,11 +38,14 @@
38
38
  "./stately": "./src/stately/index.ts"
39
39
  },
40
40
  "dependencies": {
41
+ "@internationalized/date": "^3.12.2",
42
+ "@internationalized/number": "^3.6.7",
43
+ "@internationalized/string": "^3.2.9",
41
44
  "@react-types/shared": "^3.36.0",
42
45
  "clsx": "^2.1.1"
43
46
  },
44
47
  "peerDependencies": {
45
- "octane": "0.1.7"
48
+ "octane": "0.1.9"
46
49
  },
47
50
  "devDependencies": {
48
51
  "@tsrx/react": "^0.2.37",
@@ -52,7 +55,7 @@
52
55
  "react-dom": "^19.2.0",
53
56
  "react-stately": "3.48.0",
54
57
  "vitest": "^4.1.9",
55
- "octane": "0.1.7"
58
+ "octane": "0.1.9"
56
59
  },
57
60
  "scripts": {
58
61
  "test": "vitest run"
@@ -0,0 +1,95 @@
1
+ // Ported from react-aria (source: .react-spectrum/packages/react-aria/src/breadcrumbs/useBreadcrumbItem.ts).
2
+ // octane adaptations: React's `ReactNode` children type → `any` (octane renderables);
3
+ // `DOMAttributes` is a local structural prop-bag alias; public-hook slot threading.
4
+ import { AriaLinkProps, useLink } from '../link/useLink';
5
+ import type { DOMProps, FocusableElement, LinkDOMProps, RefObject } from '@react-types/shared';
6
+
7
+ import { S, splitSlot, subSlot } from '../internal';
8
+
9
+ // octane adaptation: minimal structural DOMAttributes (upstream's drags React's synthetic
10
+ // handler types along).
11
+ type DOMAttributes = Record<string, any>;
12
+
13
+ export interface BreadcrumbItemProps extends AriaLinkProps, LinkDOMProps {
14
+ /** Whether the breadcrumb item represents the current page. */
15
+ isCurrent?: boolean;
16
+ /**
17
+ * The type of current location the breadcrumb item represents, if `isCurrent` is true.
18
+ *
19
+ * @default 'page'
20
+ */
21
+ 'aria-current'?: 'page' | 'step' | 'location' | 'date' | 'time' | boolean | 'true' | 'false';
22
+ /** Whether the breadcrumb item is disabled. */
23
+ isDisabled?: boolean;
24
+ /** The contents of the breadcrumb item. */
25
+ children: any;
26
+ }
27
+
28
+ export interface AriaBreadcrumbItemProps extends BreadcrumbItemProps, DOMProps {
29
+ /**
30
+ * The HTML element used to render the breadcrumb link, e.g. 'a', or 'span'.
31
+ *
32
+ * @default 'a'
33
+ */
34
+ elementType?: string;
35
+ }
36
+
37
+ export interface BreadcrumbItemAria {
38
+ /** Props for the breadcrumb item link element. */
39
+ itemProps: DOMAttributes;
40
+ }
41
+
42
+ /**
43
+ * Provides the behavior and accessibility implementation for an in a breadcrumbs component.
44
+ * See `useBreadcrumbs` for details about breadcrumbs.
45
+ */
46
+ export function useBreadcrumbItem(
47
+ props: AriaBreadcrumbItemProps,
48
+ ref: RefObject<FocusableElement | null>,
49
+ ): BreadcrumbItemAria;
50
+ // Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
51
+ export function useBreadcrumbItem(
52
+ props: AriaBreadcrumbItemProps,
53
+ ref: RefObject<FocusableElement | null>,
54
+ slot: symbol | undefined,
55
+ ): BreadcrumbItemAria;
56
+ export function useBreadcrumbItem(...args: any[]): BreadcrumbItemAria {
57
+ const [user, slotArg] = splitSlot(args);
58
+ const slot = slotArg ?? S('useBreadcrumbItem');
59
+ const props = user[0] as AriaBreadcrumbItemProps;
60
+ const ref = user[1] as RefObject<FocusableElement | null>;
61
+
62
+ let {
63
+ isCurrent,
64
+ isDisabled,
65
+ 'aria-current': ariaCurrent,
66
+ elementType = 'a',
67
+ ...otherProps
68
+ } = props;
69
+
70
+ let { linkProps } = useLink(
71
+ { isDisabled: isDisabled || isCurrent, elementType, ...otherProps },
72
+ ref,
73
+ subSlot(slot, 'link'),
74
+ );
75
+ let isHeading = /^h[1-6]$/.test(elementType);
76
+ let itemProps: DOMAttributes = {};
77
+
78
+ if (!isHeading) {
79
+ itemProps = linkProps;
80
+ }
81
+
82
+ if (isCurrent) {
83
+ itemProps['aria-current'] = ariaCurrent || 'page';
84
+ // isCurrent sets isDisabled === true for the current item,
85
+ // so we have to restore the tabIndex in order to support autoFocus.
86
+ itemProps.tabIndex = props.autoFocus ? -1 : undefined;
87
+ }
88
+
89
+ return {
90
+ itemProps: {
91
+ 'aria-disabled': isDisabled,
92
+ ...itemProps,
93
+ },
94
+ };
95
+ }
@@ -0,0 +1,51 @@
1
+ // Ported from react-aria (source: .react-spectrum/packages/react-aria/src/breadcrumbs/useBreadcrumbs.ts).
2
+ // octane adaptations: the Parcel glob intl import becomes the generated
3
+ // src/intl/breadcrumbs index (verbatim dictionaries); `DOMAttributes` is a local
4
+ // structural prop-bag alias; public-hook slot threading.
5
+ import type { AriaLabelingProps, DOMProps } from '@react-types/shared';
6
+ import { filterDOMProps } from '../utils/filterDOMProps';
7
+ import intlMessages from '../intl/breadcrumbs';
8
+ import { useLocalizedStringFormatter } from '../i18n/useLocalizedStringFormatter';
9
+
10
+ import { S, splitSlot, subSlot } from '../internal';
11
+
12
+ // octane adaptation: minimal structural DOMAttributes (upstream's drags React's synthetic
13
+ // handler types along).
14
+ type DOMAttributes = Record<string, any>;
15
+
16
+ export interface AriaBreadcrumbsProps extends DOMProps, AriaLabelingProps {}
17
+
18
+ export interface BreadcrumbsAria {
19
+ /** Props for the breadcrumbs navigation element. */
20
+ navProps: DOMAttributes;
21
+ }
22
+
23
+ /**
24
+ * Provides the behavior and accessibility implementation for a breadcrumbs component.
25
+ * Breadcrumbs display a hierarchy of links to the current page or resource in an application.
26
+ */
27
+ export function useBreadcrumbs(props: AriaBreadcrumbsProps): BreadcrumbsAria;
28
+ // Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
29
+ export function useBreadcrumbs(
30
+ props: AriaBreadcrumbsProps,
31
+ slot: symbol | undefined,
32
+ ): BreadcrumbsAria;
33
+ export function useBreadcrumbs(...args: any[]): BreadcrumbsAria {
34
+ const [user, slotArg] = splitSlot(args);
35
+ const slot = slotArg ?? S('useBreadcrumbs');
36
+ const props = user[0] as AriaBreadcrumbsProps;
37
+
38
+ let { 'aria-label': ariaLabel, ...otherProps } = props;
39
+
40
+ let strings = useLocalizedStringFormatter(
41
+ intlMessages,
42
+ '@react-aria/breadcrumbs',
43
+ subSlot(slot, 'strings'),
44
+ );
45
+ return {
46
+ navProps: {
47
+ ...filterDOMProps(otherProps, { labelable: true }),
48
+ 'aria-label': ariaLabel || strings.format('breadcrumbs'),
49
+ },
50
+ };
51
+ }
@@ -0,0 +1,273 @@
1
+ // Ported from react-aria (source: .react-spectrum/packages/react-aria/src/button/useButton.ts).
2
+ // octane adaptations:
3
+ // - React's `ElementType`/`JSXElementConstructor` → a local structural `ElementType`
4
+ // (octane components are plain functions); the per-element attribute types
5
+ // (`ButtonHTMLAttributes` etc.) → a structural prop bag, so the per-element-type
6
+ // overloads keep upstream's ref typing with a shared structural result.
7
+ // - `ReactNode` children → `any` (octane descriptors).
8
+ // - `onClick` receives the NATIVE MouseEvent (upstream's `PressEvents.onClick` is typed
9
+ // over React's synthetic event), matching the ported `usePress`.
10
+ // - Public-hook slot threading (splitSlot/subSlot) per the binding convention.
11
+ import type {
12
+ AriaLabelingProps,
13
+ FocusableDOMProps,
14
+ PressEvents,
15
+ RefObject,
16
+ } from '@react-types/shared';
17
+
18
+ import type { FocusableProps } from '../interactions/useFocusable';
19
+
20
+ import { S, splitSlot, subSlot } from '../internal';
21
+ import { filterDOMProps } from '../utils/filterDOMProps';
22
+ import { mergeProps } from '../utils/mergeProps';
23
+ import { useFocusable } from '../interactions/useFocusable';
24
+ import { usePress } from '../interactions/usePress';
25
+
26
+ // octane adaptation: minimal structural element/prop-bag types (upstream's drag React's
27
+ // element and per-element attribute types).
28
+ export type ElementType = string | ((props: any) => any);
29
+ type DOMAttributes = Record<string, any>;
30
+
31
+ export interface ButtonProps extends Omit<PressEvents, 'onClick'>, FocusableProps {
32
+ /**
33
+ * **Not recommended – use `onPress` instead.** octane adaptation: native MouseEvent
34
+ * (upstream's `PressEvents.onClick` is typed over React's synthetic event).
35
+ */
36
+ onClick?: (e: MouseEvent) => void;
37
+ /** Whether the button is disabled. */
38
+ isDisabled?: boolean;
39
+ /** The content to display in the button. */
40
+ children?: any;
41
+ }
42
+
43
+ export interface AriaBaseButtonProps extends FocusableDOMProps, AriaLabelingProps {
44
+ /** Indicates whether the element is disabled to users of assistive technology. */
45
+ 'aria-disabled'?: boolean | 'true' | 'false';
46
+ /**
47
+ * Indicates whether the element, or another grouping element it controls, is currently expanded
48
+ * or collapsed.
49
+ */
50
+ 'aria-expanded'?: boolean | 'true' | 'false';
51
+ /**
52
+ * Indicates the availability and type of interactive popup element, such as menu or dialog, that
53
+ * can be triggered by an element.
54
+ */
55
+ 'aria-haspopup'?: boolean | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' | 'true' | 'false';
56
+ /**
57
+ * Identifies the element (or elements) whose contents or presence are controlled by the current
58
+ * element.
59
+ */
60
+ 'aria-controls'?: string;
61
+ /** Indicates the current "pressed" state of toggle buttons. */
62
+ 'aria-pressed'?: boolean | 'true' | 'false' | 'mixed';
63
+ /**
64
+ * Indicates whether this element represents the current item within a container or set of related
65
+ * elements.
66
+ */
67
+ 'aria-current'?: boolean | 'true' | 'false' | 'page' | 'step' | 'location' | 'date' | 'time';
68
+ /**
69
+ * The behavior of the button when used in an HTML form.
70
+ *
71
+ * @default 'button'
72
+ */
73
+ type?: 'button' | 'submit' | 'reset';
74
+ /**
75
+ * Whether to prevent focus from moving to the button when pressing it.
76
+ *
77
+ * Caution, this can make the button inaccessible and should only be used when alternative
78
+ * keyboard interaction is provided, such as ComboBox's MenuTrigger or a NumberField's
79
+ * increment/decrement control.
80
+ */
81
+ preventFocusOnPress?: boolean;
82
+ /**
83
+ * The `<form>` element to associate the button with.
84
+ * The value of this attribute must be the id of a `<form>` in the same document.
85
+ * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/button#form).
86
+ */
87
+ form?: string;
88
+ /**
89
+ * The URL that processes the information submitted by the button.
90
+ * Overrides the action attribute of the button's form owner.
91
+ *
92
+ * octane adaptation: typed locally (upstream borrows React's `formAction` attribute type,
93
+ * which also admits a function form action).
94
+ */
95
+ formAction?: string | ((formData: FormData) => void | Promise<void>);
96
+ /** Indicates how to encode the form data that is submitted. */
97
+ formEncType?: string;
98
+ /** Indicates the HTTP method used to submit the form. */
99
+ formMethod?: string;
100
+ /** Indicates that the form is not to be validated when it is submitted. */
101
+ formNoValidate?: boolean;
102
+ /** Overrides the target attribute of the button's form owner. */
103
+ formTarget?: string;
104
+ /** Submitted as a pair with the button's value as part of the form data. */
105
+ name?: string;
106
+ /** The value associated with the button's name when it's submitted with the form data. */
107
+ value?: string;
108
+ }
109
+
110
+ export interface AriaButtonElementTypeProps<T extends ElementType = 'button'> {
111
+ /**
112
+ * The HTML element or octane component used to render the button, e.g. 'div', 'a', or
113
+ * `RouterLink`.
114
+ *
115
+ * @default 'button'
116
+ */
117
+ elementType?: T | ((props: any) => any);
118
+ }
119
+
120
+ export interface LinkButtonProps<
121
+ T extends ElementType = 'button',
122
+ > extends AriaButtonElementTypeProps<T> {
123
+ /** A URL to link to if elementType="a". */
124
+ href?: string;
125
+ /** The target window for the link. */
126
+ target?: string;
127
+ /**
128
+ * The relationship between the linked resource and the current page. See
129
+ * [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel).
130
+ */
131
+ rel?: string;
132
+ }
133
+
134
+ export interface AriaButtonProps<T extends ElementType = 'button'>
135
+ extends ButtonProps, LinkButtonProps<T>, AriaBaseButtonProps {}
136
+
137
+ export interface AriaButtonOptions<E extends ElementType> extends Omit<
138
+ AriaButtonProps<E>,
139
+ 'children'
140
+ > {}
141
+
142
+ export interface ButtonAria<T> {
143
+ /** Props for the button element. */
144
+ buttonProps: T;
145
+ /** Whether the button is currently pressed. */
146
+ isPressed: boolean;
147
+ }
148
+
149
+ // Order with overrides is important: 'button' should be default
150
+ export function useButton(
151
+ props: AriaButtonOptions<'button'>,
152
+ ref: RefObject<HTMLButtonElement | null>,
153
+ ): ButtonAria<DOMAttributes>;
154
+ export function useButton(
155
+ props: AriaButtonOptions<'a'>,
156
+ ref: RefObject<HTMLAnchorElement | null>,
157
+ ): ButtonAria<DOMAttributes>;
158
+ export function useButton(
159
+ props: AriaButtonOptions<'div'>,
160
+ ref: RefObject<HTMLDivElement | null>,
161
+ ): ButtonAria<DOMAttributes>;
162
+ export function useButton(
163
+ props: AriaButtonOptions<'input'>,
164
+ ref: RefObject<HTMLInputElement | null>,
165
+ ): ButtonAria<DOMAttributes>;
166
+ export function useButton(
167
+ props: AriaButtonOptions<'span'>,
168
+ ref: RefObject<HTMLSpanElement | null>,
169
+ ): ButtonAria<DOMAttributes>;
170
+ export function useButton(
171
+ props: AriaButtonOptions<ElementType>,
172
+ ref: RefObject<Element | null>,
173
+ ): ButtonAria<DOMAttributes>;
174
+ // Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
175
+ export function useButton(
176
+ props: AriaButtonOptions<ElementType>,
177
+ ref: RefObject<any>,
178
+ slot: symbol | undefined,
179
+ ): ButtonAria<DOMAttributes>;
180
+ /**
181
+ * Provides the behavior and accessibility implementation for a button component. Handles mouse,
182
+ * keyboard, and touch interactions, focus behavior, and ARIA props for both native button elements
183
+ * and custom element types.
184
+ *
185
+ * @param props - Props to be applied to the button.
186
+ * @param ref - A ref to a DOM element for the button.
187
+ */
188
+ export function useButton(...args: any[]): ButtonAria<DOMAttributes> {
189
+ const [user, slotArg] = splitSlot(args);
190
+ const slot = slotArg ?? S('useButton');
191
+ const props = user[0] as AriaButtonOptions<ElementType>;
192
+ const ref = user[1] as RefObject<any>;
193
+
194
+ let {
195
+ elementType = 'button',
196
+ isDisabled,
197
+ onPress,
198
+ onPressStart,
199
+ onPressEnd,
200
+ onPressUp,
201
+ onPressChange,
202
+ preventFocusOnPress,
203
+ // @ts-ignore - undocumented
204
+ allowFocusWhenDisabled,
205
+ onClick,
206
+ href,
207
+ target,
208
+ rel,
209
+ type = 'button',
210
+ } = props;
211
+ let additionalProps;
212
+ if (elementType === 'button') {
213
+ additionalProps = {
214
+ type,
215
+ disabled: isDisabled,
216
+ form: props.form,
217
+ formAction: props.formAction,
218
+ formEncType: props.formEncType,
219
+ formMethod: props.formMethod,
220
+ formNoValidate: props.formNoValidate,
221
+ formTarget: props.formTarget,
222
+ name: props.name,
223
+ value: props.value,
224
+ };
225
+ } else {
226
+ additionalProps = {
227
+ role: 'button',
228
+ href: elementType === 'a' && !isDisabled ? href : undefined,
229
+ target: elementType === 'a' ? target : undefined,
230
+ type: elementType === 'input' ? type : undefined,
231
+ disabled: elementType === 'input' ? isDisabled : undefined,
232
+ 'aria-disabled': !isDisabled || elementType === 'input' ? undefined : isDisabled,
233
+ rel: elementType === 'a' ? rel : undefined,
234
+ };
235
+ }
236
+
237
+ let { pressProps, isPressed } = usePress(
238
+ {
239
+ onPressStart,
240
+ onPressEnd,
241
+ onPressChange,
242
+ onPress,
243
+ onPressUp,
244
+ onClick,
245
+ isDisabled,
246
+ preventFocusOnPress,
247
+ ref,
248
+ },
249
+ subSlot(slot, 'press'),
250
+ );
251
+
252
+ let { focusableProps } = useFocusable(props, ref, subSlot(slot, 'focusable'));
253
+ if (allowFocusWhenDisabled) {
254
+ focusableProps.tabIndex = isDisabled ? -1 : focusableProps.tabIndex;
255
+ }
256
+ let buttonProps = mergeProps(
257
+ focusableProps,
258
+ pressProps,
259
+ filterDOMProps(props, { labelable: true }),
260
+ );
261
+
262
+ return {
263
+ isPressed, // Used to indicate press state for visual
264
+ buttonProps: mergeProps(additionalProps, buttonProps, {
265
+ 'aria-haspopup': props['aria-haspopup'],
266
+ 'aria-expanded': props['aria-expanded'],
267
+ 'aria-controls': props['aria-controls'],
268
+ 'aria-pressed': props['aria-pressed'],
269
+ 'aria-current': props['aria-current'],
270
+ 'aria-disabled': props['aria-disabled'],
271
+ }),
272
+ };
273
+ }
@@ -0,0 +1,131 @@
1
+ // Ported from react-aria (source: .react-spectrum/packages/react-aria/src/button/useToggleButton.ts).
2
+ // octane adaptations:
3
+ // - `react-stately/useToggleState` → the ported `../stately/toggle/useToggleState`.
4
+ // - React's per-element attribute types → the shared structural prop bag (see useButton).
5
+ // - Public-hook slot threading (splitSlot/subSlot) per the binding convention.
6
+ import type { RefObject } from '@react-types/shared';
7
+
8
+ import {
9
+ AriaBaseButtonProps,
10
+ AriaButtonElementTypeProps,
11
+ ButtonAria,
12
+ ButtonProps,
13
+ ElementType,
14
+ useButton,
15
+ } from './useButton';
16
+ import { chain } from '../utils/chain';
17
+ import { mergeProps } from '../utils/mergeProps';
18
+ import { S, splitSlot, subSlot } from '../internal';
19
+ import type { ToggleState } from '../stately/toggle/useToggleState';
20
+
21
+ // octane adaptation: minimal structural prop bag (upstream's drags React attribute types).
22
+ type DOMAttributes = Record<string, any>;
23
+
24
+ export interface ToggleButtonProps extends ButtonProps {
25
+ /** Whether the element should be selected (controlled). */
26
+ isSelected?: boolean;
27
+ /** Whether the element should be selected (uncontrolled). */
28
+ defaultSelected?: boolean;
29
+ /** Handler that is called when the element's selection state changes. */
30
+ onChange?: (isSelected: boolean) => void;
31
+ }
32
+
33
+ export interface AriaToggleButtonProps<T extends ElementType = 'button'>
34
+ extends
35
+ ToggleButtonProps,
36
+ Omit<
37
+ AriaBaseButtonProps,
38
+ | 'aria-current'
39
+ | 'form'
40
+ | 'formAction'
41
+ | 'formEncType'
42
+ | 'formMethod'
43
+ | 'formNoValidate'
44
+ | 'formTarget'
45
+ | 'name'
46
+ | 'value'
47
+ | 'type'
48
+ >,
49
+ AriaButtonElementTypeProps<T> {}
50
+
51
+ export interface AriaToggleButtonOptions<E extends ElementType> extends Omit<
52
+ AriaToggleButtonProps<E>,
53
+ 'children'
54
+ > {}
55
+
56
+ export interface ToggleButtonAria<T> extends ButtonAria<T> {
57
+ /** Whether the button is selected. */
58
+ isSelected: boolean;
59
+ /** Whether the button is disabled. */
60
+ isDisabled: boolean;
61
+ }
62
+
63
+ // Order with overrides is important: 'button' should be default
64
+ export function useToggleButton(
65
+ props: AriaToggleButtonOptions<'button'>,
66
+ state: ToggleState,
67
+ ref: RefObject<HTMLButtonElement | null>,
68
+ ): ToggleButtonAria<DOMAttributes>;
69
+ export function useToggleButton(
70
+ props: AriaToggleButtonOptions<'a'>,
71
+ state: ToggleState,
72
+ ref: RefObject<HTMLAnchorElement | null>,
73
+ ): ToggleButtonAria<DOMAttributes>;
74
+ export function useToggleButton(
75
+ props: AriaToggleButtonOptions<'div'>,
76
+ state: ToggleState,
77
+ ref: RefObject<HTMLDivElement | null>,
78
+ ): ToggleButtonAria<DOMAttributes>;
79
+ export function useToggleButton(
80
+ props: AriaToggleButtonOptions<'input'>,
81
+ state: ToggleState,
82
+ ref: RefObject<HTMLInputElement | null>,
83
+ ): ToggleButtonAria<DOMAttributes>;
84
+ export function useToggleButton(
85
+ props: AriaToggleButtonOptions<'span'>,
86
+ state: ToggleState,
87
+ ref: RefObject<HTMLSpanElement | null>,
88
+ ): ToggleButtonAria<DOMAttributes>;
89
+ export function useToggleButton(
90
+ props: AriaToggleButtonOptions<ElementType>,
91
+ state: ToggleState,
92
+ ref: RefObject<Element | null>,
93
+ ): ToggleButtonAria<DOMAttributes>;
94
+ // Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
95
+ export function useToggleButton(
96
+ props: AriaToggleButtonOptions<ElementType>,
97
+ state: ToggleState,
98
+ ref: RefObject<any>,
99
+ slot: symbol | undefined,
100
+ ): ToggleButtonAria<DOMAttributes>;
101
+ /**
102
+ * Provides the behavior and accessibility implementation for a toggle button component.
103
+ * ToggleButtons allow users to toggle a selection on or off, for example switching between two
104
+ * states or modes.
105
+ */
106
+ export function useToggleButton(...args: any[]): ToggleButtonAria<DOMAttributes> {
107
+ const [user, slotArg] = splitSlot(args);
108
+ const slot = slotArg ?? S('useToggleButton');
109
+ const props = user[0] as AriaToggleButtonOptions<ElementType>;
110
+ const state = user[1] as ToggleState;
111
+ const ref = user[2] as RefObject<any>;
112
+
113
+ const { isSelected } = state;
114
+ const { isPressed, buttonProps } = useButton(
115
+ {
116
+ ...props,
117
+ onPress: chain(state.toggle, props.onPress),
118
+ },
119
+ ref,
120
+ subSlot(slot, 'button'),
121
+ );
122
+
123
+ return {
124
+ isPressed,
125
+ isSelected,
126
+ isDisabled: props.isDisabled || false,
127
+ buttonProps: mergeProps(buttonProps, {
128
+ 'aria-pressed': isSelected,
129
+ }),
130
+ };
131
+ }