@astryxdesign/core 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -25,6 +25,7 @@ import { Icon } from "../Icon/index.js";
|
|
|
25
25
|
import { Spinner } from "../Spinner/index.js";
|
|
26
26
|
import { Calendar } from "../Calendar/index.js";
|
|
27
27
|
import { usePopover } from "../Popover/index.js";
|
|
28
|
+
import { useTooltip } from "../Tooltip/index.js";
|
|
28
29
|
import { mergeProps } from "../utils/index.js";
|
|
29
30
|
import { useSize } from "../SizeContext/SizeContext.js";
|
|
30
31
|
import { themeProps } from "../utils/themeProps.js";
|
|
@@ -89,6 +90,7 @@ export function DateRangeInput({
|
|
|
89
90
|
isOptional = false,
|
|
90
91
|
isRequired = false,
|
|
91
92
|
isDisabled = false,
|
|
93
|
+
disabledMessage,
|
|
92
94
|
value,
|
|
93
95
|
onChange,
|
|
94
96
|
changeAction,
|
|
@@ -118,6 +120,21 @@ export function DateRangeInput({
|
|
|
118
120
|
const [optimisticValue, setOptimisticValue] = useOptimistic(value);
|
|
119
121
|
const isBusy = isLoading || optimisticValue !== value;
|
|
120
122
|
const isEffectivelyDisabled = isDisabled || isBusy;
|
|
123
|
+
|
|
124
|
+
// Disabled-reason tooltip. Disabled controls swallow pointer events, so the
|
|
125
|
+
// tooltip listeners attach to the trigger container (which already exists)
|
|
126
|
+
// and the trigger button stays perceivable via aria-disabled instead of the
|
|
127
|
+
// disabled attribute. Activation is blocked by the isEffectivelyDisabled
|
|
128
|
+
// guard in handleToggle. Only the persistent isDisabled state (not the
|
|
129
|
+
// transient busy state) surfaces a reason.
|
|
130
|
+
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
131
|
+
const disabledMessageTooltip = useTooltip({
|
|
132
|
+
placement: 'above',
|
|
133
|
+
// The container div is not naturally focusable; focusin bubbles up from
|
|
134
|
+
// the trigger button, so always attach focus listeners.
|
|
135
|
+
focusTrigger: 'always',
|
|
136
|
+
isEnabled: showsDisabledMessage
|
|
137
|
+
});
|
|
121
138
|
const statusIconMap = {
|
|
122
139
|
warning: 'warning',
|
|
123
140
|
error: 'error',
|
|
@@ -128,7 +145,7 @@ export function DateRangeInput({
|
|
|
128
145
|
error: 'error',
|
|
129
146
|
success: 'success'
|
|
130
147
|
};
|
|
131
|
-
const ariaDescribedBy = [description ? descriptionID : null, status?.message ? statusMessageID : null].filter(Boolean).join(' ') || undefined;
|
|
148
|
+
const ariaDescribedBy = [description ? descriptionID : null, status?.message ? statusMessageID : null, showsDisabledMessage ? disabledMessageTooltip.describedBy : null].filter(Boolean).join(' ') || undefined;
|
|
132
149
|
const displayValue = useMemo(() => formatRangeDisplay(optimisticValue), [optimisticValue]);
|
|
133
150
|
const popover = usePopover({
|
|
134
151
|
dialogLabel: 'Choose date range',
|
|
@@ -185,7 +202,13 @@ export function DateRangeInput({
|
|
|
185
202
|
labelTooltip: labelTooltip,
|
|
186
203
|
width: width,
|
|
187
204
|
children: [/*#__PURE__*/_jsxs("div", {
|
|
188
|
-
ref:
|
|
205
|
+
ref: el => {
|
|
206
|
+
popover.triggerRef(el);
|
|
207
|
+
// Anchor + hover/focus listeners for the disabled-message tooltip.
|
|
208
|
+
// Handlers are gated internally by isEnabled, and anchor names
|
|
209
|
+
// compose, so attaching unconditionally is safe.
|
|
210
|
+
disabledMessageTooltip.ref(el);
|
|
211
|
+
},
|
|
189
212
|
...rest,
|
|
190
213
|
...mergeProps(themeProps('date-range-input', {
|
|
191
214
|
size,
|
|
@@ -214,8 +237,13 @@ export function DateRangeInput({
|
|
|
214
237
|
ref: ref,
|
|
215
238
|
id: id,
|
|
216
239
|
type: "button",
|
|
217
|
-
onClick: handleToggle
|
|
218
|
-
|
|
240
|
+
onClick: handleToggle
|
|
241
|
+
// With a disabledMessage the trigger keeps focusability via
|
|
242
|
+
// aria-disabled so the reason is focus-discoverable; activation is
|
|
243
|
+
// still blocked by the isEffectivelyDisabled guard in handleToggle.
|
|
244
|
+
,
|
|
245
|
+
disabled: isEffectivelyDisabled && !showsDisabledMessage,
|
|
246
|
+
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
219
247
|
"aria-label": triggerAriaLabel,
|
|
220
248
|
"aria-describedby": ariaDescribedBy,
|
|
221
249
|
"aria-required": isRequired === true ? 'true' : undefined,
|
|
@@ -263,7 +291,7 @@ export function DateRangeInput({
|
|
|
263
291
|
className: "x78zum5"
|
|
264
292
|
},
|
|
265
293
|
children: [presets && presets.length > 0 && /*#__PURE__*/_jsx("div", {
|
|
266
|
-
role: "
|
|
294
|
+
role: "group",
|
|
267
295
|
"aria-label": "Preset date ranges",
|
|
268
296
|
...{
|
|
269
297
|
className: "x78zum5 xdt5ytf xzye2dw x1b2ylru x1pcaw5z x32b0ac xdz7fjg x1d77m7x"
|
|
@@ -272,9 +300,14 @@ export function DateRangeInput({
|
|
|
272
300
|
const presetRange = preset.getRange();
|
|
273
301
|
const isActive = isRangeEqual(value, presetRange);
|
|
274
302
|
return /*#__PURE__*/_jsx("button", {
|
|
275
|
-
type: "button"
|
|
276
|
-
|
|
277
|
-
|
|
303
|
+
type: "button"
|
|
304
|
+
// These presets are independent action buttons navigated by
|
|
305
|
+
// Tab, not a single-tab-stop listbox — so they are a labeled
|
|
306
|
+
// group of buttons, and the currently-applied preset is
|
|
307
|
+
// marked with aria-current (not aria-selected, a listbox
|
|
308
|
+
// concept that contradicted the Tab interaction) (forms-5).
|
|
309
|
+
,
|
|
310
|
+
"aria-current": isActive ? 'true' : undefined,
|
|
278
311
|
onClick: () => handlePresetClick(preset),
|
|
279
312
|
...{
|
|
280
313
|
0: {
|
|
@@ -299,7 +332,7 @@ export function DateRangeInput({
|
|
|
299
332
|
}), {
|
|
300
333
|
placement: 'below',
|
|
301
334
|
alignment: 'start'
|
|
302
|
-
})]
|
|
335
|
+
}), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
|
|
303
336
|
});
|
|
304
337
|
}
|
|
305
338
|
DateRangeInput.displayName = 'DateRangeInput';
|
|
@@ -39,6 +39,28 @@ export interface DateTimeInputProps extends Omit<BaseProps, 'onChange' | 'defaul
|
|
|
39
39
|
* @default false
|
|
40
40
|
*/
|
|
41
41
|
isDisabled?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Explains why the input is disabled. When set together with
|
|
44
|
+
* `isDisabled`, the input shows a tooltip with this text on hover and
|
|
45
|
+
* keyboard focus, and the date and time fields stay focusable (via
|
|
46
|
+
* `aria-disabled`) so the reason is discoverable by keyboard and assistive
|
|
47
|
+
* technology. Typing and calendar activation stay blocked.
|
|
48
|
+
*
|
|
49
|
+
* Use this instead of wrapping a disabled input in `Tooltip` — disabled
|
|
50
|
+
* controls don't emit the pointer events an external tooltip needs.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```
|
|
54
|
+
* <DateTimeInput
|
|
55
|
+
* label="Meeting time"
|
|
56
|
+
* value={dateTime}
|
|
57
|
+
* onChange={setDateTime}
|
|
58
|
+
* isDisabled
|
|
59
|
+
* disabledMessage="You need the Editor role to change this"
|
|
60
|
+
* />
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
disabledMessage?: string;
|
|
42
64
|
/**
|
|
43
65
|
* The selected datetime in ISO 8601 format ("YYYY-MM-DDTHH:MM" or "YYYY-MM-DDTHH:MM:SS").
|
|
44
66
|
*/
|
|
@@ -93,10 +115,21 @@ export interface DateTimeInputProps extends Omit<BaseProps, 'onChange' | 'defaul
|
|
|
93
115
|
*/
|
|
94
116
|
hasClear?: boolean;
|
|
95
117
|
/**
|
|
96
|
-
* Placeholder text shown when no date is selected.
|
|
118
|
+
* Placeholder text shown in the date portion when no date is selected.
|
|
97
119
|
* @default "Select a date"
|
|
98
120
|
*/
|
|
99
121
|
placeholder?: string;
|
|
122
|
+
/**
|
|
123
|
+
* Placeholder text shown in the time portion when no time is selected.
|
|
124
|
+
* @default "Select a time"
|
|
125
|
+
*/
|
|
126
|
+
timePlaceholder?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Accessible label for the time portion of the field. Defaults to
|
|
129
|
+
* `"{label} time"` so it is tied to the field's own label and localizable,
|
|
130
|
+
* rather than a hardcoded English "Time".
|
|
131
|
+
*/
|
|
132
|
+
timeLabel?: string;
|
|
100
133
|
/**
|
|
101
134
|
* The size of the inputs.
|
|
102
135
|
* @default 'md'
|
|
@@ -140,7 +173,7 @@ export interface DateTimeInputProps extends Omit<BaseProps, 'onChange' | 'defaul
|
|
|
140
173
|
* />
|
|
141
174
|
* ```
|
|
142
175
|
*/
|
|
143
|
-
export declare function DateTimeInput({ label, isLabelHidden, description, isOptional, isRequired, isDisabled, value, onChange, changeAction, isLoading, min, max, dateConstraints, hasSeconds, hourFormat, timeIncrement, hasClear, placeholder, size: sizeProp, status, labelTooltip, numberOfMonths, width, xstyle, className, style, ref, ...rest }: DateTimeInputProps): import("react").JSX.Element;
|
|
176
|
+
export declare function DateTimeInput({ label, isLabelHidden, description, isOptional, isRequired, isDisabled, disabledMessage, value, onChange, changeAction, isLoading, min, max, dateConstraints, hasSeconds, hourFormat, timeIncrement, hasClear, placeholder, timePlaceholder, timeLabel, size: sizeProp, status, labelTooltip, numberOfMonths, width, xstyle, className, style, ref, ...rest }: DateTimeInputProps): import("react").JSX.Element;
|
|
144
177
|
export declare namespace DateTimeInput {
|
|
145
178
|
var displayName: string;
|
|
146
179
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTimeInput.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/DateTimeInput.tsx"],"names":[],"mappings":"AAuCA,OAAO,EAEL,KAAK,WAAW,EAMjB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"DateTimeInput.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/DateTimeInput.tsx"],"names":[],"mappings":"AAuCA,OAAO,EAEL,KAAK,WAAW,EAMjB,MAAM,UAAU,CAAC;AA2BlB,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAI9C,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG;IACvC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,KAAK,GAAG,KAAK,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnD,YAAY,EACV,WAAW,IAAI,mBAAmB,EAClC,eAAe,IAAI,uBAAuB,GAC3C,MAAM,UAAU,CAAC;AAiFlB,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAC9C,SAAS,EACT,UAAU,GAAG,cAAc,CAC5B;IACC,8CAA8C;IAC9C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAElC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAE1B;;;OAGG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,GAAG,SAAS,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9E;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,GAAG,CAAC,EAAE,iBAAiB,CAAC;IAExB;;;OAGG;IACH,GAAG,CAAC,EAAE,iBAAiB,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC;IAEzD;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,uBAAuB,CAAC;IAErC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAqCD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,eAAe,EACf,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,GAAG,EACH,GAAG,EACH,eAAe,EACf,UAAkB,EAClB,UAAkB,EAClB,aAAiB,EACjB,QAAgB,EAChB,WAA6B,EAC7B,eAAiC,EACjC,SAAS,EACT,IAAI,EAAE,QAAQ,EACd,MAAM,EACN,YAAY,EACZ,cAAkB,EAClB,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,kBAAkB,+BAslBpB;yBAtnBe,aAAa"}
|
|
@@ -21,10 +21,12 @@ import "../theme/tokens.stylex.js";
|
|
|
21
21
|
import { colorVars, sizeVars, radiusVars, spacingVars, typographyVars, typeScaleVars, borderVars } from "../theme/tokens.stylex.js";
|
|
22
22
|
import { Field, inputWrapperStyles, inputStatusBorderStyles, inputStatusHoverShadowStyles, inputStatusFocusWithinStyles } from "../Field/index.js";
|
|
23
23
|
import { Icon } from "../Icon/index.js";
|
|
24
|
+
import { VisuallyHidden } from "../VisuallyHidden/index.js";
|
|
24
25
|
import { Spinner } from "../Spinner/index.js";
|
|
25
26
|
import { Calendar } from "../Calendar/index.js";
|
|
26
27
|
import { useCalendarConstraints } from "../Calendar/hooks/index.js";
|
|
27
28
|
import { usePopover } from "../Popover/index.js";
|
|
29
|
+
import { useTooltip } from "../Tooltip/index.js";
|
|
28
30
|
import { useInputContainer } from "../hooks/useInputContainer.js";
|
|
29
31
|
import { parseDateInput, parseTimeInput, formatDisplayTime12h, formatDisplayTime24h, formatISOTime, isTimeInRange, adjustTime, mergeProps, mergeRefs } from "../utils/index.js";
|
|
30
32
|
import { plainDateFromISO, plainDateToISO, plainDateFormat, DATE_FORMAT_LONG } from "../utils/plainDate.js";
|
|
@@ -117,6 +119,7 @@ export function DateTimeInput({
|
|
|
117
119
|
isOptional = false,
|
|
118
120
|
isRequired = false,
|
|
119
121
|
isDisabled = false,
|
|
122
|
+
disabledMessage,
|
|
120
123
|
value,
|
|
121
124
|
onChange,
|
|
122
125
|
changeAction,
|
|
@@ -129,6 +132,8 @@ export function DateTimeInput({
|
|
|
129
132
|
timeIncrement = 1,
|
|
130
133
|
hasClear = false,
|
|
131
134
|
placeholder = 'Select a date',
|
|
135
|
+
timePlaceholder = 'Select a time',
|
|
136
|
+
timeLabel,
|
|
132
137
|
size: sizeProp,
|
|
133
138
|
status,
|
|
134
139
|
labelTooltip,
|
|
@@ -154,6 +159,22 @@ export function DateTimeInput({
|
|
|
154
159
|
const [optimisticValue, setOptimisticValue] = useOptimistic(value);
|
|
155
160
|
const isBusy = isLoading || optimisticValue !== value;
|
|
156
161
|
const isEffectivelyDisabled = isDisabled || isBusy;
|
|
162
|
+
|
|
163
|
+
// Disabled-reason tooltip. Disabled controls swallow pointer events, so the
|
|
164
|
+
// tooltip listeners attach to the outer row container (which already exists)
|
|
165
|
+
// and both the date and time inputs stay perceivable via aria-disabled
|
|
166
|
+
// instead of the disabled attribute. Typing is blocked with readOnly and the
|
|
167
|
+
// value mutation guards; calendar activation is blocked by the
|
|
168
|
+
// isEffectivelyDisabled guards. Only the persistent isDisabled state (not the
|
|
169
|
+
// transient busy state) surfaces a reason.
|
|
170
|
+
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
171
|
+
const disabledMessageTooltip = useTooltip({
|
|
172
|
+
placement: 'above',
|
|
173
|
+
// The container div is not naturally focusable; focusin bubbles up from
|
|
174
|
+
// the inputs, so always attach focus listeners.
|
|
175
|
+
focusTrigger: 'always',
|
|
176
|
+
isEnabled: showsDisabledMessage
|
|
177
|
+
});
|
|
157
178
|
const statusIconMap = {
|
|
158
179
|
warning: 'warning',
|
|
159
180
|
error: 'error',
|
|
@@ -164,7 +185,7 @@ export function DateTimeInput({
|
|
|
164
185
|
error: 'error',
|
|
165
186
|
success: 'success'
|
|
166
187
|
};
|
|
167
|
-
const ariaDescribedBy = [description ? descriptionID : null, status?.message ? statusMessageID : null].filter(Boolean).join(' ') || undefined;
|
|
188
|
+
const ariaDescribedBy = [description ? descriptionID : null, status?.message ? statusMessageID : null, showsDisabledMessage ? disabledMessageTooltip.describedBy : null].filter(Boolean).join(' ') || undefined;
|
|
168
189
|
|
|
169
190
|
// Split min/max and current value
|
|
170
191
|
const minParts = useMemo(() => splitDateTime(min), [min]);
|
|
@@ -231,12 +252,12 @@ export function DateTimeInput({
|
|
|
231
252
|
}
|
|
232
253
|
return isTimeInRange(parsed, timeMin, timeMax);
|
|
233
254
|
}, [timePendingInput, hasSeconds, timeMin, timeMax]);
|
|
234
|
-
const
|
|
255
|
+
const resolvedTimePlaceholder = useMemo(() => {
|
|
235
256
|
if (isTimeFocused && !timeDisplayValue) {
|
|
236
257
|
return hourFormat === '12h' ? 'e.g., 2:30 PM' : 'e.g., 14:30';
|
|
237
258
|
}
|
|
238
|
-
return
|
|
239
|
-
}, [isTimeFocused, timeDisplayValue, hourFormat]);
|
|
259
|
+
return timePlaceholder;
|
|
260
|
+
}, [isTimeFocused, timeDisplayValue, hourFormat, timePlaceholder]);
|
|
240
261
|
|
|
241
262
|
// --- Unified change handler ---
|
|
242
263
|
const fireChange = useCallback(newValue => {
|
|
@@ -299,6 +320,11 @@ export function DateTimeInput({
|
|
|
299
320
|
}
|
|
300
321
|
}, [valueParts.time, hasSeconds, minParts, maxParts, fireChange, popover]);
|
|
301
322
|
const handleDateInputChange = useCallback(e => {
|
|
323
|
+
// With a disabledMessage the input drops `disabled` for focusability, so
|
|
324
|
+
// guard value mutation explicitly (readOnly also blocks typing).
|
|
325
|
+
if (isEffectivelyDisabled) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
302
328
|
const text = e.target.value;
|
|
303
329
|
setDatePendingInput(text);
|
|
304
330
|
const parsed = parseDateInput(text);
|
|
@@ -308,7 +334,7 @@ export function DateTimeInput({
|
|
|
308
334
|
handleDateChange(parsedISO, 'input');
|
|
309
335
|
calendarRef.current?.navigateTo(parsedISO);
|
|
310
336
|
}
|
|
311
|
-
}, [valueParts.date, isDateDisabled, handleDateChange]);
|
|
337
|
+
}, [valueParts.date, isDateDisabled, handleDateChange, isEffectivelyDisabled]);
|
|
312
338
|
const commitDatePendingInput = useCallback(() => {
|
|
313
339
|
if (datePendingInput === null) {
|
|
314
340
|
return;
|
|
@@ -344,6 +370,11 @@ export function DateTimeInput({
|
|
|
344
370
|
|
|
345
371
|
// --- Time handlers ---
|
|
346
372
|
const handleTimeInputChange = useCallback(e => {
|
|
373
|
+
// With a disabledMessage the input drops `disabled` for focusability, so
|
|
374
|
+
// guard value mutation explicitly (readOnly also blocks typing).
|
|
375
|
+
if (isEffectivelyDisabled) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
347
378
|
const text = e.target.value;
|
|
348
379
|
setTimePendingInput(text);
|
|
349
380
|
const parsed = parseTimeInput(text, hasSeconds);
|
|
@@ -355,8 +386,16 @@ export function DateTimeInput({
|
|
|
355
386
|
}
|
|
356
387
|
}
|
|
357
388
|
}
|
|
358
|
-
}, [hasSeconds, timeMin, timeMax, valueParts.time, valueParts.date, fireChange]);
|
|
359
|
-
const handleTimeFocus = useCallback(() =>
|
|
389
|
+
}, [hasSeconds, timeMin, timeMax, valueParts.time, valueParts.date, fireChange, isEffectivelyDisabled]);
|
|
390
|
+
const handleTimeFocus = useCallback(() => {
|
|
391
|
+
// A disabled/busy input stays focusable (via aria-disabled) so its reason
|
|
392
|
+
// is discoverable, but it must not present editing affordances — keep the
|
|
393
|
+
// static placeholder rather than swapping in the format hint.
|
|
394
|
+
if (isEffectivelyDisabled) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
setIsTimeFocused(true);
|
|
398
|
+
}, [isEffectivelyDisabled]);
|
|
360
399
|
const handleTimeBlur = useCallback(() => {
|
|
361
400
|
setIsTimeFocused(false);
|
|
362
401
|
if (timePendingInput === null) {
|
|
@@ -434,6 +473,7 @@ export function DateTimeInput({
|
|
|
434
473
|
statusVariant: "detached",
|
|
435
474
|
width: width,
|
|
436
475
|
children: [/*#__PURE__*/_jsxs("div", {
|
|
476
|
+
ref: disabledMessageTooltip.ref,
|
|
437
477
|
...rest,
|
|
438
478
|
...mergeProps(themeProps('date-time-input', {
|
|
439
479
|
size,
|
|
@@ -470,11 +510,18 @@ export function DateTimeInput({
|
|
|
470
510
|
onBlur: handleDateBlur,
|
|
471
511
|
onClick: handleDateInputClick,
|
|
472
512
|
onKeyDown: handleDateKeyDown,
|
|
473
|
-
placeholder: placeholder
|
|
474
|
-
|
|
513
|
+
placeholder: placeholder
|
|
514
|
+
// With a disabledMessage the input keeps focusability via
|
|
515
|
+
// aria-disabled so the reason is focus-discoverable; typing is
|
|
516
|
+
// blocked with readOnly and the mutation guards, and calendar
|
|
517
|
+
// activation is blocked by the isEffectivelyDisabled guards.
|
|
518
|
+
,
|
|
519
|
+
disabled: isEffectivelyDisabled && !showsDisabledMessage,
|
|
520
|
+
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
521
|
+
readOnly: showsDisabledMessage || undefined,
|
|
475
522
|
"aria-describedby": ariaDescribedBy,
|
|
476
523
|
"aria-required": isRequired === true ? 'true' : undefined,
|
|
477
|
-
"aria-invalid": status?.type === 'error' ? 'true' : undefined,
|
|
524
|
+
"aria-invalid": status?.type === 'error' || !isDateInputValid ? 'true' : undefined,
|
|
478
525
|
"aria-busy": isBusy || undefined,
|
|
479
526
|
"aria-expanded": popover.isOpen,
|
|
480
527
|
"aria-haspopup": "dialog",
|
|
@@ -495,6 +542,11 @@ export function DateTimeInput({
|
|
|
495
542
|
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx xjbqb8w x1a2a7pz xeyghm5 x1h6gzvc xv1l7n4"
|
|
496
543
|
}
|
|
497
544
|
}[!!isEffectivelyDisabled << 1 | !!!isDateInputValid << 0]
|
|
545
|
+
}), /*#__PURE__*/_jsx(VisuallyHidden, {
|
|
546
|
+
as: "div",
|
|
547
|
+
role: "alert",
|
|
548
|
+
"aria-live": "assertive",
|
|
549
|
+
children: !isDateInputValid ? 'Invalid date' : ''
|
|
498
550
|
}), hasClear && value !== undefined && !isEffectivelyDisabled && /*#__PURE__*/_jsx("button", {
|
|
499
551
|
type: "button",
|
|
500
552
|
onClick: handleClear,
|
|
@@ -537,11 +589,17 @@ export function DateTimeInput({
|
|
|
537
589
|
onFocus: handleTimeFocus,
|
|
538
590
|
onBlur: handleTimeBlur,
|
|
539
591
|
onKeyDown: handleTimeKeyDown,
|
|
540
|
-
placeholder:
|
|
541
|
-
|
|
542
|
-
|
|
592
|
+
placeholder: resolvedTimePlaceholder
|
|
593
|
+
// With a disabledMessage the input keeps focusability via
|
|
594
|
+
// aria-disabled so the reason is focus-discoverable; typing is
|
|
595
|
+
// blocked with readOnly and the mutation guards.
|
|
596
|
+
,
|
|
597
|
+
disabled: isEffectivelyDisabled && !showsDisabledMessage,
|
|
598
|
+
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
599
|
+
readOnly: showsDisabledMessage || undefined,
|
|
600
|
+
"aria-label": timeLabel ?? `${label} time`,
|
|
543
601
|
"aria-required": isRequired === true ? 'true' : undefined,
|
|
544
|
-
"aria-invalid": status?.type === 'error' ? 'true' : undefined,
|
|
602
|
+
"aria-invalid": status?.type === 'error' || !isTimeInputValid ? 'true' : undefined,
|
|
545
603
|
...{
|
|
546
604
|
0: {
|
|
547
605
|
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xeyghm5"
|
|
@@ -556,6 +614,11 @@ export function DateTimeInput({
|
|
|
556
614
|
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx xjbqb8w x1a2a7pz xeyghm5 x1h6gzvc xv1l7n4"
|
|
557
615
|
}
|
|
558
616
|
}[!!isEffectivelyDisabled << 1 | !!!isTimeInputValid << 0]
|
|
617
|
+
}), /*#__PURE__*/_jsx(VisuallyHidden, {
|
|
618
|
+
as: "div",
|
|
619
|
+
role: "alert",
|
|
620
|
+
"aria-live": "assertive",
|
|
621
|
+
children: !isTimeInputValid ? 'Invalid time' : ''
|
|
559
622
|
})]
|
|
560
623
|
})]
|
|
561
624
|
}), popover.render(/*#__PURE__*/_jsx(Calendar, {
|
|
@@ -570,7 +633,7 @@ export function DateTimeInput({
|
|
|
570
633
|
}), {
|
|
571
634
|
placement: 'below',
|
|
572
635
|
alignment: 'start'
|
|
573
|
-
})]
|
|
636
|
+
}), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
|
|
574
637
|
});
|
|
575
638
|
}
|
|
576
639
|
DateTimeInput.displayName = 'DateTimeInput';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAA6B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACjE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAA6B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACjE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAoB5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAwBhD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,IAAI,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAyHD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,QAAgB,EAChB,YAAY,EACZ,KAAW,EACX,SAAkB,EAClB,QAAQ,EACR,OAAoB,EACpB,OAAgB,EAChB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,sCAyOb;yBAzPe,MAAM"}
|
package/dist/Dialog/Dialog.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { useEffect, useMemo, useRef } from 'react';
|
|
19
19
|
import * as stylex from '@stylexjs/stylex';
|
|
20
20
|
import { useScrollLock } from "../hooks/useScrollLock.js";
|
|
21
|
+
import { hasActiveFocusTrapEscape, isImeKeyEvent } from "../hooks/useFocusTrap.js";
|
|
21
22
|
import "../theme/tokens.stylex.js";
|
|
22
23
|
import { colorVars, radiusVars, durationVars, easeVars, shadowVars } from "../theme/tokens.stylex.js";
|
|
23
24
|
import { container } from "../Layout/container.stylex.js";
|
|
@@ -300,6 +301,12 @@ export function Dialog({
|
|
|
300
301
|
}
|
|
301
302
|
const handleKeyDown = event => {
|
|
302
303
|
if (event.key === 'Escape') {
|
|
304
|
+
// Ignore IME composition-cancel, and defer to any popover/menu layered
|
|
305
|
+
// on top of this dialog so a single Escape closes only the top-most
|
|
306
|
+
// layer (the popover's own focus trap handles it and stops propagation).
|
|
307
|
+
if (isImeKeyEvent(event) || hasActiveFocusTrapEscape()) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
303
310
|
event.preventDefault();
|
|
304
311
|
if (allowEscape) {
|
|
305
312
|
onOpenChange(false);
|
|
@@ -324,6 +331,11 @@ export function Dialog({
|
|
|
324
331
|
// Handle native cancel event (browser Escape handling)
|
|
325
332
|
const handleCancel = event => {
|
|
326
333
|
event.preventDefault();
|
|
334
|
+
// Defer to a popover/menu layered on top of this dialog; it will dismiss
|
|
335
|
+
// itself on the same Escape press.
|
|
336
|
+
if (hasActiveFocusTrapEscape()) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
327
339
|
if (allowEscape) {
|
|
328
340
|
onOpenChange(false);
|
|
329
341
|
}
|
|
@@ -51,13 +51,6 @@ interface DropdownMenuBaseProps extends BaseProps {
|
|
|
51
51
|
* @default 'below'
|
|
52
52
|
*/
|
|
53
53
|
placement?: LayerPlacement;
|
|
54
|
-
/**
|
|
55
|
-
* Whether to auto-focus the first menu item when the menu opens.
|
|
56
|
-
* Set to `false` for inline showcases or documentation previews
|
|
57
|
-
* where stealing focus is undesirable.
|
|
58
|
-
* @default true
|
|
59
|
-
*/
|
|
60
|
-
hasAutoFocus?: boolean;
|
|
61
54
|
'data-testid'?: string;
|
|
62
55
|
}
|
|
63
56
|
interface DropdownMenuDataProps extends DropdownMenuBaseProps {
|
|
@@ -69,7 +62,7 @@ interface DropdownMenuCompoundProps extends DropdownMenuBaseProps {
|
|
|
69
62
|
children: ReactNode;
|
|
70
63
|
}
|
|
71
64
|
export type DropdownMenuProps = DropdownMenuDataProps | DropdownMenuCompoundProps;
|
|
72
|
-
export declare function DropdownMenu({ button, isMenuOpen: controlledIsOpen, onOpenChange, menuWidth, onClick, hasChevron, placement,
|
|
65
|
+
export declare function DropdownMenu({ button, isMenuOpen: controlledIsOpen, onOpenChange, menuWidth, onClick, hasChevron, placement, className, style, xstyle, 'data-testid': testId, ...props }: DropdownMenuProps): React.JSX.Element;
|
|
73
66
|
export declare namespace DropdownMenu {
|
|
74
67
|
var displayName: string;
|
|
75
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAS,KAAK,WAAW,EAAC,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAS,KAAK,WAAW,EAAC,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAUtC,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAQtD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAwC5C,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,oBAAoB,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,kBAAkB,GAC1B,oBAAoB,GACpB,mBAAmB,GACnB,mBAAmB,CAAC;AAMxB,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAEnE,UAAU,qBAAsB,SAAQ,SAAS;IAC/C,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,qBAAsB,SAAQ,qBAAqB;IAC3D,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,UAAU,yBAA0B,SAAQ,qBAAqB;IAC/D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,MAAM,iBAAiB,GACzB,qBAAqB,GACrB,yBAAyB,CAAC;AA4B9B,wBAAgB,YAAY,CAAC,EAC3B,MAAuB,EACvB,UAAU,EAAE,gBAAgB,EAC5B,YAAY,EACZ,SAAS,EACT,OAAO,EACP,UAAiB,EACjB,SAAmB,EACnB,SAAS,EACT,KAAK,EACL,MAAM,EACN,aAAa,EAAE,MAAM,EACrB,GAAG,KAAK,EACT,EAAE,iBAAiB,qBAqQnB;yBAlRe,YAAY"}
|
|
@@ -29,6 +29,7 @@ import { Icon } from "../Icon/index.js";
|
|
|
29
29
|
import { renderDropdownItems } from "./renderDropdownItems.js";
|
|
30
30
|
import { DropdownMenuContext } from "./DropdownMenuContext.js";
|
|
31
31
|
import { useListFocus } from "../hooks/useListFocus.js";
|
|
32
|
+
import { useTypeahead } from "../hooks/useTypeahead.js";
|
|
32
33
|
import { layerAnimations } from "../Layer/layerAnimations.stylex.js";
|
|
33
34
|
import "../theme/tokens.stylex.js";
|
|
34
35
|
import { spacingVars, radiusVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
|
|
@@ -118,7 +119,6 @@ export function DropdownMenu({
|
|
|
118
119
|
onClick,
|
|
119
120
|
hasChevron = true,
|
|
120
121
|
placement = 'below',
|
|
121
|
-
hasAutoFocus = true,
|
|
122
122
|
className,
|
|
123
123
|
style,
|
|
124
124
|
xstyle,
|
|
@@ -171,7 +171,10 @@ export function DropdownMenu({
|
|
|
171
171
|
onShow: handleLayerShow,
|
|
172
172
|
hasLightDismiss: true,
|
|
173
173
|
hasCloseButton: false,
|
|
174
|
-
hasAutoFocus: false
|
|
174
|
+
hasAutoFocus: false,
|
|
175
|
+
// The popup's own role="menu" is the exposed semantics; wrapping it in a
|
|
176
|
+
// modal dialog would announce an unnamed dialog around the menu.
|
|
177
|
+
role: 'none'
|
|
175
178
|
});
|
|
176
179
|
const closeMenu = useCallback(() => {
|
|
177
180
|
popover.hide();
|
|
@@ -181,28 +184,36 @@ export function DropdownMenu({
|
|
|
181
184
|
const {
|
|
182
185
|
listRef,
|
|
183
186
|
handleKeyDown: listNavKeyDown,
|
|
184
|
-
focusFirst
|
|
187
|
+
focusFirst,
|
|
188
|
+
focusItem
|
|
185
189
|
} = useListFocus({
|
|
186
190
|
itemSelector: '[role="menuitem"]:not([aria-disabled="true"])',
|
|
187
191
|
wrap: false,
|
|
188
192
|
onEscape: closeMenu
|
|
189
193
|
});
|
|
190
194
|
|
|
195
|
+
// First-character typeahead over the (enabled) menu items — jump to the next
|
|
196
|
+
// item whose label starts with the typed text (menus-11).
|
|
197
|
+
const getMenuItems = useCallback(() => listRef.current ? Array.from(listRef.current.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])')) : [], [listRef]);
|
|
198
|
+
const typeahead = useTypeahead({
|
|
199
|
+
getItemLabels: () => getMenuItems().map(el => el.textContent),
|
|
200
|
+
onMatch: focusItem,
|
|
201
|
+
getCurrentIndex: () => getMenuItems().findIndex(el => el === document.activeElement || el.contains(document.activeElement))
|
|
202
|
+
});
|
|
203
|
+
|
|
191
204
|
// Sync controlled open state → popover, and focus first item on open
|
|
192
205
|
useEffect(() => {
|
|
193
206
|
if (isControlled) {
|
|
194
207
|
if (controlledIsOpen && !popover.isOpen) {
|
|
195
208
|
popover.show();
|
|
196
|
-
|
|
197
|
-
requestAnimationFrame(() => focusFirst());
|
|
198
|
-
}
|
|
209
|
+
requestAnimationFrame(() => focusFirst());
|
|
199
210
|
} else if (!controlledIsOpen && popover.isOpen) {
|
|
200
211
|
popover.hide();
|
|
201
212
|
}
|
|
202
213
|
}
|
|
203
|
-
}, [controlledIsOpen, isControlled, popover,
|
|
214
|
+
}, [controlledIsOpen, isControlled, popover, focusFirst]);
|
|
204
215
|
|
|
205
|
-
// Extend useListFocus with Enter/Space activation
|
|
216
|
+
// Extend useListFocus with Enter/Space activation + typeahead
|
|
206
217
|
const listKeyDown = useCallback(e => {
|
|
207
218
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
208
219
|
e.preventDefault();
|
|
@@ -212,14 +223,26 @@ export function DropdownMenu({
|
|
|
212
223
|
}
|
|
213
224
|
return;
|
|
214
225
|
}
|
|
226
|
+
// APG menu-button pattern: Tab closes the menu. Menu items are
|
|
227
|
+
// tabIndex={-1} so the focus trap has nothing trappable and Tab would
|
|
228
|
+
// otherwise leak into the page while the menu stayed open (menus-5).
|
|
229
|
+
// Do NOT preventDefault — closing restores focus to the trigger, and the
|
|
230
|
+
// browser's default Tab then continues from there to the next element.
|
|
231
|
+
if (e.key === 'Tab') {
|
|
232
|
+
closeMenu();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
// Type-to-focus next; if it consumed a printable key, stop here.
|
|
236
|
+
if (typeahead.onKeyDown(e)) {
|
|
237
|
+
e.preventDefault();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
215
240
|
listNavKeyDown(e);
|
|
216
|
-
}, [listNavKeyDown]);
|
|
241
|
+
}, [listNavKeyDown, closeMenu, typeahead]);
|
|
217
242
|
const openAndFocus = useCallback(() => {
|
|
218
243
|
popover.show();
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
}, [popover, hasAutoFocus, focusFirst]);
|
|
244
|
+
requestAnimationFrame(() => focusFirst());
|
|
245
|
+
}, [popover, focusFirst]);
|
|
223
246
|
const handleButtonClick = useCallback(() => {
|
|
224
247
|
// If the menu was just closed by light dismiss (e.g. iOS Safari fires
|
|
225
248
|
// pointerdown → hide before the trigger's click), the click would
|
|
@@ -292,7 +315,12 @@ export function DropdownMenu({
|
|
|
292
315
|
}), popover.render(/*#__PURE__*/_jsx("div", {
|
|
293
316
|
ref: listRef,
|
|
294
317
|
id: menuId,
|
|
295
|
-
role: "menu"
|
|
318
|
+
role: "menu"
|
|
319
|
+
// Give the menu an accessible name from its trigger's label, so
|
|
320
|
+
// screen readers announce e.g. "Actions menu" rather than an unnamed
|
|
321
|
+
// menu (menus-13).
|
|
322
|
+
,
|
|
323
|
+
"aria-label": button.label,
|
|
296
324
|
onKeyDown: listKeyDown,
|
|
297
325
|
...mergeProps(themeProps('dropdown-menu'), stylex.props(styles.dropdown, xstyle), className, style),
|
|
298
326
|
children: /*#__PURE__*/_jsx(DropdownMenuContext, {
|
package/dist/Field/Field.d.ts
CHANGED
|
@@ -49,9 +49,26 @@ export interface FieldProps extends Omit<BaseProps<HTMLDivElement>, 'children'>
|
|
|
49
49
|
*/
|
|
50
50
|
description?: string;
|
|
51
51
|
/**
|
|
52
|
-
* ID
|
|
52
|
+
* ID of the input element this label points AT (used as the label's
|
|
53
|
+
* `htmlFor`). This is the id of the *control*, not of the label element —
|
|
54
|
+
* see `labelID` for the latter.
|
|
53
55
|
*/
|
|
54
56
|
inputID: string;
|
|
57
|
+
/**
|
|
58
|
+
* The `id` applied TO the label element itself (distinct from `inputID`,
|
|
59
|
+
* which is the control the label points at). A grouping control
|
|
60
|
+
* (radiogroup, checkbox group) references this via `aria-labelledby` to take
|
|
61
|
+
* the label as its accessible name. Pair with `isGroupLabel`.
|
|
62
|
+
*/
|
|
63
|
+
labelID?: string;
|
|
64
|
+
/**
|
|
65
|
+
* When the field wraps a group of controls rather than a single input, set
|
|
66
|
+
* this so the label renders as a non-`<label>` element (a `<span>`): a
|
|
67
|
+
* `<label>` semantically names one control and can't be associated with a
|
|
68
|
+
* group. Pair with `labelID` + `aria-labelledby` on the group.
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
isGroupLabel?: boolean;
|
|
55
72
|
/**
|
|
56
73
|
* ID for the description element (use for aria-describedby on the input).
|
|
57
74
|
*/
|
|
@@ -116,7 +133,7 @@ export interface FieldProps extends Omit<BaseProps<HTMLDivElement>, 'children'>
|
|
|
116
133
|
* </Field>
|
|
117
134
|
* ```
|
|
118
135
|
*/
|
|
119
|
-
export declare function Field({ label, isLabelHidden, description, inputID, descriptionID, isOptional, isRequired, isDisabled, labelIcon, status, labelTooltip, statusVariant, width, xstyle, children, className, style, ref, ...props }: FieldProps): import("react").JSX.Element;
|
|
136
|
+
export declare function Field({ label, isLabelHidden, description, inputID, labelID, isGroupLabel, descriptionID, isOptional, isRequired, isDisabled, labelIcon, status, labelTooltip, statusVariant, width, xstyle, children, className, style, ref, ...props }: FieldProps): import("react").JSX.Element;
|
|
120
137
|
export declare namespace Field {
|
|
121
138
|
var displayName: string;
|
|
122
139
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../src/Field/Field.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAM,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAI9C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAoCtC,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,eAAe,CAAC;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB
|
|
1
|
+
{"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../src/Field/Field.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAM,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAI9C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAoCtC,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,eAAe,CAAC;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACxC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,OAAO,EACP,OAAO,EACP,YAAoB,EACpB,aAAa,EACb,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAA0B,EAC1B,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,+BAqGZ;yBA3He,KAAK"}
|
package/dist/Field/Field.js
CHANGED
|
@@ -69,6 +69,8 @@ export function Field({
|
|
|
69
69
|
isLabelHidden = false,
|
|
70
70
|
description,
|
|
71
71
|
inputID,
|
|
72
|
+
labelID,
|
|
73
|
+
isGroupLabel = false,
|
|
72
74
|
descriptionID,
|
|
73
75
|
isOptional = false,
|
|
74
76
|
isRequired = false,
|
|
@@ -97,6 +99,8 @@ export function Field({
|
|
|
97
99
|
const labelNode = /*#__PURE__*/_jsx(FieldLabel, {
|
|
98
100
|
label: label,
|
|
99
101
|
inputID: inputID,
|
|
102
|
+
labelID: labelID,
|
|
103
|
+
isGroupLabel: isGroupLabel,
|
|
100
104
|
isLabelHidden: isLabelHidden,
|
|
101
105
|
isDisabled: isDisabled,
|
|
102
106
|
isOptional: isOptional,
|