@astryxdesign/core 0.7.7-canary.fc68123 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +104 -0
- package/dist/AlertDialog/AlertDialog.d.ts +1 -4
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +6 -36
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +4 -23
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +1 -3
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +1 -17
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +2 -13
- package/dist/ComplexSelector/ComplexSelector.d.ts +1 -4
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +4 -14
- package/dist/ContextMenu/ContextMenu.js +2 -2
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +31 -7
- package/dist/Field/Field.js +2 -2
- package/dist/HoverCard/HoverCard.d.ts +3 -4
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +2 -27
- package/dist/HoverCard/useHoverCard.d.ts +4 -5
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +31 -17
- package/dist/Icon/Icon.d.ts +1 -5
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +2 -5
- package/dist/Layer/usePressPin.d.ts +5 -17
- package/dist/Layer/usePressPin.d.ts.map +1 -1
- package/dist/Layer/usePressPin.js +12 -62
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +0 -18
- package/dist/PowerSearch/PowerSearch.d.ts +3 -36
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +127 -433
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts +1 -32
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +6 -17
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -38
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +61 -170
- package/dist/PowerSearch/formatFilterValue.d.ts +0 -7
- package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatFilterValue.js +1 -11
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +2 -3
- package/dist/RadioList/RadioListItem.d.ts +1 -1
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +3 -5
- package/dist/Resizable/ResizeHandle.d.ts +1 -2
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +77 -99
- package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -1
- package/dist/SegmentedControl/useSegmentedSelectionMotion.js +3 -3
- package/dist/Slider/sliderTouchController.js +2 -2
- package/dist/Spinner/Spinner.d.ts +1 -1
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +58 -60
- package/dist/Switch/useSwitchTouch.js +4 -4
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +8 -29
- package/dist/TextInput/TextInput.d.ts +2 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +7 -10
- package/dist/Toast/Toast.d.ts +1 -11
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +15 -25
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +34 -94
- package/dist/Toast/types.d.ts +3 -9
- package/dist/Toast/types.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +1 -19
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +53 -34
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -2
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/astryx.css +6 -35
- package/dist/gestures/PressTracker.d.ts.map +1 -1
- package/dist/gestures/PressTracker.js +3 -4
- package/dist/hooks/actionGroupTracker.d.ts +1 -4
- package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
- package/dist/hooks/actionGroupTracker.js +3 -13
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +0 -1
- package/dist/hooks/useAttachment.d.ts +1 -1
- package/dist/hooks/useAttachment.js +1 -1
- package/dist/hooks/useInputStatusIcon.d.ts +1 -1
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
- package/dist/hooks/useInputStatusIcon.js +2 -2
- package/dist/hooks/useLongPress.d.ts +2 -6
- package/dist/hooks/useLongPress.d.ts.map +1 -1
- package/dist/hooks/useLongPress.js +15 -95
- package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
- package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +0 -6
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +0 -30
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +0 -30
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -4
- package/dist/motion/animatedLayout.d.ts.map +1 -1
- package/dist/motion/animatedLayout.js +6 -5
- package/dist/motion/animator.d.ts +14 -14
- package/dist/motion/animator.d.ts.map +1 -1
- package/dist/motion/animator.js +18 -41
- package/dist/utils/dateParser.d.ts.map +1 -1
- package/dist/utils/dateParser.js +0 -12
- package/dist/utils/focusReturn.d.ts +0 -15
- package/dist/utils/focusReturn.d.ts.map +1 -1
- package/dist/utils/focusReturn.js +0 -28
- package/dist/utils/interactionOverlay.stylex.d.ts +2 -3
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +2 -3
- package/dist/utils/pressFeedback.d.ts.map +1 -1
- package/dist/utils/pressFeedback.js +6 -19
- package/locales/en.json +0 -120
- package/locales/pseudo.json +0 -90
- package/package.json +5 -10
- package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
- package/src/AlertDialog/AlertDialog.tsx +5 -37
- package/src/BottomSheet/BottomSheetPanel.tsx +3 -37
- package/src/BottomSheet/useSheetGestures.ts +1 -3
- package/src/Button/Button.tsx +4 -26
- package/src/CheckboxInput/CheckboxInput.doc.mjs +0 -18
- package/src/CheckboxInput/CheckboxInput.tsx +9 -36
- package/src/ComplexSelector/ComplexSelector.tsx +5 -20
- package/src/ContextMenu/ContextMenu.tsx +2 -2
- package/src/Dialog/Dialog.tsx +31 -10
- package/src/Field/Field.tsx +2 -2
- package/src/HoverCard/HoverCard.doc.mjs +2 -4
- package/src/HoverCard/HoverCard.tsx +4 -35
- package/src/HoverCard/useHoverCard.doc.mjs +36 -178
- package/src/HoverCard/useHoverCard.tsx +52 -46
- package/src/Icon/Icon.doc.mjs +8 -49
- package/src/Icon/Icon.tsx +7 -15
- package/src/Layer/usePressPin.ts +15 -81
- package/src/Lightbox/Lightbox.tsx +0 -18
- package/src/PowerSearch/PowerSearch.doc.mjs +5 -54
- package/src/PowerSearch/PowerSearch.tsx +155 -609
- package/src/PowerSearch/PowerSearchEditPopover.tsx +6 -28
- package/src/PowerSearch/PowerSearchValueEditor.tsx +38 -203
- package/src/PowerSearch/formatFilterValue.ts +1 -18
- package/src/RadioList/RadioList.tsx +2 -3
- package/src/RadioList/RadioListItem.tsx +3 -5
- package/src/Resizable/Resizable.doc.mjs +4 -5
- package/src/Resizable/ResizeHandle.tsx +109 -167
- package/src/SegmentedControl/useSegmentedSelectionMotion.ts +3 -6
- package/src/Slider/sliderTouchController.ts +2 -2
- package/src/Spinner/Spinner.tsx +63 -77
- package/src/Switch/useSwitchTouch.ts +4 -4
- package/src/Table/BaseTable.tsx +12 -46
- package/src/TextInput/TextInput.tsx +10 -11
- package/src/Toast/Toast.doc.mjs +3 -4
- package/src/Toast/Toast.tsx +32 -52
- package/src/Toast/ToastViewport.tsx +35 -121
- package/src/Toast/types.ts +3 -9
- package/src/Tooltip/useTooltip.doc.mjs +0 -24
- package/src/Tooltip/useTooltip.tsx +56 -61
- package/src/Typeahead/TypeaheadItem.doc.mjs +3 -6
- package/src/Typeahead/TypeaheadItem.tsx +1 -2
- package/src/gestures/PressTracker.ts +3 -4
- package/src/gestures/README.md +1 -7
- package/src/hooks/actionGroupTracker.ts +5 -20
- package/src/hooks/index.ts +0 -2
- package/src/hooks/useAttachment.ts +1 -1
- package/src/hooks/useInputStatusIcon.tsx +2 -3
- package/src/hooks/useLongPress.doc.mjs +2 -2
- package/src/hooks/useLongPress.ts +15 -136
- package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +0 -6
- package/src/i18n/generated-locales/en.generated.ts +0 -41
- package/src/i18n/generated-locales/pseudo.generated.ts +0 -42
- package/src/index.ts +0 -13
- package/src/motion/README.md +5 -9
- package/src/motion/animatedLayout.ts +4 -5
- package/src/motion/animator.ts +29 -61
- package/src/utils/dateParser.ts +0 -16
- package/src/utils/focusReturn.ts +0 -30
- package/src/utils/interactionOverlay.stylex.ts +2 -3
- package/src/utils/pressFeedback.ts +6 -19
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +0 -100
- package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +0 -1
- package/dist/PowerSearch/PowerSearchBottomSheet.js +0 -1913
- package/dist/PowerSearch/formatTokenValue.d.ts +0 -28
- package/dist/PowerSearch/formatTokenValue.d.ts.map +0 -1
- package/dist/PowerSearch/formatTokenValue.js +0 -160
- package/dist/PowerSearch/powerSearchSheetUtils.d.ts +0 -65
- package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +0 -1
- package/dist/PowerSearch/powerSearchSheetUtils.js +0 -168
- package/dist/animator/createAnimator.d.ts +0 -98
- package/dist/animator/createAnimator.d.ts.map +0 -1
- package/dist/animator/createAnimator.js +0 -259
- package/dist/hooks/pressGroupContext.d.ts +0 -6
- package/dist/hooks/pressGroupContext.d.ts.map +0 -1
- package/dist/hooks/pressGroupContext.js +0 -20
- package/dist/hooks/useActionGroupTracking.d.ts +0 -53
- package/dist/hooks/useActionGroupTracking.d.ts.map +0 -1
- package/dist/hooks/useActionGroupTracking.js +0 -174
- package/dist/hooks/useAnimator.d.ts +0 -41
- package/dist/hooks/useAnimator.d.ts.map +0 -1
- package/dist/hooks/useAnimator.js +0 -70
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +0 -8
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +0 -1
- package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +0 -42
- package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +0 -8
- package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +0 -1
- package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +0 -14
- package/dist/internal/indicatorPress.stylex.d.ts +0 -20
- package/dist/internal/indicatorPress.stylex.d.ts.map +0 -1
- package/dist/internal/indicatorPress.stylex.js +0 -26
- package/dist/motion/progress.d.ts +0 -88
- package/dist/motion/progress.d.ts.map +0 -1
- package/dist/motion/progress.js +0 -128
- package/dist/motion/uikit/alert.d.ts +0 -41
- package/dist/motion/uikit/alert.d.ts.map +0 -1
- package/dist/motion/uikit/alert.js +0 -43
- package/dist/privateAttributes/pressGroupItem.stylex.d.ts +0 -15
- package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +0 -1
- package/dist/privateAttributes/pressGroupItem.stylex.js +0 -23
- package/dist/utils/triggerFocus.d.ts +0 -36
- package/dist/utils/triggerFocus.d.ts.map +0 -1
- package/dist/utils/triggerFocus.js +0 -65
- package/src/PowerSearch/PowerSearchBottomSheet.tsx +0 -2515
- package/src/PowerSearch/formatTokenValue.ts +0 -215
- package/src/PowerSearch/powerSearchSheetUtils.ts +0 -224
- package/src/animator/createAnimator.doc.mjs +0 -153
- package/src/animator/createAnimator.ts +0 -324
- package/src/hooks/pressGroupContext.ts +0 -21
- package/src/hooks/useActionGroupTracking.ts +0 -224
- package/src/hooks/useAnimator.doc.mjs +0 -109
- package/src/hooks/useAnimator.ts +0 -67
- package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +0 -43
- package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +0 -15
- package/src/internal/indicatorPress.stylex.ts +0 -24
- package/src/motion/progress.ts +0 -155
- package/src/motion/uikit/alert.ts +0 -43
- package/src/privateAttributes/pressGroupItem.stylex.ts +0 -23
- package/src/utils/triggerFocus.ts +0 -80
|
@@ -57,8 +57,7 @@ export interface ActionGroupTrackerOptions {
|
|
|
57
57
|
* target past the group's ends commits the lift there wherever the finger
|
|
58
58
|
* lifts.
|
|
59
59
|
* @default the target whose rect, grown by `highlightExpansion`, holds the
|
|
60
|
-
* point
|
|
61
|
-
* outside them
|
|
60
|
+
* point; none between or outside them
|
|
62
61
|
*/
|
|
63
62
|
resolveTarget?: (
|
|
64
63
|
x: number,
|
|
@@ -84,13 +83,8 @@ export interface ActionGroupTracker {
|
|
|
84
83
|
/**
|
|
85
84
|
* A press began at viewport (x, y): read the actions' rects once and
|
|
86
85
|
* highlight the one under it. An inert press is taken but tracks nothing.
|
|
87
|
-
* `landed` is the node the press landed on.
|
|
88
86
|
*/
|
|
89
|
-
begin(
|
|
90
|
-
x: number,
|
|
91
|
-
y: number,
|
|
92
|
-
options?: {inert?: boolean; landed?: Node | null},
|
|
93
|
-
): void;
|
|
87
|
+
begin(x: number, y: number, options?: {inert?: boolean}): void;
|
|
94
88
|
/** The finger moved to viewport (x, y). */
|
|
95
89
|
move(x: number, y: number): void;
|
|
96
90
|
/**
|
|
@@ -156,7 +150,6 @@ export function createActionGroupTracker(
|
|
|
156
150
|
let actions: TrackedAction[] = [];
|
|
157
151
|
let highlighted: HTMLElement | null = null;
|
|
158
152
|
let beganOn: HTMLElement | null = null;
|
|
159
|
-
let landedOn: Node | null = null;
|
|
160
153
|
let isTracking = false;
|
|
161
154
|
let isInert = false;
|
|
162
155
|
// The finger's last position: `remeasure` resolves it again.
|
|
@@ -248,9 +241,6 @@ export function createActionGroupTracker(
|
|
|
248
241
|
if (resolveTarget != null) {
|
|
249
242
|
return actions.length === 0 ? null : resolveTarget(x, y, actions);
|
|
250
243
|
}
|
|
251
|
-
// Rects that share an edge, or that have no layout (a test renderer), can
|
|
252
|
-
// both hold the point: the one the press landed on wins.
|
|
253
|
-
let first: HTMLElement | null = null;
|
|
254
244
|
for (const action of actions) {
|
|
255
245
|
if (
|
|
256
246
|
x >= action.left - margin &&
|
|
@@ -258,26 +248,22 @@ export function createActionGroupTracker(
|
|
|
258
248
|
y >= action.top - margin &&
|
|
259
249
|
y <= action.bottom + margin
|
|
260
250
|
) {
|
|
261
|
-
|
|
262
|
-
return action.element;
|
|
263
|
-
}
|
|
264
|
-
first ??= action.element;
|
|
251
|
+
return action.element;
|
|
265
252
|
}
|
|
266
253
|
}
|
|
267
|
-
return
|
|
254
|
+
return null;
|
|
268
255
|
};
|
|
269
256
|
|
|
270
257
|
const reset = () => {
|
|
271
258
|
actions = [];
|
|
272
259
|
highlighted = null;
|
|
273
260
|
beganOn = null;
|
|
274
|
-
landedOn = null;
|
|
275
261
|
isTracking = false;
|
|
276
262
|
isInert = false;
|
|
277
263
|
};
|
|
278
264
|
|
|
279
265
|
return {
|
|
280
|
-
begin(x, y, {inert = false
|
|
266
|
+
begin(x, y, {inert = false} = {}) {
|
|
281
267
|
// A press can begin while another is tracked, when a second recognizer
|
|
282
268
|
// takes over the finger (a trigger's held press, then the menu's): the
|
|
283
269
|
// action the first one lit loses its paint.
|
|
@@ -290,7 +276,6 @@ export function createActionGroupTracker(
|
|
|
290
276
|
highlighted = null;
|
|
291
277
|
isTracking = true;
|
|
292
278
|
isInert = inert;
|
|
293
|
-
landedOn = landed;
|
|
294
279
|
lastX = x;
|
|
295
280
|
lastY = y;
|
|
296
281
|
getOptions().onMove?.(x, y);
|
package/src/hooks/index.ts
CHANGED
|
@@ -133,8 +133,6 @@ export type {
|
|
|
133
133
|
UseInteractiveRoleOptions,
|
|
134
134
|
} from './useInteractiveRole';
|
|
135
135
|
|
|
136
|
-
export {useAnimator} from './useAnimator';
|
|
137
|
-
|
|
138
136
|
export {useLongPress} from './useLongPress';
|
|
139
137
|
export type {UseLongPressOptions, UseLongPressHandlers} from './useLongPress';
|
|
140
138
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @output Exports useAttachment and useAttachmentPair (two elements): they keep
|
|
10
10
|
* the attach function bound to the nodes the refs hold across commits
|
|
11
11
|
* @position Internal React helper, not in hooks/index.ts: the one attach and
|
|
12
|
-
* release lifecycle of the gesture hooks
|
|
12
|
+
* release lifecycle of the gesture hooks and the pager
|
|
13
13
|
*
|
|
14
14
|
* SYNC: When modified, update gestures/__tests__/useGestureRecognizer.test.tsx,
|
|
15
15
|
* gestures/__tests__/useFingerScroll.test.tsx and
|
|
@@ -15,10 +15,9 @@
|
|
|
15
15
|
import {useCallback, useEffect, useState} from 'react';
|
|
16
16
|
import type {ReactNode} from 'react';
|
|
17
17
|
import * as stylex from '@stylexjs/stylex';
|
|
18
|
-
import {Icon, type IconSize} from '../Icon
|
|
19
|
-
import type {IconName} from '../Icon/globalIconRegistry';
|
|
18
|
+
import {Icon, type IconName, type IconSize} from '../Icon';
|
|
20
19
|
import type {InputStatus, InputStatusType} from '../Field/types';
|
|
21
|
-
import {useTooltip} from '../Tooltip
|
|
20
|
+
import {useTooltip} from '../Tooltip';
|
|
22
21
|
import {radiusVars} from '../theme/tokens.stylex';
|
|
23
22
|
import {themeProps} from '../utils/themeProps';
|
|
24
23
|
import {focusOutlineStyles} from '../utils/focusOutline.stylex';
|
|
@@ -59,7 +59,7 @@ export const docs = {
|
|
|
59
59
|
],
|
|
60
60
|
usage: {
|
|
61
61
|
description:
|
|
62
|
-
'Detects a single-finger press-and-hold and reports where it happened, so touch users can reach affordances that a pointer gets from right-click. iOS Safari never synthesizes a contextmenu event on long-press, which makes this the only touch route into a cursor-positioned surface such as ContextMenu. The press cancels on movement, lift, multi-touch or unmount.
|
|
62
|
+
'Detects a single-finger press-and-hold and reports where it happened, so touch users can reach affordances that a pointer gets from right-click. iOS Safari never synthesizes a contextmenu event on long-press, which makes this the only touch route into a cursor-positioned surface such as ContextMenu. The press cancels on movement, lift, multi-touch or unmount.',
|
|
63
63
|
bestPractices: [
|
|
64
64
|
{
|
|
65
65
|
guidance: true,
|
|
@@ -102,7 +102,7 @@ export const docsDense = {
|
|
|
102
102
|
},
|
|
103
103
|
usage: {
|
|
104
104
|
description:
|
|
105
|
-
|
|
105
|
+
'Touch press-and-hold for affordances a pointer reaches by right-click (e.g. ContextMenu). Reports the point so the surface opens under the finger.',
|
|
106
106
|
bestPractices: [
|
|
107
107
|
{
|
|
108
108
|
guidance: true,
|
|
@@ -25,11 +25,6 @@
|
|
|
25
25
|
// its tolerance as a distance, as UIKit does. This hook measures it on each
|
|
26
26
|
// axis. The context menu's own movement allowance is a guess and is not
|
|
27
27
|
// measured yet (AST-094).
|
|
28
|
-
//
|
|
29
|
-
// The hold is a deadline on the touch events' timestamps, on the clock of the
|
|
30
|
-
// touch's own window. A busy main thread can delay the timer past the
|
|
31
|
-
// deadline. A touch stamped after the deadline then reports the press before
|
|
32
|
-
// it acts.
|
|
33
28
|
|
|
34
29
|
import {useCallback, useEffect, useRef} from 'react';
|
|
35
30
|
import {
|
|
@@ -42,41 +37,6 @@ import {
|
|
|
42
37
|
const DEFAULT_DELAY_MS = LONG_PRESS_DURATION_MS;
|
|
43
38
|
const DEFAULT_MOVE_CANCEL_PX = LONG_PRESS_ALLOWABLE_MOVEMENT_PX;
|
|
44
39
|
|
|
45
|
-
/** The part of a window's performance timeline a press reads. */
|
|
46
|
-
type EventClock = Pick<Performance, 'now'>;
|
|
47
|
-
|
|
48
|
-
function clockOf(e: React.TouchEvent): EventClock | null {
|
|
49
|
-
const view = e.view as unknown as {performance?: EventClock} | null;
|
|
50
|
-
return (
|
|
51
|
-
view?.performance ??
|
|
52
|
-
(typeof performance === 'undefined' ? null : performance)
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* An event's time on its window's clock. jsdom stamps events with
|
|
58
|
-
* `Date.now()`. The hook reads the age of such a stamp on that clock, so a
|
|
59
|
-
* frozen system time keeps the hold's length. A stamp nearer `Date.now()` than
|
|
60
|
-
* the window's clock is that kind of stamp.
|
|
61
|
-
*/
|
|
62
|
-
function timeOn(
|
|
63
|
-
clock: EventClock | null,
|
|
64
|
-
timeStamp: number | undefined,
|
|
65
|
-
): number | undefined {
|
|
66
|
-
// A stamp of 0 means the event carries no time, so the hold falls back to
|
|
67
|
-
// the full delay on the page's timer.
|
|
68
|
-
if (timeStamp == null || !Number.isFinite(timeStamp) || timeStamp <= 0) {
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
71
|
-
if (
|
|
72
|
-
clock != null &&
|
|
73
|
-
Math.abs(Date.now() - timeStamp) < Math.abs(clock.now() - timeStamp)
|
|
74
|
-
) {
|
|
75
|
-
return clock.now() - (Date.now() - timeStamp);
|
|
76
|
-
}
|
|
77
|
-
return timeStamp;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
40
|
export interface UseLongPressOptions {
|
|
81
41
|
/** Fired with the touch start point once the press is held for `delayMs`. */
|
|
82
42
|
onLongPress: (point: {x: number; y: number}) => void;
|
|
@@ -99,12 +59,8 @@ export interface LongPressTolerance {
|
|
|
99
59
|
export interface UseLongPressHandlers {
|
|
100
60
|
onTouchStart: (e: React.TouchEvent) => void;
|
|
101
61
|
onTouchMove: (e: React.TouchEvent) => void;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
* back by a busy page) still reports first. Spreading the handlers does.
|
|
105
|
-
*/
|
|
106
|
-
onTouchEnd: (e?: React.TouchEvent) => void;
|
|
107
|
-
onTouchCancel: (e?: React.TouchEvent) => void;
|
|
62
|
+
onTouchEnd: () => void;
|
|
63
|
+
onTouchCancel: () => void;
|
|
108
64
|
/**
|
|
109
65
|
* Begin detection at a point, for a caller driving this from its own
|
|
110
66
|
* pointer events rather than the touch handlers above.
|
|
@@ -162,9 +118,6 @@ export function useLongPressDetector(
|
|
|
162
118
|
|
|
163
119
|
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
164
120
|
const startRef = useRef<{x: number; y: number} | null>(null);
|
|
165
|
-
// The pending press's deadline and clock, when it started from a touch.
|
|
166
|
-
const deadlineRef = useRef<number | null>(null);
|
|
167
|
-
const clockRef = useRef<EventClock | null>(null);
|
|
168
121
|
// The press in progress's tolerance, when its caller chose one at start.
|
|
169
122
|
const pressToleranceRef = useRef<LongPressTolerance | null>(null);
|
|
170
123
|
// Keep the latest callback without re-creating handlers on every render.
|
|
@@ -177,39 +130,10 @@ export function useLongPressDetector(
|
|
|
177
130
|
timerRef.current = null;
|
|
178
131
|
}
|
|
179
132
|
startRef.current = null;
|
|
180
|
-
deadlineRef.current = null;
|
|
181
|
-
clockRef.current = null;
|
|
182
133
|
}, []);
|
|
183
134
|
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
if (from == null) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
clear();
|
|
190
|
-
onLongPressRef.current({x: from.x, y: from.y});
|
|
191
|
-
}, [clear]);
|
|
192
|
-
|
|
193
|
-
// A touch stamped at or past the deadline: the finger was down for the
|
|
194
|
-
// whole delay, so the press reports before the touch acts.
|
|
195
|
-
const fireIfDue = useCallback(
|
|
196
|
-
(e: React.TouchEvent | undefined) => {
|
|
197
|
-
const deadline = deadlineRef.current;
|
|
198
|
-
const eventTime =
|
|
199
|
-
e == null ? undefined : timeOn(clockRef.current, e.timeStamp);
|
|
200
|
-
if (deadline != null && eventTime != null && eventTime >= deadline) {
|
|
201
|
-
fire();
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
[fire],
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
const begin = useCallback(
|
|
208
|
-
(
|
|
209
|
-
point: {x: number; y: number},
|
|
210
|
-
tolerance: LongPressTolerance | undefined,
|
|
211
|
-
started: {at: number; clock: EventClock} | undefined,
|
|
212
|
-
) => {
|
|
135
|
+
const start = useCallback(
|
|
136
|
+
(point: {x: number; y: number}, tolerance?: LongPressTolerance) => {
|
|
213
137
|
if (disabled) {
|
|
214
138
|
return;
|
|
215
139
|
}
|
|
@@ -218,40 +142,15 @@ export function useLongPressDetector(
|
|
|
218
142
|
clear();
|
|
219
143
|
startRef.current = {x: point.x, y: point.y};
|
|
220
144
|
pressToleranceRef.current = tolerance ?? null;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
deadlineRef.current = deadline;
|
|
225
|
-
// Wait only for the rest of the hold, so a touch handled late does not
|
|
226
|
-
// lengthen it, and never past the delay.
|
|
227
|
-
const remaining =
|
|
228
|
-
clock == null || deadline == null
|
|
229
|
-
? delayMs
|
|
230
|
-
: Math.min(delayMs, Math.max(0, deadline - clock.now()));
|
|
231
|
-
// A late timer yields to queued input once, so a lift stamped before
|
|
232
|
-
// the deadline still cancels the press. The gesture arena does the same.
|
|
233
|
-
const run = (mayYield: boolean) => {
|
|
234
|
-
timerRef.current = null;
|
|
235
|
-
if (
|
|
236
|
-
mayYield &&
|
|
237
|
-
clock != null &&
|
|
238
|
-
deadline != null &&
|
|
239
|
-
clock.now() > deadline
|
|
240
|
-
) {
|
|
241
|
-
timerRef.current = setTimeout(() => run(false), 0);
|
|
145
|
+
timerRef.current = setTimeout(() => {
|
|
146
|
+
const from = startRef.current;
|
|
147
|
+
if (from == null) {
|
|
242
148
|
return;
|
|
243
149
|
}
|
|
244
|
-
|
|
245
|
-
};
|
|
246
|
-
timerRef.current = setTimeout(() => run(true), remaining);
|
|
150
|
+
onLongPressRef.current({x: from.x, y: from.y});
|
|
151
|
+
}, delayMs);
|
|
247
152
|
},
|
|
248
|
-
[disabled, delayMs, clear
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
const start = useCallback(
|
|
252
|
-
(point: {x: number; y: number}, tolerance?: LongPressTolerance) =>
|
|
253
|
-
begin(point, tolerance, undefined),
|
|
254
|
-
[begin],
|
|
153
|
+
[disabled, delayMs, clear],
|
|
255
154
|
);
|
|
256
155
|
|
|
257
156
|
const moveTo = useCallback(
|
|
@@ -280,29 +179,17 @@ export function useLongPressDetector(
|
|
|
280
179
|
return;
|
|
281
180
|
}
|
|
282
181
|
if (e.touches.length !== 1) {
|
|
283
|
-
// A second finger ends the press, unless the press was already due.
|
|
284
|
-
fireIfDue(e);
|
|
285
182
|
clear();
|
|
286
183
|
return;
|
|
287
184
|
}
|
|
288
185
|
const touch = e.touches[0];
|
|
289
|
-
|
|
290
|
-
const at = timeOn(clock, e.timeStamp);
|
|
291
|
-
begin(
|
|
292
|
-
{x: touch.clientX, y: touch.clientY},
|
|
293
|
-
undefined,
|
|
294
|
-
clock == null || at == null ? undefined : {at, clock},
|
|
295
|
-
);
|
|
186
|
+
start({x: touch.clientX, y: touch.clientY});
|
|
296
187
|
},
|
|
297
|
-
[disabled, clear,
|
|
188
|
+
[disabled, clear, start],
|
|
298
189
|
);
|
|
299
190
|
|
|
300
191
|
const onTouchMove = useCallback(
|
|
301
192
|
(e: React.TouchEvent) => {
|
|
302
|
-
if (startRef.current == null) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
fireIfDue(e);
|
|
306
193
|
if (startRef.current == null) {
|
|
307
194
|
return;
|
|
308
195
|
}
|
|
@@ -313,15 +200,7 @@ export function useLongPressDetector(
|
|
|
313
200
|
const touch = e.touches[0];
|
|
314
201
|
moveTo({x: touch.clientX, y: touch.clientY});
|
|
315
202
|
},
|
|
316
|
-
[clear, moveTo
|
|
317
|
-
);
|
|
318
|
-
|
|
319
|
-
const onTouchEnd = useCallback(
|
|
320
|
-
(e?: React.TouchEvent) => {
|
|
321
|
-
fireIfDue(e);
|
|
322
|
-
clear();
|
|
323
|
-
},
|
|
324
|
-
[clear, fireIfDue],
|
|
203
|
+
[clear, moveTo],
|
|
325
204
|
);
|
|
326
205
|
|
|
327
206
|
useEffect(() => clear, [clear]);
|
|
@@ -329,8 +208,8 @@ export function useLongPressDetector(
|
|
|
329
208
|
return {
|
|
330
209
|
onTouchStart,
|
|
331
210
|
onTouchMove,
|
|
332
|
-
onTouchEnd,
|
|
333
|
-
onTouchCancel:
|
|
211
|
+
onTouchEnd: clear,
|
|
212
|
+
onTouchCancel: clear,
|
|
334
213
|
start,
|
|
335
214
|
moveTo,
|
|
336
215
|
cancel: clear,
|
|
@@ -7,12 +7,6 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const english: Readonly<Record<string, string>> = {
|
|
10
|
-
"@astryx.powersearch.sheet.relativeDaysAgo": "{count, number} {count, plural, one {day} other {days}} ago",
|
|
11
|
-
"@astryx.powersearch.sheet.relativeDaysFromNow": "{count, number} {count, plural, one {day} other {days}} from now",
|
|
12
|
-
"@astryx.powersearch.sheet.relativeMonthsAgo": "{count, number} {count, plural, one {month} other {months}} ago",
|
|
13
|
-
"@astryx.powersearch.sheet.relativeMonthsFromNow": "{count, number} {count, plural, one {month} other {months}} from now",
|
|
14
|
-
"@astryx.powersearch.sheet.relativeWeeksAgo": "{count, number} {count, plural, one {week} other {weeks}} ago",
|
|
15
|
-
"@astryx.powersearch.sheet.relativeWeeksFromNow": "{count, number} {count, plural, one {week} other {weeks}} from now",
|
|
16
10
|
"@astryx.powersearch.valueEditor.addValuesPlaceholder": "Add values…",
|
|
17
11
|
"@astryx.powersearch.valueEditor.date": "Date",
|
|
18
12
|
"@astryx.powersearch.valueEditor.dateRange": "date range",
|
|
@@ -78,47 +78,6 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
78
78
|
'{count, number} {count, plural, one {filter} other {filters}}',
|
|
79
79
|
'@astryx.powersearch.resultCount':
|
|
80
80
|
'{count, number} {count, plural, one {result} other {results}}',
|
|
81
|
-
'@astryx.powersearch.sheet.filtersTitle': 'Filters',
|
|
82
|
-
'@astryx.powersearch.sheet.addFilter': 'Add filter',
|
|
83
|
-
'@astryx.powersearch.sheet.noFilters': 'No filters applied',
|
|
84
|
-
'@astryx.powersearch.sheet.noFiltersDescription':
|
|
85
|
-
'Add a filter to narrow your results and find what you need faster.',
|
|
86
|
-
'@astryx.powersearch.sheet.clearAll': 'Clear all',
|
|
87
|
-
'@astryx.powersearch.sheet.clearAllTitle': 'Clear all filters?',
|
|
88
|
-
'@astryx.powersearch.sheet.clearAllDescription':
|
|
89
|
-
'This removes all editable filters from this search.',
|
|
90
|
-
'@astryx.powersearch.sheet.clearAllConfirm': 'Clear filters',
|
|
91
|
-
'@astryx.powersearch.sheet.clearAllCancel': 'Keep filters',
|
|
92
|
-
'@astryx.powersearch.sheet.done': 'Done',
|
|
93
|
-
'@astryx.powersearch.sheet.search': 'Search',
|
|
94
|
-
'@astryx.powersearch.sheet.searchResults': 'Search results',
|
|
95
|
-
'@astryx.powersearch.sheet.searchFields': 'Search filters',
|
|
96
|
-
'@astryx.powersearch.sheet.searchFieldsPlaceholder': 'Search filters…',
|
|
97
|
-
'@astryx.powersearch.sheet.ungroupedFields': 'General',
|
|
98
|
-
'@astryx.powersearch.sheet.noMatchingFields': 'No filters match your search',
|
|
99
|
-
'@astryx.powersearch.sheet.tryDifferentSearch': 'Try a different search.',
|
|
100
|
-
'@astryx.powersearch.sheet.noResults': 'No results found',
|
|
101
|
-
'@astryx.powersearch.sheet.filterUnavailable':
|
|
102
|
-
'This filter is no longer available',
|
|
103
|
-
'@astryx.powersearch.sheet.removeFilter': 'Remove {field} filter',
|
|
104
|
-
'@astryx.powersearch.sheet.relativeDaysAgo':
|
|
105
|
-
'{count, number} {count, plural, one {day} other {days}} ago',
|
|
106
|
-
'@astryx.powersearch.sheet.relativeDaysFromNow':
|
|
107
|
-
'{count, number} {count, plural, one {day} other {days}} from now',
|
|
108
|
-
'@astryx.powersearch.sheet.relativeWeeksAgo':
|
|
109
|
-
'{count, number} {count, plural, one {week} other {weeks}} ago',
|
|
110
|
-
'@astryx.powersearch.sheet.relativeWeeksFromNow':
|
|
111
|
-
'{count, number} {count, plural, one {week} other {weeks}} from now',
|
|
112
|
-
'@astryx.powersearch.sheet.relativeMonthsAgo':
|
|
113
|
-
'{count, number} {count, plural, one {month} other {months}} ago',
|
|
114
|
-
'@astryx.powersearch.sheet.relativeMonthsFromNow':
|
|
115
|
-
'{count, number} {count, plural, one {month} other {months}} from now',
|
|
116
|
-
'@astryx.powersearch.sheet.fieldOperator': '{field} {operator}',
|
|
117
|
-
'@astryx.powersearch.sheet.labelValue': '{label} {value}',
|
|
118
|
-
'@astryx.powersearch.sheet.filtersClearedWithCount':
|
|
119
|
-
'All filters removed. {resultCount}',
|
|
120
|
-
'@astryx.powersearch.sheet.editableFiltersClearedWithCount':
|
|
121
|
-
'Editable filters removed. {resultCount}',
|
|
122
81
|
'@astryx.alertDialog.cancel': 'Cancel',
|
|
123
82
|
'@astryx.appShell.mobileNavigation': 'Mobile navigation',
|
|
124
83
|
'@astryx.appShell.skipToContent': 'Skip to content',
|
|
@@ -80,48 +80,6 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
80
80
|
'⟦{count, number} {count, plural, one {filter} other {filters}}⟧',
|
|
81
81
|
'@astryx.powersearch.resultCount':
|
|
82
82
|
'⟦{count, number} {count, plural, one {result} other {results}}⟧',
|
|
83
|
-
'@astryx.powersearch.sheet.filtersTitle': '⟦Ƒíłţéřš⟧',
|
|
84
|
-
'@astryx.powersearch.sheet.addFilter': '⟦Àðð ƒíłţéř⟧',
|
|
85
|
-
'@astryx.powersearch.sheet.noFilters': '⟦Ñó ƒíłţéřš àþþłíéð⟧',
|
|
86
|
-
'@astryx.powersearch.sheet.noFiltersDescription':
|
|
87
|
-
'⟦Àðð à ƒíłţéř ţó ñàřřóŵ ýóúř řéšúłţš àñð ƒíñð ŵĥàţ ýóú ñééð ƒàšţéř.⟧',
|
|
88
|
-
'@astryx.powersearch.sheet.clearAll': '⟦Çłéàř àłł⟧',
|
|
89
|
-
'@astryx.powersearch.sheet.clearAllTitle': '⟦Çłéàř àłł ƒíłţéřš?⟧',
|
|
90
|
-
'@astryx.powersearch.sheet.clearAllDescription':
|
|
91
|
-
'⟦Ţĥíš řéɱóṽéš àłł éðíţàƀłé ƒíłţéřš ƒřóɱ ţĥíš šéàřçĥ.⟧',
|
|
92
|
-
'@astryx.powersearch.sheet.clearAllConfirm': '⟦Çłéàř ƒíłţéřš⟧',
|
|
93
|
-
'@astryx.powersearch.sheet.clearAllCancel': '⟦Ķééþ ƒíłţéřš⟧',
|
|
94
|
-
'@astryx.powersearch.sheet.done': '⟦Ðóñé⟧',
|
|
95
|
-
'@astryx.powersearch.sheet.search': '⟦Šéàřçĥ⟧',
|
|
96
|
-
'@astryx.powersearch.sheet.searchResults': '⟦Šéàřçĥ řéšúłţš⟧',
|
|
97
|
-
'@astryx.powersearch.sheet.searchFields': '⟦Šéàřçĥ ƒíłţéřš⟧',
|
|
98
|
-
'@astryx.powersearch.sheet.searchFieldsPlaceholder': '⟦Šéàřçĥ ƒíłţéřš…⟧',
|
|
99
|
-
'@astryx.powersearch.sheet.ungroupedFields': '⟦Ĝéñéřàł⟧',
|
|
100
|
-
'@astryx.powersearch.sheet.noMatchingFields':
|
|
101
|
-
'⟦Ñó ƒíłţéřš ɱàţçĥ ýóúř šéàřçĥ⟧',
|
|
102
|
-
'@astryx.powersearch.sheet.tryDifferentSearch': '⟦Ţřý à ð탃éřéñţ šéàřçĥ.⟧',
|
|
103
|
-
'@astryx.powersearch.sheet.noResults': '⟦Ñó řéšúłţš ƒóúñð⟧',
|
|
104
|
-
'@astryx.powersearch.sheet.filterUnavailable':
|
|
105
|
-
'⟦Ţĥíš ƒíłţéř íš ñó łóñĝéř àṽàíłàƀłé⟧',
|
|
106
|
-
'@astryx.powersearch.sheet.removeFilter': '⟦Řéɱóṽé {field} ƒíłţéř⟧',
|
|
107
|
-
'@astryx.powersearch.sheet.relativeDaysAgo':
|
|
108
|
-
'⟦{count, number} {count, plural, one {day} other {days}} àĝó⟧',
|
|
109
|
-
'@astryx.powersearch.sheet.relativeDaysFromNow':
|
|
110
|
-
'⟦{count, number} {count, plural, one {day} other {days}} ƒřóɱ ñóŵ⟧',
|
|
111
|
-
'@astryx.powersearch.sheet.relativeWeeksAgo':
|
|
112
|
-
'⟦{count, number} {count, plural, one {week} other {weeks}} àĝó⟧',
|
|
113
|
-
'@astryx.powersearch.sheet.relativeWeeksFromNow':
|
|
114
|
-
'⟦{count, number} {count, plural, one {week} other {weeks}} ƒřóɱ ñóŵ⟧',
|
|
115
|
-
'@astryx.powersearch.sheet.relativeMonthsAgo':
|
|
116
|
-
'⟦{count, number} {count, plural, one {month} other {months}} àĝó⟧',
|
|
117
|
-
'@astryx.powersearch.sheet.relativeMonthsFromNow':
|
|
118
|
-
'⟦{count, number} {count, plural, one {month} other {months}} ƒřóɱ ñóŵ⟧',
|
|
119
|
-
'@astryx.powersearch.sheet.fieldOperator': '⟦{field} {operator}⟧',
|
|
120
|
-
'@astryx.powersearch.sheet.labelValue': '⟦{label} {value}⟧',
|
|
121
|
-
'@astryx.powersearch.sheet.filtersClearedWithCount':
|
|
122
|
-
'⟦Àłł ƒíłţéřš řéɱóṽéð. {resultCount}⟧',
|
|
123
|
-
'@astryx.powersearch.sheet.editableFiltersClearedWithCount':
|
|
124
|
-
'⟦Éðíţàƀłé ƒíłţéřš řéɱóṽéð. {resultCount}⟧',
|
|
125
83
|
'@astryx.alertDialog.cancel': '⟦Çàñçéł⟧',
|
|
126
84
|
'@astryx.appShell.mobileNavigation': '⟦Ṁóƀíłé ñàṽíĝàţíóñ⟧',
|
|
127
85
|
'@astryx.appShell.skipToContent': '⟦Šķíþ ţó çóñţéñţ⟧',
|
package/src/index.ts
CHANGED
|
@@ -173,19 +173,6 @@ export * from './Outline';
|
|
|
173
173
|
// Overflow list
|
|
174
174
|
export * from './OverflowList';
|
|
175
175
|
|
|
176
|
-
// Animating one element: from the package root only, since one API has one
|
|
177
|
-
// entry. Its hook ships from './hooks'.
|
|
178
|
-
export {
|
|
179
|
-
createAnimator,
|
|
180
|
-
type Animator,
|
|
181
|
-
type AnimatorAnimateOptions,
|
|
182
|
-
type AnimatorChannel,
|
|
183
|
-
type AnimatorDecayVelocity,
|
|
184
|
-
type AnimatorHandle,
|
|
185
|
-
type AnimatorSnapshot,
|
|
186
|
-
type AnimatorValues,
|
|
187
|
-
} from './animator/createAnimator';
|
|
188
|
-
|
|
189
176
|
// Hooks
|
|
190
177
|
export * from './hooks';
|
|
191
178
|
|
package/src/motion/README.md
CHANGED
|
@@ -19,7 +19,6 @@ roles through `resolveMotion`.
|
|
|
19
19
|
| `uikit/scroll.ts` | UIScrollView: deceleration rates, rubber band, bounce-back spring, `delaysContentTouches`, scroll to top. |
|
|
20
20
|
| `uikit/timing.ts` | Non-spring clocks and curves: press highlight, Core Animation's named curves, keyboard, Reduced Motion cross-fade. |
|
|
21
21
|
| `uikit/paging.ts` | A paging UIScrollView: the integrator that settles a release on its page, the page rule, the catch, `setContentOffset(animated:)`. |
|
|
22
|
-
| `uikit/alert.ts` | UIAlertController: how a finger is tracked across the actions (highlight onset and bounds). |
|
|
23
22
|
| `uikit/navigation.ts` | UINavigationController: push velocity, parallax, dimming, transition clock, interactive pop finish rule. |
|
|
24
23
|
| `uikit/progressBar.ts` | UIProgressView's fill: the whole-track duration and curve, its minimum length and empty alpha; the reduced-motion pulse (three roles). |
|
|
25
24
|
| `uikit/gestures.ts` | Gesture recognizer thresholds, the velocity filter and haptic stand-ins, as `{value, unit}` entries (sources in JSDoc). |
|
|
@@ -38,7 +37,6 @@ roles through `resolveMotion`.
|
|
|
38
37
|
| `resolveSnapPoint.ts` | Release policy: the snap point a release lands on (flick, back-out cancel, step limit), on `selectSnapPoint`. Internal. |
|
|
39
38
|
| `bezier.ts` | Cubic-bézier timing functions (Core Animation's named curves). |
|
|
40
39
|
| `animator.ts` | Compositor animator: springs, coasts and any closed-form curve compiled to Web Animations, read back analytically. |
|
|
41
|
-
| `progress.ts` | A spring's progress, one curve mapped from another (companions, clamped ranges), the velocity that continues a motion. |
|
|
42
40
|
| `presentation.ts` | Where each moving element is drawn relative to where the engine hit-tests it, reported by the animator while translate runs; read by the gesture host at touch-down. |
|
|
43
41
|
| `reducedMotionPlan.ts` | The animator's Reduce Motion planner: what one call becomes, a cross-fade whose travel lands while transparent or at once. |
|
|
44
42
|
| `__tests__/animator.interaction.browser.spec.ts` | Browser proofs on the interaction harness (Chromium and WebKit): busy main thread, end state through a block, no Layout / Paint, seeked curves, a dialog's backdrop. |
|
|
@@ -66,7 +64,7 @@ the timings that decide who gets a touch are not roles.
|
|
|
66
64
|
## Animator
|
|
67
65
|
|
|
68
66
|
```
|
|
69
|
-
import {
|
|
67
|
+
import {createAnimator} from '../motion/animator';
|
|
70
68
|
import {coast} from '../motion/coast';
|
|
71
69
|
import {solveSpringTowardRamp, toSpring} from '../motion/spring';
|
|
72
70
|
import {resolveMotion} from '../motion/resolveMotion';
|
|
@@ -75,7 +73,7 @@ import {registerSpringsTable, springs} from '../motion/uikit';
|
|
|
75
73
|
// Once, so the springs are registered as their roles:
|
|
76
74
|
registerSpringsTable();
|
|
77
75
|
|
|
78
|
-
const animator =
|
|
76
|
+
const animator = createAnimator(sheet);
|
|
79
77
|
// The animator plays a motion role (spec:AST-094 FR4), its table value, as the
|
|
80
78
|
// per-role tables stay internal (DEC-15); math on a spring reads the role with
|
|
81
79
|
// resolveMotion.
|
|
@@ -140,10 +138,8 @@ await handle.finished; // true if it ran to the end, false if interrupted
|
|
|
140
138
|
presented call's second frame) runs on over two frames, the start moves to
|
|
141
139
|
the call's first read after it, with every call of that task. Everything
|
|
142
140
|
the call starts shares that start
|
|
143
|
-
(`handle.started`); a retarget
|
|
144
|
-
|
|
145
|
-
sample tolerances of its target, and slower than one a frame) counts as a
|
|
146
|
-
call from rest. `{at}` puts several animators on one clock. `{start: 'commit'}` lets the browser date
|
|
141
|
+
(`handle.started`); a retarget keeps an explicit one, and `{at}` puts
|
|
142
|
+
several animators on one clock. `{start: 'commit'}` lets the browser date
|
|
147
143
|
a retarget too; `{start: 'presented'}` waits two frames, until the
|
|
148
144
|
element at rest has been presented. `handle.curve(property)` is the curve
|
|
149
145
|
a call plays, for a companion to follow. `{additive: true}` retargets the
|
|
@@ -172,7 +168,7 @@ await handle.finished; // true if it ran to the end, false if interrupted
|
|
|
172
168
|
- `animatorFor(element)` returns the one animator for an element, so code
|
|
173
169
|
that animates it from several places (a swipe on x, a removal on y)
|
|
174
170
|
composes in one `translate` track.
|
|
175
|
-
- `
|
|
171
|
+
- `createAnimator(dialog, {pseudoElement: '::backdrop'})` drives a
|
|
176
172
|
pseudo-element; with no inline style to hold it, a static filling animation
|
|
177
173
|
holds its end value until the next animation replaces it, while the
|
|
178
174
|
pseudo-element exists. A dialog's `::backdrop` is made again each time the
|
|
@@ -89,8 +89,7 @@ import {
|
|
|
89
89
|
wrapText,
|
|
90
90
|
} from './transientCopy';
|
|
91
91
|
import {isSpring} from './roleValue';
|
|
92
|
-
import {
|
|
93
|
-
import type {SpringDescription} from './spring';
|
|
92
|
+
import {solveSpring, toSpring, type SpringDescription} from './spring';
|
|
94
93
|
import {registerSpringsTable, SETTLE_SPRING} from './uikit/springs';
|
|
95
94
|
import {reducedMotionCrossFade} from './uikit/timing';
|
|
96
95
|
|
|
@@ -143,11 +142,11 @@ function settleSpring(): SpringDescription {
|
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
function springProgress(description: SpringDescription): SpringProgress {
|
|
146
|
-
const curve =
|
|
147
|
-
const durationMs = Math.max(1, curve.
|
|
145
|
+
const curve = solveSpring(toSpring(description), {from: 1, to: 0});
|
|
146
|
+
const durationMs = Math.max(1, curve.settleTime(0.001) * 1000);
|
|
148
147
|
return {
|
|
149
148
|
durationMs,
|
|
150
|
-
remaining: t => (t >= durationMs ? 0 :
|
|
149
|
+
remaining: t => (t >= durationMs ? 0 : curve.value(t / 1000)),
|
|
151
150
|
};
|
|
152
151
|
}
|
|
153
152
|
|