@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.
- package/package.json +6 -3
- package/src/breadcrumbs/useBreadcrumbItem.ts +95 -0
- package/src/breadcrumbs/useBreadcrumbs.ts +51 -0
- package/src/button/useButton.ts +273 -0
- package/src/button/useToggleButton.ts +131 -0
- package/src/button/useToggleButtonGroup.ts +131 -0
- package/src/checkbox/useCheckbox.ts +114 -0
- package/src/checkbox/useCheckboxGroup.ts +107 -0
- package/src/checkbox/useCheckboxGroupItem.ts +132 -0
- package/src/checkbox/utils.ts +15 -0
- package/src/combobox/useComboBox.ts +602 -0
- package/src/dialog/useDialog.ts +147 -0
- package/src/disclosure/useDisclosure.ts +180 -0
- package/src/focus/FocusRing.ts +69 -0
- package/src/focus/FocusScope.ts +1205 -0
- package/src/focus/useFocusRing.ts +125 -0
- package/src/focus/useHasTabbableChild.ts +82 -0
- package/src/focus/virtualFocus.ts +38 -0
- package/src/form/useFormValidation.ts +205 -0
- package/src/grid/useGridSelectionAnnouncement.ts +177 -0
- package/src/grid/useGridSelectionCheckbox.ts +86 -0
- package/src/grid/useHighlightSelectionDescription.ts +81 -0
- package/src/gridlist/useGridList.ts +236 -0
- package/src/gridlist/useGridListItem.ts +512 -0
- package/src/gridlist/useGridListSection.ts +78 -0
- package/src/gridlist/useGridListSelectionCheckbox.ts +47 -0
- package/src/gridlist/utils.ts +36 -0
- package/src/i18n/I18nProvider.ts +97 -0
- package/src/i18n/server.ts +115 -0
- package/src/i18n/useCollator.ts +42 -0
- package/src/i18n/useDateFormatter.ts +64 -0
- package/src/i18n/useDefaultLocale.ts +93 -0
- package/src/i18n/useFilter.ts +107 -0
- package/src/i18n/useListFormatter.ts +33 -0
- package/src/i18n/useLocalizedStringFormatter.ts +90 -0
- package/src/i18n/useNumberFormatter.ts +33 -0
- package/src/i18n/utils.ts +67 -0
- package/src/index.ts +268 -0
- package/src/intl/breadcrumbs/ar-AE.json +3 -0
- package/src/intl/breadcrumbs/bg-BG.json +3 -0
- package/src/intl/breadcrumbs/cs-CZ.json +3 -0
- package/src/intl/breadcrumbs/da-DK.json +3 -0
- package/src/intl/breadcrumbs/de-DE.json +3 -0
- package/src/intl/breadcrumbs/el-GR.json +3 -0
- package/src/intl/breadcrumbs/en-US.json +3 -0
- package/src/intl/breadcrumbs/es-ES.json +3 -0
- package/src/intl/breadcrumbs/et-EE.json +3 -0
- package/src/intl/breadcrumbs/fi-FI.json +3 -0
- package/src/intl/breadcrumbs/fr-FR.json +3 -0
- package/src/intl/breadcrumbs/he-IL.json +3 -0
- package/src/intl/breadcrumbs/hr-HR.json +3 -0
- package/src/intl/breadcrumbs/hu-HU.json +3 -0
- package/src/intl/breadcrumbs/index.ts +75 -0
- package/src/intl/breadcrumbs/it-IT.json +3 -0
- package/src/intl/breadcrumbs/ja-JP.json +3 -0
- package/src/intl/breadcrumbs/ko-KR.json +3 -0
- package/src/intl/breadcrumbs/lt-LT.json +3 -0
- package/src/intl/breadcrumbs/lv-LV.json +3 -0
- package/src/intl/breadcrumbs/nb-NO.json +3 -0
- package/src/intl/breadcrumbs/nl-NL.json +3 -0
- package/src/intl/breadcrumbs/pl-PL.json +3 -0
- package/src/intl/breadcrumbs/pt-BR.json +3 -0
- package/src/intl/breadcrumbs/pt-PT.json +3 -0
- package/src/intl/breadcrumbs/ro-RO.json +3 -0
- package/src/intl/breadcrumbs/ru-RU.json +3 -0
- package/src/intl/breadcrumbs/sk-SK.json +3 -0
- package/src/intl/breadcrumbs/sl-SI.json +3 -0
- package/src/intl/breadcrumbs/sr-SP.json +3 -0
- package/src/intl/breadcrumbs/sv-SE.json +3 -0
- package/src/intl/breadcrumbs/tr-TR.json +3 -0
- package/src/intl/breadcrumbs/uk-UA.json +3 -0
- package/src/intl/breadcrumbs/zh-CN.json +3 -0
- package/src/intl/breadcrumbs/zh-TW.json +3 -0
- package/src/intl/combobox/ar-AE.json +7 -0
- package/src/intl/combobox/bg-BG.json +7 -0
- package/src/intl/combobox/cs-CZ.json +7 -0
- package/src/intl/combobox/da-DK.json +7 -0
- package/src/intl/combobox/de-DE.json +7 -0
- package/src/intl/combobox/el-GR.json +7 -0
- package/src/intl/combobox/en-US.json +7 -0
- package/src/intl/combobox/es-ES.json +7 -0
- package/src/intl/combobox/et-EE.json +7 -0
- package/src/intl/combobox/fi-FI.json +7 -0
- package/src/intl/combobox/fr-FR.json +7 -0
- package/src/intl/combobox/he-IL.json +7 -0
- package/src/intl/combobox/hr-HR.json +7 -0
- package/src/intl/combobox/hu-HU.json +7 -0
- package/src/intl/combobox/index.ts +75 -0
- package/src/intl/combobox/it-IT.json +7 -0
- package/src/intl/combobox/ja-JP.json +7 -0
- package/src/intl/combobox/ko-KR.json +7 -0
- package/src/intl/combobox/lt-LT.json +7 -0
- package/src/intl/combobox/lv-LV.json +7 -0
- package/src/intl/combobox/nb-NO.json +7 -0
- package/src/intl/combobox/nl-NL.json +7 -0
- package/src/intl/combobox/pl-PL.json +7 -0
- package/src/intl/combobox/pt-BR.json +7 -0
- package/src/intl/combobox/pt-PT.json +7 -0
- package/src/intl/combobox/ro-RO.json +7 -0
- package/src/intl/combobox/ru-RU.json +7 -0
- package/src/intl/combobox/sk-SK.json +7 -0
- package/src/intl/combobox/sl-SI.json +7 -0
- package/src/intl/combobox/sr-SP.json +7 -0
- package/src/intl/combobox/sv-SE.json +7 -0
- package/src/intl/combobox/tr-TR.json +7 -0
- package/src/intl/combobox/uk-UA.json +7 -0
- package/src/intl/combobox/zh-CN.json +7 -0
- package/src/intl/combobox/zh-TW.json +7 -0
- package/src/intl/grid/ar-AE.json +8 -0
- package/src/intl/grid/bg-BG.json +8 -0
- package/src/intl/grid/cs-CZ.json +8 -0
- package/src/intl/grid/da-DK.json +8 -0
- package/src/intl/grid/de-DE.json +8 -0
- package/src/intl/grid/el-GR.json +8 -0
- package/src/intl/grid/en-US.json +8 -0
- package/src/intl/grid/es-ES.json +8 -0
- package/src/intl/grid/et-EE.json +8 -0
- package/src/intl/grid/fi-FI.json +8 -0
- package/src/intl/grid/fr-FR.json +8 -0
- package/src/intl/grid/he-IL.json +8 -0
- package/src/intl/grid/hr-HR.json +8 -0
- package/src/intl/grid/hu-HU.json +8 -0
- package/src/intl/grid/index.ts +75 -0
- package/src/intl/grid/it-IT.json +8 -0
- package/src/intl/grid/ja-JP.json +8 -0
- package/src/intl/grid/ko-KR.json +8 -0
- package/src/intl/grid/lt-LT.json +8 -0
- package/src/intl/grid/lv-LV.json +8 -0
- package/src/intl/grid/nb-NO.json +8 -0
- package/src/intl/grid/nl-NL.json +8 -0
- package/src/intl/grid/pl-PL.json +8 -0
- package/src/intl/grid/pt-BR.json +8 -0
- package/src/intl/grid/pt-PT.json +8 -0
- package/src/intl/grid/ro-RO.json +8 -0
- package/src/intl/grid/ru-RU.json +8 -0
- package/src/intl/grid/sk-SK.json +8 -0
- package/src/intl/grid/sl-SI.json +8 -0
- package/src/intl/grid/sr-SP.json +8 -0
- package/src/intl/grid/sv-SE.json +8 -0
- package/src/intl/grid/tr-TR.json +8 -0
- package/src/intl/grid/uk-UA.json +8 -0
- package/src/intl/grid/zh-CN.json +8 -0
- package/src/intl/grid/zh-TW.json +8 -0
- package/src/intl/gridlist/ar-AE.json +4 -0
- package/src/intl/gridlist/bg-BG.json +4 -0
- package/src/intl/gridlist/cs-CZ.json +4 -0
- package/src/intl/gridlist/da-DK.json +4 -0
- package/src/intl/gridlist/de-DE.json +4 -0
- package/src/intl/gridlist/el-GR.json +4 -0
- package/src/intl/gridlist/en-US.json +4 -0
- package/src/intl/gridlist/es-ES.json +4 -0
- package/src/intl/gridlist/et-EE.json +4 -0
- package/src/intl/gridlist/fi-FI.json +4 -0
- package/src/intl/gridlist/fr-FR.json +4 -0
- package/src/intl/gridlist/he-IL.json +4 -0
- package/src/intl/gridlist/hr-HR.json +4 -0
- package/src/intl/gridlist/hu-HU.json +4 -0
- package/src/intl/gridlist/index.ts +75 -0
- package/src/intl/gridlist/it-IT.json +4 -0
- package/src/intl/gridlist/ja-JP.json +4 -0
- package/src/intl/gridlist/ko-KR.json +4 -0
- package/src/intl/gridlist/lt-LT.json +4 -0
- package/src/intl/gridlist/lv-LV.json +4 -0
- package/src/intl/gridlist/nb-NO.json +4 -0
- package/src/intl/gridlist/nl-NL.json +4 -0
- package/src/intl/gridlist/pl-PL.json +4 -0
- package/src/intl/gridlist/pt-BR.json +4 -0
- package/src/intl/gridlist/pt-PT.json +4 -0
- package/src/intl/gridlist/ro-RO.json +4 -0
- package/src/intl/gridlist/ru-RU.json +4 -0
- package/src/intl/gridlist/sk-SK.json +4 -0
- package/src/intl/gridlist/sl-SI.json +4 -0
- package/src/intl/gridlist/sr-SP.json +4 -0
- package/src/intl/gridlist/sv-SE.json +4 -0
- package/src/intl/gridlist/tr-TR.json +4 -0
- package/src/intl/gridlist/uk-UA.json +4 -0
- package/src/intl/gridlist/zh-CN.json +4 -0
- package/src/intl/gridlist/zh-TW.json +4 -0
- package/src/intl/menu/ar-AE.json +3 -0
- package/src/intl/menu/bg-BG.json +3 -0
- package/src/intl/menu/cs-CZ.json +3 -0
- package/src/intl/menu/da-DK.json +3 -0
- package/src/intl/menu/de-DE.json +3 -0
- package/src/intl/menu/el-GR.json +3 -0
- package/src/intl/menu/en-US.json +3 -0
- package/src/intl/menu/es-ES.json +3 -0
- package/src/intl/menu/et-EE.json +3 -0
- package/src/intl/menu/fi-FI.json +3 -0
- package/src/intl/menu/fr-FR.json +3 -0
- package/src/intl/menu/he-IL.json +3 -0
- package/src/intl/menu/hr-HR.json +3 -0
- package/src/intl/menu/hu-HU.json +3 -0
- package/src/intl/menu/index.ts +75 -0
- package/src/intl/menu/it-IT.json +3 -0
- package/src/intl/menu/ja-JP.json +3 -0
- package/src/intl/menu/ko-KR.json +3 -0
- package/src/intl/menu/lt-LT.json +3 -0
- package/src/intl/menu/lv-LV.json +3 -0
- package/src/intl/menu/nb-NO.json +3 -0
- package/src/intl/menu/nl-NL.json +3 -0
- package/src/intl/menu/pl-PL.json +3 -0
- package/src/intl/menu/pt-BR.json +3 -0
- package/src/intl/menu/pt-PT.json +3 -0
- package/src/intl/menu/ro-RO.json +3 -0
- package/src/intl/menu/ru-RU.json +3 -0
- package/src/intl/menu/sk-SK.json +3 -0
- package/src/intl/menu/sl-SI.json +3 -0
- package/src/intl/menu/sr-SP.json +3 -0
- package/src/intl/menu/sv-SE.json +3 -0
- package/src/intl/menu/tr-TR.json +3 -0
- package/src/intl/menu/uk-UA.json +3 -0
- package/src/intl/menu/zh-CN.json +3 -0
- package/src/intl/menu/zh-TW.json +3 -0
- package/src/intl/numberfield/ar-AE.json +5 -0
- package/src/intl/numberfield/bg-BG.json +5 -0
- package/src/intl/numberfield/cs-CZ.json +5 -0
- package/src/intl/numberfield/da-DK.json +5 -0
- package/src/intl/numberfield/de-DE.json +5 -0
- package/src/intl/numberfield/el-GR.json +5 -0
- package/src/intl/numberfield/en-US.json +5 -0
- package/src/intl/numberfield/es-ES.json +5 -0
- package/src/intl/numberfield/et-EE.json +5 -0
- package/src/intl/numberfield/fi-FI.json +5 -0
- package/src/intl/numberfield/fr-FR.json +5 -0
- package/src/intl/numberfield/he-IL.json +5 -0
- package/src/intl/numberfield/hr-HR.json +5 -0
- package/src/intl/numberfield/hu-HU.json +5 -0
- package/src/intl/numberfield/index.ts +75 -0
- package/src/intl/numberfield/it-IT.json +5 -0
- package/src/intl/numberfield/ja-JP.json +5 -0
- package/src/intl/numberfield/ko-KR.json +5 -0
- package/src/intl/numberfield/lt-LT.json +5 -0
- package/src/intl/numberfield/lv-LV.json +5 -0
- package/src/intl/numberfield/nb-NO.json +5 -0
- package/src/intl/numberfield/nl-NL.json +5 -0
- package/src/intl/numberfield/pl-PL.json +5 -0
- package/src/intl/numberfield/pt-BR.json +5 -0
- package/src/intl/numberfield/pt-PT.json +5 -0
- package/src/intl/numberfield/ro-RO.json +5 -0
- package/src/intl/numberfield/ru-RU.json +5 -0
- package/src/intl/numberfield/sk-SK.json +5 -0
- package/src/intl/numberfield/sl-SI.json +5 -0
- package/src/intl/numberfield/sr-SP.json +5 -0
- package/src/intl/numberfield/sv-SE.json +5 -0
- package/src/intl/numberfield/tr-TR.json +5 -0
- package/src/intl/numberfield/uk-UA.json +5 -0
- package/src/intl/numberfield/zh-CN.json +5 -0
- package/src/intl/numberfield/zh-TW.json +5 -0
- package/src/intl/overlays/ar-AE.json +3 -0
- package/src/intl/overlays/bg-BG.json +3 -0
- package/src/intl/overlays/cs-CZ.json +3 -0
- package/src/intl/overlays/da-DK.json +3 -0
- package/src/intl/overlays/de-DE.json +3 -0
- package/src/intl/overlays/el-GR.json +3 -0
- package/src/intl/overlays/en-US.json +3 -0
- package/src/intl/overlays/es-ES.json +3 -0
- package/src/intl/overlays/et-EE.json +3 -0
- package/src/intl/overlays/fi-FI.json +3 -0
- package/src/intl/overlays/fr-FR.json +3 -0
- package/src/intl/overlays/he-IL.json +3 -0
- package/src/intl/overlays/hr-HR.json +3 -0
- package/src/intl/overlays/hu-HU.json +3 -0
- package/src/intl/overlays/index.ts +75 -0
- package/src/intl/overlays/it-IT.json +3 -0
- package/src/intl/overlays/ja-JP.json +3 -0
- package/src/intl/overlays/ko-KR.json +3 -0
- package/src/intl/overlays/lt-LT.json +3 -0
- package/src/intl/overlays/lv-LV.json +3 -0
- package/src/intl/overlays/nb-NO.json +3 -0
- package/src/intl/overlays/nl-NL.json +3 -0
- package/src/intl/overlays/pl-PL.json +3 -0
- package/src/intl/overlays/pt-BR.json +3 -0
- package/src/intl/overlays/pt-PT.json +3 -0
- package/src/intl/overlays/ro-RO.json +3 -0
- package/src/intl/overlays/ru-RU.json +3 -0
- package/src/intl/overlays/sk-SK.json +3 -0
- package/src/intl/overlays/sl-SI.json +3 -0
- package/src/intl/overlays/sr-SP.json +3 -0
- package/src/intl/overlays/sv-SE.json +3 -0
- package/src/intl/overlays/tr-TR.json +3 -0
- package/src/intl/overlays/uk-UA.json +3 -0
- package/src/intl/overlays/zh-CN.json +3 -0
- package/src/intl/overlays/zh-TW.json +3 -0
- package/src/intl/searchfield/ar-AE.json +3 -0
- package/src/intl/searchfield/bg-BG.json +3 -0
- package/src/intl/searchfield/cs-CZ.json +3 -0
- package/src/intl/searchfield/da-DK.json +3 -0
- package/src/intl/searchfield/de-DE.json +3 -0
- package/src/intl/searchfield/el-GR.json +3 -0
- package/src/intl/searchfield/en-US.json +3 -0
- package/src/intl/searchfield/es-ES.json +3 -0
- package/src/intl/searchfield/et-EE.json +3 -0
- package/src/intl/searchfield/fi-FI.json +3 -0
- package/src/intl/searchfield/fr-FR.json +3 -0
- package/src/intl/searchfield/he-IL.json +3 -0
- package/src/intl/searchfield/hr-HR.json +3 -0
- package/src/intl/searchfield/hu-HU.json +3 -0
- package/src/intl/searchfield/index.ts +75 -0
- package/src/intl/searchfield/it-IT.json +3 -0
- package/src/intl/searchfield/ja-JP.json +3 -0
- package/src/intl/searchfield/ko-KR.json +3 -0
- package/src/intl/searchfield/lt-LT.json +3 -0
- package/src/intl/searchfield/lv-LV.json +3 -0
- package/src/intl/searchfield/nb-NO.json +3 -0
- package/src/intl/searchfield/nl-NL.json +3 -0
- package/src/intl/searchfield/pl-PL.json +3 -0
- package/src/intl/searchfield/pt-BR.json +3 -0
- package/src/intl/searchfield/pt-PT.json +3 -0
- package/src/intl/searchfield/ro-RO.json +3 -0
- package/src/intl/searchfield/ru-RU.json +3 -0
- package/src/intl/searchfield/sk-SK.json +3 -0
- package/src/intl/searchfield/sl-SI.json +3 -0
- package/src/intl/searchfield/sr-SP.json +3 -0
- package/src/intl/searchfield/sv-SE.json +3 -0
- package/src/intl/searchfield/tr-TR.json +3 -0
- package/src/intl/searchfield/uk-UA.json +3 -0
- package/src/intl/searchfield/zh-CN.json +3 -0
- package/src/intl/searchfield/zh-TW.json +3 -0
- package/src/intl/spinbutton/ar-AE.json +3 -0
- package/src/intl/spinbutton/bg-BG.json +3 -0
- package/src/intl/spinbutton/cs-CZ.json +3 -0
- package/src/intl/spinbutton/da-DK.json +3 -0
- package/src/intl/spinbutton/de-DE.json +3 -0
- package/src/intl/spinbutton/el-GR.json +3 -0
- package/src/intl/spinbutton/en-US.json +3 -0
- package/src/intl/spinbutton/es-ES.json +3 -0
- package/src/intl/spinbutton/et-EE.json +3 -0
- package/src/intl/spinbutton/fi-FI.json +3 -0
- package/src/intl/spinbutton/fr-FR.json +3 -0
- package/src/intl/spinbutton/he-IL.json +3 -0
- package/src/intl/spinbutton/hr-HR.json +3 -0
- package/src/intl/spinbutton/hu-HU.json +3 -0
- package/src/intl/spinbutton/index.ts +75 -0
- package/src/intl/spinbutton/it-IT.json +3 -0
- package/src/intl/spinbutton/ja-JP.json +3 -0
- package/src/intl/spinbutton/ko-KR.json +3 -0
- package/src/intl/spinbutton/lt-LT.json +3 -0
- package/src/intl/spinbutton/lv-LV.json +3 -0
- package/src/intl/spinbutton/nb-NO.json +3 -0
- package/src/intl/spinbutton/nl-NL.json +3 -0
- package/src/intl/spinbutton/pl-PL.json +3 -0
- package/src/intl/spinbutton/pt-BR.json +3 -0
- package/src/intl/spinbutton/pt-PT.json +3 -0
- package/src/intl/spinbutton/ro-RO.json +3 -0
- package/src/intl/spinbutton/ru-RU.json +3 -0
- package/src/intl/spinbutton/sk-SK.json +3 -0
- package/src/intl/spinbutton/sl-SI.json +3 -0
- package/src/intl/spinbutton/sr-SP.json +3 -0
- package/src/intl/spinbutton/sv-SE.json +3 -0
- package/src/intl/spinbutton/tr-TR.json +3 -0
- package/src/intl/spinbutton/uk-UA.json +3 -0
- package/src/intl/spinbutton/zh-CN.json +3 -0
- package/src/intl/spinbutton/zh-TW.json +3 -0
- package/src/intl/tag/ar-AE.json +4 -0
- package/src/intl/tag/bg-BG.json +4 -0
- package/src/intl/tag/cs-CZ.json +4 -0
- package/src/intl/tag/da-DK.json +4 -0
- package/src/intl/tag/de-DE.json +4 -0
- package/src/intl/tag/el-GR.json +4 -0
- package/src/intl/tag/en-US.json +4 -0
- package/src/intl/tag/es-ES.json +4 -0
- package/src/intl/tag/et-EE.json +4 -0
- package/src/intl/tag/fi-FI.json +4 -0
- package/src/intl/tag/fr-FR.json +4 -0
- package/src/intl/tag/he-IL.json +4 -0
- package/src/intl/tag/hr-HR.json +4 -0
- package/src/intl/tag/hu-HU.json +4 -0
- package/src/intl/tag/index.ts +75 -0
- package/src/intl/tag/it-IT.json +4 -0
- package/src/intl/tag/ja-JP.json +4 -0
- package/src/intl/tag/ko-KR.json +4 -0
- package/src/intl/tag/lt-LT.json +4 -0
- package/src/intl/tag/lv-LV.json +4 -0
- package/src/intl/tag/nb-NO.json +4 -0
- package/src/intl/tag/nl-NL.json +4 -0
- package/src/intl/tag/pl-PL.json +4 -0
- package/src/intl/tag/pt-BR.json +4 -0
- package/src/intl/tag/pt-PT.json +4 -0
- package/src/intl/tag/ro-RO.json +4 -0
- package/src/intl/tag/ru-RU.json +4 -0
- package/src/intl/tag/sk-SK.json +4 -0
- package/src/intl/tag/sl-SI.json +4 -0
- package/src/intl/tag/sr-SP.json +4 -0
- package/src/intl/tag/sv-SE.json +4 -0
- package/src/intl/tag/tr-TR.json +4 -0
- package/src/intl/tag/uk-UA.json +4 -0
- package/src/intl/tag/zh-CN.json +4 -0
- package/src/intl/tag/zh-TW.json +4 -0
- package/src/label/useField.ts +67 -0
- package/src/label/useLabel.ts +78 -0
- package/src/link/useLink.ts +108 -0
- package/src/listbox/useListBox.ts +224 -0
- package/src/listbox/useListBoxSection.ts +74 -0
- package/src/listbox/useOption.ts +212 -0
- package/src/listbox/utils.ts +38 -0
- package/src/live-announcer/LiveAnnouncer.ts +172 -0
- package/src/menu/useMenu.ts +139 -0
- package/src/menu/useMenuItem.ts +453 -0
- package/src/menu/useMenuSection.ts +70 -0
- package/src/menu/useMenuTrigger.ts +189 -0
- package/src/menu/useSafelyMouseToSubmenu.ts +236 -0
- package/src/menu/useSubmenuTrigger.ts +357 -0
- package/src/menu/utils.ts +16 -0
- package/src/meter/useMeter.ts +43 -0
- package/src/numberfield/useNumberField.ts +572 -0
- package/src/overlays/DismissButton.ts +50 -0
- package/src/overlays/Overlay.ts +106 -0
- package/src/overlays/PortalProvider.ts +37 -0
- package/src/overlays/ariaHideOutside.ts +299 -0
- package/src/overlays/calculatePosition.ts +856 -0
- package/src/overlays/useCloseOnScroll.ts +75 -0
- package/src/overlays/useModal.ts +224 -0
- package/src/overlays/useModalOverlay.ts +103 -0
- package/src/overlays/useOverlay.ts +199 -0
- package/src/overlays/useOverlayPosition.ts +462 -0
- package/src/overlays/useOverlayTrigger.ts +94 -0
- package/src/overlays/usePopover.ts +170 -0
- package/src/overlays/usePreventScroll.ts +316 -0
- package/src/progress/useProgressBar.ts +115 -0
- package/src/radio/useRadio.ts +219 -0
- package/src/radio/useRadioGroup.ts +184 -0
- package/src/radio/utils.ts +15 -0
- package/src/searchfield/useSearchField.ts +156 -0
- package/src/select/HiddenSelect.ts +261 -0
- package/src/select/useSelect.ts +332 -0
- package/src/selection/DOMLayoutDelegate.ts +51 -0
- package/src/selection/ListKeyboardDelegate.ts +392 -0
- package/src/selection/useSelectableCollection.ts +750 -0
- package/src/selection/useSelectableItem.ts +499 -0
- package/src/selection/useSelectableList.ts +132 -0
- package/src/selection/useTypeSelect.ts +192 -0
- package/src/selection/utils.ts +50 -0
- package/src/separator/useSeparator.ts +41 -0
- package/src/slider/useSlider.ts +277 -0
- package/src/slider/useSliderThumb.ts +375 -0
- package/src/slider/utils.ts +20 -0
- package/src/spinbutton/useSpinButton.ts +380 -0
- package/src/stately/checkbox/useCheckboxGroupState.ts +177 -0
- package/src/stately/collections/CollectionBuilder.ts +332 -0
- package/src/stately/collections/Item.ts +78 -0
- package/src/stately/collections/Section.ts +52 -0
- package/src/stately/collections/getChildNodes.ts +94 -0
- package/src/stately/collections/getItemCount.ts +29 -0
- package/src/stately/collections/types.ts +20 -0
- package/src/stately/collections/useCollection.ts +54 -0
- package/src/stately/combobox/useComboBoxState.ts +763 -0
- package/src/stately/disclosure/useDisclosureGroupState.ts +108 -0
- package/src/stately/disclosure/useDisclosureState.ts +84 -0
- package/src/stately/form/useFormValidationState.ts +331 -0
- package/src/stately/index.ts +111 -0
- package/src/stately/list/ListCollection.ts +104 -0
- package/src/stately/list/useListState.ts +178 -0
- package/src/stately/list/useSingleSelectListState.ts +101 -0
- package/src/stately/menu/useMenuTriggerState.ts +120 -0
- package/src/stately/menu/useSubmenuTriggerState.ts +116 -0
- package/src/stately/numberfield/useNumberFieldState.ts +430 -0
- package/src/stately/overlays/useOverlayTriggerState.ts +85 -0
- package/src/stately/radio/useRadioGroupState.ts +150 -0
- package/src/stately/searchfield/useSearchFieldState.ts +79 -0
- package/src/stately/select/useSelectState.ts +322 -0
- package/src/stately/selection/Selection.ts +23 -0
- package/src/stately/selection/SelectionManager.ts +541 -0
- package/src/stately/selection/types.ts +117 -0
- package/src/stately/selection/useMultipleSelectionState.ts +178 -0
- package/src/stately/slider/useSliderState.ts +458 -0
- package/src/stately/tabs/useTabListState.ts +149 -0
- package/src/stately/toggle/useToggleGroupState.ts +109 -0
- package/src/stately/toggle/useToggleState.ts +100 -0
- package/src/stately/tooltip/useTooltipTriggerState.ts +218 -0
- package/src/stately/tree/TreeCollection.ts +92 -0
- package/src/stately/tree/useTreeState.ts +121 -0
- package/src/stately/utils/useControlledState.ts +7 -0
- package/src/switch/useSwitch.ts +77 -0
- package/src/tabs/TabsKeyboardDelegate.ts +99 -0
- package/src/tabs/useTab.ts +117 -0
- package/src/tabs/useTabList.ts +105 -0
- package/src/tabs/useTabPanel.ts +75 -0
- package/src/tabs/utils.ts +32 -0
- package/src/tag/useTag.ts +162 -0
- package/src/tag/useTagGroup.ts +192 -0
- package/src/textfield/useFormattedTextField.ts +203 -0
- package/src/textfield/useTextField.ts +248 -0
- package/src/toggle/useToggle.ts +265 -0
- package/src/toolbar/useToolbar.ts +147 -0
- package/src/tooltip/useTooltip.ts +64 -0
- package/src/tooltip/useTooltipTrigger.ts +187 -0
- package/src/utils/filterDOMProps.ts +121 -0
- package/src/utils/getScrollParent.ts +16 -0
- package/src/utils/getScrollParents.ts +20 -0
- package/src/utils/keyboard.ts +38 -0
- package/src/utils/scrollIntoView.ts +178 -0
- package/src/utils/useDeepMemo.ts +30 -0
- package/src/utils/useFormReset.ts +54 -0
- package/src/utils/useId.ts +5 -0
- package/src/utils/useLabels.ts +53 -0
- package/src/utils/useResizeObserver.ts +70 -0
- package/src/utils/useSlot.ts +78 -0
- package/src/utils/useUpdateEffect.ts +54 -0
- package/src/utils/useUpdateLayoutEffect.ts +58 -0
- package/src/visually-hidden/VisuallyHidden.ts +100 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/I18nProvider.tsx).
|
|
2
|
+
// octane adaptations:
|
|
3
|
+
// - `.tsx` → `.ts`: JSX → createElement (plain-`.ts` components get no compiled slots —
|
|
4
|
+
// hooks use the stable S()/subSlot component-slot convention). The Provider descriptor
|
|
5
|
+
// keeps a stable `{ value, children }` shape.
|
|
6
|
+
// - React's `ReactNode`/`JSX.Element` types → `any` (octane descriptors).
|
|
7
|
+
// - `useLocale` gets the public-hook slot threading (splitSlot/subSlot) per the binding
|
|
8
|
+
// convention; `useContext` needs no slot (context-identity keyed).
|
|
9
|
+
import type { Direction } from '@react-types/shared';
|
|
10
|
+
import { createContext, createElement, useContext, useMemo } from 'octane';
|
|
11
|
+
|
|
12
|
+
import { S, splitSlot, subSlot } from '../internal';
|
|
13
|
+
import { isRTL } from './utils';
|
|
14
|
+
import { useDefaultLocale } from './useDefaultLocale';
|
|
15
|
+
|
|
16
|
+
export interface Locale {
|
|
17
|
+
/** The [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) language code for the locale. */
|
|
18
|
+
locale: string;
|
|
19
|
+
/** The writing direction for the locale. */
|
|
20
|
+
direction: Direction;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface I18nProviderProps {
|
|
24
|
+
/** Contents that should have the locale applied. */
|
|
25
|
+
children: any;
|
|
26
|
+
/** The locale to apply to the children. */
|
|
27
|
+
locale?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const I18nContext = createContext<Locale | null>(null);
|
|
31
|
+
|
|
32
|
+
interface I18nProviderWithLocaleProps extends I18nProviderProps {
|
|
33
|
+
locale: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Internal component that handles the case when locale is provided.
|
|
38
|
+
*/
|
|
39
|
+
function I18nProviderWithLocale(props: I18nProviderWithLocaleProps): any {
|
|
40
|
+
const slot = S('I18nProviderWithLocale');
|
|
41
|
+
let { locale, children } = props;
|
|
42
|
+
let value: Locale = useMemo(
|
|
43
|
+
() => ({
|
|
44
|
+
locale,
|
|
45
|
+
direction: isRTL(locale) ? 'rtl' : 'ltr',
|
|
46
|
+
}),
|
|
47
|
+
[locale],
|
|
48
|
+
subSlot(slot, 'value'),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return createElement(I18nContext.Provider, { value, children });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface I18nProviderWithDefaultLocaleProps {
|
|
55
|
+
children: any;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Internal component that handles the case when no locale is provided.
|
|
60
|
+
*/
|
|
61
|
+
function I18nProviderWithDefaultLocale(props: I18nProviderWithDefaultLocaleProps): any {
|
|
62
|
+
const slot = S('I18nProviderWithDefaultLocale');
|
|
63
|
+
let { children } = props;
|
|
64
|
+
let defaultLocale = useDefaultLocale(subSlot(slot, 'default'));
|
|
65
|
+
|
|
66
|
+
return createElement(I18nContext.Provider, { value: defaultLocale, children });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Provides the locale for the application to all child components.
|
|
71
|
+
*/
|
|
72
|
+
export function I18nProvider(props: I18nProviderProps): any {
|
|
73
|
+
let { locale, children } = props;
|
|
74
|
+
|
|
75
|
+
// Conditionally render different components to avoid calling useDefaultLocale.
|
|
76
|
+
// This is necessary because useDefaultLocale triggers a re-render.
|
|
77
|
+
if (locale) {
|
|
78
|
+
return createElement(I18nProviderWithLocale, { locale, children });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return createElement(I18nProviderWithDefaultLocale, { children });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns the current locale and layout direction.
|
|
86
|
+
*/
|
|
87
|
+
export function useLocale(): Locale;
|
|
88
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
89
|
+
export function useLocale(slot: symbol | undefined): Locale;
|
|
90
|
+
export function useLocale(...args: any[]): Locale {
|
|
91
|
+
const [, slotArg] = splitSlot(args);
|
|
92
|
+
const slot = slotArg ?? S('useLocale');
|
|
93
|
+
|
|
94
|
+
let defaultLocale = useDefaultLocale(subSlot(slot, 'default'));
|
|
95
|
+
let context = useContext(I18nContext);
|
|
96
|
+
return context || defaultLocale;
|
|
97
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/server.tsx).
|
|
2
|
+
// NOT React-Server-Components machinery — a portable SSR helper: a component rendered
|
|
3
|
+
// during server rendering that injects the locale + localized string tables into the
|
|
4
|
+
// initial HTML via an inline <script> (read back on the client through the
|
|
5
|
+
// `react-aria.i18n.locale` / `react-aria.i18n.strings` window symbols that
|
|
6
|
+
// `useDefaultLocale` and `@internationalized/string` consume). octane adaptations:
|
|
7
|
+
// - `.tsx` → `.ts`: JSX → createElement; octane supports `dangerouslySetInnerHTML` and
|
|
8
|
+
// `suppressHydrationWarning` with React semantics.
|
|
9
|
+
// - React's `JSX.Element` type → `any` (octane descriptors).
|
|
10
|
+
// - The dev-only "should only be rendered on the server" console.log is not ported
|
|
11
|
+
// (repo policy); the client-side `return null` guard is kept.
|
|
12
|
+
import type { LocalizedString } from '@internationalized/string';
|
|
13
|
+
import { createElement } from 'octane';
|
|
14
|
+
|
|
15
|
+
type PackageLocalizedStrings = {
|
|
16
|
+
[packageName: string]: Record<string, LocalizedString>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface PackageLocalizationProviderProps {
|
|
20
|
+
locale: string;
|
|
21
|
+
strings: PackageLocalizedStrings;
|
|
22
|
+
nonce?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A PackageLocalizationProvider can be rendered on the server to inject the localized strings
|
|
27
|
+
* needed by the client into the initial HTML.
|
|
28
|
+
*/
|
|
29
|
+
export function PackageLocalizationProvider(props: PackageLocalizationProviderProps): any {
|
|
30
|
+
if (typeof document !== 'undefined') {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let { nonce, locale, strings } = props;
|
|
35
|
+
// suppressHydrationWarning is necessary because the browser
|
|
36
|
+
// remove the nonce parameter from the DOM before hydration
|
|
37
|
+
return createElement('script', {
|
|
38
|
+
nonce: typeof window === 'undefined' ? nonce : '',
|
|
39
|
+
suppressHydrationWarning: true,
|
|
40
|
+
dangerouslySetInnerHTML: { __html: getPackageLocalizationScript(locale, strings) },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns the content for an inline `<script>` tag to inject localized strings into initial HTML.
|
|
46
|
+
*/
|
|
47
|
+
export function getPackageLocalizationScript(
|
|
48
|
+
locale: string,
|
|
49
|
+
strings: PackageLocalizedStrings,
|
|
50
|
+
): string {
|
|
51
|
+
return `window[Symbol.for('react-aria.i18n.locale')]=${JSON.stringify(locale)};{${serialize(strings)}}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const cache = new WeakMap<PackageLocalizedStrings, string>();
|
|
55
|
+
|
|
56
|
+
// octane adaptation (upstream bug): upstream names hoisted strings with
|
|
57
|
+
// `String.fromCharCode(common.size > 25 ? common.size + 97 : common.size + 65)`,
|
|
58
|
+
// which is 'A'-'Z' for the first 26 but char codes 123+ ('{', '|', …) from the
|
|
59
|
+
// 27th on — the emitted script is a SyntaxError. A-Z matches upstream's valid
|
|
60
|
+
// range byte-for-byte; a-z and then _N continue with valid identifiers ('_N'
|
|
61
|
+
// rather than two-letter names, which could collide with reserved words).
|
|
62
|
+
function commonName(i: number): string {
|
|
63
|
+
if (i < 26) return String.fromCharCode(i + 65);
|
|
64
|
+
if (i < 52) return String.fromCharCode(i + 71);
|
|
65
|
+
return '_' + (i - 52);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function serialize(strings: PackageLocalizedStrings): string {
|
|
69
|
+
let cached = cache.get(strings);
|
|
70
|
+
if (cached) {
|
|
71
|
+
return cached;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Find common strings between packages and hoist them into variables.
|
|
75
|
+
let seen = new Set();
|
|
76
|
+
let common = new Map();
|
|
77
|
+
for (let pkg in strings) {
|
|
78
|
+
for (let key in strings[pkg]) {
|
|
79
|
+
let v = strings[pkg][key];
|
|
80
|
+
let s = typeof v === 'string' ? JSON.stringify(v) : v.toString();
|
|
81
|
+
if (seen.has(s) && !common.has(s)) {
|
|
82
|
+
common.set(s, commonName(common.size));
|
|
83
|
+
}
|
|
84
|
+
seen.add(s);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let res = '';
|
|
89
|
+
if (common.size > 0) {
|
|
90
|
+
res += 'let ';
|
|
91
|
+
}
|
|
92
|
+
for (let [string, name] of common) {
|
|
93
|
+
res += `${name}=${string},`;
|
|
94
|
+
}
|
|
95
|
+
if (common.size > 0) {
|
|
96
|
+
res = res.slice(0, -1) + ';';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
res += "window[Symbol.for('react-aria.i18n.strings')]={";
|
|
100
|
+
for (let pkg in strings) {
|
|
101
|
+
res += `'${pkg}':{`;
|
|
102
|
+
for (let key in strings[pkg]) {
|
|
103
|
+
let v = strings[pkg][key];
|
|
104
|
+
let s = typeof v === 'string' ? JSON.stringify(v) : v.toString();
|
|
105
|
+
if (common.has(s)) {
|
|
106
|
+
s = common.get(s);
|
|
107
|
+
}
|
|
108
|
+
res += `${/[ ()]/.test(key) ? JSON.stringify(key) : key}:${s},`;
|
|
109
|
+
}
|
|
110
|
+
res = res.slice(0, -1) + '},';
|
|
111
|
+
}
|
|
112
|
+
res = res.slice(0, -1) + '};';
|
|
113
|
+
cache.set(strings, res);
|
|
114
|
+
return res;
|
|
115
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/useCollator.ts).
|
|
2
|
+
// octane adaptations: public-hook slot threading (splitSlot/subSlot) per the binding
|
|
3
|
+
// convention; the module-level collator cache ports verbatim.
|
|
4
|
+
import { S, splitSlot, subSlot } from '../internal';
|
|
5
|
+
import { useLocale } from './I18nProvider';
|
|
6
|
+
|
|
7
|
+
let cache = new Map<string, Intl.Collator>();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Provides localized string collation for the current locale. Automatically updates when the locale
|
|
11
|
+
* changes, and handles caching of the collator for performance.
|
|
12
|
+
*
|
|
13
|
+
* @param options - Collator options.
|
|
14
|
+
*/
|
|
15
|
+
export function useCollator(options?: Intl.CollatorOptions): Intl.Collator;
|
|
16
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
17
|
+
export function useCollator(
|
|
18
|
+
options: Intl.CollatorOptions | undefined,
|
|
19
|
+
slot: symbol | undefined,
|
|
20
|
+
): Intl.Collator;
|
|
21
|
+
export function useCollator(...args: any[]): Intl.Collator {
|
|
22
|
+
const [user, slotArg] = splitSlot(args);
|
|
23
|
+
const slot = slotArg ?? S('useCollator');
|
|
24
|
+
const options = user[0] as Intl.CollatorOptions | undefined;
|
|
25
|
+
|
|
26
|
+
let { locale } = useLocale(subSlot(slot, 'locale'));
|
|
27
|
+
|
|
28
|
+
let cacheKey =
|
|
29
|
+
locale +
|
|
30
|
+
(options
|
|
31
|
+
? Object.entries(options)
|
|
32
|
+
.sort((a, b) => (a[0] < b[0] ? -1 : 1))
|
|
33
|
+
.join()
|
|
34
|
+
: '');
|
|
35
|
+
if (cache.has(cacheKey)) {
|
|
36
|
+
return cache.get(cacheKey)!;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let formatter = new Intl.Collator(locale, options);
|
|
40
|
+
cache.set(cacheKey, formatter);
|
|
41
|
+
return formatter;
|
|
42
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/useDateFormatter.ts).
|
|
2
|
+
// octane adaptations: public-hook slot threading (splitSlot/subSlot) per the binding
|
|
3
|
+
// convention; the explicit `[locale, options]` memo deps are preserved exactly; the
|
|
4
|
+
// `isEqual` key reads cast through `Record<string, any>` (strict index typing).
|
|
5
|
+
import { DateFormatter } from '@internationalized/date';
|
|
6
|
+
import { useMemo } from 'octane';
|
|
7
|
+
|
|
8
|
+
import { S, splitSlot, subSlot } from '../internal';
|
|
9
|
+
import { useDeepMemo } from '../utils/useDeepMemo';
|
|
10
|
+
import { useLocale } from './I18nProvider';
|
|
11
|
+
|
|
12
|
+
export interface DateFormatterOptions extends Intl.DateTimeFormatOptions {
|
|
13
|
+
calendar?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Provides localized date formatting for the current locale. Automatically updates when the locale
|
|
18
|
+
* changes, and handles caching of the date formatter for performance.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Formatting options.
|
|
21
|
+
*/
|
|
22
|
+
export function useDateFormatter(options?: DateFormatterOptions): DateFormatter;
|
|
23
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
24
|
+
export function useDateFormatter(
|
|
25
|
+
options: DateFormatterOptions | undefined,
|
|
26
|
+
slot: symbol | undefined,
|
|
27
|
+
): DateFormatter;
|
|
28
|
+
export function useDateFormatter(...args: any[]): DateFormatter {
|
|
29
|
+
const [user, slotArg] = splitSlot(args);
|
|
30
|
+
const slot = slotArg ?? S('useDateFormatter');
|
|
31
|
+
|
|
32
|
+
// Reuse last options object if it is shallowly equal, which allows the useMemo result to also be reused.
|
|
33
|
+
let options = useDeepMemo(
|
|
34
|
+
(user[0] as DateFormatterOptions | undefined) ?? {},
|
|
35
|
+
isEqual,
|
|
36
|
+
subSlot(slot, 'options'),
|
|
37
|
+
);
|
|
38
|
+
let { locale } = useLocale(subSlot(slot, 'locale'));
|
|
39
|
+
return useMemo(
|
|
40
|
+
() => new DateFormatter(locale, options),
|
|
41
|
+
[locale, options],
|
|
42
|
+
subSlot(slot, 'formatter'),
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isEqual(a: DateFormatterOptions, b: DateFormatterOptions) {
|
|
47
|
+
if (a === b) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let aKeys = Object.keys(a);
|
|
52
|
+
let bKeys = Object.keys(b);
|
|
53
|
+
if (aKeys.length !== bKeys.length) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (let key of aKeys) {
|
|
58
|
+
if ((b as Record<string, any>)[key] !== (a as Record<string, any>)[key]) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/useDefaultLocale.ts).
|
|
2
|
+
// octane adaptations: public-hook slot threading (splitSlot/subSlot) per the binding
|
|
3
|
+
// convention; the explicit `[]` effect dep array is preserved exactly; `window[localeSymbol]`
|
|
4
|
+
// reads cast through `any` (symbol-keyed Window access). The server-injected locale symbol
|
|
5
|
+
// keeps upstream's exact key so `PackageLocalizationProvider` output stays compatible.
|
|
6
|
+
import { useEffect, useState } from 'octane';
|
|
7
|
+
|
|
8
|
+
import { S, splitSlot, subSlot } from '../internal';
|
|
9
|
+
import { isRTL } from './utils';
|
|
10
|
+
import type { Locale } from './I18nProvider';
|
|
11
|
+
import { useIsSSR } from '../ssr/SSRProvider';
|
|
12
|
+
|
|
13
|
+
// Locale passed from server by PackageLocalizationProvider.
|
|
14
|
+
const localeSymbol = Symbol.for('react-aria.i18n.locale');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gets the locale setting of the browser.
|
|
18
|
+
*/
|
|
19
|
+
export function getDefaultLocale(): Locale {
|
|
20
|
+
let locale =
|
|
21
|
+
(typeof window !== 'undefined' && (window as any)[localeSymbol]) ||
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
(typeof navigator !== 'undefined' && (navigator.language || navigator.userLanguage)) ||
|
|
24
|
+
'en-US';
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
Intl.DateTimeFormat.supportedLocalesOf([locale]);
|
|
28
|
+
} catch {
|
|
29
|
+
locale = 'en-US';
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
locale,
|
|
33
|
+
direction: isRTL(locale) ? 'rtl' : 'ltr',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let currentLocale = getDefaultLocale();
|
|
38
|
+
let listeners = new Set<(locale: Locale) => void>();
|
|
39
|
+
|
|
40
|
+
function updateLocale() {
|
|
41
|
+
currentLocale = getDefaultLocale();
|
|
42
|
+
for (let listener of listeners) {
|
|
43
|
+
listener(currentLocale);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Returns the current browser/system language, and updates when it changes.
|
|
49
|
+
*/
|
|
50
|
+
export function useDefaultLocale(): Locale;
|
|
51
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
52
|
+
export function useDefaultLocale(slot: symbol | undefined): Locale;
|
|
53
|
+
export function useDefaultLocale(...args: any[]): Locale {
|
|
54
|
+
const [, slotArg] = splitSlot(args);
|
|
55
|
+
const slot = slotArg ?? S('useDefaultLocale');
|
|
56
|
+
|
|
57
|
+
let isSSR = useIsSSR(subSlot(slot, 'ssr'));
|
|
58
|
+
let [defaultLocale, setDefaultLocale] = useState(currentLocale, subSlot(slot, 'locale'));
|
|
59
|
+
|
|
60
|
+
useEffect(
|
|
61
|
+
() => {
|
|
62
|
+
if (listeners.size === 0) {
|
|
63
|
+
window.addEventListener('languagechange', updateLocale);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
listeners.add(setDefaultLocale);
|
|
67
|
+
|
|
68
|
+
return () => {
|
|
69
|
+
listeners.delete(setDefaultLocale);
|
|
70
|
+
if (listeners.size === 0) {
|
|
71
|
+
window.removeEventListener('languagechange', updateLocale);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
[],
|
|
76
|
+
subSlot(slot, 'listen'),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// We cannot determine the browser's language on the server, so default to
|
|
80
|
+
// en-US. This will be updated after hydration on the client to the correct value.
|
|
81
|
+
if (isSSR) {
|
|
82
|
+
let locale = typeof window !== 'undefined' && (window as any)[localeSymbol];
|
|
83
|
+
// octane adaptation (upstream bug): upstream hardcodes 'ltr' here even when
|
|
84
|
+
// the server-injected locale is RTL, disagreeing with getDefaultLocale's
|
|
85
|
+
// isRTL derivation for the very same value — derive it from what we return.
|
|
86
|
+
return {
|
|
87
|
+
locale: locale || 'en-US',
|
|
88
|
+
direction: locale && isRTL(locale) ? 'rtl' : 'ltr',
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return defaultLocale;
|
|
93
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/useFilter.ts).
|
|
2
|
+
// octane adaptations: public-hook slot threading (splitSlot/subSlot) per the binding
|
|
3
|
+
// convention; explicit `[collator]` / `[startsWith, endsWith, contains]` dep arrays are
|
|
4
|
+
// preserved exactly; the callback params get explicit `string` types (strict implicit-any).
|
|
5
|
+
import { useCallback, useMemo } from 'octane';
|
|
6
|
+
|
|
7
|
+
import { S, splitSlot, subSlot } from '../internal';
|
|
8
|
+
import { useCollator } from './useCollator';
|
|
9
|
+
|
|
10
|
+
export interface Filter {
|
|
11
|
+
/** Returns whether a string starts with a given substring. */
|
|
12
|
+
startsWith: (string: string, substring: string) => boolean;
|
|
13
|
+
/** Returns whether a string ends with a given substring. */
|
|
14
|
+
endsWith: (string: string, substring: string) => boolean;
|
|
15
|
+
/** Returns whether a string contains a given substring. */
|
|
16
|
+
contains: (string: string, substring: string) => boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Provides localized string search functionality that is useful for filtering or matching items in
|
|
21
|
+
* a list. Options can be provided to adjust the sensitivity to case, diacritics, and other
|
|
22
|
+
* parameters.
|
|
23
|
+
*/
|
|
24
|
+
export function useFilter(options?: Intl.CollatorOptions): Filter;
|
|
25
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
26
|
+
export function useFilter(
|
|
27
|
+
options: Intl.CollatorOptions | undefined,
|
|
28
|
+
slot: symbol | undefined,
|
|
29
|
+
): Filter;
|
|
30
|
+
export function useFilter(...args: any[]): Filter {
|
|
31
|
+
const [user, slotArg] = splitSlot(args);
|
|
32
|
+
const slot = slotArg ?? S('useFilter');
|
|
33
|
+
const options = user[0] as Intl.CollatorOptions | undefined;
|
|
34
|
+
|
|
35
|
+
let collator = useCollator(
|
|
36
|
+
{
|
|
37
|
+
usage: 'search',
|
|
38
|
+
...options,
|
|
39
|
+
},
|
|
40
|
+
subSlot(slot, 'collator'),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// TODO(later): these methods don't currently support the ignorePunctuation option.
|
|
44
|
+
let startsWith = useCallback(
|
|
45
|
+
(string: string, substring: string) => {
|
|
46
|
+
if (substring.length === 0) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Normalize both strings so we can slice safely
|
|
51
|
+
// TODO: take into account the ignorePunctuation option as well...
|
|
52
|
+
string = string.normalize('NFC');
|
|
53
|
+
substring = substring.normalize('NFC');
|
|
54
|
+
return collator.compare(string.slice(0, substring.length), substring) === 0;
|
|
55
|
+
},
|
|
56
|
+
[collator],
|
|
57
|
+
subSlot(slot, 'startsWith'),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
let endsWith = useCallback(
|
|
61
|
+
(string: string, substring: string) => {
|
|
62
|
+
if (substring.length === 0) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
string = string.normalize('NFC');
|
|
67
|
+
substring = substring.normalize('NFC');
|
|
68
|
+
return collator.compare(string.slice(-substring.length), substring) === 0;
|
|
69
|
+
},
|
|
70
|
+
[collator],
|
|
71
|
+
subSlot(slot, 'endsWith'),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
let contains = useCallback(
|
|
75
|
+
(string: string, substring: string) => {
|
|
76
|
+
if (substring.length === 0) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
string = string.normalize('NFC');
|
|
81
|
+
substring = substring.normalize('NFC');
|
|
82
|
+
|
|
83
|
+
let scan = 0;
|
|
84
|
+
let sliceLen = substring.length;
|
|
85
|
+
for (; scan + sliceLen <= string.length; scan++) {
|
|
86
|
+
let slice = string.slice(scan, scan + sliceLen);
|
|
87
|
+
if (collator.compare(substring, slice) === 0) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return false;
|
|
93
|
+
},
|
|
94
|
+
[collator],
|
|
95
|
+
subSlot(slot, 'contains'),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
return useMemo(
|
|
99
|
+
() => ({
|
|
100
|
+
startsWith,
|
|
101
|
+
endsWith,
|
|
102
|
+
contains,
|
|
103
|
+
}),
|
|
104
|
+
[startsWith, endsWith, contains],
|
|
105
|
+
subSlot(slot, 'filter'),
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/useListFormatter.tsx).
|
|
2
|
+
// octane adaptations: `.tsx` → `.ts` (the file contains no JSX); public-hook slot threading
|
|
3
|
+
// (splitSlot/subSlot) per the binding convention; the explicit `[locale, options]` memo deps
|
|
4
|
+
// are preserved exactly.
|
|
5
|
+
import { useMemo } from 'octane';
|
|
6
|
+
|
|
7
|
+
import { S, splitSlot, subSlot } from '../internal';
|
|
8
|
+
import { useLocale } from './I18nProvider';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Provides localized list formatting for the current locale. Automatically updates when the locale
|
|
12
|
+
* changes, and handles caching of the list formatter for performance.
|
|
13
|
+
*
|
|
14
|
+
* @param options - Formatting options.
|
|
15
|
+
*/
|
|
16
|
+
export function useListFormatter(options?: Intl.ListFormatOptions): Intl.ListFormat;
|
|
17
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
18
|
+
export function useListFormatter(
|
|
19
|
+
options: Intl.ListFormatOptions | undefined,
|
|
20
|
+
slot: symbol | undefined,
|
|
21
|
+
): Intl.ListFormat;
|
|
22
|
+
export function useListFormatter(...args: any[]): Intl.ListFormat {
|
|
23
|
+
const [user, slotArg] = splitSlot(args);
|
|
24
|
+
const slot = slotArg ?? S('useListFormatter');
|
|
25
|
+
const options = (user[0] as Intl.ListFormatOptions | undefined) ?? {};
|
|
26
|
+
|
|
27
|
+
let { locale } = useLocale(subSlot(slot, 'locale'));
|
|
28
|
+
return useMemo(
|
|
29
|
+
() => new Intl.ListFormat(locale, options),
|
|
30
|
+
[locale, options],
|
|
31
|
+
subSlot(slot, 'formatter'),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/useLocalizedStringFormatter.ts).
|
|
2
|
+
// octane adaptations: public-hook slot threading (splitSlot/subSlot) per the binding
|
|
3
|
+
// convention (`useLocalizedStringDictionary` calls no octane hooks today but keeps the
|
|
4
|
+
// slot-threading shape for uniformity); the explicit `[locale, dictionary]` memo deps are
|
|
5
|
+
// preserved exactly.
|
|
6
|
+
import {
|
|
7
|
+
LocalizedString,
|
|
8
|
+
LocalizedStringDictionary,
|
|
9
|
+
LocalizedStringFormatter,
|
|
10
|
+
LocalizedStrings,
|
|
11
|
+
} from '@internationalized/string';
|
|
12
|
+
import { useMemo } from 'octane';
|
|
13
|
+
|
|
14
|
+
import { S, splitSlot, subSlot } from '../internal';
|
|
15
|
+
import { useLocale } from './I18nProvider';
|
|
16
|
+
|
|
17
|
+
const cache = new WeakMap();
|
|
18
|
+
function getCachedDictionary<K extends string, T extends LocalizedString>(
|
|
19
|
+
strings: LocalizedStrings<K, T>,
|
|
20
|
+
): LocalizedStringDictionary<K, T> {
|
|
21
|
+
let dictionary = cache.get(strings);
|
|
22
|
+
if (!dictionary) {
|
|
23
|
+
dictionary = new LocalizedStringDictionary(strings);
|
|
24
|
+
cache.set(strings, dictionary);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return dictionary;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns a cached LocalizedStringDictionary for the given strings.
|
|
32
|
+
*/
|
|
33
|
+
export function useLocalizedStringDictionary<
|
|
34
|
+
K extends string = string,
|
|
35
|
+
T extends LocalizedString = string,
|
|
36
|
+
>(strings: LocalizedStrings<K, T>, packageName?: string): LocalizedStringDictionary<K, T>;
|
|
37
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
38
|
+
export function useLocalizedStringDictionary<
|
|
39
|
+
K extends string = string,
|
|
40
|
+
T extends LocalizedString = string,
|
|
41
|
+
>(
|
|
42
|
+
strings: LocalizedStrings<K, T>,
|
|
43
|
+
packageName: string | undefined,
|
|
44
|
+
slot: symbol | undefined,
|
|
45
|
+
): LocalizedStringDictionary<K, T>;
|
|
46
|
+
export function useLocalizedStringDictionary(...args: any[]): LocalizedStringDictionary<any, any> {
|
|
47
|
+
const [user] = splitSlot(args);
|
|
48
|
+
const strings = user[0] as LocalizedStrings<any, any>;
|
|
49
|
+
const packageName = user[1] as string | undefined;
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
(packageName && LocalizedStringDictionary.getGlobalDictionaryForPackage(packageName)) ||
|
|
53
|
+
getCachedDictionary(strings)
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Provides localized string formatting for the current locale. Supports interpolating variables,
|
|
59
|
+
* selecting the correct pluralization, and formatting numbers. Automatically updates when the
|
|
60
|
+
* locale changes.
|
|
61
|
+
*
|
|
62
|
+
* @param strings - A mapping of languages to localized strings by key.
|
|
63
|
+
*/
|
|
64
|
+
export function useLocalizedStringFormatter<
|
|
65
|
+
K extends string = string,
|
|
66
|
+
T extends LocalizedString = string,
|
|
67
|
+
>(strings: LocalizedStrings<K, T>, packageName?: string): LocalizedStringFormatter<K, T>;
|
|
68
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
69
|
+
export function useLocalizedStringFormatter<
|
|
70
|
+
K extends string = string,
|
|
71
|
+
T extends LocalizedString = string,
|
|
72
|
+
>(
|
|
73
|
+
strings: LocalizedStrings<K, T>,
|
|
74
|
+
packageName: string | undefined,
|
|
75
|
+
slot: symbol | undefined,
|
|
76
|
+
): LocalizedStringFormatter<K, T>;
|
|
77
|
+
export function useLocalizedStringFormatter(...args: any[]): LocalizedStringFormatter<any, any> {
|
|
78
|
+
const [user, slotArg] = splitSlot(args);
|
|
79
|
+
const slot = slotArg ?? S('useLocalizedStringFormatter');
|
|
80
|
+
const strings = user[0] as LocalizedStrings<any, any>;
|
|
81
|
+
const packageName = user[1] as string | undefined;
|
|
82
|
+
|
|
83
|
+
let { locale } = useLocale(subSlot(slot, 'locale'));
|
|
84
|
+
let dictionary = useLocalizedStringDictionary(strings, packageName, subSlot(slot, 'dictionary'));
|
|
85
|
+
return useMemo(
|
|
86
|
+
() => new LocalizedStringFormatter(locale, dictionary),
|
|
87
|
+
[locale, dictionary],
|
|
88
|
+
subSlot(slot, 'formatter'),
|
|
89
|
+
);
|
|
90
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Ported from react-aria (source: .react-spectrum/packages/react-aria/src/i18n/useNumberFormatter.ts).
|
|
2
|
+
// octane adaptations: public-hook slot threading (splitSlot/subSlot) per the binding
|
|
3
|
+
// convention; the explicit `[locale, options]` memo deps are preserved exactly.
|
|
4
|
+
import { NumberFormatOptions, NumberFormatter } from '@internationalized/number';
|
|
5
|
+
import { useMemo } from 'octane';
|
|
6
|
+
|
|
7
|
+
import { S, splitSlot, subSlot } from '../internal';
|
|
8
|
+
import { useLocale } from './I18nProvider';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Provides localized number formatting for the current locale. Automatically updates when the
|
|
12
|
+
* locale changes, and handles caching of the number formatter for performance.
|
|
13
|
+
*
|
|
14
|
+
* @param options - Formatting options.
|
|
15
|
+
*/
|
|
16
|
+
export function useNumberFormatter(options?: NumberFormatOptions): Intl.NumberFormat;
|
|
17
|
+
// Slot-threading form: sibling ported hooks pass their derived sub-slot as the trailing arg.
|
|
18
|
+
export function useNumberFormatter(
|
|
19
|
+
options: NumberFormatOptions | undefined,
|
|
20
|
+
slot: symbol | undefined,
|
|
21
|
+
): Intl.NumberFormat;
|
|
22
|
+
export function useNumberFormatter(...args: any[]): Intl.NumberFormat {
|
|
23
|
+
const [user, slotArg] = splitSlot(args);
|
|
24
|
+
const slot = slotArg ?? S('useNumberFormatter');
|
|
25
|
+
const options = (user[0] as NumberFormatOptions | undefined) ?? {};
|
|
26
|
+
|
|
27
|
+
let { locale } = useLocale(subSlot(slot, 'locale'));
|
|
28
|
+
return useMemo(
|
|
29
|
+
() => new NumberFormatter(locale, options),
|
|
30
|
+
[locale, options],
|
|
31
|
+
subSlot(slot, 'formatter'),
|
|
32
|
+
);
|
|
33
|
+
}
|