@astryxdesign/core 0.7.8 → 0.7.9-canary.07992bb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AppShell/observeMainOverflow.d.ts.map +1 -1
- package/dist/AppShell/observeMainOverflow.js +9 -6
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +5 -0
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +40 -8
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +61 -21
- package/dist/Calendar/Calendar.d.ts +14 -2
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +63 -74
- package/dist/Calendar/getInitialFocusDate.d.ts +4 -1
- package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -1
- package/dist/Calendar/getInitialFocusDate.js +7 -5
- package/dist/Calendar/hooks/useCalendarDays.d.ts +19 -2
- package/dist/Calendar/hooks/useCalendarDays.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarDays.js +57 -64
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts +28 -3
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarNavigation.js +33 -22
- package/dist/Calendar/styles.d.ts +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +54 -11
- package/dist/ClickableCard/ClickableCard.d.ts +1 -1
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +5 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +4 -1
- package/dist/DateInput/PickerWheel.d.ts.map +1 -1
- package/dist/DateInput/PickerWheel.js +7 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +5 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +4 -1
- package/dist/Dialog/Dialog.d.ts +2 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +12 -1
- package/dist/Drawer/useDrawerDialogPresence.d.ts +2 -1
- package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
- package/dist/Drawer/useDrawerDialogPresence.js +11 -2
- package/dist/DropdownMenu/DropdownMenu.d.ts +9 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +9 -4
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +3 -2
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +3 -2
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +3 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +3 -2
- package/dist/Field/inputDisabledFocus.d.ts +4 -4
- package/dist/Field/inputStyles.stylex.d.ts +1 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +16 -2
- package/dist/HoverCard/useHoverCard.d.ts +3 -1
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/Icon/Icon.d.ts +1 -1
- package/dist/InfoTip/InfoTip.d.ts +1 -0
- package/dist/InfoTip/InfoTip.d.ts.map +1 -1
- package/dist/InfoTip/InfoTip.js +1 -0
- package/dist/InputGroup/InputGroup.d.ts +4 -3
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +2 -2
- package/dist/InputGroup/groupStyles.d.ts +1 -1
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +1 -1
- package/dist/Item/Item.d.ts +2 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +29 -6
- package/dist/Layer/holdEntranceInput.d.ts +24 -0
- package/dist/Layer/holdEntranceInput.d.ts.map +1 -0
- package/dist/Layer/holdEntranceInput.js +65 -0
- package/dist/Layer/inputHold.d.ts +49 -0
- package/dist/Layer/inputHold.d.ts.map +1 -0
- package/dist/Layer/inputHold.js +636 -0
- package/dist/Layer/preserveAnimations.d.ts +1 -5
- package/dist/Layer/preserveAnimations.d.ts.map +1 -1
- package/dist/Layer/preserveAnimations.js +12 -214
- package/dist/Layer/useLayer.d.ts +3 -1
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +64 -4
- package/dist/Layout/LayoutContent.d.ts +3 -1
- package/dist/Layout/LayoutContent.d.ts.map +1 -1
- package/dist/Layout/LayoutContent.js +12 -4
- package/dist/Layout/LayoutPanel.d.ts +4 -1
- package/dist/Layout/LayoutPanel.d.ts.map +1 -1
- package/dist/Layout/LayoutPanel.js +13 -4
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +4 -0
- package/dist/MetadataList/MetadataList.js +1 -1
- package/dist/MobileNav/MobileNav.d.ts +11 -1
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +39 -1
- package/dist/MoreMenu/MoreMenu.d.ts +5 -3
- package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.d.ts +4 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +244 -11
- package/dist/Popover/usePopover.d.ts +1 -0
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +12 -5
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.js +4 -2
- package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchToken.js +3 -1
- package/dist/PowerSearch/formatFilterValue.d.ts +9 -3
- package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatFilterValue.js +14 -11
- package/dist/PowerSearch/formatTokenValue.d.ts +6 -2
- package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatTokenValue.js +6 -3
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +22 -4
- package/dist/SelectableCard/SelectableCard.d.ts +1 -1
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +5 -1
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +14 -71
- package/dist/Spinner/index.d.ts +1 -1
- package/dist/Spinner/index.d.ts.map +1 -1
- package/dist/Spinner/spinnerRotor.d.ts +28 -0
- package/dist/Spinner/spinnerRotor.d.ts.map +1 -0
- package/dist/Spinner/spinnerRotor.js +98 -0
- package/dist/Stack/StackItem.d.ts +8 -4
- package/dist/Stack/StackItem.d.ts.map +1 -1
- package/dist/Stack/StackItem.js +17 -4
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +13 -10
- package/dist/Table/plugins/sortable/useTableSortable.js +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +14 -8
- package/dist/Timestamp/formatInstant.d.ts +10 -1
- package/dist/Timestamp/formatInstant.d.ts.map +1 -1
- package/dist/Timestamp/formatInstant.js +13 -27
- package/dist/Timestamp/tooltipEntries.d.ts +5 -3
- package/dist/Timestamp/tooltipEntries.d.ts.map +1 -1
- package/dist/Timestamp/tooltipEntries.js +6 -4
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +9 -0
- package/dist/Token/TokenLink.d.ts +1 -1
- package/dist/Token/TokenLink.d.ts.map +1 -1
- package/dist/Token/TokenLink.js +4 -1
- package/dist/Tokenizer/Tokenizer.d.ts +14 -10
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +189 -89
- package/dist/Tooltip/useTooltip.d.ts +3 -1
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +162 -59
- package/dist/TreeList/TreeListItem.d.ts +2 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +27 -3
- package/dist/astryx.css +45 -18
- package/dist/gestures/GestureHost.d.ts +2 -2
- package/dist/gestures/GestureHost.d.ts.map +1 -1
- package/dist/gestures/GestureHost.js +21 -6
- package/dist/gestures/PanGestureRecognizer.d.ts +11 -1
- package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/PanGestureRecognizer.js +15 -1
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +6 -1
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/nativeScroll.d.ts +3 -6
- package/dist/gestures/nativeScroll.d.ts.map +1 -1
- package/dist/gestures/nativeScroll.js +7 -52
- package/dist/gestures/wheelSegmenter.d.ts +68 -1
- package/dist/gestures/wheelSegmenter.d.ts.map +1 -1
- package/dist/gestures/wheelSegmenter.js +199 -10
- package/dist/hooks/StackItemScrollRegion.d.ts +31 -0
- package/dist/hooks/StackItemScrollRegion.d.ts.map +1 -0
- package/dist/hooks/StackItemScrollRegion.js +40 -0
- package/dist/hooks/menuPressGesture.d.ts +133 -21
- package/dist/hooks/menuPressGesture.d.ts.map +1 -1
- package/dist/hooks/menuPressGesture.js +155 -30
- package/dist/hooks/menuPressValues.d.ts +16 -0
- package/dist/hooks/menuPressValues.d.ts.map +1 -0
- package/dist/hooks/menuPressValues.js +18 -0
- package/dist/hooks/useClickableContainer.d.ts +27 -5
- package/dist/hooks/useClickableContainer.d.ts.map +1 -1
- package/dist/hooks/useClickableContainer.js +41 -5
- package/dist/hooks/useFocusTrap.d.ts +10 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +225 -132
- package/dist/hooks/useMenuPress.d.ts +34 -1
- package/dist/hooks/useMenuPress.d.ts.map +1 -1
- package/dist/hooks/useMenuPress.js +93 -5
- package/dist/hooks/usePressFeedback.d.ts +6 -6
- package/dist/hooks/usePressFeedback.js +6 -6
- package/dist/hooks/useScrollRegionProps.d.ts +35 -0
- package/dist/hooks/useScrollRegionProps.d.ts.map +1 -0
- package/dist/hooks/useScrollRegionProps.js +51 -0
- package/dist/i18n/InternationalizationContext.d.ts +6 -0
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.d.ts +21 -3
- package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.js +8 -3
- package/dist/i18n/generated-english/hooks/useScrollRegionProps.generated.d.ts +8 -0
- package/dist/i18n/generated-english/hooks/useScrollRegionProps.generated.d.ts.map +1 -0
- package/dist/i18n/generated-english/hooks/useScrollRegionProps.generated.js +12 -0
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +1 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +1 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/useCalendarSystem.d.ts +19 -0
- package/dist/i18n/useCalendarSystem.d.ts.map +1 -0
- package/dist/i18n/useCalendarSystem.js +61 -0
- package/dist/internal/spinner-rotor.d.ts +16 -0
- package/dist/internal/spinner-rotor.d.ts.map +1 -0
- package/dist/internal/spinner-rotor.js +16 -0
- package/dist/internal/touch.d.ts +14 -1
- package/dist/internal/touch.d.ts.map +1 -1
- package/dist/internal/touch.js +20 -2
- package/dist/motion/carryAnimations.d.ts +58 -0
- package/dist/motion/carryAnimations.d.ts.map +1 -0
- package/dist/motion/carryAnimations.js +305 -0
- package/dist/motion/transientCopy.d.ts +4 -2
- package/dist/motion/transientCopy.d.ts.map +1 -1
- package/dist/motion/transientCopy.js +34 -5
- package/dist/motion/uikit/gestures.d.ts +41 -0
- package/dist/motion/uikit/gestures.d.ts.map +1 -1
- package/dist/motion/uikit/gestures.js +25 -0
- package/dist/motion/uikit/index.d.ts +1 -1
- package/dist/motion/uikit/index.d.ts.map +1 -1
- package/dist/motion/uikit/index.js +1 -1
- package/dist/motion/uikit/timing.d.ts +14 -10
- package/dist/motion/uikit/timing.d.ts.map +1 -1
- package/dist/motion/uikit/timing.js +7 -5
- package/dist/privateAttributes/menuPressLit.stylex.d.ts +52 -0
- package/dist/privateAttributes/menuPressLit.stylex.d.ts.map +1 -0
- package/dist/privateAttributes/menuPressLit.stylex.js +99 -0
- package/dist/privateAttributes/press.stylex.d.ts +139 -0
- package/dist/privateAttributes/press.stylex.d.ts.map +1 -0
- package/dist/privateAttributes/press.stylex.js +97 -0
- package/dist/theme/themeMotion.d.ts +3 -2
- package/dist/theme/themeMotion.d.ts.map +1 -1
- package/dist/theme/themeMotion.js +3 -2
- package/dist/theme/tokens.stylex.d.ts +2 -2
- package/dist/theme/tokens.stylex.js +1 -1
- package/dist/utils/calendarSystem.d.ts +114 -0
- package/dist/utils/calendarSystem.d.ts.map +1 -0
- package/dist/utils/calendarSystem.js +386 -0
- package/dist/utils/flatTree.d.ts +6 -3
- package/dist/utils/flatTree.d.ts.map +1 -1
- package/dist/utils/flatTree.js +13 -3
- package/dist/utils/hitArea.d.ts.map +1 -1
- package/dist/utils/hitArea.js +82 -5
- package/dist/utils/inputStream.d.ts +14 -1
- package/dist/utils/inputStream.d.ts.map +1 -1
- package/dist/utils/inputStream.js +40 -9
- package/dist/utils/interactionOverlay.stylex.d.ts +5 -9
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +29 -31
- package/dist/utils/plainDate.d.ts +23 -7
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +57 -18
- package/dist/utils/pressFeedback.d.ts +10 -2
- package/dist/utils/pressFeedback.d.ts.map +1 -1
- package/dist/utils/pressFeedback.js +40 -15
- package/dist/utils/pressGesture.d.ts +12 -6
- package/dist/utils/pressGesture.d.ts.map +1 -1
- package/dist/utils/pressGesture.js +26 -8
- package/dist/utils/scrollView.d.ts +25 -0
- package/dist/utils/scrollView.d.ts.map +1 -0
- package/dist/utils/scrollView.js +108 -0
- package/dist/utils/selectionLock.d.ts.map +1 -1
- package/dist/utils/selectionLock.js +1 -10
- package/dist/utils/touchHitArea.stylex.d.ts +35 -0
- package/dist/utils/touchHitArea.stylex.d.ts.map +1 -0
- package/dist/utils/touchHitArea.stylex.js +32 -0
- package/dist/utils/triggerFocus.d.ts +5 -0
- package/dist/utils/triggerFocus.d.ts.map +1 -1
- package/dist/utils/triggerFocus.js +9 -2
- package/locales/en.json +4 -0
- package/locales/pseudo.json +3 -0
- package/package.json +10 -4
- package/src/AppShell/observeMainOverflow.ts +9 -6
- package/src/BottomSheet/BottomSheet.tsx +5 -0
- package/src/BottomSheet/BottomSheetPanel.tsx +64 -7
- package/src/BottomSheet/useSheetGestures.ts +83 -20
- package/src/Calendar/Calendar.doc.mjs +76 -6
- package/src/Calendar/Calendar.tsx +123 -104
- package/src/Calendar/getInitialFocusDate.ts +22 -8
- package/src/Calendar/hooks/useCalendarDays.ts +89 -63
- package/src/Calendar/hooks/useCalendarNavigation.ts +68 -26
- package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -2
- package/src/CheckboxInput/CheckboxInput.tsx +71 -9
- package/src/ClickableCard/ClickableCard.tsx +8 -1
- package/src/DateInput/DateInput.tsx +2 -0
- package/src/DateInput/PickerWheel.tsx +7 -2
- package/src/DateRangeInput/DateRangeInput.tsx +3 -1
- package/src/DateTimeInput/DateTimeInput.tsx +2 -0
- package/src/Dialog/Dialog.doc.mjs +1 -1
- package/src/Dialog/Dialog.tsx +12 -1
- package/src/Drawer/Drawer.doc.mjs +1 -1
- package/src/Drawer/useDrawerDialogPresence.ts +9 -2
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -2
- package/src/DropdownMenu/DropdownMenu.tsx +29 -5
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +5 -1
- package/src/DropdownMenu/DropdownMenuItem.tsx +8 -4
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +5 -1
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +5 -1
- package/src/FileInput/FileInput.tsx +16 -2
- package/src/HoverCard/useHoverCard.tsx +3 -1
- package/src/InfoTip/InfoTip.doc.mjs +26 -2
- package/src/InfoTip/InfoTip.tsx +1 -0
- package/src/InputGroup/InputGroup.doc.mjs +4 -3
- package/src/InputGroup/InputGroup.tsx +4 -3
- package/src/InputGroup/groupStyles.ts +3 -1
- package/src/Item/Item.tsx +51 -9
- package/src/Layer/holdEntranceInput.ts +84 -0
- package/src/Layer/inputHold.ts +734 -0
- package/src/Layer/preserveAnimations.ts +12 -275
- package/src/Layer/useLayer.tsx +77 -4
- package/src/Layout/LayoutContent.doc.mjs +6 -3
- package/src/Layout/LayoutContent.tsx +10 -4
- package/src/Layout/LayoutPanel.doc.mjs +6 -3
- package/src/Layout/LayoutPanel.tsx +11 -4
- package/src/Lightbox/Lightbox.tsx +4 -0
- package/src/MetadataList/MetadataList.tsx +1 -1
- package/src/MobileNav/MobileNav.doc.mjs +3 -3
- package/src/MobileNav/MobileNav.tsx +39 -1
- package/src/MoreMenu/MoreMenu.doc.mjs +2 -4
- package/src/MoreMenu/MoreMenu.tsx +5 -3
- package/src/NumberInput/NumberInput.doc.mjs +1 -1
- package/src/NumberInput/NumberInput.tsx +259 -11
- package/src/Popover/usePopover.tsx +1 -0
- package/src/PowerSearch/PowerSearch.doc.mjs +3 -3
- package/src/PowerSearch/PowerSearch.tsx +20 -3
- package/src/PowerSearch/PowerSearchBottomSheet.tsx +4 -1
- package/src/PowerSearch/PowerSearchToken.tsx +3 -0
- package/src/PowerSearch/formatFilterValue.ts +21 -11
- package/src/PowerSearch/formatTokenValue.ts +7 -1
- package/src/RadioList/RadioListItem.doc.mjs +3 -2
- package/src/RadioList/RadioListItem.tsx +25 -7
- package/src/SelectableCard/SelectableCard.tsx +8 -1
- package/src/Spinner/Spinner.tsx +7 -89
- package/src/Spinner/index.ts +1 -5
- package/src/Spinner/spinnerRotor.ts +113 -0
- package/src/Stack/Stack.doc.mjs +1 -1
- package/src/Stack/StackItem.tsx +27 -13
- package/src/Switch/Switch.tsx +7 -6
- package/src/Table/plugins/sortable/useTableSortable.tsx +1 -1
- package/src/Timestamp/Timestamp.doc.mjs +3 -3
- package/src/Timestamp/Timestamp.tsx +13 -8
- package/src/Timestamp/formatInstant.ts +49 -28
- package/src/Timestamp/tooltipEntries.ts +7 -3
- package/src/Token/Token.tsx +18 -1
- package/src/Token/TokenLink.tsx +7 -1
- package/src/Tokenizer/Tokenizer.doc.mjs +3 -3
- package/src/Tokenizer/Tokenizer.tsx +252 -115
- package/src/Tooltip/useTooltip.tsx +178 -80
- package/src/TreeList/TreeListItem.tsx +36 -2
- package/src/gestures/GestureHost.ts +21 -5
- package/src/gestures/PanGestureRecognizer.ts +19 -2
- package/src/gestures/README.md +14 -5
- package/src/gestures/ScreenEdgePanGestureRecognizer.ts +6 -1
- package/src/gestures/nativeScroll.ts +12 -68
- package/src/gestures/wheelSegmenter.ts +243 -10
- package/src/hooks/StackItemScrollRegion.tsx +57 -0
- package/src/hooks/menuPressGesture.ts +244 -38
- package/src/hooks/menuPressValues.ts +18 -0
- package/src/hooks/useClickableContainer.doc.mjs +8 -2
- package/src/hooks/useClickableContainer.ts +72 -6
- package/src/hooks/useFocusTrap.ts +268 -151
- package/src/hooks/useMenuPress.ts +118 -11
- package/src/hooks/usePressFeedback.doc.mjs +3 -3
- package/src/hooks/usePressFeedback.ts +6 -6
- package/src/hooks/useScrollRegionProps.ts +76 -0
- package/src/i18n/InternationalizationContext.ts +6 -0
- package/src/i18n/InternationalizationProvider.doc.mjs +29 -1
- package/src/i18n/InternationalizationProvider.tsx +33 -3
- package/src/i18n/generated-english/hooks/useScrollRegionProps.generated.ts +13 -0
- package/src/i18n/generated-locales/en.generated.ts +1 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +1 -0
- package/src/i18n/index.ts +2 -0
- package/src/i18n/useCalendarSystem.ts +95 -0
- package/src/internal/spinner-rotor.ts +20 -0
- package/src/internal/touch.ts +34 -1
- package/src/motion/MEASUREMENTS.md +11 -0
- package/src/motion/carryAnimations.ts +389 -0
- package/src/motion/transientCopy.ts +45 -5
- package/src/motion/uikit/gestures.ts +22 -0
- package/src/motion/uikit/index.ts +1 -0
- package/src/motion/uikit/timing.ts +7 -5
- package/src/privateAttributes/menuPressLit.stylex.ts +104 -0
- package/src/privateAttributes/press.stylex.ts +243 -0
- package/src/theme/themeMotion.ts +3 -2
- package/src/theme/tokens.stylex.ts +1 -1
- package/src/utils/calendarSystem.ts +548 -0
- package/src/utils/flatTree.ts +15 -3
- package/src/utils/hitArea.ts +107 -5
- package/src/utils/inputStream.ts +47 -10
- package/src/utils/interactionOverlay.stylex.ts +19 -22
- package/src/utils/plainDate.ts +84 -19
- package/src/utils/pressFeedback.ts +46 -14
- package/src/utils/pressGesture.ts +35 -9
- package/src/utils/scrollView.ts +135 -0
- package/src/utils/selectionLock.ts +5 -10
- package/src/utils/touchHitArea.stylex.ts +41 -0
- package/src/utils/triggerFocus.ts +17 -4
|
@@ -13,6 +13,7 @@ import React from 'react';
|
|
|
13
13
|
import * as stylex from '@stylexjs/stylex';
|
|
14
14
|
import {Token} from '../Token';
|
|
15
15
|
import {useLocale} from '../i18n/useLocale';
|
|
16
|
+
import {useCalendarSystem} from '../i18n/useCalendarSystem';
|
|
16
17
|
import {fontWeightVars} from '../theme/tokens.stylex';
|
|
17
18
|
import {formatFilterValue} from './formatFilterValue';
|
|
18
19
|
import {resolveOperatorLabel} from './resolveOperatorLabel';
|
|
@@ -47,6 +48,7 @@ export function PowerSearchToken({
|
|
|
47
48
|
const config = useInternalConfig(configProp);
|
|
48
49
|
const t = useComponentTranslator();
|
|
49
50
|
const locale = useLocale();
|
|
51
|
+
const calendar = useCalendarSystem(undefined, 'PowerSearchToken');
|
|
50
52
|
|
|
51
53
|
const fieldLabel = field.label;
|
|
52
54
|
const resolvedOperatorLabel = resolveOperatorLabel(operator, t);
|
|
@@ -68,6 +70,7 @@ export function PowerSearchToken({
|
|
|
68
70
|
t,
|
|
69
71
|
locale,
|
|
70
72
|
timezoneID,
|
|
73
|
+
calendar,
|
|
71
74
|
);
|
|
72
75
|
|
|
73
76
|
const valueContent = valueStr ? (
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file formatFilterValue.ts
|
|
5
|
-
* @input OperatorValue, FilterValue, config
|
|
5
|
+
* @input OperatorValue, FilterValue, config, locale, time zone, calendar
|
|
6
6
|
* @output Formatted display string for a filter value
|
|
7
7
|
* @position Pure utility; consumed by PowerSearch token rendering
|
|
8
8
|
*
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
import type {OperatorValue, FilterValue, EnumItem} from './types';
|
|
14
14
|
import type {InternalConfig} from './useInternalConfig';
|
|
15
15
|
import type {Locale, TranslatorFn} from '../i18n';
|
|
16
|
+
import {
|
|
17
|
+
formatCalendarInstant,
|
|
18
|
+
type CalendarSystem,
|
|
19
|
+
} from '../utils/calendarSystem';
|
|
16
20
|
import {truncateCharacters} from '../utils/characters';
|
|
17
21
|
import {registerEnglishFallback} from '../i18n/englishFallback';
|
|
18
22
|
import english from '../i18n/generated-english/PowerSearch/formatFilterValue.generated';
|
|
@@ -67,25 +71,24 @@ export function formatDateAbsolute(
|
|
|
67
71
|
locale: Locale,
|
|
68
72
|
timezoneID: string | undefined,
|
|
69
73
|
isDateOnly = true,
|
|
74
|
+
calendar: CalendarSystem = 'gregory',
|
|
70
75
|
): string {
|
|
71
76
|
const options: Intl.DateTimeFormatOptions = isDateOnly
|
|
72
|
-
? {
|
|
73
|
-
year: 'numeric',
|
|
74
|
-
month: 'short',
|
|
75
|
-
day: 'numeric',
|
|
76
|
-
timeZone: resolveDateZone(timezoneID, true),
|
|
77
|
-
calendar: 'gregory',
|
|
78
|
-
}
|
|
77
|
+
? {year: 'numeric', month: 'short', day: 'numeric'}
|
|
79
78
|
: {
|
|
80
79
|
year: 'numeric',
|
|
81
80
|
month: 'short',
|
|
82
81
|
day: 'numeric',
|
|
83
82
|
hour: 'numeric',
|
|
84
83
|
minute: '2-digit',
|
|
85
|
-
timeZone: resolveDateZone(timezoneID, false),
|
|
86
|
-
calendar: 'gregory',
|
|
87
84
|
};
|
|
88
|
-
return
|
|
85
|
+
return formatCalendarInstant(
|
|
86
|
+
calendar,
|
|
87
|
+
new Date(unixSeconds * 1000),
|
|
88
|
+
options,
|
|
89
|
+
locale,
|
|
90
|
+
resolveDateZone(timezoneID, isDateOnly),
|
|
91
|
+
);
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
function formatRelativeDate(value: string): string {
|
|
@@ -100,6 +103,11 @@ function formatDateRange(
|
|
|
100
103
|
return t('@astryx.powersearch.valueEditor.dateRange');
|
|
101
104
|
}
|
|
102
105
|
|
|
106
|
+
/**
|
|
107
|
+
* The display text of a filter value. A `date_absolute` value is written in
|
|
108
|
+
* `calendar`, which defaults to Gregorian; PowerSearch passes the calendar that
|
|
109
|
+
* its provider resolves.
|
|
110
|
+
*/
|
|
103
111
|
export function formatFilterValue(
|
|
104
112
|
_config: InternalConfig,
|
|
105
113
|
operatorValue: OperatorValue,
|
|
@@ -108,6 +116,7 @@ export function formatFilterValue(
|
|
|
108
116
|
t: TranslatorFn,
|
|
109
117
|
locale: Locale,
|
|
110
118
|
timezoneID?: string,
|
|
119
|
+
calendar: CalendarSystem = 'gregory',
|
|
111
120
|
): string {
|
|
112
121
|
switch (filterValue.type) {
|
|
113
122
|
case 'empty':
|
|
@@ -210,6 +219,7 @@ export function formatFilterValue(
|
|
|
210
219
|
timezoneID,
|
|
211
220
|
operatorValue.type !== 'date_absolute' ||
|
|
212
221
|
operatorValue.isDateOnly !== false,
|
|
222
|
+
calendar,
|
|
213
223
|
),
|
|
214
224
|
maxLength,
|
|
215
225
|
);
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @fileoverview The text a PowerSearch filter token shows for a value.
|
|
5
5
|
*
|
|
6
|
-
* @input `OperatorValue`, `FilterValue`, a width budget, and the
|
|
6
|
+
* @input `OperatorValue`, `FilterValue`, a width budget, the locale, and the
|
|
7
|
+
* calendar.
|
|
7
8
|
* @output `formatTokenValueText` — one string, or null for an empty value.
|
|
8
9
|
* @position Shared by the token itself (`PowerSearch.tsx`) and the sheet
|
|
9
10
|
* presentation's Filters rows and removal announcement
|
|
@@ -13,6 +14,7 @@
|
|
|
13
14
|
|
|
14
15
|
import type {OperatorValue, FilterValue, EnumItem} from './types';
|
|
15
16
|
import type {Locale, TranslatorFn} from '../i18n';
|
|
17
|
+
import type {CalendarSystem} from '../utils/calendarSystem';
|
|
16
18
|
import {truncateCharacters} from '../utils/characters';
|
|
17
19
|
import {formatDateAbsolute, formatSharedNumber} from './formatFilterValue';
|
|
18
20
|
import {registerEnglishFallback} from '../i18n/englishFallback';
|
|
@@ -103,6 +105,8 @@ function formatListText(
|
|
|
103
105
|
* the sheet presentation's Filters rows and its removal announcement — can
|
|
104
106
|
* use the same words and the same zone handling. `maxLength` is the token's
|
|
105
107
|
* width budget; pass `Number.MAX_SAFE_INTEGER` for the untruncated text.
|
|
108
|
+
* A `date_absolute` value is written in `calendar`, the calendar that the
|
|
109
|
+
* provider resolves.
|
|
106
110
|
* With `t`, the list, date-range and nested summaries resolve through the
|
|
107
111
|
* catalog (`@astryx.powersearch.valueEditor.*`); without it they are the
|
|
108
112
|
* token's own literals. With `formatList` (the provider's list formatter),
|
|
@@ -114,6 +118,7 @@ export function formatTokenValueText(
|
|
|
114
118
|
filterValue: FilterValue,
|
|
115
119
|
maxLength: number,
|
|
116
120
|
locale: Locale,
|
|
121
|
+
calendar: CalendarSystem,
|
|
117
122
|
t?: TranslatorFn,
|
|
118
123
|
formatList?: ListFormatFn,
|
|
119
124
|
timezoneID?: string,
|
|
@@ -182,6 +187,7 @@ export function formatTokenValueText(
|
|
|
182
187
|
timezoneID,
|
|
183
188
|
operatorValue.type !== 'date_absolute' ||
|
|
184
189
|
operatorValue.isDateOnly !== false,
|
|
190
|
+
calendar,
|
|
185
191
|
),
|
|
186
192
|
maxLength,
|
|
187
193
|
);
|
|
@@ -8,7 +8,7 @@ export const docs = {
|
|
|
8
8
|
displayName: 'Radio List Item',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
10
|
description:
|
|
11
|
-
'Individual radio item with label, description, and content slots.',
|
|
11
|
+
'Individual radio item with label, description, and content slots. Under a coarse pointer an enabled option’s target grows toward 44 px through an invisible hit area. It never shrinks below the row and stops at half the gap to a closer neighbour; the row keeps its size. That hit area is the row’s `::after`, so decorate a row with a child.',
|
|
12
12
|
// RadioListItem requires RadioList context; wrap it so the preview doesn't throw.
|
|
13
13
|
playground: {
|
|
14
14
|
defaults: {value: 'option-1', label: 'Option'},
|
|
@@ -97,7 +97,8 @@ export const docsZh = {
|
|
|
97
97
|
name: 'RadioListItem',
|
|
98
98
|
isHiddenFromOverview: true,
|
|
99
99
|
displayName: 'Radio List Item',
|
|
100
|
-
description:
|
|
100
|
+
description:
|
|
101
|
+
'单个单选选项,包含标签、描述和内容插槽。在粗指针(触摸)下,已启用选项的目标通过不可见的点击区域向 44 px 扩展。它不小于所在行,与相邻控件较近时止于间距的一半;行尺寸不变。该点击区域是行的 `::after`,因此请用子元素装饰行。',
|
|
101
102
|
props: [
|
|
102
103
|
{
|
|
103
104
|
name: 'label',
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* - /packages/cli/assets/templates/blocks/components/RadioList/ (showcase blocks)
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import React, {use, useId, useRef, type ReactNode} from 'react';
|
|
21
|
+
import React, {use, useCallback, useId, useRef, type ReactNode} from 'react';
|
|
22
22
|
import * as stylex from '@stylexjs/stylex';
|
|
23
23
|
import type {StyleXStyles} from '@stylexjs/stylex';
|
|
24
24
|
import type {BaseProps} from '../BaseProps';
|
|
@@ -32,9 +32,13 @@ import {rtlStyles} from '../utils/rtlStyles';
|
|
|
32
32
|
import {indicatorScope} from '../Indicator/indicator.markers.stylex';
|
|
33
33
|
import {useIndicatorFocusRing} from '../hooks/useIndicatorFocusRing';
|
|
34
34
|
import {usePressFeedback} from '../hooks/usePressFeedback';
|
|
35
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
36
|
+
import {watchHitArea, writeHitInsets} from '../utils/hitArea';
|
|
37
|
+
import {touchHitAreaStyles} from '../utils/touchHitArea.stylex';
|
|
35
38
|
import {useIndicator} from '../Indicator/useIndicator';
|
|
36
39
|
import {Item, type ItemAlign} from '../Item/Item';
|
|
37
40
|
import {themeProps} from '../utils/themeProps';
|
|
41
|
+
import {rowPressLayerStyles} from '../privateAttributes/press.stylex';
|
|
38
42
|
|
|
39
43
|
// The touch press's paint, declared by the shared overlay styles on the
|
|
40
44
|
// element the controller writes to (`pressedAlpha`) at the press's strength,
|
|
@@ -147,11 +151,6 @@ const rowStyles = stylex.create({
|
|
|
147
151
|
// Suppress Item's interactive hover/press background so the resting and
|
|
148
152
|
// hovered row look identical by default (a theme can restyle either).
|
|
149
153
|
backgroundColor: 'transparent',
|
|
150
|
-
// ...and the touch press's overlay image, for the same reason: under a
|
|
151
|
-
// finger only the radio circle paints, as under a mouse. The press's
|
|
152
|
-
// strength still lands on the row, which is where the layer over the
|
|
153
|
-
// circle reads it.
|
|
154
|
-
backgroundImage: 'none',
|
|
155
154
|
},
|
|
156
155
|
// The mouse press (a finger's lives on `data-astryx-press`): the row is
|
|
157
156
|
// pressed, but not through a nested link or button, which keep their own
|
|
@@ -309,6 +308,21 @@ export function RadioListItem({
|
|
|
309
308
|
// `<label htmlFor>` would double-fire under delegation.
|
|
310
309
|
const radioRef = useRef<HTMLInputElement>(null);
|
|
311
310
|
|
|
311
|
+
// Under a coarse pointer an option's row grows toward 44 px through an
|
|
312
|
+
// invisible band, and the row keeps its size. A tap on the band lands on
|
|
313
|
+
// the row, which hands it to the radio. The watch lives as long as the row
|
|
314
|
+
// is attached: the ref's cleanup stops it.
|
|
315
|
+
const watchRowHitArea = useCallback(
|
|
316
|
+
(row: HTMLDivElement | null) => {
|
|
317
|
+
if (row == null || isDisabled) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
return watchHitArea(row, insets => writeHitInsets(row, insets));
|
|
321
|
+
},
|
|
322
|
+
[isDisabled],
|
|
323
|
+
);
|
|
324
|
+
const mergedRowRef = useMergedRefs(ref, watchRowHitArea);
|
|
325
|
+
|
|
312
326
|
const radioCircle = (
|
|
313
327
|
<div
|
|
314
328
|
{...stylex.props(
|
|
@@ -391,7 +405,7 @@ export function RadioListItem({
|
|
|
391
405
|
|
|
392
406
|
return (
|
|
393
407
|
<Item
|
|
394
|
-
ref={
|
|
408
|
+
ref={mergedRowRef}
|
|
395
409
|
{...(isDisabled ? undefined : pressable)}
|
|
396
410
|
startContent={mediaContent}
|
|
397
411
|
// Delegate row-surface clicks (label text, description, and the empty
|
|
@@ -414,12 +428,16 @@ export function RadioListItem({
|
|
|
414
428
|
// the painting row element (Item), the same element that carries the
|
|
415
429
|
// theme target, so a theme's hover styling stays in step with the tint.
|
|
416
430
|
!isDisabled && indicatorScope,
|
|
431
|
+
// The row keeps no press paint of its own: the circle paints, and
|
|
432
|
+
// reads the strength whose release the row keeps.
|
|
433
|
+
rowPressLayerStyles.cellWithoutLayer,
|
|
417
434
|
// Restore the bare default look: zero Item's padding/radius and its
|
|
418
435
|
// interactive hover/press background. Applied after Item's own base
|
|
419
436
|
// styles so it wins within the base layer; a `radio-list-item` theme
|
|
420
437
|
// still overrides it from the higher `astryx-theme` layer.
|
|
421
438
|
rowStyles.root,
|
|
422
439
|
!isDisabled && rowStyles.press,
|
|
440
|
+
!isDisabled && touchHitAreaStyles.layer,
|
|
423
441
|
xstyle,
|
|
424
442
|
] as StyleXStyles
|
|
425
443
|
}
|
|
@@ -44,6 +44,7 @@ import type {StyleXStyles} from '@stylexjs/stylex';
|
|
|
44
44
|
import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
|
|
45
45
|
import type {Elevation, SizeValue, SpacingStep} from '../utils/types';
|
|
46
46
|
import {isImeKeyEvent, mergeProps} from '../utils';
|
|
47
|
+
import {chainEventHandlers} from '../utils/chainEventHandlers';
|
|
47
48
|
import {Card} from '../Card/Card';
|
|
48
49
|
import type {CardVariant} from '../Card/Card';
|
|
49
50
|
import {useClickableContainer} from '../hooks/useClickableContainer';
|
|
@@ -398,6 +399,7 @@ export function SelectableCard({
|
|
|
398
399
|
onChange,
|
|
399
400
|
onClick: onClickProp,
|
|
400
401
|
onMouseUp: onMouseUpProp,
|
|
402
|
+
onPointerDown: onPointerDownProp,
|
|
401
403
|
isDisabled = false,
|
|
402
404
|
children,
|
|
403
405
|
padding,
|
|
@@ -458,7 +460,7 @@ export function SelectableCard({
|
|
|
458
460
|
[isDisabled, requestChange],
|
|
459
461
|
);
|
|
460
462
|
|
|
461
|
-
const {onClick, onMouseUp} = useClickableContainer({
|
|
463
|
+
const {onClick, onMouseUp, onPointerDown} = useClickableContainer({
|
|
462
464
|
containerRef,
|
|
463
465
|
interactiveRef,
|
|
464
466
|
onClick: handleClick,
|
|
@@ -530,6 +532,11 @@ export function SelectableCard({
|
|
|
530
532
|
}
|
|
531
533
|
onClick={!isDisabled ? composedOnClick : undefined}
|
|
532
534
|
onMouseUp={!isDisabled ? composedOnMouseUp : undefined}
|
|
535
|
+
onPointerDown={
|
|
536
|
+
!isDisabled
|
|
537
|
+
? chainEventHandlers(onPointerDown, onPointerDownProp)
|
|
538
|
+
: onPointerDownProp
|
|
539
|
+
}
|
|
533
540
|
{...props}
|
|
534
541
|
onClickCapture={
|
|
535
542
|
!isDisabled && handleLayerClickCapture
|
package/src/Spinner/Spinner.tsx
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import {useId, type ReactNode} from 'react';
|
|
20
20
|
import * as stylex from '@stylexjs/stylex';
|
|
21
|
-
import {colorVars,
|
|
21
|
+
import {colorVars, spacingVars} from '../theme/tokens.stylex';
|
|
22
22
|
import type {BaseProps} from '../BaseProps';
|
|
23
23
|
import {Text} from '../Text/Text';
|
|
24
24
|
import {mergeProps} from '../utils/mergeProps';
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
useComponentTranslator,
|
|
29
29
|
} from '../i18n/useComponentTranslator';
|
|
30
30
|
import english from '../i18n/generated-english/Spinner/Spinner.generated';
|
|
31
|
+
import {spinnerRotorStyles, syncRotationPhase} from './spinnerRotor';
|
|
31
32
|
|
|
32
33
|
registerEnglishFallback(english);
|
|
33
34
|
|
|
@@ -36,13 +37,13 @@ registerEnglishFallback(english);
|
|
|
36
37
|
// =============================================================================
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
40
|
+
* The fraction of the ring the arc covers: SPINNER_ARC_FRACTION. StyleX reads
|
|
41
|
+
* only a literal in this file, and a test pins the two together.
|
|
41
42
|
*
|
|
42
43
|
* Themeable via `--spinner-arc-fraction`, declared alongside the other public
|
|
43
44
|
* vars in `sizeStyles` below. Only the inline `strokeDasharray` attribute
|
|
44
|
-
* (the pre-stylesheet render
|
|
45
|
-
*
|
|
45
|
+
* (the pre-stylesheet render) still reads the constant directly; the CSS side
|
|
46
|
+
* composes the dash from the live var.
|
|
46
47
|
*/
|
|
47
48
|
const ARC_FRACTION = 0.375;
|
|
48
49
|
|
|
@@ -152,75 +153,6 @@ function registerSpinnerVars(): void {
|
|
|
152
153
|
// elide.
|
|
153
154
|
registerSpinnerVars();
|
|
154
155
|
|
|
155
|
-
/**
|
|
156
|
-
* Pin every ring's rotation to the document timeline's origin instead of its
|
|
157
|
-
* own start time, so spinners mounted seconds apart stay in phase.
|
|
158
|
-
*
|
|
159
|
-
* Setting `startTime` is exact where arithmetic on a clock read is not. A
|
|
160
|
-
* negative `animation-delay` computed at mount is only as good as the gap
|
|
161
|
-
* between the clock read and the frame the animation starts in. At 10x CPU
|
|
162
|
-
* throttling that gap measured 116 degrees of drift.
|
|
163
|
-
*
|
|
164
|
-
* Rotors are collected and pinned in one frame. `getAnimations()` resolves
|
|
165
|
-
* style, and `startTime` dirties it again. So pinning them one at a time makes
|
|
166
|
-
* each mount re-force what the previous one invalidated: 53 style recalcs for
|
|
167
|
-
* 38 spinners, against 19 batched.
|
|
168
|
-
*/
|
|
169
|
-
const pendingRotors = new Set<HTMLSpanElement>();
|
|
170
|
-
let flushScheduled = false;
|
|
171
|
-
|
|
172
|
-
function pinRotorsToTimelineOrigin(): void {
|
|
173
|
-
flushScheduled = false;
|
|
174
|
-
const animations: Animation[] = [];
|
|
175
|
-
for (const rotor of pendingRotors) {
|
|
176
|
-
animations.push(...rotor.getAnimations());
|
|
177
|
-
}
|
|
178
|
-
pendingRotors.clear();
|
|
179
|
-
for (const animation of animations) {
|
|
180
|
-
animation.startTime = 0;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Ref callback for the rotor: the one place a mounted ring touches the DOM.
|
|
186
|
-
*
|
|
187
|
-
* It reads nothing back — the geometry is resolved by the cascade, not in JS.
|
|
188
|
-
*/
|
|
189
|
-
function syncRotationPhase(
|
|
190
|
-
rotor: HTMLSpanElement | null,
|
|
191
|
-
): (() => void) | undefined {
|
|
192
|
-
if (rotor == null) {
|
|
193
|
-
return undefined;
|
|
194
|
-
}
|
|
195
|
-
// jsdom implements no Web Animations, and this runs in every consumer's
|
|
196
|
-
// component tests.
|
|
197
|
-
if (typeof rotor.getAnimations !== 'function') {
|
|
198
|
-
return undefined;
|
|
199
|
-
}
|
|
200
|
-
pendingRotors.add(rotor);
|
|
201
|
-
if (!flushScheduled) {
|
|
202
|
-
flushScheduled = true;
|
|
203
|
-
requestAnimationFrame(pinRotorsToTimelineOrigin);
|
|
204
|
-
}
|
|
205
|
-
return () => {
|
|
206
|
-
pendingRotors.delete(rotor);
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// =============================================================================
|
|
211
|
-
// Animation
|
|
212
|
-
// =============================================================================
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* A `transform` animation runs on the compositor, so the ring keeps turning
|
|
216
|
-
* while a script runs. A `stroke-dashoffset` animation would repaint the arc
|
|
217
|
-
* on the main thread every frame, so it would stop while a script runs.
|
|
218
|
-
*/
|
|
219
|
-
const rotation = stylex.keyframes({
|
|
220
|
-
'0%': {transform: 'rotate(0deg)'},
|
|
221
|
-
'100%': {transform: 'rotate(360deg)'},
|
|
222
|
-
});
|
|
223
|
-
|
|
224
156
|
// =============================================================================
|
|
225
157
|
// Styles
|
|
226
158
|
// =============================================================================
|
|
@@ -299,20 +231,6 @@ const styles = stylex.create({
|
|
|
299
231
|
gridArea: '1 / 1',
|
|
300
232
|
width: `var(${BOX_SIZE})`,
|
|
301
233
|
height: `var(${BOX_SIZE})`,
|
|
302
|
-
// Mobile Safari keeps a re-timed animation off the main thread only on an
|
|
303
|
-
// element with its own layer. So the rotor declares one before the start
|
|
304
|
-
// time is set (see `pinRotorsToTimelineOrigin`).
|
|
305
|
-
willChange: 'transform',
|
|
306
|
-
// Reduced motion slows the turn but never stops it: a still ring reads as
|
|
307
|
-
// broken. The status role and its name still say that work is busy.
|
|
308
|
-
animationDuration: {
|
|
309
|
-
// The loop reads the duration before a theme's tempo scales it.
|
|
310
|
-
default: `var(--_astryx-pre-tempo-duration-slow-min, ${durationVars['--duration-slow-min']})`,
|
|
311
|
-
'@media (prefers-reduced-motion: reduce)': '3s',
|
|
312
|
-
},
|
|
313
|
-
animationIterationCount: 'infinite',
|
|
314
|
-
animationName: rotation,
|
|
315
|
-
animationTimingFunction: 'linear',
|
|
316
234
|
},
|
|
317
235
|
circle: {
|
|
318
236
|
fill: 'none',
|
|
@@ -594,7 +512,7 @@ export function Spinner({
|
|
|
594
512
|
<span
|
|
595
513
|
ref={syncRotationPhase}
|
|
596
514
|
aria-hidden="true"
|
|
597
|
-
{...stylex.props(styles.rotor)}>
|
|
515
|
+
{...stylex.props(styles.rotor, spinnerRotorStyles.turn)}>
|
|
598
516
|
<svg
|
|
599
517
|
width={frameSize}
|
|
600
518
|
height={frameSize}
|
package/src/Spinner/index.ts
CHANGED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file spinnerRotor.ts
|
|
7
|
+
* @input StyleX keyframes and the slow-min duration token
|
|
8
|
+
* @output The one turning arc: SPINNER_ARC_FRACTION, spinnerRotorStyles.turn
|
|
9
|
+
* and syncRotationPhase
|
|
10
|
+
* @position Spinner's rotor, shared by Spinner and Lab's indeterminate
|
|
11
|
+
* CircularProgress (through `@astryxdesign/core/internal/spinner-rotor`), so
|
|
12
|
+
* both rings turn the same way on the compositor.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import * as stylex from '@stylexjs/stylex';
|
|
16
|
+
import {durationVars} from '../theme/tokens.stylex';
|
|
17
|
+
|
|
18
|
+
/** The fraction of the ring the arc covers: 135°. */
|
|
19
|
+
export const SPINNER_ARC_FRACTION = 0.375;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Full turns in one iteration of the rotation.
|
|
23
|
+
*
|
|
24
|
+
* Chromium wakes the main thread at each iteration boundary while the
|
|
25
|
+
* document listens for `animationiteration`. React listens for it on every
|
|
26
|
+
* root. One iteration holds 100 turns, so the wake comes once in 100 turns.
|
|
27
|
+
* Each turn is 360 degrees, so the ring looks the same.
|
|
28
|
+
*/
|
|
29
|
+
const TURNS_PER_ITERATION = 100;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A `transform` animation runs on the compositor, so the ring keeps turning
|
|
33
|
+
* while a script runs. A `stroke-dashoffset` animation would repaint the arc
|
|
34
|
+
* on the main thread every frame, so it would stop while a script runs.
|
|
35
|
+
*/
|
|
36
|
+
const rotation = stylex.keyframes({
|
|
37
|
+
'0%': {transform: 'rotate(0deg)'},
|
|
38
|
+
'100%': {transform: `rotate(${360 * TURNS_PER_ITERATION}deg)`},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const spinnerRotorStyles = stylex.create({
|
|
42
|
+
turn: {
|
|
43
|
+
// Mobile Safari keeps a re-timed animation off the main thread only on an
|
|
44
|
+
// element with its own layer. So the rotor declares one before the start
|
|
45
|
+
// time is set (see `pinRotorsToTimelineOrigin`).
|
|
46
|
+
willChange: 'transform',
|
|
47
|
+
// Reduced motion slows the turn but never stops it: a still ring reads as
|
|
48
|
+
// broken. The ring's role and name still say that work is busy.
|
|
49
|
+
animationDuration: {
|
|
50
|
+
// The loop reads the duration before a theme's tempo scales it.
|
|
51
|
+
default: `calc(var(--_astryx-pre-tempo-duration-slow-min, ${durationVars['--duration-slow-min']}) * ${TURNS_PER_ITERATION})`,
|
|
52
|
+
'@media (prefers-reduced-motion: reduce)': `calc(3s * ${TURNS_PER_ITERATION})`,
|
|
53
|
+
},
|
|
54
|
+
animationIterationCount: 'infinite',
|
|
55
|
+
animationName: rotation,
|
|
56
|
+
animationTimingFunction: 'linear',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Pin every ring's rotation to the document timeline's origin instead of its
|
|
62
|
+
* own start time, so spinners mounted seconds apart stay in phase.
|
|
63
|
+
*
|
|
64
|
+
* Setting `startTime` is exact where arithmetic on a clock read is not. A
|
|
65
|
+
* negative `animation-delay` computed at mount is only as good as the gap
|
|
66
|
+
* between the clock read and the frame the animation starts in. At 10x CPU
|
|
67
|
+
* throttling that gap measured 116 degrees of drift.
|
|
68
|
+
*
|
|
69
|
+
* Rotors are collected and pinned in one frame. `getAnimations()` resolves
|
|
70
|
+
* style, and `startTime` dirties it again. So pinning them one at a time makes
|
|
71
|
+
* each mount re-force what the previous one invalidated: 53 style recalcs for
|
|
72
|
+
* 38 spinners, against 19 batched.
|
|
73
|
+
*/
|
|
74
|
+
const pendingRotors = new Set<Element>();
|
|
75
|
+
let flushScheduled = false;
|
|
76
|
+
|
|
77
|
+
function pinRotorsToTimelineOrigin(): void {
|
|
78
|
+
flushScheduled = false;
|
|
79
|
+
const animations: Animation[] = [];
|
|
80
|
+
for (const rotor of pendingRotors) {
|
|
81
|
+
animations.push(...rotor.getAnimations());
|
|
82
|
+
}
|
|
83
|
+
pendingRotors.clear();
|
|
84
|
+
for (const animation of animations) {
|
|
85
|
+
animation.startTime = 0;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Ref callback for a rotor: the one place a mounted ring touches the DOM.
|
|
91
|
+
*
|
|
92
|
+
* It reads nothing back — the geometry is resolved by the cascade, not in JS.
|
|
93
|
+
*/
|
|
94
|
+
export function syncRotationPhase(
|
|
95
|
+
rotor: Element | null,
|
|
96
|
+
): (() => void) | undefined {
|
|
97
|
+
if (rotor == null) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
// jsdom implements no Web Animations, and this runs in every consumer's
|
|
101
|
+
// component tests.
|
|
102
|
+
if (typeof rotor.getAnimations !== 'function') {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
pendingRotors.add(rotor);
|
|
106
|
+
if (!flushScheduled) {
|
|
107
|
+
flushScheduled = true;
|
|
108
|
+
requestAnimationFrame(pinRotorsToTimelineOrigin);
|
|
109
|
+
}
|
|
110
|
+
return () => {
|
|
111
|
+
pendingRotors.delete(rotor);
|
|
112
|
+
};
|
|
113
|
+
}
|
package/src/Stack/Stack.doc.mjs
CHANGED
|
@@ -524,7 +524,7 @@ export const docs = {
|
|
|
524
524
|
name: 'isScrollable',
|
|
525
525
|
type: 'boolean',
|
|
526
526
|
description:
|
|
527
|
-
'Enables scrollable overflow (overflow: auto). StackItem already applies the flex min-height/min-width reset, so <StackItem size="fill" isScrollable> is a complete scroll region. Matches isScrollable on LayoutContent and LayoutPanel.',
|
|
527
|
+
'Enables scrollable overflow (overflow: auto). StackItem already applies the flex min-height/min-width reset, so <StackItem size="fill" isScrollable> is a complete scroll region. Matches isScrollable on LayoutContent and LayoutPanel. While its content overflows, a div or span item is a group named by aria-label, or by a translated "Content"; another element keeps its own role.',
|
|
528
528
|
default: 'false',
|
|
529
529
|
},
|
|
530
530
|
{
|
package/src/Stack/StackItem.tsx
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file StackItem.tsx
|
|
5
|
-
* @input Uses React, ElementType, stackItem utility
|
|
5
|
+
* @input Uses React, ElementType, stackItem utility, StackItemScrollRegion
|
|
6
6
|
* @output Exports StackItem polymorphic component and StackItemProps
|
|
7
|
-
* @position Layout/Stack component; uses stackItem.stylex.ts
|
|
7
|
+
* @position Layout/Stack component; uses stackItem.stylex.ts. A scrollable
|
|
8
|
+
* `div` or `span` item renders through StackItemScrollRegion, which names
|
|
9
|
+
* it while it scrolls.
|
|
8
10
|
*
|
|
9
11
|
* SYNC: When modified, update these files to stay in sync:
|
|
10
12
|
* - /packages/core/src/Stack/Stack.doc.mjs
|
|
@@ -21,6 +23,7 @@ import {
|
|
|
21
23
|
} from './stackItem.stylex';
|
|
22
24
|
import {mergeProps} from '../utils/mergeProps';
|
|
23
25
|
import {themeProps} from '../utils/themeProps';
|
|
26
|
+
import {StackItemScrollRegion} from '../hooks/StackItemScrollRegion';
|
|
24
27
|
|
|
25
28
|
const overflowStyles = stylex.create({
|
|
26
29
|
scrollable: {
|
|
@@ -53,7 +56,9 @@ export interface StackItemProps extends BaseProps<HTMLElement> {
|
|
|
53
56
|
* reset, so `<StackItem size="fill" isScrollable>` is a complete scroll
|
|
54
57
|
* region — it grows to fill the stack and scrolls its own overflow with
|
|
55
58
|
* no extra style plumbing. Matches `isScrollable` on `LayoutContent`
|
|
56
|
-
* and `LayoutPanel`.
|
|
59
|
+
* and `LayoutPanel`. While its content overflows, a `div` or `span` item
|
|
60
|
+
* is a group named by the caller's `aria-label`, or by a translated
|
|
61
|
+
* "Content". Another element keeps its own role.
|
|
57
62
|
* @default false
|
|
58
63
|
*/
|
|
59
64
|
isScrollable?: boolean;
|
|
@@ -102,18 +107,27 @@ export function StackItem({
|
|
|
102
107
|
xstyle,
|
|
103
108
|
);
|
|
104
109
|
|
|
110
|
+
const elementProps = {
|
|
111
|
+
...mergeProps(
|
|
112
|
+
themeProps('stack-item', {size}),
|
|
113
|
+
stylexProps,
|
|
114
|
+
className,
|
|
115
|
+
style,
|
|
116
|
+
),
|
|
117
|
+
...props,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
if (isScrollable && (element === 'div' || element === 'span')) {
|
|
121
|
+
return createElement(
|
|
122
|
+
StackItemScrollRegion,
|
|
123
|
+
{as: element, ref, elementProps},
|
|
124
|
+
children,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
105
128
|
return createElement(
|
|
106
129
|
element,
|
|
107
|
-
{
|
|
108
|
-
ref: ref as Ref<Element>,
|
|
109
|
-
...mergeProps(
|
|
110
|
-
themeProps('stack-item', {size}),
|
|
111
|
-
stylexProps,
|
|
112
|
-
className,
|
|
113
|
-
style,
|
|
114
|
-
),
|
|
115
|
-
...props,
|
|
116
|
-
},
|
|
130
|
+
{ref: ref as Ref<Element>, ...elementProps},
|
|
117
131
|
children,
|
|
118
132
|
);
|
|
119
133
|
}
|
package/src/Switch/Switch.tsx
CHANGED
|
@@ -62,9 +62,9 @@ import {
|
|
|
62
62
|
import english from '../i18n/generated-english/Switch/Switch.generated';
|
|
63
63
|
|
|
64
64
|
registerEnglishFallback(english);
|
|
65
|
+
import {reducedMotionFadeConsts} from '../motion/reducedMotion.stylex';
|
|
65
66
|
import {
|
|
66
67
|
interactionOverlayStyles,
|
|
67
|
-
pressConsts,
|
|
68
68
|
pressVars,
|
|
69
69
|
} from '../utils/interactionOverlay.stylex';
|
|
70
70
|
import {pressHoldsDragProps} from '../privateAttributes/pressHoldsDrag.stylex';
|
|
@@ -93,14 +93,15 @@ const PRESS_FADING = '[data-astryx-press="fading"]';
|
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
95
|
* The shared press release, for the press layers the switch fades on the
|
|
96
|
-
* compositor
|
|
97
|
-
*
|
|
96
|
+
* compositor: the theme's exit motion tokens, no longer than the Reduce
|
|
97
|
+
* Motion fade under Reduce Motion. Switch.test.tsx compares them with
|
|
98
|
+
* the overlay's.
|
|
98
99
|
* SYNC: utils/interactionOverlay.stylex.ts PRESS_RELEASE_DURATION,
|
|
99
100
|
* PRESS_RELEASE_DURATION_REDUCED and RELEASE_EASE.
|
|
100
101
|
*/
|
|
101
|
-
const PRESS_RELEASE_DURATION =
|
|
102
|
-
const PRESS_RELEASE_DURATION_REDUCED = `min(${
|
|
103
|
-
const PRESS_RELEASE_EASE = '
|
|
102
|
+
const PRESS_RELEASE_DURATION = durationVars['--duration-exit'];
|
|
103
|
+
const PRESS_RELEASE_DURATION_REDUCED = `min(${durationVars['--duration-exit']}, ${reducedMotionFadeConsts.duration})`;
|
|
104
|
+
const PRESS_RELEASE_EASE = easeVars['--ease-exit'];
|
|
104
105
|
|
|
105
106
|
// The measured hit insets (utils/hitArea), 0 until measured.
|
|
106
107
|
const HIT_TOP = 'var(--astryx-hit-inset-top, 0px)';
|
|
@@ -168,7 +168,7 @@ const sortStyles = stylex.create({
|
|
|
168
168
|
fontSize: 10,
|
|
169
169
|
// eslint-disable-next-line @astryx/no-hardcoded-styles -- no token for lineHeight:1 (tight badge)
|
|
170
170
|
lineHeight: '1',
|
|
171
|
-
color: colorVars['--color-accent'],
|
|
171
|
+
color: colorVars['--color-text-accent'],
|
|
172
172
|
},
|
|
173
173
|
});
|
|
174
174
|
|