@astryxdesign/core 0.7.5 → 0.7.6-canary.bb18c81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +5 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +12 -3
- package/dist/BottomSheet/BottomSheet.js +1 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +2 -1
- package/dist/BottomSheet/useSheetGestures.d.ts +12 -0
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +30 -3
- package/dist/Button/Button.js +4 -4
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +6 -5
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +4 -1
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +101 -15
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +4 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +34 -9
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +5 -4
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +2 -1
- package/dist/Drawer/Drawer.d.ts.map +1 -1
- package/dist/Drawer/Drawer.js +5 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +4 -1
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
- package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +10 -1
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
- package/dist/DropdownMenu/lazyMenuBottomSheet.js +16 -2
- package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
- package/dist/DropdownMenu/renderDropdownItems.js +21 -16
- package/dist/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/EmptyState/EmptyState.js +2 -1
- package/dist/Field/FieldLabel.d.ts +1 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +4 -4
- package/dist/Field/InputClearButton.js +3 -3
- package/dist/Field/PanelSearchInput.js +2 -2
- package/dist/FieldStatus/FieldStatus.js +2 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +7 -1
- package/dist/Heading/Heading.js +1 -1
- package/dist/Icon/Icon.js +1 -1
- package/dist/Indicator/CheckIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckIndicator.js +2 -1
- package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckboxIndicator.js +3 -1
- package/dist/Indicator/RadioIndicator.d.ts.map +1 -1
- package/dist/Indicator/RadioIndicator.js +3 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +2 -1
- package/dist/Item/ItemSwipeLayer.js +1 -1
- package/dist/Layout/Layout.js +1 -1
- package/dist/Layout/LayoutContent.js +1 -1
- package/dist/Layout/LayoutFooter.js +1 -1
- package/dist/Layout/LayoutHeader.js +1 -1
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +5 -0
- package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +5 -4
- package/dist/List/List.js +1 -1
- package/dist/List/ListItem.js +3 -3
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +7 -2
- package/dist/MultiSelector/MultiSelector.d.ts +1 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +5 -2
- package/dist/NumberInput/NumberInput.d.ts +3 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +3 -3
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +16 -12
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +28 -2
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
- package/dist/Selector/useSelectorPresentation.d.ts +8 -1
- package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
- package/dist/Selector/useSelectorPresentation.js +20 -4
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +7 -1
- package/dist/Spinner/Spinner.js +2 -2
- package/dist/Stack/Stack.js +1 -1
- package/dist/Stack/StackItem.js +1 -1
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +16 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
- package/dist/Text/Text.js +1 -1
- package/dist/Text/useTruncation.d.ts.map +1 -1
- package/dist/Text/useTruncation.js +23 -5
- package/dist/TextArea/TextArea.d.ts +1 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +13 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +3 -3
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +2 -2
- package/dist/Timestamp/TimestampHoverCard.js +4 -4
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +82 -51
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +13 -2
- package/dist/Tokenizer/TokenizerBottomSheet.js +3 -3
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +2 -1
- package/dist/Typeahead/Typeahead.d.ts +1 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +9 -1
- package/dist/astryx.css +14 -1
- package/dist/gestures/PinchGestureRecognizer.d.ts +30 -0
- package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/PinchGestureRecognizer.js +125 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +70 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.js +220 -0
- package/dist/gestures/SwipeGestureRecognizer.d.ts +36 -0
- package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/SwipeGestureRecognizer.js +145 -0
- package/dist/gestures/VelocityTracker.d.ts +6 -2
- package/dist/gestures/VelocityTracker.d.ts.map +1 -1
- package/dist/gestures/VelocityTracker.js +7 -3
- package/dist/gestures/types.d.ts +11 -7
- package/dist/gestures/types.d.ts.map +1 -1
- package/dist/gestures/types.js +22 -2
- package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
- package/dist/hooks/useAdaptivePresentation.js +4 -1
- package/dist/hooks/useMenuHover.d.ts.map +1 -1
- package/dist/hooks/useMenuHover.js +12 -1
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +3 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +3 -0
- package/dist/motion/animator.d.ts +7 -1
- package/dist/motion/animator.d.ts.map +1 -1
- package/dist/motion/animator.js +119 -27
- package/dist/theme/defineTheme.js +1 -1
- package/dist/theme/domainTokens/domainTokenDefaults.d.ts +3 -0
- package/dist/theme/domainTokens/domainTokenDefaults.d.ts.map +1 -0
- package/dist/theme/domainTokens/domainTokenDefaults.js +19 -0
- package/dist/theme/domainTokens/index.d.ts +5 -4
- package/dist/theme/domainTokens/index.d.ts.map +1 -1
- package/dist/theme/domainTokens/index.js +5 -9
- package/dist/utils/focusReturn.d.ts +17 -1
- package/dist/utils/focusReturn.d.ts.map +1 -1
- package/dist/utils/focusReturn.js +11 -4
- package/dist/utils/getNodeText.d.ts +8 -0
- package/dist/utils/getNodeText.d.ts.map +1 -0
- package/dist/utils/getNodeText.js +37 -0
- package/dist/utils/interactionModality.d.ts +11 -2
- package/dist/utils/interactionModality.d.ts.map +1 -1
- package/dist/utils/interactionModality.js +58 -5
- package/dist/utils/presentation.d.ts +50 -0
- package/dist/utils/presentation.d.ts.map +1 -0
- package/dist/utils/presentation.js +125 -0
- package/dist/utils/touchPresentation.d.ts.map +1 -1
- package/dist/utils/touchPresentation.js +5 -3
- package/dist/utils/touchPresentation.stylex.d.ts +15 -0
- package/dist/utils/touchPresentation.stylex.d.ts.map +1 -0
- package/dist/utils/touchPresentation.stylex.js +33 -0
- package/locales/en.json +13 -1
- package/locales/pseudo.json +9 -0
- package/package.json +5 -4
- package/src/AlertDialog/AlertDialog.tsx +6 -5
- package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +18 -6
- package/src/Avatar/Avatar.spec.md +22 -22
- package/src/Avatar/Avatar.tsx +18 -1
- package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +126 -0
- package/src/BottomSheet/BottomSheet.test.tsx +46 -0
- package/src/BottomSheet/BottomSheet.tsx +1 -1
- package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
- package/src/BottomSheet/useSheetGestures.test.ts +52 -0
- package/src/BottomSheet/useSheetGestures.ts +37 -6
- package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +18 -6
- package/src/Button/Button.tsx +4 -4
- package/src/Calendar/Calendar.spec.md +87 -48
- package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +21 -7
- package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +21 -7
- package/src/CheckboxInput/CheckboxInput.tsx +6 -5
- package/src/Collapsible/Collapsible.spec.md +2 -0
- package/src/Collapsible/CollapsibleGroup.spec.md +57 -29
- package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +18 -7
- package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +18 -6
- package/src/ContextMenu/ContextMenu.test.tsx +35 -0
- package/src/DateInput/DateInput.test.tsx +53 -2
- package/src/DateInput/DateInput.tsx +15 -11
- package/src/DateInput/MonthScroller.tsx +106 -20
- package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
- package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +312 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +46 -3
- package/src/DateRangeInput/DateRangeInput.tsx +16 -12
- package/src/DateTimeInput/DateTimeInput.spec.md +71 -48
- package/src/DateTimeInput/DateTimeInput.test.tsx +61 -0
- package/src/DateTimeInput/DateTimeInput.tsx +15 -11
- package/src/Dialog/Dialog.test.tsx +216 -2
- package/src/Dialog/Dialog.tsx +42 -9
- package/src/Dialog/DialogHeader.tsx +5 -4
- package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +202 -0
- package/src/Divider/Divider.tsx +2 -1
- package/src/Drawer/Drawer.spec.md +111 -80
- package/src/Drawer/Drawer.test.tsx +22 -0
- package/src/Drawer/Drawer.tsx +5 -0
- package/src/Drawer/DrawerHeader.spec.md +181 -0
- package/src/DropdownMenu/DropdownMenu.test.tsx +41 -0
- package/src/DropdownMenu/DropdownMenu.tsx +7 -1
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +34 -0
- package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
- package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +19 -7
- package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +21 -9
- package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +53 -0
- package/src/DropdownMenu/lazyMenuBottomSheet.ts +23 -6
- package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
- package/src/EmptyState/EmptyState.tsx +2 -1
- package/src/Field/FieldLabel.tsx +5 -4
- package/src/Field/InputClearButton.tsx +3 -3
- package/src/Field/PanelSearchInput.tsx +2 -2
- package/src/FieldStatus/FieldStatus.tsx +2 -2
- package/src/FileInput/FileInput.test.tsx +21 -0
- package/src/FileInput/FileInput.tsx +4 -1
- package/src/FormLayout/FormLayout.spec.md +7 -8
- package/src/Heading/Heading.tsx +1 -1
- package/src/Icon/Icon.tsx +1 -1
- package/src/Indicator/CheckIndicator.spec.md +47 -42
- package/src/Indicator/CheckIndicator.tsx +2 -1
- package/src/Indicator/CheckboxIndicator.spec.md +40 -37
- package/src/Indicator/CheckboxIndicator.tsx +3 -1
- package/src/Indicator/Indicator.spec.md +188 -0
- package/src/Indicator/RadioIndicator.tsx +3 -1
- package/src/Item/Item.tsx +2 -1
- package/src/Item/ItemSwipeLayer.tsx +1 -1
- package/src/Layout/Layout.spec.md +127 -131
- package/src/Layout/Layout.tsx +1 -1
- package/src/Layout/LayoutContent.spec.md +205 -0
- package/src/Layout/LayoutContent.tsx +1 -1
- package/src/Layout/LayoutFooter.spec.md +190 -0
- package/src/Layout/LayoutFooter.tsx +1 -1
- package/src/Layout/LayoutHeader.spec.md +193 -0
- package/src/Layout/LayoutHeader.tsx +1 -1
- package/src/Layout/LayoutPanel.spec.md +194 -0
- package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +18 -6
- package/src/Lightbox/Lightbox.test.tsx +18 -0
- package/src/Lightbox/Lightbox.tsx +5 -0
- package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +8 -4
- package/src/Link/__tests__/Link.a11y.chromium.spec.ts +18 -8
- package/src/List/List.tsx +1 -1
- package/src/List/ListItem.tsx +3 -3
- package/src/MobileNav/MobileNav.test.tsx +15 -0
- package/src/MobileNav/MobileNav.tsx +9 -1
- package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +89 -0
- package/src/MoreMenu/MoreMenu.test.tsx +11 -0
- package/src/MultiSelector/MultiSelector.spec.md +7 -4
- package/src/MultiSelector/MultiSelector.test.tsx +118 -1
- package/src/MultiSelector/MultiSelector.tsx +6 -2
- package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +8 -1
- package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
- package/src/NumberInput/NumberInput.doc.mjs +13 -7
- package/src/NumberInput/NumberInput.spec.md +59 -37
- package/src/NumberInput/NumberInput.tsx +13 -3
- package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +102 -0
- package/src/ProgressBar/ProgressBar.test.tsx +108 -32
- package/src/ProgressBar/ProgressBar.tsx +58 -10
- package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +21 -9
- package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +831 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +21 -14
- package/src/Resizable/useResizable.test.ts +43 -0
- package/src/Resizable/useResizable.ts +32 -9
- package/src/SegmentedControl/SegmentedControl.test.tsx +84 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
- package/src/Selector/Selector.test.tsx +90 -1
- package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +8 -1
- package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +8 -1
- package/src/Selector/useSelectorPresentation.ts +31 -3
- package/src/SideNav/SideNav.test.tsx +27 -0
- package/src/Slider/Slider.test.tsx +12 -0
- package/src/Slider/Slider.tsx +4 -1
- package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
- package/src/Spinner/Spinner.tsx +2 -2
- package/src/Stack/Stack.tsx +1 -1
- package/src/Stack/StackItem.tsx +1 -1
- package/src/TabList/TabList.test.tsx +52 -1
- package/src/TabList/TabList.tsx +16 -1
- package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +163 -0
- package/src/Table/__tests__/Table.a11y.chromium.spec.ts +18 -6
- package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +22 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
- package/src/Text/Text.tsx +1 -1
- package/src/Text/useTruncation.test.tsx +128 -1
- package/src/Text/useTruncation.ts +23 -5
- package/src/TextArea/TextArea.spec.md +10 -13
- package/src/TextArea/TextArea.test.tsx +60 -0
- package/src/TextArea/TextArea.tsx +15 -1
- package/src/TextInput/TextInput.test.tsx +21 -0
- package/src/TextInput/TextInput.tsx +3 -1
- package/src/Timestamp/Timestamp.spec.md +6 -12
- package/src/Timestamp/Timestamp.test.tsx +30 -5
- package/src/Timestamp/Timestamp.tsx +6 -2
- package/src/Timestamp/TimestampHoverCard.tsx +4 -4
- package/src/Toast/Toast.spec.md +7 -10
- package/src/Toast/ToastViewport.test.tsx +575 -1
- package/src/Toast/ToastViewport.tsx +100 -50
- package/src/Tokenizer/Tokenizer.spec.md +5 -3
- package/src/Tokenizer/Tokenizer.test.tsx +68 -0
- package/src/Tokenizer/Tokenizer.tsx +14 -2
- package/src/Tokenizer/TokenizerBottomSheet.test.tsx +15 -4
- package/src/Tokenizer/TokenizerBottomSheet.tsx +3 -3
- package/src/Toolbar/Toolbar.spec.md +5 -6
- package/src/Toolbar/Toolbar.test.tsx +30 -0
- package/src/Toolbar/Toolbar.tsx +2 -1
- package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +18 -6
- package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +18 -7
- package/src/TopNav/TopNav.test.tsx +27 -0
- package/src/Typeahead/Typeahead.test.tsx +40 -0
- package/src/Typeahead/Typeahead.tsx +12 -1
- package/src/gestures/PinchGestureRecognizer.ts +144 -0
- package/src/gestures/ScreenEdgePanGestureRecognizer.ts +252 -0
- package/src/gestures/SwipeGestureRecognizer.ts +193 -0
- package/src/gestures/VelocityTracker.ts +10 -3
- package/src/gestures/__tests__/PanGestureRecognizer.test.ts +4 -4
- package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +74 -0
- package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +498 -0
- package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +108 -0
- package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +188 -0
- package/src/gestures/__tests__/harness.ts +21 -2
- package/src/gestures/types.ts +23 -9
- package/src/hooks/useAdaptivePresentation.ts +4 -1
- package/src/hooks/useMenuHover.ts +15 -1
- package/src/i18n/generated-locales/en.generated.ts +4 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +4 -0
- package/src/motion/README.md +11 -1
- package/src/motion/animator.test.ts +151 -3
- package/src/motion/animator.ts +149 -33
- package/src/theme/defineTheme.ts +1 -1
- package/src/theme/derivedVarRegistry.test.ts +4 -0
- package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
- package/src/theme/domainTokens/index.ts +6 -10
- package/src/utils/focusReturn.ts +17 -6
- package/src/utils/getNodeText.test.ts +24 -0
- package/src/utils/getNodeText.ts +37 -0
- package/src/utils/interactionModality.test.ts +45 -1
- package/src/utils/interactionModality.ts +64 -5
- package/src/utils/presentation.test.ts +380 -0
- package/src/utils/presentation.ts +180 -0
- package/src/utils/pressPaintPriority.test.ts +80 -0
- package/src/utils/touchPresentation.stylex.ts +43 -0
- package/src/utils/touchPresentation.test.ts +140 -1
- package/src/utils/touchPresentation.ts +5 -3
package/dist/motion/animator.js
CHANGED
|
@@ -69,13 +69,17 @@
|
|
|
69
69
|
* Chromium starts it after the block.
|
|
70
70
|
*
|
|
71
71
|
* Promotion: Mobile Safari runs an animation whose start time is set from
|
|
72
|
-
* script on its compositor at its first commit only if the element
|
|
73
|
-
* has a compositing layer; without one, a block
|
|
74
|
-
* freezes it (iOS 26.2 simulator: 2 of 7 runs kept
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
72
|
+
* script on its compositor at its first commit only if the element (or the
|
|
73
|
+
* pseudo-element) already has a compositing layer; without one, a block
|
|
74
|
+
* right after that commit freezes it (iOS 26.2 simulator: 2 of 7 runs kept
|
|
75
|
+
* moving, 0 of 5 on a ::before). Every animation the animator creates, and
|
|
76
|
+
* every `set`, therefore promotes its channels in the same task: inline
|
|
77
|
+
* `will-change` on the element, merged with the element's own, or the custom
|
|
78
|
+
* property `--astryx-motion-will-change-<pseudo>` on the host for a
|
|
79
|
+
* pseudo-element, whose style opts in with
|
|
80
|
+
* `will-change: var(--astryx-motion-will-change-before, auto)`. That is
|
|
81
|
+
* enough (5 of 5, and 4 of 4 through the animator); promotion ends
|
|
82
|
+
* PROMOTION_LINGER_MS after the last motion.
|
|
79
83
|
*
|
|
80
84
|
* Known limits, iOS Safari (measured on the iOS 26.2 simulator):
|
|
81
85
|
* - a block in the task that starts a motion delays it: it starts when the
|
|
@@ -125,6 +129,14 @@
|
|
|
125
129
|
* Motion policy above, a cross-fade on a coarse pointer or after a touch
|
|
126
130
|
* release (`touchRelease`) and at once elsewhere (DR2, DR3).
|
|
127
131
|
*
|
|
132
|
+
* A pseudo-element (`options.pseudoElement`, a dialog's `::backdrop`) has no
|
|
133
|
+
* inline style: its end value is held by a static filling animation (after a
|
|
134
|
+
* curve ends, and after `set`) until the next animation replaces it, and for
|
|
135
|
+
* as long as the pseudo-element exists. The browser makes a `::backdrop`
|
|
136
|
+
* again each time its dialog opens, without the hold, so a presentation
|
|
137
|
+
* calls `set` with its starting value right after `showModal()`, in the same
|
|
138
|
+
* task: a `set` before it lands on the backdrop the open replaces.
|
|
139
|
+
*
|
|
128
140
|
* SSR-safe: nothing touches `window` or `document` at module scope, and an
|
|
129
141
|
* animator created without an element only keeps state until one is attached.
|
|
130
142
|
*
|
|
@@ -285,7 +297,7 @@ function format(channel, value) {
|
|
|
285
297
|
const shared = new WeakMap();
|
|
286
298
|
|
|
287
299
|
/**
|
|
288
|
-
* The one animator for `element
|
|
300
|
+
* The one animator for `element` (and `options.pseudoElement`), created on
|
|
289
301
|
* first use. Code that animates one element from several places (a swipe on
|
|
290
302
|
* x, a removal on y) shares it, so their curves compose in one `translate`
|
|
291
303
|
* track and retargeting one axis leaves the other on its curve; two
|
|
@@ -294,10 +306,16 @@ const shared = new WeakMap();
|
|
|
294
306
|
* elsewhere or `dispose` it: it lives as long as the element.
|
|
295
307
|
*/
|
|
296
308
|
export function animatorFor(element, options = {}) {
|
|
297
|
-
let
|
|
309
|
+
let byPseudo = shared.get(element);
|
|
310
|
+
if (byPseudo == null) {
|
|
311
|
+
byPseudo = new Map();
|
|
312
|
+
shared.set(element, byPseudo);
|
|
313
|
+
}
|
|
314
|
+
const key = options.pseudoElement ?? '';
|
|
315
|
+
let animator = byPseudo.get(key);
|
|
298
316
|
if (animator == null) {
|
|
299
317
|
animator = createAnimator(element, options);
|
|
300
|
-
|
|
318
|
+
byPseudo.set(key, animator);
|
|
301
319
|
}
|
|
302
320
|
return animator;
|
|
303
321
|
}
|
|
@@ -413,6 +431,7 @@ export function createAnimator(element, options = {}) {
|
|
|
413
431
|
const requestFrame = options.requestFrame ?? (typeof requestAnimationFrame === 'function' ? callback => {
|
|
414
432
|
requestAnimationFrame(() => callback());
|
|
415
433
|
} : null);
|
|
434
|
+
const pseudoElement = options.pseudoElement;
|
|
416
435
|
// Reduced Motion reads the person's settings and nothing else: no option
|
|
417
436
|
// overrides them (design:reduced-motion DR4).
|
|
418
437
|
const prefersReducedMotion = defaultPrefersReducedMotion;
|
|
@@ -463,6 +482,8 @@ export function createAnimator(element, options = {}) {
|
|
|
463
482
|
/** The stylesheet's will-change when there is no inline value. */
|
|
464
483
|
let sheetWillChange = '';
|
|
465
484
|
let demoteTimer = null;
|
|
485
|
+
/** A pseudo-element is promoted through a custom property on its host. */
|
|
486
|
+
const promotionProperty = pseudoElement == null ? null : `--astryx-motion-will-change-${pseudoElement.replace(/^:+/, '')}`;
|
|
466
487
|
/** Channels whose identity the last node held inline (see `attach`). */
|
|
467
488
|
let heldIdentity = new Set();
|
|
468
489
|
|
|
@@ -533,7 +554,7 @@ export function createAnimator(element, options = {}) {
|
|
|
533
554
|
|
|
534
555
|
const finalValue = property => segments.get(property)?.target ?? resting[property];
|
|
535
556
|
const writeInline = (channel, value) => {
|
|
536
|
-
if (target == null) {
|
|
557
|
+
if (target == null || pseudoElement != null) {
|
|
537
558
|
return;
|
|
538
559
|
}
|
|
539
560
|
touched.add(channel);
|
|
@@ -588,14 +609,36 @@ export function createAnimator(element, options = {}) {
|
|
|
588
609
|
}
|
|
589
610
|
return times;
|
|
590
611
|
};
|
|
612
|
+
|
|
613
|
+
/** A pseudo-element's resting value, held by a static filling animation. */
|
|
614
|
+
const hold = (channel, time) => {
|
|
615
|
+
if (target == null) {
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
const value = format(channel, finalValue);
|
|
619
|
+
const animation = target.animate([{
|
|
620
|
+
[channel]: value
|
|
621
|
+
}, {
|
|
622
|
+
[channel]: value
|
|
623
|
+
}], {
|
|
624
|
+
duration: 1,
|
|
625
|
+
fill: 'both',
|
|
626
|
+
pseudoElement
|
|
627
|
+
});
|
|
628
|
+
animation.startTime = time;
|
|
629
|
+
running.set(channel, animation);
|
|
630
|
+
};
|
|
591
631
|
const rebuild = (channel, time) => {
|
|
592
632
|
const previous = running.get(channel);
|
|
593
633
|
running.delete(channel);
|
|
594
634
|
clearTimeout(retireTimers.get(channel));
|
|
595
635
|
retireTimers.delete(channel);
|
|
596
|
-
//
|
|
597
|
-
//
|
|
598
|
-
|
|
636
|
+
// An element's inline style holds the end state, so its old animation can
|
|
637
|
+
// go first. A pseudo-element has none: its old animation keeps holding the
|
|
638
|
+
// value until the new one exists (same task, no frame in between).
|
|
639
|
+
if (pseudoElement == null) {
|
|
640
|
+
previous?.cancel();
|
|
641
|
+
}
|
|
599
642
|
const properties = CHANNELS[channel];
|
|
600
643
|
// Settled curves become resting values.
|
|
601
644
|
for (const property of properties) {
|
|
@@ -612,6 +655,10 @@ export function createAnimator(element, options = {}) {
|
|
|
612
655
|
return;
|
|
613
656
|
}
|
|
614
657
|
if (moving.length === 0) {
|
|
658
|
+
if (pseudoElement != null) {
|
|
659
|
+
hold(channel, time);
|
|
660
|
+
}
|
|
661
|
+
previous?.cancel();
|
|
615
662
|
return;
|
|
616
663
|
}
|
|
617
664
|
// A channel rebuilt by an explicit call (set, rebase, a retarget of
|
|
@@ -624,6 +671,10 @@ export function createAnimator(element, options = {}) {
|
|
|
624
671
|
const from = waiting?.provisional ?? time;
|
|
625
672
|
const end = Math.min(from + MAX_DURATION_MS, Math.max(...moving.map(p => segments.get(p).start + segments.get(p).duration)));
|
|
626
673
|
if (end <= from) {
|
|
674
|
+
if (pseudoElement != null) {
|
|
675
|
+
hold(channel, time);
|
|
676
|
+
}
|
|
677
|
+
previous?.cancel();
|
|
627
678
|
return;
|
|
628
679
|
}
|
|
629
680
|
if (callGroup != null) {
|
|
@@ -702,7 +753,10 @@ export function createAnimator(element, options = {}) {
|
|
|
702
753
|
// The main thread drops the animation once it runs after the end; the
|
|
703
754
|
// inline style already holds the same values, so that changes no pixel.
|
|
704
755
|
fill: 'both',
|
|
705
|
-
easing: 'linear'
|
|
756
|
+
easing: 'linear',
|
|
757
|
+
...(pseudoElement != null ? {
|
|
758
|
+
pseudoElement
|
|
759
|
+
} : {})
|
|
706
760
|
});
|
|
707
761
|
if (waiting != null) {
|
|
708
762
|
// From rest: no start time, so the browser starts the animation when
|
|
@@ -723,7 +777,9 @@ export function createAnimator(element, options = {}) {
|
|
|
723
777
|
|
|
724
778
|
/**
|
|
725
779
|
* Once the main thread runs after the curve's end, the animation leaves the
|
|
726
|
-
* running state:
|
|
780
|
+
* running state: an element's inline style already shows the end values; a
|
|
781
|
+
* pseudo-element's end value moves to a static holding animation, created
|
|
782
|
+
* before the long one goes.
|
|
727
783
|
*/
|
|
728
784
|
const scheduleRetire = (channel, animation, end) => {
|
|
729
785
|
clearTimeout(retireTimers.get(channel));
|
|
@@ -740,6 +796,12 @@ export function createAnimator(element, options = {}) {
|
|
|
740
796
|
return;
|
|
741
797
|
}
|
|
742
798
|
running.delete(channel);
|
|
799
|
+
// A pseudo-element holds its resting value, unless the stylesheet
|
|
800
|
+
// takes it back now (a borrowed dip that has ended).
|
|
801
|
+
const handsBack = channel === 'opacity' && borrowedOpacity != null && ![...landings].some(landing => landing.fadeIn?.isBorrowed === true);
|
|
802
|
+
if (pseudoElement != null && !handsBack) {
|
|
803
|
+
hold(channel, now());
|
|
804
|
+
}
|
|
743
805
|
animation.cancel();
|
|
744
806
|
releaseIdentity(channel);
|
|
745
807
|
flushReleases();
|
|
@@ -750,20 +812,30 @@ export function createAnimator(element, options = {}) {
|
|
|
750
812
|
/** The element's own (stylesheet) opacity, read once when a dip starts. */
|
|
751
813
|
const ownOpacity = () => {
|
|
752
814
|
const view = target?.ownerDocument.defaultView;
|
|
753
|
-
const value = target == null ? NaN : Number.parseFloat(view?.getComputedStyle(target).getPropertyValue('opacity') ?? '');
|
|
815
|
+
const value = target == null ? NaN : Number.parseFloat(view?.getComputedStyle(target, pseudoElement ?? null).getPropertyValue('opacity') ?? '');
|
|
754
816
|
return Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 1;
|
|
755
817
|
};
|
|
756
818
|
|
|
757
819
|
/**
|
|
758
820
|
* Whether the animator holds an opacity of its own on the element: an inline
|
|
759
|
-
* value it wrote (a `set` over a
|
|
760
|
-
* returns to that value.
|
|
821
|
+
* value it wrote, or a pseudo-element's holding animation (a `set` over a
|
|
822
|
+
* stylesheet that hides or dims it). A dip returns to that value.
|
|
761
823
|
*/
|
|
762
|
-
const writesOwnOpacity = () => (target?.style.getPropertyValue('opacity') ?? '') !== '';
|
|
824
|
+
const writesOwnOpacity = () => pseudoElement == null ? (target?.style.getPropertyValue('opacity') ?? '') !== '' : running.has('opacity');
|
|
763
825
|
|
|
764
|
-
/**
|
|
826
|
+
/**
|
|
827
|
+
* Gives the element's opacity back to its stylesheet: an element's inline
|
|
828
|
+
* value goes; a pseudo-element, which has no inline style, loses the
|
|
829
|
+
* animation holding its value.
|
|
830
|
+
*/
|
|
765
831
|
const releaseOwnOpacity = () => {
|
|
766
|
-
|
|
832
|
+
if (pseudoElement == null) {
|
|
833
|
+
target?.style.removeProperty('opacity');
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
const held = running.get('opacity');
|
|
837
|
+
running.delete('opacity');
|
|
838
|
+
held?.cancel();
|
|
767
839
|
};
|
|
768
840
|
|
|
769
841
|
/**
|
|
@@ -844,6 +916,9 @@ export function createAnimator(element, options = {}) {
|
|
|
844
916
|
releaseOwnOpacity();
|
|
845
917
|
return;
|
|
846
918
|
}
|
|
919
|
+
if (pseudoElement != null) {
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
847
922
|
if (target.style.getPropertyValue(channel) !== IDENTITY_TEXT[channel]) {
|
|
848
923
|
return;
|
|
849
924
|
}
|
|
@@ -903,9 +978,17 @@ export function createAnimator(element, options = {}) {
|
|
|
903
978
|
|
|
904
979
|
// -- promotion -------------------------------------------------------------
|
|
905
980
|
|
|
906
|
-
/** Writes the promoted channels as will-change. */
|
|
981
|
+
/** Writes the promoted channels as will-change (or the pseudo's property). */
|
|
907
982
|
const writePromotion = element => {
|
|
908
983
|
const list = [...promoted].join(', ');
|
|
984
|
+
if (promotionProperty != null) {
|
|
985
|
+
if (list === '') {
|
|
986
|
+
element.style.removeProperty(promotionProperty);
|
|
987
|
+
} else {
|
|
988
|
+
element.style.setProperty(promotionProperty, list);
|
|
989
|
+
}
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
909
992
|
if (list === '') {
|
|
910
993
|
element.style.willChange = ownWillChange ?? '';
|
|
911
994
|
ownWillChange = null;
|
|
@@ -924,7 +1007,7 @@ export function createAnimator(element, options = {}) {
|
|
|
924
1007
|
};
|
|
925
1008
|
|
|
926
1009
|
/**
|
|
927
|
-
* Gives the element a compositing layer for
|
|
1010
|
+
* Gives the element (or its pseudo-element) a compositing layer for
|
|
928
1011
|
* `channel` from the task that starts the motion: Mobile Safari runs an
|
|
929
1012
|
* animation whose start time is set from script on its compositor at its
|
|
930
1013
|
* first commit only if the element already has a layer.
|
|
@@ -1747,7 +1830,11 @@ export function createAnimator(element, options = {}) {
|
|
|
1747
1830
|
}
|
|
1748
1831
|
// After the landing's commit, which can promote the element again.
|
|
1749
1832
|
demote();
|
|
1833
|
+
// A pseudo-element holds an identity with a static animation, which the
|
|
1834
|
+
// cancel below drops: note the channels to hold again on the next node
|
|
1835
|
+
// (never a borrowed opacity, which is the stylesheet's).
|
|
1750
1836
|
const isOpacityBorrowed = borrowedOpacity != null || [...landings].some(landing => landing.restoreIsBorrowed === true);
|
|
1837
|
+
const pseudoHeld = pseudoElement == null || target == null ? null : new Set(Object.keys(CHANNELS).filter(channel => running.has(channel) && !(channel === 'opacity' && isOpacityBorrowed) && CHANNELS[channel].every(p => !segments.has(p) && resting[p] === IDENTITY[p])));
|
|
1751
1838
|
for (const animation of running.values()) {
|
|
1752
1839
|
animation.cancel();
|
|
1753
1840
|
}
|
|
@@ -1767,7 +1854,7 @@ export function createAnimator(element, options = {}) {
|
|
|
1767
1854
|
// differs, kept through a detach for the node that comes next.
|
|
1768
1855
|
if (target != null) {
|
|
1769
1856
|
const outgoing = target;
|
|
1770
|
-
heldIdentity = new Set(Object.keys(CHANNELS).filter(channel => outgoing.style.getPropertyValue(channel) === IDENTITY_TEXT[channel]));
|
|
1857
|
+
heldIdentity = pseudoHeld ?? new Set(Object.keys(CHANNELS).filter(channel => outgoing.style.getPropertyValue(channel) === IDENTITY_TEXT[channel]));
|
|
1771
1858
|
}
|
|
1772
1859
|
const held = heldIdentity;
|
|
1773
1860
|
target = next;
|
|
@@ -1792,8 +1879,13 @@ export function createAnimator(element, options = {}) {
|
|
|
1792
1879
|
} else if (held.has(channel)) {
|
|
1793
1880
|
// An identity the animator held inline over a stylesheet that
|
|
1794
1881
|
// differs goes onto the new node too (writeInline keeps it only
|
|
1795
|
-
// where the new node's stylesheet still differs)
|
|
1796
|
-
|
|
1882
|
+
// where the new node's stylesheet still differs); a pseudo-element's
|
|
1883
|
+
// is held again.
|
|
1884
|
+
if (pseudoElement != null) {
|
|
1885
|
+
hold(channel, time);
|
|
1886
|
+
} else {
|
|
1887
|
+
writeInline(channel, property => resting[property]);
|
|
1888
|
+
}
|
|
1797
1889
|
}
|
|
1798
1890
|
}
|
|
1799
1891
|
flushReleases();
|
|
@@ -68,7 +68,7 @@ import { resolveOnMedia } from "./onMediaTokens.js";
|
|
|
68
68
|
import { colorDefaults, spacingDefaults, sizeDefaults, borderDefaults, focusDefaults, radiusDefaults, shadowDefaults, durationDefaults, easeDefaults, typographyDefaults, textSizeDefaults, fontWeightDefaults, typeScaleDefaults } from "./tokens.stylex.js";
|
|
69
69
|
import { resolveThemeValues } from "./resolveThemeValues.js";
|
|
70
70
|
import { normalizeThemeAdaptations, resolveThemeAdaptationRules, resolveThemeGenerativeAxes } from "./themeAdaptations.js";
|
|
71
|
-
import { domainTokenDefaults } from "./domainTokens/
|
|
71
|
+
import { domainTokenDefaults } from "./domainTokens/domainTokenDefaults.js";
|
|
72
72
|
import { registerTheme } from "./themeRegistry.js";
|
|
73
73
|
import { resolveLocalTokenContract } from "./localTokens.js";
|
|
74
74
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domainTokenDefaults.d.ts","sourceRoot":"","sources":["../../../src/theme/domainTokens/domainTokenDefaults.ts"],"names":[],"mappings":"AAcA,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGtD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file domainTokens/domainTokenDefaults.ts
|
|
5
|
+
* @input syntaxTokenDefaults, dataTokenDefaults
|
|
6
|
+
* @output domainTokenDefaults
|
|
7
|
+
* @position Merges the domain token defaults for defineTheme. Kept out of the
|
|
8
|
+
* domainTokens barrel because defineTheme sits in a lazily imported module
|
|
9
|
+
* graph, which imports no barrel (pinned by scripts/core-single-bundle.test.mjs).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { syntaxTokenDefaults } from "../syntax/tokens.js";
|
|
13
|
+
import { dataTokenDefaults } from "./dataTokens.js";
|
|
14
|
+
|
|
15
|
+
/** All domain token defaults merged — used by defineTheme for validation */
|
|
16
|
+
export const domainTokenDefaults = {
|
|
17
|
+
...syntaxTokenDefaults,
|
|
18
|
+
...dataTokenDefaults
|
|
19
|
+
};
|
|
@@ -4,17 +4,18 @@
|
|
|
4
4
|
* @output domainTokenDefaults, DomainTokenName
|
|
5
5
|
* @position Token aggregator; consumed by defineTheme for validation + autocomplete
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Re-exports only. The merged map lives in domainTokenDefaults.ts so that
|
|
8
|
+
* defineTheme, inside a lazily imported module graph, imports it without a
|
|
9
|
+
* barrel. Actual token definitions live in their own directories (syntax/,
|
|
10
|
+
* dataviz/).
|
|
9
11
|
*/
|
|
10
12
|
export { syntaxTokenDefaults } from '../syntax/tokens.js';
|
|
11
13
|
export type { SyntaxTokenName } from '../syntax/tokens.js';
|
|
12
14
|
export { dataTokenDefaults } from './dataTokens.js';
|
|
13
15
|
export type { DataTokenName } from './dataTokens.js';
|
|
16
|
+
export { domainTokenDefaults } from './domainTokenDefaults.js';
|
|
14
17
|
import type { SyntaxTokenName } from '../syntax/tokens.js';
|
|
15
18
|
import type { DataTokenName } from './dataTokens.js';
|
|
16
|
-
/** All domain token defaults merged — used by defineTheme for validation */
|
|
17
|
-
export declare const domainTokenDefaults: Record<string, string>;
|
|
18
19
|
/** Union of all domain token names */
|
|
19
20
|
export type DomainTokenName = SyntaxTokenName | DataTokenName;
|
|
20
21
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/theme/domainTokens/index.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/theme/domainTokens/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAC,iBAAiB,EAAC,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAE1D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAEhD,sCAAsC;AACtC,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,aAAa,CAAC"}
|
|
@@ -6,18 +6,14 @@
|
|
|
6
6
|
* @output domainTokenDefaults, DomainTokenName
|
|
7
7
|
* @position Token aggregator; consumed by defineTheme for validation + autocomplete
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Re-exports only. The merged map lives in domainTokenDefaults.ts so that
|
|
10
|
+
* defineTheme, inside a lazily imported module graph, imports it without a
|
|
11
|
+
* barrel. Actual token definitions live in their own directories (syntax/,
|
|
12
|
+
* dataviz/).
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
export { syntaxTokenDefaults } from "../syntax/tokens.js";
|
|
14
16
|
export { dataTokenDefaults } from "./dataTokens.js";
|
|
15
|
-
|
|
16
|
-
import { dataTokenDefaults } from "./dataTokens.js";
|
|
17
|
-
/** All domain token defaults merged — used by defineTheme for validation */
|
|
18
|
-
export const domainTokenDefaults = {
|
|
19
|
-
...syntaxTokenDefaults,
|
|
20
|
-
...dataTokenDefaults
|
|
21
|
-
};
|
|
17
|
+
export { domainTokenDefaults } from "./domainTokenDefaults.js";
|
|
22
18
|
|
|
23
19
|
/** Union of all domain token names */
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file focusReturn.ts
|
|
3
|
+
* @input The document's current active element and the shared interaction
|
|
4
|
+
* modality.
|
|
5
|
+
* @output Whether focus is currently "detached" — on nothing in particular —
|
|
6
|
+
* and a focus move whose ring follows the last input.
|
|
7
|
+
* @position Utility; used by overlay triggers (e.g. DateInput, DateTimeInput)
|
|
8
|
+
* that return focus to their control when the overlay closes, but only when
|
|
9
|
+
* the dismiss did not already move focus somewhere the user chose, and by
|
|
10
|
+
* overlays (Dialog, DropdownMenu) that move focus programmatically.
|
|
11
|
+
*/
|
|
12
|
+
import { type InteractionModality } from './interactionModality.js';
|
|
1
13
|
/**
|
|
2
14
|
* True when focus rests on nothing in particular — no active element, or the
|
|
3
15
|
* document body / root element.
|
|
@@ -21,8 +33,12 @@ export declare function isFocusDetached(doc?: Document): boolean;
|
|
|
21
33
|
* autofocus target, the control that opened a Dialog, or a menu trigger the
|
|
22
34
|
* caller renders. Pass `options` (for example `preventScroll`) as to `focus()`.
|
|
23
35
|
*
|
|
36
|
+
* `modality` defaults to the page's last input. A caller moving focus inside a
|
|
37
|
+
* second document (a same-origin iframe, a Document Picture-in-Picture window)
|
|
38
|
+
* passes that document's, which it tracks with `trackInteractionModalityIn`.
|
|
39
|
+
*
|
|
24
40
|
* Make sure modality tracking is active (`useInteractionModalityTracking()`)
|
|
25
41
|
* in the component that calls this.
|
|
26
42
|
*/
|
|
27
|
-
export declare function focusForLastInput(element: HTMLElement, options?: FocusOptions): void;
|
|
43
|
+
export declare function focusForLastInput(element: HTMLElement, options?: FocusOptions, modality?: InteractionModality): void;
|
|
28
44
|
//# sourceMappingURL=focusReturn.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focusReturn.d.ts","sourceRoot":"","sources":["../../src/utils/focusReturn.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"focusReturn.d.ts","sourceRoot":"","sources":["../../src/utils/focusReturn.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,QAAmB,GAAG,OAAO,CAKjE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,YAAY,EACtB,QAAQ,GAAE,mBAA8C,GACvD,IAAI,CA2BN"}
|
|
@@ -41,14 +41,21 @@ export function isFocusDetached(doc = document) {
|
|
|
41
41
|
* autofocus target, the control that opened a Dialog, or a menu trigger the
|
|
42
42
|
* caller renders. Pass `options` (for example `preventScroll`) as to `focus()`.
|
|
43
43
|
*
|
|
44
|
+
* `modality` defaults to the page's last input. A caller moving focus inside a
|
|
45
|
+
* second document (a same-origin iframe, a Document Picture-in-Picture window)
|
|
46
|
+
* passes that document's, which it tracks with `trackInteractionModalityIn`.
|
|
47
|
+
*
|
|
44
48
|
* Make sure modality tracking is active (`useInteractionModalityTracking()`)
|
|
45
49
|
* in the component that calls this.
|
|
46
50
|
*/
|
|
47
|
-
export function focusForLastInput(element, options) {
|
|
51
|
+
export function focusForLastInput(element, options, modality = getInteractionModality()) {
|
|
48
52
|
// A text-entry field paints its own focus treatment to show where typing
|
|
49
|
-
// goes, and an extra blur there can run validation or mark it touched.
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
// goes, and an extra blur there can run validation or mark it touched. The
|
|
54
|
+
// field's own window: one in an iframe or a Picture-in-Picture window is
|
|
55
|
+
// never an instance of the page's constructors.
|
|
56
|
+
const view = element.ownerDocument.defaultView ?? window;
|
|
57
|
+
const isTextEntry = element instanceof view.HTMLInputElement || element instanceof view.HTMLTextAreaElement || element instanceof view.HTMLSelectElement || element.isContentEditable;
|
|
58
|
+
if (isTextEntry || modality !== 'pointer') {
|
|
52
59
|
if (options === undefined) {
|
|
53
60
|
element.focus();
|
|
54
61
|
} else {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The plain text a node renders through strings, numbers and element
|
|
4
|
+
* children, joined with spaces. Text a component renders internally, from
|
|
5
|
+
* props other than `children`, is not reachable and yields `''`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getNodeText(node: ReactNode): string;
|
|
8
|
+
//# sourceMappingURL=getNodeText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getNodeText.d.ts","sourceRoot":"","sources":["../../src/utils/getNodeText.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAkBnD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file getNodeText.ts
|
|
5
|
+
* @input Receives a React node
|
|
6
|
+
* @output Exports getNodeText, the node's plain text
|
|
7
|
+
* @position Shared utility; consumed where a rendered node also needs a
|
|
8
|
+
* spoken name (Toast announcements, Table column-resize handle names)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { isValidElement } from 'react';
|
|
12
|
+
/**
|
|
13
|
+
* The plain text a node renders through strings, numbers and element
|
|
14
|
+
* children, joined with spaces. Text a component renders internally, from
|
|
15
|
+
* props other than `children`, is not reachable and yields `''`.
|
|
16
|
+
*/
|
|
17
|
+
export function getNodeText(node) {
|
|
18
|
+
if (node == null || typeof node === 'boolean') {
|
|
19
|
+
return '';
|
|
20
|
+
}
|
|
21
|
+
if (typeof node === 'string') {
|
|
22
|
+
return node;
|
|
23
|
+
}
|
|
24
|
+
if (typeof node === 'number') {
|
|
25
|
+
return String(node);
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(node)) {
|
|
28
|
+
return node.map(getNodeText).filter(Boolean).join(' ');
|
|
29
|
+
}
|
|
30
|
+
if (/*#__PURE__*/isValidElement(node)) {
|
|
31
|
+
const {
|
|
32
|
+
children
|
|
33
|
+
} = node.props;
|
|
34
|
+
return getNodeText(children);
|
|
35
|
+
}
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
@@ -2,8 +2,17 @@ export type InteractionModality = 'keyboard' | 'pointer';
|
|
|
2
2
|
declare function trackInteractionModality(): () => void;
|
|
3
3
|
/** Activate shared modality tracking when the first consumer mounts. */
|
|
4
4
|
export declare function useInteractionModalityTracking(): void;
|
|
5
|
-
/**
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Track a second document while a consumer there is mounted: a component an
|
|
7
|
+
* app renders into a same-origin iframe or a Document Picture-in-Picture
|
|
8
|
+
* window gets input there that never reaches the page's listeners. The first
|
|
9
|
+
* consumer installs the document's listener pair and the last one's cleanup
|
|
10
|
+
* removes it. Read the value with `getInteractionModality(doc)`. The page's
|
|
11
|
+
* own document keeps its document-lifetime listeners.
|
|
12
|
+
*/
|
|
13
|
+
export declare function trackInteractionModalityIn(targetDocument: Document): () => void;
|
|
14
|
+
/** How the user last interacted with the page, or with `targetDocument`. */
|
|
15
|
+
export declare function getInteractionModality(targetDocument?: Document): InteractionModality;
|
|
7
16
|
/** Test-only: restore the initial state between cases. */
|
|
8
17
|
export declare function __resetInteractionModalityForTest(): void;
|
|
9
18
|
/** Test-only: activate the tracker without rendering a hook. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactionModality.d.ts","sourceRoot":"","sources":["../../src/utils/interactionModality.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"interactionModality.d.ts","sourceRoot":"","sources":["../../src/utils/interactionModality.ts"],"names":[],"mappings":"AAwCA,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,SAAS,CAAC;AAgDzD,iBAAS,wBAAwB,IAAI,MAAM,IAAI,CAsB9C;AAED,wEAAwE;AACxE,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,QAAQ,GACvB,MAAM,IAAI,CAkCZ;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CACpC,cAAc,CAAC,EAAE,QAAQ,GACxB,mBAAmB,CAOrB;AAED,0DAA0D;AAC1D,wBAAgB,iCAAiC,IAAI,IAAI,CAIxD;AAED,gEAAgE;AAChE,eAAO,MAAM,yCAAyC,iCAC5B,CAAC"}
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* @file interactionModality.ts
|
|
7
7
|
* @input Global pointerdown/keydown events
|
|
8
8
|
* @output `useInteractionModalityTracking()` activates document-lifetime tracking;
|
|
9
|
-
* `getInteractionModality()` reads how the user last interacted
|
|
9
|
+
* `getInteractionModality()` reads how the user last interacted;
|
|
10
|
+
* `trackInteractionModalityIn(doc)` and `getInteractionModality(doc)` do the
|
|
11
|
+
* same for a second document
|
|
10
12
|
* @position Internal document-wide singleton; used where `:focus-visible` alone
|
|
11
13
|
* is too broad
|
|
12
14
|
*
|
|
@@ -26,8 +28,12 @@
|
|
|
26
28
|
* The store lives on `document`, so duplicate Astryx bundles share one state
|
|
27
29
|
* value and one listener pair. The first mounted consumer activates tracking;
|
|
28
30
|
* the listeners then remain for the document lifetime so input during a gap
|
|
29
|
-
* between consumers is not lost.
|
|
30
|
-
*
|
|
31
|
+
* between consumers is not lost. A second document (a same-origin iframe, a
|
|
32
|
+
* Document Picture-in-Picture window) gets its own store when a component
|
|
33
|
+
* tracks it, since input there never reaches the page's listeners; its
|
|
34
|
+
* listeners stay only while a consumer there is mounted. Importing this module
|
|
35
|
+
* has no DOM side effects, and server rendering keeps the keyboard-safe
|
|
36
|
+
* default.
|
|
31
37
|
*/
|
|
32
38
|
import { useEffect } from 'react';
|
|
33
39
|
const interactionModalityStoreKey = Symbol.for('@astryxdesign/core/interaction-modality/v1');
|
|
@@ -89,8 +95,55 @@ export function useInteractionModalityTracking() {
|
|
|
89
95
|
useEffect(() => trackInteractionModality(), []);
|
|
90
96
|
}
|
|
91
97
|
|
|
92
|
-
/**
|
|
93
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Track a second document while a consumer there is mounted: a component an
|
|
100
|
+
* app renders into a same-origin iframe or a Document Picture-in-Picture
|
|
101
|
+
* window gets input there that never reaches the page's listeners. The first
|
|
102
|
+
* consumer installs the document's listener pair and the last one's cleanup
|
|
103
|
+
* removes it. Read the value with `getInteractionModality(doc)`. The page's
|
|
104
|
+
* own document keeps its document-lifetime listeners.
|
|
105
|
+
*/
|
|
106
|
+
export function trackInteractionModalityIn(targetDocument) {
|
|
107
|
+
if (typeof document !== 'undefined' && targetDocument === document) {
|
|
108
|
+
return trackInteractionModality();
|
|
109
|
+
}
|
|
110
|
+
const store = getStore(targetDocument);
|
|
111
|
+
store.consumers = (store.consumers ?? 0) + 1;
|
|
112
|
+
if (store.consumers === 1) {
|
|
113
|
+
store.isListening = true;
|
|
114
|
+
targetDocument.addEventListener('pointerdown', store.onPointerDown, {
|
|
115
|
+
capture: true,
|
|
116
|
+
passive: true
|
|
117
|
+
});
|
|
118
|
+
targetDocument.addEventListener('keydown', store.onKeyDown, {
|
|
119
|
+
capture: true,
|
|
120
|
+
passive: true
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
let isReleased = false;
|
|
124
|
+
return () => {
|
|
125
|
+
if (isReleased) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
isReleased = true;
|
|
129
|
+
store.consumers = (store.consumers ?? 1) - 1;
|
|
130
|
+
if (store.consumers === 0) {
|
|
131
|
+
store.isListening = false;
|
|
132
|
+
targetDocument.removeEventListener('pointerdown', store.onPointerDown, {
|
|
133
|
+
capture: true
|
|
134
|
+
});
|
|
135
|
+
targetDocument.removeEventListener('keydown', store.onKeyDown, {
|
|
136
|
+
capture: true
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** How the user last interacted with the page, or with `targetDocument`. */
|
|
143
|
+
export function getInteractionModality(targetDocument) {
|
|
144
|
+
if (targetDocument != null) {
|
|
145
|
+
return getStore(targetDocument).modality;
|
|
146
|
+
}
|
|
94
147
|
return typeof document === 'undefined' ? 'keyboard' : getStore(document).modality;
|
|
95
148
|
}
|
|
96
149
|
|