@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,473 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Drawer.doc.mjs
|
|
5
|
+
* @input Drawer props, panel anatomy, DrawerHeader composition, overlay playground config, and story-aligned examples
|
|
6
|
+
* @output Consumer documentation and examples for Drawer
|
|
7
|
+
* @position CLI and docsite metadata; runnable docsite demos live in packages/cli/assets/templates/blocks/components/Drawer
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
|
|
11
|
+
const anatomy = [
|
|
12
|
+
{
|
|
13
|
+
name: 'Panel',
|
|
14
|
+
required: true,
|
|
15
|
+
description:
|
|
16
|
+
'The root <dialog> element: a full-height surface anchored to the inline start or end edge, flush with three viewport edges (square corners).',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'Content area',
|
|
20
|
+
required: true,
|
|
21
|
+
description:
|
|
22
|
+
'Scrollable container that receives children; compose the header, body, and footer inside it with a Layout, as in Dialog. Inset by --spacing-4 (16px) by default; the padding prop or a theme sets a different container inset.',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'Header',
|
|
26
|
+
required: false,
|
|
27
|
+
description:
|
|
28
|
+
'DrawerHeader, composed in a Layout header slot as DialogHeader is in Dialog: a title row with optional subtitle and start/end content. Pass it onOpenChange to show a close button, as with DialogHeader.',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'Scrim',
|
|
32
|
+
required: false,
|
|
33
|
+
description:
|
|
34
|
+
'Backdrop that dims and blocks the page behind a modal drawer (hasScrim, the default); a non-modal drawer renders none.',
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
|
|
39
|
+
|
|
40
|
+
export const docs = {
|
|
41
|
+
name: 'Drawer',
|
|
42
|
+
displayName: 'Drawer',
|
|
43
|
+
// Keeps the registry route Drawer had as a canary-only Lab component.
|
|
44
|
+
registry: {aliases: ['lab/drawer']},
|
|
45
|
+
group: 'Drawer',
|
|
46
|
+
category: 'Overlay',
|
|
47
|
+
keywords: [
|
|
48
|
+
'drawer',
|
|
49
|
+
'side panel',
|
|
50
|
+
'panel',
|
|
51
|
+
'inspector',
|
|
52
|
+
'detail view',
|
|
53
|
+
'overlay',
|
|
54
|
+
'slide',
|
|
55
|
+
'sidebar',
|
|
56
|
+
'dialog',
|
|
57
|
+
'side drawer',
|
|
58
|
+
'sidesheet',
|
|
59
|
+
],
|
|
60
|
+
// No isInline docs-preview prop (the drawer has no inline containment), so
|
|
61
|
+
// this is the overlay preview: closed on load with an open trigger, knobs
|
|
62
|
+
// live, and opening renders the real top-layer drawer — see
|
|
63
|
+
// ComponentPlaygroundConfig.overlay (#3657).
|
|
64
|
+
playground: {
|
|
65
|
+
overlay: true,
|
|
66
|
+
defaults: {
|
|
67
|
+
isOpen: false,
|
|
68
|
+
label: 'Details',
|
|
69
|
+
children: {
|
|
70
|
+
__element: 'Section',
|
|
71
|
+
props: {padding: 4},
|
|
72
|
+
children: {
|
|
73
|
+
__element: 'VStack',
|
|
74
|
+
props: {gap: 2},
|
|
75
|
+
children: [
|
|
76
|
+
{__element: 'Heading', props: {level: 3}, children: 'Details'},
|
|
77
|
+
{
|
|
78
|
+
__element: 'Text',
|
|
79
|
+
props: {type: 'body'},
|
|
80
|
+
children: 'Adjust the properties below, then open the preview.',
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
theming: {
|
|
88
|
+
container: true,
|
|
89
|
+
targets: [
|
|
90
|
+
{className: 'astryx-drawer', visualProps: ['side']},
|
|
91
|
+
{className: 'astryx-drawer-header'},
|
|
92
|
+
{className: 'astryx-drawer-header-start-content'},
|
|
93
|
+
{className: 'astryx-drawer-header-title-block'},
|
|
94
|
+
{className: 'astryx-drawer-header-end-content'},
|
|
95
|
+
{className: 'astryx-drawer-header-close-icon'},
|
|
96
|
+
],
|
|
97
|
+
derived: [{property: 'padding', expand: 'container'}],
|
|
98
|
+
},
|
|
99
|
+
description:
|
|
100
|
+
"Side panel that floats above page content, using the native <dialog> element. Slides in from the inline start or end edge; full height, never reflows the layout underneath. Like Dialog, it is a container: set padding (or a theme's drawer padding) and a lone Section child or bleed children such as Table and Divider align against that inset. The default inset is --spacing-4 (16px), as in Dialog.",
|
|
101
|
+
props: [
|
|
102
|
+
{
|
|
103
|
+
name: 'isOpen',
|
|
104
|
+
type: 'boolean',
|
|
105
|
+
description:
|
|
106
|
+
'Whether the drawer is open. Fully controlled; pair with onOpenChange.',
|
|
107
|
+
required: true,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'onOpenChange',
|
|
111
|
+
type: '(isOpen: boolean) => void',
|
|
112
|
+
description:
|
|
113
|
+
'Called when the drawer requests an open-state change. Escape and a scrim click call it with false as purpose allows; a DrawerHeader given the same callback calls it from its close button. The caller owns the open state. With sibling drawers open, Escape only closes the last-opened one.',
|
|
114
|
+
required: true,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'label',
|
|
118
|
+
type: 'string',
|
|
119
|
+
description:
|
|
120
|
+
'Accessible label for the drawer. Required; the drawer has no built-in heading to derive a name from.',
|
|
121
|
+
required: true,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'children',
|
|
125
|
+
type: 'ReactNode',
|
|
126
|
+
description:
|
|
127
|
+
'Drawer content, rendered inside a full-height scrollable area. Compose your own header/body/footer; an element with data-autofocus is focused on open. Children stay mounted during the exit animation; keep the last-selected item rendered instead of nulling content on close.',
|
|
128
|
+
required: true,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: 'side',
|
|
132
|
+
type: "'start' | 'end'",
|
|
133
|
+
description:
|
|
134
|
+
"Edge the drawer slides from: 'end' is right in LTR (the inspector convention), 'start' is left. Inline axis only; for a bottom sheet use BottomSheet.",
|
|
135
|
+
default: "'end'",
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'width',
|
|
139
|
+
type: 'number | string',
|
|
140
|
+
description:
|
|
141
|
+
"Desktop width budget. A number is pixels; a string is any CSS length ('50%', '32rem'). Below the 640px mobile breakpoint this remains the maximum while the drawer preserves a 56px reveal of the page behind.",
|
|
142
|
+
default: '400',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: 'experimental',
|
|
146
|
+
type: '{isFullWidthOnMobile?: boolean}',
|
|
147
|
+
stability: 'experimental',
|
|
148
|
+
description:
|
|
149
|
+
'Experimental options: anything in this object may change or be removed in a patch release, and omitting it keeps the stable behavior. isFullWidthOnMobile (default false) covers the full viewport width below the 640px mobile breakpoint instead of preserving the default 56px reveal of the page behind, which makes the drawer read as an overlay, not a navigation.',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'hasScrim',
|
|
153
|
+
type: 'boolean',
|
|
154
|
+
description:
|
|
155
|
+
'Modal scrim behind the drawer. true uses showModal() (top layer, focus trap, scroll lock; clicking the scrim closes unless purpose prevents it; modal only); false uses the manual Popover API for a non-modal top-layer overlay that does NOT trap focus and keeps the page behind interactive.',
|
|
156
|
+
default: 'true',
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'purpose',
|
|
160
|
+
type: "'required' | 'form' | 'info'",
|
|
161
|
+
description:
|
|
162
|
+
'Configures implicit dismissal, matching Dialog. info: Escape and a scrim click close. form: Escape closes, a scrim click does not. required: neither closes (Escape is consumed) and a modal drawer is exposed as an alertdialog, so give its content a way out. A non-modal drawer has no scrim, so form and info behave the same.',
|
|
163
|
+
default: "'info'",
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: 'padding',
|
|
167
|
+
type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10',
|
|
168
|
+
description:
|
|
169
|
+
"Internal padding of the drawer content using the spacing scale, matching Dialog. When omitted, uses the theme default for drawers: --spacing-4 (16px) unless the theme sets padding on drawer. Pass 0 for a full-bleed content area. A lone Section child escapes the padding, bleed children such as Table and Divider compensate against it, and a Layout picks it up for its regions. The content area's block-end edge adds the home-indicator safe area on top in every mode.",
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
usage: {
|
|
173
|
+
anatomy,
|
|
174
|
+
description:
|
|
175
|
+
'A side panel that floats above page content for inspectors and detail views: the "click a table row, see its details" pattern. Unlike a docked panel it overlays the layout instead of reflowing it. Works on desktop and touch: the width budget applies on desktop and the panel preserves a 56px page reveal below 640px without exceeding the width budget. Escape closes the drawer (unless purpose is required) and focus returns to the element that opened it. Entry/exit slide animation respects prefers-reduced-motion. Stacking contract: sibling drawers stack last-opened on top, Escape closes only the topmost, and closing peels innermost-first; render them as siblings, never nested.\n\nLike Dialog, the drawer is a container: its content area is inset by --spacing-4 (16px) by default, by the padding prop, or by a theme\'s padding on drawer. Compose the header, body, and footer the way Dialog does, with a Layout: DrawerHeader in the header slot (it shows a close button when you pass it onOpenChange, like DialogHeader), the body in LayoutContent, and actions in LayoutFooter. The Layout redistributes the inset to those regions so they line up on one content line, and the header is not inset twice. A lone Section child also escapes the inset. Drawer renders no close button of its own, so give every drawer a visible way to close, especially a non-modal one, which has no scrim to click. Put data-autofocus on the control that should receive focus on open.\n\nChoosing a surface: use Dialog for a centered decision or short form, Drawer for full-height side detail that keeps the page in sight, BottomSheet for block-axis sheets on touch, and a docked panel (a layout column) when content should reflow the page instead of floating over it.\n\nTheming: the panel is the single stable target (astryx-drawer, with data-side reflecting side), and the scrim is the panel\'s native ::backdrop. DrawerHeader exposes astryx-drawer-header targets for its row, slots, and close icon.',
|
|
176
|
+
bestPractices: [
|
|
177
|
+
{
|
|
178
|
+
guidance: true,
|
|
179
|
+
description:
|
|
180
|
+
'Use for contextual detail views (row inspectors, entity details) where the user should keep the underlying list in sight.',
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
guidance: true,
|
|
184
|
+
description:
|
|
185
|
+
'Keep the caller as the source of truth: derive isOpen from selection state and clear the selection in onOpenChange.',
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
guidance: true,
|
|
189
|
+
description:
|
|
190
|
+
'Use hasScrim={false} for master-detail flows; non-modal drawers do not trap focus and the page behind stays interactive.',
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
guidance: true,
|
|
194
|
+
description:
|
|
195
|
+
'Keep the last-selected item rendered on close: children stay mounted during the exit animation, so nulling content mid-close blanks the panel while it slides out.',
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
guidance: true,
|
|
199
|
+
description:
|
|
200
|
+
'Give every drawer a visible close action, usually DrawerHeader with onOpenChange; a non-modal drawer has no scrim to click.',
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
guidance: true,
|
|
204
|
+
description:
|
|
205
|
+
'Use purpose="form" when a stray scrim click would discard unsaved input.',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
guidance: false,
|
|
209
|
+
description:
|
|
210
|
+
'Use a Drawer for short confirmations or small forms; use Dialog or AlertDialog instead.',
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
guidance: false,
|
|
214
|
+
description:
|
|
215
|
+
'Reach for a Drawer when the content should push the page aside; a Drawer floats over content, so use a docked panel or layout column instead.',
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
guidance: false,
|
|
219
|
+
description:
|
|
220
|
+
'Use a Drawer as a bottom or top sheet; it is inline-axis only, so use BottomSheet for block-axis sheets.',
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
guidance: false,
|
|
224
|
+
description:
|
|
225
|
+
'Nest a Drawer inside another Drawer; render drawers as siblings; the last-opened stacks on top and Escape closes it first.',
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
},
|
|
229
|
+
// CLI snippets. The docsite renders the paired Drawer blocks in ../../blocks.
|
|
230
|
+
examples: [
|
|
231
|
+
{
|
|
232
|
+
label: 'Basic',
|
|
233
|
+
code: `const [isOpen, setIsOpen] = useState(false);
|
|
234
|
+
<>
|
|
235
|
+
<Button label="Open drawer" onClick={() => setIsOpen(true)} />
|
|
236
|
+
<Drawer
|
|
237
|
+
isOpen={isOpen}
|
|
238
|
+
onOpenChange={setIsOpen}
|
|
239
|
+
label="Details"
|
|
240
|
+
width={360}>
|
|
241
|
+
<Layout
|
|
242
|
+
header={<DrawerHeader title="Details" onOpenChange={setIsOpen} />}
|
|
243
|
+
content={
|
|
244
|
+
<LayoutContent>
|
|
245
|
+
<Text type="body">Close with Escape, the scrim, or the close button.</Text>
|
|
246
|
+
</LayoutContent>
|
|
247
|
+
}
|
|
248
|
+
/>
|
|
249
|
+
</Drawer>
|
|
250
|
+
</>
|
|
251
|
+
// Modal by default: the scrim dims the page and focus is trapped. Escape, a
|
|
252
|
+
// scrim click, or the header's close button closes it, and focus returns to
|
|
253
|
+
// the trigger.`,
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
label: 'Modal or non-modal (hasScrim)',
|
|
257
|
+
code: `const [openModal, setOpenModal] = useState(false);
|
|
258
|
+
const [openPanel, setOpenPanel] = useState(false);
|
|
259
|
+
<>
|
|
260
|
+
{/* Modal (default): the scrim dims the page, focus is trapped, and a
|
|
261
|
+
scrim click closes. */}
|
|
262
|
+
<Drawer isOpen={openModal} onOpenChange={setOpenModal} label="Edit details">
|
|
263
|
+
<EditForm />
|
|
264
|
+
</Drawer>
|
|
265
|
+
{/* Non-modal: no scrim, no focus trap; the page behind stays interactive.
|
|
266
|
+
With no scrim to click, the header's close button is the visible exit. */}
|
|
267
|
+
<Drawer
|
|
268
|
+
isOpen={openPanel}
|
|
269
|
+
onOpenChange={setOpenPanel}
|
|
270
|
+
label="Details"
|
|
271
|
+
hasScrim={false}>
|
|
272
|
+
<Layout
|
|
273
|
+
header={<DrawerHeader title="Details" onOpenChange={setOpenPanel} />}
|
|
274
|
+
content={<LayoutContent><DetailsPanel /></LayoutContent>}
|
|
275
|
+
/>
|
|
276
|
+
</Drawer>
|
|
277
|
+
</>`,
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
label: 'Edit form with footer actions',
|
|
281
|
+
code: `const [isOpen, setIsOpen] = useState(false);
|
|
282
|
+
<Drawer
|
|
283
|
+
isOpen={isOpen}
|
|
284
|
+
onOpenChange={setIsOpen}
|
|
285
|
+
label="Edit host"
|
|
286
|
+
purpose="form">
|
|
287
|
+
<Layout
|
|
288
|
+
header={<DrawerHeader title="Edit host" onOpenChange={setIsOpen} />}
|
|
289
|
+
content={<LayoutContent><HostFields /></LayoutContent>}
|
|
290
|
+
footer={
|
|
291
|
+
<LayoutFooter>
|
|
292
|
+
<HStack gap={2} hAlign="end">
|
|
293
|
+
<Button label="Cancel" variant="secondary" onClick={() => setIsOpen(false)} />
|
|
294
|
+
<Button label="Save" variant="primary" onClick={save} />
|
|
295
|
+
</HStack>
|
|
296
|
+
</LayoutFooter>
|
|
297
|
+
}
|
|
298
|
+
/>
|
|
299
|
+
</Drawer>
|
|
300
|
+
// purpose="form" keeps Escape but ignores scrim clicks, so a stray click
|
|
301
|
+
// outside does not discard edits. The footer stays pinned while the fields
|
|
302
|
+
// scroll.`,
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
label: 'Slide in from the start edge',
|
|
306
|
+
code: `const [isOpen, setIsOpen] = useState(false);
|
|
307
|
+
<Drawer
|
|
308
|
+
isOpen={isOpen}
|
|
309
|
+
onOpenChange={setIsOpen}
|
|
310
|
+
label="Navigation"
|
|
311
|
+
side="start">
|
|
312
|
+
<NavPanel />
|
|
313
|
+
</Drawer>
|
|
314
|
+
// 'start' is left in LTR and mirrors under RTL; 'end' (the default) is the
|
|
315
|
+
// inspector convention.`,
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
label: 'Width budget: pixels or any CSS length',
|
|
319
|
+
code: `const [isOpen, setIsOpen] = useState(false);
|
|
320
|
+
<Drawer
|
|
321
|
+
isOpen={isOpen}
|
|
322
|
+
onOpenChange={setIsOpen}
|
|
323
|
+
label="Details"
|
|
324
|
+
width="50%">
|
|
325
|
+
<DetailsPanel />
|
|
326
|
+
</Drawer>
|
|
327
|
+
// A number is pixels (width={320}); a string is any CSS length ('32rem',
|
|
328
|
+
// '50%'). The budget also caps the drawer on mobile.`,
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
|
|
334
|
+
export const docsZh = {
|
|
335
|
+
usage: {
|
|
336
|
+
anatomy: [
|
|
337
|
+
{
|
|
338
|
+
name: 'Panel',
|
|
339
|
+
required: true,
|
|
340
|
+
description:
|
|
341
|
+
'根 <dialog> 元素:锚定于行内起始或结束边缘的全高表面,与三个视口边缘齐平(直角)。',
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
name: 'Content area',
|
|
345
|
+
required: true,
|
|
346
|
+
description:
|
|
347
|
+
'承载 children 的可滚动容器;像 Dialog 一样在其中用 Layout 组合页眉、正文和页脚。默认带有 --spacing-4(16px)的内边距;padding 属性或主题的 drawer padding 可设置其他容器内边距。',
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
name: 'Header',
|
|
351
|
+
required: false,
|
|
352
|
+
description:
|
|
353
|
+
'DrawerHeader,像 Dialog 中的 DialogHeader 一样放在 Layout 的 header 插槽:包含标题,以及可选的副标题和首尾内容。传入 onOpenChange 即显示关闭按钮,与 DialogHeader 相同。',
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
name: 'Scrim',
|
|
357
|
+
required: false,
|
|
358
|
+
description:
|
|
359
|
+
'模态抽屉(hasScrim,默认开启)背后调暗并阻止页面交互的背景层;非模态抽屉没有。',
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
description:
|
|
363
|
+
'浮在页面内容之上的侧边面板,用于检查器和详情视图——"点击表格行查看详情"的模式。与停靠面板不同,它覆盖在布局之上,不会挤压页面。桌面端按 width 设定宽度,宽度小于 640px 时保留 56px 的底层页面,并且不超过 width 上限。按 Escape 关闭抽屉(purpose 为 required 时除外),焦点返回到打开它的元素。滑入/滑出动画遵循 prefers-reduced-motion。堆叠约定:同级抽屉后开的在上层,Escape 只关闭最上层的,关闭顺序由内向外——请以同级方式渲染,切勿嵌套。\n\n与 Dialog 一样,Drawer 是一个容器:内容区域默认带有 --spacing-4(16px)的内边距,也可以由 padding 属性或主题中 drawer 的 padding 设置。像 Dialog 一样用 Layout 组合页眉、正文和页脚:DrawerHeader 放在 header 插槽(传入 onOpenChange 时显示关闭按钮,与 DialogHeader 相同),正文放在 LayoutContent,操作放在 LayoutFooter。Layout 会把内边距分配给这些区域,使它们对齐在同一条内容线上,页眉也不会被重复缩进。作为唯一子元素的 Section 同样会越出该内边距。Drawer 本身不渲染关闭按钮,所以每个抽屉都要提供可见的关闭方式,非模态抽屉尤其如此,因为它没有可点击的遮罩。在打开时应获得焦点的控件上加 data-autofocus。\n\n如何选择:居中的决定或短表单用 Dialog;保持页面可见的全高侧边详情用 Drawer;触屏上的块轴面板用 BottomSheet;内容应当把页面挤开重排时用停靠面板(布局分栏),而不是浮层。\n\n主题化:面板是唯一的稳定目标(astryx-drawer,data-side 反映 side 值),遮罩是面板的原生 ::backdrop。DrawerHeader 为其标题行、插槽和关闭图标提供 astryx-drawer-header 系列目标。',
|
|
364
|
+
bestPractices: [
|
|
365
|
+
{
|
|
366
|
+
guidance: true,
|
|
367
|
+
description:
|
|
368
|
+
'用于上下文详情视图(行检查器、实体详情),让用户保持对底层列表的可见性。',
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
guidance: true,
|
|
372
|
+
description:
|
|
373
|
+
'让调用方作为唯一数据源:从选中状态派生 isOpen,并在 onOpenChange 中清除选中。',
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
guidance: true,
|
|
377
|
+
description:
|
|
378
|
+
'在主从流程中使用 hasScrim={false}——非模态抽屉不捕获焦点,抽屉后面的页面保持可交互。',
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
guidance: true,
|
|
382
|
+
description:
|
|
383
|
+
'关闭时保留最后选中的内容:退出动画期间子内容仍然挂载,中途置空会让面板在滑出时变为空白。',
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
guidance: true,
|
|
387
|
+
description:
|
|
388
|
+
'为每个抽屉提供可见的关闭操作,通常是带 onOpenChange 的 DrawerHeader;非模态抽屉没有可点击的遮罩。',
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
guidance: true,
|
|
392
|
+
description: '误点遮罩会丢失未保存的输入时,使用 purpose="form"。',
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
guidance: false,
|
|
396
|
+
description:
|
|
397
|
+
'用 Drawer 做简短确认或小表单——请改用 Dialog 或 AlertDialog。',
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
guidance: false,
|
|
401
|
+
description:
|
|
402
|
+
'需要把页面内容挤开时不要用 Drawer——它浮在内容之上,请改用停靠面板或布局分栏。',
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
guidance: false,
|
|
406
|
+
description:
|
|
407
|
+
'不要把 Drawer 当作底部/顶部面板使用——它只支持行内轴,块轴面板请用 BottomSheet。',
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
guidance: false,
|
|
411
|
+
description:
|
|
412
|
+
'在 Drawer 中嵌套另一个 Drawer;应以同级方式渲染——后开的堆叠在上层,Escape 先关闭它。',
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
},
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
|
|
419
|
+
export const docsDense = {
|
|
420
|
+
description:
|
|
421
|
+
'side panel floating over content (native <dialog>): start/end edge, full height, Dialog-like container padding (--spacing-4 by default; padding prop or theme drawer padding)',
|
|
422
|
+
usage: {
|
|
423
|
+
anatomy,
|
|
424
|
+
description:
|
|
425
|
+
"Overlay side panel for inspectors and detail views; floats over content, never reflows it. width = desktop budget; 56px page reveal below 640px, capped by width. Escape closes topmost (not when purpose=required); focus restores to the opener. Siblings stack last-opened on top; never nest. Slide animation respects prefers-reduced-motion. Dialog-like container: content area inset = --spacing-4 (16px) by default, or the padding prop / a theme's drawer padding (padding={0} = full bleed). Compose like Dialog: Layout with DrawerHeader in the header slot (close button only when given onOpenChange), LayoutContent, LayoutFooter; Layout redistributes the inset so regions line up and the header is not inset twice; a lone Section escapes the inset. No built-in close button, so every drawer needs a visible exit; data-autofocus picks the focus target. purpose matches Dialog: info = Escape + scrim click, form = Escape only, required = neither (modal → alertdialog). Choose: Dialog for centered decisions/short forms, Drawer for full-height side detail, BottomSheet for block-axis sheets, docked layout column to reflow instead of float. Theming: single target astryx-drawer (data-side); scrim is its ::backdrop; DrawerHeader has astryx-drawer-header targets.",
|
|
426
|
+
bestPractices: [
|
|
427
|
+
{
|
|
428
|
+
guidance: true,
|
|
429
|
+
description: 'Use for row inspectors and entity detail views.',
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
guidance: true,
|
|
433
|
+
description:
|
|
434
|
+
'Derive isOpen from selection state; clear it in onOpenChange.',
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
guidance: true,
|
|
438
|
+
description:
|
|
439
|
+
'Use hasScrim={false} for non-modal master-detail flows (no focus trap, page stays interactive).',
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
guidance: true,
|
|
443
|
+
description:
|
|
444
|
+
'Keep last-selected content rendered on close (children stay mounted during exit).',
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
guidance: true,
|
|
448
|
+
description:
|
|
449
|
+
'Give every drawer a visible close action (DrawerHeader + onOpenChange); non-modal has no scrim.',
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
guidance: true,
|
|
453
|
+
description:
|
|
454
|
+
'Use purpose="form" when a stray scrim click would lose input.',
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
guidance: false,
|
|
458
|
+
description:
|
|
459
|
+
'Use for confirmations or small forms; use Dialog instead.',
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
guidance: false,
|
|
463
|
+
description:
|
|
464
|
+
'Use when content should push the page aside (it floats over) or as a bottom sheet (use BottomSheet).',
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
guidance: false,
|
|
468
|
+
description:
|
|
469
|
+
'Nest Drawers: render as siblings; Escape closes the last-opened first.',
|
|
470
|
+
},
|
|
471
|
+
],
|
|
472
|
+
},
|
|
473
|
+
};
|