@astryxdesign/core 0.1.8 → 0.1.9-canary.08c278e
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 +100 -0
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +6 -2
- package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
- package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
- package/dist/Avatar/Avatar.d.ts +53 -3
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +203 -49
- package/dist/Avatar/AvatarStatusDot.d.ts +33 -5
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Avatar/AvatarStatusDot.js +144 -19
- 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.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -0
- package/dist/Banner/Banner.d.ts +9 -1
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +33 -4
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +208 -6
- package/dist/Breadcrumbs/index.d.ts +5 -0
- package/dist/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/Breadcrumbs/index.js +9 -1
- package/dist/Button/Button.d.ts +8 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +33 -4
- package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +30 -1
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +30 -2
- package/dist/Calendar/dayCellUtils.js +1 -1
- package/dist/Card/Card.d.ts +8 -2
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +28 -2
- package/dist/Carousel/Carousel.d.ts +4 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +24 -4
- package/dist/Chat/ChatComposer.d.ts +8 -0
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +46 -7
- package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +11 -1
- package/dist/Chat/ChatComposerInput.d.ts +20 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +36 -4
- package/dist/Chat/ChatContext.d.ts +33 -0
- package/dist/Chat/ChatContext.d.ts.map +1 -1
- package/dist/Chat/ChatContext.js +16 -2
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +1 -1
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +4 -4
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +4 -4
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.js +7 -1
- package/dist/Chat/ChatToolCalls.d.ts +5 -1
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +18 -9
- package/dist/Chat/index.d.ts +2 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/Chat/index.js +1 -1
- package/dist/Chat/useChatStreamScroll.d.ts +2 -1
- package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
- package/dist/Chat/useChatStreamScroll.js +22 -8
- package/dist/Chat/useSpeechRecognition.d.ts +0 -1
- package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.js +1 -1
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +2 -2
- package/dist/CheckboxInput/CheckboxInput.js +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts +20 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +11 -1
- package/dist/ClickableCard/ClickableCard.d.ts +9 -2
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +5 -2
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +9 -2
- package/dist/CommandPalette/CommandPalette.d.ts +1 -1
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +3 -1
- package/dist/CommandPalette/CommandPaletteGroup.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteGroup.js +9 -2
- package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +6 -1
- package/dist/CommandPalette/CommandPaletteItem.js +1 -1
- package/dist/DateInput/DateInput.d.ts +55 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +28 -2
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts +9 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +3 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +18 -3
- package/dist/Dialog/Dialog.d.ts +3 -0
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +57 -6
- package/dist/Dialog/DialogContext.d.ts +7 -0
- package/dist/Dialog/DialogContext.d.ts.map +1 -1
- package/dist/Dialog/DialogContext.js +2 -2
- package/dist/Dialog/DialogHeader.d.ts +5 -2
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +6 -1
- package/dist/Divider/Divider.js +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +1 -2
- package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -2
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +2 -3
- package/dist/Field/FieldLabel.d.ts +1 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +43 -16
- package/dist/FieldStatus/FieldStatus.d.ts +15 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +58 -6
- package/dist/FileInput/FileInput.d.ts +9 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +42 -20
- package/dist/HoverCard/HoverCard.d.ts +9 -1
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +2 -0
- package/dist/HoverCard/useHoverCard.d.ts +8 -0
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +7 -2
- package/dist/Icon/Icon.d.ts +7 -2
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Item/Item.d.ts +6 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +22 -1
- package/dist/Layer/useLayer.d.ts +6 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +2 -0
- package/dist/Lightbox/Lightbox.js +4 -4
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +6 -1
- package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
- package/dist/MobileNav/MobileNavToggle.js +4 -0
- package/dist/MultiSelector/MultiSelector.d.ts +9 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +41 -12
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +16 -0
- package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
- package/dist/NumberInput/NumberInput.d.ts +9 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +8 -1
- package/dist/Outline/Outline.d.ts +0 -1
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +0 -1
- package/dist/OverflowList/OverflowList.d.ts +20 -3
- package/dist/OverflowList/OverflowList.d.ts.map +1 -1
- package/dist/OverflowList/OverflowList.js +29 -4
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +11 -3
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +3 -2
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +3 -9
- 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/PowerSearch/PowerSearchEditPopover.js +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.d.ts +9 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +16 -13
- package/dist/Selector/Selector.d.ts +8 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +7 -3
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +16 -0
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +21 -8
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +19 -2
- package/dist/Stack/stack.stylex.d.ts +9 -9
- package/dist/TabList/Tab.js +2 -2
- package/dist/TabList/TabMenu.js +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +3 -2
- package/dist/Table/TableCell.js +3 -3
- package/dist/Table/TableHeaderCell.js +3 -3
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
- package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
- package/dist/Table/plugins/rowStatus/index.js +3 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts +13 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +4 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.d.ts +16 -0
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +87 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts +6 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeState.js +22 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -3
- package/dist/TextArea/TextArea.d.ts +9 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +2 -0
- package/dist/TextInput/TextInput.d.ts +9 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +6 -1
- package/dist/Thumbnail/Thumbnail.d.ts +26 -5
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +97 -54
- package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +9 -0
- package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +1 -0
- package/dist/Thumbnail/thumbnail.markers.stylex.js +14 -0
- package/dist/TimeInput/TimeInput.d.ts +9 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +17 -4
- package/dist/Timestamp/Timestamp.d.ts +3 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +8 -6
- package/dist/Toast/useToast.d.ts.map +1 -1
- package/dist/Toast/useToast.js +2 -5
- package/dist/ToggleButton/ToggleButtonGroup.d.ts +0 -1
- package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButtonGroup.js +1 -1
- package/dist/Tokenizer/Tokenizer.d.ts +10 -3
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +18 -4
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +18 -8
- package/dist/TopNav/TopNavMegaMenu.js +10 -4
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +9 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +8 -1
- package/dist/TopNav/TopNavMenu.d.ts +2 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +68 -6
- package/dist/TreeList/TreeList.d.ts +12 -3
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +2 -0
- package/dist/TreeList/TreeListBranches.d.ts +5 -0
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +10 -4
- package/dist/TreeList/TreeListItem.d.ts +8 -2
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +28 -8
- package/dist/TreeList/TreeListTypes.d.ts +25 -1
- package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
- package/dist/TreeList/index.d.ts +2 -2
- package/dist/TreeList/index.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +1 -1
- package/dist/Typeahead/Typeahead.d.ts +9 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +2 -0
- package/dist/astryx.css +41 -31
- package/dist/astryx.umd.js +51 -51
- package/dist/astryx.umd.js.map +4 -4
- package/dist/authoring/doc.d.ts.map +1 -1
- package/dist/docs-types.d.ts +8 -0
- package/dist/docs-types.d.ts.map +1 -1
- package/dist/hooks/computeOverflow.d.ts +47 -0
- package/dist/hooks/computeOverflow.d.ts.map +1 -0
- package/dist/hooks/computeOverflow.js +213 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -1
- 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/useDevWarning.d.ts +18 -0
- package/dist/hooks/useDevWarning.d.ts.map +1 -0
- package/dist/hooks/useDevWarning.js +49 -0
- 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/useListFocus.d.ts +6 -1
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +12 -4
- package/dist/hooks/useOverflow.d.ts +19 -0
- package/dist/hooks/useOverflow.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +36 -25
- 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/resolve.d.ts.map +1 -1
- package/dist/i18n/resolve.js +7 -18
- 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/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +2 -7
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +13 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +51 -0
- package/dist/theme/hct.d.ts +0 -1
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +2 -1
- package/dist/utils/devWarning.d.ts +42 -0
- package/dist/utils/devWarning.d.ts.map +1 -0
- package/dist/utils/devWarning.js +88 -0
- package/dist/utils/index.d.ts +3 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -2
- package/dist/utils/plainDate.d.ts +30 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +53 -0
- package/dist/utils/types.d.ts +13 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/locales/en.json +32 -0
- package/locales/fr-FR.json +14 -0
- package/locales/pseudo.json +24 -0
- package/package.json +1 -1
- package/src/AppShell/AppShell.tsx +6 -0
- package/src/AppShell/AppShellMobileContext.tsx +8 -0
- package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
- package/src/Avatar/Avatar.doc.mjs +60 -3
- package/src/Avatar/Avatar.test.tsx +281 -1
- package/src/Avatar/Avatar.tsx +324 -64
- package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
- package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
- package/src/Avatar/AvatarStatusDot.tsx +178 -21
- package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
- package/src/AvatarGroup/AvatarGroup.test.tsx +125 -0
- package/src/AvatarGroup/AvatarGroup.tsx +58 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -0
- package/src/Banner/Banner.doc.mjs +9 -0
- package/src/Banner/Banner.test.tsx +30 -0
- package/src/Banner/Banner.tsx +53 -9
- package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +26 -0
- package/src/Breadcrumbs/BreadcrumbItem.tsx +333 -14
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -0
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +284 -2
- package/src/Breadcrumbs/index.ts +27 -0
- package/src/Button/Button.doc.mjs +9 -0
- package/src/Button/Button.test.tsx +49 -0
- package/src/Button/Button.tsx +27 -3
- package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
- package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
- package/src/ButtonGroup/ButtonGroup.tsx +32 -0
- package/src/Calendar/Calendar.doc.mjs +12 -1
- package/src/Calendar/Calendar.test.tsx +193 -0
- package/src/Calendar/Calendar.tsx +38 -16
- package/src/Calendar/dayCellUtils.test.ts +5 -0
- package/src/Calendar/dayCellUtils.ts +1 -1
- package/src/Card/Card.doc.mjs +9 -0
- package/src/Card/Card.test.tsx +21 -3
- package/src/Card/Card.tsx +35 -2
- package/src/Carousel/Carousel.doc.mjs +1 -0
- package/src/Carousel/Carousel.test.tsx +53 -0
- package/src/Carousel/Carousel.tsx +34 -4
- package/src/Chat/ChatComposer.doc.mjs +12 -3
- package/src/Chat/ChatComposer.test.tsx +115 -0
- package/src/Chat/ChatComposer.tsx +73 -9
- package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
- package/src/Chat/ChatComposerDrawer.tsx +11 -1
- package/src/Chat/ChatComposerInput.doc.mjs +7 -0
- package/src/Chat/ChatComposerInput.test.tsx +103 -0
- package/src/Chat/ChatComposerInput.tsx +51 -5
- package/src/Chat/ChatContext.tsx +37 -10
- package/src/Chat/ChatDictationButton.tsx +4 -1
- package/src/Chat/ChatLayout.tsx +7 -5
- package/src/Chat/ChatLayoutScrollButton.tsx +7 -2
- package/src/Chat/ChatMessageMetadata.tsx +1 -2
- package/src/Chat/ChatSendButton.tsx +11 -1
- package/src/Chat/ChatToolCalls.test.tsx +64 -0
- package/src/Chat/ChatToolCalls.tsx +25 -4
- package/src/Chat/index.ts +5 -1
- package/src/Chat/useChatStreamScroll.test.tsx +49 -0
- package/src/Chat/useChatStreamScroll.ts +27 -10
- package/src/Chat/useSpeechRecognition.ts +1 -1
- package/src/Chat/useTriggerMenu.tsx +4 -2
- package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
- package/src/CheckboxInput/CheckboxInput.tsx +1 -1
- package/src/CheckboxList/CheckboxList.test.tsx +81 -3
- package/src/CheckboxList/CheckboxListItem.doc.mjs +33 -5
- package/src/CheckboxList/CheckboxListItem.tsx +41 -5
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
- package/src/ClickableCard/ClickableCard.test.tsx +34 -0
- package/src/ClickableCard/ClickableCard.tsx +13 -3
- package/src/CodeBlock/CodeBlock.test.tsx +56 -0
- package/src/CodeBlock/CodeBlock.tsx +10 -2
- package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
- package/src/CommandPalette/CommandPalette.tsx +3 -1
- package/src/CommandPalette/CommandPaletteGroup.test.tsx +71 -0
- package/src/CommandPalette/CommandPaletteGroup.tsx +12 -1
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
- package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
- package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
- package/src/ContextMenu/ContextMenu.test.tsx +193 -0
- package/src/DateInput/DateInput.doc.mjs +31 -0
- package/src/DateInput/DateInput.test.tsx +131 -0
- package/src/DateInput/DateInput.tsx +78 -3
- package/src/DateInput/index.ts +1 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +8 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +23 -0
- package/src/DateRangeInput/DateRangeInput.tsx +13 -3
- package/src/DateTimeInput/DateTimeInput.doc.mjs +16 -1
- package/src/DateTimeInput/DateTimeInput.test.tsx +147 -0
- package/src/DateTimeInput/DateTimeInput.tsx +42 -18
- package/src/Dialog/Dialog.doc.mjs +2 -2
- package/src/Dialog/Dialog.test.tsx +77 -4
- package/src/Dialog/Dialog.tsx +89 -5
- package/src/Dialog/DialogContext.ts +9 -2
- package/src/Dialog/DialogHeader.doc.mjs +2 -2
- package/src/Dialog/DialogHeader.tsx +9 -2
- package/src/Divider/Divider.tsx +2 -2
- package/src/DropdownMenu/DropdownMenu.test.tsx +169 -0
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +1 -2
- package/src/DropdownMenu/DropdownMenuItem.tsx +1 -1
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
- package/src/Field/Field.test.tsx +57 -12
- package/src/Field/Field.tsx +6 -5
- package/src/Field/FieldLabel.tsx +9 -1
- package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
- package/src/FieldStatus/FieldStatus.test.tsx +150 -40
- package/src/FieldStatus/FieldStatus.tsx +63 -5
- package/src/FileInput/FileInput.doc.mjs +17 -2
- package/src/FileInput/FileInput.test.tsx +135 -12
- package/src/FileInput/FileInput.tsx +53 -28
- package/src/HoverCard/HoverCard.doc.mjs +13 -0
- package/src/HoverCard/HoverCard.test.tsx +21 -2
- package/src/HoverCard/HoverCard.tsx +11 -0
- package/src/HoverCard/useHoverCard.doc.mjs +2 -0
- package/src/HoverCard/useHoverCard.tsx +24 -2
- package/src/Icon/Icon.doc.mjs +3 -2
- package/src/Icon/Icon.tsx +7 -2
- package/src/IconButton/IconButton.doc.mjs +8 -0
- package/src/IconButton/IconButton.test.tsx +15 -18
- package/src/Item/Item.test.tsx +40 -18
- package/src/Item/Item.tsx +38 -2
- package/src/Layer/useLayer.tsx +8 -0
- package/src/Lightbox/Lightbox.tsx +4 -4
- package/src/List/List.test.tsx +9 -8
- package/src/MobileNav/MobileNav.tsx +12 -1
- package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
- package/src/MobileNav/MobileNavToggle.tsx +9 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +13 -2
- package/src/MultiSelector/MultiSelector.test.tsx +195 -3
- package/src/MultiSelector/MultiSelector.tsx +65 -12
- package/src/MultiSelector/hooks.ts +17 -0
- package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +15 -0
- package/src/NumberInput/NumberInput.test.tsx +82 -7
- package/src/NumberInput/NumberInput.tsx +21 -4
- package/src/Outline/Outline.tsx +0 -1
- package/src/OverflowList/OverflowList.doc.mjs +39 -6
- package/src/OverflowList/OverflowList.test.tsx +111 -0
- package/src/OverflowList/OverflowList.tsx +48 -8
- package/src/Pagination/Pagination.tsx +11 -3
- package/src/Popover/Popover.tsx +7 -4
- package/src/Popover/usePopover.tsx +9 -13
- package/src/PowerSearch/PowerSearch.doc.mjs +29 -0
- package/src/PowerSearch/PowerSearch.test.tsx +43 -0
- package/src/PowerSearch/PowerSearch.tsx +10 -1
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
- package/src/PowerSearch/usePowerSearchSource.ts +1 -2
- package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
- package/src/SelectableCard/SelectableCard.test.tsx +46 -4
- package/src/SelectableCard/SelectableCard.tsx +29 -16
- package/src/Selector/Selector.doc.mjs +7 -0
- package/src/Selector/Selector.test.tsx +92 -0
- package/src/Selector/Selector.tsx +16 -2
- package/src/Selector/hooks.ts +17 -0
- package/src/SideNav/SideNav.test.tsx +119 -3
- package/src/SideNav/SideNavCollapseButton.tsx +6 -1
- package/src/SideNav/SideNavHeading.tsx +24 -8
- package/src/SideNav/SideNavItem.tsx +5 -1
- package/src/Slider/Slider.test.tsx +75 -2
- package/src/Slider/Slider.tsx +21 -5
- package/src/Switch/Switch.test.tsx +32 -1
- package/src/TabList/Tab.tsx +2 -2
- package/src/TabList/TabMenu.tsx +2 -2
- package/src/Table/BaseTable.tsx +3 -5
- package/src/Table/TableCell.tsx +3 -3
- package/src/Table/TableHeaderCell.tsx +3 -3
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +6 -2
- package/src/Table/plugins/rowStatus/index.ts +7 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +138 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +189 -0
- package/src/Table/plugins/selection/useTableSelection.test.tsx +16 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +19 -1
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -1
- package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
- package/src/Table/plugins/tree/useTableTreeData.tsx +128 -1
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
- package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
- package/src/Table/useBaseTablePlugins.ts +10 -6
- package/src/Table/useTableRowStatus.doc.mjs +30 -0
- package/src/Table/useTableSelection.doc.mjs +65 -14
- package/src/Table/useTableTreeData.doc.mjs +29 -0
- package/src/Table/useTableTreeState.doc.mjs +2 -2
- package/src/TextArea/TextArea.doc.mjs +15 -0
- package/src/TextArea/TextArea.test.tsx +32 -1
- package/src/TextArea/TextArea.tsx +10 -0
- package/src/TextInput/TextInput.doc.mjs +15 -0
- package/src/TextInput/TextInput.test.tsx +44 -0
- package/src/TextInput/TextInput.tsx +13 -1
- package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
- package/src/Thumbnail/Thumbnail.test.tsx +98 -7
- package/src/Thumbnail/Thumbnail.tsx +142 -42
- package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
- package/src/TimeInput/TimeInput.doc.mjs +15 -0
- package/src/TimeInput/TimeInput.test.tsx +99 -1
- package/src/TimeInput/TimeInput.tsx +29 -6
- package/src/Timestamp/Timestamp.doc.mjs +4 -4
- package/src/Timestamp/Timestamp.test.tsx +32 -0
- package/src/Timestamp/Timestamp.tsx +28 -8
- package/src/Toast/useToast.tsx +7 -8
- package/src/ToggleButton/ToggleButtonGroup.tsx +1 -1
- package/src/Tokenizer/Tokenizer.doc.mjs +30 -1
- package/src/Tokenizer/Tokenizer.test.tsx +206 -2
- package/src/Tokenizer/Tokenizer.tsx +26 -4
- package/src/TopNav/TopNav.test.tsx +125 -1
- package/src/TopNav/TopNavHeading.tsx +24 -8
- package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
- package/src/TopNav/TopNavMegaMenu.tsx +10 -4
- package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +3 -3
- package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +19 -2
- package/src/TopNav/TopNavMenu.test.tsx +118 -4
- package/src/TopNav/TopNavMenu.tsx +83 -5
- package/src/TreeList/TreeList.doc.mjs +22 -0
- package/src/TreeList/TreeList.test.tsx +232 -0
- package/src/TreeList/TreeList.tsx +18 -2
- package/src/TreeList/TreeListBranches.tsx +16 -2
- package/src/TreeList/TreeListItem.tsx +52 -12
- package/src/TreeList/TreeListTypes.ts +27 -1
- package/src/TreeList/index.ts +2 -2
- package/src/Typeahead/BaseTypeahead.tsx +1 -1
- package/src/Typeahead/Typeahead.doc.mjs +7 -0
- package/src/Typeahead/Typeahead.test.tsx +23 -0
- package/src/Typeahead/Typeahead.tsx +10 -0
- package/src/authoring/doc.ts +1 -3
- package/src/docs-types.ts +5 -0
- package/src/hooks/computeOverflow.test.ts +422 -0
- package/src/hooks/computeOverflow.ts +290 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/isRtlElement.ts +27 -0
- package/src/hooks/useDevWarning.test.tsx +45 -0
- package/src/hooks/useDevWarning.ts +54 -0
- 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/useListFocus.doc.mjs +3 -3
- package/src/hooks/useListFocus.test.tsx +67 -1
- package/src/hooks/useListFocus.ts +21 -5
- package/src/hooks/useOverflow.test.ts +96 -4
- package/src/hooks/useOverflow.ts +74 -33
- package/src/i18n/InternationalizationContext.ts +4 -0
- package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
- 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/resolve.ts +9 -21
- package/src/i18n/useDirection.ts +29 -0
- package/src/reset.css +0 -26
- package/src/reset.test.ts +60 -0
- package/src/theme/Theme.tsx +11 -14
- package/src/theme/derivedVarRegistry.test.ts +1 -0
- package/src/theme/derivedVarRegistry.ts +6 -0
- package/src/theme/generateThemeRules.test.ts +107 -0
- package/src/theme/generateThemeRules.ts +56 -0
- package/src/theme/hct.ts +1 -1
- package/src/theme/syntax/defineSyntaxTheme.ts +5 -6
- package/src/utils/devWarning.test.ts +56 -0
- package/src/utils/devWarning.ts +102 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/plainDate.test.ts +22 -0
- package/src/utils/plainDate.ts +61 -0
- package/src/utils/types.ts +14 -0
|
@@ -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: HTMLElement | null): boolean {
|
|
23
|
+
if (!el || typeof window === 'undefined') {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return window.getComputedStyle(el).direction === 'rtl';
|
|
27
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import {afterEach, describe, expect, it, vi} from 'vitest';
|
|
4
|
+
import {render} from '@testing-library/react';
|
|
5
|
+
import {useDevWarning} from './useDevWarning';
|
|
6
|
+
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
vi.restoreAllMocks();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
function Probe({
|
|
12
|
+
condition,
|
|
13
|
+
message = 'boom',
|
|
14
|
+
}: {
|
|
15
|
+
condition: boolean;
|
|
16
|
+
message?: string;
|
|
17
|
+
}) {
|
|
18
|
+
useDevWarning('TestComponent', message, condition);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe('useDevWarning', () => {
|
|
23
|
+
it('warns once, in the standardized format, when the condition is true', () => {
|
|
24
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
25
|
+
const {rerender} = render(<Probe condition={true} />);
|
|
26
|
+
rerender(<Probe condition={true} />);
|
|
27
|
+
rerender(<Probe condition={true} />);
|
|
28
|
+
expect(warn).toHaveBeenCalledTimes(1);
|
|
29
|
+
expect(warn).toHaveBeenCalledWith('TestComponent: boom');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('does not warn when the condition is false', () => {
|
|
33
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
34
|
+
render(<Probe condition={false} />);
|
|
35
|
+
expect(warn).not.toHaveBeenCalled();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('warns after the condition flips from false to true', () => {
|
|
39
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
40
|
+
const {rerender} = render(<Probe condition={false} />);
|
|
41
|
+
expect(warn).not.toHaveBeenCalled();
|
|
42
|
+
rerender(<Probe condition={true} />);
|
|
43
|
+
expect(warn).toHaveBeenCalledTimes(1);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file useDevWarning.ts
|
|
7
|
+
* @input A component name, a message, and a boolean condition
|
|
8
|
+
* @output Fires a dev-only `Component: message` warning once per mount
|
|
9
|
+
* @position Core hook; the render-safe way to warn the builder from a component
|
|
10
|
+
*
|
|
11
|
+
* The right way to surface a dev guardrail from inside a component. A naive
|
|
12
|
+
* `if (condition) console.warn(...)` in the render body repeats on every
|
|
13
|
+
* render, and reaching for `useState` to gate it adds needless state and
|
|
14
|
+
* re-renders. This hook uses a ref + effect: the warning fires once per mount
|
|
15
|
+
* when the condition holds, never during render, and never triggers a
|
|
16
|
+
* re-render. Messages use the standardized `Component: message` format.
|
|
17
|
+
*
|
|
18
|
+
* SYNC: When modified, update:
|
|
19
|
+
* - /packages/core/src/hooks/index.ts
|
|
20
|
+
* - /packages/core/src/utils/devWarning.ts (the imperative counterpart)
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import {useEffect, useRef} from 'react';
|
|
24
|
+
import {devWarn} from '../utils/devWarning';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Fire a dev-only warning once per mount while `condition` is true.
|
|
28
|
+
*
|
|
29
|
+
* @param component - Component or hook name (message prefix)
|
|
30
|
+
* @param message - What went wrong and how to fix it
|
|
31
|
+
* @param condition - Whether to warn; defaults to `true`
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```
|
|
35
|
+
* useDevWarning(
|
|
36
|
+
* 'Field',
|
|
37
|
+
* 'isOptional and isRequired are mutually exclusive. isOptional takes precedence.',
|
|
38
|
+
* isOptional && isRequired,
|
|
39
|
+
* );
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function useDevWarning(
|
|
43
|
+
component: string,
|
|
44
|
+
message: string,
|
|
45
|
+
condition: boolean = true,
|
|
46
|
+
): void {
|
|
47
|
+
const hasWarnedRef = useRef(false);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (condition && !hasWarnedRef.current) {
|
|
50
|
+
hasWarnedRef.current = true;
|
|
51
|
+
devWarn(component, message);
|
|
52
|
+
}
|
|
53
|
+
}, [component, message, condition]);
|
|
54
|
+
}
|
|
@@ -64,8 +64,8 @@ export const docs = {
|
|
|
64
64
|
{
|
|
65
65
|
name: 'options.isRtl',
|
|
66
66
|
type: 'boolean',
|
|
67
|
-
description: 'Swap ArrowLeft/ArrowRight so horizontal navigation follows visual direction in right-to-left contexts.',
|
|
68
|
-
default: '
|
|
67
|
+
description: 'Swap ArrowLeft/ArrowRight so horizontal navigation follows visual direction in right-to-left contexts. When omitted, auto-detected from the container computed direction on keydown.',
|
|
68
|
+
default: "undefined (auto-detect from the container's computed direction)",
|
|
69
69
|
required: false,
|
|
70
70
|
},
|
|
71
71
|
{
|
|
@@ -138,7 +138,7 @@ export const docsDense = {
|
|
|
138
138
|
'options.onNavigateAfter': 'callback when navigation would go after last cell. Receives column index + offset.',
|
|
139
139
|
'options.onPageUp': 'callback for Page Up key (e.g. navigate to previous month in calendars).',
|
|
140
140
|
'options.onPageDown': 'callback for Page Down key (e.g. navigate to next month in calendars).',
|
|
141
|
-
'options.isRtl': 'swap ArrowLeft/ArrowRight for RTL horizontal navigation. default
|
|
141
|
+
'options.isRtl': 'swap ArrowLeft/ArrowRight for RTL horizontal navigation. default: auto-detect from container computed direction; explicit boolean wins.',
|
|
142
142
|
'options.hasRovingTabIndex': 'own a single roving tab stop across the grid (one focus target tabindex=0, rest -1); repaired on render + moved with arrows. Attach handleFocus to onFocus. default false.',
|
|
143
143
|
},
|
|
144
144
|
returnDescriptions: {
|
|
@@ -23,10 +23,12 @@ const NO_DISABLED: number[] = [];
|
|
|
23
23
|
function Grid({
|
|
24
24
|
disabled = NO_DISABLED,
|
|
25
25
|
seed = 0,
|
|
26
|
+
dir,
|
|
26
27
|
...opts
|
|
27
28
|
}: {
|
|
28
29
|
disabled?: number[];
|
|
29
30
|
seed?: number;
|
|
31
|
+
dir?: 'ltr' | 'rtl';
|
|
30
32
|
} & Partial<Parameters<typeof useGridFocus>[0]>) {
|
|
31
33
|
const {gridRef, handleKeyDown, handleFocus} = useGridFocus<HTMLDivElement>({
|
|
32
34
|
columns: 3,
|
|
@@ -41,6 +43,7 @@ function Grid({
|
|
|
41
43
|
<div
|
|
42
44
|
ref={gridRef}
|
|
43
45
|
role="grid"
|
|
46
|
+
dir={dir}
|
|
44
47
|
onKeyDown={handleKeyDown}
|
|
45
48
|
onFocus={handleFocus}>
|
|
46
49
|
{Array.from({length: 9}, (_, i) => (
|
|
@@ -130,3 +133,41 @@ describe('useGridFocus roving tabindex (hasRovingTabIndex)', () => {
|
|
|
130
133
|
expect(screen.getByTestId('cell-1')).toHaveAttribute('tabindex', '-1');
|
|
131
134
|
});
|
|
132
135
|
});
|
|
136
|
+
|
|
137
|
+
describe('useGridFocus RTL auto-detection (WCAG 1.3.2)', () => {
|
|
138
|
+
// jsdom reflects the `dir` attribute into computed style only on the element
|
|
139
|
+
// that carries it, so tests set dir="rtl" on the grid container itself — the
|
|
140
|
+
// element the hook reads via gridRef.
|
|
141
|
+
|
|
142
|
+
it('auto-detects dir="rtl": ArrowLeft moves forward (next cell)', () => {
|
|
143
|
+
render(<Grid seed={1} dir="rtl" />);
|
|
144
|
+
const grid = screen.getByRole('grid');
|
|
145
|
+
screen.getByTestId('cell-1').focus();
|
|
146
|
+
fireEvent.keyDown(grid, {key: 'ArrowLeft'});
|
|
147
|
+
expect(screen.getByTestId('cell-2')).toHaveFocus();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('auto-detects dir="rtl": ArrowRight moves backward (previous cell)', () => {
|
|
151
|
+
render(<Grid seed={1} dir="rtl" />);
|
|
152
|
+
const grid = screen.getByRole('grid');
|
|
153
|
+
screen.getByTestId('cell-1').focus();
|
|
154
|
+
fireEvent.keyDown(grid, {key: 'ArrowRight'});
|
|
155
|
+
expect(screen.getByTestId('cell-0')).toHaveFocus();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('leaves vertical navigation unaffected under dir="rtl"', () => {
|
|
159
|
+
render(<Grid seed={0} dir="rtl" />);
|
|
160
|
+
const grid = screen.getByRole('grid');
|
|
161
|
+
screen.getByTestId('cell-0').focus();
|
|
162
|
+
fireEvent.keyDown(grid, {key: 'ArrowDown'});
|
|
163
|
+
expect(screen.getByTestId('cell-3')).toHaveFocus();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('explicit isRtl={false} overrides a dir="rtl" container', () => {
|
|
167
|
+
render(<Grid seed={1} dir="rtl" isRtl={false} />);
|
|
168
|
+
const grid = screen.getByRole('grid');
|
|
169
|
+
screen.getByTestId('cell-1').focus();
|
|
170
|
+
fireEvent.keyDown(grid, {key: 'ArrowRight'});
|
|
171
|
+
expect(screen.getByTestId('cell-2')).toHaveFocus();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -4,9 +4,12 @@
|
|
|
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
|
|
@@ -14,6 +17,7 @@
|
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
19
|
import {useCallback, useRef} from 'react';
|
|
20
|
+
import {isRtlElement} from './isRtlElement';
|
|
17
21
|
import {useIsomorphicLayoutEffect} from './useIsomorphicLayoutEffect';
|
|
18
22
|
|
|
19
23
|
/**
|
|
@@ -88,7 +92,12 @@ export interface UseGridFocusOptions {
|
|
|
88
92
|
/**
|
|
89
93
|
* Whether the grid is in a right-to-left context. When true, ArrowLeft and
|
|
90
94
|
* ArrowRight are swapped so horizontal navigation follows visual direction.
|
|
91
|
-
*
|
|
95
|
+
*
|
|
96
|
+
* When omitted, the direction is auto-detected from the container's computed
|
|
97
|
+
* `direction` (read lazily on keydown, only for horizontal arrow keys), so
|
|
98
|
+
* grids inside `dir="rtl"` subtrees flip automatically. Pass an explicit
|
|
99
|
+
* boolean to override detection.
|
|
100
|
+
* @default undefined (auto-detect from the container)
|
|
92
101
|
*/
|
|
93
102
|
isRtl?: boolean;
|
|
94
103
|
|
|
@@ -217,7 +226,7 @@ export function useGridFocus<T extends HTMLElement = HTMLElement>(
|
|
|
217
226
|
onNavigateAfter,
|
|
218
227
|
onPageUp,
|
|
219
228
|
onPageDown,
|
|
220
|
-
isRtl
|
|
229
|
+
isRtl,
|
|
221
230
|
hasRovingTabIndex = false,
|
|
222
231
|
} = options;
|
|
223
232
|
|
|
@@ -455,13 +464,15 @@ export function useGridFocus<T extends HTMLElement = HTMLElement>(
|
|
|
455
464
|
|
|
456
465
|
// In RTL, ArrowLeft/ArrowRight are swapped so horizontal navigation
|
|
457
466
|
// follows visual direction. Vertical keys (Up/Down) are unaffected.
|
|
467
|
+
// Direction is resolved lazily — getComputedStyle runs only when a
|
|
468
|
+
// horizontal arrow key is actually pressed (SSR-safe, no layout thrash
|
|
469
|
+
// on unrelated keys) — and an explicit `isRtl` always wins.
|
|
458
470
|
let key = e.key;
|
|
459
|
-
if (
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
}
|
|
471
|
+
if (
|
|
472
|
+
(key === 'ArrowLeft' || key === 'ArrowRight') &&
|
|
473
|
+
(isRtl ?? isRtlElement(gridRef.current))
|
|
474
|
+
) {
|
|
475
|
+
key = key === 'ArrowLeft' ? 'ArrowRight' : 'ArrowLeft';
|
|
465
476
|
}
|
|
466
477
|
|
|
467
478
|
switch (key) {
|
|
@@ -49,8 +49,8 @@ export const docs = {
|
|
|
49
49
|
{
|
|
50
50
|
name: 'options.isRtl',
|
|
51
51
|
type: 'boolean',
|
|
52
|
-
description: 'Whether the list is in a right-to-left context. When true, ArrowLeft/ArrowRight are swapped for horizontal navigation so it follows visual direction.',
|
|
53
|
-
default: '
|
|
52
|
+
description: 'Whether the list is in a right-to-left context. When true, ArrowLeft/ArrowRight are swapped for horizontal navigation so it follows visual direction. When omitted, auto-detected from the container computed direction on keydown.',
|
|
53
|
+
default: "undefined (auto-detect from the container's computed direction)",
|
|
54
54
|
required: false,
|
|
55
55
|
},
|
|
56
56
|
{
|
|
@@ -127,7 +127,7 @@ export const docsDense = {
|
|
|
127
127
|
'options.onEscape': 'callback when Escape key pressed (e.g. close menu).',
|
|
128
128
|
'options.orientation': "navigation orientation. 'horizontal' uses ArrowLeft/ArrowRight, 'vertical' uses ArrowUp/ArrowDown, 'both' accepts all four arrows.",
|
|
129
129
|
'options.hasHomeEnd': 'whether Home/End jump to first/last enabled item.',
|
|
130
|
-
'options.isRtl': '
|
|
130
|
+
'options.isRtl': 'ArrowLeft/ArrowRight swap for horizontal nav (RTL). default: auto-detect from container computed direction; explicit boolean wins.',
|
|
131
131
|
'options.hasRovingTabIndex': 'opt into roving-tabindex ownership: hook stamps + repairs a single tab stop across items.',
|
|
132
132
|
'options.hasCaretGuard': "when true, don't steal arrow keys from a nested text input/textarea mid-line or from a contenteditable.",
|
|
133
133
|
},
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file useListFocus.test.tsx
|
|
5
5
|
* @input Uses vitest, @testing-library/react, useListFocus hook
|
|
6
|
-
* @output Unit tests for useListFocus disabled-item skipping
|
|
6
|
+
* @output Unit tests for useListFocus disabled-item skipping, navigation, and
|
|
7
|
+
* RTL auto-detection
|
|
7
8
|
* @position Testing; validates useListFocus.ts keyboard navigation
|
|
8
9
|
*
|
|
9
10
|
* SYNC: When useListFocus.ts changes, update tests to match new behavior
|
|
@@ -373,3 +374,68 @@ describe('useListFocus shortcut passthrough', () => {
|
|
|
373
374
|
expect(screen.getByTestId('A')).toHaveFocus();
|
|
374
375
|
});
|
|
375
376
|
});
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* A horizontal list (menubar-like) for RTL direction tests. jsdom reflects the
|
|
380
|
+
* `dir` attribute into computed style only on the element that carries it, so
|
|
381
|
+
* `dir` is set on the list container itself — the element the hook reads via
|
|
382
|
+
* listRef.
|
|
383
|
+
*/
|
|
384
|
+
function HorizontalMenu({dir, isRtl}: {dir?: 'ltr' | 'rtl'; isRtl?: boolean}) {
|
|
385
|
+
const {listRef, handleKeyDown} = useListFocus<HTMLDivElement>({
|
|
386
|
+
orientation: 'horizontal',
|
|
387
|
+
isRtl,
|
|
388
|
+
});
|
|
389
|
+
const items = ['One', 'Two', 'Three'];
|
|
390
|
+
return (
|
|
391
|
+
<div ref={listRef} role="menu" dir={dir} onKeyDown={handleKeyDown}>
|
|
392
|
+
{items.map(label => (
|
|
393
|
+
<div key={label} role="menuitem" tabIndex={-1} data-testid={label}>
|
|
394
|
+
{label}
|
|
395
|
+
</div>
|
|
396
|
+
))}
|
|
397
|
+
</div>
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
describe('useListFocus RTL auto-detection (WCAG 1.3.2)', () => {
|
|
402
|
+
it('auto-detects dir="rtl": ArrowLeft moves to the next item', () => {
|
|
403
|
+
render(<HorizontalMenu dir="rtl" />);
|
|
404
|
+
const menu = screen.getByRole('menu');
|
|
405
|
+
screen.getByTestId('One').focus();
|
|
406
|
+
fireEvent.keyDown(menu, {key: 'ArrowLeft'});
|
|
407
|
+
expect(screen.getByTestId('Two')).toHaveFocus();
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it('auto-detects dir="rtl": ArrowRight moves to the previous item', () => {
|
|
411
|
+
render(<HorizontalMenu dir="rtl" />);
|
|
412
|
+
const menu = screen.getByRole('menu');
|
|
413
|
+
screen.getByTestId('Two').focus();
|
|
414
|
+
fireEvent.keyDown(menu, {key: 'ArrowRight'});
|
|
415
|
+
expect(screen.getByTestId('One')).toHaveFocus();
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('stays LTR without a direction: ArrowRight moves to the next item', () => {
|
|
419
|
+
render(<HorizontalMenu />);
|
|
420
|
+
const menu = screen.getByRole('menu');
|
|
421
|
+
screen.getByTestId('One').focus();
|
|
422
|
+
fireEvent.keyDown(menu, {key: 'ArrowRight'});
|
|
423
|
+
expect(screen.getByTestId('Two')).toHaveFocus();
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it('explicit isRtl={false} overrides a dir="rtl" container', () => {
|
|
427
|
+
render(<HorizontalMenu dir="rtl" isRtl={false} />);
|
|
428
|
+
const menu = screen.getByRole('menu');
|
|
429
|
+
screen.getByTestId('One').focus();
|
|
430
|
+
fireEvent.keyDown(menu, {key: 'ArrowRight'});
|
|
431
|
+
expect(screen.getByTestId('Two')).toHaveFocus();
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
it('explicit isRtl={true} flips arrows without a dir attribute', () => {
|
|
435
|
+
render(<HorizontalMenu isRtl />);
|
|
436
|
+
const menu = screen.getByRole('menu');
|
|
437
|
+
screen.getByTestId('One').focus();
|
|
438
|
+
fireEvent.keyDown(menu, {key: 'ArrowLeft'});
|
|
439
|
+
expect(screen.getByTestId('Two')).toHaveFocus();
|
|
440
|
+
});
|
|
441
|
+
});
|
|
@@ -4,16 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file useListFocus.ts
|
|
7
|
-
* @input Uses React useCallback, useRef, useIsomorphicLayoutEffect
|
|
7
|
+
* @input Uses React useCallback, useRef, useIsomorphicLayoutEffect,
|
|
8
|
+
* isRtlElement
|
|
8
9
|
* @output Exports useListFocus hook for linear list keyboard navigation
|
|
9
10
|
* @position Core hook; used by TabMenu for dropdown menu navigation, Toolbar
|
|
10
11
|
* for roving tabindex, ButtonGroup, ContextMenu, NavHeadingMenu, and more.
|
|
12
|
+
* Auto-detects RTL from the container's computed direction so horizontal
|
|
13
|
+
* arrow keys follow visual direction (WCAG 1.3.2).
|
|
11
14
|
*
|
|
12
15
|
* SYNC: When modified, update:
|
|
13
16
|
* - /packages/core/src/hooks/index.ts
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
19
|
import {useCallback, useRef} from 'react';
|
|
20
|
+
import {isRtlElement} from './isRtlElement';
|
|
17
21
|
import {useIsomorphicLayoutEffect} from './useIsomorphicLayoutEffect';
|
|
18
22
|
|
|
19
23
|
/**
|
|
@@ -62,7 +66,12 @@ export interface UseListFocusOptions {
|
|
|
62
66
|
* Whether the list is in a right-to-left context. When true, ArrowLeft and
|
|
63
67
|
* ArrowRight are swapped so horizontal navigation follows visual direction.
|
|
64
68
|
* Only affects horizontal (`'horizontal'`/`'both'`) navigation.
|
|
65
|
-
*
|
|
69
|
+
*
|
|
70
|
+
* When omitted, the direction is auto-detected from the container's computed
|
|
71
|
+
* `direction` (read lazily on keydown, only for horizontal arrow keys), so
|
|
72
|
+
* lists inside `dir="rtl"` subtrees flip automatically. Pass an explicit
|
|
73
|
+
* boolean to override detection.
|
|
74
|
+
* @default undefined (auto-detect from the container)
|
|
66
75
|
*/
|
|
67
76
|
isRtl?: boolean;
|
|
68
77
|
|
|
@@ -275,7 +284,7 @@ export function useListFocus<T extends HTMLElement = HTMLElement>(
|
|
|
275
284
|
onEscape,
|
|
276
285
|
orientation = 'vertical',
|
|
277
286
|
hasHomeEnd = true,
|
|
278
|
-
isRtl
|
|
287
|
+
isRtl,
|
|
279
288
|
hasRovingTabIndex = false,
|
|
280
289
|
hasCaretGuard = false,
|
|
281
290
|
} = options;
|
|
@@ -486,11 +495,18 @@ export function useListFocus<T extends HTMLElement = HTMLElement>(
|
|
|
486
495
|
const vertical = orientation === 'vertical' || orientation === 'both';
|
|
487
496
|
|
|
488
497
|
// Resolve which keys advance vs retreat, honoring RTL for horizontal.
|
|
498
|
+
// Direction is resolved lazily — getComputedStyle runs only when a
|
|
499
|
+
// horizontal arrow key is actually pressed (SSR-safe, no layout thrash
|
|
500
|
+
// on unrelated keys) — and an explicit `isRtl` always wins.
|
|
489
501
|
const nextKeys: string[] = [];
|
|
490
502
|
const prevKeys: string[] = [];
|
|
491
503
|
if (horizontal) {
|
|
492
|
-
|
|
493
|
-
|
|
504
|
+
const rtl =
|
|
505
|
+
e.key === 'ArrowLeft' || e.key === 'ArrowRight'
|
|
506
|
+
? (isRtl ?? isRtlElement(listRef.current))
|
|
507
|
+
: false;
|
|
508
|
+
nextKeys.push(rtl ? 'ArrowLeft' : 'ArrowRight');
|
|
509
|
+
prevKeys.push(rtl ? 'ArrowRight' : 'ArrowLeft');
|
|
494
510
|
}
|
|
495
511
|
if (vertical) {
|
|
496
512
|
nextKeys.push('ArrowDown');
|
|
@@ -14,12 +14,15 @@ function mockContainer(width: number): HTMLElement {
|
|
|
14
14
|
function mockMeasure(
|
|
15
15
|
itemWidths: number[],
|
|
16
16
|
indicatorWidth?: number,
|
|
17
|
+
itemHeight = 0,
|
|
17
18
|
): HTMLElement {
|
|
18
|
-
const children: {offsetWidth: number}[] =
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const children: {offsetWidth: number; offsetHeight: number}[] =
|
|
20
|
+
itemWidths.map(w => ({
|
|
21
|
+
offsetWidth: w,
|
|
22
|
+
offsetHeight: itemHeight,
|
|
23
|
+
}));
|
|
21
24
|
if (indicatorWidth != null) {
|
|
22
|
-
children.push({offsetWidth: indicatorWidth});
|
|
25
|
+
children.push({offsetWidth: indicatorWidth, offsetHeight: itemHeight});
|
|
23
26
|
}
|
|
24
27
|
return {children} as unknown as HTMLElement;
|
|
25
28
|
}
|
|
@@ -332,6 +335,95 @@ describe('useOverflow', () => {
|
|
|
332
335
|
});
|
|
333
336
|
});
|
|
334
337
|
|
|
338
|
+
describe('useOverflow with maxVisibleItems (cap)', () => {
|
|
339
|
+
it('caps visible items even when they all fit', () => {
|
|
340
|
+
const {result} = renderHook(() =>
|
|
341
|
+
useOverflow(5, {gap: 10, maxVisibleItems: 3}),
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
act(() => {
|
|
345
|
+
result.current.measureRef(mockMeasure([50, 50, 50, 50, 50], 30));
|
|
346
|
+
result.current.containerRef(mockContainer(10000));
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
expect(result.current.visibleCount).toBe(3);
|
|
350
|
+
expect(result.current.hasOverflow).toBe(true);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('cap does not raise a fit-limited count', () => {
|
|
354
|
+
const {result} = renderHook(() =>
|
|
355
|
+
useOverflow(4, {gap: 10, maxVisibleItems: 4}),
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
act(() => {
|
|
359
|
+
result.current.measureRef(mockMeasure([50, 50, 50, 50], 30));
|
|
360
|
+
result.current.containerRef(mockContainer(150));
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
expect(result.current.visibleCount).toBe(2);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it('min wins when maxVisibleItems < minVisibleItems and warns in dev', () => {
|
|
367
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
368
|
+
const {result} = renderHook(() =>
|
|
369
|
+
useOverflow(5, {gap: 10, minVisibleItems: 3, maxVisibleItems: 1}),
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
act(() => {
|
|
373
|
+
result.current.measureRef(mockMeasure([50, 50, 50, 50, 50], 30));
|
|
374
|
+
result.current.containerRef(mockContainer(10000));
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
expect(result.current.visibleCount).toBe(3);
|
|
378
|
+
expect(warn).toHaveBeenCalled();
|
|
379
|
+
warn.mockRestore();
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
describe('useOverflow with maxRows (multi-row)', () => {
|
|
384
|
+
it('exposes rows and rowHeight', () => {
|
|
385
|
+
const {result} = renderHook(() => useOverflow(6, {gap: 10, maxRows: 2}));
|
|
386
|
+
|
|
387
|
+
act(() => {
|
|
388
|
+
result.current.measureRef(mockMeasure([50, 50, 50, 50, 50, 50], 40, 24));
|
|
389
|
+
result.current.containerRef(mockContainer(170));
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// 3 items per row (170), 2 rows → all 6 fit
|
|
393
|
+
expect(result.current.visibleCount).toBe(6);
|
|
394
|
+
expect(result.current.rows).toBe(2);
|
|
395
|
+
expect(result.current.rowHeight).toBe(24);
|
|
396
|
+
expect(result.current.hasOverflow).toBe(false);
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it('collapses items beyond maxRows into the indicator', () => {
|
|
400
|
+
const {result} = renderHook(() => useOverflow(8, {gap: 10, maxRows: 2}));
|
|
401
|
+
|
|
402
|
+
act(() => {
|
|
403
|
+
result.current.measureRef(
|
|
404
|
+
mockMeasure([50, 50, 50, 50, 50, 50, 50, 50], 40, 24),
|
|
405
|
+
);
|
|
406
|
+
result.current.containerRef(mockContainer(170));
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
expect(result.current.visibleCount).toBe(5);
|
|
410
|
+
expect(result.current.rows).toBe(2);
|
|
411
|
+
expect(result.current.hasOverflow).toBe(true);
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it('maxRows=1 matches single-line behavior', () => {
|
|
415
|
+
const {result} = renderHook(() => useOverflow(4, {gap: 10, maxRows: 1}));
|
|
416
|
+
|
|
417
|
+
act(() => {
|
|
418
|
+
result.current.measureRef(mockMeasure([50, 50, 50, 50], 30, 24));
|
|
419
|
+
result.current.containerRef(mockContainer(150));
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
expect(result.current.visibleCount).toBe(2);
|
|
423
|
+
expect(result.current.rows).toBe(1);
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
|
|
335
427
|
describe('useOverflow with behavior=observeParent', () => {
|
|
336
428
|
function mockContainerWithParent(
|
|
337
429
|
parentWidth: number,
|