@astryxdesign/core 0.1.9 → 0.2.0-canary.136a00f
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 +107 -0
- package/dist/Avatar/Avatar.d.ts +42 -3
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +190 -59
- package/dist/Avatar/AvatarStatusDot.d.ts +6 -4
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +58 -6
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +7 -2
- package/dist/Banner/Banner.js +2 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +11 -4
- package/dist/Breadcrumbs/index.d.ts +1 -0
- package/dist/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/Breadcrumbs/index.js +2 -1
- package/dist/Button/Button.d.ts +1 -1
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +6 -4
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +50 -9
- package/dist/Calendar/dayCellUtils.d.ts +4 -4
- package/dist/Calendar/dayCellUtils.js +2 -2
- package/dist/Calendar/styles.d.ts +30 -31
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +30 -31
- package/dist/Card/Card.js +1 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +22 -12
- package/dist/Chat/ChatComposerInput.js +1 -1
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +3 -1
- package/dist/Chat/ChatLayout.js +4 -4
- package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
- package/dist/Chat/ChatMessageBubble.js +8 -8
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +10 -3
- package/dist/Chat/useTriggerMenu.js +2 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +6 -6
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +19 -4
- package/dist/Citation/Citation.d.ts +22 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +20 -6
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +16 -10
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +3 -1
- package/dist/CommandPalette/CommandPalette.d.ts +1 -1
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +42 -3
- package/dist/CommandPalette/CommandPaletteItem.js +1 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +23 -5
- package/dist/ContextMenu/index.d.ts +1 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/ContextMenu/index.js +3 -1
- package/dist/DateInput/DateInput.d.ts +10 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +33 -19
- package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +23 -20
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +23 -18
- package/dist/Divider/Divider.d.ts +2 -2
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +13 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +22 -5
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +4 -1
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +8 -11
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioGroup.js +3 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +5 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
- package/dist/DropdownMenu/index.d.ts +10 -0
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/index.js +13 -0
- package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
- package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
- package/dist/DropdownMenu/menuItemHover.js +33 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
- package/dist/DropdownMenu/menuItemRoles.js +10 -1
- package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
- package/dist/DropdownMenu/renderDropdownItems.js +21 -6
- package/dist/Field/Field.d.ts +3 -1
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +4 -1
- package/dist/Field/FieldLabel.d.ts +2 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +9 -5
- package/dist/Field/inputStyles.stylex.d.ts +1 -0
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +1 -0
- package/dist/FieldStatus/FieldStatus.d.ts +10 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +39 -3
- package/dist/FileInput/FileInput.d.ts +10 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +93 -65
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +10 -4
- package/dist/Icon/Icon.d.ts +15 -1
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +19 -3
- package/dist/Item/Item.d.ts +16 -3
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +31 -6
- package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
- package/dist/Layer/layerAnimations.stylex.js +10 -2
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +19 -13
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +6 -3
- package/dist/List/ListItem.d.ts +11 -1
- package/dist/List/ListItem.d.ts.map +1 -1
- package/dist/List/ListItem.js +2 -0
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +7 -0
- package/dist/MetadataList/MetadataList.d.ts +1 -1
- package/dist/MetadataList/MetadataList.d.ts.map +1 -1
- package/dist/MetadataList/MetadataList.js +4 -2
- package/dist/MultiSelector/MultiSelector.d.ts +9 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +80 -42
- package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
- package/dist/NumberInput/NumberInput.d.ts +10 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +22 -17
- package/dist/Outline/Outline.js +2 -2
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +11 -3
- package/dist/PowerSearch/PowerSearch.d.ts +9 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +2 -0
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +6 -1
- package/dist/RadioList/RadioList.d.ts +2 -2
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +5 -5
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +49 -19
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +5 -3
- package/dist/Selector/Selector.d.ts +8 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +66 -17
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +5 -5
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavCollapseButton.js +13 -10
- package/dist/SideNav/SideNavItem.d.ts +1 -1
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +12 -10
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +2 -2
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +87 -34
- package/dist/Spinner/Spinner.d.ts +3 -2
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +11 -2
- package/dist/Switch/Switch.d.ts +8 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +171 -91
- package/dist/TabList/Tab.js +2 -2
- package/dist/TabList/TabList.d.ts +2 -11
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +5 -9
- package/dist/TabList/TabListContext.d.ts +0 -5
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +0 -5
- package/dist/TabList/TabMenu.js +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +30 -4
- package/dist/Table/TableCell.js +3 -3
- package/dist/Table/TableHeaderCell.js +3 -3
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +37 -27
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +3 -0
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +15 -7
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +29 -23
- package/dist/Table/types.d.ts +32 -0
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/TextArea/TextArea.d.ts +10 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +18 -19
- package/dist/TextInput/TextInput.d.ts +10 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +20 -17
- package/dist/Thumbnail/Thumbnail.js +2 -2
- package/dist/TimeInput/TimeInput.d.ts +10 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +17 -17
- package/dist/Timestamp/Timestamp.d.ts +31 -3
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +47 -76
- package/dist/Timestamp/formatInstant.d.ts +41 -0
- package/dist/Timestamp/formatInstant.d.ts.map +1 -0
- package/dist/Timestamp/formatInstant.js +177 -0
- package/dist/Timestamp/index.d.ts +1 -0
- package/dist/Timestamp/index.d.ts.map +1 -1
- package/dist/Timestamp/tooltipEntries.d.ts +56 -0
- package/dist/Timestamp/tooltipEntries.d.ts.map +1 -0
- package/dist/Timestamp/tooltipEntries.js +163 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +61 -9
- package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButton.js +3 -1
- package/dist/Token/Token.d.ts +34 -4
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +85 -45
- package/dist/Token/TokenLink.d.ts +62 -0
- package/dist/Token/TokenLink.d.ts.map +1 -0
- package/dist/Token/TokenLink.js +76 -0
- package/dist/Token/index.d.ts +1 -1
- package/dist/Token/index.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.d.ts +9 -2
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +4 -2
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +17 -1
- package/dist/TopNav/TopNavItem.d.ts +3 -1
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +30 -3
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +1 -0
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +8 -6
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +32 -14
- package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +22 -11
- package/dist/Typeahead/Typeahead.d.ts +9 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +11 -2
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +20 -10
- package/dist/astryx.css +70 -30
- package/dist/astryx.umd.js +51 -51
- package/dist/astryx.umd.js.map +4 -4
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/isRtlElement.d.ts +18 -0
- package/dist/hooks/isRtlElement.d.ts.map +1 -0
- package/dist/hooks/isRtlElement.js +27 -0
- package/dist/hooks/useAnnounce.d.ts +3 -0
- package/dist/hooks/useAnnounce.d.ts.map +1 -1
- package/dist/hooks/useAnnounce.js +39 -1
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +52 -11
- package/dist/hooks/useGridFocus.d.ts +6 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +12 -9
- package/dist/hooks/useHotkeys.d.ts +9 -0
- package/dist/hooks/useHotkeys.d.ts.map +1 -1
- package/dist/hooks/useHotkeys.js +9 -0
- package/dist/hooks/useInputStatusIcon.d.ts +38 -0
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
- package/dist/hooks/useInputStatusIcon.js +158 -0
- package/dist/hooks/useKeyboardHint.d.ts +1 -1
- package/dist/hooks/useKeyboardHint.d.ts.map +1 -1
- package/dist/hooks/useKeyboardHint.js +4 -2
- package/dist/hooks/useListFocus.d.ts +39 -1
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +54 -9
- package/dist/i18n/InternationalizationContext.d.ts +1 -0
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +3 -0
- package/dist/i18n/InternationalizationProvider.d.ts +8 -1
- package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.js +5 -1
- package/dist/i18n/getLocaleDirection.d.ts +18 -0
- package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
- package/dist/i18n/getLocaleDirection.js +29 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +7 -1
- package/dist/i18n/useDirection.d.ts +2 -0
- package/dist/i18n/useDirection.d.ts.map +1 -0
- package/dist/i18n/useDirection.js +27 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +13 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/plainDate.d.ts +17 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +23 -4
- package/dist/utils/rtlStyles.d.ts +24 -0
- package/dist/utils/rtlStyles.d.ts.map +1 -0
- package/dist/utils/rtlStyles.js +27 -0
- package/locales/en.json +112 -0
- package/locales/pseudo.json +84 -0
- package/package.json +6 -1
- package/src/Avatar/Avatar.doc.mjs +50 -3
- package/src/Avatar/Avatar.test.tsx +218 -0
- package/src/Avatar/Avatar.tsx +285 -79
- package/src/Avatar/AvatarStatusDot.doc.mjs +4 -4
- package/src/Avatar/AvatarStatusDot.tsx +6 -4
- package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
- package/src/AvatarGroup/AvatarGroup.test.tsx +162 -2
- package/src/AvatarGroup/AvatarGroup.tsx +58 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +5 -2
- package/src/Banner/Banner.tsx +6 -6
- package/src/Breadcrumbs/BreadcrumbItem.tsx +10 -10
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +52 -1
- package/src/Breadcrumbs/index.ts +4 -0
- package/src/Button/Button.doc.mjs +0 -4
- package/src/Button/Button.test.tsx +16 -0
- package/src/Button/Button.tsx +6 -4
- package/src/Calendar/Calendar.test.tsx +170 -20
- package/src/Calendar/Calendar.tsx +73 -16
- package/src/Calendar/dayCellUtils.test.ts +18 -18
- package/src/Calendar/dayCellUtils.ts +2 -2
- package/src/Calendar/styles.ts +33 -39
- package/src/Card/Card.tsx +1 -1
- package/src/Carousel/Carousel.tsx +25 -6
- package/src/Chat/ChatComposer.doc.mjs +2 -2
- package/src/Chat/ChatComposerInput.doc.mjs +1 -1
- package/src/Chat/ChatComposerInput.tsx +2 -2
- package/src/Chat/ChatDictationButton.tsx +7 -1
- package/src/Chat/ChatLayout.tsx +4 -4
- package/src/Chat/ChatMessageBubble.tsx +15 -10
- package/src/Chat/ChatSystemMessage.test.tsx +5 -0
- package/src/Chat/ChatToolCalls.tsx +9 -2
- package/src/Chat/useTriggerMenu.tsx +1 -1
- package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +23 -0
- package/src/CheckboxInput/CheckboxInput.tsx +21 -6
- package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
- package/src/CheckboxList/CheckboxList.test.tsx +94 -3
- package/src/CheckboxList/CheckboxListItem.tsx +17 -10
- package/src/Citation/Citation.doc.mjs +4 -3
- package/src/Citation/Citation.test.tsx +97 -0
- package/src/Citation/Citation.tsx +43 -11
- package/src/CodeBlock/CodeBlock.test.tsx +17 -0
- package/src/CodeBlock/CodeBlock.tsx +38 -11
- package/src/Collapsible/Collapsible.doc.mjs +1 -0
- package/src/Collapsible/Collapsible.test.tsx +7 -0
- package/src/Collapsible/Collapsible.tsx +16 -6
- package/src/CommandPalette/CommandPalette.test.tsx +95 -1
- package/src/CommandPalette/CommandPalette.tsx +41 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
- package/src/ContextMenu/ContextMenu.test.tsx +59 -2
- package/src/ContextMenu/ContextMenu.tsx +22 -11
- package/src/ContextMenu/index.ts +5 -0
- package/src/DateInput/DateInput.doc.mjs +25 -0
- package/src/DateInput/DateInput.test.tsx +230 -0
- package/src/DateInput/DateInput.tsx +51 -29
- package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
- package/src/DateRangeInput/DateRangeInput.tsx +42 -30
- package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
- package/src/DateTimeInput/DateTimeInput.test.tsx +112 -0
- package/src/DateTimeInput/DateTimeInput.tsx +44 -39
- package/src/Divider/Divider.test.tsx +32 -8
- package/src/Divider/Divider.tsx +14 -1
- package/src/DropdownMenu/DropdownMenu.test.tsx +60 -0
- package/src/DropdownMenu/DropdownMenu.tsx +31 -12
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +8 -2
- package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
- package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +4 -12
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +9 -10
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +9 -3
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +20 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
- package/src/DropdownMenu/index.ts +16 -0
- package/src/DropdownMenu/menuItemHover.ts +39 -0
- package/src/DropdownMenu/menuItemRoles.ts +9 -0
- package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
- package/src/Field/Field.tsx +14 -9
- package/src/Field/FieldLabel.test.tsx +25 -0
- package/src/Field/FieldLabel.tsx +12 -3
- package/src/Field/inputStyles.stylex.ts +2 -0
- package/src/FieldStatus/FieldStatus.test.tsx +72 -0
- package/src/FieldStatus/FieldStatus.tsx +48 -2
- package/src/FileInput/FileInput.doc.mjs +23 -2
- package/src/FileInput/FileInput.test.tsx +104 -13
- package/src/FileInput/FileInput.tsx +106 -79
- package/src/HoverCard/useHoverCard.tsx +15 -3
- package/src/Icon/Icon.doc.mjs +13 -0
- package/src/Icon/Icon.test.tsx +89 -0
- package/src/Icon/Icon.tsx +51 -3
- package/src/Item/Item.doc.mjs +5 -0
- package/src/Item/Item.test.tsx +88 -0
- package/src/Item/Item.tsx +57 -11
- package/src/Layer/layerAnimations.stylex.ts +23 -0
- package/src/Lightbox/Lightbox.tsx +15 -7
- package/src/List/List.test.tsx +17 -29
- package/src/List/List.tsx +6 -1
- package/src/List/ListItem.doc.mjs +12 -0
- package/src/List/ListItem.tsx +13 -0
- package/src/Markdown/Markdown.test.tsx +21 -0
- package/src/Markdown/Markdown.tsx +4 -0
- package/src/MetadataList/MetadataList.test.tsx +24 -0
- package/src/MetadataList/MetadataList.tsx +6 -2
- package/src/MultiSelector/MultiSelector.doc.mjs +20 -0
- package/src/MultiSelector/MultiSelector.test.tsx +402 -0
- package/src/MultiSelector/MultiSelector.tsx +120 -59
- package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +21 -0
- package/src/NumberInput/NumberInput.test.tsx +71 -0
- package/src/NumberInput/NumberInput.tsx +35 -26
- package/src/Outline/Outline.test.tsx +12 -12
- package/src/Outline/Outline.tsx +2 -2
- package/src/Pagination/Pagination.tsx +11 -3
- package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
- package/src/PowerSearch/PowerSearch.test.tsx +23 -0
- package/src/PowerSearch/PowerSearch.tsx +10 -1
- package/src/ProgressBar/ProgressBar.test.tsx +34 -0
- package/src/ProgressBar/ProgressBar.tsx +16 -1
- package/src/RadioList/RadioList.doc.mjs +6 -0
- package/src/RadioList/RadioList.test.tsx +26 -4
- package/src/RadioList/RadioList.tsx +2 -2
- package/src/RadioList/RadioListItem.tsx +12 -5
- package/src/Resizable/ResizeHandle.test.tsx +94 -0
- package/src/Resizable/ResizeHandle.tsx +70 -20
- package/src/SegmentedControl/SegmentedControl.test.tsx +28 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +22 -2
- package/src/Selector/Selector.doc.mjs +15 -0
- package/src/Selector/Selector.test.tsx +370 -0
- package/src/Selector/Selector.tsx +88 -20
- package/src/SideNav/SideNav.tsx +1 -8
- package/src/SideNav/SideNavCollapseButton.tsx +9 -7
- package/src/SideNav/SideNavItem.tsx +5 -3
- package/src/Skeleton/Skeleton.test.tsx +16 -0
- package/src/Skeleton/Skeleton.tsx +13 -1
- package/src/Slider/Slider.doc.mjs +6 -0
- package/src/Slider/Slider.test.tsx +240 -12
- package/src/Slider/Slider.tsx +96 -23
- package/src/Spinner/Spinner.test.tsx +10 -8
- package/src/Spinner/Spinner.tsx +15 -5
- package/src/Switch/Switch.doc.mjs +142 -42
- package/src/Switch/Switch.test.tsx +111 -0
- package/src/Switch/Switch.tsx +149 -32
- package/src/TabList/Tab.tsx +2 -2
- package/src/TabList/TabList.doc.mjs +0 -6
- package/src/TabList/TabList.test.tsx +3 -15
- package/src/TabList/TabList.tsx +6 -17
- package/src/TabList/TabListContext.ts +0 -6
- package/src/TabList/TabMenu.tsx +2 -2
- package/src/Table/BaseTable.tsx +34 -2
- package/src/Table/Table.doc.mjs +11 -0
- package/src/Table/Table.test.tsx +85 -0
- package/src/Table/TableCell.tsx +3 -3
- package/src/Table/TableHeaderCell.tsx +3 -3
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +9 -6
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +19 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +27 -18
- package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
- package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +38 -9
- package/src/Table/plugins/tree/useTableTreeData.tsx +17 -13
- package/src/Table/types.ts +33 -0
- package/src/Table/useTableRowStatus.doc.mjs +1 -1
- package/src/TextArea/TextArea.doc.mjs +21 -0
- package/src/TextArea/TextArea.test.tsx +23 -0
- package/src/TextArea/TextArea.tsx +27 -26
- package/src/TextInput/TextInput.doc.mjs +21 -0
- package/src/TextInput/TextInput.test.tsx +150 -0
- package/src/TextInput/TextInput.tsx +28 -25
- package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
- package/src/Thumbnail/Thumbnail.tsx +1 -1
- package/src/TimeInput/TimeInput.doc.mjs +21 -0
- package/src/TimeInput/TimeInput.test.tsx +23 -0
- package/src/TimeInput/TimeInput.tsx +24 -25
- package/src/Timestamp/Timestamp.doc.mjs +32 -6
- package/src/Timestamp/Timestamp.test.tsx +371 -0
- package/src/Timestamp/Timestamp.tsx +96 -93
- package/src/Timestamp/formatInstant.ts +218 -0
- package/src/Timestamp/index.ts +4 -0
- package/src/Timestamp/tooltipEntries.test.ts +552 -0
- package/src/Timestamp/tooltipEntries.ts +210 -0
- package/src/Toast/ToastViewport.test.tsx +218 -8
- package/src/Toast/ToastViewport.tsx +71 -12
- package/src/ToggleButton/ToggleButton.test.tsx +24 -0
- package/src/ToggleButton/ToggleButton.tsx +19 -1
- package/src/Token/Token.test.tsx +166 -15
- package/src/Token/Token.tsx +104 -47
- package/src/Token/TokenLink.tsx +107 -0
- package/src/Token/index.ts +1 -1
- package/src/Tokenizer/Tokenizer.doc.mjs +23 -1
- package/src/Tokenizer/Tokenizer.test.tsx +23 -0
- package/src/Tokenizer/Tokenizer.tsx +14 -2
- package/src/Tooltip/Tooltip.test.tsx +46 -0
- package/src/Tooltip/useTooltip.tsx +20 -0
- package/src/TopNav/TopNav.test.tsx +93 -2
- package/src/TopNav/TopNavItem.doc.mjs +3 -3
- package/src/TopNav/TopNavItem.tsx +35 -6
- package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +1 -1
- package/src/TreeList/TreeList.doc.mjs +6 -0
- package/src/TreeList/TreeList.test.tsx +50 -10
- package/src/TreeList/TreeList.tsx +5 -0
- package/src/TreeList/TreeListBranches.tsx +8 -6
- package/src/TreeList/TreeListItem.tsx +33 -11
- package/src/Typeahead/BaseTypeahead.tsx +42 -15
- package/src/Typeahead/Typeahead.doc.mjs +13 -0
- package/src/Typeahead/Typeahead.test.tsx +112 -0
- package/src/Typeahead/Typeahead.tsx +17 -1
- package/src/Typeahead/TypeaheadItem.tsx +2 -1
- package/src/__tests__/forcedColors.ts +60 -0
- package/src/__tests__/inputWidthContract.test.tsx +62 -0
- package/src/doc-mjs.d.ts +19 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/isRtlElement.ts +27 -0
- package/src/hooks/useAnnounce.test.tsx +75 -2
- package/src/hooks/useAnnounce.ts +47 -1
- package/src/hooks/useFocusTrap.test.tsx +104 -0
- package/src/hooks/useFocusTrap.ts +61 -12
- package/src/hooks/useGridFocus.doc.mjs +3 -3
- package/src/hooks/useGridFocus.test.tsx +41 -0
- package/src/hooks/useGridFocus.ts +21 -10
- package/src/hooks/useHotkeys.ts +9 -0
- package/src/hooks/useInputStatusIcon.test.tsx +162 -0
- package/src/hooks/useInputStatusIcon.tsx +224 -0
- package/src/hooks/useKeyboardHint.test.tsx +22 -0
- package/src/hooks/useKeyboardHint.tsx +6 -2
- package/src/hooks/useListFocus.doc.mjs +25 -3
- package/src/hooks/useListFocus.test.tsx +153 -1
- package/src/hooks/useListFocus.ts +102 -9
- package/src/i18n/InternationalizationContext.ts +4 -0
- package/src/i18n/InternationalizationProvider.tsx +12 -2
- package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
- package/src/i18n/__tests__/useDirection.test.tsx +66 -0
- package/src/i18n/getLocaleDirection.ts +29 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/useDirection.ts +29 -0
- package/src/reset.css +0 -26
- package/src/reset.test.ts +60 -0
- package/src/theme/derivedVarRegistry.test.ts +1 -0
- package/src/theme/derivedVarRegistry.ts +6 -0
- package/src/theme/generateThemeRules.test.ts +42 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/plainDate.test.ts +24 -6
- package/src/utils/plainDate.ts +18 -4
- package/src/utils/rtlStyles.ts +27 -0
package/dist/hooks/index.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export { useClickableContainer, INTERACTIVE_SELECTORS, } from './useClickableCon
|
|
|
38
38
|
export type { UseClickableContainerOptions, ClickableContainerResult, } from './useClickableContainer';
|
|
39
39
|
export { useInputContainer } from './useInputContainer';
|
|
40
40
|
export type { UseInputContainerOptions } from './useInputContainer';
|
|
41
|
+
export { useInputStatusIcon } from './useInputStatusIcon';
|
|
42
|
+
export type { UseInputStatusIconOptions, UseInputStatusIconReturn, } from './useInputStatusIcon';
|
|
41
43
|
export { useInteractiveRole } from './useInteractiveRole';
|
|
42
44
|
export type { InteractiveRole, UseInteractiveRoleOptions, } from './useInteractiveRole';
|
|
43
45
|
export { useLongPress } from './useLongPress';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,YAAY,EAAC,UAAU,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAElE,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,YAAY,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAC,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,YAAY,EAAC,kBAAkB,EAAE,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAC,mBAAmB,EAAC,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,iBAAiB,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAC,wBAAwB,EAAC,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,YAAY,EACV,eAAe,EACf,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,YAAY,EAAC,UAAU,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAElE,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,YAAY,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAC,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,YAAY,EAAC,kBAAkB,EAAE,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAC,mBAAmB,EAAC,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,iBAAiB,EAAE,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAC,wBAAwB,EAAC,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,YAAY,EACV,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,YAAY,EACV,eAAe,EACf,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC"}
|
package/dist/hooks/index.js
CHANGED
|
@@ -27,6 +27,7 @@ export { useStreamingText } from "./useStreamingText.js";
|
|
|
27
27
|
export { useImageMode } from "./useImageMode.js";
|
|
28
28
|
export { useClickableContainer, INTERACTIVE_SELECTORS } from "./useClickableContainer.js";
|
|
29
29
|
export { useInputContainer } from "./useInputContainer.js";
|
|
30
|
+
export { useInputStatusIcon } from "./useInputStatusIcon.js";
|
|
30
31
|
export { useInteractiveRole } from "./useInteractiveRole.js";
|
|
31
32
|
export { useLongPress } from "./useLongPress.js";
|
|
32
33
|
export { useDevWarning } from "./useDevWarning.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file isRtlElement.ts
|
|
3
|
+
* @input DOM element (nullable)
|
|
4
|
+
* @output Exports isRtlElement helper resolving an element's computed text
|
|
5
|
+
* direction
|
|
6
|
+
* @position Internal hook utility; used by useListFocus and useGridFocus to
|
|
7
|
+
* auto-detect RTL for arrow-key navigation (same getComputedStyle precedent
|
|
8
|
+
* as Resizable's ResizeHandle drag deltas).
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Whether `el` renders right-to-left, per its computed `direction`.
|
|
12
|
+
*
|
|
13
|
+
* SSR-safe: returns false when `el` is null or no DOM is available. Callers
|
|
14
|
+
* should invoke this lazily (on keydown, not on render) so getComputedStyle
|
|
15
|
+
* runs only when a horizontal arrow key is actually handled.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isRtlElement(el: HTMLElement | null): boolean;
|
|
18
|
+
//# sourceMappingURL=isRtlElement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isRtlElement.d.ts","sourceRoot":"","sources":["../../src/hooks/isRtlElement.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAK5D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file isRtlElement.ts
|
|
7
|
+
* @input DOM element (nullable)
|
|
8
|
+
* @output Exports isRtlElement helper resolving an element's computed text
|
|
9
|
+
* direction
|
|
10
|
+
* @position Internal hook utility; used by useListFocus and useGridFocus to
|
|
11
|
+
* auto-detect RTL for arrow-key navigation (same getComputedStyle precedent
|
|
12
|
+
* as Resizable's ResizeHandle drag deltas).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Whether `el` renders right-to-left, per its computed `direction`.
|
|
17
|
+
*
|
|
18
|
+
* SSR-safe: returns false when `el` is null or no DOM is available. Callers
|
|
19
|
+
* should invoke this lazily (on keydown, not on render) so getComputedStyle
|
|
20
|
+
* runs only when a horizontal arrow key is actually handled.
|
|
21
|
+
*/
|
|
22
|
+
export function isRtlElement(el) {
|
|
23
|
+
if (!el || typeof window === 'undefined') {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return window.getComputedStyle(el).direction === 'rtl';
|
|
27
|
+
}
|
|
@@ -17,6 +17,9 @@ export type AnnounceFn = (message: string, politeness?: AnnouncePoliteness) => v
|
|
|
17
17
|
* The polite and assertive regions are created once on first use and kept
|
|
18
18
|
* mounted, so announcements are reliable even for messages that appear
|
|
19
19
|
* immediately (unlike a live region rendered together with its content).
|
|
20
|
+
* Each message is automatically cleared a couple of seconds after being
|
|
21
|
+
* announced, so users browsing the DOM later do not encounter stale status
|
|
22
|
+
* text; announcing again before the clear simply resets the countdown.
|
|
20
23
|
*
|
|
21
24
|
* @example
|
|
22
25
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnnounce.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnnounce.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useAnnounce.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnnounce.ts"],"names":[],"mappings":"AAmBA;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAExD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,kBAAkB,KAC5B,IAAI,CAAC;AAgIV;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,IAAI,UAAU,CAaxC;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAQhD"}
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* @input Uses React useCallback; DOM APIs for a singleton live-region pair
|
|
8
8
|
* @output Exports useAnnounce hook and AnnouncePoliteness type
|
|
9
9
|
* @position Core a11y hook; provides imperative screen-reader announcements
|
|
10
|
-
* via persistently-mounted polite/assertive live regions
|
|
10
|
+
* via persistently-mounted polite/assertive live regions; regions are
|
|
11
|
+
* auto-cleared shortly after announcing so stale status text does not
|
|
12
|
+
* linger in the accessibility tree
|
|
11
13
|
*
|
|
12
14
|
* SYNC: When modified, update:
|
|
13
15
|
* - /packages/core/src/hooks/index.ts
|
|
@@ -31,6 +33,32 @@ const CONTAINER_ATTR = 'data-astryx-live-region';
|
|
|
31
33
|
// Visually-hidden clip block (matches the VisuallyHidden primitive). Applied
|
|
32
34
|
// inline so the regions work without any stylesheet being present.
|
|
33
35
|
const VISUALLY_HIDDEN_CSS = 'position:absolute;width:1px;height:1px;margin:-1px;padding:0;' + 'overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;' + 'inset-block-start:0;inset-inline-start:0;pointer-events:none;' + 'user-select:none;';
|
|
36
|
+
/**
|
|
37
|
+
* How long an announcement stays in its region before being auto-cleared.
|
|
38
|
+
* Long enough for screen readers to pick the message up and finish reading
|
|
39
|
+
* it; clearing afterwards keeps stale status text out of the accessibility
|
|
40
|
+
* tree for users who browse the DOM later. Each announce resets the timer.
|
|
41
|
+
*/
|
|
42
|
+
const CLEAR_DELAY_MS = 2000;
|
|
43
|
+
const clearTimers = {
|
|
44
|
+
polite: null,
|
|
45
|
+
assertive: null
|
|
46
|
+
};
|
|
47
|
+
function cancelScheduledClear(politeness) {
|
|
48
|
+
const timer = clearTimers[politeness];
|
|
49
|
+
if (timer != null) {
|
|
50
|
+
clearTimeout(timer);
|
|
51
|
+
clearTimers[politeness] = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function scheduleClear(politeness, target) {
|
|
55
|
+
cancelScheduledClear(politeness);
|
|
56
|
+
clearTimers[politeness] = setTimeout(() => {
|
|
57
|
+
clearTimers[politeness] = null;
|
|
58
|
+
target.textContent = '';
|
|
59
|
+
}, CLEAR_DELAY_MS);
|
|
60
|
+
}
|
|
61
|
+
|
|
34
62
|
// Singleton: the live regions are created ONCE and stay mounted for the
|
|
35
63
|
// lifetime of the document. This is the crux of reliable announcements — many
|
|
36
64
|
// screen readers will not announce content injected into a live region that is
|
|
@@ -81,6 +109,10 @@ function announceMessage(message, politeness) {
|
|
|
81
109
|
requestAnimationFrame(() => {
|
|
82
110
|
target.textContent = message;
|
|
83
111
|
});
|
|
112
|
+
// Auto-clear so the last message does not linger in the accessibility tree
|
|
113
|
+
// indefinitely. Scheduled per announce, so a newer announcement always
|
|
114
|
+
// resets the countdown (the delay comfortably outlasts the rAF re-set).
|
|
115
|
+
scheduleClear(politeness, target);
|
|
84
116
|
}
|
|
85
117
|
|
|
86
118
|
/**
|
|
@@ -89,6 +121,7 @@ function announceMessage(message, politeness) {
|
|
|
89
121
|
* so stale status text does not linger in the accessibility tree.
|
|
90
122
|
*/
|
|
91
123
|
function clearRegion(politeness) {
|
|
124
|
+
cancelScheduledClear(politeness);
|
|
92
125
|
if (!regions) {
|
|
93
126
|
return;
|
|
94
127
|
}
|
|
@@ -103,6 +136,9 @@ function clearRegion(politeness) {
|
|
|
103
136
|
* The polite and assertive regions are created once on first use and kept
|
|
104
137
|
* mounted, so announcements are reliable even for messages that appear
|
|
105
138
|
* immediately (unlike a live region rendered together with its content).
|
|
139
|
+
* Each message is automatically cleared a couple of seconds after being
|
|
140
|
+
* announced, so users browsing the DOM later do not encounter stale status
|
|
141
|
+
* text; announcing again before the clear simply resets the countdown.
|
|
106
142
|
*
|
|
107
143
|
* @example
|
|
108
144
|
* ```
|
|
@@ -134,6 +170,8 @@ export function useAnnounce() {
|
|
|
134
170
|
* @internal
|
|
135
171
|
*/
|
|
136
172
|
export function __resetLiveRegionsForTest() {
|
|
173
|
+
cancelScheduledClear('polite');
|
|
174
|
+
cancelScheduledClear('assertive');
|
|
137
175
|
if (regions) {
|
|
138
176
|
regions.polite.remove();
|
|
139
177
|
regions.assertive.remove();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFocusTrap.d.ts","sourceRoot":"","sources":["../../src/hooks/useFocusTrap.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useFocusTrap.d.ts","sourceRoot":"","sources":["../../src/hooks/useFocusTrap.ts"],"names":[],"mappings":"AAsFA;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAEV;AAgFD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IACrE;;OAEG;IACH,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAExC;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAC9D,OAAO,EAAE,mBAAmB,GAC3B,kBAAkB,CAAC,CAAC,CAAC,CAsMvB"}
|
|
@@ -24,21 +24,51 @@ import { FOCUSABLE_SELECTOR } from "./focusableSelector.js";
|
|
|
24
24
|
* Every active `useFocusTrap` used to attach its own document-level `keydown`
|
|
25
25
|
* listener with no coordination, so a single Escape press closed *every* open
|
|
26
26
|
* layer at once (e.g. a popover nested inside a Dialog closed both). Tracking
|
|
27
|
-
* traps in a shared stack lets only the most
|
|
28
|
-
*
|
|
27
|
+
* traps in a shared stack lets only the top-most trap respond to Escape.
|
|
28
|
+
*
|
|
29
|
+
* "Top-most" is resolved by DOM containment first, push order second. Push
|
|
30
|
+
* order alone is not reliable: React runs child effects before parent
|
|
31
|
+
* effects, so when an outer and an inner (DOM-nested) trap mount in the SAME
|
|
32
|
+
* commit, the inner trap pushes first and the outer trap would wrongly win a
|
|
33
|
+
* pure last-pushed comparison.
|
|
29
34
|
*/
|
|
35
|
+
|
|
30
36
|
const escapeStack = [];
|
|
31
|
-
function pushEscapeHandler(
|
|
32
|
-
escapeStack.push(
|
|
37
|
+
function pushEscapeHandler(entry) {
|
|
38
|
+
escapeStack.push(entry);
|
|
33
39
|
}
|
|
34
40
|
function removeEscapeHandler(handler) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
for (let i = escapeStack.length - 1; i >= 0; i--) {
|
|
42
|
+
if (escapeStack[i].handler === handler) {
|
|
43
|
+
escapeStack.splice(i, 1);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
47
|
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the top-most trap: walk the stack in push order, keeping the
|
|
51
|
+
* deepest container by DOM containment. When a later entry's container
|
|
52
|
+
* contains the current candidate's container, the candidate is nested inside
|
|
53
|
+
* it and stays on top; otherwise the later push wins (containment for nested
|
|
54
|
+
* traps, push order as the tiebreaker for unrelated ones).
|
|
55
|
+
*/
|
|
40
56
|
function isTopEscapeHandler(handler) {
|
|
41
|
-
|
|
57
|
+
if (escapeStack.length === 0) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
let top = escapeStack[0];
|
|
61
|
+
for (let i = 1; i < escapeStack.length; i++) {
|
|
62
|
+
const entry = escapeStack[i];
|
|
63
|
+
const topContainer = top.getContainer();
|
|
64
|
+
const entryContainer = entry.getContainer();
|
|
65
|
+
if (topContainer != null && entryContainer != null && entryContainer !== topContainer && entryContainer.contains(topContainer)) {
|
|
66
|
+
// The current top is nested inside this entry — it stays on top.
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
top = entry;
|
|
70
|
+
}
|
|
71
|
+
return top.handler === handler;
|
|
42
72
|
}
|
|
43
73
|
|
|
44
74
|
/**
|
|
@@ -65,7 +95,9 @@ export function isImeKeyEvent(event) {
|
|
|
65
95
|
/**
|
|
66
96
|
* Whether an element is currently perceivable/focusable — excludes ones hidden
|
|
67
97
|
* via `display:none`/`visibility:hidden` or inside an `inert`/`hidden` subtree,
|
|
68
|
-
* which the browser skips for Tab
|
|
98
|
+
* which the browser skips for Tab, and ones inside an `aria-hidden="true"`
|
|
99
|
+
* subtree, which sighted-keyboard users could Tab to while AT skips them
|
|
100
|
+
* (WCAG 4.1.2 — focusable content must be exposed to assistive tech).
|
|
69
101
|
*/
|
|
70
102
|
function isVisiblyFocusable(el) {
|
|
71
103
|
if (el.hasAttribute('inert') || el.closest('[inert]')) {
|
|
@@ -74,6 +106,10 @@ function isVisiblyFocusable(el) {
|
|
|
74
106
|
if (el.hidden || el.closest('[hidden]')) {
|
|
75
107
|
return false;
|
|
76
108
|
}
|
|
109
|
+
// closest() matches the element itself as well as any ancestor.
|
|
110
|
+
if (el.closest('[aria-hidden="true"]')) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
77
113
|
// offsetParent is null for display:none (and fixed elements); pair with a
|
|
78
114
|
// visibility check via getComputedStyle when available.
|
|
79
115
|
if (typeof window !== 'undefined' && window.getComputedStyle) {
|
|
@@ -274,12 +310,17 @@ export function useFocusTrap(options) {
|
|
|
274
310
|
|
|
275
311
|
// Register this trap on the shared Escape stack so only the top-most
|
|
276
312
|
// active trap responds to Escape. A stable identity per active period is
|
|
277
|
-
// enough — we push on activate and remove on cleanup.
|
|
313
|
+
// enough — we push on activate and remove on cleanup. The container is
|
|
314
|
+
// read lazily: the ref may not be attached yet at effect time, and the
|
|
315
|
+
// stack resolves top-most by DOM containment at keydown time.
|
|
278
316
|
const escapeHandler = () => {
|
|
279
317
|
onEscape?.();
|
|
280
318
|
};
|
|
281
319
|
if (onEscape) {
|
|
282
|
-
pushEscapeHandler(
|
|
320
|
+
pushEscapeHandler({
|
|
321
|
+
handler: escapeHandler,
|
|
322
|
+
getContainer: () => containerRef.current
|
|
323
|
+
});
|
|
283
324
|
}
|
|
284
325
|
const handleKeyDown = event => {
|
|
285
326
|
const container = containerRef.current;
|
|
@@ -62,7 +62,12 @@ export interface UseGridFocusOptions {
|
|
|
62
62
|
/**
|
|
63
63
|
* Whether the grid is in a right-to-left context. When true, ArrowLeft and
|
|
64
64
|
* ArrowRight are swapped so horizontal navigation follows visual direction.
|
|
65
|
-
*
|
|
65
|
+
*
|
|
66
|
+
* When omitted, the direction is auto-detected from the container's computed
|
|
67
|
+
* `direction` (read lazily on keydown, only for horizontal arrow keys), so
|
|
68
|
+
* grids inside `dir="rtl"` subtrees flip automatically. Pass an explicit
|
|
69
|
+
* boolean to override detection.
|
|
70
|
+
* @default undefined (auto-detect from the container)
|
|
66
71
|
*/
|
|
67
72
|
isRtl?: boolean;
|
|
68
73
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGridFocus.d.ts","sourceRoot":"","sources":["../../src/hooks/useGridFocus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useGridFocus.d.ts","sourceRoot":"","sources":["../../src/hooks/useGridFocus.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC;IAEjD;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,WAAW,GAAG,IAAI,CAAC;IAE3D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAE5D;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAE3D;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IAExB;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;;;;;;;;;;;;;;OAkBG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IACrE;;OAEG;IACH,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEnC;;OAEG;IACH,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC;IAEhD;;;;OAIG;IACH,WAAW,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAE3C;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAC;IAEvB;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAC9D,OAAO,EAAE,mBAAmB,GAC3B,kBAAkB,CAAC,CAAC,CAAC,CAyYvB"}
|
|
@@ -4,15 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file useGridFocus.ts
|
|
7
|
-
* @input Uses React useCallback, useRef, useIsomorphicLayoutEffect
|
|
7
|
+
* @input Uses React useCallback, useRef, useIsomorphicLayoutEffect,
|
|
8
|
+
* isRtlElement
|
|
8
9
|
* @output Exports useGridFocus hook for grid keyboard navigation
|
|
9
|
-
* @position Core hook; used by Calendar for date grid navigation
|
|
10
|
+
* @position Core hook; used by Calendar for date grid navigation. Auto-detects
|
|
11
|
+
* RTL from the container's computed direction so horizontal arrow keys
|
|
12
|
+
* follow visual direction (WCAG 1.3.2).
|
|
10
13
|
*
|
|
11
14
|
* SYNC: When modified, update:
|
|
12
15
|
* - /packages/core/src/hooks/index.ts
|
|
13
16
|
* - /packages/core/src/hooks/useGridFocus.test.tsx
|
|
14
17
|
*/
|
|
15
18
|
import { useCallback, useRef } from 'react';
|
|
19
|
+
import { isRtlElement } from "./isRtlElement.js";
|
|
16
20
|
import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
|
|
17
21
|
|
|
18
22
|
/**
|
|
@@ -87,7 +91,7 @@ export function useGridFocus(options) {
|
|
|
87
91
|
onNavigateAfter,
|
|
88
92
|
onPageUp,
|
|
89
93
|
onPageDown,
|
|
90
|
-
isRtl
|
|
94
|
+
isRtl,
|
|
91
95
|
hasRovingTabIndex = false
|
|
92
96
|
} = options;
|
|
93
97
|
const gridRef = useRef(null);
|
|
@@ -297,13 +301,12 @@ export function useGridFocus(options) {
|
|
|
297
301
|
|
|
298
302
|
// In RTL, ArrowLeft/ArrowRight are swapped so horizontal navigation
|
|
299
303
|
// follows visual direction. Vertical keys (Up/Down) are unaffected.
|
|
304
|
+
// Direction is resolved lazily — getComputedStyle runs only when a
|
|
305
|
+
// horizontal arrow key is actually pressed (SSR-safe, no layout thrash
|
|
306
|
+
// on unrelated keys) — and an explicit `isRtl` always wins.
|
|
300
307
|
let key = e.key;
|
|
301
|
-
if (isRtl) {
|
|
302
|
-
|
|
303
|
-
key = 'ArrowRight';
|
|
304
|
-
} else if (key === 'ArrowRight') {
|
|
305
|
-
key = 'ArrowLeft';
|
|
306
|
-
}
|
|
308
|
+
if ((key === 'ArrowLeft' || key === 'ArrowRight') && (isRtl ?? isRtlElement(gridRef.current))) {
|
|
309
|
+
key = key === 'ArrowLeft' ? 'ArrowRight' : 'ArrowLeft';
|
|
307
310
|
}
|
|
308
311
|
switch (key) {
|
|
309
312
|
case 'ArrowRight':
|
|
@@ -36,6 +36,15 @@ export interface Hotkey {
|
|
|
36
36
|
* definitions live in a ref, so re-renders update behavior without
|
|
37
37
|
* re-subscribing. First matching hotkey wins per event.
|
|
38
38
|
*
|
|
39
|
+
* Accessibility (WCAG 2.1.4 — Character Key Shortcuts): a shortcut whose
|
|
40
|
+
* combo is a single unmodified character (letter, digit, punctuation or
|
|
41
|
+
* symbol — e.g. 'c' or '/') is easily triggered by accident by speech-input
|
|
42
|
+
* users and keyboard users with motor impairments. If you register one, you
|
|
43
|
+
* MUST also provide at least one of: (a) a way to turn the shortcut off,
|
|
44
|
+
* (b) a way to remap it to include a modifier, or (c) scope it so it is only
|
|
45
|
+
* active while the relevant component has focus. Prefer `mod`-based combos
|
|
46
|
+
* where possible; the `isDisabled` flag can back a user-facing off switch.
|
|
47
|
+
*
|
|
39
48
|
* @param hotkeys - Shortcut registrations to listen for.
|
|
40
49
|
*
|
|
41
50
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHotkeys.d.ts","sourceRoot":"","sources":["../../src/hooks/useHotkeys.ts"],"names":[],"mappings":"AA6BA;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB;;;;;;;;;;;;;;;OAeG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gEAAgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AA2FD
|
|
1
|
+
{"version":3,"file":"useHotkeys.d.ts","sourceRoot":"","sources":["../../src/hooks/useHotkeys.ts"],"names":[],"mappings":"AA6BA;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB;;;;;;;;;;;;;;;OAeG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gEAAgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AA2FD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAkClD"}
|
package/dist/hooks/useHotkeys.js
CHANGED
|
@@ -115,6 +115,15 @@ function matchesCombo(keys, event, isApple) {
|
|
|
115
115
|
* definitions live in a ref, so re-renders update behavior without
|
|
116
116
|
* re-subscribing. First matching hotkey wins per event.
|
|
117
117
|
*
|
|
118
|
+
* Accessibility (WCAG 2.1.4 — Character Key Shortcuts): a shortcut whose
|
|
119
|
+
* combo is a single unmodified character (letter, digit, punctuation or
|
|
120
|
+
* symbol — e.g. 'c' or '/') is easily triggered by accident by speech-input
|
|
121
|
+
* users and keyboard users with motor impairments. If you register one, you
|
|
122
|
+
* MUST also provide at least one of: (a) a way to turn the shortcut off,
|
|
123
|
+
* (b) a way to remap it to include a modifier, or (c) scope it so it is only
|
|
124
|
+
* active while the relevant component has focus. Prefer `mod`-based combos
|
|
125
|
+
* where possible; the `isDisabled` flag can back a user-facing off switch.
|
|
126
|
+
*
|
|
118
127
|
* @param hotkeys - Shortcut registrations to listen for.
|
|
119
128
|
*
|
|
120
129
|
* @example
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type IconSize } from '../Icon';
|
|
3
|
+
import type { FieldStatusVariant } from '../FieldStatus/FieldStatus';
|
|
4
|
+
import type { InputStatus } from '../Field/types';
|
|
5
|
+
export interface UseInputStatusIconOptions {
|
|
6
|
+
/** The input's status, or undefined when there is none. */
|
|
7
|
+
status?: InputStatus;
|
|
8
|
+
/** How the status is presented relative to the input. */
|
|
9
|
+
statusVariant?: FieldStatusVariant;
|
|
10
|
+
/** Whether the input is inside an InputGroup (which owns status rendering). */
|
|
11
|
+
isInGroup?: boolean;
|
|
12
|
+
/** Size of the on-field icon. @default 'md' */
|
|
13
|
+
size?: IconSize;
|
|
14
|
+
}
|
|
15
|
+
export interface UseInputStatusIconReturn {
|
|
16
|
+
/**
|
|
17
|
+
* The on-field status affordance to render inside the input container —
|
|
18
|
+
* the status icon (plain, for attached) or a focusable info-tip button plus
|
|
19
|
+
* its tooltip layer (for the `tooltip` variant). `null` when no icon should
|
|
20
|
+
* render (no status, `detached` variant, or inside a group).
|
|
21
|
+
*/
|
|
22
|
+
statusIcon: ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* ID to add to the input's `aria-describedby` when — and only when — the
|
|
25
|
+
* status is surfaced through a rendered tooltip layer (the `tooltip` variant
|
|
26
|
+
* with a message). It is `undefined` in every other case (no status, no
|
|
27
|
+
* message, `attached`/`detached`, or inside a group), so call-sites can drop
|
|
28
|
+
* it straight into their described-by list without a dangling reference: the
|
|
29
|
+
* id is present exactly when its tooltip element is in the DOM.
|
|
30
|
+
*/
|
|
31
|
+
describedBy: string | undefined;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Builds the on-field status icon and its accessibility wiring for a bordered
|
|
35
|
+
* input. See the file header for the per-variant behavior.
|
|
36
|
+
*/
|
|
37
|
+
export declare function useInputStatusIcon({ status, statusVariant, isInGroup, size, }: UseInputStatusIconOptions): UseInputStatusIconReturn;
|
|
38
|
+
//# sourceMappingURL=useInputStatusIcon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInputStatusIcon.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputStatusIcon.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,EAAsB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAC,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAsDjE,MAAM,WAAW,yBAAyB;IACxC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,yDAAyD;IACzD,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;;;;OAOG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,aAA0B,EAC1B,SAAiB,EACjB,IAAW,GACZ,EAAE,yBAAyB,GAAG,wBAAwB,CA2FtD"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file useInputStatusIcon.tsx
|
|
7
|
+
* @input Input status, statusVariant, and InputGroup awareness
|
|
8
|
+
* @output The on-field status icon element (with tooltip) and aria-describedby wiring
|
|
9
|
+
* @position Shared hook for bordered inputs that render a status affordance inside the control
|
|
10
|
+
*
|
|
11
|
+
* SYNC: When modified, update:
|
|
12
|
+
* - /packages/core/src/hooks/index.ts (exports)
|
|
13
|
+
*
|
|
14
|
+
* Centralizes the on-field status icon across the bordered inputs (TextInput,
|
|
15
|
+
* TextArea, NumberInput, DateInput, DateTimeInput, DateRangeInput, TimeInput,
|
|
16
|
+
* FileInput) so the three statusVariants behave consistently:
|
|
17
|
+
*
|
|
18
|
+
* - `attached` → icon sits inside the control; the message box below carries
|
|
19
|
+
* the text.
|
|
20
|
+
* - `detached` → the detached message box renders its OWN leading icon, so the
|
|
21
|
+
* on-field icon is suppressed here to avoid a duplicate glyph.
|
|
22
|
+
* - `tooltip` → no message box renders; the status is surfaced through an
|
|
23
|
+
* info-tip on the on-field icon. The icon is a real focusable `<button>` so
|
|
24
|
+
* the status is reachable by every user, not just those with hover or a
|
|
25
|
+
* screen reader:
|
|
26
|
+
* - Keyboard (no AT): the button is in the tab order (WCAG 2.1.1) with a
|
|
27
|
+
* visible focus ring (WCAG 2.4.7); focusing it opens the tooltip.
|
|
28
|
+
* - Pointer: hover opens it (guarded to fine pointers).
|
|
29
|
+
* - Touch: hover is unavailable, so a tap toggles the tooltip open/closed.
|
|
30
|
+
* - Assistive tech: the button has an accessible name (its status type,
|
|
31
|
+
* WCAG 4.1.2) and is described by the message via `aria-describedby`.
|
|
32
|
+
* - Dismissible with Escape and hoverable (WCAG 1.4.13) via useTooltip.
|
|
33
|
+
*/
|
|
34
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
35
|
+
import * as stylex from '@stylexjs/stylex';
|
|
36
|
+
import { Icon } from "../Icon/index.js";
|
|
37
|
+
import { useTooltip } from "../Tooltip/index.js";
|
|
38
|
+
import { useTranslator } from "../i18n/index.js";
|
|
39
|
+
import "../theme/tokens.stylex.js";
|
|
40
|
+
import { colorVars, radiusVars } from "../theme/tokens.stylex.js";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Maps each status type to its glyph. Shared so every input shows the same icon
|
|
44
|
+
* for a given status, matching the detached message box's leading icon.
|
|
45
|
+
*/
|
|
46
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
47
|
+
const STATUS_ICON = {
|
|
48
|
+
warning: 'warning',
|
|
49
|
+
error: 'error',
|
|
50
|
+
success: 'success'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Accessible-name i18n keys for the focusable status button, keyed by type.
|
|
55
|
+
*/
|
|
56
|
+
const STATUS_BUTTON_LABEL_KEY = {
|
|
57
|
+
warning: '@astryx.input.statusButton.warning',
|
|
58
|
+
error: '@astryx.input.statusButton.error',
|
|
59
|
+
success: '@astryx.input.statusButton.success'
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Builds the on-field status icon and its accessibility wiring for a bordered
|
|
63
|
+
* input. See the file header for the per-variant behavior.
|
|
64
|
+
*/
|
|
65
|
+
export function useInputStatusIcon({
|
|
66
|
+
status,
|
|
67
|
+
statusVariant = 'attached',
|
|
68
|
+
isInGroup = false,
|
|
69
|
+
size = 'md'
|
|
70
|
+
}) {
|
|
71
|
+
const t = useTranslator();
|
|
72
|
+
const isTooltipVariant = statusVariant === 'tooltip';
|
|
73
|
+
const hasTooltip = isTooltipVariant && !!status?.message;
|
|
74
|
+
|
|
75
|
+
// Touch tap-to-toggle. Hover is unavailable on touch, and useTooltip
|
|
76
|
+
// suppresses simulated hover there, so on touch a tap controls visibility.
|
|
77
|
+
// `undefined` leaves the tooltip uncontrolled (pointer + keyboard drive it);
|
|
78
|
+
// a boolean takes control for the current open/close cycle.
|
|
79
|
+
const [tapOpen, setTapOpen] = useState(undefined);
|
|
80
|
+
const tooltip = useTooltip({
|
|
81
|
+
placement: 'above',
|
|
82
|
+
isEnabled: hasTooltip,
|
|
83
|
+
isOpen: tapOpen
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Re-hand control back to hover/focus once a tap-opened tooltip is dismissed
|
|
87
|
+
// (Escape/outside interaction), so subsequent pointer/keyboard use behaves
|
|
88
|
+
// normally.
|
|
89
|
+
const handleButtonBlur = useCallback(() => {
|
|
90
|
+
setTapOpen(undefined);
|
|
91
|
+
}, []);
|
|
92
|
+
const handleButtonClick = useCallback(() => {
|
|
93
|
+
// Only take control on touch/hover-less devices. On hover-capable devices
|
|
94
|
+
// pointer hover and keyboard focus already drive the tooltip (uncontrolled),
|
|
95
|
+
// so a click-toggle would fight them; leave it uncontrolled there.
|
|
96
|
+
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function' || !window.matchMedia('(hover: none)').matches) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
setTapOpen(prev => prev === true ? false : true);
|
|
100
|
+
}, []);
|
|
101
|
+
|
|
102
|
+
// Dismiss a tap-opened tooltip on Escape and return to the uncontrolled
|
|
103
|
+
// state (useTooltip owns Escape for the uncontrolled case, but while we hold
|
|
104
|
+
// control via isOpen it does not, so mirror it here).
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (tapOpen !== true) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const onKeyDown = e => {
|
|
110
|
+
if (e.key === 'Escape') {
|
|
111
|
+
setTapOpen(undefined);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
document.addEventListener('keydown', onKeyDown);
|
|
115
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
116
|
+
}, [tapOpen]);
|
|
117
|
+
|
|
118
|
+
// Inside a group the group owns status rendering; the detached message box
|
|
119
|
+
// renders its own leading icon, so the on-field icon would duplicate it.
|
|
120
|
+
const shouldRenderIcon = !!status && !isInGroup && statusVariant !== 'detached';
|
|
121
|
+
if (!shouldRenderIcon) {
|
|
122
|
+
return {
|
|
123
|
+
statusIcon: null,
|
|
124
|
+
describedBy: undefined
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const icon = /*#__PURE__*/_jsx(Icon, {
|
|
128
|
+
icon: STATUS_ICON[status.type],
|
|
129
|
+
size: size,
|
|
130
|
+
color: status.type
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Attached (and tooltip-without-message) variants: plain, non-interactive
|
|
134
|
+
// icon. The message box (attached) already carries the text.
|
|
135
|
+
if (!hasTooltip) {
|
|
136
|
+
return {
|
|
137
|
+
statusIcon: icon,
|
|
138
|
+
describedBy: undefined
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
statusIcon: /*#__PURE__*/_jsxs(_Fragment, {
|
|
143
|
+
children: [/*#__PURE__*/_jsx("button", {
|
|
144
|
+
type: "button",
|
|
145
|
+
ref: tooltip.ref,
|
|
146
|
+
"aria-label": t(STATUS_BUTTON_LABEL_KEY[status.type]),
|
|
147
|
+
"aria-describedby": tooltip.describedBy,
|
|
148
|
+
onClick: handleButtonClick,
|
|
149
|
+
onBlur: handleButtonBlur,
|
|
150
|
+
...{
|
|
151
|
+
className: "x3nfvp2 x6s0dn4 xl56j7k x1717udv x1ghz6dp x1heor9g x1ypdohk xjspbzw x784prv x9v5kkp xzunyri x7s97pk"
|
|
152
|
+
},
|
|
153
|
+
children: icon
|
|
154
|
+
}), tooltip.renderTooltip(status.message)]
|
|
155
|
+
}),
|
|
156
|
+
describedBy: tooltip.describedBy
|
|
157
|
+
};
|
|
158
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file useKeyboardHint.tsx
|
|
3
|
-
* @input Uses React, StyleX, Kbd, useLayer
|
|
3
|
+
* @input Uses React, StyleX, Kbd, useLayer, i18n (useTranslator)
|
|
4
4
|
* @output Exports useKeyboardHint hook — ephemeral arrow-key navigation hint
|
|
5
5
|
* @position Core hook; shows sighted keyboard users how to navigate composite
|
|
6
6
|
* widgets that use roving tabindex (single Tab stop, arrows inside)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useKeyboardHint.d.ts","sourceRoot":"","sources":["../../src/hooks/useKeyboardHint.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useKeyboardHint.d.ts","sourceRoot":"","sources":["../../src/hooks/useKeyboardHint.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAiB5E,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;AAEzE,MAAM,WAAW,sBAAsB;IACrC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAC;IAEtC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,WAAW,EAAE,SAAS,CAAC;IAEvB;;;OAGG;IACH,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAEvC;;;OAGG;IACH,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAEtC;;;OAGG;IACH,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC;CAC7C;AAkED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAgKvB"}
|