@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
|
@@ -13,6 +13,10 @@ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
|
13
13
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
15
|
import {Switch} from './Switch';
|
|
16
|
+
import {
|
|
17
|
+
getAllInjectedCss,
|
|
18
|
+
getForcedColorsRules,
|
|
19
|
+
} from '../__tests__/forcedColors';
|
|
16
20
|
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
17
21
|
|
|
18
22
|
afterEach(() => {
|
|
@@ -68,6 +72,28 @@ describe('Switch', () => {
|
|
|
68
72
|
expect(screen.getByRole('switch')).toBeChecked();
|
|
69
73
|
});
|
|
70
74
|
|
|
75
|
+
it('renders with custom size prop (sm / md)', () => {
|
|
76
|
+
const {rerender} = render(
|
|
77
|
+
<Switch
|
|
78
|
+
label="Small switch"
|
|
79
|
+
value={false}
|
|
80
|
+
size="sm"
|
|
81
|
+
onChange={() => {}}
|
|
82
|
+
/>,
|
|
83
|
+
);
|
|
84
|
+
expect(screen.getByRole('switch')).toBeInTheDocument();
|
|
85
|
+
|
|
86
|
+
rerender(
|
|
87
|
+
<Switch
|
|
88
|
+
label="Medium switch"
|
|
89
|
+
value={false}
|
|
90
|
+
size="md"
|
|
91
|
+
onChange={() => {}}
|
|
92
|
+
/>,
|
|
93
|
+
);
|
|
94
|
+
expect(screen.getByRole('switch')).toBeInTheDocument();
|
|
95
|
+
});
|
|
96
|
+
|
|
71
97
|
it('calls onChange with new checked state when clicked', async () => {
|
|
72
98
|
const user = userEvent.setup();
|
|
73
99
|
const handleChange = vi.fn();
|
|
@@ -636,6 +662,58 @@ describe('Switch', () => {
|
|
|
636
662
|
});
|
|
637
663
|
});
|
|
638
664
|
|
|
665
|
+
describe('RTL thumb travel direction', () => {
|
|
666
|
+
// StyleX injects atomic rules into the document; scan them so we can assert
|
|
667
|
+
// the direction-aware transform without relying on jsdom to resolve the
|
|
668
|
+
// `:is([dir="rtl"] *)` descendant selector against computed style.
|
|
669
|
+
function injectedCss(): string {
|
|
670
|
+
let out = '';
|
|
671
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
672
|
+
try {
|
|
673
|
+
for (const rule of Array.from(sheet.cssRules)) {
|
|
674
|
+
out += rule.cssText + '\n';
|
|
675
|
+
}
|
|
676
|
+
} catch {
|
|
677
|
+
// ignore cross-origin sheets
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
out += Array.from(document.querySelectorAll('style'))
|
|
681
|
+
.map(s => s.textContent || '')
|
|
682
|
+
.join('\n');
|
|
683
|
+
return out;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
it('applies a distinct thumb style when on vs off (on-travel is wired)', () => {
|
|
687
|
+
const on = render(<Switch label="On" value={true} onChange={() => {}} />);
|
|
688
|
+
const off = render(
|
|
689
|
+
<Switch label="Off" value={false} onChange={() => {}} />,
|
|
690
|
+
);
|
|
691
|
+
const onThumb = on.container.querySelector(
|
|
692
|
+
'[class*="thumbOnSizeStyles"]',
|
|
693
|
+
);
|
|
694
|
+
const offThumb = off.container.querySelector(
|
|
695
|
+
'[class*="thumbOffSizeStyles"]',
|
|
696
|
+
);
|
|
697
|
+
expect(onThumb).not.toBeNull();
|
|
698
|
+
expect(offThumb).not.toBeNull();
|
|
699
|
+
expect(onThumb!.getAttribute('class')).not.toBe(
|
|
700
|
+
offThumb!.getAttribute('class'),
|
|
701
|
+
);
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
it('mirrors the on-state thumb travel under RTL (negative translateX)', () => {
|
|
705
|
+
render(<Switch label="Toggle" value={true} onChange={() => {}} />);
|
|
706
|
+
const css = injectedCss();
|
|
707
|
+
// LTR on-travel moves the thumb toward the physical right (positive px).
|
|
708
|
+
expect(css).toMatch(/transform:\s*translateX\(1[24]px\)/);
|
|
709
|
+
// RTL mirrors it: the on-thumb lands on the inline-end (physical left)
|
|
710
|
+
// side, so the travel flips sign, scoped to `[dir="rtl"]`.
|
|
711
|
+
expect(css).toMatch(
|
|
712
|
+
/:is\(\[dir="rtl"\][^)]*\)[^{]*\{\s*transform:\s*translateX\(-1[24]px\)/,
|
|
713
|
+
);
|
|
714
|
+
});
|
|
715
|
+
});
|
|
716
|
+
|
|
639
717
|
describe('rest forwarding', () => {
|
|
640
718
|
it('forwards data-testid, id, and aria-* to the root element', () => {
|
|
641
719
|
const {container} = render(
|
|
@@ -655,3 +733,36 @@ describe('Switch', () => {
|
|
|
655
733
|
});
|
|
656
734
|
});
|
|
657
735
|
});
|
|
736
|
+
|
|
737
|
+
// jsdom cannot emulate forced-colors rendering, so these assert that the
|
|
738
|
+
// compiled output includes the forced-colors rules; visual behavior needs
|
|
739
|
+
// manual verification under Windows High Contrast.
|
|
740
|
+
describe('forced colors (WCAG 1.4.11)', () => {
|
|
741
|
+
it('compiles forced-colors overrides so on/off state survives Windows High Contrast', () => {
|
|
742
|
+
render(<Switch label="Notifications" value={true} onChange={() => {}} />);
|
|
743
|
+
const css = getForcedColorsRules();
|
|
744
|
+
// Track outline (backgrounds are stripped; the border keeps the bounds).
|
|
745
|
+
expect(css).toContain('border-color: canvastext;');
|
|
746
|
+
// Off track stays empty; on track uses the selection color.
|
|
747
|
+
expect(css).toContain('background-color: canvas;');
|
|
748
|
+
expect(css).toContain('background-color: highlight;');
|
|
749
|
+
// Thumb fill per state.
|
|
750
|
+
expect(css).toContain('background-color: canvastext;');
|
|
751
|
+
expect(css).toContain('background-color: highlighttext;');
|
|
752
|
+
// Disabled affordance (opacity dimming does not survive forcing).
|
|
753
|
+
expect(css).toContain('border-color: graytext;');
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
it('gates the hover tint out of forced colors so the thumb stays visible on hover', () => {
|
|
757
|
+
render(<Switch label="Notifications" value={true} onChange={() => {}} />);
|
|
758
|
+
// The ancestor-hover tint is a non-system color-mix whose rule outranks the
|
|
759
|
+
// plain forced-colors track rule. It is gated behind `forced-colors: none`
|
|
760
|
+
// so it cannot reassert on hover and flatten the Highlight track to white
|
|
761
|
+
// under the HighlightText thumb (white-on-white).
|
|
762
|
+
expect(getAllInjectedCss()).toContain(
|
|
763
|
+
'(hover: hover) and (forced-colors: none)',
|
|
764
|
+
);
|
|
765
|
+
// And the tint never leaks into the forced-colors output.
|
|
766
|
+
expect(getForcedColorsRules()).not.toContain('color-mix');
|
|
767
|
+
});
|
|
768
|
+
});
|
package/src/Switch/Switch.tsx
CHANGED
|
@@ -47,17 +47,86 @@ import type {SizeValue} from '../utils/types';
|
|
|
47
47
|
import {themeProps} from '../utils/themeProps';
|
|
48
48
|
import {VisuallyHidden} from '../VisuallyHidden';
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
const wrapperSizeStyles = stylex.create({
|
|
51
|
+
sm: {
|
|
52
|
+
width: 32,
|
|
53
|
+
height: 20,
|
|
54
|
+
},
|
|
55
|
+
md: {
|
|
56
|
+
width: 40,
|
|
57
|
+
height: 24,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const inputSizeStyles = stylex.create({
|
|
62
|
+
sm: {
|
|
63
|
+
width: 32,
|
|
64
|
+
height: 20,
|
|
65
|
+
},
|
|
66
|
+
md: {
|
|
67
|
+
width: 40,
|
|
68
|
+
height: 24,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const trackSizeStyles = stylex.create({
|
|
73
|
+
sm: {
|
|
74
|
+
width: 32,
|
|
75
|
+
height: 20,
|
|
76
|
+
padding: 2,
|
|
77
|
+
},
|
|
78
|
+
md: {
|
|
79
|
+
width: 40,
|
|
80
|
+
height: 24,
|
|
81
|
+
padding: 4,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const thumbOffSizeStyles = stylex.create({
|
|
86
|
+
sm: {
|
|
87
|
+
width: 14,
|
|
88
|
+
height: 14,
|
|
89
|
+
transform: 'translateX(0)',
|
|
90
|
+
},
|
|
91
|
+
md: {
|
|
92
|
+
width: 16,
|
|
93
|
+
height: 16,
|
|
94
|
+
transform: 'translateX(0)',
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const thumbOnSizeStyles = stylex.create({
|
|
99
|
+
sm: {
|
|
100
|
+
width: 16,
|
|
101
|
+
height: 16,
|
|
102
|
+
// The thumb rests at the inline-start edge (flex-start, which flexbox
|
|
103
|
+
// already mirrors under RTL). The on-state travel toward the inline-end
|
|
104
|
+
// edge is a physical translateX, so it must flip sign under RTL — right
|
|
105
|
+
// in LTR, left in RTL — so the switch mirrors per convention (Material,
|
|
106
|
+
// iOS): off-thumb on the reading-start side, on-thumb on the reading-end.
|
|
107
|
+
transform: {
|
|
108
|
+
default: 'translateX(12px)',
|
|
109
|
+
':is([dir="rtl"] *)': 'translateX(-12px)',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
md: {
|
|
113
|
+
width: 20,
|
|
114
|
+
height: 20,
|
|
115
|
+
transform: {
|
|
116
|
+
default: 'translateX(14px)',
|
|
117
|
+
':is([dir="rtl"] *)': 'translateX(-14px)',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const labelWrapperSizeStyles = stylex.create({
|
|
123
|
+
sm: {
|
|
124
|
+
minHeight: 20,
|
|
125
|
+
},
|
|
126
|
+
md: {
|
|
127
|
+
minHeight: 24,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
61
130
|
|
|
62
131
|
const styles = stylex.create({
|
|
63
132
|
container: {
|
|
@@ -77,8 +146,6 @@ const styles = stylex.create({
|
|
|
77
146
|
display: 'flex',
|
|
78
147
|
alignItems: 'center',
|
|
79
148
|
flexShrink: 0,
|
|
80
|
-
width: SWITCH_WIDTH,
|
|
81
|
-
height: SWITCH_HEIGHT,
|
|
82
149
|
isolation: 'isolate',
|
|
83
150
|
},
|
|
84
151
|
input: {
|
|
@@ -88,8 +155,6 @@ const styles = stylex.create({
|
|
|
88
155
|
opacity: 0,
|
|
89
156
|
cursor: 'pointer',
|
|
90
157
|
zIndex: 1,
|
|
91
|
-
width: SWITCH_WIDTH,
|
|
92
|
-
height: SWITCH_HEIGHT,
|
|
93
158
|
},
|
|
94
159
|
inputDisabled: {
|
|
95
160
|
cursor: 'not-allowed',
|
|
@@ -100,9 +165,6 @@ const styles = stylex.create({
|
|
|
100
165
|
track: {
|
|
101
166
|
display: 'flex',
|
|
102
167
|
alignItems: 'center',
|
|
103
|
-
width: SWITCH_WIDTH,
|
|
104
|
-
height: SWITCH_HEIGHT,
|
|
105
|
-
padding: TRACK_PADDING,
|
|
106
168
|
borderRadius: radiusVars['--radius-full'],
|
|
107
169
|
transitionProperty: 'background-color',
|
|
108
170
|
transitionDuration: {
|
|
@@ -111,6 +173,21 @@ const styles = stylex.create({
|
|
|
111
173
|
},
|
|
112
174
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
113
175
|
boxSizing: 'border-box',
|
|
176
|
+
// Forced colors (Windows High Contrast) strips painted backgrounds, which
|
|
177
|
+
// would leave the track invisible. A system-color border keeps the
|
|
178
|
+
// control's bounds perceivable (WCAG 1.4.11).
|
|
179
|
+
borderWidth: {
|
|
180
|
+
default: 0,
|
|
181
|
+
'@media (forced-colors: active)': '1px',
|
|
182
|
+
},
|
|
183
|
+
borderStyle: {
|
|
184
|
+
default: 'none',
|
|
185
|
+
'@media (forced-colors: active)': 'solid',
|
|
186
|
+
},
|
|
187
|
+
borderColor: {
|
|
188
|
+
default: null,
|
|
189
|
+
'@media (forced-colors: active)': 'CanvasText',
|
|
190
|
+
},
|
|
114
191
|
},
|
|
115
192
|
trackFocus: {
|
|
116
193
|
outline: {
|
|
@@ -127,21 +204,39 @@ const styles = stylex.create({
|
|
|
127
204
|
trackOff: {
|
|
128
205
|
backgroundColor: {
|
|
129
206
|
default: colorVars['--color-background-gray'],
|
|
207
|
+
// Off = empty (Canvas) track; on = Highlight track, so the two states
|
|
208
|
+
// stay distinguishable under forced colors.
|
|
209
|
+
'@media (forced-colors: active)': 'Canvas',
|
|
210
|
+
// The ancestor-hover tint is a non-system color-mix, and its rule
|
|
211
|
+
// outranks the plain forced-colors rule above. Left ungated it would
|
|
212
|
+
// reassert on hover under forced colors, where the UA flattens the
|
|
213
|
+
// color-mix back to Canvas — so the HighlightText thumb would sit on a
|
|
214
|
+
// white track (white-on-white). Gating on `forced-colors: none` keeps
|
|
215
|
+
// the tint out of forced colors and lets the system-color track stand.
|
|
130
216
|
[stylex.when.ancestor(':hover', switchScope)]: {
|
|
131
|
-
'@media (hover: hover)': `color-mix(in srgb, ${colorVars['--color-background-gray']}, ${colorVars['--color-tint-hover']} 5%)`,
|
|
217
|
+
'@media (hover: hover) and (forced-colors: none)': `color-mix(in srgb, ${colorVars['--color-background-gray']}, ${colorVars['--color-tint-hover']} 5%)`,
|
|
132
218
|
},
|
|
133
219
|
},
|
|
134
220
|
},
|
|
135
221
|
trackOn: {
|
|
136
222
|
backgroundColor: {
|
|
137
223
|
default: colorVars['--color-accent'],
|
|
224
|
+
'@media (forced-colors: active)': 'Highlight',
|
|
225
|
+
// See trackOff: gate the hover tint out of forced colors so it cannot
|
|
226
|
+
// flatten the Highlight track to white under the HighlightText thumb.
|
|
138
227
|
[stylex.when.ancestor(':hover', switchScope)]: {
|
|
139
|
-
'@media (hover: hover)': `color-mix(in srgb, ${colorVars['--color-accent']}, ${colorVars['--color-tint-hover']} 15%)`,
|
|
228
|
+
'@media (hover: hover) and (forced-colors: none)': `color-mix(in srgb, ${colorVars['--color-accent']}, ${colorVars['--color-tint-hover']} 15%)`,
|
|
140
229
|
},
|
|
141
230
|
},
|
|
142
231
|
},
|
|
143
232
|
trackDisabled: {
|
|
144
233
|
opacity: 0.5,
|
|
234
|
+
// Opacity dimming does not survive forced colors; GrayText is the
|
|
235
|
+
// platform's disabled affordance there.
|
|
236
|
+
borderColor: {
|
|
237
|
+
default: null,
|
|
238
|
+
'@media (forced-colors: active)': 'GrayText',
|
|
239
|
+
},
|
|
145
240
|
},
|
|
146
241
|
trackDisabledOff: {
|
|
147
242
|
backgroundColor: colorVars['--color-background-gray'],
|
|
@@ -151,7 +246,6 @@ const styles = stylex.create({
|
|
|
151
246
|
alignItems: 'center',
|
|
152
247
|
justifyContent: 'center',
|
|
153
248
|
borderRadius: radiusVars['--radius-full'],
|
|
154
|
-
backgroundColor: colorVars['--color-background-surface'],
|
|
155
249
|
transitionProperty: 'transform, width, height',
|
|
156
250
|
transitionDuration: {
|
|
157
251
|
default: durationVars['--duration-fast'],
|
|
@@ -159,22 +253,27 @@ const styles = stylex.create({
|
|
|
159
253
|
},
|
|
160
254
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
161
255
|
},
|
|
256
|
+
// The thumb fill lives on the on/off styles (not the shared thumb style)
|
|
257
|
+
// because forced colors needs a per-state system color: CanvasText on the
|
|
258
|
+
// empty off track, HighlightText on the Highlight on track. Sizing stays in
|
|
259
|
+
// thumbOffSizeStyles/thumbOnSizeStyles; only the fill is state-dependent.
|
|
162
260
|
thumbOff: {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
261
|
+
backgroundColor: {
|
|
262
|
+
default: colorVars['--color-background-surface'],
|
|
263
|
+
'@media (forced-colors: active)': 'CanvasText',
|
|
264
|
+
},
|
|
166
265
|
},
|
|
167
266
|
thumbOn: {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
267
|
+
backgroundColor: {
|
|
268
|
+
default: colorVars['--color-background-surface'],
|
|
269
|
+
'@media (forced-colors: active)': 'HighlightText',
|
|
270
|
+
},
|
|
171
271
|
},
|
|
172
272
|
labelWrapper: {
|
|
173
273
|
display: 'flex',
|
|
174
274
|
flexDirection: 'column',
|
|
175
275
|
gap: spacingVars['--spacing-0-5'],
|
|
176
276
|
justifyContent: 'center',
|
|
177
|
-
minHeight: SWITCH_HEIGHT,
|
|
178
277
|
},
|
|
179
278
|
description: {
|
|
180
279
|
fontFamily: typographyVars['--font-family-body'],
|
|
@@ -313,6 +412,13 @@ export interface SwitchProps extends Omit<BaseProps, 'onChange'> {
|
|
|
313
412
|
* When set with a message, displays a colored message box below the switch.
|
|
314
413
|
*/
|
|
315
414
|
status?: InputStatus;
|
|
415
|
+
/**
|
|
416
|
+
* Size variant controlling track and thumb dimensions.
|
|
417
|
+
* - 'sm': 34x20px (matches sm checkbox/radio vertical rhythm)
|
|
418
|
+
* - 'md': 40x24px (default, matches md checkbox/radio vertical rhythm)
|
|
419
|
+
* @default 'md'
|
|
420
|
+
*/
|
|
421
|
+
size?: 'sm' | 'md';
|
|
316
422
|
}
|
|
317
423
|
|
|
318
424
|
// Dynamic field width (number -> px, string used as-is).
|
|
@@ -358,6 +464,7 @@ export function Switch({
|
|
|
358
464
|
labelPosition = 'end',
|
|
359
465
|
labelSpacing = 'hug',
|
|
360
466
|
status,
|
|
467
|
+
size = 'md',
|
|
361
468
|
width,
|
|
362
469
|
xstyle,
|
|
363
470
|
className,
|
|
@@ -410,7 +517,7 @@ export function Switch({
|
|
|
410
517
|
describedByParts.length > 0 ? describedByParts.join(' ') : undefined;
|
|
411
518
|
|
|
412
519
|
const switchElement = (
|
|
413
|
-
<div {...stylex.props(styles.switchWrapper)}>
|
|
520
|
+
<div {...stylex.props(styles.switchWrapper, wrapperSizeStyles[size])}>
|
|
414
521
|
<input
|
|
415
522
|
ref={mergeRefs(ref, disabledMessageTooltip.positionRef)}
|
|
416
523
|
id={id}
|
|
@@ -447,6 +554,7 @@ export function Switch({
|
|
|
447
554
|
aria-busy={isBusy || undefined}
|
|
448
555
|
{...stylex.props(
|
|
449
556
|
styles.input,
|
|
557
|
+
inputSizeStyles[size],
|
|
450
558
|
isDisabled && styles.inputDisabled,
|
|
451
559
|
isBusy && styles.inputBusy,
|
|
452
560
|
)}
|
|
@@ -457,9 +565,11 @@ export function Switch({
|
|
|
457
565
|
themeProps('switch', {
|
|
458
566
|
checked: isOn ? 'checked' : null,
|
|
459
567
|
disabled: isDisabled ? 'disabled' : null,
|
|
568
|
+
size,
|
|
460
569
|
}),
|
|
461
570
|
stylex.props(
|
|
462
571
|
styles.track,
|
|
572
|
+
trackSizeStyles[size],
|
|
463
573
|
isOn ? styles.trackOn : styles.trackOff,
|
|
464
574
|
!isDisabled && styles.trackFocus,
|
|
465
575
|
isDisabled && styles.trackDisabled,
|
|
@@ -468,8 +578,15 @@ export function Switch({
|
|
|
468
578
|
)}>
|
|
469
579
|
<div
|
|
470
580
|
{...mergeProps(
|
|
471
|
-
themeProps('switch-thumb', {
|
|
472
|
-
|
|
581
|
+
themeProps('switch-thumb', {
|
|
582
|
+
checked: isOn ? 'checked' : null,
|
|
583
|
+
size,
|
|
584
|
+
}),
|
|
585
|
+
stylex.props(
|
|
586
|
+
styles.thumb,
|
|
587
|
+
isOn ? thumbOnSizeStyles[size] : thumbOffSizeStyles[size],
|
|
588
|
+
isOn ? styles.thumbOn : styles.thumbOff,
|
|
589
|
+
),
|
|
473
590
|
)}>
|
|
474
591
|
{isBusy && <Spinner size="sm" />}
|
|
475
592
|
</div>
|
|
@@ -479,7 +596,7 @@ export function Switch({
|
|
|
479
596
|
);
|
|
480
597
|
|
|
481
598
|
const labelElement = (
|
|
482
|
-
<div {...stylex.props(styles.labelWrapper)}>
|
|
599
|
+
<div {...stylex.props(styles.labelWrapper, labelWrapperSizeStyles[size])}>
|
|
483
600
|
<FieldLabel
|
|
484
601
|
label={label}
|
|
485
602
|
inputID={id}
|
package/src/TabList/Tab.tsx
CHANGED
|
@@ -143,8 +143,8 @@ const styles = stylex.create({
|
|
|
143
143
|
// with a bottom divider — that ancestor sets `--_tab-indicator-bottom`
|
|
144
144
|
// to drop the indicator onto the rail beneath the reserved gap.
|
|
145
145
|
bottom: 'var(--_tab-indicator-bottom, -1px)',
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
insetInlineStart: spacingVars['--spacing-3'],
|
|
147
|
+
insetInlineEnd: spacingVars['--spacing-3'],
|
|
148
148
|
height: '2px',
|
|
149
149
|
borderRadius: radiusVars['--radius-full'],
|
|
150
150
|
pointerEvents: 'none',
|
|
@@ -55,12 +55,6 @@ export const docs = {
|
|
|
55
55
|
description: 'Whether to show a bottom border divider under the tab list.',
|
|
56
56
|
default: 'false',
|
|
57
57
|
},
|
|
58
|
-
{
|
|
59
|
-
name: 'orientation',
|
|
60
|
-
type: "'horizontal' | 'vertical'",
|
|
61
|
-
description: "Orientation of the tab strip, controlling which arrow keys move focus between tabs and the reported aria-orientation. 'horizontal': ArrowLeft/ArrowRight. 'vertical': ArrowUp/ArrowDown. Both axes' arrows are accepted regardless.",
|
|
62
|
-
default: "'horizontal'",
|
|
63
|
-
},
|
|
64
58
|
{
|
|
65
59
|
name: 'children',
|
|
66
60
|
type: 'ReactNode',
|
|
@@ -77,10 +77,9 @@ describe('TabList', () => {
|
|
|
77
77
|
|
|
78
78
|
it('does not set aria-orientation on the nav (invalid for role navigation)', () => {
|
|
79
79
|
// Regression: aria-orientation is not an allowed attribute on the
|
|
80
|
-
// navigation role and produces an axe aria-allowed-attr violation.
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
const {rerender} = render(
|
|
80
|
+
// navigation role and produces an axe aria-allowed-attr violation.
|
|
81
|
+
// TabList deliberately never sets this attribute.
|
|
82
|
+
render(
|
|
84
83
|
<TabList value="home" onChange={() => {}}>
|
|
85
84
|
<Tab value="home" label="Home" />
|
|
86
85
|
<Tab value="settings" label="Settings" />
|
|
@@ -90,17 +89,6 @@ describe('TabList', () => {
|
|
|
90
89
|
expect(screen.getByRole('navigation')).not.toHaveAttribute(
|
|
91
90
|
'aria-orientation',
|
|
92
91
|
);
|
|
93
|
-
|
|
94
|
-
rerender(
|
|
95
|
-
<TabList value="home" onChange={() => {}} orientation="vertical">
|
|
96
|
-
<Tab value="home" label="Home" />
|
|
97
|
-
<Tab value="settings" label="Settings" />
|
|
98
|
-
</TabList>,
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
expect(screen.getByRole('navigation')).not.toHaveAttribute(
|
|
102
|
-
'aria-orientation',
|
|
103
|
-
);
|
|
104
92
|
});
|
|
105
93
|
|
|
106
94
|
it('ignores a consumer-supplied aria-orientation on the nav', () => {
|
package/src/TabList/TabList.tsx
CHANGED
|
@@ -22,7 +22,7 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
22
22
|
import {borderVars, colorVars, spacingVars} from '../theme/tokens.stylex';
|
|
23
23
|
import type {BaseProps} from '../BaseProps';
|
|
24
24
|
import {TabListContext} from './TabListContext';
|
|
25
|
-
import type {
|
|
25
|
+
import type {TabListSize} from './TabListContext';
|
|
26
26
|
import {useSize} from '../SizeContext/SizeContext';
|
|
27
27
|
import {mergeProps, mergeRefs} from '../utils';
|
|
28
28
|
import {useListFocus} from '../hooks/useListFocus';
|
|
@@ -66,15 +66,6 @@ export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
|
|
|
66
66
|
* @default false
|
|
67
67
|
*/
|
|
68
68
|
hasDivider?: boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Orientation of the tab strip, controlling which arrow keys move
|
|
71
|
-
* focus between tabs.
|
|
72
|
-
* - `'horizontal'` (default): ArrowLeft / ArrowRight (ArrowUp / ArrowDown
|
|
73
|
-
* also work per the WAI-ARIA APG).
|
|
74
|
-
* - `'vertical'`: ArrowUp / ArrowDown (ArrowLeft / ArrowRight also work).
|
|
75
|
-
* @default 'horizontal'
|
|
76
|
-
*/
|
|
77
|
-
orientation?: TabListOrientation;
|
|
78
69
|
/**
|
|
79
70
|
* Tab and TabMenu children.
|
|
80
71
|
*/
|
|
@@ -130,7 +121,6 @@ export function TabList({
|
|
|
130
121
|
size: sizeProp,
|
|
131
122
|
layout = 'hug',
|
|
132
123
|
hasDivider = false,
|
|
133
|
-
orientation = 'horizontal',
|
|
134
124
|
xstyle,
|
|
135
125
|
className,
|
|
136
126
|
style,
|
|
@@ -150,14 +140,13 @@ export function TabList({
|
|
|
150
140
|
// Roving-tabindex keyboard navigation across the tab strip via the shared
|
|
151
141
|
// hook. `orientation: 'both'` accepts both arrow axes per the WAI-ARIA APG
|
|
152
142
|
// allowance for tab strips (ArrowRight/ArrowDown advance, ArrowLeft/ArrowUp
|
|
153
|
-
// retreat)
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
// navigation role and triggers an axe `aria-allowed-attr` violation.
|
|
143
|
+
// retreat). We do not set `aria-orientation` on the `<nav>`: that attribute
|
|
144
|
+
// is invalid on the navigation role and triggers an axe `aria-allowed-attr`
|
|
145
|
+
// violation.
|
|
157
146
|
//
|
|
158
147
|
// `hasRovingTabIndex` makes the hook own the single tab stop: it stamps
|
|
159
148
|
// tabindex 0/-1, repairs the stop on mount and as stops mount/unmount or
|
|
160
|
-
// toggle disabled, and
|
|
149
|
+
// toggle disabled, and -- via `handleFocus` on the nav -- keeps the stop in
|
|
161
150
|
// sync after clicks or programmatic focus. Individual Tabs still render
|
|
162
151
|
// `tabIndex={isSelected ? 0 : -1}` (see Tab.tsx) as the initial source of
|
|
163
152
|
// truth; the hook's repair preserves an existing tab stop and only promotes
|
|
@@ -173,7 +162,7 @@ export function TabList({
|
|
|
173
162
|
onKeyDown: onHintKeyDown,
|
|
174
163
|
onFocus: onHintFocus,
|
|
175
164
|
onBlur: onHintBlur,
|
|
176
|
-
} = useKeyboardHint(
|
|
165
|
+
} = useKeyboardHint();
|
|
177
166
|
|
|
178
167
|
const contextValue = useMemo(
|
|
179
168
|
() => ({value, onChange, size, layout}),
|
|
@@ -26,12 +26,6 @@ export type TabListSize = 'sm' | 'md' | 'lg';
|
|
|
26
26
|
*/
|
|
27
27
|
export type TabListLayout = 'hug' | 'fill';
|
|
28
28
|
|
|
29
|
-
/**
|
|
30
|
-
* Orientation of the tab strip. Controls which arrow keys move focus
|
|
31
|
-
* between tabs and the reported `aria-orientation`.
|
|
32
|
-
*/
|
|
33
|
-
export type TabListOrientation = 'horizontal' | 'vertical';
|
|
34
|
-
|
|
35
29
|
/**
|
|
36
30
|
* Context for communicating value/onChange/size/layout from TabList to children.
|
|
37
31
|
*/
|
package/src/TabList/TabMenu.tsx
CHANGED
|
@@ -126,8 +126,8 @@ const styles = stylex.create({
|
|
|
126
126
|
// drops onto the divider rail when an ancestor (TabList `hasDivider` or a
|
|
127
127
|
// Toolbar with a bottom divider) sets `--_tab-indicator-bottom`.
|
|
128
128
|
bottom: 'var(--_tab-indicator-bottom, -1px)',
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
insetInlineStart: spacingVars['--spacing-3'],
|
|
130
|
+
insetInlineEnd: spacingVars['--spacing-3'],
|
|
131
131
|
height: '2px',
|
|
132
132
|
borderRadius: radiusVars['--radius-full'],
|
|
133
133
|
pointerEvents: 'none',
|
package/src/Table/BaseTable.tsx
CHANGED
|
@@ -134,6 +134,12 @@ interface TableRowProps<T extends Record<string, unknown>> {
|
|
|
134
134
|
textOverflow: 'wrap' | 'truncate';
|
|
135
135
|
RowComponent: React.ComponentType<TableRowComponentProps>;
|
|
136
136
|
CellComponent: React.ComponentType<TableCellComponentProps>;
|
|
137
|
+
/**
|
|
138
|
+
* 1-based ARIA row index for this row's position in the full dataset.
|
|
139
|
+
* `undefined` when the table hasn't opted into ARIA row indexing, in which
|
|
140
|
+
* case no `aria-rowindex` is emitted (native table semantics).
|
|
141
|
+
*/
|
|
142
|
+
ariaRowIndex?: number;
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
/**
|
|
@@ -150,6 +156,7 @@ function TableRowInner<T extends Record<string, unknown>>({
|
|
|
150
156
|
textOverflow,
|
|
151
157
|
RowComponent,
|
|
152
158
|
CellComponent,
|
|
159
|
+
ariaRowIndex,
|
|
153
160
|
}: TableRowProps<T>): ReactElement {
|
|
154
161
|
// Build cells first
|
|
155
162
|
const cells = columns.map((col, columnIndex) => {
|
|
@@ -211,12 +218,14 @@ function TableRowInner<T extends Record<string, unknown>>({
|
|
|
211
218
|
);
|
|
212
219
|
});
|
|
213
220
|
|
|
214
|
-
// Apply plugin transforms for row (with pre-rendered children)
|
|
221
|
+
// Apply plugin transforms for row (with pre-rendered children).
|
|
222
|
+
// Seed `aria-rowindex` (when the table opts into ARIA row indexing) as a
|
|
223
|
+
// base htmlProp so plugins compose over it and can still override.
|
|
215
224
|
const rowRenderProps = applyPlugins(
|
|
216
225
|
plugins,
|
|
217
226
|
p => p.transformBodyRow,
|
|
218
227
|
{
|
|
219
|
-
htmlProps: {},
|
|
228
|
+
htmlProps: ariaRowIndex == null ? {} : {'aria-rowindex': ariaRowIndex},
|
|
220
229
|
xstyle: [],
|
|
221
230
|
children: <>{cells}</>,
|
|
222
231
|
} satisfies BodyRowRenderProps,
|
|
@@ -256,6 +265,9 @@ function areRowPropsEqual<T extends Record<string, unknown>>(
|
|
|
256
265
|
if (prevProps.rowIndex !== nextProps.rowIndex) {
|
|
257
266
|
return false;
|
|
258
267
|
}
|
|
268
|
+
if (prevProps.ariaRowIndex !== nextProps.ariaRowIndex) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
259
271
|
|
|
260
272
|
if (prevProps.columns !== nextProps.columns) {
|
|
261
273
|
return false;
|
|
@@ -323,6 +335,8 @@ function BaseTableInner<T extends Record<string, unknown>>({
|
|
|
323
335
|
textOverflow = 'wrap',
|
|
324
336
|
scrollWrapper: ScrollWrapper,
|
|
325
337
|
emptyState,
|
|
338
|
+
rowIndexStart,
|
|
339
|
+
rowCount,
|
|
326
340
|
xstyle,
|
|
327
341
|
className,
|
|
328
342
|
style,
|
|
@@ -333,6 +347,18 @@ function BaseTableInner<T extends Record<string, unknown>>({
|
|
|
333
347
|
// Use stable empty array when no plugins provided
|
|
334
348
|
const plugins = pluginsProp ?? (EMPTY_PLUGINS as TablePlugin<T>[]);
|
|
335
349
|
|
|
350
|
+
// ARIA row indexing. The row ordinal is an accessibility concern that is
|
|
351
|
+
// independent of any visible index column: when the consumer opts in (by
|
|
352
|
+
// passing rowIndexStart or rowCount), body rows carry `aria-rowindex`
|
|
353
|
+
// reflecting their position in the full dataset, and the <table> carries
|
|
354
|
+
// `aria-rowcount`. `aria-rowindex` is 1-based and counts data rows from
|
|
355
|
+
// `rowIndexStart` (default 1); a windowed/paginated view passes the offset
|
|
356
|
+
// of its first visible row. `aria-rowcount` is `rowCount` when known, or
|
|
357
|
+
// `-1` (ARIA's "unknown count") for a windowed view with an unknown total.
|
|
358
|
+
const ariaRowIndexingEnabled = rowIndexStart != null || rowCount != null;
|
|
359
|
+
const firstRowAriaIndex = rowIndexStart ?? 1;
|
|
360
|
+
const ariaRowCount = ariaRowIndexingEnabled ? (rowCount ?? -1) : undefined;
|
|
361
|
+
|
|
336
362
|
const RowComponent = TableRow as React.ComponentType<TableRowComponentProps>;
|
|
337
363
|
const CellComponent =
|
|
338
364
|
TableCell as React.ComponentType<TableCellComponentProps>;
|
|
@@ -486,6 +512,7 @@ function BaseTableInner<T extends Record<string, unknown>>({
|
|
|
486
512
|
let tableElement: ReactNode = (
|
|
487
513
|
<table
|
|
488
514
|
ref={ref}
|
|
515
|
+
{...(ariaRowCount != null ? {'aria-rowcount': ariaRowCount} : null)}
|
|
489
516
|
{...tableRenderProps.htmlProps}
|
|
490
517
|
{...mergeProps(
|
|
491
518
|
themeProps('base-table'),
|
|
@@ -530,6 +557,11 @@ function BaseTableInner<T extends Record<string, unknown>>({
|
|
|
530
557
|
textOverflow={textOverflow}
|
|
531
558
|
RowComponent={RowComponent}
|
|
532
559
|
CellComponent={CellComponent}
|
|
560
|
+
ariaRowIndex={
|
|
561
|
+
ariaRowIndexingEnabled
|
|
562
|
+
? firstRowAriaIndex + rowIndex
|
|
563
|
+
: undefined
|
|
564
|
+
}
|
|
533
565
|
/>
|
|
534
566
|
);
|
|
535
567
|
})
|