@astryxdesign/core 0.7.5-canary.fccd771 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +211 -10
- package/README.md +15 -12
- package/dist/AlertDialog/AlertDialog.js +1 -1
- package/dist/AppShell/AppShell.d.ts +0 -22
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +155 -1
- package/dist/Avatar/AvatarStatusDot.js +2 -2
- package/dist/Badge/Badge.d.ts.map +1 -1
- package/dist/Badge/Badge.js +18 -2
- package/dist/Banner/Banner.d.ts +1 -0
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +64 -9
- package/dist/BottomSheet/BottomSheet.d.ts +53 -5
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +435 -198
- package/dist/BottomSheet/BottomSheetHostContext.d.ts +8 -0
- package/dist/BottomSheet/BottomSheetHostContext.d.ts.map +1 -0
- package/dist/BottomSheet/BottomSheetHostContext.js +35 -0
- package/dist/BottomSheet/BottomSheetPanel.d.ts +9 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +77 -23
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts +53 -14
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +229 -27
- package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +6 -0
- package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -1
- package/dist/BottomSheet/bottomSheetEscape.d.ts +3 -0
- package/dist/BottomSheet/bottomSheetEscape.d.ts.map +1 -0
- package/dist/BottomSheet/bottomSheetEscape.js +20 -0
- package/dist/BottomSheet/bottomSheetStack.d.ts +262 -0
- package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -0
- package/dist/BottomSheet/bottomSheetStack.js +1675 -0
- package/dist/BottomSheet/useSheetGestures.d.ts +19 -3
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +43 -14
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +36 -3
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +18 -7
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +25 -32
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +55 -16
- package/dist/Chat/ChatMessageMetadata.js +2 -2
- package/dist/Chat/ChatPastedTextToken.d.ts.map +1 -1
- package/dist/Chat/ChatPastedTextToken.js +7 -6
- package/dist/Chat/ChatToolCalls.js +4 -4
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +10 -6
- package/dist/CodeBlock/CodeBlock.d.ts +25 -2
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +58 -19
- package/dist/CodeBlock/grammar.d.ts +134 -0
- package/dist/CodeBlock/grammar.d.ts.map +1 -0
- package/dist/CodeBlock/grammar.js +219 -0
- package/dist/CodeBlock/index.d.ts +2 -0
- package/dist/CodeBlock/index.d.ts.map +1 -1
- package/dist/CodeBlock/index.js +1 -0
- package/dist/CodeBlock/languages/dockerfile.d.ts +3 -0
- package/dist/CodeBlock/languages/dockerfile.d.ts.map +1 -0
- package/dist/CodeBlock/languages/dockerfile.js +45 -0
- package/dist/CodeBlock/languages/graphql.d.ts +3 -0
- package/dist/CodeBlock/languages/graphql.d.ts.map +1 -0
- package/dist/CodeBlock/languages/graphql.js +27 -0
- package/dist/CodeBlock/languages/java.d.ts +3 -0
- package/dist/CodeBlock/languages/java.d.ts.map +1 -0
- package/dist/CodeBlock/languages/java.js +24 -0
- package/dist/CodeBlock/languages/lua.d.ts +3 -0
- package/dist/CodeBlock/languages/lua.d.ts.map +1 -0
- package/dist/CodeBlock/languages/lua.js +21 -0
- package/dist/CodeBlock/languages/objective-c.d.ts +3 -0
- package/dist/CodeBlock/languages/objective-c.d.ts.map +1 -0
- package/dist/CodeBlock/languages/objective-c.js +27 -0
- package/dist/CodeBlock/languages/powershell.d.ts +3 -0
- package/dist/CodeBlock/languages/powershell.d.ts.map +1 -0
- package/dist/CodeBlock/languages/powershell.js +30 -0
- package/dist/CodeBlock/languages/ruby.d.ts +3 -0
- package/dist/CodeBlock/languages/ruby.d.ts.map +1 -0
- package/dist/CodeBlock/languages/ruby.js +24 -0
- package/dist/CodeBlock/languages/thrift.d.ts +3 -0
- package/dist/CodeBlock/languages/thrift.d.ts.map +1 -0
- package/dist/CodeBlock/languages/thrift.js +18 -0
- package/dist/CodeBlock/languages/toml.d.ts +3 -0
- package/dist/CodeBlock/languages/toml.d.ts.map +1 -0
- package/dist/CodeBlock/languages/toml.js +53 -0
- package/dist/CodeBlock/tokenizer.d.ts +8 -4
- package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
- package/dist/CodeBlock/tokenizer.js +158 -8
- package/dist/Collapsible/Collapsible.d.ts +8 -1
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +84 -2
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +15 -1
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.js +1 -0
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +14 -2
- package/dist/CommandPalette/busyStartSettle.d.ts +4 -0
- package/dist/CommandPalette/busyStartSettle.d.ts.map +1 -0
- package/dist/CommandPalette/busyStartSettle.js +23 -0
- package/dist/ComplexSelector/ComplexSelector.d.ts +20 -2
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +42 -7
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +48 -13
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +12 -5
- package/dist/DateInput/NativeDateField.d.ts.map +1 -1
- package/dist/DateInput/NativeDateField.js +2 -1
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +2 -1
- package/dist/DateInput/Wheel.d.ts.map +1 -1
- package/dist/DateInput/Wheel.js +1 -1
- package/dist/Dialog/Dialog.d.ts +4 -0
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +20 -8
- package/dist/Drawer/Drawer.d.ts.map +1 -1
- package/dist/Drawer/Drawer.js +18 -13
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +34 -30
- package/dist/DropdownMenu/DropdownMenuGroup.d.ts +7 -4
- package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuGroup.js +10 -4
- package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +10 -5
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +13 -5
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +6 -6
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +0 -3
- package/dist/DropdownMenu/MenuBottomSheet.d.ts +11 -4
- package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -1
- package/dist/DropdownMenu/MenuBottomSheet.js +35 -9
- package/dist/DropdownMenu/MenuBottomSheetActionList.js +3 -3
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +2 -0
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
- package/dist/DropdownMenu/lazyMenuBottomSheet.js +25 -3
- package/dist/DropdownMenu/menuBottomSheet.stylex.d.ts +23 -0
- package/dist/DropdownMenu/menuBottomSheet.stylex.d.ts.map +1 -0
- package/dist/DropdownMenu/menuBottomSheet.stylex.js +29 -0
- package/dist/DropdownMenu/menuItemHover.d.ts +3 -0
- package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -1
- package/dist/DropdownMenu/menuItemHover.js +14 -1
- package/dist/DropdownMenu/menuTouchAction.stylex.d.ts +25 -0
- package/dist/DropdownMenu/menuTouchAction.stylex.d.ts.map +1 -0
- package/dist/DropdownMenu/menuTouchAction.stylex.js +29 -0
- package/dist/DropdownMenu/useMenuDrillIn.d.ts.map +1 -1
- package/dist/DropdownMenu/useMenuDrillIn.js +7 -5
- package/dist/EmptyState/EmptyState.d.ts +4 -2
- package/dist/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/EmptyState/EmptyState.js +6 -4
- package/dist/Field/Field.js +1 -1
- package/dist/Field/FieldLabel.js +1 -1
- package/dist/Field/PanelSearchInput.d.ts +9 -1
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +31 -22
- package/dist/Field/inputDisabledFocus.d.ts +14 -0
- package/dist/Field/inputDisabledFocus.d.ts.map +1 -0
- package/dist/Field/inputDisabledFocus.js +19 -0
- package/dist/Field/inputStyles.stylex.d.ts +9 -9
- package/dist/Field/inputStyles.stylex.js +9 -9
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +7 -3
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +22 -12
- package/dist/Icon/Icon.d.ts +37 -5
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +65 -11
- package/dist/Icon/IconSize.stylex.d.ts +16 -11
- package/dist/Icon/IconSize.stylex.d.ts.map +1 -1
- package/dist/Icon/IconSize.stylex.js +27 -11
- package/dist/Icon/globalIconRegistry.d.ts +71 -4
- package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
- package/dist/Icon/globalIconRegistry.js +163 -23
- package/dist/Icon/index.d.ts +26 -2
- package/dist/Icon/index.d.ts.map +1 -1
- package/dist/Icon/index.js +24 -1
- package/dist/Icon/useIcon.d.ts +5 -1
- package/dist/Icon/useIcon.d.ts.map +1 -1
- package/dist/Icon/useIcon.js +5 -1
- package/dist/InputGroup/InputGroup.d.ts +1 -1
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +46 -36
- package/dist/InputGroup/InputGroupInternalContext.d.ts +4 -0
- package/dist/InputGroup/InputGroupInternalContext.d.ts.map +1 -0
- package/dist/InputGroup/InputGroupInternalContext.js +15 -0
- package/dist/InputGroup/InputGroupText.d.ts.map +1 -1
- package/dist/InputGroup/InputGroupText.js +2 -0
- package/dist/InputGroup/groupStyles.d.ts +9 -0
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +28 -14
- package/dist/Item/Item.d.ts +5 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +23 -7
- package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.d.ts +2 -0
- package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.d.ts.map +1 -0
- package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.js +132 -0
- package/dist/Item/ItemMarkerColumnsContext.d.ts +14 -0
- package/dist/Item/ItemMarkerColumnsContext.d.ts.map +1 -0
- package/dist/Item/ItemMarkerColumnsContext.js +18 -0
- package/dist/Item/ItemSwipeLayer.d.ts.map +1 -1
- package/dist/Item/ItemSwipeLayer.js +3 -0
- package/dist/Item/useSwipeAction.d.ts.map +1 -1
- package/dist/Item/useSwipeAction.js +60 -5
- package/dist/Kbd/Kbd.d.ts +2 -2
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +18 -11
- package/dist/Layer/layerAnimations.stylex.d.ts +9 -5
- package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
- package/dist/Layer/layerAnimations.stylex.js +23 -10
- package/dist/Layer/layerSlideRules.d.ts +62 -2
- package/dist/Layer/layerSlideRules.d.ts.map +1 -1
- package/dist/Layer/layerSlideRules.js +124 -3
- package/dist/Layer/layerStack.d.ts +12 -9
- package/dist/Layer/layerStack.d.ts.map +1 -1
- package/dist/Layer/layerStack.js +116 -53
- package/dist/Layer/modalOutlet.d.ts +44 -6
- package/dist/Layer/modalOutlet.d.ts.map +1 -1
- package/dist/Layer/modalOutlet.js +150 -14
- package/dist/Layer/preserveAnimations.d.ts +11 -0
- package/dist/Layer/preserveAnimations.d.ts.map +1 -0
- package/dist/Layer/preserveAnimations.js +245 -0
- package/dist/Layer/useLayer.d.ts +19 -2
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +531 -44
- package/dist/Layer/useLayerDismissal.d.ts +10 -7
- package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
- package/dist/Layer/useLayerDismissal.js +8 -8
- package/dist/Layer/useTouchTrigger.d.ts +14 -1
- package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
- package/dist/Layer/useTouchTrigger.js +72 -17
- package/dist/Layout/Layout.d.ts.map +1 -1
- package/dist/Layout/Layout.js +4 -0
- package/dist/Layout/LayoutContent.d.ts.map +1 -1
- package/dist/Layout/LayoutContent.js +2 -2
- package/dist/Layout/LayoutFooter.d.ts.map +1 -1
- package/dist/Layout/LayoutFooter.js +2 -1
- package/dist/Layout/LayoutHeader.d.ts.map +1 -1
- package/dist/Layout/LayoutHeader.js +2 -1
- package/dist/Layout/layoutEdges.stylex.d.ts +20 -0
- package/dist/Layout/layoutEdges.stylex.d.ts.map +1 -0
- package/dist/Layout/layoutEdges.stylex.js +28 -0
- package/dist/Lightbox/Lightbox.d.ts +5 -2
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +111 -89
- package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts +2 -0
- package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts.map +1 -0
- package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.js +78 -0
- package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts +2 -0
- package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts.map +1 -0
- package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +65 -0
- package/dist/List/List.d.ts +2 -1
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +9 -2
- package/dist/List/ListContext.d.ts +16 -4
- package/dist/List/ListContext.d.ts.map +1 -1
- package/dist/List/ListContext.js +10 -5
- package/dist/List/ListItem.d.ts +7 -1
- package/dist/List/ListItem.d.ts.map +1 -1
- package/dist/List/ListItem.js +52 -8
- package/dist/List/ListMarkers.a11y.chromium.spec.d.ts +2 -0
- package/dist/List/ListMarkers.a11y.chromium.spec.d.ts.map +1 -0
- package/dist/List/ListMarkers.a11y.chromium.spec.js +677 -0
- package/dist/Markdown/Markdown.d.ts +11 -1
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.fr23.bench.js +3 -1
- package/dist/Markdown/Markdown.fr23.sampling.d.ts +16 -0
- package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -1
- package/dist/Markdown/Markdown.fr23.sampling.js +13 -4
- package/dist/Markdown/Markdown.js +41 -14
- package/dist/Markdown/MarkdownTable.a11y.chromium.spec.js +1 -0
- package/dist/MobileNav/MobileNav.d.ts +2 -1
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +46 -37
- package/dist/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.js +1 -0
- package/dist/MobileNav/MobileNavToggle.d.ts +7 -3
- package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
- package/dist/MobileNav/MobileNavToggle.js +11 -3
- package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +53 -6
- package/dist/MultiSelector/MultiSelector.d.ts +1 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.js +1 -0
- package/dist/MultiSelector/MultiSelector.js +21 -5
- package/dist/MultiSelector/OptionActions.a11y.chromium.spec.js +1 -0
- package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +29 -5
- package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenuItem.js +51 -7
- package/dist/NavMenu/NavMenuContext.d.ts +9 -0
- package/dist/NavMenu/NavMenuContext.d.ts.map +1 -1
- package/dist/NavMenu/NavMenuContext.js +9 -0
- package/dist/NumberInput/NumberInput.d.ts +4 -4
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +61 -24
- package/dist/Overlay/Overlay.d.ts +3 -3
- package/dist/Overlay/Overlay.d.ts.map +1 -1
- package/dist/Overlay/Overlay.js +12 -5
- package/dist/Popover/Popover.d.ts +41 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +276 -44
- package/dist/Popover/index.d.ts +1 -1
- package/dist/Popover/index.d.ts.map +1 -1
- package/dist/Popover/lazyPopoverBottomSheet.d.ts +23 -0
- package/dist/Popover/lazyPopoverBottomSheet.d.ts.map +1 -0
- package/dist/Popover/lazyPopoverBottomSheet.js +40 -0
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +11 -5
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +7 -5
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +8 -0
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +10 -2
- package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
- package/dist/ScrollableArea/ScrollableArea.js +1 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +6 -2
- package/dist/SelectableCard/SelectableCard.d.ts +5 -5
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +15 -11
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +27 -8
- package/dist/Selector/hooks.d.ts +52 -6
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +145 -2
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +58 -2
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +79 -3
- package/dist/SideNav/SideNavItem.d.ts +5 -1
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +36 -13
- package/dist/SideNav/railMotion.d.ts +54 -0
- package/dist/SideNav/railMotion.d.ts.map +1 -0
- package/dist/SideNav/railMotion.js +253 -0
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +12 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +52 -15
- package/dist/StatusDot/StatusDot.d.ts.map +1 -1
- package/dist/StatusDot/StatusDot.js +12 -0
- package/dist/Stepper/Step.d.ts.map +1 -1
- package/dist/Stepper/Step.js +10 -6
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +5 -5
- package/dist/Switch/switch.markers.stylex.d.ts +7 -2
- package/dist/Switch/switch.markers.stylex.d.ts.map +1 -1
- package/dist/Switch/switch.markers.stylex.js +8 -3
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +5 -1
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +25 -3
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +5 -1
- package/dist/Table/TableHeaderCell.d.ts.map +1 -1
- package/dist/Table/TableHeaderCell.js +1 -0
- package/dist/Table/TableRow.d.ts.map +1 -1
- package/dist/Table/TableRow.js +3 -0
- package/dist/Table/glidingDivider.d.ts +96 -0
- package/dist/Table/glidingDivider.d.ts.map +1 -0
- package/dist/Table/glidingDivider.js +275 -0
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +11 -2
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +8 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +374 -13
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +244 -6
- package/dist/Table/rowDivider.d.ts +34 -0
- package/dist/Table/rowDivider.d.ts.map +1 -0
- package/dist/Table/rowDivider.js +118 -0
- package/dist/TextArea/TextArea.d.ts +6 -4
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +15 -12
- package/dist/TextInput/TextInput.d.ts +7 -5
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +43 -22
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +45 -11
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +12 -4
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
- package/dist/TimeInput/TouchTimeField.js +2 -1
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +62 -6
- package/dist/Tokenizer/Tokenizer.d.ts +71 -4
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +430 -45
- package/dist/Tokenizer/TokenizerBottomSheet.d.ts +98 -0
- package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -0
- package/dist/Tokenizer/TokenizerBottomSheet.js +721 -0
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +9 -3
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +26 -0
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +4 -4
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +32 -4
- package/dist/TreeList/TreeList.d.ts +8 -23
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +175 -3
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +7 -5
- package/dist/TreeList/TreeListItem.d.ts +7 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +5 -3
- package/dist/Typeahead/BaseTypeahead.d.ts +1 -1
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.d.ts +2 -0
- package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.d.ts.map +1 -0
- package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.js +118 -0
- package/dist/Typeahead/BaseTypeahead.js +27 -11
- package/dist/Typeahead/Typeahead.d.ts +1 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +31 -14
- package/dist/astryx.css +164 -41
- package/dist/gestures/GestureArena.d.ts +175 -0
- package/dist/gestures/GestureArena.d.ts.map +1 -0
- package/dist/gestures/GestureArena.js +816 -0
- package/dist/gestures/GestureRecognizer.d.ts +239 -0
- package/dist/gestures/GestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/GestureRecognizer.js +487 -0
- package/dist/gestures/LongPressGestureRecognizer.d.ts +32 -0
- package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/LongPressGestureRecognizer.js +135 -0
- package/dist/gestures/PanGestureRecognizer.d.ts +117 -0
- package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/PanGestureRecognizer.js +349 -0
- package/dist/gestures/TapGestureRecognizer.d.ts +39 -0
- package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/TapGestureRecognizer.js +151 -0
- package/dist/gestures/VelocityTracker.d.ts +51 -0
- package/dist/gestures/VelocityTracker.d.ts.map +1 -0
- package/dist/gestures/VelocityTracker.js +186 -0
- package/dist/gestures/geometry.d.ts +17 -0
- package/dist/gestures/geometry.d.ts.map +1 -0
- package/dist/gestures/geometry.js +55 -0
- package/dist/gestures/types.d.ts +139 -0
- package/dist/gestures/types.d.ts.map +1 -0
- package/dist/gestures/types.js +67 -0
- package/dist/hooks/AnnounceRenderedText.d.ts +17 -0
- package/dist/hooks/AnnounceRenderedText.d.ts.map +1 -0
- package/dist/hooks/AnnounceRenderedText.js +32 -0
- package/dist/hooks/ModalAnnounceProvider.d.ts +41 -0
- package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -0
- package/dist/hooks/ModalAnnounceProvider.js +133 -0
- package/dist/hooks/actionGroupTracker.d.ts +98 -0
- package/dist/hooks/actionGroupTracker.d.ts.map +1 -0
- package/dist/hooks/actionGroupTracker.js +338 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/menuPressOnItems.d.ts +19 -0
- package/dist/hooks/menuPressOnItems.d.ts.map +1 -0
- package/dist/hooks/menuPressOnItems.js +32 -0
- package/dist/hooks/modalAnnounce.d.ts +18 -0
- package/dist/hooks/modalAnnounce.d.ts.map +1 -0
- package/dist/hooks/modalAnnounce.js +382 -0
- package/dist/hooks/scrollGeometry.d.ts +28 -0
- package/dist/hooks/scrollGeometry.d.ts.map +1 -1
- package/dist/hooks/scrollGeometry.js +36 -2
- package/dist/hooks/useAdaptivePresentation.d.ts +9 -1
- package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
- package/dist/hooks/useAdaptivePresentation.js +33 -8
- package/dist/hooks/useAnimatedLayout.d.ts +42 -0
- package/dist/hooks/useAnimatedLayout.d.ts.map +1 -0
- package/dist/hooks/useAnimatedLayout.js +46 -0
- package/dist/hooks/useAnnounce.d.ts +132 -1
- package/dist/hooks/useAnnounce.d.ts.map +1 -1
- package/dist/hooks/useAnnounce.js +356 -27
- package/dist/hooks/useAnnounceRenderedText.d.ts +19 -2
- package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
- package/dist/hooks/useAnnounceRenderedText.js +52 -11
- package/dist/hooks/useBusyAnnouncement.d.ts +9 -5
- package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
- package/dist/hooks/useBusyAnnouncement.js +58 -46
- package/dist/hooks/useFocusTrap.d.ts +1 -1
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +57 -26
- package/dist/hooks/useMenuHover.d.ts.map +1 -1
- package/dist/hooks/useMenuHover.js +6 -2
- package/dist/hooks/useMenuPress.d.ts +4 -2
- package/dist/hooks/useMenuPress.d.ts.map +1 -1
- package/dist/hooks/useMenuPress.js +58 -33
- package/dist/hooks/usePressFeedback.d.ts +5 -2
- package/dist/hooks/usePressFeedback.d.ts.map +1 -1
- package/dist/hooks/usePressFeedback.js +5 -2
- package/dist/hooks/useScrollableArea.d.ts +5 -0
- package/dist/hooks/useScrollableArea.d.ts.map +1 -1
- package/dist/hooks/useScrollableArea.js +104 -11
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +33 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +33 -0
- package/dist/internal/tokenizer-presentation.d.ts +21 -0
- package/dist/internal/tokenizer-presentation.d.ts.map +1 -0
- package/dist/internal/tokenizer-presentation.js +21 -0
- package/dist/internal/touch.d.ts +26 -0
- package/dist/internal/touch.d.ts.map +1 -0
- package/dist/internal/touch.js +28 -0
- package/dist/motion/LayoutChangeSnapshot.d.ts +33 -0
- package/dist/motion/LayoutChangeSnapshot.d.ts.map +1 -0
- package/dist/motion/LayoutChangeSnapshot.js +37 -0
- package/dist/motion/animatedLayout.d.ts +190 -0
- package/dist/motion/animatedLayout.d.ts.map +1 -0
- package/dist/motion/animatedLayout.js +1502 -0
- package/dist/motion/animator.d.ts +240 -0
- package/dist/motion/animator.d.ts.map +1 -0
- package/dist/motion/animator.js +2203 -0
- package/dist/motion/bezier.d.ts +18 -0
- package/dist/motion/bezier.d.ts.map +1 -0
- package/dist/motion/bezier.js +60 -0
- package/dist/motion/coast.d.ts +61 -0
- package/dist/motion/coast.d.ts.map +1 -0
- package/dist/motion/coast.js +107 -0
- package/dist/motion/decay.d.ts +41 -0
- package/dist/motion/decay.d.ts.map +1 -0
- package/dist/motion/decay.js +90 -0
- package/dist/motion/projection.d.ts +36 -0
- package/dist/motion/projection.d.ts.map +1 -0
- package/dist/motion/projection.js +92 -0
- package/dist/motion/reducedMotion.d.ts +25 -0
- package/dist/motion/reducedMotion.d.ts.map +1 -0
- package/dist/motion/reducedMotion.js +85 -0
- package/dist/motion/reducedMotion.stylex.d.ts +19 -0
- package/dist/motion/reducedMotion.stylex.d.ts.map +1 -0
- package/dist/motion/reducedMotion.stylex.js +37 -0
- package/dist/motion/reducedMotionPlan.d.ts +89 -0
- package/dist/motion/reducedMotionPlan.d.ts.map +1 -0
- package/dist/motion/reducedMotionPlan.js +194 -0
- package/dist/motion/resolveSnapPoint.d.ts +52 -0
- package/dist/motion/resolveSnapPoint.d.ts.map +1 -0
- package/dist/motion/resolveSnapPoint.js +135 -0
- package/dist/motion/roleValue.d.ts +33 -0
- package/dist/motion/roleValue.d.ts.map +1 -0
- package/dist/motion/roleValue.js +84 -0
- package/dist/motion/roles.d.ts +79 -0
- package/dist/motion/roles.d.ts.map +1 -0
- package/dist/motion/roles.js +199 -0
- package/dist/motion/rubberBand.d.ts +20 -0
- package/dist/motion/rubberBand.d.ts.map +1 -0
- package/dist/motion/rubberBand.js +91 -0
- package/dist/motion/selectPage.d.ts +26 -0
- package/dist/motion/selectPage.d.ts.map +1 -0
- package/dist/motion/selectPage.js +55 -0
- package/dist/motion/spring.d.ts +193 -0
- package/dist/motion/spring.d.ts.map +1 -0
- package/dist/motion/spring.js +442 -0
- package/dist/motion/transientCopy.d.ts +33 -0
- package/dist/motion/transientCopy.d.ts.map +1 -0
- package/dist/motion/transientCopy.js +314 -0
- package/dist/motion/uikit/gestures.d.ts +642 -0
- package/dist/motion/uikit/gestures.d.ts.map +1 -0
- package/dist/motion/uikit/gestures.js +428 -0
- package/dist/motion/uikit/index.d.ts +24 -0
- package/dist/motion/uikit/index.d.ts.map +1 -0
- package/dist/motion/uikit/index.js +26 -0
- package/dist/motion/uikit/navigation.d.ts +54 -0
- package/dist/motion/uikit/navigation.d.ts.map +1 -0
- package/dist/motion/uikit/navigation.js +83 -0
- package/dist/motion/uikit/scroll.d.ts +116 -0
- package/dist/motion/uikit/scroll.d.ts.map +1 -0
- package/dist/motion/uikit/scroll.js +146 -0
- package/dist/motion/uikit/springs.d.ts +545 -0
- package/dist/motion/uikit/springs.d.ts.map +1 -0
- package/dist/motion/uikit/springs.js +548 -0
- package/dist/motion/uikit/timing.d.ts +202 -0
- package/dist/motion/uikit/timing.d.ts.map +1 -0
- package/dist/motion/uikit/timing.js +201 -0
- package/dist/reset.a11y.chromium.spec.js +1 -0
- package/dist/reset.until-found.a11y.browser.spec.js +1 -0
- package/dist/theme/declarationBoundary.d.ts +13 -0
- package/dist/theme/declarationBoundary.d.ts.map +1 -1
- package/dist/theme/declarationBoundary.js +264 -1
- package/dist/theme/defineTheme.d.ts +111 -11
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +97 -7
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +9 -0
- package/dist/theme/generateThemeRules.d.ts +6 -2
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +468 -24
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/theme/statusColor.d.ts +48 -0
- package/dist/theme/statusColor.d.ts.map +1 -0
- package/dist/theme/statusColor.js +203 -0
- package/dist/theme/statusRoleDerivation.d.ts +11 -0
- package/dist/theme/statusRoleDerivation.d.ts.map +1 -0
- package/dist/theme/statusRoleDerivation.js +236 -0
- package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
- package/dist/theme/syntax/SyntaxTheme.js +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +1 -1
- package/dist/theme/syntax/presets.d.ts +1 -1
- package/dist/theme/syntax/presets.js +1 -1
- package/dist/theme/syntax/tokens.d.ts +1 -1
- package/dist/theme/syntax/tokens.js +1 -1
- package/dist/theme/themeAdaptations.d.ts +25 -1
- package/dist/theme/themeAdaptations.d.ts.map +1 -1
- package/dist/theme/themeAdaptations.js +30 -1
- package/dist/theme/tokens.d.ts.map +1 -1
- package/dist/theme/tokens.js +16 -1
- package/dist/theme/tokens.stylex.d.ts +42 -2
- package/dist/theme/tokens.stylex.d.ts.map +1 -1
- package/dist/theme/tokens.stylex.js +54 -3
- package/dist/theme/useTheme.d.ts +4 -2
- package/dist/theme/useTheme.d.ts.map +1 -1
- package/dist/theme/useTheme.js +10 -4
- package/dist/utils/edgeAutoscroll.d.ts +53 -0
- package/dist/utils/edgeAutoscroll.d.ts.map +1 -0
- package/dist/utils/edgeAutoscroll.js +81 -0
- package/dist/utils/hitArea.d.ts +72 -0
- package/dist/utils/hitArea.d.ts.map +1 -0
- package/dist/utils/hitArea.js +681 -0
- package/dist/utils/interactionOverlay.stylex.d.ts +4 -1
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +4 -1
- package/dist/utils/pressFeedback.d.ts +5 -1
- package/dist/utils/pressFeedback.d.ts.map +1 -1
- package/dist/utils/pressFeedback.js +285 -54
- package/dist/utils/pressGesture.d.ts +13 -1
- package/dist/utils/pressGesture.d.ts.map +1 -1
- package/dist/utils/pressGesture.js +40 -1
- package/dist/utils/touchPresentation.d.ts +48 -0
- package/dist/utils/touchPresentation.d.ts.map +1 -0
- package/dist/utils/touchPresentation.js +133 -0
- package/locales/af-ZA.json +1 -1
- package/locales/ar-SA.json +1 -1
- package/locales/ca-ES.json +1 -1
- package/locales/cs-CZ.json +1 -1
- package/locales/da-DK.json +1 -1
- package/locales/de-DE.json +1 -1
- package/locales/el-GR.json +1 -1
- package/locales/en.json +132 -0
- package/locales/es-ES.json +1 -1
- package/locales/fi-FI.json +1 -1
- package/locales/fr-FR.json +1 -1
- package/locales/he-IL.json +1 -1
- package/locales/hu-HU.json +1 -1
- package/locales/it-IT.json +1 -1
- package/locales/ja-JP.json +1 -1
- package/locales/ko-KR.json +1 -1
- package/locales/nl-NL.json +1 -1
- package/locales/no-NO.json +1 -1
- package/locales/pl-PL.json +1 -1
- package/locales/pseudo.json +99 -0
- package/locales/pt-BR.json +1 -1
- package/locales/pt-PT.json +1 -1
- package/locales/ro-RO.json +1 -1
- package/locales/ru-RU.json +1 -1
- package/locales/sr-SP.json +1 -1
- package/locales/sv-SE.json +1 -1
- package/locales/tr-TR.json +1 -1
- package/locales/uk-UA.json +1 -1
- package/locales/vi-VN.json +1 -1
- package/locales/zh-CN.json +1 -1
- package/locales/zh-TW.json +1 -1
- package/package.json +63 -8
- package/src/AlertDialog/AlertDialog.spec.md +85 -31
- package/src/AlertDialog/AlertDialog.tsx +1 -1
- package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +1 -0
- package/src/AppShell/AppShell.spec.md +334 -0
- package/src/AppShell/AppShell.tsx +170 -2
- package/src/AspectRatio/AspectRatio.spec.md +179 -0
- package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +1 -0
- package/src/Avatar/Avatar.spec.md +253 -0
- package/src/Avatar/AvatarStatusDot.spec.md +93 -79
- package/src/Avatar/AvatarStatusDot.test.tsx +22 -0
- package/src/Avatar/AvatarStatusDot.tsx +2 -2
- package/src/AvatarGroup/AvatarGroup.spec.md +205 -0
- package/src/AvatarGroup/AvatarGroupOverflow.spec.md +123 -120
- package/src/Badge/Badge.spec.md +207 -0
- package/src/Badge/Badge.test.tsx +13 -0
- package/src/Badge/Badge.tsx +38 -2
- package/src/Banner/Banner.spec.md +41 -28
- package/src/Banner/Banner.test.tsx +118 -16
- package/src/Banner/Banner.tsx +94 -7
- package/src/Blockquote/Blockquote.spec.md +171 -0
- package/src/BottomSheet/BottomSheet.doc.mjs +106 -24
- package/src/BottomSheet/BottomSheet.spec.md +271 -40
- package/src/BottomSheet/BottomSheet.test.tsx +491 -5
- package/src/BottomSheet/BottomSheet.tsx +544 -145
- package/src/BottomSheet/BottomSheetHostContext.ts +44 -0
- package/src/BottomSheet/BottomSheetPanel.test.tsx +73 -19
- package/src/BottomSheet/BottomSheetPanel.tsx +178 -63
- package/src/BottomSheet/BottomSheetReplace.test.tsx +1638 -0
- package/src/BottomSheet/BottomSheetStacking.announce.test.tsx +246 -0
- package/src/BottomSheet/BottomSheetStacking.test.tsx +3184 -0
- package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +27 -31
- package/src/BottomSheet/BottomSheetSwitcher.spec.md +138 -43
- package/src/BottomSheet/BottomSheetSwitcher.tsx +275 -26
- package/src/BottomSheet/BottomSheetSwitcherContext.ts +6 -0
- package/src/BottomSheet/__tests__/BottomSheetDrag.a11y.chromium.spec.ts +1 -0
- package/src/BottomSheet/__tests__/BottomSheetFocusReturn.a11y.browser.spec.ts +1 -0
- package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +4 -1
- package/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts +1 -0
- package/src/BottomSheet/__tests__/BottomSheetPinchZoom.a11y.chromium.spec.ts +1 -0
- package/src/BottomSheet/__tests__/BottomSheetToastOutlet.a11y.chromium.spec.ts +83 -0
- package/src/BottomSheet/bottomSheetEscape.ts +21 -0
- package/src/BottomSheet/bottomSheetStack.ts +2054 -0
- package/src/BottomSheet/useSheetGestures.ts +68 -12
- package/src/Breadcrumbs/BreadcrumbItem.spec.md +104 -60
- package/src/Breadcrumbs/BreadcrumbItem.tsx +30 -1
- package/src/Breadcrumbs/Breadcrumbs.spec.md +165 -0
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +90 -0
- package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +1 -0
- package/src/Button/Button.spec.md +322 -0
- package/src/Button/Button.test.tsx +8 -1
- package/src/Button/Button.tsx +36 -7
- package/src/Button/__tests__/Button.a11y.chromium.spec.ts +1 -0
- package/src/ButtonGroup/ButtonGroup.spec.md +220 -0
- package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +1 -0
- package/src/Card/Card.spec.md +205 -0
- package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +1 -0
- package/src/Center/Center.spec.md +104 -124
- package/src/Chat/ChatComposer.test.tsx +54 -0
- package/src/Chat/ChatComposer.tsx +41 -27
- package/src/Chat/ChatComposerInput.test.tsx +165 -21
- package/src/Chat/ChatComposerInput.tsx +73 -16
- package/src/Chat/ChatMessageMetadata.tsx +1 -1
- package/src/Chat/ChatPastedTextToken.test.tsx +71 -0
- package/src/Chat/ChatPastedTextToken.tsx +8 -7
- package/src/Chat/ChatToolCalls.tsx +5 -5
- package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +22 -4
- package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +1 -0
- package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +1 -0
- package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +1 -0
- package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1 -0
- package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +1 -0
- package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +1 -0
- package/src/Chat/__tests__/useChatStreamScroll.a11y.chromium.spec.ts +1 -0
- package/src/CheckboxInput/CheckboxInput.spec.md +97 -66
- package/src/CheckboxInput/__tests__/Checkbox.a11y.chromium.spec.ts +1 -0
- package/src/CheckboxList/CheckboxList.spec.md +92 -78
- package/src/CheckboxList/CheckboxListItem.spec.md +86 -60
- package/src/CheckboxList/__tests__/CheckboxList.a11y.chromium.spec.ts +1 -0
- package/src/ClickableCard/ClickableCard.doc.mjs +1 -2
- package/src/ClickableCard/ClickableCard.spec.md +124 -128
- package/src/ClickableCard/ClickableCard.test.tsx +14 -3
- package/src/ClickableCard/ClickableCard.tsx +44 -28
- package/src/Code/Code.spec.md +30 -32
- package/src/CodeBlock/CodeBlock.doc.mjs +21 -4
- package/src/CodeBlock/CodeBlock.spec.md +96 -61
- package/src/CodeBlock/CodeBlock.test.tsx +97 -1
- package/src/CodeBlock/CodeBlock.tsx +132 -22
- package/src/CodeBlock/CodeLanguage.test.tsx +173 -0
- package/src/CodeBlock/__tests__/CodeBlockCopyClearance.a11y.chromium.spec.ts +290 -0
- package/src/CodeBlock/__tests__/CodeBlockLanguages.a11y.chromium.spec.ts +64 -0
- package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +1 -0
- package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +1 -0
- package/src/CodeBlock/grammar.ts +291 -0
- package/src/CodeBlock/index.ts +7 -0
- package/src/CodeBlock/languages/dockerfile.ts +43 -0
- package/src/CodeBlock/languages/graphql.ts +30 -0
- package/src/CodeBlock/languages/java.ts +28 -0
- package/src/CodeBlock/languages/lua.ts +21 -0
- package/src/CodeBlock/languages/objective-c.ts +26 -0
- package/src/CodeBlock/languages/powershell.ts +31 -0
- package/src/CodeBlock/languages/ruby.ts +29 -0
- package/src/CodeBlock/languages/thrift.ts +32 -0
- package/src/CodeBlock/languages/toml.ts +36 -0
- package/src/CodeBlock/languages.test.ts +402 -0
- package/src/CodeBlock/tokenizer.ts +176 -16
- package/src/CodeBlock/tokenizerBudget.test.ts +112 -0
- package/src/Collapsible/Collapsible.doc.mjs +6 -0
- package/src/Collapsible/Collapsible.spec.md +26 -23
- package/src/Collapsible/Collapsible.tsx +121 -2
- package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +1 -0
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.chromium.spec.ts +1 -0
- package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +1 -0
- package/src/CommandPalette/CommandPalette.perf.test.ts +8 -4
- package/src/CommandPalette/CommandPalette.tsx +17 -1
- package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +6 -3
- package/src/CommandPalette/CommandPaletteEmpty.spec.md +190 -0
- package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +21 -2
- package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +1 -0
- package/src/CommandPalette/__tests__/CommandPaletteEmptyAudit.a11y.chromium.spec.ts +715 -0
- package/src/CommandPalette/__tests__/CommandPaletteFooter.a11y.chromium.spec.ts +3 -2
- package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +1 -0
- package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +1 -0
- package/src/CommandPalette/busyStartSettle.ts +26 -0
- package/src/ComplexSelector/ComplexSelector.doc.mjs +1 -1
- package/src/ComplexSelector/ComplexSelector.focusableDisabled.test.tsx +1 -1
- package/src/ComplexSelector/ComplexSelector.fr10.test.tsx +9 -9
- package/src/ComplexSelector/ComplexSelector.spec.md +161 -107
- package/src/ComplexSelector/ComplexSelector.test.tsx +236 -17
- package/src/ComplexSelector/ComplexSelector.tsx +69 -4
- package/src/ComplexSelector/__tests__/ComplexSelector.a11y.chromium.spec.ts +965 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +1 -1
- package/src/ContextMenu/ContextMenu.spec.md +38 -30
- package/src/ContextMenu/ContextMenu.test.tsx +189 -11
- package/src/ContextMenu/ContextMenu.tsx +75 -17
- package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +1 -0
- package/src/ContextMenu/__tests__/ContextMenuCursorAnchor.a11y.browser.spec.ts +1 -0
- package/src/ContextMenu/__tests__/ContextMenuLongPress.a11y.chromium.spec.ts +117 -0
- package/src/DateInput/DateInput.tsx +9 -4
- package/src/DateInput/DateInputTouch.test.tsx +10 -1
- package/src/DateInput/NativeDateField.tsx +2 -1
- package/src/DateInput/TouchDateField.tsx +2 -1
- package/src/DateInput/Wheel.tsx +4 -1
- package/src/DateInput/__tests__/DateInputAudit.a11y.chromium.spec.ts +1 -0
- package/src/DateInput/__tests__/WheelPinchZoom.a11y.chromium.spec.ts +171 -0
- package/src/Dialog/Dialog.doc.mjs +201 -47
- package/src/Dialog/Dialog.spec.md +20 -4
- package/src/Dialog/Dialog.tsx +37 -10
- package/src/Dialog/__tests__/Dialog.a11y.browser.spec.ts +1 -0
- package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +1 -0
- package/src/Dialog/__tests__/Dialog.reduced-motion.a11y.browser.spec.ts +252 -0
- package/src/Divider/Divider.spec.md +79 -70
- package/src/Drawer/Drawer.tsx +38 -35
- package/src/Drawer/__tests__/DrawerAudit.a11y.chromium.spec.ts +1 -0
- package/src/Drawer/__tests__/DrawerHeaderAudit.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/DropdownMenu.spec.md +14 -6
- package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +44 -8
- package/src/DropdownMenu/DropdownMenu.test.tsx +107 -5
- package/src/DropdownMenu/DropdownMenu.tsx +51 -34
- package/src/DropdownMenu/DropdownMenuGroup.doc.mjs +2 -2
- package/src/DropdownMenu/DropdownMenuGroup.tsx +12 -6
- package/src/DropdownMenu/DropdownMenuItem.tsx +5 -5
- package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +5 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +226 -0
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +32 -16
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +158 -0
- package/src/DropdownMenu/DropdownMenuSheetFirstOpen.test.tsx +72 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +9 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.spec.md +225 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +105 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +6 -6
- package/src/DropdownMenu/MenuBottomSheet.tsx +42 -7
- package/src/DropdownMenu/MenuBottomSheetActionList.tsx +3 -3
- package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/DropdownMenuDrillIn.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/DropdownMenuFocusReturn.a11y.browser.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/DropdownMenuItemAudit.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/DropdownMenuRadioGroupAudit.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/DropdownMenuRadioItemAudit.a11y.chromium.spec.ts +540 -0
- package/src/DropdownMenu/__tests__/DropdownMenuSubMenuAudit.a11y.chromium.spec.ts +671 -0
- package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/MenuHoverFocus.a11y.chromium.spec.ts +238 -0
- package/src/DropdownMenu/__tests__/MenuPinchZoom.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/MenuPress.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/__tests__/SubMenuHeaderFooter.a11y.chromium.spec.ts +1 -0
- package/src/DropdownMenu/lazyMenuBottomSheet.ts +28 -2
- package/src/DropdownMenu/menuBottomSheet.stylex.ts +33 -0
- package/src/DropdownMenu/menuItemHover.ts +13 -1
- package/src/DropdownMenu/menuTouchAction.stylex.ts +28 -0
- package/src/DropdownMenu/modules/useMenuPress.spec.md +90 -62
- package/src/DropdownMenu/useMenuDrillIn.tsx +7 -5
- package/src/EmptyState/EmptyState.announce.test.tsx +227 -0
- package/src/EmptyState/EmptyState.doc.mjs +1 -1
- package/src/EmptyState/EmptyState.spec.md +22 -14
- package/src/EmptyState/EmptyState.test.tsx +8 -8
- package/src/EmptyState/EmptyState.tsx +7 -5
- package/src/Field/Field.spec.md +57 -48
- package/src/Field/Field.tsx +1 -1
- package/src/Field/FieldLabel.spec.md +70 -59
- package/src/Field/FieldLabel.tsx +1 -1
- package/src/Field/PanelSearchInput.tsx +23 -13
- package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +1 -0
- package/src/Field/inputDisabledFocus.ts +28 -0
- package/src/Field/inputStyles.stylex.ts +15 -15
- package/src/FieldStatus/FieldStatus.test.tsx +12 -0
- package/src/FieldStatus/FieldStatus.tsx +12 -3
- package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +1 -0
- package/src/FileInput/FileInput.doc.mjs +1 -1
- package/src/FileInput/FileInput.test.tsx +102 -0
- package/src/FileInput/FileInput.tsx +18 -12
- package/src/FormLayout/FormLayout.spec.md +69 -51
- package/src/Grid/Grid.spec.md +72 -69
- package/src/Grid/GridSpan.spec.md +158 -0
- package/src/Heading/Heading.spec.md +198 -0
- package/src/HoverCard/HoverCard.spec.md +244 -0
- package/src/HoverCard/HoverCard.test.tsx +93 -3
- package/src/Icon/Icon.doc.mjs +67 -5
- package/src/Icon/Icon.test.tsx +548 -9
- package/src/Icon/Icon.tsx +79 -15
- package/src/Icon/IconSize.stylex.ts +27 -11
- package/src/Icon/globalIconRegistry.test.tsx +395 -3
- package/src/Icon/globalIconRegistry.tsx +184 -36
- package/src/Icon/index.ts +29 -1
- package/src/Icon/useIcon.ts +5 -1
- package/src/IconButton/IconButton.spec.md +197 -0
- package/src/IconButton/IconButton.test.tsx +5 -2
- package/src/InputGroup/InputGroup.spec.md +199 -0
- package/src/InputGroup/InputGroup.test.tsx +120 -0
- package/src/InputGroup/InputGroup.tsx +59 -52
- package/src/InputGroup/InputGroupInternalContext.ts +15 -0
- package/src/InputGroup/InputGroupText.spec.md +139 -0
- package/src/InputGroup/InputGroupText.tsx +2 -0
- package/src/InputGroup/groupStyles.ts +22 -11
- package/src/Item/Item.test.tsx +158 -1
- package/src/Item/Item.tsx +42 -7
- package/src/Item/ItemMarkerColumns.a11y.chromium.spec.ts +211 -0
- package/src/Item/ItemMarkerColumnsContext.tsx +20 -0
- package/src/Item/ItemSwipeLayer.tsx +9 -0
- package/src/Item/__tests__/ItemSwipeActions.a11y.chromium.spec.ts +1 -0
- package/src/Item/__tests__/ItemSwipePinchZoom.a11y.chromium.spec.ts +186 -0
- package/src/Item/useSwipeAction.ts +71 -5
- package/src/Kbd/Kbd.test.tsx +95 -0
- package/src/Kbd/Kbd.tsx +30 -23
- package/src/Layer/LayerProvider.spec.md +149 -0
- package/src/Layer/__tests__/LayerReducedMotion.a11y.chromium.spec.ts +176 -0
- package/src/Layer/__tests__/TouchTrigger.a11y.chromium.spec.ts +200 -0
- package/src/Layer/layerAnimations.stylex.ts +22 -2
- package/src/Layer/layerDismissalInvariants.test.tsx +9 -0
- package/src/Layer/layerSlideRules.ts +141 -8
- package/src/Layer/layerStack.ts +129 -62
- package/src/Layer/modalOutlet.ts +156 -15
- package/src/Layer/preserveAnimations.ts +304 -0
- package/src/Layer/useLayer.doc.mjs +1 -1
- package/src/Layer/useLayer.test.tsx +850 -0
- package/src/Layer/useLayer.tsx +644 -58
- package/src/Layer/useLayerDismissal.test.tsx +85 -2
- package/src/Layer/useLayerDismissal.ts +12 -9
- package/src/Layer/useTouchTrigger.ts +95 -41
- package/src/Layout/Layout.tsx +18 -0
- package/src/Layout/LayoutContent.tsx +5 -14
- package/src/Layout/LayoutFooter.tsx +2 -0
- package/src/Layout/LayoutHeader.tsx +2 -0
- package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +1 -0
- package/src/Layout/layoutEdges.stylex.ts +25 -0
- package/src/Lightbox/Lightbox.spec.md +9 -8
- package/src/Lightbox/Lightbox.test.tsx +83 -0
- package/src/Lightbox/Lightbox.tsx +149 -125
- package/src/Lightbox/LightboxKeyboard.a11y.browser.spec.ts +78 -0
- package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +70 -0
- package/src/Link/Link.spec.md +229 -0
- package/src/Link/LinkProvider.spec.md +167 -0
- package/src/Link/__tests__/Link.a11y.chromium.spec.ts +1 -0
- package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +1 -0
- package/src/List/List.spec.md +113 -34
- package/src/List/List.tsx +13 -1
- package/src/List/ListContext.tsx +19 -5
- package/src/List/ListItem.doc.mjs +3 -3
- package/src/List/ListItem.tsx +97 -28
- package/src/List/ListMarkers.a11y.chromium.spec.ts +904 -0
- package/src/Markdown/Markdown.codeLanguages.test.tsx +137 -0
- package/src/Markdown/Markdown.doc.mjs +12 -0
- package/src/Markdown/Markdown.fr23.bench.ts +3 -1
- package/src/Markdown/Markdown.fr23.perf.test.ts +45 -3
- package/src/Markdown/Markdown.fr23.sampling.ts +13 -4
- package/src/Markdown/Markdown.spec.md +71 -59
- package/src/Markdown/Markdown.test.tsx +50 -0
- package/src/Markdown/Markdown.tsx +61 -8
- package/src/Markdown/MarkdownTable.a11y.chromium.spec.ts +1 -0
- package/src/Markdown/__tests__/MarkdownNesting.a11y.chromium.spec.ts +1 -0
- package/src/MobileNav/MobileNav.doc.mjs +2 -2
- package/src/MobileNav/MobileNav.spec.md +161 -64
- package/src/MobileNav/MobileNav.test.tsx +27 -10
- package/src/MobileNav/MobileNav.tsx +51 -38
- package/src/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.ts +1 -0
- package/src/MobileNav/MobileNavToggle.test.tsx +63 -0
- package/src/MobileNav/MobileNavToggle.tsx +13 -5
- package/src/MobileNav/__tests__/MobileNavWidth.a11y.chromium.spec.ts +103 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +2 -2
- package/src/MoreMenu/MoreMenu.spec.md +88 -53
- package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +67 -9
- package/src/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.ts +1 -0
- package/src/MultiSelector/MultiSelector.test.tsx +122 -10
- package/src/MultiSelector/MultiSelector.tsx +24 -4
- package/src/MultiSelector/OptionActions.a11y.chromium.spec.ts +1 -0
- package/src/MultiSelector/__tests__/MultiSelector.a11y.chromium.spec.ts +1 -0
- package/src/NavIcon/NavIcon.spec.md +66 -38
- package/src/NavMenu/NavHeadingMenu.spec.md +104 -46
- package/src/NavMenu/NavHeadingMenu.test.tsx +276 -2
- package/src/NavMenu/NavHeadingMenu.tsx +42 -4
- package/src/NavMenu/NavHeadingMenuItem.tsx +60 -6
- package/src/NavMenu/NavMenuContext.tsx +11 -0
- package/src/NavMenu/__tests__/NavMenusSlideSelection.a11y.chromium.spec.ts +137 -0
- package/src/NumberInput/NumberInput.doc.mjs +6 -6
- package/src/NumberInput/NumberInput.spec.md +248 -0
- package/src/NumberInput/NumberInput.test.tsx +187 -14
- package/src/NumberInput/NumberInput.tsx +86 -24
- package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +1 -0
- package/src/Overlay/Overlay.doc.mjs +2 -2
- package/src/Overlay/Overlay.test.tsx +72 -4
- package/src/Overlay/Overlay.tsx +18 -8
- package/src/Pagination/Pagination.test.tsx +2 -2
- package/src/Popover/Popover.doc.mjs +38 -2
- package/src/Popover/Popover.spec.md +90 -11
- package/src/Popover/Popover.test.tsx +340 -2
- package/src/Popover/Popover.tsx +401 -35
- package/src/Popover/PopoverPresentation.test.tsx +952 -0
- package/src/Popover/__tests__/PopoverSecondDocument.a11y.chromium.spec.ts +205 -0
- package/src/Popover/index.ts +5 -1
- package/src/Popover/lazyPopoverBottomSheet.ts +57 -0
- package/src/Popover/usePopover.tsx +11 -5
- package/src/PowerSearch/PowerSearch.spec.md +423 -53
- package/src/PowerSearch/PowerSearch.test.tsx +77 -1
- package/src/PowerSearch/PowerSearch.tsx +7 -5
- package/src/ProgressBar/ProgressBar.test.tsx +12 -0
- package/src/ProgressBar/ProgressBar.tsx +18 -0
- package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +1 -0
- package/src/RadioList/RadioList.spec.md +227 -0
- package/src/RadioList/RadioList.test.tsx +34 -7
- package/src/RadioList/RadioListItem.press.source-build.test.mjs +80 -0
- package/src/RadioList/RadioListItem.spec.md +223 -0
- package/src/RadioList/RadioListItem.tsx +26 -12
- package/src/RadioList/__tests__/RadioGroup.a11y.chromium.spec.ts +1 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +1 -0
- package/src/ScrollableArea/ScrollableArea.spec.md +6 -5
- package/src/ScrollableArea/ScrollableArea.test.tsx +5 -0
- package/src/ScrollableArea/ScrollableArea.tsx +4 -0
- package/src/Section/Section.spec.md +102 -44
- package/src/SegmentedControl/SegmentedControl.spec.md +162 -53
- package/src/SegmentedControl/SegmentedControl.test.tsx +46 -0
- package/src/SegmentedControl/SegmentedControl.tsx +7 -3
- package/src/SegmentedControl/SegmentedControlItem.spec.md +206 -0
- package/src/SelectableCard/SelectableCard.doc.mjs +7 -6
- package/src/SelectableCard/SelectableCard.spec.md +230 -0
- package/src/SelectableCard/SelectableCard.test.tsx +11 -1
- package/src/SelectableCard/SelectableCard.tsx +49 -33
- package/src/Selector/Selector.sheetActiveDescendant.test.tsx +95 -0
- package/src/Selector/Selector.spec.md +12 -4
- package/src/Selector/Selector.test.tsx +114 -8
- package/src/Selector/Selector.tsx +30 -6
- package/src/Selector/__tests__/ComboboxField.a11y.chromium.spec.ts +458 -0
- package/src/Selector/__tests__/EmptyStateAnnouncement.a11y.chromium.spec.ts +1 -0
- package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +1 -0
- package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +1 -0
- package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +1 -0
- package/src/Selector/hooks.ts +234 -10
- package/src/Selector/useCombobox.doc.mjs +156 -9
- package/src/Selector/useCombobox.public.test.tsx +89 -0
- package/src/Selector/useCombobox.test.tsx +444 -0
- package/src/SideNav/SideNav.spec.md +50 -30
- package/src/SideNav/SideNav.test.tsx +425 -25
- package/src/SideNav/SideNav.tsx +85 -1
- package/src/SideNav/SideNavCollapseButton.spec.md +161 -0
- package/src/SideNav/SideNavHeading.spec.md +226 -0
- package/src/SideNav/SideNavHeading.tsx +102 -6
- package/src/SideNav/SideNavItem.spec.md +246 -0
- package/src/SideNav/SideNavItem.tsx +40 -9
- package/src/SideNav/SideNavRailMotion.test.tsx +620 -0
- package/src/SideNav/SideNavSection.spec.md +153 -0
- package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +417 -0
- package/src/SideNav/railMotion.ts +315 -0
- package/src/Skeleton/Skeleton.spec.md +99 -42
- package/src/Skeleton/Skeleton.test.tsx +108 -1
- package/src/Skeleton/Skeleton.tsx +30 -2
- package/src/Slider/Slider.fr10.test.tsx +34 -0
- package/src/Slider/Slider.test.tsx +172 -0
- package/src/Slider/Slider.tsx +70 -14
- package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +1 -0
- package/src/Spinner/Spinner.spec.md +231 -0
- package/src/Stack/Stack.spec.md +104 -56
- package/src/StatusDot/StatusDot.spec.md +139 -51
- package/src/StatusDot/StatusDot.test.tsx +13 -0
- package/src/StatusDot/StatusDot.tsx +27 -0
- package/src/Stepper/Step.spec.md +206 -0
- package/src/Stepper/Step.tsx +19 -3
- package/src/Stepper/Stepper.test.tsx +50 -0
- package/src/Switch/Switch.focusRing.source-build.test.mjs +81 -0
- package/src/Switch/Switch.spec.md +150 -66
- package/src/Switch/Switch.tsx +11 -9
- package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +1 -0
- package/src/Switch/switch.markers.stylex.ts +7 -2
- package/src/TabList/Tab.spec.md +201 -0
- package/src/TabList/Tab.tsx +7 -1
- package/src/TabList/TabList.doc.mjs +3 -3
- package/src/TabList/TabList.test.tsx +27 -0
- package/src/TabList/TabMenu.spec.md +198 -0
- package/src/TabList/TabMenu.tsx +24 -1
- package/src/TabList/__tests__/TabListOverflow.interaction.browser.spec.ts +99 -0
- package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +1 -0
- package/src/Table/Table.spec.md +54 -30
- package/src/Table/TableCell.tsx +9 -0
- package/src/Table/TableHeaderCell.tsx +2 -0
- package/src/Table/TableRow.tsx +3 -0
- package/src/Table/__tests__/Table.a11y.chromium.spec.ts +129 -0
- package/src/Table/__tests__/Table.a11y.contracts.ts +35 -0
- package/src/Table/__tests__/Table.a11y.renders.tsx +112 -0
- package/src/Table/__tests__/Table.a11y.states.ts +140 -0
- package/src/Table/__tests__/Table.a11y.test.tsx +198 -0
- package/src/Table/__tests__/TableMinWidth.a11y.chromium.spec.ts +1 -0
- package/src/Table/__tests__/TableRowGlide.a11y.browser.spec.ts +382 -0
- package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +1 -0
- package/src/Table/__tests__/TableStickyDividers.a11y.browser.spec.ts +560 -0
- package/src/Table/glidingDivider.ts +336 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +23 -8
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.glide.test.tsx +280 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +91 -9
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +471 -10
- package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +4 -4
- package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.test.tsx +174 -0
- package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.ts +86 -0
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +0 -12
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +51 -1
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +312 -12
- package/src/Table/rowDivider.ts +154 -0
- package/src/Table/useTableRowExpansion.doc.mjs +8 -0
- package/src/Text/Text.spec.md +114 -127
- package/src/TextArea/TextArea.doc.mjs +6 -6
- package/src/TextArea/TextArea.spec.md +164 -64
- package/src/TextArea/TextArea.test.tsx +65 -6
- package/src/TextArea/TextArea.tsx +27 -15
- package/src/TextInput/TextInput.doc.mjs +8 -8
- package/src/TextInput/TextInput.spec.md +260 -0
- package/src/TextInput/TextInput.test.tsx +126 -10
- package/src/TextInput/TextInput.tsx +57 -23
- package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +1 -0
- package/src/Thumbnail/Thumbnail.doc.mjs +1 -2
- package/src/Thumbnail/Thumbnail.spec.md +244 -0
- package/src/Thumbnail/Thumbnail.test.tsx +120 -7
- package/src/Thumbnail/Thumbnail.tsx +77 -31
- package/src/TimeInput/TimeInput.spec.md +273 -0
- package/src/TimeInput/TimeInput.tsx +12 -4
- package/src/TimeInput/TouchTimeField.tsx +2 -1
- package/src/Timestamp/Timestamp.spec.md +252 -0
- package/src/Toast/Toast.spec.md +300 -0
- package/src/Toast/ToastViewport.modalHost.test.tsx +630 -5
- package/src/Toast/ToastViewport.test.tsx +137 -0
- package/src/Toast/ToastViewport.tsx +63 -6
- package/src/ToggleButton/ToggleButton.spec.md +256 -0
- package/src/ToggleButton/ToggleButtonGroup.spec.md +195 -0
- package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +1 -0
- package/src/Token/Token.spec.md +271 -0
- package/src/Token/__tests__/TokenRemoveTarget.a11y.chromium.spec.ts +1 -0
- package/src/Tokenizer/Tokenizer.props-type.test.tsx +126 -0
- package/src/Tokenizer/Tokenizer.spec.md +313 -72
- package/src/Tokenizer/Tokenizer.ssr.test.tsx +196 -0
- package/src/Tokenizer/Tokenizer.test.tsx +44 -8
- package/src/Tokenizer/Tokenizer.tsx +586 -41
- package/src/Tokenizer/TokenizerBottomSheet.test.tsx +2719 -0
- package/src/Tokenizer/TokenizerBottomSheet.tsx +957 -0
- package/src/Tokenizer/__tests__/TokenizerEndLane.a11y.chromium.spec.ts +61 -27
- package/src/Toolbar/Toolbar.spec.md +103 -49
- package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +1 -0
- package/src/Tooltip/Tooltip.spec.md +161 -36
- package/src/Tooltip/Tooltip.test.tsx +171 -3
- package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +1 -0
- package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +2 -2
- package/src/Tooltip/__tests__/TooltipFocusReturn.a11y.chromium.spec.ts +1 -0
- package/src/Tooltip/__tests__/TooltipHoverBridge.a11y.chromium.spec.ts +1 -0
- package/src/Tooltip/__tests__/TooltipTallContent.a11y.browser.spec.ts +673 -0
- package/src/Tooltip/__tests__/TooltipTallContentTracking.a11y.browser.spec.ts +1162 -0
- package/src/Tooltip/useTooltip.tsx +7 -2
- package/src/TopNav/TopNav.spec.md +190 -0
- package/src/TopNav/TopNav.test.tsx +89 -0
- package/src/TopNav/TopNavHeading.spec.md +211 -0
- package/src/TopNav/TopNavHeading.tsx +35 -2
- package/src/TopNav/TopNavItem.spec.md +189 -0
- package/src/TopNav/TopNavMegaMenu.reduced-motion.source-build.test.mjs +83 -0
- package/src/TopNav/TopNavMegaMenu.spec.md +190 -0
- package/src/TopNav/TopNavMegaMenu.tsx +21 -4
- package/src/TopNav/TopNavMegaMenuFeaturedCard.spec.md +150 -0
- package/src/TopNav/TopNavMegaMenuItem.spec.md +155 -0
- package/src/TopNav/TopNavMenu.spec.md +202 -0
- package/src/TopNav/TopNavMenu.test.tsx +65 -1
- package/src/TopNav/TopNavMenu.tsx +30 -1
- package/src/TopNav/__tests__/TopNavMobileLongHeading.a11y.chromium.spec.ts +1 -0
- package/src/TreeList/TreeList.doc.mjs +13 -0
- package/src/TreeList/TreeList.spec.md +54 -35
- package/src/TreeList/TreeList.tsx +234 -2
- package/src/TreeList/TreeListBranches.tsx +8 -6
- package/src/TreeList/TreeListItem.tsx +12 -6
- package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +19 -6
- package/src/TreeList/__tests__/TreeListGuideAlignment.interaction.browser.spec.ts +127 -0
- package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +1 -0
- package/src/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.ts +138 -0
- package/src/Typeahead/BaseTypeahead.test.tsx +201 -4
- package/src/Typeahead/BaseTypeahead.tsx +26 -10
- package/src/Typeahead/Typeahead.test.tsx +114 -1
- package/src/Typeahead/Typeahead.tsx +34 -16
- package/src/VisuallyHidden/VisuallyHidden.spec.md +170 -0
- package/src/__tests__/BusyOwnerAnnouncement.test.tsx +66 -5
- package/src/__tests__/CardPress.a11y.chromium.spec.ts +353 -0
- package/src/__tests__/DisabledTriggerFocus.a11y.chromium.spec.ts +2 -1
- package/src/__tests__/PressModality.a11y.chromium.spec.ts +392 -0
- package/src/__tests__/PressedState.a11y.chromium.spec.ts +1 -0
- package/src/__tests__/pressState.ts +43 -1
- package/src/__tests__/unthemedLength.ts +34 -0
- package/src/gestures/GestureArena.ts +966 -0
- package/src/gestures/GestureRecognizer.ts +626 -0
- package/src/gestures/LongPressGestureRecognizer.ts +186 -0
- package/src/gestures/PanGestureRecognizer.ts +410 -0
- package/src/gestures/TapGestureRecognizer.ts +192 -0
- package/src/gestures/VelocityTracker.ts +194 -0
- package/src/gestures/__tests__/LongPressGestureRecognizer.test.ts +141 -0
- package/src/gestures/__tests__/PanGestureRecognizer.test.ts +327 -0
- package/src/gestures/__tests__/TapGestureRecognizer.test.ts +154 -0
- package/src/gestures/__tests__/VelocityTracker.streams.test.ts +243 -0
- package/src/gestures/__tests__/VelocityTracker.test.ts +261 -0
- package/src/gestures/__tests__/arena.test.ts +824 -0
- package/src/gestures/__tests__/arenaContinuous.test.ts +207 -0
- package/src/gestures/__tests__/arenaTapLongPress.test.ts +211 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/README.md +82 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-fling.json +130 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-slow.json +860 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-stop-release.json +357 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-fling.json +66 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-slow.json +268 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-stop-release.json +128 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/capture.html +123 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-fling.json +64 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-slow.json +268 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-stop-release.json +124 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-fling.json +64 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-slow.json +268 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-stop-release.json +124 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-fling.json +84 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-slow.json +381 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-stop-release.json +171 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-fling.json +45 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-slow.json +101 -0
- package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-stop-release.json +130 -0
- package/src/gestures/__tests__/harness.ts +204 -0
- package/src/gestures/geometry.ts +55 -0
- package/src/gestures/types.ts +161 -0
- package/src/hooks/AnnounceRenderedText.tsx +27 -0
- package/src/hooks/ModalAnnounceProvider.tsx +155 -0
- package/src/hooks/__tests__/MenuPressShadowRoot.a11y.chromium.spec.ts +98 -4
- package/src/hooks/__tests__/menuLinkClicks.ts +71 -0
- package/src/hooks/actionGroupTracker.exports.test.ts +28 -0
- package/src/hooks/actionGroupTracker.test.ts +510 -0
- package/src/hooks/actionGroupTracker.ts +449 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/menuPressOnItems.ts +40 -0
- package/src/hooks/modalAnnounce.ts +439 -0
- package/src/hooks/scrollGeometry.ts +71 -4
- package/src/hooks/useAdaptivePresentation.ts +46 -9
- package/src/hooks/useAnimatedLayout.doc.mjs +101 -0
- package/src/hooks/useAnimatedLayout.ts +61 -0
- package/src/hooks/useAnnounce.doc.mjs +4 -4
- package/src/hooks/useAnnounce.modal.test.tsx +1291 -0
- package/src/hooks/useAnnounce.test.tsx +64 -4
- package/src/hooks/useAnnounce.ts +452 -28
- package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +226 -0
- package/src/hooks/useAnnounceRenderedText.ts +81 -11
- package/src/hooks/useBusyAnnouncement.adopters.test.tsx +69 -0
- package/src/hooks/useBusyAnnouncement.test.tsx +112 -0
- package/src/hooks/useBusyAnnouncement.ts +64 -54
- package/src/hooks/useFocusTrap.doc.mjs +3 -3
- package/src/hooks/useFocusTrap.test.tsx +135 -2
- package/src/hooks/useFocusTrap.ts +59 -27
- package/src/hooks/useMenuHover.ts +6 -2
- package/src/hooks/useMenuPress.doc.mjs +2 -2
- package/src/hooks/useMenuPress.test.tsx +5 -2
- package/src/hooks/useMenuPress.ts +72 -37
- package/src/hooks/usePressFeedback.doc.mjs +4 -4
- package/src/hooks/usePressFeedback.ts +5 -2
- package/src/hooks/useScrollableArea.test.tsx +344 -3
- package/src/hooks/useScrollableArea.ts +120 -12
- package/src/i18n/generated-locales/en.generated.ts +35 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +37 -0
- package/src/internal/tokenizer-presentation.test.ts +29 -0
- package/src/internal/tokenizer-presentation.ts +25 -0
- package/src/internal/touch.test.ts +44 -0
- package/src/internal/touch.ts +41 -0
- package/src/motion/LayoutChangeSnapshot.tsx +50 -0
- package/src/motion/MEASUREMENTS.md +271 -0
- package/src/motion/README.md +218 -0
- package/src/motion/__tests__/animatedLayout.interaction.browser.spec.ts +1613 -0
- package/src/motion/__tests__/animatedLayoutAdopters.interaction.browser.spec.ts +217 -0
- package/src/motion/__tests__/animatedLayoutBundle.ts +17 -0
- package/src/motion/animatedLayout.boundary.test.ts +155 -0
- package/src/motion/animatedLayout.swap.test.ts +827 -0
- package/src/motion/animatedLayout.test.ts +1154 -0
- package/src/motion/animatedLayout.ts +1801 -0
- package/src/motion/animatedLayoutAdopters.test.tsx +500 -0
- package/src/motion/animator.test.ts +2653 -0
- package/src/motion/animator.ts +2794 -0
- package/src/motion/bezier.test.ts +52 -0
- package/src/motion/bezier.ts +64 -0
- package/src/motion/coast.test.ts +99 -0
- package/src/motion/coast.ts +150 -0
- package/src/motion/decay.test.ts +120 -0
- package/src/motion/decay.ts +126 -0
- package/src/motion/projection.test.ts +107 -0
- package/src/motion/projection.ts +116 -0
- package/src/motion/reducedMotion.stylex.ts +41 -0
- package/src/motion/reducedMotion.test.ts +129 -0
- package/src/motion/reducedMotion.ts +94 -0
- package/src/motion/reducedMotionPlan.test.ts +182 -0
- package/src/motion/reducedMotionPlan.ts +263 -0
- package/src/motion/resolveSnapPoint.test.ts +189 -0
- package/src/motion/resolveSnapPoint.ts +169 -0
- package/src/motion/roleValue.ts +105 -0
- package/src/motion/roles.test.ts +256 -0
- package/src/motion/roles.ts +262 -0
- package/src/motion/rubberBand.test.ts +88 -0
- package/src/motion/rubberBand.ts +115 -0
- package/src/motion/selectPage.test.ts +31 -0
- package/src/motion/selectPage.ts +55 -0
- package/src/motion/spring.test.ts +650 -0
- package/src/motion/spring.ts +551 -0
- package/src/motion/transientCopy.ts +374 -0
- package/src/motion/uikit/gestures.test.ts +89 -0
- package/src/motion/uikit/gestures.ts +359 -0
- package/src/motion/uikit/index.ts +80 -0
- package/src/motion/uikit/navigation.ts +83 -0
- package/src/motion/uikit/scroll.ts +141 -0
- package/src/motion/uikit/springRows.test.ts +71 -0
- package/src/motion/uikit/springs.ts +514 -0
- package/src/motion/uikit/timing.ts +210 -0
- package/src/motion/uikit/uikit.test.ts +364 -0
- package/src/motion/uikit/values.test.ts +110 -0
- package/src/reset.a11y.chromium.spec.ts +1 -0
- package/src/reset.until-found.a11y.browser.spec.ts +1 -0
- package/src/serverSafeComponents.test.ts +10 -0
- package/src/tailwind-theme.css +51 -1
- package/src/tailwind-theme.test.ts +51 -0
- package/src/theme/Theme.test.tsx +28 -0
- package/src/theme/__tests__/SpacingRootFontSize.a11y.chromium.spec.ts +1 -0
- package/src/theme/declarationBoundary.ts +282 -1
- package/src/theme/defineTheme.test.ts +529 -12
- package/src/theme/defineTheme.ts +231 -19
- package/src/theme/derivedVarRegistry.test.ts +34 -5
- package/src/theme/derivedVarRegistry.ts +4 -0
- package/src/theme/expandMotionScale.test.ts +17 -0
- package/src/theme/extensibleAxes.test.ts +74 -29
- package/src/theme/generateThemeRules.ts +772 -35
- package/src/theme/index.ts +3 -0
- package/src/theme/onMediaTokens.test.ts +186 -0
- package/src/theme/statusColor.ts +189 -0
- package/src/theme/statusRoleDerivation.ts +289 -0
- package/src/theme/syntax/SyntaxTheme.tsx +1 -1
- package/src/theme/syntax/defineSyntaxTheme.ts +1 -1
- package/src/theme/syntax/presets.ts +1 -1
- package/src/theme/syntax/tokens.ts +1 -1
- package/src/theme/themeAdaptations.test.ts +412 -0
- package/src/theme/themeAdaptations.ts +43 -1
- package/src/theme/tokens.stylex.ts +36 -2
- package/src/theme/tokens.test.ts +111 -1
- package/src/theme/tokens.ts +23 -1
- package/src/theme/useTheme.ts +10 -4
- package/src/utils/customPropertyArmLayering.test.ts +131 -0
- package/src/utils/edgeAutoscroll.test.ts +192 -0
- package/src/utils/edgeAutoscroll.ts +111 -0
- package/src/utils/hitArea.test.ts +628 -0
- package/src/utils/hitArea.ts +770 -0
- package/src/utils/interactionOverlay.stylex.ts +4 -1
- package/src/utils/pressFeedback.test.ts +310 -2
- package/src/utils/pressFeedback.ts +306 -54
- package/src/utils/pressGesture.test.ts +50 -0
- package/src/utils/pressGesture.ts +40 -2
- package/src/utils/touchPresentation.test.ts +323 -0
- package/src/utils/touchPresentation.ts +153 -0
|
@@ -0,0 +1,1162 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file TooltipTallContentTracking.a11y.browser.spec.ts
|
|
5
|
+
* @input The `Core/Tooltip` TallContent and TallContentReplacedTrigger
|
|
6
|
+
* stories in a built Storybook, and real keyboard input and scrolling.
|
|
7
|
+
* @output Real-engine proof, in Chromium and WebKit, that an open tooltip
|
|
8
|
+
* that keeps its trigger clear follows a same-size trigger that moves on
|
|
9
|
+
* screen, in layout or because the page scrolled: at most the first painted
|
|
10
|
+
* frame after the move shows it over the trigger, a smooth scroll is
|
|
11
|
+
* followed through every frame and later moves are still observed (also
|
|
12
|
+
* after a scrolled container has hidden the trigger), it
|
|
13
|
+
* ends on the roomier side at a readable size, a scroll alone never
|
|
14
|
+
* switches a tooltip that fits, and placing a shown tooltip afresh keeps
|
|
15
|
+
* every animation in its content in its exact state.
|
|
16
|
+
* @position Run with `pnpm test:a11y-contract` (Chromium) and
|
|
17
|
+
* `pnpm exec playwright test TooltipTallContentTracking --project webkit`.
|
|
18
|
+
* The tracking reads geometry after paint, which only a real engine paints.
|
|
19
|
+
*
|
|
20
|
+
* SYNC: Fixtures live in /apps/storybook/stories/Tooltip.stories.tsx
|
|
21
|
+
* (TallContent, TallContentReplacedTrigger).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import {expect, test, type Page} from '@playwright/test';
|
|
25
|
+
import {holdMotionStill} from '@astryxdesign/a11y-spec/chromium';
|
|
26
|
+
import {
|
|
27
|
+
DEFAULT_STORYBOOK_DIR,
|
|
28
|
+
serveStorybook,
|
|
29
|
+
type StaticServer,
|
|
30
|
+
} from '@astryxdesign/a11y-spec/storybook';
|
|
31
|
+
|
|
32
|
+
let storybook: StaticServer;
|
|
33
|
+
|
|
34
|
+
test.beforeAll(async () => {
|
|
35
|
+
storybook = await serveStorybook(
|
|
36
|
+
process.env.ASTRYX_STORYBOOK_DIR ?? DEFAULT_STORYBOOK_DIR,
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test.afterAll(async () => {
|
|
41
|
+
await storybook?.close();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
interface Box {
|
|
45
|
+
top: number;
|
|
46
|
+
bottom: number;
|
|
47
|
+
left: number;
|
|
48
|
+
right: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function overlaps(a: Box, b: Box): boolean {
|
|
52
|
+
return (
|
|
53
|
+
a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function rect(page: Page, selector: string): Promise<Box> {
|
|
58
|
+
return page.evaluate(sel => {
|
|
59
|
+
const el = document.querySelector(sel);
|
|
60
|
+
if (el == null) {
|
|
61
|
+
throw new Error(`${sel} is not in the document`);
|
|
62
|
+
}
|
|
63
|
+
const r = el.getBoundingClientRect();
|
|
64
|
+
return {top: r.top, bottom: r.bottom, left: r.left, right: r.right};
|
|
65
|
+
}, selector);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** The story's trigger; Storybook's own buttons share the iframe. */
|
|
69
|
+
const TRIGGER = '#storybook-root button';
|
|
70
|
+
const TOOLTIP = '[role="tooltip"]';
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The replacement trigger in the TallContentReplacedTrigger story, once
|
|
74
|
+
* `openReplacedTrigger` has marked it.
|
|
75
|
+
*/
|
|
76
|
+
const TRIGGER_2 = '[data-test-replacement]';
|
|
77
|
+
|
|
78
|
+
interface Frame {
|
|
79
|
+
tooltip: Box;
|
|
80
|
+
trigger: Box;
|
|
81
|
+
/** The tooltip's visible content height in that frame. */
|
|
82
|
+
tooltipHeight: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Apply `style` to the element `selector` names, then read the tooltip's and
|
|
87
|
+
* that element's boxes as each of the next eight frames painted them.
|
|
88
|
+
*/
|
|
89
|
+
async function moveAndSampleFrames(
|
|
90
|
+
page: Page,
|
|
91
|
+
selector: string,
|
|
92
|
+
style: Partial<
|
|
93
|
+
Record<
|
|
94
|
+
'marginBlockEnd' | 'blockSize' | 'position' | 'insetBlockStart',
|
|
95
|
+
string
|
|
96
|
+
>
|
|
97
|
+
>,
|
|
98
|
+
): Promise<Frame[]> {
|
|
99
|
+
return page.evaluate(
|
|
100
|
+
async ({sel, tip, changes}) => {
|
|
101
|
+
const box = (el: Element) => {
|
|
102
|
+
const r = el.getBoundingClientRect();
|
|
103
|
+
return {top: r.top, bottom: r.bottom, left: r.left, right: r.right};
|
|
104
|
+
};
|
|
105
|
+
const el = document.querySelector<HTMLElement>(sel);
|
|
106
|
+
if (el == null) {
|
|
107
|
+
throw new Error(`${sel} is not in the document`);
|
|
108
|
+
}
|
|
109
|
+
Object.assign(el.style, changes);
|
|
110
|
+
const frames: {tooltip: Box; trigger: Box; tooltipHeight: number}[] = [];
|
|
111
|
+
// A message posted from a frame callback runs as the first task after
|
|
112
|
+
// that frame has painted, before the tasks the frame itself queued
|
|
113
|
+
// (intersection observer callbacks among them), so it reads what the
|
|
114
|
+
// frame painted.
|
|
115
|
+
const afterPaint = async () =>
|
|
116
|
+
new Promise<void>(resolve => {
|
|
117
|
+
requestAnimationFrame(() => {
|
|
118
|
+
const channel = new MessageChannel();
|
|
119
|
+
channel.port1.onmessage = () => resolve();
|
|
120
|
+
channel.port2.postMessage(null);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
for (let i = 0; i < 8; i++) {
|
|
124
|
+
await afterPaint();
|
|
125
|
+
const t = document.querySelector(tip);
|
|
126
|
+
if (t != null) {
|
|
127
|
+
frames.push({
|
|
128
|
+
tooltip: box(t),
|
|
129
|
+
trigger: box(el),
|
|
130
|
+
tooltipHeight: (t as HTMLElement).clientHeight,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return frames;
|
|
135
|
+
},
|
|
136
|
+
{sel: selector, tip: TOOLTIP, changes: style},
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** At most the first painted frame after a move may show the overlap. */
|
|
141
|
+
function expectClearFromSecondFrame(frames: Frame[]) {
|
|
142
|
+
expect(frames.length).toBe(8);
|
|
143
|
+
for (const [i, frame] of frames.entries()) {
|
|
144
|
+
if (i === 0) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
expect(
|
|
148
|
+
overlaps(frame.tooltip, frame.trigger),
|
|
149
|
+
`painted frame ${i + 1} after the move covers the trigger`,
|
|
150
|
+
).toBe(false);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Open the TallContentReplacedTrigger story, whose trigger sits near the
|
|
156
|
+
* bottom of the viewport where the held-open tooltip fits above it, then
|
|
157
|
+
* replace the trigger with a new element in the same place. Returns the
|
|
158
|
+
* replacement's top.
|
|
159
|
+
*/
|
|
160
|
+
async function openReplacedTrigger(page: Page): Promise<number> {
|
|
161
|
+
await page.setViewportSize({width: 1280, height: 720});
|
|
162
|
+
await page.goto(
|
|
163
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content-replaced-trigger&viewMode=story`,
|
|
164
|
+
);
|
|
165
|
+
await holdMotionStill(page);
|
|
166
|
+
const first = page.getByRole('button', {name: 'Trigger 1'});
|
|
167
|
+
await expect(first).toBeVisible();
|
|
168
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
169
|
+
await page.waitForTimeout(200);
|
|
170
|
+
// It opened above the first trigger, on its standard list.
|
|
171
|
+
expect(
|
|
172
|
+
await page.evaluate(sel => {
|
|
173
|
+
const el = document.querySelector(sel);
|
|
174
|
+
return el?.hasAttribute('data-astryx-clears-anchor');
|
|
175
|
+
}, TOOLTIP),
|
|
176
|
+
).toBe(false);
|
|
177
|
+
await page.getByRole('button', {name: 'Replace the trigger'}).click();
|
|
178
|
+
const second = page.getByRole('button', {name: 'Trigger 2'});
|
|
179
|
+
await expect(second).toBeVisible();
|
|
180
|
+
await second.evaluate(el => el.setAttribute('data-test-replacement', ''));
|
|
181
|
+
await page.waitForTimeout(200);
|
|
182
|
+
const t = await second.boundingBox();
|
|
183
|
+
if (t == null) {
|
|
184
|
+
throw new Error('the replacement trigger has no layout box');
|
|
185
|
+
}
|
|
186
|
+
expect(overlaps(await rect(page, TOOLTIP), await rect(page, TRIGGER_2))).toBe(
|
|
187
|
+
false,
|
|
188
|
+
);
|
|
189
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
190
|
+
return t.y;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
test('a trigger that moves in layout while its tooltip is open, without resizing or scrolling, is kept clear', async ({
|
|
194
|
+
page,
|
|
195
|
+
browserName,
|
|
196
|
+
}) => {
|
|
197
|
+
await page.setViewportSize({width: 1280, height: 720});
|
|
198
|
+
await page.goto(
|
|
199
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story&args=content:A+short+tooltip`,
|
|
200
|
+
);
|
|
201
|
+
await holdMotionStill(page);
|
|
202
|
+
const trigger = page.getByRole('button', {name: 'Hover for details'});
|
|
203
|
+
await expect(trigger).toBeVisible();
|
|
204
|
+
// The trigger's top at 650px, near the bottom of a 720px viewport.
|
|
205
|
+
await page.evaluate(sel => {
|
|
206
|
+
const el = document.querySelector(sel) as HTMLElement;
|
|
207
|
+
window.scrollBy(0, el.getBoundingClientRect().top - 650);
|
|
208
|
+
}, TRIGGER);
|
|
209
|
+
// Opened from the keyboard, so no pointer is involved.
|
|
210
|
+
await trigger.focus();
|
|
211
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
212
|
+
// Its content becomes 368px tall: it still fits above the trigger.
|
|
213
|
+
await page.evaluate(sel => {
|
|
214
|
+
const content = document.querySelector(sel)?.firstElementChild;
|
|
215
|
+
for (let i = 1; i <= 17; i++) {
|
|
216
|
+
const line = document.createElement('div');
|
|
217
|
+
line.textContent = `Line ${i}`;
|
|
218
|
+
content?.appendChild(line);
|
|
219
|
+
}
|
|
220
|
+
}, TOOLTIP);
|
|
221
|
+
await page.waitForTimeout(200);
|
|
222
|
+
const before = await rect(page, TRIGGER);
|
|
223
|
+
expect(overlaps(await rect(page, TOOLTIP), before)).toBe(false);
|
|
224
|
+
const scrollY = await page.evaluate(() => window.scrollY);
|
|
225
|
+
|
|
226
|
+
// The same-size trigger moves up to 340px in layout. Nothing resizes or
|
|
227
|
+
// scrolls; now the tooltip fits neither above nor below it. Only an
|
|
228
|
+
// intersection observer reports that move, after the frame that shows it
|
|
229
|
+
// has painted, so at most that first painted frame may show the overlap;
|
|
230
|
+
// the frame after it must not.
|
|
231
|
+
const frames = await moveAndSampleFrames(page, TRIGGER, {
|
|
232
|
+
position: 'relative',
|
|
233
|
+
insetBlockStart: '-310px',
|
|
234
|
+
});
|
|
235
|
+
// WebKit scrolls the page itself when an open popover's anchor moves (it
|
|
236
|
+
// does on the base too), so the trigger's move is measured in the document.
|
|
237
|
+
const after = await rect(page, TRIGGER);
|
|
238
|
+
const scrolled = (await page.evaluate(() => window.scrollY)) - scrollY;
|
|
239
|
+
expect(Math.round(after.top + scrolled)).toBe(Math.round(before.top) - 310);
|
|
240
|
+
if (browserName === 'chromium') {
|
|
241
|
+
// A pure layout move: nothing scrolled.
|
|
242
|
+
expect(scrolled).toBe(0);
|
|
243
|
+
}
|
|
244
|
+
expect(after.bottom - after.top).toBe(before.bottom - before.top);
|
|
245
|
+
expectClearFromSecondFrame(frames);
|
|
246
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
247
|
+
expect(overlaps(await rect(page, TOOLTIP), after)).toBe(false);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
test('a held-open tooltip keeps a replaced trigger clear when the replacement moves', async ({
|
|
251
|
+
page,
|
|
252
|
+
}) => {
|
|
253
|
+
const top = await openReplacedTrigger(page);
|
|
254
|
+
const frames = await moveAndSampleFrames(page, TRIGGER_2, {
|
|
255
|
+
marginBlockEnd: '310px',
|
|
256
|
+
});
|
|
257
|
+
const after = await rect(page, TRIGGER_2);
|
|
258
|
+
expect(Math.round(after.top)).toBe(Math.round(top) - 310);
|
|
259
|
+
expect(Math.round(after.bottom - after.top)).toBe(32);
|
|
260
|
+
expectClearFromSecondFrame(frames);
|
|
261
|
+
expect(overlaps(await rect(page, TOOLTIP), after)).toBe(false);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* From the second painted frame after a move, the tooltip is clear of the
|
|
266
|
+
* trigger, inside the viewport, on the block side with more room, and tall
|
|
267
|
+
* enough to read.
|
|
268
|
+
*/
|
|
269
|
+
function expectReadableOnRoomierSide(frames: Frame[], viewportHeight: number) {
|
|
270
|
+
expectClearFromSecondFrame(frames);
|
|
271
|
+
for (const [i, {tooltip, trigger, tooltipHeight}] of frames.entries()) {
|
|
272
|
+
if (i === 0) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
expect(tooltip.top).toBeGreaterThanOrEqual(0);
|
|
276
|
+
expect(tooltip.bottom).toBeLessThanOrEqual(viewportHeight);
|
|
277
|
+
expect(
|
|
278
|
+
tooltipHeight,
|
|
279
|
+
`painted frame ${i + 1} squeezes the tooltip to ${tooltipHeight}px`,
|
|
280
|
+
).toBeGreaterThan(200);
|
|
281
|
+
if (trigger.top > viewportHeight - trigger.bottom) {
|
|
282
|
+
expect(tooltip.bottom).toBeLessThanOrEqual(trigger.top);
|
|
283
|
+
} else {
|
|
284
|
+
expect(tooltip.top).toBeGreaterThanOrEqual(trigger.bottom);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Focus the trigger of a 60-line tooltip on a phone, with the trigger's centre
|
|
291
|
+
* at `triggerY`, and wait until the tooltip has switched to its anchor-clear
|
|
292
|
+
* list.
|
|
293
|
+
*/
|
|
294
|
+
async function focusTallTriggerOnPhone(page: Page, triggerY: number) {
|
|
295
|
+
await page.setViewportSize({width: 390, height: 700});
|
|
296
|
+
await page.goto(
|
|
297
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story`,
|
|
298
|
+
);
|
|
299
|
+
await holdMotionStill(page);
|
|
300
|
+
const trigger = page.getByRole('button', {name: 'Hover for details'});
|
|
301
|
+
await expect(trigger).toBeVisible();
|
|
302
|
+
await page.evaluate(
|
|
303
|
+
([sel, y]) => {
|
|
304
|
+
const el = document.querySelector(sel as string) as HTMLElement;
|
|
305
|
+
const r = el.getBoundingClientRect();
|
|
306
|
+
window.scrollBy(0, r.top + r.height / 2 - (y as number));
|
|
307
|
+
},
|
|
308
|
+
[TRIGGER, triggerY],
|
|
309
|
+
);
|
|
310
|
+
await trigger.focus();
|
|
311
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
312
|
+
await page.waitForTimeout(200);
|
|
313
|
+
expect(
|
|
314
|
+
await page.evaluate(
|
|
315
|
+
sel =>
|
|
316
|
+
document.querySelector(sel)?.hasAttribute('data-astryx-clears-anchor'),
|
|
317
|
+
TOOLTIP,
|
|
318
|
+
),
|
|
319
|
+
).toBe(true);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
test('a switched tooltip whose trigger moves toward the far edge moves to the roomier side, readable', async ({
|
|
323
|
+
page,
|
|
324
|
+
}) => {
|
|
325
|
+
// The 390×700 case: opened below a trigger in the upper half, the tooltip
|
|
326
|
+
// must not stay below, squeezed to a sliver, once the trigger moves down.
|
|
327
|
+
await focusTallTriggerOnPhone(page, 200);
|
|
328
|
+
const before = await rect(page, TOOLTIP);
|
|
329
|
+
const trigger = await rect(page, TRIGGER);
|
|
330
|
+
expect(before.top).toBeGreaterThanOrEqual(trigger.bottom);
|
|
331
|
+
const frames = await moveAndSampleFrames(page, TRIGGER, {
|
|
332
|
+
position: 'relative',
|
|
333
|
+
insetBlockStart: '460px',
|
|
334
|
+
});
|
|
335
|
+
expectReadableOnRoomierSide(frames, 700);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
test('a switched tooltip whose trigger moves the other way moves to the roomier side, readable', async ({
|
|
339
|
+
page,
|
|
340
|
+
}) => {
|
|
341
|
+
// Opened above a trigger in the lower half, then the trigger moves up.
|
|
342
|
+
await focusTallTriggerOnPhone(page, 500);
|
|
343
|
+
const before = await rect(page, TOOLTIP);
|
|
344
|
+
const trigger = await rect(page, TRIGGER);
|
|
345
|
+
expect(before.bottom).toBeLessThanOrEqual(trigger.top);
|
|
346
|
+
const frames = await moveAndSampleFrames(page, TRIGGER, {
|
|
347
|
+
position: 'relative',
|
|
348
|
+
insetBlockStart: '-400px',
|
|
349
|
+
});
|
|
350
|
+
expectReadableOnRoomierSide(frames, 700);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
test('a tooltip that switches lists after it has painted is placed afresh, not left on its old option', async ({
|
|
354
|
+
page,
|
|
355
|
+
}) => {
|
|
356
|
+
// A held-open short tooltip paints above its trigger, then grows to 368px
|
|
357
|
+
// and its trigger moves up: the old option leaves the box past the top of
|
|
358
|
+
// the viewport, so the tooltip switches lists while it is showing.
|
|
359
|
+
await page.setViewportSize({width: 1280, height: 720});
|
|
360
|
+
await page.goto(
|
|
361
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story&args=content:A+short+tooltip;isOpen:!true`,
|
|
362
|
+
);
|
|
363
|
+
await holdMotionStill(page);
|
|
364
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
365
|
+
await page.evaluate(sel => {
|
|
366
|
+
const el = document.querySelector(sel) as HTMLElement;
|
|
367
|
+
window.scrollBy(0, el.getBoundingClientRect().top - 650);
|
|
368
|
+
}, TRIGGER);
|
|
369
|
+
await page.waitForTimeout(200);
|
|
370
|
+
await page.evaluate(sel => {
|
|
371
|
+
const content = document.querySelector(sel)?.firstElementChild;
|
|
372
|
+
for (let i = 1; i <= 17; i++) {
|
|
373
|
+
const line = document.createElement('div');
|
|
374
|
+
line.textContent = `Line ${i}`;
|
|
375
|
+
content?.appendChild(line);
|
|
376
|
+
}
|
|
377
|
+
}, TOOLTIP);
|
|
378
|
+
await page.waitForTimeout(200);
|
|
379
|
+
const frames = await moveAndSampleFrames(page, TRIGGER, {
|
|
380
|
+
position: 'relative',
|
|
381
|
+
insetBlockStart: '-310px',
|
|
382
|
+
});
|
|
383
|
+
expectClearFromSecondFrame(frames);
|
|
384
|
+
for (const {tooltip} of frames.slice(1)) {
|
|
385
|
+
expect(tooltip.top).toBeGreaterThanOrEqual(0);
|
|
386
|
+
expect(tooltip.bottom).toBeLessThanOrEqual(720);
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Open the held-open TallContent story with `content` at `viewport`, with the
|
|
392
|
+
* trigger's centre at `triggerY`.
|
|
393
|
+
*/
|
|
394
|
+
async function openHeldTooltip(
|
|
395
|
+
page: Page,
|
|
396
|
+
viewport: {width: number; height: number},
|
|
397
|
+
content: string,
|
|
398
|
+
triggerY: number,
|
|
399
|
+
) {
|
|
400
|
+
await page.setViewportSize(viewport);
|
|
401
|
+
await page.goto(
|
|
402
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story&args=isOpen:!true${content ? `;content:${content}` : ''}`,
|
|
403
|
+
);
|
|
404
|
+
await holdMotionStill(page);
|
|
405
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
406
|
+
await page.evaluate(
|
|
407
|
+
([sel, y]) => {
|
|
408
|
+
const el = document.querySelector(sel as string) as HTMLElement;
|
|
409
|
+
const r = el.getBoundingClientRect();
|
|
410
|
+
window.scrollBy(0, r.top + r.height / 2 - (y as number));
|
|
411
|
+
},
|
|
412
|
+
[TRIGGER, triggerY],
|
|
413
|
+
);
|
|
414
|
+
await page.waitForTimeout(300);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
async function hasSwitched(page: Page): Promise<boolean | undefined> {
|
|
418
|
+
return page.evaluate(
|
|
419
|
+
sel =>
|
|
420
|
+
document.querySelector(sel)?.hasAttribute('data-astryx-clears-anchor'),
|
|
421
|
+
TOOLTIP,
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
test('a scroll never switches a tooltip that fits, so it still flips below when it grows', async ({
|
|
426
|
+
page,
|
|
427
|
+
}) => {
|
|
428
|
+
// A short tooltip opened by keyboard focus above a trigger near the top.
|
|
429
|
+
await page.setViewportSize({width: 1280, height: 720});
|
|
430
|
+
await page.goto(
|
|
431
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story&args=content:A+short+tooltip`,
|
|
432
|
+
);
|
|
433
|
+
await holdMotionStill(page);
|
|
434
|
+
const button = page.getByRole('button', {name: 'Hover for details'});
|
|
435
|
+
await expect(button).toBeVisible();
|
|
436
|
+
await page.evaluate(sel => {
|
|
437
|
+
const el = document.querySelector(sel) as HTMLElement;
|
|
438
|
+
const r = el.getBoundingClientRect();
|
|
439
|
+
window.scrollBy(0, r.top + r.height / 2 - 200);
|
|
440
|
+
}, TRIGGER);
|
|
441
|
+
await button.focus();
|
|
442
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
443
|
+
await page.waitForTimeout(200);
|
|
444
|
+
const atOpen = await hasSwitched(page);
|
|
445
|
+
// Small scroll steps, each one painted, with the tooltip open throughout.
|
|
446
|
+
for (let i = 0; i < 10; i++) {
|
|
447
|
+
await page.evaluate(() => window.scrollBy(0, 6));
|
|
448
|
+
await page.waitForTimeout(40);
|
|
449
|
+
}
|
|
450
|
+
await page.waitForTimeout(200);
|
|
451
|
+
expect(await hasSwitched(page)).toBe(atOpen);
|
|
452
|
+
// Grown past the room above, it stays clear of its trigger and in view.
|
|
453
|
+
await page.evaluate(sel => {
|
|
454
|
+
const content = document.querySelector(sel)?.firstElementChild;
|
|
455
|
+
for (let i = 1; i <= 12; i++) {
|
|
456
|
+
const line = document.createElement('div');
|
|
457
|
+
line.textContent = `Line ${i}`;
|
|
458
|
+
content?.appendChild(line);
|
|
459
|
+
}
|
|
460
|
+
}, TOOLTIP);
|
|
461
|
+
await page.waitForTimeout(300);
|
|
462
|
+
const tooltip = await rect(page, TOOLTIP);
|
|
463
|
+
const trigger = await rect(page, TRIGGER);
|
|
464
|
+
expect(overlaps(tooltip, trigger)).toBe(false);
|
|
465
|
+
expect(tooltip.top).toBeGreaterThanOrEqual(0);
|
|
466
|
+
expect(tooltip.bottom).toBeLessThanOrEqual(720);
|
|
467
|
+
// On the standard list it flips below, as any layer does, rather than
|
|
468
|
+
// moving beside its trigger.
|
|
469
|
+
expect(atOpen).toBe(false);
|
|
470
|
+
expect(tooltip.top).toBeGreaterThanOrEqual(trigger.bottom);
|
|
471
|
+
expect(tooltip.left).toBeLessThan(trigger.right);
|
|
472
|
+
expect(await hasSwitched(page)).toBe(false);
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
test('a scroll that moves a tall tooltip’s trigger never leaves the tooltip over it past the first painted frame, and it ends on the roomier side', async ({
|
|
476
|
+
page,
|
|
477
|
+
}) => {
|
|
478
|
+
// The 60-line tooltip, switched and below a trigger in the upper half of a
|
|
479
|
+
// phone; the page scrolls in steps that carry the trigger down the screen,
|
|
480
|
+
// past the middle, until the room above is the larger.
|
|
481
|
+
await openHeldTooltip(page, {width: 390, height: 700}, '', 150);
|
|
482
|
+
expect(await hasSwitched(page)).toBe(true);
|
|
483
|
+
for (let step = 0; step < 4; step++) {
|
|
484
|
+
const frames = await page.evaluate(
|
|
485
|
+
async ({sel, tip}) => {
|
|
486
|
+
const box = (el: Element) => {
|
|
487
|
+
const r = el.getBoundingClientRect();
|
|
488
|
+
return {top: r.top, bottom: r.bottom, left: r.left, right: r.right};
|
|
489
|
+
};
|
|
490
|
+
window.scrollBy(0, -110);
|
|
491
|
+
const out: {tooltip: Box; trigger: Box}[] = [];
|
|
492
|
+
for (let i = 0; i < 4; i++) {
|
|
493
|
+
await new Promise<void>(resolve => {
|
|
494
|
+
requestAnimationFrame(() => {
|
|
495
|
+
const channel = new MessageChannel();
|
|
496
|
+
channel.port1.onmessage = () => resolve();
|
|
497
|
+
channel.port2.postMessage(null);
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
const t = document.querySelector(tip);
|
|
501
|
+
const a = document.querySelector(sel);
|
|
502
|
+
if (t != null && a != null) {
|
|
503
|
+
out.push({tooltip: box(t), trigger: box(a)});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return out;
|
|
507
|
+
},
|
|
508
|
+
{sel: TRIGGER, tip: TOOLTIP},
|
|
509
|
+
);
|
|
510
|
+
expect(frames.length).toBe(4);
|
|
511
|
+
for (const [i, frame] of frames.entries()) {
|
|
512
|
+
if (i === 0) {
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
expect(
|
|
516
|
+
overlaps(frame.tooltip, frame.trigger),
|
|
517
|
+
`scroll step ${step + 1}, painted frame ${i + 1} covers the trigger`,
|
|
518
|
+
).toBe(false);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
const trigger = await rect(page, TRIGGER);
|
|
522
|
+
const tooltip = await rect(page, TOOLTIP);
|
|
523
|
+
expect(trigger.top).toBeGreaterThan(700 - trigger.bottom);
|
|
524
|
+
expect(tooltip.bottom).toBeLessThanOrEqual(trigger.top);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
test('a smooth scroll that carries a tall tooltip’s trigger leaves it clear and in view, and a later scroll is still followed', async ({
|
|
528
|
+
page,
|
|
529
|
+
}) => {
|
|
530
|
+
// The 60-line tooltip, switched and below a trigger near the top of a
|
|
531
|
+
// phone. One smooth scroll carries the trigger 440px down the screen over
|
|
532
|
+
// many frames; the observer must follow every frame of it, not only the
|
|
533
|
+
// first, and stay armed for the next move.
|
|
534
|
+
await openHeldTooltip(page, {width: 390, height: 700}, '', 150);
|
|
535
|
+
expect(await hasSwitched(page)).toBe(true);
|
|
536
|
+
const settle = async () =>
|
|
537
|
+
page.evaluate(async () => {
|
|
538
|
+
const frame = async () =>
|
|
539
|
+
new Promise<void>(resolve => requestAnimationFrame(() => resolve()));
|
|
540
|
+
let last = Number.NaN;
|
|
541
|
+
let still = 0;
|
|
542
|
+
while (still < 5) {
|
|
543
|
+
await frame();
|
|
544
|
+
still = window.scrollY === last ? still + 1 : 0;
|
|
545
|
+
last = window.scrollY;
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
await page.evaluate(() => window.scrollBy({top: -440, behavior: 'smooth'}));
|
|
549
|
+
await settle();
|
|
550
|
+
let trigger = await rect(page, TRIGGER);
|
|
551
|
+
let tooltip = await rect(page, TOOLTIP);
|
|
552
|
+
expect(trigger.top).toBeGreaterThan(500);
|
|
553
|
+
expect(overlaps(tooltip, trigger), 'covers the trigger').toBe(false);
|
|
554
|
+
expect(tooltip.top).toBeGreaterThanOrEqual(0);
|
|
555
|
+
expect(tooltip.bottom).toBeLessThanOrEqual(700);
|
|
556
|
+
expect(tooltip.bottom - tooltip.top).toBeGreaterThan(200);
|
|
557
|
+
|
|
558
|
+
// A later instant scroll that would carry the tooltip past the top of the
|
|
559
|
+
// viewport is still observed and corrected by the second painted frame.
|
|
560
|
+
const frames = await page.evaluate(
|
|
561
|
+
async ({sel, tip}) => {
|
|
562
|
+
const box = (el: Element) => {
|
|
563
|
+
const r = el.getBoundingClientRect();
|
|
564
|
+
return {top: r.top, bottom: r.bottom, left: r.left, right: r.right};
|
|
565
|
+
};
|
|
566
|
+
window.scrollBy(0, 240);
|
|
567
|
+
const out: {tooltip: Box; trigger: Box}[] = [];
|
|
568
|
+
for (let i = 0; i < 4; i++) {
|
|
569
|
+
await new Promise<void>(resolve => {
|
|
570
|
+
requestAnimationFrame(() => {
|
|
571
|
+
const channel = new MessageChannel();
|
|
572
|
+
channel.port1.onmessage = () => resolve();
|
|
573
|
+
channel.port2.postMessage(null);
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
const t = document.querySelector(tip);
|
|
577
|
+
const a = document.querySelector(sel);
|
|
578
|
+
if (t != null && a != null) {
|
|
579
|
+
out.push({tooltip: box(t), trigger: box(a)});
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return out;
|
|
583
|
+
},
|
|
584
|
+
{sel: TRIGGER, tip: TOOLTIP},
|
|
585
|
+
);
|
|
586
|
+
expect(frames.length).toBe(4);
|
|
587
|
+
for (const [i, frame] of frames.entries()) {
|
|
588
|
+
if (i === 0) {
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
expect(
|
|
592
|
+
overlaps(frame.tooltip, frame.trigger),
|
|
593
|
+
`painted frame ${i + 1} covers the trigger`,
|
|
594
|
+
).toBe(false);
|
|
595
|
+
expect(
|
|
596
|
+
frame.tooltip.top,
|
|
597
|
+
`painted frame ${i + 1} leaves the viewport`,
|
|
598
|
+
).toBeGreaterThanOrEqual(0);
|
|
599
|
+
expect(frame.tooltip.bottom).toBeLessThanOrEqual(700);
|
|
600
|
+
}
|
|
601
|
+
await settle();
|
|
602
|
+
trigger = await rect(page, TRIGGER);
|
|
603
|
+
tooltip = await rect(page, TOOLTIP);
|
|
604
|
+
expect(overlaps(tooltip, trigger)).toBe(false);
|
|
605
|
+
expect(tooltip.bottom - tooltip.top).toBeGreaterThan(200);
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
test('a trigger that a scrolled container hides for several seconds is followed again when it scrolls back into view', async ({
|
|
609
|
+
page,
|
|
610
|
+
}) => {
|
|
611
|
+
// The 60-line tooltip, held open, with the page inside a 700px scroll
|
|
612
|
+
// container on a phone. The container scrolls the trigger out of its view
|
|
613
|
+
// for longer than any short retry would wait, then scrolls it back to
|
|
614
|
+
// where the room above is the larger.
|
|
615
|
+
await page.setViewportSize({width: 390, height: 700});
|
|
616
|
+
await page.goto(
|
|
617
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story&args=isOpen:!true`,
|
|
618
|
+
);
|
|
619
|
+
await holdMotionStill(page);
|
|
620
|
+
await page.addStyleTag({
|
|
621
|
+
content: '#storybook-root{height:700px;overflow:auto}',
|
|
622
|
+
});
|
|
623
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
624
|
+
// Scroll the container so the trigger's centre lands at `y` in the
|
|
625
|
+
// viewport.
|
|
626
|
+
const scrollTriggerTo = async (y: number) =>
|
|
627
|
+
page.evaluate(
|
|
628
|
+
([sel, y]) => {
|
|
629
|
+
const el = document.querySelector(sel as string);
|
|
630
|
+
if (el == null) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
const r = el.getBoundingClientRect();
|
|
634
|
+
document
|
|
635
|
+
.getElementById('storybook-root')
|
|
636
|
+
?.scrollBy(0, r.top + r.height / 2 - (y as number));
|
|
637
|
+
},
|
|
638
|
+
[TRIGGER, y],
|
|
639
|
+
);
|
|
640
|
+
// Making the container clips the trigger for a moment; let any recheck of
|
|
641
|
+
// that settle before the case starts.
|
|
642
|
+
await scrollTriggerTo(150);
|
|
643
|
+
await page.waitForTimeout(1500);
|
|
644
|
+
expect(await hasSwitched(page)).toBe(true);
|
|
645
|
+
|
|
646
|
+
await scrollTriggerTo(-150);
|
|
647
|
+
await page.waitForTimeout(3500);
|
|
648
|
+
expect((await rect(page, TRIGGER)).bottom).toBeLessThan(0);
|
|
649
|
+
|
|
650
|
+
await scrollTriggerTo(590);
|
|
651
|
+
await page.waitForTimeout(300);
|
|
652
|
+
const trigger = await rect(page, TRIGGER);
|
|
653
|
+
const tooltip = await rect(page, TOOLTIP);
|
|
654
|
+
expect(trigger.top).toBeGreaterThan(500);
|
|
655
|
+
expect(overlaps(tooltip, trigger), 'covers the trigger').toBe(false);
|
|
656
|
+
expect(tooltip.top).toBeGreaterThanOrEqual(0);
|
|
657
|
+
expect(tooltip.bottom).toBeLessThanOrEqual(700);
|
|
658
|
+
expect(tooltip.bottom - tooltip.top).toBeGreaterThan(200);
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
test('placing a shown tooltip afresh never replays its entry animation', async ({
|
|
662
|
+
page,
|
|
663
|
+
browserName,
|
|
664
|
+
}) => {
|
|
665
|
+
// Motion allowed: the entry fade plays once, at open. A keyboard-focused
|
|
666
|
+
// short tooltip grows, then its trigger moves up so the old option leaves
|
|
667
|
+
// it past the top of the viewport: it switches lists after it has painted,
|
|
668
|
+
// and that re-placement must not fade it in again.
|
|
669
|
+
await page.setViewportSize({width: 1280, height: 720});
|
|
670
|
+
await page.goto(
|
|
671
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story&args=content:A+short+tooltip`,
|
|
672
|
+
);
|
|
673
|
+
const button = page.getByRole('button', {name: 'Hover for details'});
|
|
674
|
+
await expect(button).toBeVisible();
|
|
675
|
+
await page.evaluate(sel => {
|
|
676
|
+
const el = document.querySelector(sel) as HTMLElement;
|
|
677
|
+
window.scrollBy(0, el.getBoundingClientRect().top - 650);
|
|
678
|
+
}, TRIGGER);
|
|
679
|
+
await button.focus();
|
|
680
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
681
|
+
// Let the entry fade finish.
|
|
682
|
+
await page.waitForTimeout(600);
|
|
683
|
+
await page.evaluate(sel => {
|
|
684
|
+
const content = document.querySelector(sel)?.firstElementChild;
|
|
685
|
+
for (let i = 1; i <= 17; i++) {
|
|
686
|
+
const line = document.createElement('div');
|
|
687
|
+
line.textContent = `Line ${i}`;
|
|
688
|
+
content?.appendChild(line);
|
|
689
|
+
}
|
|
690
|
+
}, TOOLTIP);
|
|
691
|
+
await page.waitForTimeout(300);
|
|
692
|
+
const opacities = await page.evaluate(
|
|
693
|
+
async ({sel, tip}) => {
|
|
694
|
+
const trigger = document.querySelector(sel) as HTMLElement;
|
|
695
|
+
const tooltip = document.querySelector(tip) as HTMLElement;
|
|
696
|
+
trigger.style.position = 'relative';
|
|
697
|
+
trigger.style.insetBlockStart = '-310px';
|
|
698
|
+
const out: number[] = [];
|
|
699
|
+
for (let i = 0; i < 12; i++) {
|
|
700
|
+
await new Promise<void>(resolve => {
|
|
701
|
+
requestAnimationFrame(() => {
|
|
702
|
+
const channel = new MessageChannel();
|
|
703
|
+
channel.port1.onmessage = () => resolve();
|
|
704
|
+
channel.port2.postMessage(null);
|
|
705
|
+
});
|
|
706
|
+
});
|
|
707
|
+
out.push(Number(getComputedStyle(tooltip).opacity));
|
|
708
|
+
}
|
|
709
|
+
return {
|
|
710
|
+
out,
|
|
711
|
+
switched: tooltip.hasAttribute('data-astryx-clears-anchor'),
|
|
712
|
+
};
|
|
713
|
+
},
|
|
714
|
+
{sel: TRIGGER, tip: TOOLTIP},
|
|
715
|
+
);
|
|
716
|
+
if (browserName === 'chromium') {
|
|
717
|
+
// Chromium keeps the tooltip on its old option until the runtime
|
|
718
|
+
// switches and re-places it; WebKit re-runs the standard list itself when
|
|
719
|
+
// the trigger moves, so there it never fails and is never re-placed.
|
|
720
|
+
expect(opacities.switched).toBe(true);
|
|
721
|
+
}
|
|
722
|
+
for (const [i, opacity] of opacities.out.entries()) {
|
|
723
|
+
expect(opacity, `painted frame ${i + 1}`).toBe(1);
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* The animation-state regression for the re-placement, driven by what the
|
|
729
|
+
* engine exposes. In the page it lists every accessor with a setter on a CSS
|
|
730
|
+
* animation's and its keyframe effect's prototype chains, plus every field of
|
|
731
|
+
* the effect's timing, and fails if any has no row here. Each row gives one
|
|
732
|
+
* content element's animation a non-default value for that member (or a
|
|
733
|
+
* method-only state), and the test checks that the element's whole
|
|
734
|
+
* animation state is the same after the after-paint re-placement as before.
|
|
735
|
+
*/
|
|
736
|
+
const STATE_ROWS: Record<
|
|
737
|
+
string,
|
|
738
|
+
{css?: string; extraCss?: string; set?: string}
|
|
739
|
+
> = {
|
|
740
|
+
// Animation accessors.
|
|
741
|
+
currentTime: {set: 'a.currentTime = 4321'},
|
|
742
|
+
startTime: {set: 'a.startTime = document.timeline.currentTime - 2500'},
|
|
743
|
+
playbackRate: {set: 'a.playbackRate = 2'},
|
|
744
|
+
id: {set: "a.id = 'kept'"},
|
|
745
|
+
onfinish: {set: 'a.onfinish = window.__handler'},
|
|
746
|
+
oncancel: {set: 'a.oncancel = window.__handler'},
|
|
747
|
+
onremove: {set: 'a.onremove = window.__handler'},
|
|
748
|
+
timeline: {
|
|
749
|
+
set: 'a.timeline = new ScrollTimeline({source: document.documentElement})',
|
|
750
|
+
},
|
|
751
|
+
rangeStart: {
|
|
752
|
+
css: 'animation-timeline:scroll(nearest block);animation-range:entry 10% exit 80%',
|
|
753
|
+
set: "a.rangeStart = 'cover 20%'",
|
|
754
|
+
},
|
|
755
|
+
rangeEnd: {
|
|
756
|
+
css: 'animation-timeline:scroll(nearest block);animation-range:entry 10% exit 80%',
|
|
757
|
+
set: "a.rangeEnd = 'cover 70%'",
|
|
758
|
+
},
|
|
759
|
+
effect: {
|
|
760
|
+
set: "a.effect = new KeyframeEffect(el, [{translate: '0px'}, {translate: '30px'}], {duration: 7000, fill: 'both'})",
|
|
761
|
+
},
|
|
762
|
+
// Keyframe effect accessors.
|
|
763
|
+
target: {set: 'a.effect.target = el.nextElementSibling'},
|
|
764
|
+
pseudoElement: {
|
|
765
|
+
extraCss: '[data-row="pseudoElement"]::before{content:"·"}',
|
|
766
|
+
set: "a.effect.pseudoElement = '::before'",
|
|
767
|
+
},
|
|
768
|
+
composite: {set: "a.effect.composite = 'add'"},
|
|
769
|
+
iterationComposite: {set: "a.effect.iterationComposite = 'accumulate'"},
|
|
770
|
+
// Effect timing fields.
|
|
771
|
+
delay: {set: 'a.effect.updateTiming({delay: 500})'},
|
|
772
|
+
direction: {set: "a.effect.updateTiming({direction: 'alternate'})"},
|
|
773
|
+
duration: {set: 'a.effect.updateTiming({duration: 20000})'},
|
|
774
|
+
easing: {set: "a.effect.updateTiming({easing: 'ease-in'})"},
|
|
775
|
+
endDelay: {set: 'a.effect.updateTiming({endDelay: 300})'},
|
|
776
|
+
fill: {set: "a.effect.updateTiming({fill: 'forwards'})"},
|
|
777
|
+
iterationStart: {set: 'a.effect.updateTiming({iterationStart: 0.25})'},
|
|
778
|
+
iterations: {set: 'a.effect.updateTiming({iterations: 3})'},
|
|
779
|
+
// Method-only state.
|
|
780
|
+
keyframes: {
|
|
781
|
+
set: "a.effect.setKeyframes([{translate: '0px'}, {translate: '50px'}])",
|
|
782
|
+
},
|
|
783
|
+
paused: {set: 'a.pause()'},
|
|
784
|
+
reversed: {set: 'a.reverse()'},
|
|
785
|
+
finished: {css: 'animation-duration:1ms;animation-fill-mode:forwards'},
|
|
786
|
+
persisted: {set: 'a.persist()'},
|
|
787
|
+
// Shapes.
|
|
788
|
+
running: {},
|
|
789
|
+
'stylesheet-paused': {css: 'animation-play-state:paused'},
|
|
790
|
+
duplicate: {
|
|
791
|
+
css: 'animation:test-shift 10s linear both,test-shift 10s linear both;animation-composition:add,add',
|
|
792
|
+
set: 'el.getAnimations()[1].currentTime = Number(a.currentTime) + 3000',
|
|
793
|
+
},
|
|
794
|
+
descendant: {},
|
|
795
|
+
script: {
|
|
796
|
+
css: 'animation:none',
|
|
797
|
+
set: "window.__scriptAnimation = el.animate([{translate: '0px'}, {translate: '100px'}], {duration: 10000})",
|
|
798
|
+
},
|
|
799
|
+
transition: {
|
|
800
|
+
css: 'animation:none;transition:translate 10s linear',
|
|
801
|
+
set: "el.style.translate = '100px'",
|
|
802
|
+
},
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
test('placing a shown tooltip afresh keeps every animation in its content in its exact state', async ({
|
|
806
|
+
page,
|
|
807
|
+
browserName,
|
|
808
|
+
}) => {
|
|
809
|
+
await page.setViewportSize({width: 1280, height: 720});
|
|
810
|
+
await page.goto(
|
|
811
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story&args=content:A+short+tooltip;isOpen:!true`,
|
|
812
|
+
);
|
|
813
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
814
|
+
await page.evaluate(sel => {
|
|
815
|
+
const el = document.querySelector(sel) as HTMLElement;
|
|
816
|
+
window.scrollBy(0, el.getBoundingClientRect().top - 650);
|
|
817
|
+
}, TRIGGER);
|
|
818
|
+
await page.waitForTimeout(300);
|
|
819
|
+
await page.addStyleTag({
|
|
820
|
+
content: `@keyframes test-shift{from{translate:0}to{translate:100px}}[data-row]{display:inline-block;margin-inline-end:4px;animation:test-shift 10s linear both}${Object.entries(
|
|
821
|
+
STATE_ROWS,
|
|
822
|
+
)
|
|
823
|
+
.map(
|
|
824
|
+
([name, row]) =>
|
|
825
|
+
(row.css ? `[data-row="${name}"]{${row.css}}` : '') +
|
|
826
|
+
(row.extraCss ?? ''),
|
|
827
|
+
)
|
|
828
|
+
.join('')}`,
|
|
829
|
+
});
|
|
830
|
+
// One element per row (and a spare sibling to retarget to), then enough
|
|
831
|
+
// lines for the switch below.
|
|
832
|
+
const uncovered = await page.evaluate(
|
|
833
|
+
({sel, names}) => {
|
|
834
|
+
const content = document.querySelector(sel)?.firstElementChild;
|
|
835
|
+
for (const name of names) {
|
|
836
|
+
let host = content;
|
|
837
|
+
if (name === 'descendant') {
|
|
838
|
+
for (let i = 0; i < 3; i++) {
|
|
839
|
+
const wrapper = document.createElement('span');
|
|
840
|
+
host?.appendChild(wrapper);
|
|
841
|
+
host = wrapper;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
const row = document.createElement('span');
|
|
845
|
+
row.dataset.row = name;
|
|
846
|
+
row.textContent = name.slice(0, 2);
|
|
847
|
+
host?.appendChild(row);
|
|
848
|
+
const spare = document.createElement('span');
|
|
849
|
+
spare.textContent = '·';
|
|
850
|
+
host?.appendChild(spare);
|
|
851
|
+
}
|
|
852
|
+
for (let i = 1; i <= 17; i++) {
|
|
853
|
+
const line = document.createElement('div');
|
|
854
|
+
line.textContent = `Line ${i}`;
|
|
855
|
+
content?.appendChild(line);
|
|
856
|
+
}
|
|
857
|
+
// What the engine exposes as writable state.
|
|
858
|
+
const sample = document.querySelector('[data-row="running"]') as Element;
|
|
859
|
+
const animation = sample.getAnimations()[0];
|
|
860
|
+
const accessors = (object: object) => {
|
|
861
|
+
const out: string[] = [];
|
|
862
|
+
for (
|
|
863
|
+
let proto = Object.getPrototypeOf(object);
|
|
864
|
+
proto != null && proto !== Object.prototype;
|
|
865
|
+
proto = Object.getPrototypeOf(proto)
|
|
866
|
+
) {
|
|
867
|
+
for (const [key, d] of Object.entries(
|
|
868
|
+
Object.getOwnPropertyDescriptors(proto),
|
|
869
|
+
)) {
|
|
870
|
+
if (d.set != null) {
|
|
871
|
+
out.push(key);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
return out;
|
|
876
|
+
};
|
|
877
|
+
const members = [
|
|
878
|
+
...accessors(animation),
|
|
879
|
+
...accessors(animation.effect as object),
|
|
880
|
+
...Object.keys((animation.effect as KeyframeEffect).getTiming()),
|
|
881
|
+
];
|
|
882
|
+
return members.filter(member => !names.includes(member));
|
|
883
|
+
},
|
|
884
|
+
{sel: TOOLTIP, names: Object.keys(STATE_ROWS)},
|
|
885
|
+
);
|
|
886
|
+
expect(uncovered, 'writable animation members with no row').toEqual([]);
|
|
887
|
+
await page.waitForTimeout(700);
|
|
888
|
+
// Give each row its state. A row whose member this engine lacks (WebKit's
|
|
889
|
+
// `iterationComposite` is missing from Chromium) is skipped.
|
|
890
|
+
await page.evaluate(() => {
|
|
891
|
+
(window as unknown as {__handler: unknown}).__handler =
|
|
892
|
+
function handler() {};
|
|
893
|
+
});
|
|
894
|
+
const skipped: string[] = [];
|
|
895
|
+
for (const [name, row] of Object.entries(STATE_ROWS)) {
|
|
896
|
+
if (row.set == null) {
|
|
897
|
+
continue;
|
|
898
|
+
}
|
|
899
|
+
const applied = await page.evaluate(
|
|
900
|
+
`(() => {
|
|
901
|
+
const el = document.querySelector('[data-row="${name}"]');
|
|
902
|
+
const a = el.getAnimations()[0];
|
|
903
|
+
if (${name === 'iterationComposite'} && !('iterationComposite' in a.effect)) {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
${row.set};
|
|
907
|
+
return true;
|
|
908
|
+
})()`,
|
|
909
|
+
);
|
|
910
|
+
if (applied !== true) {
|
|
911
|
+
skipped.push(name);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
await page.evaluate(() => {
|
|
915
|
+
(window as unknown as {__runningBefore: unknown}).__runningBefore = (
|
|
916
|
+
document.querySelector('[data-row="running"]') as Element
|
|
917
|
+
).getAnimations()[0];
|
|
918
|
+
});
|
|
919
|
+
await page.waitForTimeout(100);
|
|
920
|
+
const read = async () =>
|
|
921
|
+
page.evaluate(names => {
|
|
922
|
+
const handler = (window as unknown as {__handler: unknown}).__handler;
|
|
923
|
+
type Serialized =
|
|
924
|
+
| string
|
|
925
|
+
| number
|
|
926
|
+
| boolean
|
|
927
|
+
| null
|
|
928
|
+
| undefined
|
|
929
|
+
| {[key: string]: Serialized};
|
|
930
|
+
const ser = (value: unknown): Serialized => {
|
|
931
|
+
if (
|
|
932
|
+
value == null ||
|
|
933
|
+
typeof value === 'boolean' ||
|
|
934
|
+
typeof value === 'string'
|
|
935
|
+
) {
|
|
936
|
+
return value;
|
|
937
|
+
}
|
|
938
|
+
if (typeof value === 'number') {
|
|
939
|
+
return Math.round(value * 10) / 10;
|
|
940
|
+
}
|
|
941
|
+
if (typeof value === 'function') {
|
|
942
|
+
return value === handler ? 'handler' : 'function';
|
|
943
|
+
}
|
|
944
|
+
if (
|
|
945
|
+
typeof CSSNumericValue !== 'undefined' &&
|
|
946
|
+
value instanceof CSSNumericValue
|
|
947
|
+
) {
|
|
948
|
+
return value.toString();
|
|
949
|
+
}
|
|
950
|
+
if (value instanceof Element) {
|
|
951
|
+
return (value as HTMLElement).dataset.row ?? value.textContent;
|
|
952
|
+
}
|
|
953
|
+
if (Object.getPrototypeOf(value) === Object.prototype) {
|
|
954
|
+
return Object.fromEntries(
|
|
955
|
+
Object.entries(value).map(([k, v]) => [k, ser(v)]),
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
return value.constructor.name;
|
|
959
|
+
};
|
|
960
|
+
const stateOf = (a: Animation) => {
|
|
961
|
+
const effect = a.effect as KeyframeEffect;
|
|
962
|
+
const out: Record<string, unknown> = {};
|
|
963
|
+
for (const object of [a, effect]) {
|
|
964
|
+
for (
|
|
965
|
+
let proto = Object.getPrototypeOf(object);
|
|
966
|
+
proto != null && proto !== Object.prototype;
|
|
967
|
+
proto = Object.getPrototypeOf(proto)
|
|
968
|
+
) {
|
|
969
|
+
for (const [key, d] of Object.entries(
|
|
970
|
+
Object.getOwnPropertyDescriptors(proto),
|
|
971
|
+
)) {
|
|
972
|
+
if (d.get != null && d.set != null && !(key in out)) {
|
|
973
|
+
out[key] = ser(
|
|
974
|
+
(object as unknown as Record<string, unknown>)[key],
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
out.timing = ser(effect.getTiming());
|
|
981
|
+
out.keyframes = JSON.stringify(effect.getKeyframes());
|
|
982
|
+
out.playState = a.playState;
|
|
983
|
+
out.replaceState = a.replaceState;
|
|
984
|
+
return out;
|
|
985
|
+
};
|
|
986
|
+
const rows: Record<string, Record<string, unknown>[]> = {};
|
|
987
|
+
for (const name of names) {
|
|
988
|
+
const el = document.querySelector(`[data-row="${name}"]`) as Element;
|
|
989
|
+
// Its animations, including one moved to a pseudo-element or (for a
|
|
990
|
+
// retargeted effect) to the spare sibling.
|
|
991
|
+
const tooltip = document.querySelector('[role="tooltip"]') as Element;
|
|
992
|
+
rows[name] = tooltip
|
|
993
|
+
.getAnimations({subtree: true})
|
|
994
|
+
.filter(animation => {
|
|
995
|
+
const target = (animation.effect as KeyframeEffect).target;
|
|
996
|
+
return target === el || target === el.nextElementSibling;
|
|
997
|
+
})
|
|
998
|
+
.map(stateOf);
|
|
999
|
+
}
|
|
1000
|
+
const script = (
|
|
1001
|
+
document.querySelector('[data-row="script"]') as Element
|
|
1002
|
+
).getAnimations()[0];
|
|
1003
|
+
const running = (
|
|
1004
|
+
document.querySelector('[data-row="running"]') as Element
|
|
1005
|
+
).getAnimations()[0];
|
|
1006
|
+
const w = window as unknown as Record<string, unknown>;
|
|
1007
|
+
return {
|
|
1008
|
+
rows,
|
|
1009
|
+
at: performance.now(),
|
|
1010
|
+
scrollY: window.scrollY,
|
|
1011
|
+
scriptSame: script === w.__scriptAnimation,
|
|
1012
|
+
recreated: running !== w.__runningBefore,
|
|
1013
|
+
};
|
|
1014
|
+
}, Object.keys(STATE_ROWS));
|
|
1015
|
+
const before = await read();
|
|
1016
|
+
await page.evaluate(sel => {
|
|
1017
|
+
const el = document.querySelector(sel) as HTMLElement;
|
|
1018
|
+
el.style.position = 'relative';
|
|
1019
|
+
el.style.insetBlockStart = '-310px';
|
|
1020
|
+
}, TRIGGER);
|
|
1021
|
+
await page.waitForTimeout(450);
|
|
1022
|
+
if (browserName === 'chromium') {
|
|
1023
|
+
expect(await hasSwitched(page)).toBe(true);
|
|
1024
|
+
}
|
|
1025
|
+
const after = await read();
|
|
1026
|
+
// In Chromium the browser recreated the content's CSS animations: this is
|
|
1027
|
+
// the path that has to put them back. (WebKit re-runs the standard list
|
|
1028
|
+
// itself when the trigger moves, so there the tooltip is never re-placed;
|
|
1029
|
+
// every row must hold either way.)
|
|
1030
|
+
if (browserName === 'chromium') {
|
|
1031
|
+
expect(after.recreated).toBe(true);
|
|
1032
|
+
}
|
|
1033
|
+
expect(after.scriptSame).toBe(true);
|
|
1034
|
+
const elapsed = after.at - before.at;
|
|
1035
|
+
const failed: string[] = [];
|
|
1036
|
+
for (const name of Object.keys(STATE_ROWS)) {
|
|
1037
|
+
if (skipped.includes(name)) {
|
|
1038
|
+
continue;
|
|
1039
|
+
}
|
|
1040
|
+
const b = before.rows[name];
|
|
1041
|
+
const a = after.rows[name];
|
|
1042
|
+
if (a.length !== b.length) {
|
|
1043
|
+
failed.push(`${name}: ${b.length} animations before, ${a.length} after`);
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1046
|
+
for (const [i, stateBefore] of b.entries()) {
|
|
1047
|
+
const stateAfter = a[i];
|
|
1048
|
+
// Times move on with the clock; every other member must be unchanged.
|
|
1049
|
+
const {currentTime: t0, startTime: s0, ...restBefore} = stateBefore;
|
|
1050
|
+
const {currentTime: t1, startTime: s1, ...restAfter} = stateAfter;
|
|
1051
|
+
if (JSON.stringify(restBefore) !== JSON.stringify(restAfter)) {
|
|
1052
|
+
failed.push(
|
|
1053
|
+
`${name}: ${JSON.stringify(restBefore)} -> ${JSON.stringify(restAfter)}`,
|
|
1054
|
+
);
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
const rate = Number(stateBefore.playbackRate);
|
|
1058
|
+
// A scroll-driven animation's time follows the page's scroll position,
|
|
1059
|
+
// which WebKit moves by itself when an open popover's anchor moves.
|
|
1060
|
+
const scrollDriven = stateBefore.timeline !== 'DocumentTimeline';
|
|
1061
|
+
if (scrollDriven && after.scrollY !== before.scrollY) {
|
|
1062
|
+
// Its time is the browser's to change; the rest was compared above.
|
|
1063
|
+
} else if (typeof t0 === 'number' && typeof t1 === 'number') {
|
|
1064
|
+
const expected =
|
|
1065
|
+
stateBefore.playState === 'running' &&
|
|
1066
|
+
stateBefore.timeline === 'DocumentTimeline'
|
|
1067
|
+
? t0 + rate * elapsed
|
|
1068
|
+
: t0;
|
|
1069
|
+
if (Math.abs(t1 - expected) > 150) {
|
|
1070
|
+
failed.push(
|
|
1071
|
+
`${name}: currentTime ${t0} -> ${t1}, expected about ${Math.round(expected)}`,
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
} else if (t0 !== t1) {
|
|
1075
|
+
failed.push(`${name}: currentTime ${String(t0)} -> ${String(t1)}`);
|
|
1076
|
+
}
|
|
1077
|
+
// A finished animation's start time is the one documented limitation:
|
|
1078
|
+
// script cannot set a start time and a held end time together.
|
|
1079
|
+
if (
|
|
1080
|
+
stateBefore.playState !== 'finished' &&
|
|
1081
|
+
typeof s0 === 'number' &&
|
|
1082
|
+
typeof s1 === 'number' &&
|
|
1083
|
+
Math.abs(s1 - s0) > 50
|
|
1084
|
+
) {
|
|
1085
|
+
failed.push(`${name}: startTime ${s0} -> ${s1}`);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
expect(failed).toEqual([]);
|
|
1090
|
+
// The stylesheet still controls the animation it paused.
|
|
1091
|
+
await page.addStyleTag({
|
|
1092
|
+
content: '[data-row="stylesheet-paused"]{animation-play-state:running}',
|
|
1093
|
+
});
|
|
1094
|
+
await page.waitForTimeout(100);
|
|
1095
|
+
expect(
|
|
1096
|
+
await page.evaluate(
|
|
1097
|
+
() =>
|
|
1098
|
+
(
|
|
1099
|
+
document.querySelector(
|
|
1100
|
+
'[data-row="stylesheet-paused"]',
|
|
1101
|
+
) as HTMLElement
|
|
1102
|
+
).getAnimations()[0].playState,
|
|
1103
|
+
),
|
|
1104
|
+
).toBe('running');
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
test('a short, wide tooltip carried past the viewport edge moves to the other side at its own size', async ({
|
|
1108
|
+
page,
|
|
1109
|
+
}) => {
|
|
1110
|
+
// A held-open tooltip too wide to go beside its trigger on a phone sits
|
|
1111
|
+
// above a trigger near the bottom. A scroll carries the trigger to the top,
|
|
1112
|
+
// so the tooltip can no longer fit above: it moves below, keeping its size
|
|
1113
|
+
// rather than stretching to the room there, and still keeps its size when
|
|
1114
|
+
// its content then grows within that room.
|
|
1115
|
+
await page.setViewportSize({width: 390, height: 700});
|
|
1116
|
+
await page.goto(
|
|
1117
|
+
`${storybook.origin}/iframe.html?id=core-tooltip--tall-content&viewMode=story&args=isOpen:!true;content:A+short+but+wide+tooltip+whose+text+wraps+onto+a+few+lines+here`,
|
|
1118
|
+
);
|
|
1119
|
+
await holdMotionStill(page);
|
|
1120
|
+
await expect(page.getByRole('tooltip')).toBeVisible();
|
|
1121
|
+
const scrollTriggerTo = async (y: number) => {
|
|
1122
|
+
await page.evaluate(
|
|
1123
|
+
([sel, top]) => {
|
|
1124
|
+
const el = document.querySelector(sel as string) as HTMLElement;
|
|
1125
|
+
const r = el.getBoundingClientRect();
|
|
1126
|
+
window.scrollBy(0, r.top + r.height / 2 - (top as number));
|
|
1127
|
+
},
|
|
1128
|
+
[TRIGGER, y],
|
|
1129
|
+
);
|
|
1130
|
+
await page.waitForTimeout(400);
|
|
1131
|
+
};
|
|
1132
|
+
await scrollTriggerTo(650);
|
|
1133
|
+
const before = await rect(page, TOOLTIP);
|
|
1134
|
+
const triggerBefore = await rect(page, TRIGGER);
|
|
1135
|
+
expect(before.bottom).toBeLessThanOrEqual(triggerBefore.top);
|
|
1136
|
+
const height = before.bottom - before.top;
|
|
1137
|
+
expect(height).toBeLessThan(120);
|
|
1138
|
+
await scrollTriggerTo(28);
|
|
1139
|
+
const after = await rect(page, TOOLTIP);
|
|
1140
|
+
const trigger = await rect(page, TRIGGER);
|
|
1141
|
+
expect(overlaps(after, trigger)).toBe(false);
|
|
1142
|
+
expect(after.top).toBeGreaterThanOrEqual(trigger.bottom);
|
|
1143
|
+
expect(Math.abs(after.bottom - after.top - height)).toBeLessThanOrEqual(1);
|
|
1144
|
+
// Grown within the room below, it still takes only the room it needs.
|
|
1145
|
+
await page.evaluate(sel => {
|
|
1146
|
+
const content = document.querySelector(sel)?.firstElementChild;
|
|
1147
|
+
for (let i = 1; i <= 10; i++) {
|
|
1148
|
+
const line = document.createElement('div');
|
|
1149
|
+
line.textContent = `Line ${i}`;
|
|
1150
|
+
content?.appendChild(line);
|
|
1151
|
+
}
|
|
1152
|
+
}, TOOLTIP);
|
|
1153
|
+
await page.waitForTimeout(400);
|
|
1154
|
+
const grown = await rect(page, TOOLTIP);
|
|
1155
|
+
const metrics = await page.evaluate(sel => {
|
|
1156
|
+
const el = document.querySelector(sel) as HTMLElement;
|
|
1157
|
+
return {scrollHeight: el.scrollHeight, clientHeight: el.clientHeight};
|
|
1158
|
+
}, TOOLTIP);
|
|
1159
|
+
expect(grown.top).toBeGreaterThanOrEqual(trigger.bottom);
|
|
1160
|
+
expect(grown.bottom - grown.top).toBeLessThan(400);
|
|
1161
|
+
expect(metrics.scrollHeight).toBeLessThanOrEqual(metrics.clientHeight + 1);
|
|
1162
|
+
});
|