@astryxdesign/core 0.7.1 → 0.7.2-canary.020e1fe
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/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +40 -1
- package/dist/AspectRatio/AspectRatio.d.ts +6 -8
- package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
- package/dist/AspectRatio/AspectRatio.js +44 -3
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +5 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +38 -14
- package/dist/CheckboxInput/CheckboxInput.d.ts +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +3 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts +9 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +4 -2
- package/dist/CommandPalette/CommandPaletteInput.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +37 -5
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +5 -2
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +20 -8
- package/dist/Drawer/Drawer.d.ts +191 -0
- package/dist/Drawer/Drawer.d.ts.map +1 -0
- package/dist/Drawer/Drawer.js +382 -0
- package/dist/Drawer/DrawerHeader.d.ts +85 -0
- package/dist/Drawer/DrawerHeader.d.ts.map +1 -0
- package/dist/Drawer/DrawerHeader.js +134 -0
- package/dist/Drawer/index.d.ts +11 -0
- package/dist/Drawer/index.d.ts.map +1 -0
- package/dist/Drawer/index.js +11 -0
- package/dist/Drawer/useDrawerDialogPresence.d.ts +42 -0
- package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -0
- package/dist/Drawer/useDrawerDialogPresence.js +236 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +83 -11
- package/dist/DropdownMenu/DropdownMenuContext.d.ts +17 -0
- package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuContext.js +21 -0
- package/dist/DropdownMenu/DropdownMenuDivider.d.ts +5 -3
- package/dist/DropdownMenu/DropdownMenuDivider.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuDivider.js +7 -3
- package/dist/DropdownMenu/DropdownMenuGroup.d.ts +6 -4
- package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuGroup.js +4 -3
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +19 -8
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +24 -0
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -0
- package/dist/DropdownMenu/lazyMenuBottomSheet.js +46 -0
- package/dist/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/EmptyState/EmptyState.js +4 -10
- package/dist/Field/Field.d.ts +1 -1
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +8 -4
- package/dist/Grid/GridSpan.d.ts.map +1 -1
- package/dist/Grid/GridSpan.js +1 -0
- package/dist/Heading/Heading.d.ts.map +1 -1
- package/dist/Heading/Heading.js +4 -2
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +10 -2
- package/dist/Item/Item.d.ts +6 -2
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +19 -4
- package/dist/Layer/layerViewportInset.stylex.d.ts +6 -2
- package/dist/Layer/layerViewportInset.stylex.d.ts.map +1 -1
- package/dist/Layer/layerViewportInset.stylex.js +6 -2
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +13 -7
- package/dist/Layer/useLayerDismissal.d.ts +1 -1
- package/dist/Layer/useLayerDismissal.js +1 -1
- package/dist/Layout/container.stylex.d.ts +5 -5
- package/dist/Layout/container.stylex.js +4 -4
- package/dist/List/List.d.ts +46 -19
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +28 -10
- package/dist/List/ListContext.d.ts +8 -3
- package/dist/List/ListContext.d.ts.map +1 -1
- package/dist/List/ListContext.js +7 -2
- package/dist/List/ListItem.d.ts +13 -5
- package/dist/List/ListItem.d.ts.map +1 -1
- package/dist/List/ListItem.js +21 -8
- package/dist/List/index.d.ts +1 -1
- package/dist/List/index.d.ts.map +1 -1
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +8 -1
- package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -1
- package/dist/Markdown/plugins/frontmatter.js +7 -3
- package/dist/MetadataList/MetadataList.d.ts.map +1 -1
- package/dist/MetadataList/MetadataList.js +5 -1
- package/dist/MetadataList/MetadataListContext.d.ts +1 -1
- package/dist/MetadataList/MetadataListContext.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.d.ts +9 -0
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +30 -3
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +22 -8
- package/dist/MultiSelector/OptionActions.a11y.chromium.spec.js +100 -2
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +3 -1
- package/dist/Pagination/Pagination.d.ts +8 -5
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +21 -8
- package/dist/Popover/Popover.js +2 -2
- package/dist/PowerSearch/PowerSearch.js +1 -1
- package/dist/RadioList/RadioList.d.ts +1 -1
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +6 -2
- package/dist/RadioList/RadioListItem.d.ts +9 -1
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +2 -0
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +6 -2
- package/dist/SideNav/SideNavItem.d.ts +8 -1
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +71 -9
- package/dist/Switch/Switch.d.ts +1 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +13 -1
- package/dist/TabList/TabMenu.d.ts +2 -2
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +6 -3
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +4 -2
- package/dist/Text/useTruncation.d.ts +7 -5
- package/dist/Text/useTruncation.d.ts.map +1 -1
- package/dist/Text/useTruncation.js +16 -5
- package/dist/ToggleButton/ToggleButton.d.ts +3 -2
- package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButton.js +12 -1
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +11 -0
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +3 -3
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +3 -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 +2 -2
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +57 -9
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +26 -0
- package/dist/astryx.css +47 -13
- package/dist/hooks/useEntryAnimation.d.ts +2 -1
- package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
- package/dist/hooks/useEntryAnimation.js +14 -12
- package/dist/hooks/useIsHydrating.d.ts +6 -0
- package/dist/hooks/useIsHydrating.d.ts.map +1 -0
- package/dist/hooks/useIsHydrating.js +30 -0
- package/dist/hooks/useMenuHover.d.ts.map +1 -1
- package/dist/hooks/useMenuHover.js +18 -13
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +112 -1
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +112 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +0 -3
- package/dist/utils/focusOutline.stylex.d.ts +4 -0
- package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
- package/dist/utils/focusOutline.stylex.js +4 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +15 -9
- package/dist/utils/sharedMutationObserver.d.ts +21 -0
- package/dist/utils/sharedMutationObserver.d.ts.map +1 -0
- package/dist/utils/sharedMutationObserver.js +69 -0
- package/locales/en.json +444 -0
- package/locales/pseudo.json +333 -0
- package/package.json +9 -4
- package/scripts/agent-doc-state.mjs +38 -0
- package/scripts/postinstall.mjs +1 -1
- package/src/AppShell/AppShell.tsx +45 -1
- package/src/AspectRatio/AspectRatio.test.tsx +44 -43
- package/src/AspectRatio/AspectRatio.tsx +38 -18
- package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +157 -0
- package/src/Avatar/Avatar.doc.mjs +5 -3
- package/src/AvatarGroup/AvatarGroup.doc.mjs +3 -2
- package/src/Breadcrumbs/BreadcrumbItem.tsx +4 -1
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +30 -1
- package/src/Button/Button.doc.mjs +2 -2
- package/src/Button/Button.test.tsx +155 -9
- package/src/Button/Button.tsx +39 -16
- package/src/Button/__tests__/Button.a11y.known-failures.ts +1 -62
- package/src/Button/__tests__/Button.a11y.states.ts +0 -10
- package/src/Card/Card.doc.mjs +1 -1
- package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +3 -1
- package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
- package/src/CheckboxInput/CheckboxInput.tsx +3 -1
- package/src/CheckboxList/CheckboxList.test.tsx +22 -0
- package/src/CheckboxList/CheckboxListItem.doc.mjs +16 -0
- package/src/CheckboxList/CheckboxListItem.tsx +10 -0
- package/src/Code/Code.doc.mjs +1 -0
- package/src/CommandPalette/CommandPalette.doc.mjs +2 -0
- package/src/CommandPalette/CommandPaletteInput.test.tsx +53 -4
- package/src/CommandPalette/CommandPaletteInput.tsx +33 -3
- package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +335 -0
- package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +292 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +2 -3
- package/src/ContextMenu/ContextMenu.tsx +4 -1
- package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +438 -0
- package/src/Dialog/Dialog.test.tsx +46 -0
- package/src/Dialog/Dialog.tsx +20 -7
- package/src/Dialog/__tests__/Dialog.a11y.known-failures.ts +0 -14
- package/src/Drawer/Drawer.doc.mjs +473 -0
- package/src/Drawer/Drawer.spec.md +357 -0
- package/src/Drawer/Drawer.test.tsx +1300 -0
- package/src/Drawer/Drawer.tsx +613 -0
- package/src/Drawer/DrawerDirection.test.tsx +127 -0
- package/src/Drawer/DrawerHeader.doc.mjs +293 -0
- package/src/Drawer/DrawerHeader.test.tsx +102 -0
- package/src/Drawer/DrawerHeader.tsx +235 -0
- package/src/Drawer/__tests__/DrawerAudit.a11y.chromium.spec.ts +401 -0
- package/src/Drawer/__tests__/DrawerHeaderAudit.a11y.chromium.spec.ts +297 -0
- package/src/Drawer/index.ts +13 -0
- package/src/Drawer/useDrawerDialogPresence.ts +284 -0
- package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +57 -0
- package/src/DropdownMenu/DropdownMenu.test.tsx +79 -18
- package/src/DropdownMenu/DropdownMenu.tsx +83 -12
- package/src/DropdownMenu/DropdownMenuContext.tsx +24 -0
- package/src/DropdownMenu/DropdownMenuDivider.doc.mjs +2 -2
- package/src/DropdownMenu/DropdownMenuDivider.spec.md +192 -0
- package/src/DropdownMenu/DropdownMenuDivider.tsx +9 -5
- package/src/DropdownMenu/DropdownMenuGroup.doc.mjs +169 -10
- package/src/DropdownMenu/DropdownMenuGroup.tsx +6 -4
- package/src/DropdownMenu/DropdownMenuLazySheet.test.tsx +126 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +185 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +19 -5
- package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +280 -0
- package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +334 -0
- package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +145 -0
- package/src/DropdownMenu/__tests__/Menu.a11y.known-failures.ts +26 -0
- package/src/DropdownMenu/__tests__/Menu.a11y.renders.tsx +65 -0
- package/src/DropdownMenu/__tests__/Menu.a11y.states.ts +138 -0
- package/src/DropdownMenu/__tests__/Menu.a11y.test.tsx +136 -0
- package/src/DropdownMenu/__tests__/warmMenuBottomSheet.tsx +43 -0
- package/src/DropdownMenu/lazyMenuBottomSheet.ts +71 -0
- package/src/EmptyState/EmptyState.doc.mjs +3 -2
- package/src/EmptyState/EmptyState.spec.md +189 -0
- package/src/EmptyState/EmptyState.test.tsx +74 -3
- package/src/EmptyState/EmptyState.tsx +4 -8
- package/src/Field/Field.doc.mjs +14 -8
- package/src/Field/Field.spec.md +217 -0
- package/src/Field/Field.test.tsx +60 -2
- package/src/Field/Field.tsx +17 -8
- package/src/Field/FieldLabel.doc.mjs +133 -26
- package/src/Field/FieldLabel.spec.md +172 -0
- package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +296 -0
- package/src/Grid/GridSpan.tsx +3 -0
- package/src/Heading/Heading.test.tsx +57 -0
- package/src/Heading/Heading.tsx +6 -2
- package/src/HoverCard/HoverCard.test.tsx +58 -0
- package/src/HoverCard/useHoverCard.tsx +10 -2
- package/src/Icon/Icon.doc.mjs +36 -0
- package/src/IconButton/IconButton.doc.mjs +2 -2
- package/src/IconButton/IconButton.test.tsx +3 -1
- package/src/Item/Item.doc.mjs +12 -8
- package/src/Item/Item.spec.md +226 -0
- package/src/Item/Item.test.tsx +61 -0
- package/src/Item/Item.tsx +40 -4
- package/src/Layer/layerViewportInset.source-build.test.mjs +90 -0
- package/src/Layer/layerViewportInset.stylex.ts +6 -2
- package/src/Layer/layerViewportInset.test.ts +1 -0
- package/src/Layer/useLayer.tsx +24 -13
- package/src/Layer/useLayerDismissal.ts +1 -1
- package/src/Layout/LayoutHeader.doc.mjs +5 -0
- package/src/Layout/container.stylex.ts +6 -6
- package/src/List/List.doc.mjs +14 -1
- package/src/List/List.spec.md +129 -77
- package/src/List/List.test.tsx +163 -94
- package/src/List/List.tsx +74 -18
- package/src/List/ListContext.tsx +9 -3
- package/src/List/ListItem.doc.mjs +24 -5
- package/src/List/ListItem.tsx +56 -27
- package/src/List/index.ts +1 -1
- package/src/Markdown/Markdown.tsx +14 -1
- package/src/Markdown/plugins/frontmatter.test.tsx +25 -0
- package/src/Markdown/plugins/frontmatter.ts +7 -3
- package/src/MetadataList/MetadataList.doc.mjs +3 -3
- package/src/MetadataList/MetadataList.test.tsx +38 -0
- package/src/MetadataList/MetadataList.tsx +8 -1
- package/src/MetadataList/MetadataListContext.tsx +1 -1
- package/src/MobileNav/MobileNav.tsx +30 -3
- package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +173 -15
- package/src/MoreMenu/MoreMenu.test.tsx +5 -1
- package/src/MultiSelector/MultiSelector.test.tsx +159 -0
- package/src/MultiSelector/MultiSelector.tsx +40 -7
- package/src/MultiSelector/OptionActions.a11y.chromium.spec.ts +112 -2
- package/src/MultiSelector/hooks.ts +3 -1
- package/src/MultiSelector/useMultiCombobox.doc.mjs +267 -0
- package/src/Pagination/Pagination.doc.mjs +7 -7
- package/src/Pagination/Pagination.spec.md +9 -9
- package/src/Pagination/Pagination.test.tsx +242 -0
- package/src/Pagination/Pagination.tsx +27 -11
- package/src/Popover/Popover.test.tsx +2 -2
- package/src/Popover/Popover.tsx +4 -4
- package/src/PowerSearch/PowerSearch.test.tsx +85 -0
- package/src/PowerSearch/PowerSearch.tsx +2 -2
- package/src/ProgressBar/ProgressBar.doc.mjs +1 -0
- package/src/RadioList/RadioList.fr10.test.tsx +45 -2
- package/src/RadioList/RadioList.test.tsx +22 -0
- package/src/RadioList/RadioList.tsx +4 -1
- package/src/RadioList/RadioListItem.doc.mjs +16 -0
- package/src/RadioList/RadioListItem.tsx +10 -1
- package/src/Resizable/useResizable.doc.mjs +2 -0
- package/src/ScrollableArea/ScrollableArea.doc.mjs +1 -1
- package/src/Selector/hooks.ts +6 -2
- package/src/Selector/useCombobox.doc.mjs +237 -0
- package/src/SideNav/SideNav.spec.md +227 -0
- package/src/SideNav/SideNav.test.tsx +179 -0
- package/src/SideNav/SideNavItem.doc.mjs +2 -2
- package/src/SideNav/SideNavItem.tsx +96 -17
- package/src/Slider/Slider.spec.md +39 -18
- package/src/Spinner/Spinner.doc.mjs +1 -1
- package/src/Switch/Switch.test.tsx +49 -0
- package/src/Switch/Switch.tsx +11 -0
- package/src/TabList/TabList.spec.md +57 -44
- package/src/TabList/TabList.test.tsx +67 -0
- package/src/TabList/TabMenu.doc.mjs +4 -3
- package/src/TabList/TabMenu.tsx +7 -4
- package/src/Text/Text.test.tsx +57 -0
- package/src/Text/Text.tsx +6 -2
- package/src/Text/useTruncation.test.tsx +69 -0
- package/src/Text/useTruncation.ts +16 -5
- package/src/TimeInput/TimeInput.fr10.test.tsx +15 -0
- package/src/Timestamp/Timestamp.doc.mjs +1 -1
- package/src/ToggleButton/ToggleButton.test.tsx +95 -0
- package/src/ToggleButton/ToggleButton.tsx +12 -1
- package/src/ToggleButton/ToggleButtonGroup.doc.mjs +4 -0
- package/src/Tokenizer/Tokenizer.test.tsx +54 -1
- package/src/Toolbar/Toolbar.test.tsx +0 -8
- package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +163 -0
- package/src/Toolbar/__tests__/Toolbar.a11y.renders.tsx +63 -0
- package/src/Toolbar/__tests__/Toolbar.a11y.states.ts +142 -0
- package/src/Toolbar/__tests__/Toolbar.a11y.test.tsx +126 -0
- package/src/Tooltip/Tooltip.test.tsx +31 -0
- package/src/Tooltip/useTooltip.test.tsx +13 -0
- package/src/Tooltip/useTooltip.tsx +11 -0
- package/src/TopNav/TopNavMegaMenu.test.tsx +22 -0
- package/src/TopNav/TopNavMegaMenu.tsx +7 -3
- package/src/TopNav/TopNavMenu.test.tsx +19 -0
- package/src/TopNav/TopNavMenu.tsx +11 -3
- package/src/TreeList/TreeList.doc.mjs +1 -0
- package/src/TreeList/TreeList.spec.md +29 -17
- package/src/TreeList/TreeList.test.tsx +327 -6
- package/src/TreeList/TreeList.tsx +5 -1
- package/src/TreeList/TreeListBranches.tsx +6 -0
- package/src/TreeList/TreeListItem.tsx +88 -13
- package/src/Typeahead/BaseTypeahead.tsx +26 -0
- package/src/Typeahead/Typeahead.test.tsx +260 -2
- package/src/docPropLiterals.test.ts +36 -10
- package/src/hooks/useEntryAnimation.doc.mjs +4 -4
- package/src/hooks/useEntryAnimation.ssr.test.tsx +143 -0
- package/src/hooks/useEntryAnimation.ts +15 -16
- package/src/hooks/useIsHydrating.test.tsx +70 -0
- package/src/hooks/useIsHydrating.ts +31 -0
- package/src/hooks/useMenuHover.ts +18 -13
- package/src/i18n/InternationalizationProvider.doc.mjs +8 -0
- package/src/i18n/InternationalizationProvider.spec.md +252 -0
- package/src/i18n/__tests__/InternationalizationProvider.test.tsx +128 -0
- package/src/i18n/generated-locales/en.generated.ts +121 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +121 -0
- package/src/i18n/useTranslator.test.tsx +37 -0
- package/src/index.ts +1 -0
- package/src/postinstall.test.mjs +46 -0
- package/src/reset.css +0 -29
- package/src/theme/derivedVarRegistry.test.ts +7 -3
- package/src/theme/derivedVarRegistry.ts +0 -3
- package/src/utils/focusOutline.stylex.ts +4 -0
- package/src/utils/plainDate.test.ts +37 -1
- package/src/utils/plainDate.ts +15 -5
- package/src/utils/sharedMutationObserver.test.ts +53 -0
- package/src/utils/sharedMutationObserver.ts +78 -0
|
@@ -137,7 +137,7 @@ export const docs = {
|
|
|
137
137
|
name: 'variant',
|
|
138
138
|
type: "'pages' | 'count' | 'compact' | 'dots' | 'input' | 'none'",
|
|
139
139
|
description:
|
|
140
|
-
"Visual variant controlling what appears between prev/next buttons. 'pages' shows page number buttons with ellipsis, 'count' shows 'X-Y of Z' text, 'compact' shows 'Page X of Y', 'dots' shows dot indicators, 'input' shows an editable page-number box with a leading label ('Page [ n ] / N') flanked by first/last buttons by default (the box needs a known total to clamp against, so it is disabled in cursor/hasMore mode), 'none' shows just prev/next buttons.",
|
|
140
|
+
"Visual variant controlling what appears between prev/next buttons. 'pages' shows page number buttons with ellipsis, 'count' shows 'X-Y of Z' text, 'compact' shows 'Page X of Y' (add first/last buttons with hasFirstLast), 'dots' shows dot indicators, 'input' shows an editable page-number box with a leading label ('Page [ n ] / N') flanked by first/last buttons by default (the box needs a known total to clamp against, so it is disabled in cursor/hasMore mode), 'none' shows just prev/next buttons.",
|
|
141
141
|
default: "'pages'",
|
|
142
142
|
},
|
|
143
143
|
{
|
|
@@ -150,8 +150,8 @@ export const docs = {
|
|
|
150
150
|
name: 'hasFirstLast',
|
|
151
151
|
type: 'boolean',
|
|
152
152
|
description:
|
|
153
|
-
"Whether to show first/last («/») double-chevron buttons flanking prev/next.
|
|
154
|
-
default:
|
|
153
|
+
"Whether to show first/last («/») double-chevron buttons flanking prev/next. Applies to the 'input' variant (shown unless false) and the 'compact' variant (shown only when true); other variants ignore it. Omitted when the page count is unknown (cursor/hasMore pagination).",
|
|
154
|
+
default: "true for 'input'; false for 'compact'",
|
|
155
155
|
},
|
|
156
156
|
{
|
|
157
157
|
name: 'step',
|
|
@@ -288,7 +288,7 @@ export const docsZh = {
|
|
|
288
288
|
name: 'variant',
|
|
289
289
|
type: "'pages' | 'count' | 'compact' | 'dots' | 'input' | 'none'",
|
|
290
290
|
description:
|
|
291
|
-
"控制上一页/下一页按钮之间显示内容的视觉变体。'pages' 显示带省略号的页码按钮,'count' 显示 'X-Y of Z' 文本,'compact' 显示 'Page X of Y'
|
|
291
|
+
"控制上一页/下一页按钮之间显示内容的视觉变体。'pages' 显示带省略号的页码按钮,'count' 显示 'X-Y of Z' 文本,'compact' 显示 'Page X of Y'(可通过 hasFirstLast 添加首页/末页按钮),'dots' 显示点指示器,'input' 显示带前置标签的可编辑页码框——'Page [ n ] / N'——默认两侧带首页/末页按钮,'none' 仅显示上一页/下一页按钮。",
|
|
292
292
|
default: "'pages'",
|
|
293
293
|
},
|
|
294
294
|
{
|
|
@@ -301,8 +301,8 @@ export const docsZh = {
|
|
|
301
301
|
name: 'hasFirstLast',
|
|
302
302
|
type: 'boolean',
|
|
303
303
|
description:
|
|
304
|
-
"
|
|
305
|
-
default: 'true',
|
|
304
|
+
"是否显示首页/末页(«/»)双箭头按钮,位于上一页/下一页两侧。适用于 'input' 变体(除非设为 false 否则显示)和 'compact' 变体(仅在设为 true 时显示);其他变体忽略此项。当页数未知(游标/hasMore 分页)时省略。",
|
|
305
|
+
default: "'input' 为 true;'compact' 为 false",
|
|
306
306
|
},
|
|
307
307
|
{
|
|
308
308
|
name: 'step',
|
|
@@ -400,7 +400,7 @@ export const docsDense = {
|
|
|
400
400
|
onPageSizeChange: 'Called on page size change. Auto resets to page 1.',
|
|
401
401
|
variant: "Display between prev/next. 'input' = 'Page [n] / N' + first/last.",
|
|
402
402
|
pageLabel: "Noun before the 'input' box (e.g. 'Page' or 'Row'). Navigation stays page-based. Default localized 'Page'.",
|
|
403
|
-
hasFirstLast: "Show first/last («/») buttons
|
|
403
|
+
hasFirstLast: "Show first/last («/») buttons. 'input' default true; 'compact' default false (opt in). Other variants ignore. Omitted when total unknown.",
|
|
404
404
|
step: 'Pages the prev/next buttons advance per click. Clamped to range; < 1 or non-integer falls back to 1.',
|
|
405
405
|
siblingCount: "Page buttons each side of current; only variant='pages'.",
|
|
406
406
|
size: 'Control size.',
|
|
@@ -92,15 +92,15 @@ and usage remain documented in `Pagination.doc.mjs`.
|
|
|
92
92
|
|
|
93
93
|
### Representative states
|
|
94
94
|
|
|
95
|
-
| State | Required invariant
|
|
96
|
-
| ----------------------------- |
|
|
97
|
-
| Numbered, known page count | Page number buttons render; Ellipsis appears only where pages are omitted.
|
|
98
|
-
| Count with known item total | Count readout renders between Previous/next buttons.
|
|
99
|
-
| Compact with known page count | Compact readout renders between Previous/next buttons.
|
|
100
|
-
| Dots with known page count | One Dot renders for each page and active state stays on the Dot target.
|
|
101
|
-
| Input with known page count | Page input label, Page input, and Page input total render; First/last may render.
|
|
102
|
-
| Input with unknown page count | Page input label and disabled Page input remain; total and First/last are absent.
|
|
103
|
-
| None | Previous/next buttons remain without a presentation-specific part between them.
|
|
95
|
+
| State | Required invariant | Allowed variation |
|
|
96
|
+
| ----------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
|
97
|
+
| Numbered, known page count | Page number buttons render; Ellipsis appears only where pages are omitted. | Page count, sibling range, and active page. |
|
|
98
|
+
| Count with known item total | Count readout renders between Previous/next buttons. | Range and total text. |
|
|
99
|
+
| Compact with known page count | Compact readout renders between Previous/next buttons; First/last render only when opted in. | Current and total page text and first/last opt-in. |
|
|
100
|
+
| Dots with known page count | One Dot renders for each page and active state stays on the Dot target. | Dot count and active Dot. |
|
|
101
|
+
| Input with known page count | Page input label, Page input, and Page input total render; First/last may render. | Label text and first/last opt-out. |
|
|
102
|
+
| Input with unknown page count | Page input label and disabled Page input remain; total and First/last are absent. | Cursor-backed current page. |
|
|
103
|
+
| None | Previous/next buttons remain without a presentation-specific part between them. | Enabled state follows current paging availability. |
|
|
104
104
|
|
|
105
105
|
The optional Page-size selector may precede the paging controls in any current
|
|
106
106
|
presentation when page-size options are provided.
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from '@testing-library/react';
|
|
21
21
|
import userEvent from '@testing-library/user-event';
|
|
22
22
|
import {Pagination, generatePageRange} from './Pagination';
|
|
23
|
+
import {InternationalizationProvider} from '../i18n';
|
|
23
24
|
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
24
25
|
|
|
25
26
|
afterEach(() => {
|
|
@@ -119,6 +120,28 @@ describe('Pagination', () => {
|
|
|
119
120
|
).toBeInTheDocument();
|
|
120
121
|
});
|
|
121
122
|
|
|
123
|
+
it('does not introduce Stack theme targets around navigation controls', () => {
|
|
124
|
+
const {rerender} = render(
|
|
125
|
+
<Pagination page={3} onChange={() => {}} totalPages={5} />,
|
|
126
|
+
);
|
|
127
|
+
expect(
|
|
128
|
+
screen.getByRole('navigation').querySelector('.astryx-stack'),
|
|
129
|
+
).toBeNull();
|
|
130
|
+
|
|
131
|
+
rerender(
|
|
132
|
+
<Pagination
|
|
133
|
+
page={3}
|
|
134
|
+
onChange={() => {}}
|
|
135
|
+
totalPages={5}
|
|
136
|
+
variant="compact"
|
|
137
|
+
hasFirstLast
|
|
138
|
+
/>,
|
|
139
|
+
);
|
|
140
|
+
expect(
|
|
141
|
+
screen.getByRole('navigation').querySelector('.astryx-stack'),
|
|
142
|
+
).toBeNull();
|
|
143
|
+
});
|
|
144
|
+
|
|
122
145
|
it('gives the prev/next carets a hover tooltip matching their accessible name', () => {
|
|
123
146
|
// The carets are icon-only, so sighted users need a visible label on
|
|
124
147
|
// hover, not just the accessible name. The tooltip reuses the same
|
|
@@ -291,6 +314,225 @@ describe('Pagination', () => {
|
|
|
291
314
|
);
|
|
292
315
|
expect(screen.getByText('Page 3 of 10')).toBeInTheDocument();
|
|
293
316
|
});
|
|
317
|
+
|
|
318
|
+
describe('first/last buttons', () => {
|
|
319
|
+
function navButtonNames(): string[] {
|
|
320
|
+
return within(screen.getByRole('navigation'))
|
|
321
|
+
.getAllByRole('button')
|
|
322
|
+
.map(button => button.getAttribute('aria-label') ?? '');
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
it('omits first/last when hasFirstLast is unset', () => {
|
|
326
|
+
render(
|
|
327
|
+
<Pagination
|
|
328
|
+
page={5}
|
|
329
|
+
onChange={() => {}}
|
|
330
|
+
totalPages={10}
|
|
331
|
+
variant="compact"
|
|
332
|
+
/>,
|
|
333
|
+
);
|
|
334
|
+
expect(navButtonNames()).toEqual([
|
|
335
|
+
'Go to previous page',
|
|
336
|
+
'Go to next page',
|
|
337
|
+
]);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('omits first/last when hasFirstLast is false', () => {
|
|
341
|
+
render(
|
|
342
|
+
<Pagination
|
|
343
|
+
page={5}
|
|
344
|
+
onChange={() => {}}
|
|
345
|
+
totalPages={10}
|
|
346
|
+
variant="compact"
|
|
347
|
+
hasFirstLast={false}
|
|
348
|
+
/>,
|
|
349
|
+
);
|
|
350
|
+
expect(navButtonNames()).toEqual([
|
|
351
|
+
'Go to previous page',
|
|
352
|
+
'Go to next page',
|
|
353
|
+
]);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('flanks prev/next with first/last when hasFirstLast is true', () => {
|
|
357
|
+
render(
|
|
358
|
+
<Pagination
|
|
359
|
+
page={5}
|
|
360
|
+
onChange={() => {}}
|
|
361
|
+
totalPages={10}
|
|
362
|
+
variant="compact"
|
|
363
|
+
hasFirstLast
|
|
364
|
+
/>,
|
|
365
|
+
);
|
|
366
|
+
expect(navButtonNames()).toEqual([
|
|
367
|
+
'Go to first page',
|
|
368
|
+
'Go to previous page',
|
|
369
|
+
'Go to next page',
|
|
370
|
+
'Go to last page',
|
|
371
|
+
]);
|
|
372
|
+
// The readout stays between prev and next.
|
|
373
|
+
const readout = within(screen.getByRole('navigation')).getByText(
|
|
374
|
+
'Page 5 of 10',
|
|
375
|
+
);
|
|
376
|
+
const prev = screen.getByRole('button', {name: 'Go to previous page'});
|
|
377
|
+
const next = screen.getByRole('button', {name: 'Go to next page'});
|
|
378
|
+
expect(
|
|
379
|
+
prev.compareDocumentPosition(readout) &
|
|
380
|
+
Node.DOCUMENT_POSITION_FOLLOWING,
|
|
381
|
+
).toBeTruthy();
|
|
382
|
+
expect(
|
|
383
|
+
next.compareDocumentPosition(readout) &
|
|
384
|
+
Node.DOCUMENT_POSITION_PRECEDING,
|
|
385
|
+
).toBeTruthy();
|
|
386
|
+
// Compact never gains an editable box.
|
|
387
|
+
expect(screen.queryByRole('spinbutton')).not.toBeInTheDocument();
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it('jumps to the first and last page through onChange and changeAction', async () => {
|
|
391
|
+
const user = userEvent.setup();
|
|
392
|
+
const onChange = vi.fn();
|
|
393
|
+
const changeAction = vi.fn();
|
|
394
|
+
render(
|
|
395
|
+
<Pagination
|
|
396
|
+
page={5}
|
|
397
|
+
onChange={onChange}
|
|
398
|
+
changeAction={changeAction}
|
|
399
|
+
totalItems={95}
|
|
400
|
+
pageSize={10}
|
|
401
|
+
variant="compact"
|
|
402
|
+
hasFirstLast
|
|
403
|
+
/>,
|
|
404
|
+
);
|
|
405
|
+
await user.click(
|
|
406
|
+
screen.getByRole('button', {name: 'Go to first page'}),
|
|
407
|
+
);
|
|
408
|
+
expect(onChange).toHaveBeenLastCalledWith(1);
|
|
409
|
+
expect(changeAction).toHaveBeenLastCalledWith(1);
|
|
410
|
+
await waitFor(() => {
|
|
411
|
+
expect(politeRegion()).toHaveTextContent('Page 1 of 10');
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
await user.click(screen.getByRole('button', {name: 'Go to last page'}));
|
|
415
|
+
// 95 items at 10 per page is 10 pages.
|
|
416
|
+
expect(onChange).toHaveBeenLastCalledWith(10);
|
|
417
|
+
expect(changeAction).toHaveBeenLastCalledWith(10);
|
|
418
|
+
await waitFor(() => {
|
|
419
|
+
expect(politeRegion()).toHaveTextContent('Page 10 of 10');
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
it('disables first on the first page and last on the last page', () => {
|
|
424
|
+
const {rerender} = render(
|
|
425
|
+
<Pagination
|
|
426
|
+
page={1}
|
|
427
|
+
onChange={() => {}}
|
|
428
|
+
totalPages={10}
|
|
429
|
+
variant="compact"
|
|
430
|
+
hasFirstLast
|
|
431
|
+
/>,
|
|
432
|
+
);
|
|
433
|
+
expect(
|
|
434
|
+
screen.getByRole('button', {name: 'Go to first page'}),
|
|
435
|
+
).toBeDisabled();
|
|
436
|
+
expect(
|
|
437
|
+
screen.getByRole('button', {name: 'Go to last page'}),
|
|
438
|
+
).not.toBeDisabled();
|
|
439
|
+
|
|
440
|
+
rerender(
|
|
441
|
+
<Pagination
|
|
442
|
+
page={10}
|
|
443
|
+
onChange={() => {}}
|
|
444
|
+
totalPages={10}
|
|
445
|
+
variant="compact"
|
|
446
|
+
hasFirstLast
|
|
447
|
+
/>,
|
|
448
|
+
);
|
|
449
|
+
expect(
|
|
450
|
+
screen.getByRole('button', {name: 'Go to first page'}),
|
|
451
|
+
).not.toBeDisabled();
|
|
452
|
+
expect(
|
|
453
|
+
screen.getByRole('button', {name: 'Go to last page'}),
|
|
454
|
+
).toBeDisabled();
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
it('omits first/last when the total page count is unknown', async () => {
|
|
458
|
+
const user = userEvent.setup();
|
|
459
|
+
const onChange = vi.fn();
|
|
460
|
+
render(
|
|
461
|
+
<Pagination
|
|
462
|
+
page={2}
|
|
463
|
+
onChange={onChange}
|
|
464
|
+
hasMore
|
|
465
|
+
variant="compact"
|
|
466
|
+
hasFirstLast
|
|
467
|
+
/>,
|
|
468
|
+
);
|
|
469
|
+
expect(navButtonNames()).toEqual([
|
|
470
|
+
'Go to previous page',
|
|
471
|
+
'Go to next page',
|
|
472
|
+
]);
|
|
473
|
+
await user.click(screen.getByRole('button', {name: 'Go to next page'}));
|
|
474
|
+
expect(onChange).toHaveBeenLastCalledWith(3);
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('mirrors the first/last chevrons under RTL like prev/next', () => {
|
|
478
|
+
render(
|
|
479
|
+
<InternationalizationProvider locale="en" dir="rtl">
|
|
480
|
+
<div dir="rtl">
|
|
481
|
+
<Pagination
|
|
482
|
+
page={5}
|
|
483
|
+
onChange={() => {}}
|
|
484
|
+
totalPages={10}
|
|
485
|
+
variant="compact"
|
|
486
|
+
hasFirstLast
|
|
487
|
+
/>
|
|
488
|
+
</div>
|
|
489
|
+
</InternationalizationProvider>,
|
|
490
|
+
);
|
|
491
|
+
// jsdom applies no CSS transforms, so assert the first/last icons carry
|
|
492
|
+
// every class the mirrored prev/next icons share (the mirror included).
|
|
493
|
+
const iconClasses = (name: string) =>
|
|
494
|
+
new Set(
|
|
495
|
+
screen
|
|
496
|
+
.getByRole('button', {name})
|
|
497
|
+
.querySelector('.astryx-icon')
|
|
498
|
+
?.getAttribute('class')
|
|
499
|
+
?.split(/\s+/) ?? [],
|
|
500
|
+
);
|
|
501
|
+
const prev = iconClasses('Go to previous page');
|
|
502
|
+
const shared = [...iconClasses('Go to next page')].filter(name =>
|
|
503
|
+
prev.has(name),
|
|
504
|
+
);
|
|
505
|
+
expect(shared.length).toBeGreaterThan(0);
|
|
506
|
+
for (const name of ['Go to first page', 'Go to last page']) {
|
|
507
|
+
const classes = iconClasses(name);
|
|
508
|
+
expect(shared.filter(c => !classes.has(c))).toEqual([]);
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
});
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
describe('hasFirstLast on other variants', () => {
|
|
515
|
+
it.each(['pages', 'count', 'dots', 'none'] as const)(
|
|
516
|
+
'does not add first/last to the %s variant',
|
|
517
|
+
variant => {
|
|
518
|
+
render(
|
|
519
|
+
<Pagination
|
|
520
|
+
page={3}
|
|
521
|
+
onChange={() => {}}
|
|
522
|
+
totalItems={50}
|
|
523
|
+
pageSize={10}
|
|
524
|
+
variant={variant}
|
|
525
|
+
hasFirstLast
|
|
526
|
+
/>,
|
|
527
|
+
);
|
|
528
|
+
expect(
|
|
529
|
+
screen.queryByRole('button', {name: 'Go to first page'}),
|
|
530
|
+
).not.toBeInTheDocument();
|
|
531
|
+
expect(
|
|
532
|
+
screen.queryByRole('button', {name: 'Go to last page'}),
|
|
533
|
+
).not.toBeInTheDocument();
|
|
534
|
+
},
|
|
535
|
+
);
|
|
294
536
|
});
|
|
295
537
|
|
|
296
538
|
// ---------------------------------------------------------------------------
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @file Pagination.tsx
|
|
7
7
|
* @input Uses React, StyleX, Button, Icon, Selector, Text; page number buttons delegate to Button.
|
|
8
|
+
* Compact first/last buttons cancel the inside control gap with logical token margins.
|
|
8
9
|
* Prev/next and first/last chevrons mirror under RTL via the shared rtlStyles.mirror
|
|
9
|
-
* (CSS scaleX), not a JS direction read. The input
|
|
10
|
-
* (first/last) icons.
|
|
10
|
+
* (CSS scaleX), not a JS direction read. The input and compact variants use the
|
|
11
|
+
* chevronsLeft/chevronsRight (first/last) icons.
|
|
11
12
|
* @output Exports Pagination component, PaginationProps, PaginationVariant, PaginationSize types
|
|
12
13
|
* @position Core implementation; consumed by index.ts, tested by Pagination.test.tsx
|
|
13
14
|
*
|
|
@@ -105,7 +106,8 @@ export interface PaginationProps extends Omit<
|
|
|
105
106
|
* Visual variant controlling what appears between prev/next buttons.
|
|
106
107
|
* - pages: Page number buttons with ellipsis (default)
|
|
107
108
|
* - count: "X–Y of Z" text
|
|
108
|
-
* - compact: "Page X of Y" text
|
|
109
|
+
* - compact: "Page X of Y" text. First/last buttons are opt-in (see
|
|
110
|
+
* hasFirstLast).
|
|
109
111
|
* - dots: Dot indicators
|
|
110
112
|
* - input: An editable number box rendering "Page [ n ] / N". The leading
|
|
111
113
|
* noun is controlled by `pageLabel`. First/last double-chevron buttons
|
|
@@ -122,9 +124,11 @@ export interface PaginationProps extends Omit<
|
|
|
122
124
|
pageLabel?: string;
|
|
123
125
|
/**
|
|
124
126
|
* Whether to show first/last («/») double-chevron buttons flanking
|
|
125
|
-
* prev/next.
|
|
126
|
-
*
|
|
127
|
-
*
|
|
127
|
+
* prev/next. Applies to the `input` variant (shown unless false) and the
|
|
128
|
+
* `compact` variant (shown only when true); other variants ignore it.
|
|
129
|
+
* The last button needs a known total — both are omitted when the page count
|
|
130
|
+
* is unknown (cursor/hasMore pagination).
|
|
131
|
+
* @default true for `input`, false for `compact`
|
|
128
132
|
*/
|
|
129
133
|
hasFirstLast?: boolean;
|
|
130
134
|
/**
|
|
@@ -181,6 +185,12 @@ const styles = stylex.create({
|
|
|
181
185
|
alignItems: 'center',
|
|
182
186
|
gap: spacingVars['--spacing-1'],
|
|
183
187
|
},
|
|
188
|
+
compactFirst: {
|
|
189
|
+
marginInlineEnd: `calc(-1 * ${spacingVars['--spacing-1']})`,
|
|
190
|
+
},
|
|
191
|
+
compactLast: {
|
|
192
|
+
marginInlineStart: `calc(-1 * ${spacingVars['--spacing-1']})`,
|
|
193
|
+
},
|
|
184
194
|
ellipsis: {
|
|
185
195
|
display: 'inline-flex',
|
|
186
196
|
alignItems: 'center',
|
|
@@ -369,7 +379,7 @@ export function Pagination({
|
|
|
369
379
|
onPageSizeChange,
|
|
370
380
|
variant = 'pages',
|
|
371
381
|
pageLabel,
|
|
372
|
-
hasFirstLast
|
|
382
|
+
hasFirstLast: hasFirstLastProp,
|
|
373
383
|
step: stepProp = 1,
|
|
374
384
|
siblingCount = 1,
|
|
375
385
|
size = 'md',
|
|
@@ -572,10 +582,14 @@ export function Pagination({
|
|
|
572
582
|
const buttonSize = size === 'sm' ? 'sm' : 'md';
|
|
573
583
|
const isSm = size === 'sm';
|
|
574
584
|
|
|
575
|
-
// First/last buttons
|
|
576
|
-
//
|
|
577
|
-
|
|
578
|
-
|
|
585
|
+
// First/last buttons are on by default in the input variant and opt-in for
|
|
586
|
+
// compact; other variants never render them. They also need a known page
|
|
587
|
+
// count (the last button would have no target otherwise).
|
|
588
|
+
const hasFirstLast =
|
|
589
|
+
variant === 'input'
|
|
590
|
+
? (hasFirstLastProp ?? true)
|
|
591
|
+
: variant === 'compact' && hasFirstLastProp === true;
|
|
592
|
+
const showFirstLast = hasFirstLast && computedTotalPages != null;
|
|
579
593
|
|
|
580
594
|
const renderIndicator = () => {
|
|
581
595
|
switch (variant) {
|
|
@@ -819,6 +833,7 @@ export function Pagination({
|
|
|
819
833
|
onClick={handleFirst}
|
|
820
834
|
isDisabled={isDisabled || !hasPrevious}
|
|
821
835
|
isIconOnly
|
|
836
|
+
xstyle={variant === 'compact' && styles.compactFirst}
|
|
822
837
|
/>
|
|
823
838
|
)}
|
|
824
839
|
|
|
@@ -874,6 +889,7 @@ export function Pagination({
|
|
|
874
889
|
onClick={handleLast}
|
|
875
890
|
isDisabled={isDisabled || !hasNext}
|
|
876
891
|
isIconOnly
|
|
892
|
+
xstyle={variant === 'compact' && styles.compactLast}
|
|
877
893
|
/>
|
|
878
894
|
)}
|
|
879
895
|
</div>
|
|
@@ -280,10 +280,10 @@ describe('Popover', () => {
|
|
|
280
280
|
'utf8',
|
|
281
281
|
);
|
|
282
282
|
expect(popoverSource).toMatch(
|
|
283
|
-
/surfaceViewportFit:[\s\S]*?maxInlineSize: stylex\.firstThatWorks\(\s
|
|
283
|
+
/surfaceViewportFit:[\s\S]*?maxInlineSize: stylex\.firstThatWorks\(\s*`calc\(\$\{layerViewportInset\.maxInlineSize\}\)`/,
|
|
284
284
|
);
|
|
285
285
|
expect(popoverSource).toMatch(
|
|
286
|
-
/surfaceViewportFit:[\s\S]*?maxBlockSize: stylex\.firstThatWorks\(\s
|
|
286
|
+
/surfaceViewportFit:[\s\S]*?maxBlockSize: stylex\.firstThatWorks\(\s*`calc\(\$\{layerViewportInset\.maxBlockSize\}\)`/,
|
|
287
287
|
);
|
|
288
288
|
expect(popoverSource).not.toMatch(/safe-area-inset|calc\(100%/);
|
|
289
289
|
expect(surface?.className).not.toContain(
|
package/src/Popover/Popover.tsx
CHANGED
|
@@ -272,12 +272,12 @@ const styles = stylex.create({
|
|
|
272
272
|
surfaceViewportFit: {
|
|
273
273
|
boxSizing: 'border-box',
|
|
274
274
|
maxInlineSize: stylex.firstThatWorks(
|
|
275
|
-
layerViewportInset.maxInlineSize
|
|
276
|
-
layerViewportInset.maxInlineSizeFallback
|
|
275
|
+
`calc(${layerViewportInset.maxInlineSize})`,
|
|
276
|
+
`calc(${layerViewportInset.maxInlineSizeFallback})`,
|
|
277
277
|
),
|
|
278
278
|
maxBlockSize: stylex.firstThatWorks(
|
|
279
|
-
layerViewportInset.maxBlockSize
|
|
280
|
-
layerViewportInset.maxBlockSizeFallback
|
|
279
|
+
`calc(${layerViewportInset.maxBlockSize})`,
|
|
280
|
+
`calc(${layerViewportInset.maxBlockSizeFallback})`,
|
|
281
281
|
),
|
|
282
282
|
},
|
|
283
283
|
surfaceScrollable: {
|
|
@@ -165,6 +165,91 @@ describe('PowerSearch', () => {
|
|
|
165
165
|
expect(screen.getByRole('combobox')).toHaveFocus();
|
|
166
166
|
});
|
|
167
167
|
|
|
168
|
+
it('clears all added filters when the clear button is clicked', async () => {
|
|
169
|
+
const user = userEvent.setup();
|
|
170
|
+
render(<PowerSearchWrapper config={config} />);
|
|
171
|
+
const input = screen.getByRole('combobox', {name: 'Search'});
|
|
172
|
+
await user.type(input, 'status open');
|
|
173
|
+
await user.click(
|
|
174
|
+
await screen.findByRole('option', {name: 'Status is Open', hidden: true}),
|
|
175
|
+
);
|
|
176
|
+
await user.type(input, 'title login');
|
|
177
|
+
await user.click(
|
|
178
|
+
await screen.findByRole('option', {
|
|
179
|
+
name: 'Title contains "login"',
|
|
180
|
+
hidden: true,
|
|
181
|
+
}),
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
await user.type(input, 'status closed');
|
|
185
|
+
await user.click(
|
|
186
|
+
await screen.findByRole('option', {
|
|
187
|
+
name: 'Status is Closed',
|
|
188
|
+
hidden: true,
|
|
189
|
+
}),
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
expect(screen.getAllByRole('button', {name: /^Remove /})).toHaveLength(3);
|
|
193
|
+
|
|
194
|
+
await user.click(screen.getByRole('button', {name: 'Clear all'}));
|
|
195
|
+
|
|
196
|
+
expect(screen.queryAllByRole('button', {name: /^Remove /})).toHaveLength(0);
|
|
197
|
+
expect(
|
|
198
|
+
screen.queryByRole('button', {name: 'Clear all'}),
|
|
199
|
+
).not.toBeInTheDocument();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('clicking the remove button on a filter removes only that filter', async () => {
|
|
203
|
+
const user = userEvent.setup();
|
|
204
|
+
render(<PowerSearchWrapper config={config} />);
|
|
205
|
+
const input = screen.getByRole('combobox', {name: 'Search'});
|
|
206
|
+
await user.type(input, 'status open');
|
|
207
|
+
await user.click(
|
|
208
|
+
await screen.findByRole('option', {name: 'Status is Open', hidden: true}),
|
|
209
|
+
);
|
|
210
|
+
await user.type(input, 'title login');
|
|
211
|
+
await user.click(
|
|
212
|
+
await screen.findByRole('option', {
|
|
213
|
+
name: 'Title contains "login"',
|
|
214
|
+
hidden: true,
|
|
215
|
+
}),
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
expect(screen.getAllByRole('button', {name: /^Remove /})).toHaveLength(2);
|
|
219
|
+
|
|
220
|
+
await user.click(
|
|
221
|
+
screen.getAllByRole('button', {name: 'Remove Status: is'})[0],
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
expect(screen.getAllByRole('button', {name: /^Remove /})).toHaveLength(1);
|
|
225
|
+
expect(screen.getByText('login')).toBeInTheDocument();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('Backspace on an empty input removes only the last filter', async () => {
|
|
229
|
+
const user = userEvent.setup();
|
|
230
|
+
render(<PowerSearchWrapper config={config} />);
|
|
231
|
+
const input = screen.getByRole('combobox', {name: 'Search'});
|
|
232
|
+
await user.type(input, 'status open');
|
|
233
|
+
await user.click(
|
|
234
|
+
await screen.findByRole('option', {name: 'Status is Open', hidden: true}),
|
|
235
|
+
);
|
|
236
|
+
await user.type(input, 'title login');
|
|
237
|
+
await user.click(
|
|
238
|
+
await screen.findByRole('option', {
|
|
239
|
+
name: 'Title contains "login"',
|
|
240
|
+
hidden: true,
|
|
241
|
+
}),
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
expect(screen.getAllByRole('button', {name: /^Remove /})).toHaveLength(2);
|
|
245
|
+
|
|
246
|
+
await user.click(input);
|
|
247
|
+
await user.keyboard('{Backspace}');
|
|
248
|
+
|
|
249
|
+
expect(screen.getAllByRole('button', {name: /^Remove /})).toHaveLength(1);
|
|
250
|
+
expect(screen.getByText('Open')).toBeInTheDocument();
|
|
251
|
+
});
|
|
252
|
+
|
|
168
253
|
describe('token value truncation (#4759)', () => {
|
|
169
254
|
it('truncates token values by characters, not code units', () => {
|
|
170
255
|
const truncConfig: PowerSearchConfig = {
|
|
@@ -733,8 +733,8 @@ export function PowerSearch({
|
|
|
733
733
|
} else if (change.type === 'remove' && change.item) {
|
|
734
734
|
const auxData = change.item.auxiliaryData as PowerSearchAuxData;
|
|
735
735
|
if (auxData?.filterIndex != null) {
|
|
736
|
-
const newFilters = filters.filter(
|
|
737
|
-
(
|
|
736
|
+
const newFilters = filters.filter((_, i) =>
|
|
737
|
+
_items.some(item => item.auxiliaryData?.filterIndex === i),
|
|
738
738
|
);
|
|
739
739
|
onChange(newFilters, 'remove', auxData.filterIndex);
|
|
740
740
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
import {describe, it} from 'vitest';
|
|
4
|
-
import {screen} from '@testing-library/react';
|
|
3
|
+
import {describe, it, expect} from 'vitest';
|
|
4
|
+
import {render, screen} from '@testing-library/react';
|
|
5
5
|
import {expectFieldInputProps} from '../Field/fieldInputFamily.testing';
|
|
6
6
|
import {describeFieldInputParts} from '../Field/fieldInputFamily.render-testing';
|
|
7
7
|
import {RadioList, type RadioListProps} from './RadioList';
|
|
@@ -22,3 +22,46 @@ describeFieldInputParts('RadioList', {
|
|
|
22
22
|
getControl: () => screen.getByRole('radiogroup'),
|
|
23
23
|
inGroup: false,
|
|
24
24
|
});
|
|
25
|
+
|
|
26
|
+
describe('RadioList FR10 details', () => {
|
|
27
|
+
it("names the radiogroup by its label and then a caller's aria-labelledby", () => {
|
|
28
|
+
render(
|
|
29
|
+
<>
|
|
30
|
+
<span id="caller-name">Billing</span>
|
|
31
|
+
<RadioList
|
|
32
|
+
label="Plan"
|
|
33
|
+
value="a"
|
|
34
|
+
onChange={() => {}}
|
|
35
|
+
aria-labelledby="caller-name">
|
|
36
|
+
<RadioListItem label="A" value="a" />
|
|
37
|
+
</RadioList>
|
|
38
|
+
</>,
|
|
39
|
+
);
|
|
40
|
+
const group = screen.getByRole('radiogroup');
|
|
41
|
+
const ids = group.getAttribute('aria-labelledby')?.split(' ');
|
|
42
|
+
expect(ids).toHaveLength(2);
|
|
43
|
+
expect(document.getElementById(ids?.[0] ?? '')?.textContent).toContain(
|
|
44
|
+
'Plan',
|
|
45
|
+
);
|
|
46
|
+
expect(ids?.[1]).toBe('caller-name');
|
|
47
|
+
expect(screen.getByRole('radiogroup', {name: 'Plan Billing'})).toBe(group);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('puts hidden, inert, and dir on the radiogroup', () => {
|
|
51
|
+
render(
|
|
52
|
+
<RadioList
|
|
53
|
+
label="Plan"
|
|
54
|
+
value="a"
|
|
55
|
+
onChange={() => {}}
|
|
56
|
+
hidden
|
|
57
|
+
inert
|
|
58
|
+
dir="rtl">
|
|
59
|
+
<RadioListItem label="A" value="a" />
|
|
60
|
+
</RadioList>,
|
|
61
|
+
);
|
|
62
|
+
const group = document.querySelector<HTMLElement>('[role="radiogroup"]');
|
|
63
|
+
expect(group).toHaveAttribute('hidden');
|
|
64
|
+
expect(group).toHaveAttribute('inert');
|
|
65
|
+
expect(group).toHaveAttribute('dir', 'rtl');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -524,6 +524,28 @@ describe('RadioList', () => {
|
|
|
524
524
|
});
|
|
525
525
|
|
|
526
526
|
describe('RadioListItem rest forwarding', () => {
|
|
527
|
+
it('forwards align to its Item row unchanged', () => {
|
|
528
|
+
render(
|
|
529
|
+
<RadioList label="Preference" value="" onChange={() => {}}>
|
|
530
|
+
<RadioListItem label="Option A" value="a" data-testid="item-a" />
|
|
531
|
+
<RadioListItem
|
|
532
|
+
label="Option B"
|
|
533
|
+
value="b"
|
|
534
|
+
align="first-line"
|
|
535
|
+
data-testid="item-b"
|
|
536
|
+
/>
|
|
537
|
+
</RadioList>,
|
|
538
|
+
);
|
|
539
|
+
expect(screen.getByTestId('item-a')).toHaveAttribute(
|
|
540
|
+
'data-align',
|
|
541
|
+
'center',
|
|
542
|
+
);
|
|
543
|
+
expect(screen.getByTestId('item-b')).toHaveAttribute(
|
|
544
|
+
'data-align',
|
|
545
|
+
'first-line',
|
|
546
|
+
);
|
|
547
|
+
});
|
|
548
|
+
|
|
527
549
|
it('forwards data-testid, id, and aria-* to the item root element', () => {
|
|
528
550
|
render(
|
|
529
551
|
<RadioList label="Preference" value="" onChange={() => {}}>
|