@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
package/src/utils/hitArea.ts
CHANGED
|
@@ -24,6 +24,9 @@
|
|
|
24
24
|
// live control measures: only under a coarse primary pointer (AST-094), only on
|
|
25
25
|
// screen, and in one read pass per frame within a 4 ms budget. Until the first
|
|
26
26
|
// pass the insets are 0, so first paint never overlaps anything.
|
|
27
|
+
// The insets are lengths in the control's own box, so a pass measures in its
|
|
28
|
+
// layout px. A layer that opens from a smaller scale then keeps the insets of
|
|
29
|
+
// the size it settles at.
|
|
27
30
|
|
|
28
31
|
import {observeContent} from './sharedMutationObserver';
|
|
29
32
|
|
|
@@ -330,6 +333,95 @@ function plainRect(element: Element): HitRect {
|
|
|
330
333
|
return {left, top, right, bottom};
|
|
331
334
|
}
|
|
332
335
|
|
|
336
|
+
/** A box that the transforms around it leave at its layout size. */
|
|
337
|
+
const UNSCALED = {x: 1, y: 1} as const;
|
|
338
|
+
|
|
339
|
+
/** One axis of a box's scale on screen: its client size over its layout size. */
|
|
340
|
+
function axisScale(onScreen: number, layout: number): number {
|
|
341
|
+
if (!(layout > 0) || !(onScreen > 0)) {
|
|
342
|
+
return 1;
|
|
343
|
+
}
|
|
344
|
+
const scale = onScreen / layout;
|
|
345
|
+
// Within rounding of 1 the box is at its layout size: no change to the rects.
|
|
346
|
+
return Math.abs(scale - 1) < 1e-3 ? 1 : scale;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* How far the transforms around `element` scale its box on screen, per axis.
|
|
351
|
+
* A layer that opens from a smaller scale scales every rect inside it, while
|
|
352
|
+
* the layout box keeps the size the layer settles at. Only a scale is
|
|
353
|
+
* expected: a rotated or skewed box would read as a larger scale.
|
|
354
|
+
*/
|
|
355
|
+
function screenScale(
|
|
356
|
+
element: Element,
|
|
357
|
+
onScreen: HitRect,
|
|
358
|
+
): {x: number; y: number} {
|
|
359
|
+
// The offset size is the layout size in whole pixels, unaffected by
|
|
360
|
+
// transforms, and costs no style resolution. A box with none, such as an SVG
|
|
361
|
+
// element or a jsdom box, reads as unscaled.
|
|
362
|
+
const box = element as Partial<HTMLElement>;
|
|
363
|
+
const offsetWidth = box.offsetWidth ?? 0;
|
|
364
|
+
const offsetHeight = box.offsetHeight ?? 0;
|
|
365
|
+
if (offsetWidth === 0 || offsetHeight === 0) {
|
|
366
|
+
return UNSCALED;
|
|
367
|
+
}
|
|
368
|
+
// Within a pixel of its layout size the box reads as unscaled, which bounds
|
|
369
|
+
// the inset error at about a pixel. Only a box that a transform shrinks or
|
|
370
|
+
// grows reads its exact size from the computed style.
|
|
371
|
+
if (
|
|
372
|
+
Math.abs(onScreen.right - onScreen.left - offsetWidth) <= 1 &&
|
|
373
|
+
Math.abs(onScreen.bottom - onScreen.top - offsetHeight) <= 1
|
|
374
|
+
) {
|
|
375
|
+
return UNSCALED;
|
|
376
|
+
}
|
|
377
|
+
const style = element.ownerDocument.defaultView?.getComputedStyle(element);
|
|
378
|
+
if (style == null || !style.width.endsWith('px')) {
|
|
379
|
+
return UNSCALED;
|
|
380
|
+
}
|
|
381
|
+
const px = (value: string) => Number.parseFloat(value) || 0;
|
|
382
|
+
const isContentBox = style.boxSizing !== 'border-box';
|
|
383
|
+
const width =
|
|
384
|
+
px(style.width) +
|
|
385
|
+
(isContentBox
|
|
386
|
+
? px(style.paddingLeft) +
|
|
387
|
+
px(style.paddingRight) +
|
|
388
|
+
px(style.borderLeftWidth) +
|
|
389
|
+
px(style.borderRightWidth)
|
|
390
|
+
: 0);
|
|
391
|
+
const height =
|
|
392
|
+
px(style.height) +
|
|
393
|
+
(isContentBox
|
|
394
|
+
? px(style.paddingTop) +
|
|
395
|
+
px(style.paddingBottom) +
|
|
396
|
+
px(style.borderTopWidth) +
|
|
397
|
+
px(style.borderBottomWidth)
|
|
398
|
+
: 0);
|
|
399
|
+
return {
|
|
400
|
+
x: axisScale(onScreen.right - onScreen.left, width),
|
|
401
|
+
y: axisScale(onScreen.bottom - onScreen.top, height),
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* `rect` in the layout px of the box at `origin`: its offset from `origin`,
|
|
407
|
+
* divided by that box's scale on screen.
|
|
408
|
+
*/
|
|
409
|
+
function inLayout(
|
|
410
|
+
rect: HitRect,
|
|
411
|
+
origin: HitRect,
|
|
412
|
+
scale: {x: number; y: number},
|
|
413
|
+
): HitRect {
|
|
414
|
+
if (scale.x === 1 && scale.y === 1) {
|
|
415
|
+
return rect;
|
|
416
|
+
}
|
|
417
|
+
return {
|
|
418
|
+
left: origin.left + (rect.left - origin.left) / scale.x,
|
|
419
|
+
top: origin.top + (rect.top - origin.top) / scale.y,
|
|
420
|
+
right: origin.left + (rect.right - origin.left) / scale.x,
|
|
421
|
+
bottom: origin.top + (rect.bottom - origin.top) / scale.y,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
333
425
|
interface Candidate {
|
|
334
426
|
readonly element: Element;
|
|
335
427
|
readonly rect: HitRect;
|
|
@@ -373,14 +465,15 @@ function measureOne(
|
|
|
373
465
|
candidates: ReadonlyArray<Candidate>,
|
|
374
466
|
): {target: HitRect; insets: HitInsets; neighbours: HitRect[]} {
|
|
375
467
|
const target = plainRect(watch.element);
|
|
468
|
+
const scale = screenScale(watch.element, target);
|
|
376
469
|
// Two targets each growing up to half the minimum reach each other from a
|
|
377
470
|
// minimum apart.
|
|
378
471
|
const reach = Math.max(0, watch.minSize);
|
|
379
472
|
const band = grown(target, {
|
|
380
|
-
top: reach,
|
|
381
|
-
right: reach,
|
|
382
|
-
bottom: reach,
|
|
383
|
-
left: reach,
|
|
473
|
+
top: reach * scale.y,
|
|
474
|
+
right: reach * scale.x,
|
|
475
|
+
bottom: reach * scale.y,
|
|
476
|
+
left: reach * scale.x,
|
|
384
477
|
});
|
|
385
478
|
const neighbours = candidates
|
|
386
479
|
.filter(
|
|
@@ -393,7 +486,16 @@ function measureOne(
|
|
|
393
486
|
.map(({rect}) => rect);
|
|
394
487
|
return {
|
|
395
488
|
target,
|
|
396
|
-
insets
|
|
489
|
+
// The insets are in the control's layout px. The returned rects stay in
|
|
490
|
+
// screen px for a touch's distance checks. A neighbour maps by the
|
|
491
|
+
// control's scale, as if it is in the same layer. A neighbour outside that
|
|
492
|
+
// layer then reads farther away. A touch compares screen distances, so it
|
|
493
|
+
// still counts that neighbour.
|
|
494
|
+
insets: clampedHitInsets(
|
|
495
|
+
inLayout(target, target, scale),
|
|
496
|
+
neighbours.map(rect => inLayout(rect, target, scale)),
|
|
497
|
+
watch.minSize,
|
|
498
|
+
),
|
|
397
499
|
neighbours,
|
|
398
500
|
};
|
|
399
501
|
}
|
package/src/utils/inputStream.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* @file inputStream.ts
|
|
5
5
|
* @input A window, and subscribers to its input events (the press feedback
|
|
6
6
|
* controller, the gesture host)
|
|
7
|
-
* @output subscribeInput
|
|
7
|
+
* @output subscribeInput, and getLastPointerType: the type of the latest
|
|
8
|
+
* pointer event the stream delivered
|
|
8
9
|
* @position The one entry for document-wide input listeners in core: one
|
|
9
10
|
* native listener per event type on the window's capture phase, shared by
|
|
10
11
|
* every subscriber
|
|
@@ -22,18 +23,21 @@
|
|
|
22
23
|
// `blur` or `focus`. A subscriber for the window's own event checks
|
|
23
24
|
// `event.target`.
|
|
24
25
|
//
|
|
25
|
-
// Subscribers run in subscription order
|
|
26
|
-
// the
|
|
26
|
+
// Subscribers run in subscription order, after the ones subscribed `first`.
|
|
27
|
+
// A first subscriber that returns `true` ends the dispatch: no later
|
|
28
|
+
// subscriber hears the event. One that throws is reported, and the rest still
|
|
29
|
+
// run.
|
|
27
30
|
//
|
|
28
31
|
// A type's native listener is passive, so it blocks no scroll. It is
|
|
29
32
|
// non-passive only while a subscriber that cancels the event
|
|
30
33
|
// (`{cancels: true}`) is subscribed. With no subscriber left, it is removed.
|
|
31
34
|
|
|
32
|
-
type InputListener = (event: Event) =>
|
|
35
|
+
type InputListener = (event: Event) => unknown;
|
|
33
36
|
|
|
34
37
|
interface Subscriber {
|
|
35
38
|
readonly listener: InputListener;
|
|
36
39
|
readonly cancels: boolean;
|
|
40
|
+
readonly isFirst: boolean;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
interface Channel {
|
|
@@ -50,12 +54,30 @@ export interface InputSubscriptionOptions {
|
|
|
50
54
|
* @default false
|
|
51
55
|
*/
|
|
52
56
|
readonly cancels?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The subscriber runs before every subscriber that is not first. When it
|
|
59
|
+
* returns `true`, no later subscriber hears the event.
|
|
60
|
+
* @default false
|
|
61
|
+
*/
|
|
62
|
+
readonly first?: boolean;
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
/** The events a window's capture phase sees: its own, and the document's. */
|
|
56
66
|
export type InputEventMap = WindowEventMap & DocumentEventMap;
|
|
57
67
|
|
|
58
68
|
const streams = new WeakMap<Window, Map<string, Channel>>();
|
|
69
|
+
/** The type of the latest pointer event each window's stream delivered. */
|
|
70
|
+
const lastPointerTypes = new WeakMap<Window, string>();
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The type of the latest pointer event `view`'s stream delivered: `mouse`,
|
|
74
|
+
* `pen` or `touch`, or `null` before any. The stream hears a pointer event
|
|
75
|
+
* type only while a subscriber listens to it, as press feedback does on any
|
|
76
|
+
* page with a pressable. Reading it adds no listener.
|
|
77
|
+
*/
|
|
78
|
+
export function getLastPointerType(view: Window): string | null {
|
|
79
|
+
return lastPointerTypes.get(view) ?? null;
|
|
80
|
+
}
|
|
59
81
|
|
|
60
82
|
/**
|
|
61
83
|
* Listen to `type` on `view`'s capture phase through its shared native
|
|
@@ -64,8 +86,8 @@ const streams = new WeakMap<Window, Map<string, Channel>>();
|
|
|
64
86
|
export function subscribeInput<K extends keyof InputEventMap>(
|
|
65
87
|
view: Window,
|
|
66
88
|
type: K,
|
|
67
|
-
listener: (event: InputEventMap[K]) =>
|
|
68
|
-
{cancels = false}: InputSubscriptionOptions = {},
|
|
89
|
+
listener: (event: InputEventMap[K]) => unknown,
|
|
90
|
+
{cancels = false, first = false}: InputSubscriptionOptions = {},
|
|
69
91
|
): () => void {
|
|
70
92
|
let channels = streams.get(view);
|
|
71
93
|
if (channels == null) {
|
|
@@ -80,8 +102,16 @@ export function subscribeInput<K extends keyof InputEventMap>(
|
|
|
80
102
|
const subscriber: Subscriber = {
|
|
81
103
|
listener: listener as InputListener,
|
|
82
104
|
cancels,
|
|
105
|
+
isFirst: first,
|
|
83
106
|
};
|
|
84
|
-
|
|
107
|
+
const firstLater = first
|
|
108
|
+
? channel.subscribers.findIndex(other => !other.isFirst)
|
|
109
|
+
: -1;
|
|
110
|
+
if (firstLater === -1) {
|
|
111
|
+
channel.subscribers.push(subscriber);
|
|
112
|
+
} else {
|
|
113
|
+
channel.subscribers.splice(firstLater, 0, subscriber);
|
|
114
|
+
}
|
|
85
115
|
register(view, type, channel);
|
|
86
116
|
let isSubscribed = true;
|
|
87
117
|
return () => {
|
|
@@ -124,12 +154,17 @@ function register(view: Window, type: string, channel: Channel): void {
|
|
|
124
154
|
if (wanted == null) {
|
|
125
155
|
return;
|
|
126
156
|
}
|
|
127
|
-
const listener: InputListener = event => dispatch(channel, event);
|
|
157
|
+
const listener: InputListener = event => dispatch(view, channel, event);
|
|
128
158
|
view.addEventListener(type, listener, {capture: true, passive: !wanted});
|
|
129
159
|
channel.native = {listener, cancels: wanted};
|
|
130
160
|
}
|
|
131
161
|
|
|
132
|
-
function dispatch(channel: Channel, event: Event): void {
|
|
162
|
+
function dispatch(view: Window, channel: Channel, event: Event): void {
|
|
163
|
+
// Recorded before any subscriber runs, so each reads the pointer at hand.
|
|
164
|
+
const {pointerType} = event as Partial<PointerEvent>;
|
|
165
|
+
if (typeof pointerType === 'string' && pointerType !== '') {
|
|
166
|
+
lastPointerTypes.set(view, pointerType);
|
|
167
|
+
}
|
|
133
168
|
// A subscriber may subscribe or unsubscribe while the event runs; the
|
|
134
169
|
// event goes to those subscribed when it arrived.
|
|
135
170
|
for (const subscriber of [...channel.subscribers]) {
|
|
@@ -137,7 +172,9 @@ function dispatch(channel: Channel, event: Event): void {
|
|
|
137
172
|
continue;
|
|
138
173
|
}
|
|
139
174
|
try {
|
|
140
|
-
subscriber.listener(event)
|
|
175
|
+
if (subscriber.listener(event) === true && subscriber.isFirst) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
141
178
|
} catch (error) {
|
|
142
179
|
report(error);
|
|
143
180
|
}
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* @input StyleX and the semantic interaction-overlay color tokens
|
|
10
10
|
* @output Reusable background-color and background-image state styles, the
|
|
11
11
|
* touch press's registered strength variable (`pressVars`) and its clocks
|
|
12
|
-
* (`pressConsts`)
|
|
12
|
+
* (`pressConsts`). The list row's compositor press layer and its clocks
|
|
13
|
+
* are internal (privateAttributes/press.stylex.ts, utils/rowPressLayer.stylex.ts)
|
|
13
14
|
* @position Internal styling utility for interactive core surfaces
|
|
14
15
|
*
|
|
15
16
|
* SYNC: When modified, update pressFeedback.ts, pressGesture.ts (the fade
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
// background image, so a composer's color transition cannot fade the onset
|
|
42
43
|
// in. `on` sets the strength to 1 on the first frame. `fading` animates it
|
|
43
44
|
// from 1 to 0, not to the hover strength, because a finger has no hover. The
|
|
44
|
-
// theme's motion
|
|
45
|
+
// release plays the theme's exit motion tokens, which follow its tempo.
|
|
45
46
|
//
|
|
46
47
|
// The release is an animation, not a transition. Composers own their
|
|
47
48
|
// `transition-*` longhands, and StyleX is last-wins per property. A
|
|
@@ -54,7 +55,8 @@
|
|
|
54
55
|
// `animation-*` on the element that composes them. The touch arms own both.
|
|
55
56
|
|
|
56
57
|
import * as stylex from '@stylexjs/stylex';
|
|
57
|
-
import {
|
|
58
|
+
import {reducedMotionFadeConsts} from '../motion/reducedMotion.stylex';
|
|
59
|
+
import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
|
|
58
60
|
|
|
59
61
|
/**
|
|
60
62
|
* The touch press's strength on the surface the controller painted, 0 to 1.
|
|
@@ -72,26 +74,22 @@ export const pressVars = stylex.defineVars({
|
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
/**
|
|
75
|
-
* The touch press's
|
|
76
|
-
*
|
|
77
|
-
* `defineConsts`, so the one number is inlined here at build time and is the
|
|
78
|
-
* controller's constant at run time (`PRESS_FADE_MS` in pressGesture.ts):
|
|
79
|
-
* the release animation and the controller's clock cannot drift apart. When
|
|
80
|
-
* that clock runs out, the controller waits for a release animation that a
|
|
81
|
-
* busy main thread started late, then removes the attribute.
|
|
77
|
+
* The touch press's measured release clock, kept as a reference value. Press
|
|
78
|
+
* releases now play the theme's `--duration-exit`.
|
|
82
79
|
*/
|
|
83
80
|
export const pressConsts = stylex.defineConsts({
|
|
84
|
-
/**
|
|
81
|
+
/** UIKit's deselect clock, in ms: the measured reference value. */
|
|
85
82
|
releaseMs: 200,
|
|
86
83
|
});
|
|
87
84
|
|
|
88
85
|
/**
|
|
89
|
-
* The release's clock
|
|
90
|
-
*
|
|
86
|
+
* The release's clock: the theme's exit duration. The token already
|
|
87
|
+
* follows the theme's tempo. The controller's timer reads the
|
|
88
|
+
* same property.
|
|
91
89
|
*/
|
|
92
|
-
const PRESS_RELEASE_DURATION =
|
|
93
|
-
/** The same clock under Reduce Motion
|
|
94
|
-
const PRESS_RELEASE_DURATION_REDUCED = `min(${
|
|
90
|
+
const PRESS_RELEASE_DURATION = durationVars['--duration-exit'];
|
|
91
|
+
/** The same clock under Reduce Motion, no longer than the Reduce Motion fade. */
|
|
92
|
+
const PRESS_RELEASE_DURATION_REDUCED = `min(${durationVars['--duration-exit']}, ${reducedMotionFadeConsts.duration})`;
|
|
95
93
|
|
|
96
94
|
const ENABLED = ':where(:not(:disabled,[aria-disabled="true"]))';
|
|
97
95
|
const HOVER_HOVER = '@media (hover: hover)';
|
|
@@ -144,13 +142,12 @@ const pressRelease = stylex.keyframes({
|
|
|
144
142
|
});
|
|
145
143
|
|
|
146
144
|
/**
|
|
147
|
-
* The release's curve:
|
|
148
|
-
* (
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* would read as half its clock.
|
|
145
|
+
* The release's curve: the theme's exit easing. The list row's layer
|
|
146
|
+
* (privateAttributes/press.stylex.ts) and Switch's press layers use the same
|
|
147
|
+
* token; interactionOverlay.cell.test.ts and Switch.test.tsx fail if they
|
|
148
|
+
* differ.
|
|
152
149
|
*/
|
|
153
|
-
const RELEASE_EASE = '
|
|
150
|
+
const RELEASE_EASE = easeVars['--ease-exit'];
|
|
154
151
|
|
|
155
152
|
/**
|
|
156
153
|
* The touch press's strength and its release, on the element the controller
|
package/src/utils/plainDate.ts
CHANGED
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import type {ISODateString, PlainDate} from './dateTypes';
|
|
11
11
|
import type {Locale} from '../i18n/types';
|
|
12
|
+
import {
|
|
13
|
+
formatCalendarDate,
|
|
14
|
+
isCalendarSystem,
|
|
15
|
+
type CalendarSystem,
|
|
16
|
+
} from './calendarSystem';
|
|
12
17
|
import {firstCharacter} from './characters';
|
|
13
18
|
import {standaloneMonthCapitalLanguages} from './standaloneMonthCapitals.generated';
|
|
14
19
|
|
|
@@ -374,8 +379,13 @@ export const DATE_FORMAT_MONTH_YEAR: Intl.DateTimeFormatOptions = {
|
|
|
374
379
|
export function plainDateFormatStandaloneMonthYear(
|
|
375
380
|
pd: PlainDate,
|
|
376
381
|
locale: Locale,
|
|
382
|
+
calendar: Intl.DateTimeFormatOptions['calendar'] = 'gregory',
|
|
377
383
|
): string {
|
|
378
|
-
const label = plainDateFormat(
|
|
384
|
+
const label = plainDateFormat(
|
|
385
|
+
pd,
|
|
386
|
+
{...DATE_FORMAT_MONTH_YEAR, calendar},
|
|
387
|
+
locale,
|
|
388
|
+
);
|
|
379
389
|
let language: string;
|
|
380
390
|
try {
|
|
381
391
|
language = new Intl.Locale(locale).language;
|
|
@@ -450,35 +460,63 @@ export const DATE_FORMAT_SHORT_WITH_YEAR: Intl.DateTimeFormatOptions = {
|
|
|
450
460
|
* when `options.calendar` is omitted. The explicit option remains supported for
|
|
451
461
|
* compatibility with the public `Intl.DateTimeFormatOptions` signature; it is a
|
|
452
462
|
* display-only escape hatch and does not change PlainDate arithmetic, parsing,
|
|
453
|
-
* serialization, or any Astryx component's calendar semantics.
|
|
463
|
+
* serialization, or any Astryx component's calendar semantics. Another
|
|
464
|
+
* calendar names the month and day that Calendar shows in it.
|
|
454
465
|
*/
|
|
455
466
|
export function plainDateFormat(
|
|
456
467
|
pd: PlainDate,
|
|
457
468
|
options: Intl.DateTimeFormatOptions,
|
|
458
469
|
locale: Locale = 'en',
|
|
459
470
|
): string {
|
|
471
|
+
const calendar = options.calendar ?? 'gregory';
|
|
472
|
+
if (calendar !== 'gregory' && isCalendarSystem(calendar)) {
|
|
473
|
+
return formatCalendarDate(calendar, pd, options, locale);
|
|
474
|
+
}
|
|
475
|
+
const [format, date] = plainDateFormatInput(pd, options, locale);
|
|
476
|
+
return format.format(date);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* The parts of `plainDateFormat`'s output, from the same formatter and date.
|
|
481
|
+
* Internal: not re-exported from `utils/index.ts`.
|
|
482
|
+
*/
|
|
483
|
+
export function plainDateFormatToParts(
|
|
484
|
+
pd: PlainDate,
|
|
485
|
+
options: Intl.DateTimeFormatOptions,
|
|
486
|
+
locale: Locale,
|
|
487
|
+
): Intl.DateTimeFormatPart[] {
|
|
488
|
+
const [format, date] = plainDateFormatInput(pd, options, locale);
|
|
489
|
+
return format.formatToParts(date);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function plainDateFormatInput(
|
|
493
|
+
pd: PlainDate,
|
|
494
|
+
options: Intl.DateTimeFormatOptions,
|
|
495
|
+
locale: Locale,
|
|
496
|
+
): [Intl.DateTimeFormat, Date | number] {
|
|
460
497
|
const calendar = options.calendar ?? 'gregory';
|
|
461
498
|
if (options.timeZone != null) {
|
|
462
|
-
return
|
|
499
|
+
return [
|
|
500
|
+
dateTimeFormatFor(locale, {...options, calendar}),
|
|
463
501
|
plainDateToDate(pd),
|
|
464
|
-
|
|
502
|
+
];
|
|
465
503
|
}
|
|
466
504
|
if (TIME_OF_DAY_FIELDS.some(field => options[field] != null)) {
|
|
467
505
|
// A zone name or a time of day reads local midnight in the zone current
|
|
468
506
|
// at the call. A cached formatter would keep the zone it was built in,
|
|
469
507
|
// so this one is built for the call.
|
|
470
|
-
return
|
|
508
|
+
return [
|
|
509
|
+
new Intl.DateTimeFormat(locale, {...options, calendar}),
|
|
471
510
|
plainDateToDate(pd),
|
|
472
|
-
|
|
511
|
+
];
|
|
473
512
|
}
|
|
474
513
|
// Date fields alone: UTC midnight formatted in UTC, so neither the cached
|
|
475
514
|
// formatter nor the date depends on the host's zone, which can change while
|
|
476
515
|
// a page is open.
|
|
477
|
-
return
|
|
478
|
-
...options,
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
}).format(utcTime(pd.year, pd.month - 1, pd.day));
|
|
516
|
+
return [
|
|
517
|
+
dateTimeFormatFor(locale, {...options, calendar, timeZone: 'UTC'}),
|
|
518
|
+
utcTime(pd.year, pd.month - 1, pd.day),
|
|
519
|
+
];
|
|
482
520
|
}
|
|
483
521
|
|
|
484
522
|
/** Options that print a time of day or a zone, which a PlainDate lacks. */
|
|
@@ -518,6 +556,20 @@ export function dateTimeFormatFor(
|
|
|
518
556
|
return format;
|
|
519
557
|
}
|
|
520
558
|
|
|
559
|
+
/**
|
|
560
|
+
* @internal `dateTimeFormatFor`, except that without `options.timeZone` it
|
|
561
|
+
* builds a formatter for the call. A cached formatter keeps the host zone it
|
|
562
|
+
* was built in.
|
|
563
|
+
*/
|
|
564
|
+
export function dateTimeFormatAtCall(
|
|
565
|
+
locale: Locale,
|
|
566
|
+
options: Intl.DateTimeFormatOptions,
|
|
567
|
+
): Intl.DateTimeFormat {
|
|
568
|
+
return options.timeZone === undefined
|
|
569
|
+
? new Intl.DateTimeFormat(locale, options)
|
|
570
|
+
: dateTimeFormatFor(locale, options);
|
|
571
|
+
}
|
|
572
|
+
|
|
521
573
|
/**
|
|
522
574
|
* The locale's name for the "week of year" date field ("week", "Woche", "週"),
|
|
523
575
|
* from CLDR through `Intl.DisplayNames`. Calendar names its week-number
|
|
@@ -543,23 +595,29 @@ export function plainDateWeekFieldName(locale: Locale = 'en'): string {
|
|
|
543
595
|
return 'week';
|
|
544
596
|
}
|
|
545
597
|
|
|
546
|
-
const dayNumberFormats = new Map<
|
|
598
|
+
const dayNumberFormats = new Map<string, Intl.NumberFormat>();
|
|
547
599
|
|
|
548
600
|
/**
|
|
549
601
|
* A day of the month or a week number in the locale's own digits: `15` in
|
|
550
|
-
* English, `۱۵` in Persian, `١٥` in Egyptian Arabic.
|
|
551
|
-
*
|
|
552
|
-
*
|
|
602
|
+
* English, `۱۵` in Persian, `١٥` in Egyptian Arabic. A `numberingSystem`
|
|
603
|
+
* replaces the locale's digits. Only the digits change. The number stays the
|
|
604
|
+
* value that it is given, so no calendar applies, and no grouping separator or
|
|
605
|
+
* unit word is added.
|
|
553
606
|
* Internal: not re-exported from `utils/index.ts`.
|
|
554
607
|
*/
|
|
555
608
|
export function plainDateFormatDayNumber(
|
|
556
609
|
value: number,
|
|
557
610
|
locale: Locale,
|
|
611
|
+
numberingSystem?: string,
|
|
558
612
|
): string {
|
|
559
|
-
|
|
613
|
+
const key = `${locale}|${numberingSystem ?? ''}`;
|
|
614
|
+
let format = dayNumberFormats.get(key);
|
|
560
615
|
if (format == null) {
|
|
561
|
-
format = new Intl.NumberFormat(locale, {
|
|
562
|
-
|
|
616
|
+
format = new Intl.NumberFormat(locale, {
|
|
617
|
+
useGrouping: false,
|
|
618
|
+
numberingSystem,
|
|
619
|
+
});
|
|
620
|
+
dayNumberFormats.set(key, format);
|
|
563
621
|
}
|
|
564
622
|
return format.format(value);
|
|
565
623
|
}
|
|
@@ -605,14 +663,21 @@ export const SHARED_DATE_FORMAT_OPTIONS: Record<
|
|
|
605
663
|
* members. The shared entry point DateInput uses for the named-format path;
|
|
606
664
|
* Timestamp maps the same members onto {@link SHARED_DATE_FORMAT_OPTIONS} in
|
|
607
665
|
* its own `formatTimestamp` switch (its input is a `Date`, not a `PlainDate`).
|
|
666
|
+
* The locale-aware members write the date in `calendar`, which defaults to
|
|
667
|
+
* Gregorian. `system_date` stays the Gregorian ISO date in every calendar.
|
|
608
668
|
*/
|
|
609
669
|
export function formatSharedDate(
|
|
610
670
|
pd: PlainDate,
|
|
611
671
|
format: SharedDateFormat,
|
|
612
672
|
locale: Locale = 'en',
|
|
673
|
+
calendar: CalendarSystem = 'gregory',
|
|
613
674
|
): string {
|
|
614
675
|
if (format === 'system_date') {
|
|
615
676
|
return plainDateToISO(pd);
|
|
616
677
|
}
|
|
617
|
-
return plainDateFormat(
|
|
678
|
+
return plainDateFormat(
|
|
679
|
+
pd,
|
|
680
|
+
{...SHARED_DATE_FORMAT_OPTIONS[format], calendar},
|
|
681
|
+
locale,
|
|
682
|
+
);
|
|
618
683
|
}
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file pressFeedback.ts
|
|
5
5
|
* @input The press state machine (pressGesture.ts), the menu-press and
|
|
6
|
-
* press-group markers and the document's pointer, keyboard, scroll and
|
|
6
|
+
* press-group markers, the scroll-view test (scrollView.ts) and the document's pointer, keyboard, scroll and
|
|
7
7
|
* visibility events
|
|
8
8
|
* @output PRESSABLE_ATTRIBUTE, PRESSED_ATTRIBUTE, pressableProps,
|
|
9
|
-
* pressFadeMs and
|
|
9
|
+
* pressFadeMs, installPressFeedback and cancelPress
|
|
10
10
|
* @position The DOM half of the touch press model. usePressFeedback installs
|
|
11
11
|
* it, and the CSS arms live in interactionOverlay.stylex.ts.
|
|
12
12
|
*
|
|
@@ -23,9 +23,13 @@
|
|
|
23
23
|
// Where the primary pointer is fine, the controller ignores the mouse and the
|
|
24
24
|
// keyboard, and CSS `:active` keeps their press. Under a coarse primary
|
|
25
25
|
// pointer the CSS drops `:active`, so the controller paints every press. A
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
26
|
+
// mouse, trackpad or Space press paints at once. The controller reads the
|
|
27
|
+
// same query as the stylesheet, so they agree.
|
|
28
|
+
//
|
|
29
|
+
// A finger waits only inside a scroller. Outside one, a surface highlights in
|
|
30
|
+
// the frame the finger lands, as a UIControl does. Inside one, it waits the
|
|
31
|
+
// content-touch delay, because the touch can become a scroll. Rows follow the
|
|
32
|
+
// same rule.
|
|
29
33
|
//
|
|
30
34
|
// A surface's hold does nothing, so it keeps the browser's long-press text
|
|
31
35
|
// selection (AST-094). Only an element whose hold does something suppresses
|
|
@@ -43,7 +47,10 @@ import {
|
|
|
43
47
|
pressGestureStep,
|
|
44
48
|
} from './pressGesture';
|
|
45
49
|
import {isCoarsePointer, watchCoarsePointer} from './coarsePointer';
|
|
50
|
+
import {reducedMotionFadeConsts} from '../motion/reducedMotion.stylex';
|
|
51
|
+
import {parseMotionRoleValue} from '../motion/roles';
|
|
46
52
|
import {subscribeInput} from './inputStream';
|
|
53
|
+
import {isInsideScrollView} from './scrollView';
|
|
47
54
|
import {TOUCH_QUERY} from './touchPresentation';
|
|
48
55
|
import {holdsPressThroughDrag} from '../privateAttributes/pressHoldsDrag.stylex';
|
|
49
56
|
import {isTrackedByGroup} from '../privateAttributes/pressGroupItem.stylex';
|
|
@@ -151,19 +158,24 @@ const TIMER_MS: Record<NonNullable<PressStep['timer']>, number> = {
|
|
|
151
158
|
|
|
152
159
|
/**
|
|
153
160
|
* The release fade's clock on `element`, read once, at the release, from the
|
|
154
|
-
*
|
|
155
|
-
*
|
|
161
|
+
* token its stylesheet reads: the theme's `--duration-exit`. Without a
|
|
162
|
+
* readable value it is the token's default. Under Reduce Motion it is no
|
|
163
|
+
* longer than the Reduce Motion fade, as in the stylesheet.
|
|
156
164
|
*/
|
|
157
165
|
export function pressFadeMs(element: Element): number {
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
166
|
+
const exit =
|
|
167
|
+
parseMotionRoleValue(
|
|
168
|
+
'duration',
|
|
169
|
+
getComputedStyle(element).getPropertyValue('--duration-exit'),
|
|
170
|
+
) ?? PRESS_FADE_MS;
|
|
163
171
|
const reduced =
|
|
164
172
|
typeof window.matchMedia === 'function' &&
|
|
165
173
|
window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
166
|
-
|
|
174
|
+
const bound = parseMotionRoleValue(
|
|
175
|
+
'duration',
|
|
176
|
+
reducedMotionFadeConsts.duration,
|
|
177
|
+
);
|
|
178
|
+
return reduced && bound != null ? Math.min(exit, bound) : exit;
|
|
167
179
|
}
|
|
168
180
|
|
|
169
181
|
/**
|
|
@@ -247,7 +259,11 @@ function paintElement(element: HTMLElement, paint: PressPaint): void {
|
|
|
247
259
|
element.removeAttribute(PRESSED_ATTRIBUTE);
|
|
248
260
|
return;
|
|
249
261
|
}
|
|
250
|
-
|
|
262
|
+
// A step that keeps the paint writes nothing, so the element sees one
|
|
263
|
+
// change per paint.
|
|
264
|
+
if (element.getAttribute(PRESSED_ATTRIBUTE) !== paint) {
|
|
265
|
+
element.setAttribute(PRESSED_ATTRIBUTE, paint);
|
|
266
|
+
}
|
|
251
267
|
}
|
|
252
268
|
|
|
253
269
|
function clearTimer(slot: Slot): void {
|
|
@@ -381,6 +397,21 @@ function finish(slot: Slot): void {
|
|
|
381
397
|
}
|
|
382
398
|
}
|
|
383
399
|
|
|
400
|
+
/**
|
|
401
|
+
* Ends the press the controller follows on `element`, and its paint, at once.
|
|
402
|
+
* A clickable container calls it when a press starts on an interactive
|
|
403
|
+
* element inside it: that press does not activate the container, so the
|
|
404
|
+
* container shows no press.
|
|
405
|
+
*/
|
|
406
|
+
export function cancelPress(element: Element): void {
|
|
407
|
+
if (finger.live?.element === element) {
|
|
408
|
+
finish(finger);
|
|
409
|
+
}
|
|
410
|
+
if (button.live?.element === element) {
|
|
411
|
+
finish(button);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
384
415
|
/** A new press on an element owns its paint: the other slot's gesture there ends. */
|
|
385
416
|
function takeOver(other: Slot, element: HTMLElement): void {
|
|
386
417
|
if (other.live?.element === element) {
|
|
@@ -521,6 +552,7 @@ function onPointerDown(event: PointerEvent): void {
|
|
|
521
552
|
kind: 'down',
|
|
522
553
|
x: event.clientX,
|
|
523
554
|
y: event.clientY,
|
|
555
|
+
delayed: isInsideScrollView(element),
|
|
524
556
|
}),
|
|
525
557
|
);
|
|
526
558
|
}
|