@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
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
/** @vitest-environment jsdom */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file Toolbar.a11y.test.tsx
|
|
6
|
+
* @input TOOLBAR_PATTERN bound to Toolbar's representative states
|
|
7
|
+
* @output jsdom-lane proof of the DOM expectations and an honest "unrun" report for the browser layers
|
|
8
|
+
* @position Binding test for Toolbar (the Chromium spec covers the rest)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {cleanup, render, screen} from '@testing-library/react';
|
|
12
|
+
import {describe, expect, it} from 'vitest';
|
|
13
|
+
import {
|
|
14
|
+
TOOLBAR_PATTERN,
|
|
15
|
+
checkAccessibilitySpec,
|
|
16
|
+
createJsdomHarness,
|
|
17
|
+
expectAccessibilitySpec,
|
|
18
|
+
summarize,
|
|
19
|
+
type BindingResult,
|
|
20
|
+
} from '@astryxdesign/a11y-spec';
|
|
21
|
+
import {renderToolbarState} from './Toolbar.a11y.renders';
|
|
22
|
+
import {
|
|
23
|
+
TOOLBAR_BINDING_STATES,
|
|
24
|
+
TOOLBAR_EXCLUSIONS,
|
|
25
|
+
type ToolbarBindingState,
|
|
26
|
+
} from './Toolbar.a11y.states';
|
|
27
|
+
|
|
28
|
+
function toolbarFor(state: ToolbarBindingState): HTMLElement {
|
|
29
|
+
return screen.getByRole('toolbar', {name: state.label});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function relatedFor(
|
|
33
|
+
state: ToolbarBindingState,
|
|
34
|
+
): Readonly<Record<string, Element>> {
|
|
35
|
+
const related: Record<string, Element> = {
|
|
36
|
+
before: screen.getByRole('button', {name: 'Before the toolbar'}),
|
|
37
|
+
after: screen.getByRole('button', {name: 'After the toolbar'}),
|
|
38
|
+
};
|
|
39
|
+
for (const [relation, name] of Object.entries(state.controls)) {
|
|
40
|
+
related[relation] = screen.getByRole('button', {name});
|
|
41
|
+
}
|
|
42
|
+
return related;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function checkState(state: ToolbarBindingState): Promise<BindingResult> {
|
|
46
|
+
return checkAccessibilitySpec({
|
|
47
|
+
spec: TOOLBAR_PATTERN,
|
|
48
|
+
binding: 'Toolbar',
|
|
49
|
+
state: state.id,
|
|
50
|
+
facts: state.facts,
|
|
51
|
+
mount: async () => {
|
|
52
|
+
render(renderToolbarState(state));
|
|
53
|
+
return createJsdomHarness({
|
|
54
|
+
subject: toolbarFor(state),
|
|
55
|
+
related: relatedFor(state),
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
unmount: cleanup,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
describe('Toolbar — toolbar pattern, jsdom lane', () => {
|
|
63
|
+
it.each(
|
|
64
|
+
TOOLBAR_BINDING_STATES.map(
|
|
65
|
+
state => [state.id, state.summary, state] as const,
|
|
66
|
+
),
|
|
67
|
+
)('%s — %s', async (_id, _summary, state) => {
|
|
68
|
+
await expectAccessibilitySpec({
|
|
69
|
+
spec: TOOLBAR_PATTERN,
|
|
70
|
+
binding: 'Toolbar',
|
|
71
|
+
state: state.id,
|
|
72
|
+
facts: state.facts,
|
|
73
|
+
render: () => {
|
|
74
|
+
render(renderToolbarState(state));
|
|
75
|
+
},
|
|
76
|
+
subject: () => toolbarFor(state),
|
|
77
|
+
related: () => relatedFor(state),
|
|
78
|
+
cleanup,
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('runs the DOM layer and reports the browser-owned outcomes as unrun', async () => {
|
|
83
|
+
const results: BindingResult[] = [];
|
|
84
|
+
for (const state of TOOLBAR_BINDING_STATES) {
|
|
85
|
+
results.push(await checkState(state));
|
|
86
|
+
}
|
|
87
|
+
const report = summarize(TOOLBAR_PATTERN, results);
|
|
88
|
+
expect(report.counts.pass).toBeGreaterThan(0);
|
|
89
|
+
expect(report.unrunLayers).toEqual(['accessibility-tree', 'real-browser']);
|
|
90
|
+
expect(report.counts.unexpectedPass).toBe(0);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('toolbar binding inventory', () => {
|
|
95
|
+
it('gives every representative state a distinct checked-in story', () => {
|
|
96
|
+
const stories = TOOLBAR_BINDING_STATES.map(state => state.storyId);
|
|
97
|
+
expect(new Set(stories).size).toBe(stories.length);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('keeps control semantics, editing and popover keys, the three-lane layout, and outer chrome explicit', () => {
|
|
101
|
+
expect(TOOLBAR_EXCLUSIONS.map(row => row.id)).toEqual([
|
|
102
|
+
'control-semantics',
|
|
103
|
+
'caret-guard-and-nested-popovers',
|
|
104
|
+
'three-lane-layout',
|
|
105
|
+
'outer-chrome',
|
|
106
|
+
]);
|
|
107
|
+
for (const exclusion of TOOLBAR_EXCLUSIONS) {
|
|
108
|
+
expect(exclusion.owner.length, exclusion.id).toBeGreaterThan(20);
|
|
109
|
+
expect(exclusion.reason.length, exclusion.id).toBeGreaterThan(80);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('renders the toolbar and every control relation it names for every state', () => {
|
|
114
|
+
for (const state of TOOLBAR_BINDING_STATES) {
|
|
115
|
+
render(renderToolbarState(state));
|
|
116
|
+
const toolbar = toolbarFor(state);
|
|
117
|
+
for (const name of Object.values(state.controls)) {
|
|
118
|
+
expect(
|
|
119
|
+
toolbar.contains(screen.getByRole('button', {name})),
|
|
120
|
+
`${state.id}: ${name}`,
|
|
121
|
+
).toBe(true);
|
|
122
|
+
}
|
|
123
|
+
cleanup();
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
@@ -183,6 +183,37 @@ describe('Tooltip', () => {
|
|
|
183
183
|
});
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
+
describe('icon-only trigger', () => {
|
|
187
|
+
// A rendered icon is an SVGElement, and ShowPopoverOptions.source is
|
|
188
|
+
// declared as an HTMLElement. Handing the icon to showPopover throws
|
|
189
|
+
// during dictionary conversion, before the popover opens, so the hint
|
|
190
|
+
// never appeared. (#7226)
|
|
191
|
+
it('opens an icon trigger without passing an SVGElement as the source', async () => {
|
|
192
|
+
const showSpy = vi.mocked(HTMLElement.prototype.showPopover);
|
|
193
|
+
showSpy.mockClear();
|
|
194
|
+
|
|
195
|
+
render(
|
|
196
|
+
<Tooltip content="Shared memory" isDefaultOpen>
|
|
197
|
+
<svg data-testid="icon" aria-hidden="true" />
|
|
198
|
+
</Tooltip>,
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
await waitFor(() => {
|
|
202
|
+
expect(showSpy).toHaveBeenCalled();
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const [options] = showSpy.mock.calls[0];
|
|
206
|
+
// Compared as a boolean on purpose: a plain `toBeUndefined` failure makes
|
|
207
|
+
// the diff printer walk the SVGElement, which it cannot inspect.
|
|
208
|
+
expect(options?.source === undefined).toBe(true);
|
|
209
|
+
|
|
210
|
+
// The icon is still the trigger the ARIA tooltip pattern is wired to.
|
|
211
|
+
expect(screen.getByTestId('icon').getAttribute('aria-describedby')).toBe(
|
|
212
|
+
screen.getByRole('tooltip', {hidden: true}).id,
|
|
213
|
+
);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
186
217
|
describe('WCAG 1.4.13 — content on hover or focus', () => {
|
|
187
218
|
it('dismisses on Escape while visible (dismissible)', async () => {
|
|
188
219
|
const onOpenChange = vi.fn();
|
|
@@ -147,6 +147,19 @@ describe('useTooltip — show delay', () => {
|
|
|
147
147
|
|
|
148
148
|
expect(onShow).not.toHaveBeenCalled();
|
|
149
149
|
});
|
|
150
|
+
|
|
151
|
+
it('drops a pending show when isEnabled turns false before the delay elapses', () => {
|
|
152
|
+
const onShow = vi.fn();
|
|
153
|
+
const {rerender} = render(<Harness onShow={onShow} />);
|
|
154
|
+
|
|
155
|
+
fireEvent.mouseEnter(trigger());
|
|
156
|
+
tick(100);
|
|
157
|
+
rerender(<Harness isEnabled={false} onShow={onShow} />);
|
|
158
|
+
tick(1000);
|
|
159
|
+
|
|
160
|
+
expect(onShow).not.toHaveBeenCalled();
|
|
161
|
+
expect(tooltipElement().matches(':popover-open')).toBe(false);
|
|
162
|
+
});
|
|
150
163
|
});
|
|
151
164
|
|
|
152
165
|
describe('useTooltip — touch suppression', () => {
|
|
@@ -352,6 +352,17 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
352
352
|
}, delay);
|
|
353
353
|
}, [isEnabled, isOpen, clearTimeouts, showLayer, delay]);
|
|
354
354
|
|
|
355
|
+
// A show scheduled while the triggers were enabled must not outlive them:
|
|
356
|
+
// disabling also detaches the leave listener that would have cancelled it,
|
|
357
|
+
// so the timer would open a tooltip that nothing ever closes. Only the
|
|
358
|
+
// pending show is dropped; a pending hide still runs.
|
|
359
|
+
useEffect(() => {
|
|
360
|
+
if (!isEnabled && showTimeoutRef.current) {
|
|
361
|
+
clearTimeout(showTimeoutRef.current);
|
|
362
|
+
showTimeoutRef.current = null;
|
|
363
|
+
}
|
|
364
|
+
}, [isEnabled]);
|
|
365
|
+
|
|
355
366
|
// Schedule hide with delay (suppressed when isOpen is true).
|
|
356
367
|
// A small hover bridge (when hideDelay is 0) lets the pointer travel from the
|
|
357
368
|
// trigger onto the tooltip surface without the tooltip vanishing — required
|
|
@@ -769,6 +769,28 @@ describe('TopNavMegaMenu — drawer mode', () => {
|
|
|
769
769
|
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
770
770
|
});
|
|
771
771
|
|
|
772
|
+
it('clips the drawer section only while it is collapsed', async () => {
|
|
773
|
+
// The ring paints outside the item, so a permanent clip would cut it off.
|
|
774
|
+
const user = userEvent.setup();
|
|
775
|
+
render(
|
|
776
|
+
<TopNavRenderContext value="drawer">
|
|
777
|
+
<TopNavMegaMenu
|
|
778
|
+
label="Products"
|
|
779
|
+
items={<TopNavMegaMenuItem title="Analytics" href="/analytics" />}
|
|
780
|
+
/>
|
|
781
|
+
</TopNavRenderContext>,
|
|
782
|
+
);
|
|
783
|
+
const trigger = screen.getByRole('button', {name: 'Products'});
|
|
784
|
+
const section = document.getElementById(
|
|
785
|
+
trigger.getAttribute('aria-controls') ?? '',
|
|
786
|
+
)!;
|
|
787
|
+
expect(getComputedStyle(section).overflow).toBe('hidden');
|
|
788
|
+
expect(getComputedStyle(section.firstElementChild!).overflow).toBe('');
|
|
789
|
+
|
|
790
|
+
await user.click(trigger);
|
|
791
|
+
expect(getComputedStyle(section).overflow).toBe('visible');
|
|
792
|
+
});
|
|
793
|
+
|
|
772
794
|
it('renders featured content when expanded', async () => {
|
|
773
795
|
const user = userEvent.setup();
|
|
774
796
|
|
|
@@ -229,18 +229,22 @@ const styles = stylex.create({
|
|
|
229
229
|
drawerChevronExpanded: {
|
|
230
230
|
transform: 'rotate(180deg)',
|
|
231
231
|
},
|
|
232
|
+
// Clips only while collapsed or animating; see TopNavMenu drawerStyles.items.
|
|
232
233
|
drawerItems: {
|
|
233
234
|
display: 'grid',
|
|
234
235
|
gridTemplateRows: '0fr',
|
|
235
|
-
|
|
236
|
-
|
|
236
|
+
overflow: 'hidden',
|
|
237
|
+
transitionProperty: 'grid-template-rows, overflow',
|
|
238
|
+
transitionBehavior: 'allow-discrete',
|
|
239
|
+
transitionDuration: `${durationVars['--duration-medium']}, 0s`,
|
|
237
240
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
238
241
|
},
|
|
239
242
|
drawerItemsExpanded: {
|
|
240
243
|
gridTemplateRows: '1fr',
|
|
244
|
+
overflow: 'visible',
|
|
245
|
+
transitionDelay: `0s, ${durationVars['--duration-medium']}`,
|
|
241
246
|
},
|
|
242
247
|
drawerItemsInner: {
|
|
243
|
-
overflow: 'hidden',
|
|
244
248
|
minHeight: 0,
|
|
245
249
|
},
|
|
246
250
|
|
|
@@ -241,6 +241,25 @@ describe('TopNavMenu — drawer focus ring', () => {
|
|
|
241
241
|
);
|
|
242
242
|
expectSharedFocusRing(screen.getByRole('link', {name: /Analytics/}));
|
|
243
243
|
});
|
|
244
|
+
|
|
245
|
+
it('clips the drawer section only while it is collapsed', async () => {
|
|
246
|
+
// The ring paints outside the item, so a permanent clip would cut it off.
|
|
247
|
+
const user = userEvent.setup();
|
|
248
|
+
render(
|
|
249
|
+
<TopNavRenderContext value="drawer">
|
|
250
|
+
<TopNavMenu label="Products" items={mockItems} />
|
|
251
|
+
</TopNavRenderContext>,
|
|
252
|
+
);
|
|
253
|
+
const trigger = screen.getByRole('button', {name: /Products/});
|
|
254
|
+
const section = document.getElementById(
|
|
255
|
+
trigger.getAttribute('aria-controls') ?? '',
|
|
256
|
+
)!;
|
|
257
|
+
expect(getComputedStyle(section).overflow).toBe('hidden');
|
|
258
|
+
expect(getComputedStyle(section.firstElementChild!).overflow).toBe('');
|
|
259
|
+
|
|
260
|
+
await user.click(trigger);
|
|
261
|
+
expect(getComputedStyle(section).overflow).toBe('visible');
|
|
262
|
+
});
|
|
244
263
|
});
|
|
245
264
|
|
|
246
265
|
describe('TopNavMenu pass-through props', () => {
|
|
@@ -194,18 +194,26 @@ const drawerStyles = stylex.create({
|
|
|
194
194
|
chevronExpanded: {
|
|
195
195
|
transform: 'rotate(180deg)',
|
|
196
196
|
},
|
|
197
|
+
// The section clips its items only for the 0fr collapse animation: a
|
|
198
|
+
// permanent clip cuts off the focus ring, which paints outside the item.
|
|
199
|
+
// `overflow` is discrete, so it rides the transition with `allow-discrete`
|
|
200
|
+
// and switches to `visible` only after the open has finished. Collapsing
|
|
201
|
+
// clips again at once.
|
|
197
202
|
items: {
|
|
198
203
|
display: 'grid',
|
|
199
204
|
gridTemplateRows: '0fr',
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
overflow: 'hidden',
|
|
206
|
+
transitionProperty: 'grid-template-rows, overflow',
|
|
207
|
+
transitionBehavior: 'allow-discrete',
|
|
208
|
+
transitionDuration: `${durationVars['--duration-medium']}, 0s`,
|
|
202
209
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
203
210
|
},
|
|
204
211
|
itemsExpanded: {
|
|
205
212
|
gridTemplateRows: '1fr',
|
|
213
|
+
overflow: 'visible',
|
|
214
|
+
transitionDelay: `0s, ${durationVars['--duration-medium']}`,
|
|
206
215
|
},
|
|
207
216
|
itemsInner: {
|
|
208
|
-
overflow: 'hidden',
|
|
209
217
|
minHeight: 0,
|
|
210
218
|
},
|
|
211
219
|
item: {
|
|
@@ -89,6 +89,7 @@ export const docs = {
|
|
|
89
89
|
{name: '--tree-list-indent', description: 'Per-level indentation step. Each nesting level indents its rows by this distance, and the guide lines follow it so they stay aligned. Set it on the `tree-list` target to retune the metric (e.g. `var(--spacing-5)` for a wider indent).', default: 'var(--spacing-4)'},
|
|
90
90
|
{name: '--tree-list-row-gap', description: 'Vertical gap between adjacent rows. Default `2px` (var(--spacing-0-5)) gives a subtle separation; set it on the `tree-list` target to widen or close the gap. The connector guides span the gap automatically (the line stays continuous) and do not overhang the last row, so no guide-height tuning is needed.', default: 'var(--spacing-0-5)'},
|
|
91
91
|
{name: '--_tree-indent', description: 'Distance one row is indented, computed per row from --tree-list-indent and the row depth. Set --tree-list-indent to retune indentation; this is the resolved value.', default: '0px', private: true},
|
|
92
|
+
{name: '--_tree-focus-z', description: 'Stacking order of a row while its treeitem has keyboard focus, published by each treeitem so its focused row paints above the guide lines. Not a theming lever.', default: 'auto', private: true},
|
|
92
93
|
],
|
|
93
94
|
},
|
|
94
95
|
components: [
|
|
@@ -96,14 +96,15 @@ Supporting one does not justify omitting another from the durable contract.
|
|
|
96
96
|
|
|
97
97
|
## Behavioral and layout contract
|
|
98
98
|
|
|
99
|
-
| ID | Invariant
|
|
100
|
-
| --- |
|
|
101
|
-
| FR1 | The current render contains one Tree list, one Item and Item label per rendered node, optional Header, Chevron, Item description, Start content, End content, and Guide parts, and delegated Chevron glyphs.
|
|
102
|
-
| FR2 | Tree list, Item, Chevron, Item label, and Guide carry the five current `tree-list*` targets documented below.
|
|
103
|
-
| FR3 | Chevron glyph delegates to Icon's `icon` target. Header, Start content, and End content are consumer-owned and have no TreeList target.
|
|
104
|
-
| FR4 | Item description is a stable library-rendered part below Item label and currently has no public target. It does not inherit through `tree-list-item-label`; both spans are siblings inside the row content.
|
|
105
|
-
| FR5 | `TreeListItemData` MUST admit `className`, `style`, and `xstyle` as one per-item styling seam. Every supplied value MUST compose on the same Item row box; an implementation MUST NOT treat current support for only one mechanism as authority to exclude the other two.
|
|
106
|
-
| FR6 | The Item row box is the logical element that paints the row, owns its hover state, and contains Start content, Item label and description, and End content. The styling seam MUST NOT move to the semantic `<li>` or another element without a compatibility decision.
|
|
99
|
+
| ID | Invariant | Basis | Contract state |
|
|
100
|
+
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
101
|
+
| FR1 | The current render contains one Tree list, one Item and Item label per rendered node, optional Header, Chevron, Item description, Start content, End content, and Guide parts, and delegated Chevron glyphs. | Current source, docs, and tests | Current behavior |
|
|
102
|
+
| FR2 | Tree list, Item, Chevron, Item label, and Guide carry the five current `tree-list*` targets documented below. | Current source and target docs | Current behavior |
|
|
103
|
+
| FR3 | Chevron glyph delegates to Icon's `icon` target. Header, Start content, and End content are consumer-owned and have no TreeList target. | Current source and component docs | Current ownership |
|
|
104
|
+
| FR4 | Item description is a stable library-rendered part below Item label and currently has no public target. It does not inherit through `tree-list-item-label`; both spans are siblings inside the row content. | Current source and target docs | Current reachability gap; no new target is accepted |
|
|
105
|
+
| FR5 | `TreeListItemData` MUST admit `className`, `style`, and `xstyle` as one per-item styling seam. Every supplied value MUST compose on the same Item row box; an implementation MUST NOT treat current support for only one mechanism as authority to exclude the other two. | Owner decision; `architecture:public-component-api` INV5–INV6; `spec:AST-002/DEC-1` | Settled intent; implementation may be staged |
|
|
106
|
+
| FR6 | The Item row box is the logical element that paints the row, owns its hover state, and contains Start content, Item label and description, and End content. The styling seam MUST NOT move to the semantic `<li>` or another element without a compatibility decision. | Owner decision and the caller-owned per-row interaction boundary | Settled intent |
|
|
107
|
+
| FR7 | A click on an Item row outside its Item label performs the row's action: an Item with `onClick` runs it; otherwise an Item with children toggles; otherwise an Item whose only action is its link follows that link as Enter does, with modified and middle clicks following the shared enlarged-surface rule in `family:navigation-destinations`. The Chevron and controls in Start content and End content keep their own activation, and a disabled Item does nothing. | Owner decision; `family:navigation-destinations` | Settled intent; implementation may be staged |
|
|
107
108
|
|
|
108
109
|
### Allowed variation
|
|
109
110
|
|
|
@@ -183,6 +184,16 @@ structure. Its current lack of a target is a reachability gap, not a decision
|
|
|
183
184
|
that it must remain unthemeable. Header, Start content, and End content remain
|
|
184
185
|
caller-owned even though TreeList positions their slot wrappers.
|
|
185
186
|
|
|
187
|
+
### Design decisions
|
|
188
|
+
|
|
189
|
+
<!-- design-decisions:v1 -->
|
|
190
|
+
|
|
191
|
+
| ID | Decision | Intent or reason | Applies to | Allowed variation |
|
|
192
|
+
| --- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
193
|
+
| DD1 | Every Item spans the full width of the tree list at any depth; its nesting indent sits inside the row, ahead of its content. | Hover, pressed, and selected fills line up across depths, so the tree reads as one list of equal rows while labels keep their per-level alignment. | Item at every depth, at rest and through hover, pressed, selected, disabled, and focus | Themes set the indent step with `--tree-list-indent` and may restyle the row's fill, radius, and padding; row padding adds to the indent instead of replacing it. |
|
|
194
|
+
| DD2 | A nested Item's indent area is part of the row's painted target: it shows the row's hover and press feedback. | The whole painted row reads as one target, matching where a click acts (FR7), so no part of a row lights up apart from the rest. | Nested Items that act on click | Themes may restyle the feedback through the `tree-list-item` target. |
|
|
195
|
+
| DD3 | Guides paint above row fills, and an Item whose focus ring is showing paints above the guides. | Hierarchy lines stay continuous through hover and selection, and the focus indicator is never cut; on a focused row that is also filled, the ring takes precedence and the fill covers the guides at that row. | Guide and Item in `lineGuides` trees | Themes may recolor or hide guides through the `tree-list-guide` target. |
|
|
196
|
+
|
|
186
197
|
### Theming anatomy
|
|
187
198
|
|
|
188
199
|
<!-- anatomy-theming:v1 -->
|
|
@@ -242,15 +253,16 @@ authorize or prohibit a future target.
|
|
|
242
253
|
|
|
243
254
|
## Verification map
|
|
244
255
|
|
|
245
|
-
| Contract | Verification | Representative states
|
|
246
|
-
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
247
|
-
| FR1 | `TreeList.test.tsx` rendering, hierarchy, slot, and accessibility suites plus source inspection | Flat, nested, described, headed, and slotted items
|
|
248
|
-
| FR2 | `TreeList.test.tsx` and `themingTargets.test.ts` | Five local targets and their documented states
|
|
249
|
-
| FR3 | Source inspection plus Icon public target metadata | Expandable rows and caller-provided slots
|
|
250
|
-
| FR4 | `TreeList.test.tsx` description rendering test and source inspection | Item with description
|
|
251
|
-
| AR1 | Tree View accessibility contract (`internal/a11y-spec`, pending) bound to TreeList, in jsdom and Chromium; `TreeList.test.tsx` row-naming cases ("names a parent row by its label alone, not the chevron toggle", "names a plain row by its label and describes it with its description", "names and describes link and action rows themselves, not only their inner control", "keeps start and end content, including controls, out of the row name", "typeahead matches the label, not the description or start content") and `TreeListRowNames.a11y.chromium.spec.ts` for the browser-computed names; `TreeList.test.tsx` structural ARIA cases ("sets aria-level, aria-posinset, and aria-setsize at the top level", "sets aria-level/posinset/setsize correctly at deeper levels", "sets aria-level across three depths"); `TreeList.test.tsx` and `useTreeFocus.test.tsx` keyboard suites | Flat and nested trees; expanded/collapsed; selected/unselected; LTR and RTL; typeahead
|
|
252
|
-
| FR5, FR6, ORD1 | Focused `TreeList.test.tsx` row-identity and styling-composition coverage, required with implementation | One input at a time; all three together; sibling rows
|
|
253
|
-
|
|
|
256
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
257
|
+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
|
|
258
|
+
| FR1 | `TreeList.test.tsx` rendering, hierarchy, slot, and accessibility suites plus source inspection | Flat, nested, described, headed, and slotted items | Removing asserted Tree list, Header, Item, Chevron, Item label, Item description, Start content, End content, or Guide behavior fails existing role, content, hierarchy, or state assertions; Chevron glyph presence remains source-inspected only. | `audit:TreeList/anatomy` |
|
|
259
|
+
| FR2 | `TreeList.test.tsx` and `themingTargets.test.ts` | Five local targets and their documented states | Removing or moving any current local target fails focused class assertions or the global inventory. | `audit:TreeList/theming` |
|
|
260
|
+
| FR3 | Source inspection plus Icon public target metadata | Expandable rows and caller-provided slots | Existing focused tests do not assert the composed Icon instance; changing glyph or slot ownership requires this map and the relevant owner metadata to change. | `audit:TreeList/theming` |
|
|
261
|
+
| FR4 | `TreeList.test.tsx` description rendering test and source inspection | Item with description | Removing description fails content coverage; adding a target requires an explicit map update. | `audit:TreeList/anatomy` |
|
|
262
|
+
| AR1 | Tree View accessibility contract (`internal/a11y-spec`, pending) bound to TreeList, in jsdom and Chromium; `TreeList.test.tsx` row-naming cases ("names a parent row by its label alone, not the chevron toggle", "names a plain row by its label and describes it with its description", "names and describes link and action rows themselves, not only their inner control", "keeps start and end content, including controls, out of the row name", "typeahead matches the label, not the description or start content") and `TreeListRowNames.a11y.chromium.spec.ts` for the browser-computed names; `TreeList.test.tsx` structural ARIA cases ("sets aria-level, aria-posinset, and aria-setsize at the top level", "sets aria-level/posinset/setsize correctly at deeper levels", "sets aria-level across three depths"); `TreeList.test.tsx` and `useTreeFocus.test.tsx` keyboard suites | Flat and nested trees; expanded/collapsed; selected/unselected; LTR and RTL; typeahead | A row loses its role, label name, state or position, two rows hold a Tab stop, an arrow key stops moving or stops mirroring under RTL, Home/End or typeahead stop working, or the tree claims multi-select | `audit:TreeList/accessibility` |
|
|
263
|
+
| FR5, FR6, ORD1 | Focused `TreeList.test.tsx` row-identity and styling-composition coverage, required with implementation | One input at a time; all three together; sibling rows | Dropping any mechanism, applying mechanisms to different elements, targeting the `<li>`, changing the merge order, or styling a sibling row fails. | `audit:TreeList/api` |
|
|
264
|
+
| FR7 | Focused `TreeList.test.tsx` row-click coverage, required with implementation | Action, parent, link, and disabled rows; clicks in the indent and padding, on the Chevron, and on Start and End content controls; plain, modified, and middle clicks | A click outside the label does nothing or runs the wrong action, a link-row click reaches ancestors twice, the Chevron or a Start or End content control activates the row, or a disabled row acts. | `audit:TreeList/behavior` |
|
|
265
|
+
| Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and five current local targets | Missing, extra, duplicated, prefixed, or stale mappings fail repository validation. | `audit:TreeList/theming` |
|
|
254
266
|
|
|
255
267
|
Focused target-placement assertions cover all five local targets. Runtime support
|
|
256
268
|
and mutation-sensitive coverage for the item styling seam may land separately,
|