@seed-design/stackflow 1.1.20 → 1.1.21
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/lib/_virtual/_rolldown/runtime.cjs +34 -0
- package/lib/_virtual/_rolldown/runtime.js +14 -0
- package/lib/components/AppBar/AppBar.cjs +86 -102
- package/lib/components/AppBar/AppBar.js +84 -98
- package/lib/components/AppBar/AppBar.namespace.cjs +20 -16
- package/lib/components/AppBar/AppBar.namespace.js +15 -1
- package/lib/components/AppBar/index.cjs +17 -18
- package/lib/components/AppBar/index.js +3 -3
- package/lib/components/AppScreen/AppScreen.cjs +46 -61
- package/lib/components/AppScreen/AppScreen.js +45 -57
- package/lib/components/AppScreen/AppScreen.namespace.cjs +17 -13
- package/lib/components/AppScreen/AppScreen.namespace.js +12 -1
- package/lib/components/AppScreen/index.cjs +14 -15
- package/lib/components/AppScreen/index.js +3 -3
- package/lib/components/index.cjs +30 -26
- package/lib/components/index.js +5 -6
- package/lib/hooks/index.cjs +3 -9
- package/lib/hooks/index.js +2 -1
- package/lib/hooks/useActivityZIndexBase.cjs +12 -11
- package/lib/hooks/useActivityZIndexBase.js +11 -7
- package/lib/index.cjs +41 -32
- package/lib/index.js +8 -10
- package/lib/plugin.cjs +16 -16
- package/lib/plugin.js +14 -12
- package/lib/primitive/AppBar/AppBar.cjs +41 -33
- package/lib/primitive/AppBar/AppBar.js +40 -29
- package/lib/primitive/AppBar/AppBar.namespace.cjs +16 -12
- package/lib/primitive/AppBar/AppBar.namespace.js +11 -1
- package/lib/primitive/AppBar/anatomy.cjs +18 -0
- package/lib/primitive/AppBar/anatomy.d.ts +15 -0
- package/lib/primitive/AppBar/anatomy.js +18 -0
- package/lib/primitive/AppBar/index.cjs +13 -14
- package/lib/primitive/AppBar/index.js +3 -3
- package/lib/primitive/AppBar/useAppBar.cjs +29 -36
- package/lib/primitive/AppBar/useAppBar.js +28 -32
- package/lib/primitive/AppBar/useAppBarContext.cjs +11 -18
- package/lib/primitive/AppBar/useAppBarContext.js +10 -14
- package/lib/primitive/AppScreen/AppScreen.cjs +49 -52
- package/lib/primitive/AppScreen/AppScreen.js +48 -48
- package/lib/primitive/AppScreen/AppScreen.namespace.cjs +16 -12
- package/lib/primitive/AppScreen/AppScreen.namespace.js +11 -1
- package/lib/primitive/AppScreen/anatomy.cjs +17 -0
- package/lib/primitive/AppScreen/anatomy.d.ts +14 -0
- package/lib/primitive/AppScreen/anatomy.js +17 -0
- package/lib/primitive/AppScreen/index.cjs +15 -16
- package/lib/primitive/AppScreen/index.js +4 -4
- package/lib/primitive/AppScreen/useAppScreen.cjs +60 -63
- package/lib/primitive/AppScreen/useAppScreen.js +59 -59
- package/lib/primitive/AppScreen/useAppScreenContext.cjs +11 -18
- package/lib/primitive/AppScreen/useAppScreenContext.js +10 -14
- package/lib/primitive/GlobalInteraction/GlobalInteraction.cjs +21 -26
- package/lib/primitive/GlobalInteraction/GlobalInteraction.js +20 -22
- package/lib/primitive/GlobalInteraction/animation.cjs +303 -0
- package/lib/primitive/GlobalInteraction/animation.d.ts +16 -0
- package/lib/primitive/GlobalInteraction/animation.js +299 -0
- package/lib/primitive/GlobalInteraction/constants.cjs +9 -0
- package/lib/primitive/GlobalInteraction/constants.d.ts +19 -0
- package/lib/primitive/GlobalInteraction/constants.js +8 -0
- package/lib/primitive/GlobalInteraction/dom.cjs +147 -0
- package/lib/primitive/GlobalInteraction/dom.d.ts +44 -0
- package/lib/primitive/GlobalInteraction/dom.js +140 -0
- package/lib/primitive/GlobalInteraction/index.cjs +5 -11
- package/lib/primitive/GlobalInteraction/index.js +3 -2
- package/lib/primitive/GlobalInteraction/useGlobalInteraction.cjs +220 -133
- package/lib/primitive/GlobalInteraction/useGlobalInteraction.d.ts +10 -26
- package/lib/primitive/GlobalInteraction/useGlobalInteraction.js +219 -129
- package/lib/primitive/GlobalInteraction/useGlobalInteractionContext.cjs +11 -18
- package/lib/primitive/GlobalInteraction/useGlobalInteractionContext.js +10 -14
- package/lib/primitive/GlobalInteraction/useSwipeBack.cjs +71 -55
- package/lib/primitive/GlobalInteraction/useSwipeBack.d.ts +19 -2
- package/lib/primitive/GlobalInteraction/useSwipeBack.js +70 -51
- package/lib/primitive/index.cjs +55 -27
- package/lib/primitive/index.js +26 -9
- package/lib/primitive/private/useElementOffset.cjs +29 -51
- package/lib/primitive/private/useElementOffset.js +27 -28
- package/lib/primitive/private/useTopActivity.cjs +22 -31
- package/lib/primitive/private/useTopActivity.js +21 -27
- package/lib/utils/createStyleContext.cjs +91 -74
- package/lib/utils/createStyleContext.js +89 -70
- package/lib/utils/styled.cjs +13 -20
- package/lib/utils/styled.js +12 -16
- package/package.json +4 -4
- package/src/components/AppBar/AppBar.tsx +9 -3
- package/src/primitive/AppBar/AppBar.tsx +4 -1
- package/src/primitive/AppBar/anatomy.ts +16 -0
- package/src/primitive/AppBar/useAppBar.tsx +2 -1
- package/src/primitive/AppScreen/anatomy.ts +15 -0
- package/src/primitive/AppScreen/useAppScreen.tsx +5 -4
- package/src/primitive/GlobalInteraction/animation.ts +447 -0
- package/src/primitive/GlobalInteraction/constants.ts +24 -0
- package/src/primitive/GlobalInteraction/dom.ts +211 -0
- package/src/primitive/GlobalInteraction/useGlobalInteraction.ts +302 -129
- package/src/primitive/GlobalInteraction/useSwipeBack.ts +64 -26
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { mergeProps } from
|
|
5
|
-
import { Primitive } from
|
|
6
|
-
import { forwardRef } from
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
);
|
|
1
|
+
"use client";
|
|
2
|
+
import { GlobalInteractionProvider } from "./useGlobalInteractionContext.js";
|
|
3
|
+
import { useGlobalInteraction } from "./useGlobalInteraction.js";
|
|
4
|
+
import { mergeProps } from "@seed-design/dom-utils";
|
|
5
|
+
import { Primitive } from "@seed-design/react-primitive";
|
|
6
|
+
import { forwardRef } from "react";
|
|
7
|
+
import { composeRefs } from "@radix-ui/react-compose-refs";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
//#region src/primitive/GlobalInteraction/GlobalInteraction.tsx
|
|
10
|
+
var GlobalInteraction = forwardRef((props, ref) => {
|
|
11
|
+
const api = useGlobalInteraction();
|
|
12
|
+
return /* @__PURE__ */ jsx(GlobalInteractionProvider, {
|
|
13
|
+
value: api,
|
|
14
|
+
children: /* @__PURE__ */ jsx(Primitive.div, {
|
|
15
|
+
ref: composeRefs(api.stackRef, ref),
|
|
16
|
+
...mergeProps(api.stackProps, props)
|
|
17
|
+
})
|
|
18
|
+
});
|
|
19
|
+
});
|
|
22
20
|
GlobalInteraction.displayName = "GlobalInteraction";
|
|
23
|
-
|
|
21
|
+
//#endregion
|
|
24
22
|
export { GlobalInteraction };
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_constants = require("./constants.cjs");
|
|
3
|
+
const require_dom = require("./dom.cjs");
|
|
4
|
+
//#region src/primitive/GlobalInteraction/animation.ts
|
|
5
|
+
var IOS_EASING = "cubic-bezier(0.2, 0.1, 0.21, 0.99)";
|
|
6
|
+
var IOS_DURATION = 350;
|
|
7
|
+
var ANDROID_ENTER_EASING = "cubic-bezier(0.23, 0.1, 0.32, 1)";
|
|
8
|
+
var ANDROID_ENTER_DURATION = 300;
|
|
9
|
+
var ANDROID_EXIT_EASING = "linear";
|
|
10
|
+
var ANDROID_EXIT_DURATION = 150;
|
|
11
|
+
var FADE_IN_ENTER_EASING = "ease-out";
|
|
12
|
+
var FADE_IN_ENTER_DURATION = 300;
|
|
13
|
+
var FADE_IN_EXIT_EASING = "ease-in";
|
|
14
|
+
var FADE_IN_EXIT_DURATION = 150;
|
|
15
|
+
var FINISHED_TIMEOUT_MARGIN = 100;
|
|
16
|
+
function safeAnimate(el, keyframes, options) {
|
|
17
|
+
if (!el) return null;
|
|
18
|
+
return el.animate(keyframes, options);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Snap the app-bar background element transform during an interactive gesture
|
|
22
|
+
* (e.g. swipe-back). Reuses a single Animation by swapping its keyframes each
|
|
23
|
+
* call — recreating on every touchmove would cancel-then-recreate and cause a
|
|
24
|
+
* visible flicker.
|
|
25
|
+
*/
|
|
26
|
+
function scrubAppBarBackground(el, transform, prev) {
|
|
27
|
+
if (prev && prev.effect instanceof KeyframeEffect) try {
|
|
28
|
+
prev.effect.setKeyframes([{ transform }]);
|
|
29
|
+
return prev;
|
|
30
|
+
} catch {
|
|
31
|
+
prev.cancel();
|
|
32
|
+
}
|
|
33
|
+
return safeAnimate(el, [{ transform }], {
|
|
34
|
+
duration: 1,
|
|
35
|
+
fill: "forwards"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function cancelAll(animations) {
|
|
39
|
+
for (const a of animations) try {
|
|
40
|
+
a?.cancel();
|
|
41
|
+
} catch {}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve when the animation finishes or `timeoutMs` elapses, whichever
|
|
45
|
+
* comes first. Uses `Animation.finished` when available (Chrome 84+,
|
|
46
|
+
* Safari 13.1+, Firefox 110+) and falls back to `onfinish` / `oncancel`
|
|
47
|
+
* listeners for older browsers (e.g. Chrome 77). Both the timer and the
|
|
48
|
+
* listeners are always cleaned up on the losing side of the race, so a
|
|
49
|
+
* late-firing animation cannot invoke a stale callback or leak via
|
|
50
|
+
* closure-retained Animation references.
|
|
51
|
+
*/
|
|
52
|
+
function waitOne(a, timeoutMs) {
|
|
53
|
+
const maybeFinished = a.finished;
|
|
54
|
+
if (maybeFinished && typeof maybeFinished.then === "function") return new Promise((resolve) => {
|
|
55
|
+
let settled = false;
|
|
56
|
+
const finish = () => {
|
|
57
|
+
if (settled) return;
|
|
58
|
+
settled = true;
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
resolve();
|
|
61
|
+
};
|
|
62
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
63
|
+
maybeFinished.then(finish, finish);
|
|
64
|
+
});
|
|
65
|
+
return new Promise((resolve) => {
|
|
66
|
+
let settled = false;
|
|
67
|
+
const finish = () => {
|
|
68
|
+
if (settled) return;
|
|
69
|
+
settled = true;
|
|
70
|
+
try {
|
|
71
|
+
a.onfinish = null;
|
|
72
|
+
a.oncancel = null;
|
|
73
|
+
} catch {}
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
resolve();
|
|
76
|
+
};
|
|
77
|
+
a.onfinish = finish;
|
|
78
|
+
a.oncancel = finish;
|
|
79
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function waitAll(animations, durationMs) {
|
|
83
|
+
const valid = animations.filter((a) => a !== null);
|
|
84
|
+
if (valid.length === 0) return Promise.resolve();
|
|
85
|
+
const timeout = durationMs + FINISHED_TIMEOUT_MARGIN;
|
|
86
|
+
return Promise.all(valid.map((a) => waitOne(a, timeout))).then(() => {});
|
|
87
|
+
}
|
|
88
|
+
function collectAnimations(anims, durationMs) {
|
|
89
|
+
const animations = anims.filter((a) => a !== null);
|
|
90
|
+
return {
|
|
91
|
+
animations,
|
|
92
|
+
finished: waitAll(animations, durationMs)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
var IOS_ONSCREEN = {
|
|
96
|
+
topLayer: "translate3d(0, 0, 0)",
|
|
97
|
+
behindLayer: `translate3d(-30%, 0, 0)`,
|
|
98
|
+
dim: "1",
|
|
99
|
+
topTitle: {
|
|
100
|
+
opacity: "1",
|
|
101
|
+
transform: "translate3d(0, 0, 0)"
|
|
102
|
+
},
|
|
103
|
+
behindTitle: {
|
|
104
|
+
opacity: "0",
|
|
105
|
+
transform: `translate3d(-25%, 0, 0)`
|
|
106
|
+
},
|
|
107
|
+
topIconOpacity: "1",
|
|
108
|
+
behindIconOpacity: "0",
|
|
109
|
+
appBarBackground: "translate3d(0, 0, 0)"
|
|
110
|
+
};
|
|
111
|
+
var IOS_OFFSCREEN = {
|
|
112
|
+
topLayer: "translate3d(100%, 0, 0)",
|
|
113
|
+
behindLayer: "translate3d(0, 0, 0)",
|
|
114
|
+
dim: "0",
|
|
115
|
+
topTitle: {
|
|
116
|
+
opacity: "0",
|
|
117
|
+
transform: `translate3d(25%, 0, 0)`
|
|
118
|
+
},
|
|
119
|
+
behindTitle: {
|
|
120
|
+
opacity: "1",
|
|
121
|
+
transform: "translate3d(0, 0, 0)"
|
|
122
|
+
},
|
|
123
|
+
topIconOpacity: "0",
|
|
124
|
+
behindIconOpacity: "1",
|
|
125
|
+
appBarBackground: "translate3d(100%, 0, 0)"
|
|
126
|
+
};
|
|
127
|
+
function iosAnimate(t, from, to) {
|
|
128
|
+
const opts = {
|
|
129
|
+
duration: IOS_DURATION,
|
|
130
|
+
easing: IOS_EASING,
|
|
131
|
+
fill: "forwards"
|
|
132
|
+
};
|
|
133
|
+
const anims = [];
|
|
134
|
+
anims.push(safeAnimate(t.topLayer, [{ transform: from.topLayer }, { transform: to.topLayer }], opts));
|
|
135
|
+
anims.push(safeAnimate(t.behindLayer, [{ transform: from.behindLayer }, { transform: to.behindLayer }], opts));
|
|
136
|
+
anims.push(safeAnimate(t.topDim, [{ opacity: from.dim }, { opacity: to.dim }], opts));
|
|
137
|
+
anims.push(safeAnimate(t.topTitle, [from.topTitle, to.topTitle], opts));
|
|
138
|
+
anims.push(safeAnimate(t.behindTitle, [from.behindTitle, to.behindTitle], opts));
|
|
139
|
+
for (const icon of t.topIcons) anims.push(safeAnimate(icon, [{
|
|
140
|
+
opacity: from.topIconOpacity,
|
|
141
|
+
transform: from.topTitle.transform
|
|
142
|
+
}, {
|
|
143
|
+
opacity: to.topIconOpacity,
|
|
144
|
+
transform: to.topTitle.transform
|
|
145
|
+
}], opts));
|
|
146
|
+
for (const icon of t.behindIcons) anims.push(safeAnimate(icon, [{ opacity: from.behindIconOpacity }, { opacity: to.behindIconOpacity }], opts));
|
|
147
|
+
anims.push(safeAnimate(t.topAppBarBackground, [{ transform: from.appBarBackground }, { transform: to.appBarBackground }], opts));
|
|
148
|
+
return collectAnimations(anims, IOS_DURATION);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Pin every iOS transition target to the given position with inline styles
|
|
152
|
+
* before the animation starts. Prevents a one-frame flash at the final
|
|
153
|
+
* position when the browser paints between React commit and animation
|
|
154
|
+
* commit, and guarantees a known start state when the previous transition's
|
|
155
|
+
* finish handler did not run (e.g. in browsers without Animation.finished
|
|
156
|
+
* support, where the polyfill could time out).
|
|
157
|
+
*/
|
|
158
|
+
function pinIosInlineStyles(t, pos) {
|
|
159
|
+
require_dom.setTransform(t.topLayer, pos.topLayer);
|
|
160
|
+
require_dom.setTransform(t.behindLayer, pos.behindLayer);
|
|
161
|
+
require_dom.setOpacity(t.topDim, pos.dim);
|
|
162
|
+
require_dom.setTransform(t.topAppBarBackground, pos.appBarBackground);
|
|
163
|
+
require_dom.setOpacity(t.topTitle, pos.topTitle.opacity);
|
|
164
|
+
require_dom.setTransform(t.topTitle, pos.topTitle.transform);
|
|
165
|
+
require_dom.setOpacity(t.behindTitle, pos.behindTitle.opacity);
|
|
166
|
+
require_dom.setTransform(t.behindTitle, pos.behindTitle.transform);
|
|
167
|
+
for (const icon of t.topIcons) {
|
|
168
|
+
require_dom.setOpacity(icon, pos.topIconOpacity);
|
|
169
|
+
require_dom.setTransform(icon, pos.topTitle.transform);
|
|
170
|
+
}
|
|
171
|
+
for (const icon of t.behindIcons) require_dom.setOpacity(icon, pos.behindIconOpacity);
|
|
172
|
+
}
|
|
173
|
+
function iosAnimatePush(t) {
|
|
174
|
+
pinIosInlineStyles(t, IOS_OFFSCREEN);
|
|
175
|
+
return iosAnimate(t, IOS_OFFSCREEN, IOS_ONSCREEN);
|
|
176
|
+
}
|
|
177
|
+
function iosAnimatePop(t) {
|
|
178
|
+
return iosAnimate(t, IOS_ONSCREEN, IOS_OFFSCREEN);
|
|
179
|
+
}
|
|
180
|
+
function androidAnimate(t, direction) {
|
|
181
|
+
const isPush = direction === "push";
|
|
182
|
+
const duration = isPush ? ANDROID_ENTER_DURATION : ANDROID_EXIT_DURATION;
|
|
183
|
+
const opts = {
|
|
184
|
+
duration,
|
|
185
|
+
easing: isPush ? ANDROID_ENTER_EASING : ANDROID_EXIT_EASING,
|
|
186
|
+
fill: "forwards"
|
|
187
|
+
};
|
|
188
|
+
if (isPush) {
|
|
189
|
+
require_dom.setOpacity(t.topLayer, "0");
|
|
190
|
+
require_dom.setTransform(t.topLayer, "translate3d(0, 8vh, 0)");
|
|
191
|
+
require_dom.setOpacity(t.topDim, "0");
|
|
192
|
+
if (t.topAppBarRoot) {
|
|
193
|
+
require_dom.setOpacity(t.topAppBarRoot, "0");
|
|
194
|
+
require_dom.setTransform(t.topAppBarRoot, "translate3d(0, 8vh, 0)");
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
require_dom.setOpacity(t.topLayer, "1");
|
|
198
|
+
require_dom.setTransform(t.topLayer, "translate3d(0, 0, 0)");
|
|
199
|
+
if (t.topAppBarRoot) {
|
|
200
|
+
require_dom.setOpacity(t.topAppBarRoot, "1");
|
|
201
|
+
require_dom.setTransform(t.topAppBarRoot, "translate3d(0, 0, 0)");
|
|
202
|
+
}
|
|
203
|
+
if (t.behindAppBarRoot) t.behindAppBarRoot.style.opacity = "";
|
|
204
|
+
}
|
|
205
|
+
const [fromOpacity, toOpacity] = isPush ? ["0", "1"] : ["1", "0"];
|
|
206
|
+
const [fromY, toY] = isPush ? ["8vh", "0"] : ["0", "8vh"];
|
|
207
|
+
const shared = [{
|
|
208
|
+
opacity: fromOpacity,
|
|
209
|
+
transform: `translate3d(0, ${fromY}, 0)`
|
|
210
|
+
}, {
|
|
211
|
+
opacity: toOpacity,
|
|
212
|
+
transform: `translate3d(0, ${toY}, 0)`
|
|
213
|
+
}];
|
|
214
|
+
const dimFrames = [{
|
|
215
|
+
opacity: fromOpacity,
|
|
216
|
+
transform: `translate3d(0, ${isPush ? "-8vh" : "0"}, 0)`
|
|
217
|
+
}, {
|
|
218
|
+
opacity: toOpacity,
|
|
219
|
+
transform: `translate3d(0, ${isPush ? "0" : "-8vh"}, 0)`
|
|
220
|
+
}];
|
|
221
|
+
return collectAnimations([
|
|
222
|
+
safeAnimate(t.topLayer, shared, opts),
|
|
223
|
+
safeAnimate(t.topDim, dimFrames, opts),
|
|
224
|
+
safeAnimate(t.topAppBarRoot, shared, opts)
|
|
225
|
+
], duration);
|
|
226
|
+
}
|
|
227
|
+
function fadeInAnimate(t, direction) {
|
|
228
|
+
const isPush = direction === "push";
|
|
229
|
+
const duration = isPush ? FADE_IN_ENTER_DURATION : FADE_IN_EXIT_DURATION;
|
|
230
|
+
const opts = {
|
|
231
|
+
duration,
|
|
232
|
+
easing: isPush ? FADE_IN_ENTER_EASING : FADE_IN_EXIT_EASING,
|
|
233
|
+
fill: "forwards"
|
|
234
|
+
};
|
|
235
|
+
if (isPush) {
|
|
236
|
+
require_dom.setOpacity(t.topLayer, "0");
|
|
237
|
+
if (t.topAppBarRoot) require_dom.setOpacity(t.topAppBarRoot, "0");
|
|
238
|
+
} else {
|
|
239
|
+
require_dom.setOpacity(t.topLayer, "1");
|
|
240
|
+
if (t.topAppBarRoot) require_dom.setOpacity(t.topAppBarRoot, "1");
|
|
241
|
+
if (t.behindAppBarRoot) t.behindAppBarRoot.style.opacity = "";
|
|
242
|
+
}
|
|
243
|
+
const frames = [{ opacity: isPush ? "0" : "1" }, { opacity: isPush ? "1" : "0" }];
|
|
244
|
+
return collectAnimations([safeAnimate(t.topLayer, frames, opts), safeAnimate(t.topAppBarRoot, frames, opts)], duration);
|
|
245
|
+
}
|
|
246
|
+
function animateSwipe(t, displacement, duration, end) {
|
|
247
|
+
const ratio = displacement / window.innerWidth;
|
|
248
|
+
const topFade = Math.max(0, 1 - ratio * 3);
|
|
249
|
+
const opts = {
|
|
250
|
+
duration,
|
|
251
|
+
easing: IOS_EASING,
|
|
252
|
+
fill: "forwards"
|
|
253
|
+
};
|
|
254
|
+
const currentBehind = `translate3d(calc(-30% + ${displacement * require_constants.BEHIND_PARALLAX}px), 0, 0)`;
|
|
255
|
+
const currentTitleOffset = `translate3d(${displacement * require_constants.TITLE_TRANSLATE_RATIO}px, 0, 0)`;
|
|
256
|
+
const currentBehindTitle = `translate3d(calc(-25% + ${displacement * require_constants.TITLE_TRANSLATE_RATIO}px), 0, 0)`;
|
|
257
|
+
const anims = [
|
|
258
|
+
safeAnimate(t.topLayer, [{ transform: `translate3d(${displacement}px, 0, 0)` }, { transform: end.topLayer }], opts),
|
|
259
|
+
safeAnimate(t.behindLayer, [{ transform: currentBehind }, { transform: end.behindLayer }], opts),
|
|
260
|
+
safeAnimate(t.topDim, [{ opacity: `${1 - ratio}` }, { opacity: end.dim }], opts),
|
|
261
|
+
safeAnimate(t.topTitle, [{
|
|
262
|
+
opacity: `${topFade}`,
|
|
263
|
+
transform: currentTitleOffset
|
|
264
|
+
}, end.topTitle], opts),
|
|
265
|
+
safeAnimate(t.behindTitle, [{
|
|
266
|
+
opacity: `${ratio}`,
|
|
267
|
+
transform: currentBehindTitle
|
|
268
|
+
}, end.behindTitle], opts)
|
|
269
|
+
];
|
|
270
|
+
for (const icon of t.topIcons) anims.push(safeAnimate(icon, [{
|
|
271
|
+
opacity: `${topFade}`,
|
|
272
|
+
transform: currentTitleOffset
|
|
273
|
+
}, {
|
|
274
|
+
opacity: end.topIconOpacity,
|
|
275
|
+
transform: end.topTitle.transform
|
|
276
|
+
}], opts));
|
|
277
|
+
for (const icon of t.behindIcons) anims.push(safeAnimate(icon, [{ opacity: `${ratio}` }, { opacity: end.behindIconOpacity }], opts));
|
|
278
|
+
anims.push(safeAnimate(t.topAppBarBackground, [{ transform: `translate3d(${displacement}px, 0, 0)` }, { transform: end.appBarBackground }], opts));
|
|
279
|
+
return collectAnimations(anims, duration);
|
|
280
|
+
}
|
|
281
|
+
function animateTransition(targets, direction, style) {
|
|
282
|
+
switch (style) {
|
|
283
|
+
case "slideFromRightIOS": return direction === "push" ? iosAnimatePush(targets) : iosAnimatePop(targets);
|
|
284
|
+
case "fadeFromBottomAndroid": return androidAnimate(targets, direction);
|
|
285
|
+
case "fadeIn": return fadeInAnimate(targets, direction);
|
|
286
|
+
default: return {
|
|
287
|
+
animations: [],
|
|
288
|
+
finished: Promise.resolve()
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function animateSwipeComplete(t, displacement) {
|
|
293
|
+
return animateSwipe(t, displacement, IOS_DURATION, IOS_OFFSCREEN);
|
|
294
|
+
}
|
|
295
|
+
function animateSwipeCancel(t, displacement) {
|
|
296
|
+
return animateSwipe(t, displacement, IOS_DURATION, IOS_ONSCREEN);
|
|
297
|
+
}
|
|
298
|
+
//#endregion
|
|
299
|
+
exports.animateSwipeCancel = animateSwipeCancel;
|
|
300
|
+
exports.animateSwipeComplete = animateSwipeComplete;
|
|
301
|
+
exports.animateTransition = animateTransition;
|
|
302
|
+
exports.cancelAll = cancelAll;
|
|
303
|
+
exports.scrubAppBarBackground = scrubAppBarBackground;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TransitionTargets, TransitionStyle } from './dom';
|
|
2
|
+
/**
|
|
3
|
+
* Snap the app-bar background element transform during an interactive gesture
|
|
4
|
+
* (e.g. swipe-back). Reuses a single Animation by swapping its keyframes each
|
|
5
|
+
* call — recreating on every touchmove would cancel-then-recreate and cause a
|
|
6
|
+
* visible flicker.
|
|
7
|
+
*/
|
|
8
|
+
export declare function scrubAppBarBackground(el: HTMLElement | null, transform: string, prev: Animation | null): Animation | null;
|
|
9
|
+
export declare function cancelAll(animations: (Animation | null)[]): void;
|
|
10
|
+
export type AnimationResult = {
|
|
11
|
+
animations: Animation[];
|
|
12
|
+
finished: Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export declare function animateTransition(targets: TransitionTargets, direction: "push" | "pop", style: TransitionStyle): AnimationResult;
|
|
15
|
+
export declare function animateSwipeComplete(t: TransitionTargets, displacement: number): AnimationResult;
|
|
16
|
+
export declare function animateSwipeCancel(t: TransitionTargets, displacement: number): AnimationResult;
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { BEHIND_PARALLAX, TITLE_TRANSLATE_RATIO } from "./constants.js";
|
|
3
|
+
import { setOpacity, setTransform } from "./dom.js";
|
|
4
|
+
//#region src/primitive/GlobalInteraction/animation.ts
|
|
5
|
+
var IOS_EASING = "cubic-bezier(0.2, 0.1, 0.21, 0.99)";
|
|
6
|
+
var IOS_DURATION = 350;
|
|
7
|
+
var ANDROID_ENTER_EASING = "cubic-bezier(0.23, 0.1, 0.32, 1)";
|
|
8
|
+
var ANDROID_ENTER_DURATION = 300;
|
|
9
|
+
var ANDROID_EXIT_EASING = "linear";
|
|
10
|
+
var ANDROID_EXIT_DURATION = 150;
|
|
11
|
+
var FADE_IN_ENTER_EASING = "ease-out";
|
|
12
|
+
var FADE_IN_ENTER_DURATION = 300;
|
|
13
|
+
var FADE_IN_EXIT_EASING = "ease-in";
|
|
14
|
+
var FADE_IN_EXIT_DURATION = 150;
|
|
15
|
+
var FINISHED_TIMEOUT_MARGIN = 100;
|
|
16
|
+
function safeAnimate(el, keyframes, options) {
|
|
17
|
+
if (!el) return null;
|
|
18
|
+
return el.animate(keyframes, options);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Snap the app-bar background element transform during an interactive gesture
|
|
22
|
+
* (e.g. swipe-back). Reuses a single Animation by swapping its keyframes each
|
|
23
|
+
* call — recreating on every touchmove would cancel-then-recreate and cause a
|
|
24
|
+
* visible flicker.
|
|
25
|
+
*/
|
|
26
|
+
function scrubAppBarBackground(el, transform, prev) {
|
|
27
|
+
if (prev && prev.effect instanceof KeyframeEffect) try {
|
|
28
|
+
prev.effect.setKeyframes([{ transform }]);
|
|
29
|
+
return prev;
|
|
30
|
+
} catch {
|
|
31
|
+
prev.cancel();
|
|
32
|
+
}
|
|
33
|
+
return safeAnimate(el, [{ transform }], {
|
|
34
|
+
duration: 1,
|
|
35
|
+
fill: "forwards"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function cancelAll(animations) {
|
|
39
|
+
for (const a of animations) try {
|
|
40
|
+
a?.cancel();
|
|
41
|
+
} catch {}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve when the animation finishes or `timeoutMs` elapses, whichever
|
|
45
|
+
* comes first. Uses `Animation.finished` when available (Chrome 84+,
|
|
46
|
+
* Safari 13.1+, Firefox 110+) and falls back to `onfinish` / `oncancel`
|
|
47
|
+
* listeners for older browsers (e.g. Chrome 77). Both the timer and the
|
|
48
|
+
* listeners are always cleaned up on the losing side of the race, so a
|
|
49
|
+
* late-firing animation cannot invoke a stale callback or leak via
|
|
50
|
+
* closure-retained Animation references.
|
|
51
|
+
*/
|
|
52
|
+
function waitOne(a, timeoutMs) {
|
|
53
|
+
const maybeFinished = a.finished;
|
|
54
|
+
if (maybeFinished && typeof maybeFinished.then === "function") return new Promise((resolve) => {
|
|
55
|
+
let settled = false;
|
|
56
|
+
const finish = () => {
|
|
57
|
+
if (settled) return;
|
|
58
|
+
settled = true;
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
resolve();
|
|
61
|
+
};
|
|
62
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
63
|
+
maybeFinished.then(finish, finish);
|
|
64
|
+
});
|
|
65
|
+
return new Promise((resolve) => {
|
|
66
|
+
let settled = false;
|
|
67
|
+
const finish = () => {
|
|
68
|
+
if (settled) return;
|
|
69
|
+
settled = true;
|
|
70
|
+
try {
|
|
71
|
+
a.onfinish = null;
|
|
72
|
+
a.oncancel = null;
|
|
73
|
+
} catch {}
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
resolve();
|
|
76
|
+
};
|
|
77
|
+
a.onfinish = finish;
|
|
78
|
+
a.oncancel = finish;
|
|
79
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function waitAll(animations, durationMs) {
|
|
83
|
+
const valid = animations.filter((a) => a !== null);
|
|
84
|
+
if (valid.length === 0) return Promise.resolve();
|
|
85
|
+
const timeout = durationMs + FINISHED_TIMEOUT_MARGIN;
|
|
86
|
+
return Promise.all(valid.map((a) => waitOne(a, timeout))).then(() => {});
|
|
87
|
+
}
|
|
88
|
+
function collectAnimations(anims, durationMs) {
|
|
89
|
+
const animations = anims.filter((a) => a !== null);
|
|
90
|
+
return {
|
|
91
|
+
animations,
|
|
92
|
+
finished: waitAll(animations, durationMs)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
var IOS_ONSCREEN = {
|
|
96
|
+
topLayer: "translate3d(0, 0, 0)",
|
|
97
|
+
behindLayer: `translate3d(-30%, 0, 0)`,
|
|
98
|
+
dim: "1",
|
|
99
|
+
topTitle: {
|
|
100
|
+
opacity: "1",
|
|
101
|
+
transform: "translate3d(0, 0, 0)"
|
|
102
|
+
},
|
|
103
|
+
behindTitle: {
|
|
104
|
+
opacity: "0",
|
|
105
|
+
transform: `translate3d(-25%, 0, 0)`
|
|
106
|
+
},
|
|
107
|
+
topIconOpacity: "1",
|
|
108
|
+
behindIconOpacity: "0",
|
|
109
|
+
appBarBackground: "translate3d(0, 0, 0)"
|
|
110
|
+
};
|
|
111
|
+
var IOS_OFFSCREEN = {
|
|
112
|
+
topLayer: "translate3d(100%, 0, 0)",
|
|
113
|
+
behindLayer: "translate3d(0, 0, 0)",
|
|
114
|
+
dim: "0",
|
|
115
|
+
topTitle: {
|
|
116
|
+
opacity: "0",
|
|
117
|
+
transform: `translate3d(25%, 0, 0)`
|
|
118
|
+
},
|
|
119
|
+
behindTitle: {
|
|
120
|
+
opacity: "1",
|
|
121
|
+
transform: "translate3d(0, 0, 0)"
|
|
122
|
+
},
|
|
123
|
+
topIconOpacity: "0",
|
|
124
|
+
behindIconOpacity: "1",
|
|
125
|
+
appBarBackground: "translate3d(100%, 0, 0)"
|
|
126
|
+
};
|
|
127
|
+
function iosAnimate(t, from, to) {
|
|
128
|
+
const opts = {
|
|
129
|
+
duration: IOS_DURATION,
|
|
130
|
+
easing: IOS_EASING,
|
|
131
|
+
fill: "forwards"
|
|
132
|
+
};
|
|
133
|
+
const anims = [];
|
|
134
|
+
anims.push(safeAnimate(t.topLayer, [{ transform: from.topLayer }, { transform: to.topLayer }], opts));
|
|
135
|
+
anims.push(safeAnimate(t.behindLayer, [{ transform: from.behindLayer }, { transform: to.behindLayer }], opts));
|
|
136
|
+
anims.push(safeAnimate(t.topDim, [{ opacity: from.dim }, { opacity: to.dim }], opts));
|
|
137
|
+
anims.push(safeAnimate(t.topTitle, [from.topTitle, to.topTitle], opts));
|
|
138
|
+
anims.push(safeAnimate(t.behindTitle, [from.behindTitle, to.behindTitle], opts));
|
|
139
|
+
for (const icon of t.topIcons) anims.push(safeAnimate(icon, [{
|
|
140
|
+
opacity: from.topIconOpacity,
|
|
141
|
+
transform: from.topTitle.transform
|
|
142
|
+
}, {
|
|
143
|
+
opacity: to.topIconOpacity,
|
|
144
|
+
transform: to.topTitle.transform
|
|
145
|
+
}], opts));
|
|
146
|
+
for (const icon of t.behindIcons) anims.push(safeAnimate(icon, [{ opacity: from.behindIconOpacity }, { opacity: to.behindIconOpacity }], opts));
|
|
147
|
+
anims.push(safeAnimate(t.topAppBarBackground, [{ transform: from.appBarBackground }, { transform: to.appBarBackground }], opts));
|
|
148
|
+
return collectAnimations(anims, IOS_DURATION);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Pin every iOS transition target to the given position with inline styles
|
|
152
|
+
* before the animation starts. Prevents a one-frame flash at the final
|
|
153
|
+
* position when the browser paints between React commit and animation
|
|
154
|
+
* commit, and guarantees a known start state when the previous transition's
|
|
155
|
+
* finish handler did not run (e.g. in browsers without Animation.finished
|
|
156
|
+
* support, where the polyfill could time out).
|
|
157
|
+
*/
|
|
158
|
+
function pinIosInlineStyles(t, pos) {
|
|
159
|
+
setTransform(t.topLayer, pos.topLayer);
|
|
160
|
+
setTransform(t.behindLayer, pos.behindLayer);
|
|
161
|
+
setOpacity(t.topDim, pos.dim);
|
|
162
|
+
setTransform(t.topAppBarBackground, pos.appBarBackground);
|
|
163
|
+
setOpacity(t.topTitle, pos.topTitle.opacity);
|
|
164
|
+
setTransform(t.topTitle, pos.topTitle.transform);
|
|
165
|
+
setOpacity(t.behindTitle, pos.behindTitle.opacity);
|
|
166
|
+
setTransform(t.behindTitle, pos.behindTitle.transform);
|
|
167
|
+
for (const icon of t.topIcons) {
|
|
168
|
+
setOpacity(icon, pos.topIconOpacity);
|
|
169
|
+
setTransform(icon, pos.topTitle.transform);
|
|
170
|
+
}
|
|
171
|
+
for (const icon of t.behindIcons) setOpacity(icon, pos.behindIconOpacity);
|
|
172
|
+
}
|
|
173
|
+
function iosAnimatePush(t) {
|
|
174
|
+
pinIosInlineStyles(t, IOS_OFFSCREEN);
|
|
175
|
+
return iosAnimate(t, IOS_OFFSCREEN, IOS_ONSCREEN);
|
|
176
|
+
}
|
|
177
|
+
function iosAnimatePop(t) {
|
|
178
|
+
return iosAnimate(t, IOS_ONSCREEN, IOS_OFFSCREEN);
|
|
179
|
+
}
|
|
180
|
+
function androidAnimate(t, direction) {
|
|
181
|
+
const isPush = direction === "push";
|
|
182
|
+
const duration = isPush ? ANDROID_ENTER_DURATION : ANDROID_EXIT_DURATION;
|
|
183
|
+
const opts = {
|
|
184
|
+
duration,
|
|
185
|
+
easing: isPush ? ANDROID_ENTER_EASING : ANDROID_EXIT_EASING,
|
|
186
|
+
fill: "forwards"
|
|
187
|
+
};
|
|
188
|
+
if (isPush) {
|
|
189
|
+
setOpacity(t.topLayer, "0");
|
|
190
|
+
setTransform(t.topLayer, "translate3d(0, 8vh, 0)");
|
|
191
|
+
setOpacity(t.topDim, "0");
|
|
192
|
+
if (t.topAppBarRoot) {
|
|
193
|
+
setOpacity(t.topAppBarRoot, "0");
|
|
194
|
+
setTransform(t.topAppBarRoot, "translate3d(0, 8vh, 0)");
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
setOpacity(t.topLayer, "1");
|
|
198
|
+
setTransform(t.topLayer, "translate3d(0, 0, 0)");
|
|
199
|
+
if (t.topAppBarRoot) {
|
|
200
|
+
setOpacity(t.topAppBarRoot, "1");
|
|
201
|
+
setTransform(t.topAppBarRoot, "translate3d(0, 0, 0)");
|
|
202
|
+
}
|
|
203
|
+
if (t.behindAppBarRoot) t.behindAppBarRoot.style.opacity = "";
|
|
204
|
+
}
|
|
205
|
+
const [fromOpacity, toOpacity] = isPush ? ["0", "1"] : ["1", "0"];
|
|
206
|
+
const [fromY, toY] = isPush ? ["8vh", "0"] : ["0", "8vh"];
|
|
207
|
+
const shared = [{
|
|
208
|
+
opacity: fromOpacity,
|
|
209
|
+
transform: `translate3d(0, ${fromY}, 0)`
|
|
210
|
+
}, {
|
|
211
|
+
opacity: toOpacity,
|
|
212
|
+
transform: `translate3d(0, ${toY}, 0)`
|
|
213
|
+
}];
|
|
214
|
+
const dimFrames = [{
|
|
215
|
+
opacity: fromOpacity,
|
|
216
|
+
transform: `translate3d(0, ${isPush ? "-8vh" : "0"}, 0)`
|
|
217
|
+
}, {
|
|
218
|
+
opacity: toOpacity,
|
|
219
|
+
transform: `translate3d(0, ${isPush ? "0" : "-8vh"}, 0)`
|
|
220
|
+
}];
|
|
221
|
+
return collectAnimations([
|
|
222
|
+
safeAnimate(t.topLayer, shared, opts),
|
|
223
|
+
safeAnimate(t.topDim, dimFrames, opts),
|
|
224
|
+
safeAnimate(t.topAppBarRoot, shared, opts)
|
|
225
|
+
], duration);
|
|
226
|
+
}
|
|
227
|
+
function fadeInAnimate(t, direction) {
|
|
228
|
+
const isPush = direction === "push";
|
|
229
|
+
const duration = isPush ? FADE_IN_ENTER_DURATION : FADE_IN_EXIT_DURATION;
|
|
230
|
+
const opts = {
|
|
231
|
+
duration,
|
|
232
|
+
easing: isPush ? FADE_IN_ENTER_EASING : FADE_IN_EXIT_EASING,
|
|
233
|
+
fill: "forwards"
|
|
234
|
+
};
|
|
235
|
+
if (isPush) {
|
|
236
|
+
setOpacity(t.topLayer, "0");
|
|
237
|
+
if (t.topAppBarRoot) setOpacity(t.topAppBarRoot, "0");
|
|
238
|
+
} else {
|
|
239
|
+
setOpacity(t.topLayer, "1");
|
|
240
|
+
if (t.topAppBarRoot) setOpacity(t.topAppBarRoot, "1");
|
|
241
|
+
if (t.behindAppBarRoot) t.behindAppBarRoot.style.opacity = "";
|
|
242
|
+
}
|
|
243
|
+
const frames = [{ opacity: isPush ? "0" : "1" }, { opacity: isPush ? "1" : "0" }];
|
|
244
|
+
return collectAnimations([safeAnimate(t.topLayer, frames, opts), safeAnimate(t.topAppBarRoot, frames, opts)], duration);
|
|
245
|
+
}
|
|
246
|
+
function animateSwipe(t, displacement, duration, end) {
|
|
247
|
+
const ratio = displacement / window.innerWidth;
|
|
248
|
+
const topFade = Math.max(0, 1 - ratio * 3);
|
|
249
|
+
const opts = {
|
|
250
|
+
duration,
|
|
251
|
+
easing: IOS_EASING,
|
|
252
|
+
fill: "forwards"
|
|
253
|
+
};
|
|
254
|
+
const currentBehind = `translate3d(calc(-30% + ${displacement * BEHIND_PARALLAX}px), 0, 0)`;
|
|
255
|
+
const currentTitleOffset = `translate3d(${displacement * TITLE_TRANSLATE_RATIO}px, 0, 0)`;
|
|
256
|
+
const currentBehindTitle = `translate3d(calc(-25% + ${displacement * TITLE_TRANSLATE_RATIO}px), 0, 0)`;
|
|
257
|
+
const anims = [
|
|
258
|
+
safeAnimate(t.topLayer, [{ transform: `translate3d(${displacement}px, 0, 0)` }, { transform: end.topLayer }], opts),
|
|
259
|
+
safeAnimate(t.behindLayer, [{ transform: currentBehind }, { transform: end.behindLayer }], opts),
|
|
260
|
+
safeAnimate(t.topDim, [{ opacity: `${1 - ratio}` }, { opacity: end.dim }], opts),
|
|
261
|
+
safeAnimate(t.topTitle, [{
|
|
262
|
+
opacity: `${topFade}`,
|
|
263
|
+
transform: currentTitleOffset
|
|
264
|
+
}, end.topTitle], opts),
|
|
265
|
+
safeAnimate(t.behindTitle, [{
|
|
266
|
+
opacity: `${ratio}`,
|
|
267
|
+
transform: currentBehindTitle
|
|
268
|
+
}, end.behindTitle], opts)
|
|
269
|
+
];
|
|
270
|
+
for (const icon of t.topIcons) anims.push(safeAnimate(icon, [{
|
|
271
|
+
opacity: `${topFade}`,
|
|
272
|
+
transform: currentTitleOffset
|
|
273
|
+
}, {
|
|
274
|
+
opacity: end.topIconOpacity,
|
|
275
|
+
transform: end.topTitle.transform
|
|
276
|
+
}], opts));
|
|
277
|
+
for (const icon of t.behindIcons) anims.push(safeAnimate(icon, [{ opacity: `${ratio}` }, { opacity: end.behindIconOpacity }], opts));
|
|
278
|
+
anims.push(safeAnimate(t.topAppBarBackground, [{ transform: `translate3d(${displacement}px, 0, 0)` }, { transform: end.appBarBackground }], opts));
|
|
279
|
+
return collectAnimations(anims, duration);
|
|
280
|
+
}
|
|
281
|
+
function animateTransition(targets, direction, style) {
|
|
282
|
+
switch (style) {
|
|
283
|
+
case "slideFromRightIOS": return direction === "push" ? iosAnimatePush(targets) : iosAnimatePop(targets);
|
|
284
|
+
case "fadeFromBottomAndroid": return androidAnimate(targets, direction);
|
|
285
|
+
case "fadeIn": return fadeInAnimate(targets, direction);
|
|
286
|
+
default: return {
|
|
287
|
+
animations: [],
|
|
288
|
+
finished: Promise.resolve()
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function animateSwipeComplete(t, displacement) {
|
|
293
|
+
return animateSwipe(t, displacement, IOS_DURATION, IOS_OFFSCREEN);
|
|
294
|
+
}
|
|
295
|
+
function animateSwipeCancel(t, displacement) {
|
|
296
|
+
return animateSwipe(t, displacement, IOS_DURATION, IOS_ONSCREEN);
|
|
297
|
+
}
|
|
298
|
+
//#endregion
|
|
299
|
+
export { animateSwipeCancel, animateSwipeComplete, animateTransition, cancelAll, scrubAppBarBackground };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/primitive/GlobalInteraction/constants.ts
|
|
3
|
+
/** Behind activity's parallax multiplier applied to swipe displacement. */
|
|
4
|
+
var BEHIND_PARALLAX = .3;
|
|
5
|
+
/** Title translate-X multiplier applied to swipe displacement (px). */
|
|
6
|
+
var TITLE_TRANSLATE_RATIO = .15;
|
|
7
|
+
//#endregion
|
|
8
|
+
exports.BEHIND_PARALLAX = BEHIND_PARALLAX;
|
|
9
|
+
exports.TITLE_TRANSLATE_RATIO = TITLE_TRANSLATE_RATIO;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared numeric constants for WAAPI animations and inline style math.
|
|
3
|
+
*
|
|
4
|
+
* Consumers:
|
|
5
|
+
* - animation.ts (WAAPI keyframes)
|
|
6
|
+
* - dom.ts (swipe-time inline styles)
|
|
7
|
+
*
|
|
8
|
+
* Keeping these in one place prevents drift between the two consumers.
|
|
9
|
+
*/
|
|
10
|
+
/** Behind activity's baseline X offset during iOS slide (percent). */
|
|
11
|
+
export declare const BEHIND_OFFSET_PERCENT = -30;
|
|
12
|
+
/** Behind activity's parallax multiplier applied to swipe displacement. */
|
|
13
|
+
export declare const BEHIND_PARALLAX = 0.3;
|
|
14
|
+
/** Title translate-X multiplier applied to swipe displacement (px). */
|
|
15
|
+
export declare const TITLE_TRANSLATE_RATIO = 0.15;
|
|
16
|
+
/** Top title/icon opacity fade rate during swipe (ratio multiplier). */
|
|
17
|
+
export declare const OPACITY_FADE_MULTIPLIER = 3;
|
|
18
|
+
/** Title X offset at onscreen/offscreen endpoints (percent). */
|
|
19
|
+
export declare const TITLE_OFFSET_PERCENT = 25;
|