@astryxdesign/core 0.1.2 → 0.1.3-canary.6d57c8d
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/CHANGELOG.md +165 -0
- package/README.md +12 -12
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +11 -5
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +2 -4
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +0 -1
- package/dist/Calendar/Calendar.d.ts +5 -4
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +82 -43
- package/dist/Calendar/hooks/index.d.ts +0 -2
- package/dist/Calendar/hooks/index.d.ts.map +1 -1
- package/dist/Calendar/hooks/index.js +1 -2
- package/dist/Calendar/index.d.ts +3 -3
- package/dist/Calendar/index.d.ts.map +1 -1
- package/dist/Calendar/index.js +1 -1
- package/dist/Calendar/styles.d.ts +3 -9
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +3 -11
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +17 -3
- package/dist/Center/Center.d.ts +11 -1
- package/dist/Center/Center.d.ts.map +1 -1
- package/dist/Center/Center.js +9 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +0 -1
- package/dist/Chat/ChatMessageList.d.ts +14 -1
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +2 -0
- package/dist/Chat/useTriggerMenu.d.ts +8 -1
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +15 -3
- package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +51 -9
- package/dist/CheckboxList/CheckboxList.d.ts +13 -1
- package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxList.js +39 -9
- package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
- package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +0 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +9 -5
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +51 -37
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +5 -5
- package/dist/ContextMenu/ContextMenu.d.ts +4 -5
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +93 -11
- package/dist/DateInput/DateInput.d.ts +23 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +167 -99
- package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +42 -9
- package/dist/DateTimeInput/DateTimeInput.d.ts +35 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +78 -15
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +12 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts +1 -8
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +42 -14
- package/dist/Field/Field.d.ts +19 -2
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +4 -0
- package/dist/Field/FieldLabel.d.ts +21 -2
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +41 -26
- package/dist/FileInput/FileInput.d.ts +22 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +56 -10
- package/dist/Grid/Grid.d.ts +11 -1
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +32 -6
- package/dist/InputGroup/InputGroup.d.ts +4 -3
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +16 -6
- package/dist/InputGroup/InputGroupContext.d.ts +4 -0
- package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
- package/dist/InputGroup/InputGroupContext.js +2 -2
- package/dist/InputGroup/groupStyles.d.ts +1 -1
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +3 -3
- package/dist/InputGroup/index.d.ts +1 -0
- package/dist/InputGroup/index.d.ts.map +1 -1
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +33 -1
- package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
- package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
- package/dist/Layer/layerAnimations.stylex.js +8 -4
- package/dist/Layer/useLayer.d.ts +10 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +64 -9
- package/dist/Layout/Layout.d.ts +4 -11
- package/dist/Layout/Layout.d.ts.map +1 -1
- package/dist/Layout/Layout.js +10 -11
- package/dist/Layout/LayoutFooter.d.ts +2 -2
- package/dist/Layout/LayoutFooter.d.ts.map +1 -1
- package/dist/Layout/LayoutHeader.d.ts +2 -2
- package/dist/Layout/LayoutHeader.d.ts.map +1 -1
- package/dist/Layout/LayoutPanel.d.ts +2 -2
- package/dist/Layout/LayoutPanel.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.d.ts +51 -0
- package/dist/Layout/padding.stylex.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.js +63 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +4 -2
- package/dist/Link/Link.d.ts +16 -1
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +18 -7
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +7 -0
- package/dist/MoreMenu/MoreMenu.d.ts +1 -7
- package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
- package/dist/MoreMenu/MoreMenu.js +0 -2
- package/dist/MultiSelector/MultiSelector.d.ts +27 -2
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +141 -42
- package/dist/MultiSelector/hooks.d.ts +12 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +14 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +34 -3
- package/dist/NumberInput/NumberInput.d.ts +23 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +62 -12
- package/dist/Pagination/Pagination.d.ts +1 -1
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +15 -1
- package/dist/Popover/Popover.d.ts +18 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +5 -2
- package/dist/Popover/usePopover.d.ts +38 -3
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +24 -9
- package/dist/PowerSearch/PowerSearch.d.ts +11 -1
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +6 -1
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +3 -5
- package/dist/RadioList/RadioList.d.ts +20 -2
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +105 -9
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +13 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +78 -44
- package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
- package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
- package/dist/Selector/Selector.d.ts +24 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +122 -43
- package/dist/Selector/hooks.d.ts +8 -1
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +14 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +2 -0
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +1 -1
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +8 -2
- package/dist/Slider/Slider.d.ts +21 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +36 -9
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +1 -1
- package/dist/Stack/Stack.d.ts +38 -23
- package/dist/Stack/Stack.d.ts.map +1 -1
- package/dist/Stack/Stack.js +25 -1
- package/dist/Stack/StackItem.d.ts +12 -23
- package/dist/Stack/StackItem.d.ts.map +1 -1
- package/dist/Stack/StackItem.js +8 -1
- package/dist/Switch/Switch.d.ts +23 -2
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +41 -11
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +6 -0
- package/dist/TabList/TabList.d.ts +16 -4
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +87 -10
- package/dist/TabList/TabListContext.d.ts +5 -0
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +5 -0
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +6 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +11 -8
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +10 -1
- package/dist/Table/TableCell.d.ts +8 -1
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +10 -10
- package/dist/Table/TableHeaderCell.d.ts +8 -1
- package/dist/Table/TableHeaderCell.d.ts.map +1 -1
- package/dist/Table/TableHeaderCell.js +16 -16
- package/dist/Table/index.d.ts +2 -1
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +2 -2
- package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
- package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/paginateData.js +8 -3
- package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
- package/dist/Table/tableContextMenu.d.ts +33 -0
- package/dist/Table/tableContextMenu.d.ts.map +1 -0
- package/dist/Table/tableContextMenu.js +133 -0
- package/dist/Table/types.d.ts +66 -0
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/TextArea/TextArea.d.ts +22 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +41 -9
- package/dist/TextInput/TextInput.d.ts +23 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +55 -10
- package/dist/TimeInput/TimeInput.d.ts +23 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +147 -76
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +14 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +131 -3
- package/dist/Tokenizer/Tokenizer.d.ts +12 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +26 -4
- package/dist/Toolbar/Toolbar.d.ts +3 -3
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +51 -7
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +56 -9
- package/dist/TopNav/TopNavHeading.d.ts +7 -1
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +8 -0
- package/dist/TreeList/TreeList.d.ts +1 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +72 -2
- package/dist/TreeList/TreeListItem.d.ts +11 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +51 -12
- package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
- package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
- package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
- package/dist/Typeahead/BaseTypeahead.d.ts +13 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +69 -6
- package/dist/Typeahead/Typeahead.d.ts +26 -3
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +65 -29
- package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
- package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
- package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
- package/dist/VisuallyHidden/index.d.ts +11 -0
- package/dist/VisuallyHidden/index.d.ts.map +1 -0
- package/dist/VisuallyHidden/index.js +13 -0
- package/dist/astryx.css +18 -0
- package/dist/astryx.umd.js +55 -55
- package/dist/astryx.umd.js.map +4 -4
- package/dist/hooks/focusableSelector.d.ts +22 -0
- package/dist/hooks/focusableSelector.d.ts.map +1 -0
- package/dist/hooks/focusableSelector.js +24 -0
- package/dist/hooks/index.d.ts +12 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +7 -2
- package/dist/hooks/useAnnounce.d.ts +40 -0
- package/dist/hooks/useAnnounce.d.ts.map +1 -0
- package/dist/hooks/useAnnounce.js +142 -0
- package/dist/hooks/useClickableContainer.d.ts +16 -1
- package/dist/hooks/useClickableContainer.d.ts.map +1 -1
- package/dist/hooks/useClickableContainer.js +16 -4
- package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
- package/dist/hooks/useEntryAnimation.js +4 -4
- package/dist/hooks/useFocusTrap.d.ts +18 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +87 -3
- package/dist/hooks/useGridFocus.d.ts +88 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +261 -62
- package/dist/hooks/useKeyboardHint.d.ts +82 -0
- package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
- package/dist/hooks/useKeyboardHint.js +220 -0
- package/dist/hooks/useListFocus.d.ts +78 -7
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +305 -52
- package/dist/hooks/useLongPress.d.ts +21 -0
- package/dist/hooks/useLongPress.d.ts.map +1 -0
- package/dist/hooks/useLongPress.js +89 -0
- package/dist/hooks/useTreeFocus.d.ts +157 -0
- package/dist/hooks/useTreeFocus.d.ts.map +1 -0
- package/dist/hooks/useTreeFocus.js +337 -0
- package/dist/hooks/useTypeahead.d.ts +63 -0
- package/dist/hooks/useTypeahead.d.ts.map +1 -0
- package/dist/hooks/useTypeahead.js +117 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/utils/dateTypes.d.ts +12 -0
- package/dist/utils/dateTypes.d.ts.map +1 -1
- package/dist/utils/dateTypes.js +41 -1
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/inputAria.d.ts +29 -0
- package/dist/utils/inputAria.d.ts.map +1 -0
- package/dist/utils/inputAria.js +30 -0
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +5 -2
- package/docs.mjs +2 -2
- package/package.json +12 -8
- package/src/Avatar/Avatar.test.tsx +37 -0
- package/src/Avatar/Avatar.tsx +10 -5
- package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
- package/src/Button/Button.tsx +3 -16
- package/src/ButtonGroup/ButtonGroup.test.tsx +9 -9
- package/src/ButtonGroup/ButtonGroup.tsx +0 -1
- package/src/Calendar/Calendar.doc.mjs +4 -4
- package/src/Calendar/Calendar.test.tsx +168 -30
- package/src/Calendar/Calendar.tsx +121 -66
- package/src/Calendar/hooks/index.ts +0 -6
- package/src/Calendar/index.ts +1 -3
- package/src/Calendar/styles.ts +4 -9
- package/src/Carousel/Carousel.doc.mjs +7 -1
- package/src/Carousel/Carousel.test.tsx +20 -0
- package/src/Carousel/Carousel.tsx +16 -1
- package/src/Center/Center.doc.mjs +12 -2
- package/src/Center/Center.tsx +28 -3
- package/src/Chat/ChatComposerInput.test.tsx +26 -7
- package/src/Chat/ChatComposerInput.tsx +0 -1
- package/src/Chat/ChatDictationButton.doc.mjs +1 -1
- package/src/Chat/ChatMessageList.doc.mjs +8 -0
- package/src/Chat/ChatMessageList.test.tsx +18 -0
- package/src/Chat/ChatMessageList.tsx +16 -0
- package/src/Chat/useTriggerMenu.tsx +22 -4
- package/src/CheckboxInput/CheckboxInput.doc.mjs +10 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
- package/src/CheckboxInput/CheckboxInput.tsx +78 -6
- package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
- package/src/CheckboxList/CheckboxList.test.tsx +192 -26
- package/src/CheckboxList/CheckboxList.tsx +56 -3
- package/src/CheckboxList/CheckboxListContext.tsx +7 -0
- package/src/CheckboxList/CheckboxListItem.tsx +0 -3
- package/src/Citation/Citation.doc.mjs +10 -0
- package/src/Citation/Citation.test.tsx +121 -0
- package/src/Citation/Citation.tsx +15 -3
- package/src/CodeBlock/CodeBlock.test.tsx +115 -0
- package/src/CodeBlock/CodeBlock.tsx +63 -33
- package/src/CommandPalette/CommandPalette.test.tsx +47 -1
- package/src/CommandPalette/CommandPalette.tsx +9 -21
- package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
- package/src/ContextMenu/ContextMenu.test.tsx +155 -1
- package/src/ContextMenu/ContextMenu.tsx +113 -16
- package/src/DateInput/DateInput.doc.mjs +286 -56
- package/src/DateInput/DateInput.test.tsx +248 -2
- package/src/DateInput/DateInput.tsx +196 -100
- package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
- package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
- package/src/DateRangeInput/DateRangeInput.tsx +63 -5
- package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
- package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
- package/src/DateTimeInput/DateTimeInput.tsx +125 -17
- package/src/Dialog/Dialog.doc.mjs +2 -2
- package/src/Dialog/Dialog.tsx +12 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
- package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
- package/src/DropdownMenu/DropdownMenu.tsx +52 -18
- package/src/Field/Field.doc.mjs +59 -18
- package/src/Field/Field.test.tsx +32 -0
- package/src/Field/Field.tsx +23 -5
- package/src/Field/FieldLabel.tsx +55 -17
- package/src/FileInput/FileInput.doc.mjs +17 -0
- package/src/FileInput/FileInput.test.tsx +283 -49
- package/src/FileInput/FileInput.tsx +76 -4
- package/src/Grid/Grid.doc.mjs +17 -4
- package/src/Grid/Grid.test.tsx +43 -30
- package/src/Grid/Grid.tsx +38 -3
- package/src/Icon/Icon.doc.mjs +3 -3
- package/src/InputGroup/InputGroup.doc.mjs +111 -23
- package/src/InputGroup/InputGroup.test.tsx +257 -60
- package/src/InputGroup/InputGroup.tsx +23 -5
- package/src/InputGroup/InputGroupContext.ts +9 -4
- package/src/InputGroup/groupStyles.ts +7 -1
- package/src/InputGroup/index.ts +1 -0
- package/src/Kbd/Kbd.test.tsx +22 -4
- package/src/Kbd/Kbd.tsx +35 -3
- package/src/Layer/layerAnimations.stylex.ts +20 -4
- package/src/Layer/useLayer.doc.mjs +5 -0
- package/src/Layer/useLayer.test.tsx +111 -0
- package/src/Layer/useLayer.tsx +90 -9
- package/src/Layout/Layout.tsx +8 -16
- package/src/Layout/LayoutFooter.doc.mjs +4 -4
- package/src/Layout/LayoutFooter.tsx +3 -3
- package/src/Layout/LayoutHeader.doc.mjs +4 -4
- package/src/Layout/LayoutHeader.tsx +3 -3
- package/src/Layout/LayoutPanel.tsx +3 -3
- package/src/Layout/padding.stylex.ts +52 -0
- package/src/Lightbox/Lightbox.doc.mjs +9 -0
- package/src/Lightbox/Lightbox.test.tsx +53 -5
- package/src/Lightbox/Lightbox.tsx +9 -4
- package/src/Link/Link.doc.mjs +14 -0
- package/src/Link/Link.test.tsx +50 -0
- package/src/Link/Link.tsx +39 -4
- package/src/Markdown/Markdown.test.tsx +11 -0
- package/src/Markdown/Markdown.tsx +7 -0
- package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
- package/src/MoreMenu/MoreMenu.tsx +0 -9
- package/src/MultiSelector/MultiSelector.doc.mjs +30 -0
- package/src/MultiSelector/MultiSelector.test.tsx +375 -8
- package/src/MultiSelector/MultiSelector.tsx +194 -48
- package/src/MultiSelector/hooks.ts +27 -0
- package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
- package/src/NavMenu/NavHeadingMenu.tsx +50 -3
- package/src/NumberInput/NumberInput.doc.mjs +17 -0
- package/src/NumberInput/NumberInput.test.tsx +242 -40
- package/src/NumberInput/NumberInput.tsx +89 -11
- package/src/Pagination/Pagination.doc.mjs +3 -3
- package/src/Pagination/Pagination.test.tsx +117 -5
- package/src/Pagination/Pagination.tsx +21 -1
- package/src/Popover/Popover.doc.mjs +26 -0
- package/src/Popover/Popover.test.tsx +121 -0
- package/src/Popover/Popover.tsx +23 -2
- package/src/Popover/usePopover.doc.mjs +9 -3
- package/src/Popover/usePopover.tsx +70 -12
- package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
- package/src/PowerSearch/PowerSearch.test.tsx +97 -1
- package/src/PowerSearch/PowerSearch.tsx +16 -3
- package/src/ProgressBar/ProgressBar.test.tsx +34 -26
- package/src/ProgressBar/ProgressBar.tsx +3 -4
- package/src/RadioList/RadioList.doc.mjs +9 -0
- package/src/RadioList/RadioList.test.tsx +252 -16
- package/src/RadioList/RadioList.tsx +166 -10
- package/src/RadioList/RadioListItem.tsx +14 -2
- package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
- package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
- package/src/SegmentedControl/SegmentedControl.tsx +102 -54
- package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
- package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
- package/src/Selector/Selector.doc.mjs +26 -0
- package/src/Selector/Selector.test.tsx +387 -15
- package/src/Selector/Selector.tsx +175 -67
- package/src/Selector/hooks.ts +23 -0
- package/src/SideNav/SideNav.test.tsx +48 -0
- package/src/SideNav/SideNavHeading.tsx +8 -2
- package/src/SideNav/SideNavItem.tsx +2 -4
- package/src/Skeleton/Skeleton.test.tsx +25 -0
- package/src/Skeleton/Skeleton.tsx +11 -1
- package/src/Slider/Slider.doc.mjs +15 -0
- package/src/Slider/Slider.test.tsx +155 -2
- package/src/Slider/Slider.tsx +53 -5
- package/src/Spinner/Spinner.tsx +7 -1
- package/src/Stack/Stack.doc.mjs +77 -0
- package/src/Stack/Stack.test.tsx +55 -5
- package/src/Stack/Stack.tsx +73 -24
- package/src/Stack/StackItem.test.tsx +23 -0
- package/src/Stack/StackItem.tsx +20 -23
- package/src/Switch/Switch.doc.mjs +15 -0
- package/src/Switch/Switch.test.tsx +162 -27
- package/src/Switch/Switch.tsx +61 -21
- package/src/TabList/Tab.tsx +6 -0
- package/src/TabList/TabList.doc.mjs +6 -0
- package/src/TabList/TabList.test.tsx +251 -0
- package/src/TabList/TabList.tsx +103 -12
- package/src/TabList/TabListContext.ts +7 -3
- package/src/TabList/TabMenu.tsx +6 -3
- package/src/Table/BaseTable.tsx +21 -17
- package/src/Table/Table.doc.mjs +2 -0
- package/src/Table/Table.test.tsx +10 -0
- package/src/Table/Table.tsx +8 -0
- package/src/Table/TableCell.tsx +25 -23
- package/src/Table/TableHeaderCell.tsx +28 -29
- package/src/Table/index.ts +3 -2
- package/src/Table/plugins/pagination/paginateData.ts +10 -3
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
- package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
- package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
- package/src/Table/tableContextMenu.test.tsx +157 -0
- package/src/Table/tableContextMenu.tsx +142 -0
- package/src/Table/types.ts +74 -0
- package/src/Table/useTableColumnResize.doc.mjs +3 -3
- package/src/Table/useTableStickyColumns.doc.mjs +2 -2
- package/src/Text/Text.doc.mjs +18 -18
- package/src/TextArea/TextArea.doc.mjs +17 -0
- package/src/TextArea/TextArea.test.tsx +167 -35
- package/src/TextArea/TextArea.tsx +62 -15
- package/src/TextInput/TextInput.doc.mjs +17 -0
- package/src/TextInput/TextInput.test.tsx +168 -34
- package/src/TextInput/TextInput.tsx +77 -9
- package/src/Thumbnail/Thumbnail.doc.mjs +4 -4
- package/src/TimeInput/TimeInput.doc.mjs +340 -60
- package/src/TimeInput/TimeInput.test.tsx +255 -7
- package/src/TimeInput/TimeInput.tsx +176 -70
- package/src/Timestamp/Timestamp.doc.mjs +19 -19
- package/src/Toast/Toast.tsx +14 -0
- package/src/Toast/ToastViewport.test.tsx +214 -0
- package/src/Toast/ToastViewport.tsx +167 -21
- package/src/Tokenizer/Tokenizer.doc.mjs +29 -14
- package/src/Tokenizer/Tokenizer.test.tsx +105 -1
- package/src/Tokenizer/Tokenizer.tsx +37 -1
- package/src/Toolbar/Toolbar.test.tsx +109 -6
- package/src/Toolbar/Toolbar.tsx +59 -5
- package/src/Tooltip/Tooltip.test.tsx +68 -0
- package/src/Tooltip/useTooltip.tsx +55 -8
- package/src/TopNav/TopNav.test.tsx +50 -0
- package/src/TopNav/TopNavHeading.tsx +17 -1
- package/src/TreeList/TreeList.test.tsx +295 -6
- package/src/TreeList/TreeList.tsx +73 -1
- package/src/TreeList/TreeListItem.tsx +51 -5
- package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
- package/src/Typeahead/BaseTypeahead.tsx +93 -9
- package/src/Typeahead/Typeahead.doc.mjs +141 -30
- package/src/Typeahead/Typeahead.test.tsx +331 -1
- package/src/Typeahead/Typeahead.tsx +105 -33
- package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
- package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
- package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
- package/src/VisuallyHidden/index.ts +15 -0
- package/src/docs-script.test.mjs +50 -0
- package/src/hooks/focusableSelector.ts +25 -0
- package/src/hooks/index.ts +28 -2
- package/src/hooks/useAnnounce.test.tsx +101 -0
- package/src/hooks/useAnnounce.ts +168 -0
- package/src/hooks/useClickableContainer.ts +16 -4
- package/src/hooks/useEntryAnimation.ts +16 -4
- package/src/hooks/useFocusTrap.test.tsx +132 -0
- package/src/hooks/useFocusTrap.ts +98 -4
- package/src/hooks/useGridFocus.doc.mjs +40 -2
- package/src/hooks/useGridFocus.test.tsx +132 -0
- package/src/hooks/useGridFocus.ts +343 -67
- package/src/hooks/useKeyboardHint.doc.mjs +101 -0
- package/src/hooks/useKeyboardHint.test.tsx +70 -0
- package/src/hooks/useKeyboardHint.tsx +332 -0
- package/src/hooks/useListFocus.doc.mjs +50 -10
- package/src/hooks/useListFocus.test.tsx +375 -0
- package/src/hooks/useListFocus.ts +395 -57
- package/src/hooks/useLongPress.test.tsx +134 -0
- package/src/hooks/useLongPress.ts +119 -0
- package/src/hooks/useTreeFocus.doc.mjs +140 -0
- package/src/hooks/useTreeFocus.test.tsx +214 -0
- package/src/hooks/useTreeFocus.ts +559 -0
- package/src/hooks/useTypeahead.test.tsx +109 -0
- package/src/hooks/useTypeahead.ts +183 -0
- package/src/index.ts +1 -0
- package/src/theme/derivedVarRegistry.test.ts +10 -5
- package/src/utils/dateTypes.test.ts +40 -0
- package/src/utils/dateTypes.ts +40 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/inputAria.test.ts +39 -0
- package/src/utils/inputAria.ts +58 -0
- package/src/utils/timeParser.test.ts +10 -0
- package/src/utils/timeParser.ts +5 -2
- package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
- package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
- package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
- package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file useTypeahead.ts
|
|
7
|
+
* @input Uses React useCallback/useRef
|
|
8
|
+
* @output Exports useTypeahead hook for first-character (type-to-focus) search
|
|
9
|
+
* @position Core hook; adds APG typeahead to menus, listboxes, and other
|
|
10
|
+
* collections. Composes with useListFocus/useGridFocus (or any collection)
|
|
11
|
+
* via a caller-supplied getItemLabels + onMatch.
|
|
12
|
+
*
|
|
13
|
+
* SYNC: When modified, update:
|
|
14
|
+
* - /packages/core/src/hooks/index.ts
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {useCallback, useRef} from 'react';
|
|
18
|
+
|
|
19
|
+
export interface UseTypeaheadOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Returns the current, in-DOM-order list of item labels to match against.
|
|
22
|
+
* An entry may be `null`/empty to mark a non-matchable slot (its index is
|
|
23
|
+
* preserved so it maps 1:1 to the caller's items).
|
|
24
|
+
*/
|
|
25
|
+
getItemLabels: () => ReadonlyArray<string | null | undefined>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Called with the index of the matched item so the caller can focus/select
|
|
29
|
+
* it (e.g. `useListFocus`'s `focusItem`).
|
|
30
|
+
*/
|
|
31
|
+
onMatch: (index: number) => void;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The index to start searching from — typically the currently focused item,
|
|
35
|
+
* so repeated presses of the same letter cycle through matches. Defaults to
|
|
36
|
+
* -1 (search from the top).
|
|
37
|
+
*/
|
|
38
|
+
getCurrentIndex?: () => number;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Milliseconds of inactivity after which the typed buffer resets.
|
|
42
|
+
* @default 750
|
|
43
|
+
*/
|
|
44
|
+
resetMs?: number;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Whether an index should be skipped (e.g. disabled items).
|
|
48
|
+
*/
|
|
49
|
+
isDisabled?: (index: number) => boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface UseTypeaheadReturn {
|
|
53
|
+
/**
|
|
54
|
+
* Keydown handler. Call it (or let it fall through) from the collection's
|
|
55
|
+
* own key handler. Returns `true` when it handled a printable character (so
|
|
56
|
+
* the caller can `preventDefault`/stop further handling), `false` otherwise.
|
|
57
|
+
*/
|
|
58
|
+
onKeyDown: (e: React.KeyboardEvent | KeyboardEvent) => boolean;
|
|
59
|
+
/** Clear the pending buffer (e.g. on close). */
|
|
60
|
+
reset: () => void;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Whether a key event represents a single printable character (a type-to-focus
|
|
65
|
+
* candidate) rather than a control/navigation key or a shortcut chord.
|
|
66
|
+
*/
|
|
67
|
+
function isPrintableCharacter(e: React.KeyboardEvent | KeyboardEvent): boolean {
|
|
68
|
+
return (
|
|
69
|
+
e.key.length === 1 &&
|
|
70
|
+
!e.ctrlKey &&
|
|
71
|
+
!e.metaKey &&
|
|
72
|
+
!e.altKey &&
|
|
73
|
+
// A lone space is used for activation in menus, not typeahead-from-empty.
|
|
74
|
+
e.key !== ' '
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* First-character ("type-ahead") search for a collection.
|
|
80
|
+
*
|
|
81
|
+
* Buffers printable keystrokes (resetting after `resetMs` of inactivity),
|
|
82
|
+
* matches items whose label starts with the buffer, and cycles from the
|
|
83
|
+
* current index — so pressing "s" repeatedly walks through the "s" items
|
|
84
|
+
* instead of sticking on the first. Space is reserved for activation and is
|
|
85
|
+
* only treated as typeahead while a buffer is already active.
|
|
86
|
+
*
|
|
87
|
+
* Additive and collection-agnostic: it does not move focus itself; the caller
|
|
88
|
+
* wires `onMatch` to its own focus/selection (e.g. `useListFocus.focusItem`).
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```
|
|
92
|
+
* const {listRef, handleKeyDown, focusItem, getItems} = useListFocus(...);
|
|
93
|
+
* const typeahead = useTypeahead({
|
|
94
|
+
* getItemLabels: () => getItems().map(el => el.textContent),
|
|
95
|
+
* onMatch: focusItem,
|
|
96
|
+
* getCurrentIndex: () => getItems().findIndex(el => el === document.activeElement),
|
|
97
|
+
* });
|
|
98
|
+
* const onKeyDown = (e) => { if (!typeahead.onKeyDown(e)) handleKeyDown(e); };
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export function useTypeahead(options: UseTypeaheadOptions): UseTypeaheadReturn {
|
|
102
|
+
const {
|
|
103
|
+
getItemLabels,
|
|
104
|
+
onMatch,
|
|
105
|
+
getCurrentIndex,
|
|
106
|
+
resetMs = 750,
|
|
107
|
+
isDisabled,
|
|
108
|
+
} = options;
|
|
109
|
+
|
|
110
|
+
const bufferRef = useRef('');
|
|
111
|
+
const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(
|
|
112
|
+
undefined,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
const reset = useCallback(() => {
|
|
116
|
+
bufferRef.current = '';
|
|
117
|
+
if (timeoutRef.current) {
|
|
118
|
+
clearTimeout(timeoutRef.current);
|
|
119
|
+
timeoutRef.current = undefined;
|
|
120
|
+
}
|
|
121
|
+
}, []);
|
|
122
|
+
|
|
123
|
+
const scheduleReset = useCallback(() => {
|
|
124
|
+
if (timeoutRef.current) {
|
|
125
|
+
clearTimeout(timeoutRef.current);
|
|
126
|
+
}
|
|
127
|
+
timeoutRef.current = setTimeout(() => {
|
|
128
|
+
bufferRef.current = '';
|
|
129
|
+
timeoutRef.current = undefined;
|
|
130
|
+
}, resetMs);
|
|
131
|
+
}, [resetMs]);
|
|
132
|
+
|
|
133
|
+
const onKeyDown = useCallback(
|
|
134
|
+
(e: React.KeyboardEvent | KeyboardEvent): boolean => {
|
|
135
|
+
// A bare Space with no active buffer is not typeahead (menus activate on
|
|
136
|
+
// Space); once the user is mid-typing, Space extends the query.
|
|
137
|
+
const isSpaceMidType = e.key === ' ' && bufferRef.current.length > 0;
|
|
138
|
+
if (!isPrintableCharacter(e) && !isSpaceMidType) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const labels = getItemLabels();
|
|
143
|
+
if (labels.length === 0) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Pressing the SAME single character repeatedly cycles to the next match
|
|
148
|
+
// rather than filtering deeper (APG behavior).
|
|
149
|
+
const char = e.key.toLowerCase();
|
|
150
|
+
const isRepeatSameChar =
|
|
151
|
+
bufferRef.current.length > 0 &&
|
|
152
|
+
bufferRef.current.split('').every(c => c === char);
|
|
153
|
+
const nextBuffer = isRepeatSameChar ? char : bufferRef.current + char;
|
|
154
|
+
bufferRef.current = nextBuffer;
|
|
155
|
+
scheduleReset();
|
|
156
|
+
|
|
157
|
+
const start = getCurrentIndex?.() ?? -1;
|
|
158
|
+
const count = labels.length;
|
|
159
|
+
// When repeating a single char, start the search AFTER the current item
|
|
160
|
+
// so we advance; otherwise include the current item.
|
|
161
|
+
const offset = isRepeatSameChar ? 1 : 0;
|
|
162
|
+
|
|
163
|
+
for (let i = 0; i < count; i++) {
|
|
164
|
+
const index = (start + offset + i + count) % count;
|
|
165
|
+
if (isDisabled?.(index)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const label = labels[index];
|
|
169
|
+
if (
|
|
170
|
+
label != null &&
|
|
171
|
+
label.trim().toLowerCase().startsWith(nextBuffer)
|
|
172
|
+
) {
|
|
173
|
+
onMatch(index);
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
178
|
+
},
|
|
179
|
+
[getItemLabels, onMatch, getCurrentIndex, scheduleReset, isDisabled],
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
return {onKeyDown, reset};
|
|
183
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import {describe, it, expect} from 'vitest';
|
|
16
16
|
import {derivedVarRegistry, getDerivedVars} from './derivedVarRegistry';
|
|
17
|
-
import {readdirSync, readFileSync
|
|
17
|
+
import {readdirSync, readFileSync} from 'fs';
|
|
18
18
|
import {join} from 'path';
|
|
19
19
|
|
|
20
20
|
const SRC_DIR = join(__dirname, '..');
|
|
@@ -129,8 +129,9 @@ function discoverComponents(): ComponentInfo[] {
|
|
|
129
129
|
|
|
130
130
|
for (const dir of dirs) {
|
|
131
131
|
const dirPath = join(SRC_DIR, dir);
|
|
132
|
+
const dirEntries = readdirSync(dirPath);
|
|
132
133
|
// Find source files with component vars (.tsx and .ts, excluding tests/docs)
|
|
133
|
-
const sourceFiles =
|
|
134
|
+
const sourceFiles = dirEntries
|
|
134
135
|
.filter(
|
|
135
136
|
f =>
|
|
136
137
|
(f.endsWith('.tsx') || f.endsWith('.ts')) &&
|
|
@@ -150,11 +151,15 @@ function discoverComponents(): ComponentInfo[] {
|
|
|
150
151
|
continue;
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
// Only check component directories (those with a doc file
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
// Only check component directories (those with a doc file named after the
|
|
155
|
+
// directory). Match against the on-disk listing rather than existsSync so
|
|
156
|
+
// the comparison is case-exact everywhere — on case-insensitive
|
|
157
|
+
// filesystems (macOS, Windows) existsSync('theme/theme.doc.mjs') matches
|
|
158
|
+
// theme/Theme.doc.mjs and pulls in a directory that CI never checks.
|
|
159
|
+
if (!dirEntries.includes(`${dir}.doc.mjs`)) {
|
|
156
160
|
continue;
|
|
157
161
|
}
|
|
162
|
+
const docPath = join(dirPath, `${dir}.doc.mjs`);
|
|
158
163
|
|
|
159
164
|
let docVars: string[] = [];
|
|
160
165
|
let docDerived: DerivedDocEntry[] = [];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file dateTypes.test.ts
|
|
5
|
+
* @input Uses vitest
|
|
6
|
+
* @output Test suite for date type helpers
|
|
7
|
+
* @position Tests for dateTypes.ts (normalizeDayOfWeek)
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When dateTypes.ts changes, update tests accordingly
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {describe, it, expect} from 'vitest';
|
|
13
|
+
import {normalizeDayOfWeek} from './dateTypes';
|
|
14
|
+
|
|
15
|
+
describe('normalizeDayOfWeek', () => {
|
|
16
|
+
it('passes numeric days through unchanged', () => {
|
|
17
|
+
expect(normalizeDayOfWeek(0)).toBe(0);
|
|
18
|
+
expect(normalizeDayOfWeek(1)).toBe(1);
|
|
19
|
+
expect(normalizeDayOfWeek(6)).toBe(6);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('maps three-letter day names to their index', () => {
|
|
23
|
+
expect(normalizeDayOfWeek('sun')).toBe(0);
|
|
24
|
+
expect(normalizeDayOfWeek('mon')).toBe(1);
|
|
25
|
+
expect(normalizeDayOfWeek('tue')).toBe(2);
|
|
26
|
+
expect(normalizeDayOfWeek('wed')).toBe(3);
|
|
27
|
+
expect(normalizeDayOfWeek('thu')).toBe(4);
|
|
28
|
+
expect(normalizeDayOfWeek('fri')).toBe(5);
|
|
29
|
+
expect(normalizeDayOfWeek('sat')).toBe(6);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('is case-insensitive for day names', () => {
|
|
33
|
+
expect(normalizeDayOfWeek('MON' as 'mon')).toBe(1);
|
|
34
|
+
expect(normalizeDayOfWeek('Sat' as 'sat')).toBe(6);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('falls back to 0 (Sunday) for an unrecognized name', () => {
|
|
38
|
+
expect(normalizeDayOfWeek('xyz' as 'mon')).toBe(0);
|
|
39
|
+
});
|
|
40
|
+
});
|
package/src/utils/dateTypes.ts
CHANGED
|
@@ -17,6 +17,46 @@ export type ISODateString =
|
|
|
17
17
|
/** Day of week: 0 = Sunday through 6 = Saturday */
|
|
18
18
|
export type DayOfWeek = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Three-letter lowercase weekday name, 'sun' through 'sat'.
|
|
22
|
+
* A more self-documenting alternative to the numeric {@link DayOfWeek}.
|
|
23
|
+
*/
|
|
24
|
+
export type DayOfWeekName =
|
|
25
|
+
| 'sun'
|
|
26
|
+
| 'mon'
|
|
27
|
+
| 'tue'
|
|
28
|
+
| 'wed'
|
|
29
|
+
| 'thu'
|
|
30
|
+
| 'fri'
|
|
31
|
+
| 'sat';
|
|
32
|
+
|
|
33
|
+
/** Weekday names indexed by {@link DayOfWeek} (0 = Sunday). */
|
|
34
|
+
const WEEKDAY_NAMES: ReadonlyArray<DayOfWeekName> = [
|
|
35
|
+
'sun',
|
|
36
|
+
'mon',
|
|
37
|
+
'tue',
|
|
38
|
+
'wed',
|
|
39
|
+
'thu',
|
|
40
|
+
'fri',
|
|
41
|
+
'sat',
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Normalize a weekday to its numeric {@link DayOfWeek}. Accepts either a
|
|
46
|
+
* number (0–6) or a three-letter day name ('sun'–'sat', case-insensitive),
|
|
47
|
+
* so APIs like `weekStartsOn` can take whichever is more readable at the
|
|
48
|
+
* call site. Unrecognized values fall back to 0 (Sunday).
|
|
49
|
+
*/
|
|
50
|
+
export function normalizeDayOfWeek(
|
|
51
|
+
value: DayOfWeek | DayOfWeekName,
|
|
52
|
+
): DayOfWeek {
|
|
53
|
+
if (typeof value === 'number') {
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
const index = WEEKDAY_NAMES.indexOf(value.toLowerCase() as DayOfWeekName);
|
|
57
|
+
return index === -1 ? 0 : (index as DayOfWeek);
|
|
58
|
+
}
|
|
59
|
+
|
|
20
60
|
/** Immutable date record with 1-based month. */
|
|
21
61
|
export interface PlainDate {
|
|
22
62
|
readonly year: number;
|
package/src/utils/index.ts
CHANGED
|
@@ -68,7 +68,16 @@ export {getKey, type Key, type KeyFallback} from './getKey';
|
|
|
68
68
|
|
|
69
69
|
export {mergeProps} from './mergeProps';
|
|
70
70
|
export {mergeRefs} from './mergeRefs';
|
|
71
|
+
export {themeProps, themeDataAttributes} from './themeProps';
|
|
72
|
+
export type {
|
|
73
|
+
ClassValue,
|
|
74
|
+
ClassProps,
|
|
75
|
+
ThemeDataAttributes,
|
|
76
|
+
ThemeProps,
|
|
77
|
+
} from './themeProps';
|
|
71
78
|
export {groupItems, getItemGroup} from './groupItems';
|
|
72
79
|
export type {ItemGroup} from './groupItems';
|
|
73
80
|
export {observeResize, unobserveResize} from './sharedResizeObserver';
|
|
74
81
|
export {isRenderable} from './isRenderable';
|
|
82
|
+
export {getInputARIA} from './inputAria';
|
|
83
|
+
export type {InputARIA, InputARIAInputGroup} from './inputAria';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import {describe, expect, it} from 'vitest';
|
|
4
|
+
import {getInputARIA} from './inputAria';
|
|
5
|
+
|
|
6
|
+
describe('getInputARIA', () => {
|
|
7
|
+
it('keeps standalone input labeling native while composing descriptions', () => {
|
|
8
|
+
expect(
|
|
9
|
+
getInputARIA('input-label', ['input-help', undefined, 'input-error']),
|
|
10
|
+
).toEqual({
|
|
11
|
+
ariaLabelledBy: undefined,
|
|
12
|
+
ariaDescribedBy: 'input-help input-error',
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('composes InputGroup context before input labels and descriptions', () => {
|
|
17
|
+
expect(
|
|
18
|
+
getInputARIA('input-label', ['input-help'], {
|
|
19
|
+
labelID: 'group-label',
|
|
20
|
+
describedByIDs: 'group-help group-error',
|
|
21
|
+
}),
|
|
22
|
+
).toEqual({
|
|
23
|
+
ariaLabelledBy: 'group-label input-label',
|
|
24
|
+
ariaDescribedBy: 'group-help group-error input-help',
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('deduplicates repeated IDs', () => {
|
|
29
|
+
expect(
|
|
30
|
+
getInputARIA('group-label', ['shared', 'input-help'], {
|
|
31
|
+
labelID: 'group-label',
|
|
32
|
+
describedByIDs: 'shared group-error',
|
|
33
|
+
}),
|
|
34
|
+
).toEqual({
|
|
35
|
+
ariaLabelledBy: 'group-label',
|
|
36
|
+
ariaDescribedBy: 'shared group-error input-help',
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file inputAria.ts
|
|
5
|
+
* @input Receives input label/description IDs and optional InputGroup context
|
|
6
|
+
* @output Exports helpers for consistent input ARIA composition
|
|
7
|
+
* @position Internal utility; used by inputs that compose labels/descriptions
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface InputARIAInputGroup {
|
|
11
|
+
/** ID of the visible InputGroup label. */
|
|
12
|
+
labelID: string;
|
|
13
|
+
/** Space-separated IDs for InputGroup description/status text. */
|
|
14
|
+
describedByIDs?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface InputARIA {
|
|
18
|
+
/** Value for aria-labelledby on the input. */
|
|
19
|
+
ariaLabelledBy?: string;
|
|
20
|
+
/** Value for aria-describedby on the input. */
|
|
21
|
+
ariaDescribedBy?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type AriaID = string | null | undefined | false;
|
|
25
|
+
|
|
26
|
+
function joinAriaIDs(...values: AriaID[]): string | undefined {
|
|
27
|
+
const ids = values
|
|
28
|
+
.flatMap(value =>
|
|
29
|
+
typeof value === 'string' ? value.trim().split(/\s+/) : [],
|
|
30
|
+
)
|
|
31
|
+
.filter(Boolean);
|
|
32
|
+
|
|
33
|
+
if (ids.length === 0) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return Array.from(new Set(ids)).join(' ');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Builds ARIA label/description wiring for an input.
|
|
42
|
+
*
|
|
43
|
+
* Standalone inputs keep their normal native label association. Grouped inputs
|
|
44
|
+
* are named by the visible InputGroup label plus their own input label, and
|
|
45
|
+
* inherit group description/status text in addition to input-local text.
|
|
46
|
+
*/
|
|
47
|
+
export function getInputARIA(
|
|
48
|
+
labelID: string,
|
|
49
|
+
describedByIDs: AriaID[] = [],
|
|
50
|
+
inputGroup?: InputARIAInputGroup | null,
|
|
51
|
+
): InputARIA {
|
|
52
|
+
return {
|
|
53
|
+
ariaLabelledBy: inputGroup
|
|
54
|
+
? joinAriaIDs(inputGroup.labelID, labelID)
|
|
55
|
+
: undefined,
|
|
56
|
+
ariaDescribedBy: joinAriaIDs(inputGroup?.describedByIDs, ...describedByIDs),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -144,11 +144,21 @@ describe('parseTimeInput', () => {
|
|
|
144
144
|
expect(parseTimeInput('12pm')).toBe('12:00');
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
+
it('parses dotted meridiems (a.m./p.m.)', () => {
|
|
148
|
+
expect(parseTimeInput('2:30 p.m.')).toBe('14:30');
|
|
149
|
+
expect(parseTimeInput('2:30 P.M.')).toBe('14:30');
|
|
150
|
+
expect(parseTimeInput('2:30 p.m')).toBe('14:30');
|
|
151
|
+
expect(parseTimeInput('12 a.m.')).toBe('00:00');
|
|
152
|
+
expect(parseTimeInput('12 p.m.')).toBe('12:00');
|
|
153
|
+
expect(parseTimeInput('2 p.m.')).toBe('14:00');
|
|
154
|
+
});
|
|
155
|
+
|
|
147
156
|
it('returns null for invalid input', () => {
|
|
148
157
|
expect(parseTimeInput('')).toBeNull();
|
|
149
158
|
expect(parseTimeInput('abc')).toBeNull();
|
|
150
159
|
expect(parseTimeInput('25:00')).toBeNull();
|
|
151
160
|
expect(parseTimeInput('13:00 PM')).toBeNull(); // 13 is invalid in 12h format
|
|
161
|
+
expect(parseTimeInput('13:00 p.m.')).toBeNull(); // dotted variant rejected too
|
|
152
162
|
});
|
|
153
163
|
});
|
|
154
164
|
|
package/src/utils/timeParser.ts
CHANGED
|
@@ -164,10 +164,13 @@ export function parseTimeInput(
|
|
|
164
164
|
|
|
165
165
|
const trimmed = input.trim().toLowerCase();
|
|
166
166
|
|
|
167
|
-
// Check for AM/PM
|
|
168
|
-
|
|
167
|
+
// Check for AM/PM. hasMeridiem is derived from isPM/isAM so the detection
|
|
168
|
+
// can never drift from them: it previously used its own regex without the
|
|
169
|
+
// optional dots, so dotted meridiems ("2:30 p.m.") skipped the 12h -> 24h
|
|
170
|
+
// conversion and parsed 12 hours off.
|
|
169
171
|
const isPM = /p\.?m?\.?\s*$/i.test(trimmed);
|
|
170
172
|
const isAM = /a\.?m?\.?\s*$/i.test(trimmed);
|
|
173
|
+
const hasMeridiem = isPM || isAM;
|
|
171
174
|
|
|
172
175
|
// Remove AM/PM suffix
|
|
173
176
|
const timeStr = trimmed.replace(/\s*[ap]\.?m?\.?\s*$/i, '').trim();
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import type { ISODateString } from '../../utils/dateTypes';
|
|
2
|
-
import { type PlainDate } from '../../utils/plainDate';
|
|
3
|
-
import type { CalendarDay } from './useCalendarDays';
|
|
4
|
-
/**
|
|
5
|
-
* Configuration for calendar roving tabindex
|
|
6
|
-
*/
|
|
7
|
-
export interface UseCalendarRovingTabindexOptions {
|
|
8
|
-
/** All days in the grid */
|
|
9
|
-
days: CalendarDay[];
|
|
10
|
-
/** Today's date as a PlainDate */
|
|
11
|
-
today: PlainDate;
|
|
12
|
-
/** The year being displayed */
|
|
13
|
-
year: number;
|
|
14
|
-
/** The month being displayed (1-based: 1 = January, 12 = December) */
|
|
15
|
-
month: number;
|
|
16
|
-
/** Function to check if a date is disabled */
|
|
17
|
-
isDateDisabled: (date: PlainDate) => boolean;
|
|
18
|
-
/** Currently selected date (if any) */
|
|
19
|
-
selectedDate?: PlainDate | null;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Return type for useCalendarRovingTabindex hook
|
|
23
|
-
*/
|
|
24
|
-
export interface UseCalendarRovingTabindexReturn {
|
|
25
|
-
/** The ISO date string of the tabbable element, or null */
|
|
26
|
-
tabbableDate: ISODateString | null;
|
|
27
|
-
/** Check if a specific date is the tabbable one */
|
|
28
|
-
isTabbable: (iso: ISODateString) => boolean;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Hook for managing roving tabindex in calendar grids.
|
|
32
|
-
*
|
|
33
|
-
* Implements the WAI-ARIA roving tabindex pattern where only one element
|
|
34
|
-
* in a group has tabindex="0" while others have tabindex="-1".
|
|
35
|
-
*
|
|
36
|
-
* Priority for tabbable element:
|
|
37
|
-
* 1. Today if visible in the current month and enabled
|
|
38
|
-
* 2. First enabled day in the month
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```
|
|
42
|
-
* const {tabbableDate, isTabbable} = useCalendarRovingTabindex({
|
|
43
|
-
* days,
|
|
44
|
-
* today: {year: 2026, month: 1, day: 20},
|
|
45
|
-
* year: 2026,
|
|
46
|
-
* month: 1, // January (1-based)
|
|
47
|
-
* isDateDisabled,
|
|
48
|
-
* });
|
|
49
|
-
*
|
|
50
|
-
* // In day rendering:
|
|
51
|
-
* <button tabIndex={isTabbable(day.iso) ? 0 : -1}>
|
|
52
|
-
* {day.dayNumber}
|
|
53
|
-
* </button>
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
export declare function useCalendarRovingTabindex(options: UseCalendarRovingTabindexOptions): UseCalendarRovingTabindexReturn;
|
|
57
|
-
//# sourceMappingURL=useCalendarRovingTabindex.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useCalendarRovingTabindex.d.ts","sourceRoot":"","sources":["../../../src/Calendar/hooks/useCalendarRovingTabindex.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,2BAA2B;IAC3B,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,kCAAkC;IAClC,KAAK,EAAE,SAAS,CAAC;IACjB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,cAAc,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAC7C,uCAAuC;IACvC,YAAY,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,2DAA2D;IAC3D,YAAY,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,mDAAmD;IACnD,UAAU,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,+BAA+B,CA0CjC"}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
'use client';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @file useCalendarRovingTabindex.ts
|
|
7
|
-
* @input Uses React useMemo, PlainDate utilities
|
|
8
|
-
* @output Exports useCalendarRovingTabindex hook for accessible grid navigation
|
|
9
|
-
* @position Calendar-specific hook; used by Calendar
|
|
10
|
-
*
|
|
11
|
-
* SYNC: When modified, update:
|
|
12
|
-
* - /packages/core/src/Calendar/hooks/index.ts
|
|
13
|
-
*/
|
|
14
|
-
import { useMemo } from 'react';
|
|
15
|
-
import { plainDateToISO } from "../../utils/plainDate.js";
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Configuration for calendar roving tabindex
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Return type for useCalendarRovingTabindex hook
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Hook for managing roving tabindex in calendar grids.
|
|
27
|
-
*
|
|
28
|
-
* Implements the WAI-ARIA roving tabindex pattern where only one element
|
|
29
|
-
* in a group has tabindex="0" while others have tabindex="-1".
|
|
30
|
-
*
|
|
31
|
-
* Priority for tabbable element:
|
|
32
|
-
* 1. Today if visible in the current month and enabled
|
|
33
|
-
* 2. First enabled day in the month
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```
|
|
37
|
-
* const {tabbableDate, isTabbable} = useCalendarRovingTabindex({
|
|
38
|
-
* days,
|
|
39
|
-
* today: {year: 2026, month: 1, day: 20},
|
|
40
|
-
* year: 2026,
|
|
41
|
-
* month: 1, // January (1-based)
|
|
42
|
-
* isDateDisabled,
|
|
43
|
-
* });
|
|
44
|
-
*
|
|
45
|
-
* // In day rendering:
|
|
46
|
-
* <button tabIndex={isTabbable(day.iso) ? 0 : -1}>
|
|
47
|
-
* {day.dayNumber}
|
|
48
|
-
* </button>
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
export function useCalendarRovingTabindex(options) {
|
|
52
|
-
const {
|
|
53
|
-
days,
|
|
54
|
-
today,
|
|
55
|
-
year,
|
|
56
|
-
month,
|
|
57
|
-
isDateDisabled,
|
|
58
|
-
selectedDate
|
|
59
|
-
} = options;
|
|
60
|
-
|
|
61
|
-
// Determine which day should be tabbable
|
|
62
|
-
const tabbableDate = useMemo(() => {
|
|
63
|
-
// Priority 1: Selected date if visible in this month and enabled
|
|
64
|
-
if (selectedDate) {
|
|
65
|
-
const isSelectedInMonth = selectedDate.year === year && selectedDate.month === month;
|
|
66
|
-
if (isSelectedInMonth && !isDateDisabled(selectedDate)) {
|
|
67
|
-
return plainDateToISO(selectedDate);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Priority 2: Today if visible in this month and enabled
|
|
72
|
-
const isTodayInMonth = today.year === year && today.month === month;
|
|
73
|
-
if (isTodayInMonth && !isDateDisabled(today)) {
|
|
74
|
-
return plainDateToISO(today);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Priority 3: First enabled day in this month
|
|
78
|
-
for (const day of days) {
|
|
79
|
-
if (!day.isOutside && !isDateDisabled(day.date)) {
|
|
80
|
-
return day.iso;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return null;
|
|
84
|
-
}, [days, today, year, month, isDateDisabled, selectedDate]);
|
|
85
|
-
|
|
86
|
-
// Check if a specific date is tabbable
|
|
87
|
-
const isTabbable = useMemo(() => {
|
|
88
|
-
return iso => {
|
|
89
|
-
return tabbableDate !== null && iso === tabbableDate;
|
|
90
|
-
};
|
|
91
|
-
}, [tabbableDate]);
|
|
92
|
-
return {
|
|
93
|
-
tabbableDate,
|
|
94
|
-
isTabbable
|
|
95
|
-
};
|
|
96
|
-
}
|