@octane-xplat/motion 0.0.0 → 0.7.1
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/LICENSE.motion +21 -0
- package/README.md +15 -0
- package/UPSTREAM.md +61 -0
- package/dist/native/index.js +1747 -0
- package/dist/native/octane-client-build.json +8 -0
- package/dist/web/index.js +1826 -0
- package/dist/web/octane-client-build.json +8 -0
- package/package.json +75 -5
- package/src/clock-types.ts +6 -0
- package/src/clock.ts +7 -0
- package/src/clock.web.ts +6 -0
- package/src/components.mobile.test.tsrx +84 -0
- package/src/components.tsrx +142 -0
- package/src/components.web.test.tsrx +134 -0
- package/src/config.tsrx +29 -0
- package/src/controller.ts +98 -0
- package/src/engine.test.ts +126 -0
- package/src/engine.ts +159 -0
- package/src/hooks.tsrx +56 -0
- package/src/host-types.ts +6 -0
- package/src/host.ts +50 -0
- package/src/host.web.ts +34 -0
- package/src/index.ts +9 -0
- package/src/index.web.ts +9 -0
- package/src/presence-input.ts +26 -0
- package/src/presence-input.web.ts +17 -0
- package/src/presence-state.test.ts +64 -0
- package/src/presence-state.ts +76 -0
- package/src/presence.tsrx +52 -0
- package/src/presence.web.test.tsrx +122 -0
- package/src/reduced-motion.ts +37 -0
- package/src/reduced-motion.web.ts +13 -0
- package/src/types.ts +55 -0
- package/src/value.ts +167 -0
- package/types/clock-types.d.ts +6 -0
- package/types/engine.d.ts +11 -0
- package/types/index.d.ts +53 -0
- package/types/types.d.ts +51 -0
- package/types/value.d.ts +48 -0
|
@@ -0,0 +1,1826 @@
|
|
|
1
|
+
import { bag4, child, clone, componentSlot, createContext, drainFrag, hookSlots, ifBlock, markChildrenBlock, template, useContext, useEffect, useLayoutEffect, useRef, useState, withSlot } from "octane";
|
|
2
|
+
import { textHoleUpdate } from "octane/internal/client";
|
|
3
|
+
import { Pressable, Row, View } from "@octane-xplat/ui";
|
|
4
|
+
//#region src/reduced-motion.web.ts
|
|
5
|
+
function readReducedMotion() {
|
|
6
|
+
return typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
7
|
+
}
|
|
8
|
+
function observeReducedMotion(notify) {
|
|
9
|
+
if (typeof matchMedia !== "function") return () => {};
|
|
10
|
+
const media = matchMedia("(prefers-reduced-motion: reduce)");
|
|
11
|
+
media.addEventListener("change", notify);
|
|
12
|
+
return () => media.removeEventListener("change", notify);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/config.tsrx
|
|
16
|
+
var _t$0$2 = /* @__PURE__ */ template("<!>", 0, 1);
|
|
17
|
+
var _hs$$3 = /* @__PURE__ */ hookSlots(2);
|
|
18
|
+
var _h$0$2 = /* @__PURE__ */ Symbol(_hs$$3);
|
|
19
|
+
var _h$1$2 = /* @__PURE__ */ Symbol(_hs$$3 + 1);
|
|
20
|
+
var __childrenBody$3 = {};
|
|
21
|
+
var ConfigContext = /* @__PURE__ */ createContext({ reducedMotion: "never" });
|
|
22
|
+
function useReducedMotion() {
|
|
23
|
+
const [reduced, setReduced] = useState(readReducedMotion, _h$0$2);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const update = () => setReduced(readReducedMotion());
|
|
26
|
+
const off = observeReducedMotion(update);
|
|
27
|
+
update();
|
|
28
|
+
return off;
|
|
29
|
+
}, [], _h$1$2);
|
|
30
|
+
return reduced;
|
|
31
|
+
}
|
|
32
|
+
var MotionConfig = function MotionConfig(props, __s, __extra) {
|
|
33
|
+
const __block = __s.block;
|
|
34
|
+
const parent = useContext(ConfigContext);
|
|
35
|
+
const value = {
|
|
36
|
+
transition: props.transition ?? parent.transition,
|
|
37
|
+
reducedMotion: props.reducedMotion ?? parent.reducedMotion
|
|
38
|
+
};
|
|
39
|
+
function __children$1(__props, __s, __extra) {
|
|
40
|
+
const __block = __s.block;
|
|
41
|
+
let _b = __s.slots[0];
|
|
42
|
+
if (_b === void 0) {
|
|
43
|
+
let _m0, _m1;
|
|
44
|
+
const _root = clone(_t$0$2);
|
|
45
|
+
_m0 = __block.parentNode;
|
|
46
|
+
_m1 = child(_root);
|
|
47
|
+
drainFrag(_root, __block.parentNode, __block.endMarker);
|
|
48
|
+
_b = bag4(__s, null, _m0, _m1, null, void 0);
|
|
49
|
+
}
|
|
50
|
+
{
|
|
51
|
+
const _v = props.children;
|
|
52
|
+
_b.c = textHoleUpdate(__s, 1, _b.a, _v, _b.c, _b.d, _b.b, true, true);
|
|
53
|
+
_b.d = _v;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
componentSlot(__s, 0, __block.parentNode, ConfigContext, {
|
|
57
|
+
"value": value,
|
|
58
|
+
"children": markChildrenBlock(__children$1, __childrenBody$3)
|
|
59
|
+
}, __block.endMarker, void 0, void 0, true, void 0, "c:1bf28fec");
|
|
60
|
+
};
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/presence-state.ts
|
|
63
|
+
var PresenceState = class {
|
|
64
|
+
present;
|
|
65
|
+
complete;
|
|
66
|
+
members = /* @__PURE__ */ new Set();
|
|
67
|
+
pending = /* @__PURE__ */ new Map();
|
|
68
|
+
sequence = 0;
|
|
69
|
+
generation = 0;
|
|
70
|
+
disposed = false;
|
|
71
|
+
removed = false;
|
|
72
|
+
constructor(present, complete) {
|
|
73
|
+
this.present = present;
|
|
74
|
+
this.complete = complete;
|
|
75
|
+
}
|
|
76
|
+
register(member) {
|
|
77
|
+
this.members.add(member);
|
|
78
|
+
if (!this.present) this.restart(member);
|
|
79
|
+
return () => {
|
|
80
|
+
this.members.delete(member);
|
|
81
|
+
this.pending.delete(member);
|
|
82
|
+
this.check();
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
setPresent(present) {
|
|
86
|
+
if (this.disposed || present === this.present) return;
|
|
87
|
+
this.present = present;
|
|
88
|
+
++this.generation;
|
|
89
|
+
this.removed = false;
|
|
90
|
+
this.pending.clear();
|
|
91
|
+
if (present) for (const member of this.members) member.enter();
|
|
92
|
+
else {
|
|
93
|
+
for (const member of this.members) this.restart(member);
|
|
94
|
+
this.check();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
restart(member) {
|
|
98
|
+
if (this.disposed || this.present || !this.members.has(member)) return;
|
|
99
|
+
const token = ++this.sequence;
|
|
100
|
+
this.pending.set(member, token);
|
|
101
|
+
member.exit().then((result) => {
|
|
102
|
+
if (this.disposed || this.present || this.pending.get(member) !== token) return;
|
|
103
|
+
if (result !== "finished") return;
|
|
104
|
+
this.pending.delete(member);
|
|
105
|
+
this.check();
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
check() {
|
|
109
|
+
const generation = this.generation;
|
|
110
|
+
queueMicrotask(() => {
|
|
111
|
+
if (!this.disposed && !this.present && !this.removed && !this.pending.size && generation === this.generation) {
|
|
112
|
+
this.removed = true;
|
|
113
|
+
this.complete();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
destroy() {
|
|
118
|
+
this.disposed = true;
|
|
119
|
+
++this.generation;
|
|
120
|
+
this.members.clear();
|
|
121
|
+
this.pending.clear();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/presence-input.web.ts
|
|
126
|
+
function blockInput(node) {
|
|
127
|
+
const inert = node.hasAttribute("inert");
|
|
128
|
+
const hidden = node.getAttribute("aria-hidden");
|
|
129
|
+
const pointerEvents = node.style.pointerEvents;
|
|
130
|
+
const focused = node.ownerDocument.activeElement;
|
|
131
|
+
if (focused && node.contains(focused)) focused.blur();
|
|
132
|
+
node.setAttribute("inert", "");
|
|
133
|
+
node.setAttribute("aria-hidden", "true");
|
|
134
|
+
node.style.pointerEvents = "none";
|
|
135
|
+
return () => {
|
|
136
|
+
if (!inert) node.removeAttribute("inert");
|
|
137
|
+
if (hidden === null) node.removeAttribute("aria-hidden");
|
|
138
|
+
else node.setAttribute("aria-hidden", hidden);
|
|
139
|
+
node.style.pointerEvents = pointerEvents;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/presence.tsrx
|
|
144
|
+
var _t$0$1 = /* @__PURE__ */ template("<!>", 0, 1);
|
|
145
|
+
var _hs$$2 = /* @__PURE__ */ hookSlots(7);
|
|
146
|
+
var __childrenBody$1 = {};
|
|
147
|
+
var __childrenBody$$1 = {};
|
|
148
|
+
function __then$0(__props, __s, __extra) {
|
|
149
|
+
const __block = __s.block;
|
|
150
|
+
const bind = __extra[0];
|
|
151
|
+
const children = __extra[1];
|
|
152
|
+
const host = __extra[2];
|
|
153
|
+
const restoreInput = __extra[3];
|
|
154
|
+
const state = __extra[4];
|
|
155
|
+
const syncInput = __extra[5];
|
|
156
|
+
const viewProps = __extra[6];
|
|
157
|
+
function __children$2(__props, __s, __extra) {
|
|
158
|
+
const __block = __s.block;
|
|
159
|
+
function __children$4(__props, __s, __extra) {
|
|
160
|
+
const __block = __s.block;
|
|
161
|
+
let _b = __s.slots[0];
|
|
162
|
+
if (_b === void 0) {
|
|
163
|
+
let _m0, _m1;
|
|
164
|
+
const _root = clone(_t$0$1);
|
|
165
|
+
_m0 = __block.parentNode;
|
|
166
|
+
_m1 = child(_root);
|
|
167
|
+
drainFrag(_root, __block.parentNode, __block.endMarker);
|
|
168
|
+
_b = bag4(__s, null, _m0, _m1, null, void 0);
|
|
169
|
+
}
|
|
170
|
+
{
|
|
171
|
+
const _v = children;
|
|
172
|
+
_b.c = textHoleUpdate(__s, 1, _b.a, _v, _b.c, _b.d, _b.b, true, true);
|
|
173
|
+
_b.d = _v;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
componentSlot(__s, 0, __block.parentNode, PresenceContext, {
|
|
177
|
+
"value": state,
|
|
178
|
+
"children": markChildrenBlock(__children$4, __childrenBody$1)
|
|
179
|
+
}, __block.endMarker, void 0, void 0, void 0, void 0, "c:63be6025");
|
|
180
|
+
}
|
|
181
|
+
componentSlot(__s, 0, __block.parentNode, View, {
|
|
182
|
+
...viewProps,
|
|
183
|
+
"bind": (node) => {
|
|
184
|
+
if (host.current !== node) {
|
|
185
|
+
restoreInput.current?.();
|
|
186
|
+
restoreInput.current = null;
|
|
187
|
+
host.current = node;
|
|
188
|
+
}
|
|
189
|
+
syncInput();
|
|
190
|
+
bind?.(node);
|
|
191
|
+
},
|
|
192
|
+
"children": markChildrenBlock(__children$2, __childrenBody$$1)
|
|
193
|
+
}, __block.endMarker, void 0, void 0, void 0, void 0, "c:cf4c2460");
|
|
194
|
+
}
|
|
195
|
+
var PresenceContext = /* @__PURE__ */ createContext(null);
|
|
196
|
+
var Presence = function Presence(props, __s, __extra) {
|
|
197
|
+
const __block = __s.block;
|
|
198
|
+
const [retained, setRetained] = useState(props.present, _hs$$2 + 0);
|
|
199
|
+
const latest = useRef(props, _hs$$2 + 1);
|
|
200
|
+
latest.current = props;
|
|
201
|
+
const ref = useRef(null, _hs$$2 + 2);
|
|
202
|
+
if (!ref.current) ref.current = new PresenceState(props.present, () => {
|
|
203
|
+
setRetained(false);
|
|
204
|
+
latest.current.onExitComplete?.();
|
|
205
|
+
});
|
|
206
|
+
const state = ref.current;
|
|
207
|
+
const host = useRef(null, _hs$$2 + 3);
|
|
208
|
+
const restoreInput = useRef(null, _hs$$2 + 4);
|
|
209
|
+
const syncInput = () => {
|
|
210
|
+
if (!props.present && host.current && !restoreInput.current) restoreInput.current = blockInput(host.current);
|
|
211
|
+
if (props.present && restoreInput.current) {
|
|
212
|
+
restoreInput.current();
|
|
213
|
+
restoreInput.current = null;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
useLayoutEffect(() => {
|
|
217
|
+
if (props.present) setRetained(true);
|
|
218
|
+
syncInput();
|
|
219
|
+
state.setPresent(props.present);
|
|
220
|
+
}, [props.present], _hs$$2 + 5);
|
|
221
|
+
useLayoutEffect(() => () => {
|
|
222
|
+
state.destroy();
|
|
223
|
+
restoreInput.current?.();
|
|
224
|
+
restoreInput.current = null;
|
|
225
|
+
host.current = null;
|
|
226
|
+
}, [], _hs$$2 + 6);
|
|
227
|
+
const { present, onExitComplete, children, bind, ...viewProps } = props;
|
|
228
|
+
if (__s.block.pending && !__s.block.crossRenderUpdate) return;
|
|
229
|
+
{
|
|
230
|
+
const __ifCondition = props.present || retained;
|
|
231
|
+
ifBlock(__s, 0, __block.parentNode, __ifCondition, __then$0, null, __block.endMarker, __ifCondition ? [
|
|
232
|
+
bind,
|
|
233
|
+
children,
|
|
234
|
+
host,
|
|
235
|
+
restoreInput,
|
|
236
|
+
state,
|
|
237
|
+
syncInput,
|
|
238
|
+
viewProps
|
|
239
|
+
] : void 0);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/clock.web.ts
|
|
244
|
+
var clock = {
|
|
245
|
+
now: () => performance.now(),
|
|
246
|
+
request: (callback) => requestAnimationFrame(callback),
|
|
247
|
+
cancel: (id) => cancelAnimationFrame(id)
|
|
248
|
+
};
|
|
249
|
+
//#endregion
|
|
250
|
+
//#region src/host.web.ts
|
|
251
|
+
function attachHost(node) {
|
|
252
|
+
const transform = node.style.transform;
|
|
253
|
+
const opacity = node.style.opacity;
|
|
254
|
+
const computed = getComputedStyle(node);
|
|
255
|
+
if (computed.transform && computed.transform !== "none") throw new Error("motion: put existing CSS transforms on an outer container");
|
|
256
|
+
return {
|
|
257
|
+
read: () => ({
|
|
258
|
+
opacity: Number(computed.opacity || 1),
|
|
259
|
+
x: 0,
|
|
260
|
+
y: 0,
|
|
261
|
+
scale: 1,
|
|
262
|
+
scaleX: 1,
|
|
263
|
+
scaleY: 1,
|
|
264
|
+
rotate: 0
|
|
265
|
+
}),
|
|
266
|
+
write(values) {
|
|
267
|
+
if (values.opacity !== void 0) node.style.opacity = String(Math.min(1, Math.max(0, values.opacity)));
|
|
268
|
+
if (Object.keys(values).some((key) => key !== "opacity")) node.style.transform = `translateX(${values.x ?? 0}px) translateY(${values.y ?? 0}px) scale(${values.scale ?? 1}) scaleX(${values.scaleX ?? 1}) scaleY(${values.scaleY ?? 1}) rotate(${values.rotate ?? 0}deg)`;
|
|
269
|
+
},
|
|
270
|
+
restore() {
|
|
271
|
+
node.style.transform = transform;
|
|
272
|
+
node.style.opacity = opacity;
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/clamp.mjs
|
|
278
|
+
var clamp = (min, max, v) => {
|
|
279
|
+
if (v > max) return max;
|
|
280
|
+
if (v < min) return min;
|
|
281
|
+
return v;
|
|
282
|
+
};
|
|
283
|
+
//#endregion
|
|
284
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/format-error-message.mjs
|
|
285
|
+
function formatErrorMessage(message, errorCode) {
|
|
286
|
+
return errorCode ? `${message}. For more information and steps for solving, visit https://motion.dev/troubleshooting/${errorCode}` : message;
|
|
287
|
+
}
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/errors.mjs
|
|
290
|
+
var warning = () => {};
|
|
291
|
+
var invariant = () => {};
|
|
292
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
293
|
+
warning = (check, message, errorCode) => {
|
|
294
|
+
if (!check && typeof console !== "undefined") console.warn(formatErrorMessage(message, errorCode));
|
|
295
|
+
};
|
|
296
|
+
invariant = (check, message, errorCode) => {
|
|
297
|
+
if (!check) throw new Error(formatErrorMessage(message, errorCode));
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
//#endregion
|
|
301
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/global-config.mjs
|
|
302
|
+
var MotionGlobalConfig = {};
|
|
303
|
+
//#endregion
|
|
304
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/noop.mjs
|
|
305
|
+
var noop = /* @__NO_SIDE_EFFECTS__ */ (any) => any;
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/pipe.mjs
|
|
308
|
+
/**
|
|
309
|
+
* Pipe
|
|
310
|
+
* Compose other transformers to run linearily
|
|
311
|
+
* pipe(min(20), max(40))
|
|
312
|
+
* @param {...functions} transformers
|
|
313
|
+
* @return {function}
|
|
314
|
+
*/
|
|
315
|
+
var pipe = (...transformers) => transformers.reduce((a, b) => (v) => b(a(v)));
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/progress.mjs
|
|
318
|
+
var progress = /* @__NO_SIDE_EFFECTS__ */ (from, to, value) => {
|
|
319
|
+
const range = to - from;
|
|
320
|
+
return range ? (value - from) / range : 1;
|
|
321
|
+
};
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/time-conversion.mjs
|
|
324
|
+
/**
|
|
325
|
+
* Converts seconds to milliseconds
|
|
326
|
+
*
|
|
327
|
+
* @param seconds - Time in seconds.
|
|
328
|
+
* @return milliseconds - Converted time in milliseconds.
|
|
329
|
+
*/
|
|
330
|
+
var secondsToMilliseconds = /* @__NO_SIDE_EFFECTS__ */ (seconds) => seconds * 1e3;
|
|
331
|
+
var millisecondsToSeconds = /* @__NO_SIDE_EFFECTS__ */ (milliseconds) => milliseconds / 1e3;
|
|
332
|
+
//#endregion
|
|
333
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/cubic-bezier.mjs
|
|
334
|
+
var calcBezier = (t, a1, a2) => (((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t + 3 * a1) * t;
|
|
335
|
+
var subdivisionPrecision = 1e-7;
|
|
336
|
+
var subdivisionMaxIterations = 12;
|
|
337
|
+
function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
|
|
338
|
+
let currentX;
|
|
339
|
+
let currentT;
|
|
340
|
+
let i = 0;
|
|
341
|
+
do {
|
|
342
|
+
currentT = lowerBound + (upperBound - lowerBound) / 2;
|
|
343
|
+
currentX = calcBezier(currentT, mX1, mX2) - x;
|
|
344
|
+
if (currentX > 0) upperBound = currentT;
|
|
345
|
+
else lowerBound = currentT;
|
|
346
|
+
} while (Math.abs(currentX) > subdivisionPrecision && ++i < subdivisionMaxIterations);
|
|
347
|
+
return currentT;
|
|
348
|
+
}
|
|
349
|
+
/*#__NO_SIDE_EFFECTS__*/
|
|
350
|
+
function cubicBezier(mX1, mY1, mX2, mY2) {
|
|
351
|
+
if (mX1 === mY1 && mX2 === mY2) return noop;
|
|
352
|
+
const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
|
|
353
|
+
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
|
|
354
|
+
}
|
|
355
|
+
//#endregion
|
|
356
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/modifiers/mirror.mjs
|
|
357
|
+
var mirrorEasing = /* @__NO_SIDE_EFFECTS__ */ (easing) => (p) => p <= .5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
|
|
358
|
+
//#endregion
|
|
359
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/modifiers/reverse.mjs
|
|
360
|
+
var reverseEasing = /* @__NO_SIDE_EFFECTS__ */ (easing) => (p) => 1 - easing(1 - p);
|
|
361
|
+
//#endregion
|
|
362
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/back.mjs
|
|
363
|
+
var backOut = /*@__PURE__*/ cubicBezier(.33, 1.53, .69, .99);
|
|
364
|
+
var backIn = /*@__PURE__*/ reverseEasing(backOut);
|
|
365
|
+
var backInOut = /*@__PURE__*/ mirrorEasing(backIn);
|
|
366
|
+
//#endregion
|
|
367
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/anticipate.mjs
|
|
368
|
+
var anticipate = (p) => p >= 1 ? 1 : (p *= 2) < 1 ? .5 * backIn(p) : .5 * (2 - Math.pow(2, -10 * (p - 1)));
|
|
369
|
+
//#endregion
|
|
370
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/circ.mjs
|
|
371
|
+
var circIn = (p) => 1 - Math.sin(Math.acos(p));
|
|
372
|
+
var circOut = /* @__PURE__ */ reverseEasing(circIn);
|
|
373
|
+
var circInOut = /* @__PURE__ */ mirrorEasing(circIn);
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/ease.mjs
|
|
376
|
+
var easeIn = /*@__PURE__*/ cubicBezier(.42, 0, 1, 1);
|
|
377
|
+
var easeOut = /*@__PURE__*/ cubicBezier(0, 0, .58, 1);
|
|
378
|
+
var easeInOut = /*@__PURE__*/ cubicBezier(.42, 0, .58, 1);
|
|
379
|
+
//#endregion
|
|
380
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/utils/is-easing-array.mjs
|
|
381
|
+
var isEasingArray = /* @__NO_SIDE_EFFECTS__ */ (ease) => {
|
|
382
|
+
return Array.isArray(ease) && typeof ease[0] !== "number";
|
|
383
|
+
};
|
|
384
|
+
//#endregion
|
|
385
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/utils/is-bezier-definition.mjs
|
|
386
|
+
var isBezierDefinition = /* @__NO_SIDE_EFFECTS__ */ (easing) => Array.isArray(easing) && typeof easing[0] === "number";
|
|
387
|
+
//#endregion
|
|
388
|
+
//#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/utils/map.mjs
|
|
389
|
+
var easingLookup = {
|
|
390
|
+
linear: noop,
|
|
391
|
+
easeIn,
|
|
392
|
+
easeInOut,
|
|
393
|
+
easeOut,
|
|
394
|
+
circIn,
|
|
395
|
+
circInOut,
|
|
396
|
+
circOut,
|
|
397
|
+
backIn,
|
|
398
|
+
backInOut,
|
|
399
|
+
backOut,
|
|
400
|
+
anticipate
|
|
401
|
+
};
|
|
402
|
+
var isValidEasing = (easing) => {
|
|
403
|
+
return typeof easing === "string";
|
|
404
|
+
};
|
|
405
|
+
var easingDefinitionToFunction = (definition) => {
|
|
406
|
+
if (/* @__PURE__ */ isBezierDefinition(definition)) {
|
|
407
|
+
invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`, "cubic-bezier-length");
|
|
408
|
+
const [x1, y1, x2, y2] = definition;
|
|
409
|
+
return /* @__PURE__ */ cubicBezier(x1, y1, x2, y2);
|
|
410
|
+
} else if (isValidEasing(definition)) {
|
|
411
|
+
invariant(easingLookup[definition] !== void 0, `Invalid easing type '${definition}'`, "invalid-easing-type");
|
|
412
|
+
return easingLookup[definition];
|
|
413
|
+
}
|
|
414
|
+
return definition;
|
|
415
|
+
};
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/utils/is-css-variable.mjs
|
|
418
|
+
var checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
|
|
419
|
+
var startsAsVariableToken = /*@__PURE__*/ checkStringStartsWith("var(--");
|
|
420
|
+
var isCSSVariableToken = (value) => {
|
|
421
|
+
if (!startsAsVariableToken(value)) return false;
|
|
422
|
+
return singleCssVariableRegex.test(value.split("/*")[0].trim());
|
|
423
|
+
};
|
|
424
|
+
var singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
|
|
425
|
+
//#endregion
|
|
426
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/numbers/index.mjs
|
|
427
|
+
var number = {
|
|
428
|
+
test: (v) => typeof v === "number",
|
|
429
|
+
parse: parseFloat,
|
|
430
|
+
transform: (v) => v
|
|
431
|
+
};
|
|
432
|
+
var alpha = {
|
|
433
|
+
...number,
|
|
434
|
+
transform: (v) => clamp(0, 1, v)
|
|
435
|
+
};
|
|
436
|
+
({ ...number });
|
|
437
|
+
//#endregion
|
|
438
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/sanitize.mjs
|
|
439
|
+
var sanitize = (v) => Math.round(v * 1e5) / 1e5;
|
|
440
|
+
//#endregion
|
|
441
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/float-regex.mjs
|
|
442
|
+
var floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/is-nullish.mjs
|
|
445
|
+
function isNullish(v) {
|
|
446
|
+
return v == null;
|
|
447
|
+
}
|
|
448
|
+
//#endregion
|
|
449
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/single-color-regex.mjs
|
|
450
|
+
var singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
|
|
451
|
+
//#endregion
|
|
452
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/utils.mjs
|
|
453
|
+
/**
|
|
454
|
+
* Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
|
|
455
|
+
* but false if a number or multiple colors
|
|
456
|
+
*/
|
|
457
|
+
var isColorString = (type, testProp) => (v) => {
|
|
458
|
+
return Boolean(typeof v === "string" && singleColorRegex.test(v) && v.startsWith(type) || testProp && !isNullish(v) && Object.prototype.hasOwnProperty.call(v, testProp));
|
|
459
|
+
};
|
|
460
|
+
var splitColor = (aName, bName, cName) => (v) => {
|
|
461
|
+
if (typeof v !== "string") return v;
|
|
462
|
+
const [a, b, c, alpha] = v.match(floatRegex);
|
|
463
|
+
return {
|
|
464
|
+
[aName]: parseFloat(a),
|
|
465
|
+
[bName]: parseFloat(b),
|
|
466
|
+
[cName]: parseFloat(c),
|
|
467
|
+
alpha: alpha !== void 0 ? parseFloat(alpha) : 1
|
|
468
|
+
};
|
|
469
|
+
};
|
|
470
|
+
//#endregion
|
|
471
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/rgba.mjs
|
|
472
|
+
var clampRgbUnit = (v) => clamp(0, 255, v);
|
|
473
|
+
var rgbUnit = {
|
|
474
|
+
...number,
|
|
475
|
+
transform: (v) => Math.round(clampRgbUnit(v))
|
|
476
|
+
};
|
|
477
|
+
var rgba = {
|
|
478
|
+
test: /*@__PURE__*/ isColorString("rgb", "red"),
|
|
479
|
+
parse: /*@__PURE__*/ splitColor("red", "green", "blue"),
|
|
480
|
+
transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" + rgbUnit.transform(red) + ", " + rgbUnit.transform(green) + ", " + rgbUnit.transform(blue) + ", " + sanitize(alpha.transform(alpha$1)) + ")"
|
|
481
|
+
};
|
|
482
|
+
//#endregion
|
|
483
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/hex.mjs
|
|
484
|
+
function parseHex(v) {
|
|
485
|
+
let r = "";
|
|
486
|
+
let g = "";
|
|
487
|
+
let b = "";
|
|
488
|
+
let a = "";
|
|
489
|
+
if (v.length > 5) {
|
|
490
|
+
r = v.substring(1, 3);
|
|
491
|
+
g = v.substring(3, 5);
|
|
492
|
+
b = v.substring(5, 7);
|
|
493
|
+
a = v.substring(7, 9);
|
|
494
|
+
} else {
|
|
495
|
+
r = v.substring(1, 2);
|
|
496
|
+
g = v.substring(2, 3);
|
|
497
|
+
b = v.substring(3, 4);
|
|
498
|
+
a = v.substring(4, 5);
|
|
499
|
+
r += r;
|
|
500
|
+
g += g;
|
|
501
|
+
b += b;
|
|
502
|
+
a += a;
|
|
503
|
+
}
|
|
504
|
+
return {
|
|
505
|
+
red: parseInt(r, 16),
|
|
506
|
+
green: parseInt(g, 16),
|
|
507
|
+
blue: parseInt(b, 16),
|
|
508
|
+
alpha: a ? parseInt(a, 16) / 255 : 1
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
var hex = {
|
|
512
|
+
test: /*@__PURE__*/ isColorString("#"),
|
|
513
|
+
parse: parseHex,
|
|
514
|
+
transform: rgba.transform
|
|
515
|
+
};
|
|
516
|
+
//#endregion
|
|
517
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/numbers/units.mjs
|
|
518
|
+
var createUnitType = /* @__NO_SIDE_EFFECTS__ */ (unit) => ({
|
|
519
|
+
test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
|
|
520
|
+
parse: parseFloat,
|
|
521
|
+
transform: (v) => `${v}${unit}`
|
|
522
|
+
});
|
|
523
|
+
var percent = /*@__PURE__*/ createUnitType("%");
|
|
524
|
+
//#endregion
|
|
525
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/hsla.mjs
|
|
526
|
+
var hsla = {
|
|
527
|
+
test: /*@__PURE__*/ isColorString("hsl", "hue"),
|
|
528
|
+
parse: /*@__PURE__*/ splitColor("hue", "saturation", "lightness"),
|
|
529
|
+
transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
|
|
530
|
+
return "hsla(" + Math.round(hue) + ", " + percent.transform(sanitize(saturation)) + ", " + percent.transform(sanitize(lightness)) + ", " + sanitize(alpha.transform(alpha$1)) + ")";
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/index.mjs
|
|
535
|
+
var color = {
|
|
536
|
+
test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
|
|
537
|
+
parse: (v) => {
|
|
538
|
+
if (rgba.test(v)) return rgba.parse(v);
|
|
539
|
+
else if (hsla.test(v)) return hsla.parse(v);
|
|
540
|
+
else return hex.parse(v);
|
|
541
|
+
},
|
|
542
|
+
transform: (v) => {
|
|
543
|
+
return typeof v === "string" ? v : v.hasOwnProperty("red") ? rgba.transform(v) : hsla.transform(v);
|
|
544
|
+
},
|
|
545
|
+
getAnimatableNone: (v) => {
|
|
546
|
+
const parsed = color.parse(v);
|
|
547
|
+
parsed.alpha = 0;
|
|
548
|
+
return color.transform(parsed);
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
//#endregion
|
|
552
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/color-regex.mjs
|
|
553
|
+
var colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
|
|
554
|
+
//#endregion
|
|
555
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/complex/index.mjs
|
|
556
|
+
function test(v) {
|
|
557
|
+
return isNaN(v) && typeof v === "string" && (v.match(floatRegex)?.length || 0) + (v.match(colorRegex)?.length || 0) > 0;
|
|
558
|
+
}
|
|
559
|
+
var NUMBER_TOKEN = "number";
|
|
560
|
+
var COLOR_TOKEN = "color";
|
|
561
|
+
var VAR_TOKEN = "var";
|
|
562
|
+
var VAR_FUNCTION_TOKEN = "var(";
|
|
563
|
+
var SPLIT_TOKEN = "${}";
|
|
564
|
+
var complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;
|
|
565
|
+
function analyseComplexValue(value) {
|
|
566
|
+
const originalValue = value.toString();
|
|
567
|
+
const values = [];
|
|
568
|
+
const indexes = {
|
|
569
|
+
color: [],
|
|
570
|
+
number: [],
|
|
571
|
+
var: []
|
|
572
|
+
};
|
|
573
|
+
const types = [];
|
|
574
|
+
let i = 0;
|
|
575
|
+
return {
|
|
576
|
+
values,
|
|
577
|
+
split: originalValue.replace(complexRegex, (parsedValue) => {
|
|
578
|
+
if (color.test(parsedValue)) {
|
|
579
|
+
indexes.color.push(i);
|
|
580
|
+
types.push(COLOR_TOKEN);
|
|
581
|
+
values.push(color.parse(parsedValue));
|
|
582
|
+
} else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
|
|
583
|
+
indexes.var.push(i);
|
|
584
|
+
types.push(VAR_TOKEN);
|
|
585
|
+
values.push(parsedValue);
|
|
586
|
+
} else {
|
|
587
|
+
indexes.number.push(i);
|
|
588
|
+
types.push(NUMBER_TOKEN);
|
|
589
|
+
values.push(parseFloat(parsedValue));
|
|
590
|
+
}
|
|
591
|
+
++i;
|
|
592
|
+
return SPLIT_TOKEN;
|
|
593
|
+
}).split(SPLIT_TOKEN),
|
|
594
|
+
indexes,
|
|
595
|
+
types
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
function parseComplexValue(v) {
|
|
599
|
+
return analyseComplexValue(v).values;
|
|
600
|
+
}
|
|
601
|
+
function buildTransformer({ split, types }) {
|
|
602
|
+
const numSections = split.length;
|
|
603
|
+
return (v) => {
|
|
604
|
+
let output = "";
|
|
605
|
+
for (let i = 0; i < numSections; i++) {
|
|
606
|
+
output += split[i];
|
|
607
|
+
if (v[i] !== void 0) {
|
|
608
|
+
const type = types[i];
|
|
609
|
+
if (type === NUMBER_TOKEN) output += sanitize(v[i]);
|
|
610
|
+
else if (type === COLOR_TOKEN) output += color.transform(v[i]);
|
|
611
|
+
else output += v[i];
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return output;
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
function createTransformer(source) {
|
|
618
|
+
return buildTransformer(analyseComplexValue(source));
|
|
619
|
+
}
|
|
620
|
+
var convertNumbersToZero = (v) => typeof v === "number" ? 0 : color.test(v) ? color.getAnimatableNone(v) : v;
|
|
621
|
+
/**
|
|
622
|
+
* Convert a parsed value to its zero equivalent, but preserve numbers
|
|
623
|
+
* that act as divisors in CSS calc() expressions.
|
|
624
|
+
*
|
|
625
|
+
* analyseComplexValue extracts numbers from CSS strings and puts the
|
|
626
|
+
* surrounding text into a `split` template array. For example:
|
|
627
|
+
* "calc(var(--gap) / 5)" → values: [var(--gap), 5]
|
|
628
|
+
* split: ["calc(", " / ", ")"]
|
|
629
|
+
*
|
|
630
|
+
* When building a zero-equivalent for animation, naively zeroing all
|
|
631
|
+
* numbers turns the divisor into 0 → "calc(var(--gap) / 0)" → NaN.
|
|
632
|
+
* We detect this by checking whether the text preceding a number
|
|
633
|
+
* (split[i]) ends with "/" — the CSS calc division operator.
|
|
634
|
+
*/
|
|
635
|
+
var convertToZero = (value, splitBefore) => {
|
|
636
|
+
if (typeof value === "number") return splitBefore?.trim().endsWith("/") ? value : 0;
|
|
637
|
+
return convertNumbersToZero(value);
|
|
638
|
+
};
|
|
639
|
+
function getAnimatableNone(v) {
|
|
640
|
+
const info = analyseComplexValue(v);
|
|
641
|
+
return buildTransformer(info)(info.values.map((value, i) => convertToZero(value, info.split[i])));
|
|
642
|
+
}
|
|
643
|
+
var complex = {
|
|
644
|
+
test,
|
|
645
|
+
parse: parseComplexValue,
|
|
646
|
+
createTransformer,
|
|
647
|
+
getAnimatableNone
|
|
648
|
+
};
|
|
649
|
+
//#endregion
|
|
650
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/hsla-to-rgba.mjs
|
|
651
|
+
function hueToRgb(p, q, t) {
|
|
652
|
+
if (t < 0) t += 1;
|
|
653
|
+
if (t > 1) t -= 1;
|
|
654
|
+
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
|
655
|
+
if (t < 1 / 2) return q;
|
|
656
|
+
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
|
657
|
+
return p;
|
|
658
|
+
}
|
|
659
|
+
function hslaToRgba({ hue, saturation, lightness, alpha }) {
|
|
660
|
+
hue /= 360;
|
|
661
|
+
saturation /= 100;
|
|
662
|
+
lightness /= 100;
|
|
663
|
+
let red = 0;
|
|
664
|
+
let green = 0;
|
|
665
|
+
let blue = 0;
|
|
666
|
+
if (!saturation) red = green = blue = lightness;
|
|
667
|
+
else {
|
|
668
|
+
const q = lightness < .5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
|
|
669
|
+
const p = 2 * lightness - q;
|
|
670
|
+
red = hueToRgb(p, q, hue + 1 / 3);
|
|
671
|
+
green = hueToRgb(p, q, hue);
|
|
672
|
+
blue = hueToRgb(p, q, hue - 1 / 3);
|
|
673
|
+
}
|
|
674
|
+
return {
|
|
675
|
+
red: Math.round(red * 255),
|
|
676
|
+
green: Math.round(green * 255),
|
|
677
|
+
blue: Math.round(blue * 255),
|
|
678
|
+
alpha
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
//#endregion
|
|
682
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/immediate.mjs
|
|
683
|
+
function mixImmediate(a, b) {
|
|
684
|
+
return (p) => p > 0 ? b : a;
|
|
685
|
+
}
|
|
686
|
+
//#endregion
|
|
687
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/number.mjs
|
|
688
|
+
var mixNumber$1 = (from, to, progress) => {
|
|
689
|
+
return from + (to - from) * progress;
|
|
690
|
+
};
|
|
691
|
+
//#endregion
|
|
692
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/color.mjs
|
|
693
|
+
var mixLinearColor = (from, to, v) => {
|
|
694
|
+
const fromExpo = from * from;
|
|
695
|
+
const expo = v * (to * to - fromExpo) + fromExpo;
|
|
696
|
+
return expo < 0 ? 0 : Math.sqrt(expo);
|
|
697
|
+
};
|
|
698
|
+
var colorTypes = [
|
|
699
|
+
hex,
|
|
700
|
+
rgba,
|
|
701
|
+
hsla
|
|
702
|
+
];
|
|
703
|
+
var getColorType = (v) => colorTypes.find((type) => type.test(v));
|
|
704
|
+
function asRGBA(color) {
|
|
705
|
+
const type = getColorType(color);
|
|
706
|
+
warning(Boolean(type), `'${color}' is not an animatable color. Use the equivalent color code instead.`, "color-not-animatable");
|
|
707
|
+
if (!Boolean(type)) return false;
|
|
708
|
+
let model = type.parse(color);
|
|
709
|
+
if (type === hsla) model = hslaToRgba(model);
|
|
710
|
+
return model;
|
|
711
|
+
}
|
|
712
|
+
var mixColor = (from, to) => {
|
|
713
|
+
const fromRGBA = asRGBA(from);
|
|
714
|
+
const toRGBA = asRGBA(to);
|
|
715
|
+
if (!fromRGBA || !toRGBA) return mixImmediate(from, to);
|
|
716
|
+
const blended = { ...fromRGBA };
|
|
717
|
+
return (v) => {
|
|
718
|
+
blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v);
|
|
719
|
+
blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v);
|
|
720
|
+
blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v);
|
|
721
|
+
blended.alpha = mixNumber$1(fromRGBA.alpha, toRGBA.alpha, v);
|
|
722
|
+
return rgba.transform(blended);
|
|
723
|
+
};
|
|
724
|
+
};
|
|
725
|
+
//#endregion
|
|
726
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/visibility.mjs
|
|
727
|
+
var invisibleValues = /* @__PURE__ */ new Set(["none", "hidden"]);
|
|
728
|
+
/**
|
|
729
|
+
* Returns a function that, when provided a progress value between 0 and 1,
|
|
730
|
+
* will return the "none" or "hidden" string only when the progress is that of
|
|
731
|
+
* the origin or target.
|
|
732
|
+
*/
|
|
733
|
+
function mixVisibility(origin, target) {
|
|
734
|
+
if (invisibleValues.has(origin)) return (p) => p <= 0 ? origin : target;
|
|
735
|
+
else return (p) => p >= 1 ? target : origin;
|
|
736
|
+
}
|
|
737
|
+
//#endregion
|
|
738
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/complex.mjs
|
|
739
|
+
function mixNumber(a, b) {
|
|
740
|
+
return (p) => mixNumber$1(a, b, p);
|
|
741
|
+
}
|
|
742
|
+
function getMixer(a) {
|
|
743
|
+
if (typeof a === "number") return mixNumber;
|
|
744
|
+
else if (typeof a === "string") return isCSSVariableToken(a) ? mixImmediate : color.test(a) ? mixColor : mixComplex;
|
|
745
|
+
else if (Array.isArray(a)) return mixArray;
|
|
746
|
+
else if (typeof a === "object") return color.test(a) ? mixColor : mixObject;
|
|
747
|
+
return mixImmediate;
|
|
748
|
+
}
|
|
749
|
+
function mixArray(a, b) {
|
|
750
|
+
const output = [...a];
|
|
751
|
+
const numValues = output.length;
|
|
752
|
+
const blendValue = a.map((v, i) => getMixer(v)(v, b[i]));
|
|
753
|
+
return (p) => {
|
|
754
|
+
for (let i = 0; i < numValues; i++) output[i] = blendValue[i](p);
|
|
755
|
+
return output;
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
function mixObject(a, b) {
|
|
759
|
+
const output = {
|
|
760
|
+
...a,
|
|
761
|
+
...b
|
|
762
|
+
};
|
|
763
|
+
const blendValue = {};
|
|
764
|
+
for (const key in output) if (a[key] !== void 0 && b[key] !== void 0) blendValue[key] = getMixer(a[key])(a[key], b[key]);
|
|
765
|
+
return (v) => {
|
|
766
|
+
for (const key in blendValue) output[key] = blendValue[key](v);
|
|
767
|
+
return output;
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
function matchOrder(origin, target) {
|
|
771
|
+
const orderedOrigin = [];
|
|
772
|
+
const pointers = {
|
|
773
|
+
color: 0,
|
|
774
|
+
var: 0,
|
|
775
|
+
number: 0
|
|
776
|
+
};
|
|
777
|
+
for (let i = 0; i < target.values.length; i++) {
|
|
778
|
+
const type = target.types[i];
|
|
779
|
+
const originIndex = origin.indexes[type][pointers[type]];
|
|
780
|
+
const originValue = origin.values[originIndex] ?? 0;
|
|
781
|
+
orderedOrigin[i] = originValue;
|
|
782
|
+
pointers[type]++;
|
|
783
|
+
}
|
|
784
|
+
return orderedOrigin;
|
|
785
|
+
}
|
|
786
|
+
var mixComplex = (origin, target) => {
|
|
787
|
+
const template = complex.createTransformer(target);
|
|
788
|
+
const originStats = analyseComplexValue(origin);
|
|
789
|
+
const targetStats = analyseComplexValue(target);
|
|
790
|
+
if (originStats.indexes.var.length === targetStats.indexes.var.length && originStats.indexes.color.length === targetStats.indexes.color.length && originStats.indexes.number.length >= targetStats.indexes.number.length) {
|
|
791
|
+
if (invisibleValues.has(origin) && !targetStats.values.length || invisibleValues.has(target) && !originStats.values.length) return mixVisibility(origin, target);
|
|
792
|
+
return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template);
|
|
793
|
+
} else {
|
|
794
|
+
warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`, "complex-values-different");
|
|
795
|
+
return mixImmediate(origin, target);
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
//#endregion
|
|
799
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/index.mjs
|
|
800
|
+
function mix(from, to, p) {
|
|
801
|
+
if (typeof from === "number" && typeof to === "number" && typeof p === "number") return mixNumber$1(from, to, p);
|
|
802
|
+
return getMixer(from)(from, to);
|
|
803
|
+
}
|
|
804
|
+
//#endregion
|
|
805
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/waapi/utils/linear.mjs
|
|
806
|
+
var generateLinearEasing = (easing, duration, resolution = 10) => {
|
|
807
|
+
let points = "";
|
|
808
|
+
const numPoints = Math.max(Math.round(duration / resolution), 2);
|
|
809
|
+
for (let i = 0; i < numPoints; i++) points += Math.round(easing(i / (numPoints - 1)) * 1e4) / 1e4 + ", ";
|
|
810
|
+
return `linear(${points.substring(0, points.length - 2)})`;
|
|
811
|
+
};
|
|
812
|
+
//#endregion
|
|
813
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.mjs
|
|
814
|
+
/**
|
|
815
|
+
* Implement a practical max duration for keyframe generation
|
|
816
|
+
* to prevent infinite loops
|
|
817
|
+
*/
|
|
818
|
+
var maxGeneratorDuration = 2e4;
|
|
819
|
+
function calcGeneratorDuration(generator) {
|
|
820
|
+
let duration = 0;
|
|
821
|
+
const timeStep = 50;
|
|
822
|
+
let state = generator.next(duration);
|
|
823
|
+
while (!state.done && duration < 2e4) {
|
|
824
|
+
duration += timeStep;
|
|
825
|
+
state = generator.next(duration);
|
|
826
|
+
}
|
|
827
|
+
return duration >= 2e4 ? Infinity : duration;
|
|
828
|
+
}
|
|
829
|
+
//#endregion
|
|
830
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.mjs
|
|
831
|
+
/**
|
|
832
|
+
* Create a progress => progress easing function from a generator.
|
|
833
|
+
*/
|
|
834
|
+
function createGeneratorEasing(options, scale = 100, createGenerator) {
|
|
835
|
+
const generator = createGenerator({
|
|
836
|
+
...options,
|
|
837
|
+
keyframes: [0, scale]
|
|
838
|
+
});
|
|
839
|
+
const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
|
|
840
|
+
return {
|
|
841
|
+
type: "keyframes",
|
|
842
|
+
ease: (progress) => {
|
|
843
|
+
return generator.next(duration * progress).value / scale;
|
|
844
|
+
},
|
|
845
|
+
duration: /* @__PURE__ */ millisecondsToSeconds(duration)
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
//#endregion
|
|
849
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/generators/spring.mjs
|
|
850
|
+
var springDefaults = {
|
|
851
|
+
stiffness: 100,
|
|
852
|
+
damping: 10,
|
|
853
|
+
mass: 1,
|
|
854
|
+
velocity: 0,
|
|
855
|
+
duration: 800,
|
|
856
|
+
bounce: .3,
|
|
857
|
+
visualDuration: .3,
|
|
858
|
+
restSpeed: {
|
|
859
|
+
granular: .01,
|
|
860
|
+
default: 2
|
|
861
|
+
},
|
|
862
|
+
restDelta: {
|
|
863
|
+
granular: .005,
|
|
864
|
+
default: .5
|
|
865
|
+
},
|
|
866
|
+
minDuration: .01,
|
|
867
|
+
maxDuration: 10,
|
|
868
|
+
minDamping: .05,
|
|
869
|
+
maxDamping: 1
|
|
870
|
+
};
|
|
871
|
+
function calcAngularFreq(undampedFreq, dampingRatio) {
|
|
872
|
+
return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
|
|
873
|
+
}
|
|
874
|
+
var rootIterations = 12;
|
|
875
|
+
function approximateRoot(envelope, derivative, initialGuess) {
|
|
876
|
+
let result = initialGuess;
|
|
877
|
+
for (let i = 1; i < rootIterations; i++) result = result - envelope(result) / derivative(result);
|
|
878
|
+
return result;
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* This is ported from the Framer implementation of duration-based spring resolution.
|
|
882
|
+
*/
|
|
883
|
+
var safeMin = .001;
|
|
884
|
+
function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass }) {
|
|
885
|
+
let envelope;
|
|
886
|
+
let derivative;
|
|
887
|
+
warning(duration <= /* @__PURE__ */ secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less", "spring-duration-limit");
|
|
888
|
+
let dampingRatio = 1 - bounce;
|
|
889
|
+
/**
|
|
890
|
+
* Restrict dampingRatio and duration to within acceptable ranges.
|
|
891
|
+
*/
|
|
892
|
+
dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
|
|
893
|
+
duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, /* @__PURE__ */ millisecondsToSeconds(duration));
|
|
894
|
+
if (dampingRatio < 1) {
|
|
895
|
+
/**
|
|
896
|
+
* Underdamped spring
|
|
897
|
+
*/
|
|
898
|
+
envelope = (undampedFreq) => {
|
|
899
|
+
const exponentialDecay = undampedFreq * dampingRatio;
|
|
900
|
+
const delta = exponentialDecay * duration;
|
|
901
|
+
const a = exponentialDecay - velocity;
|
|
902
|
+
const b = calcAngularFreq(undampedFreq, dampingRatio);
|
|
903
|
+
const c = Math.exp(-delta);
|
|
904
|
+
return safeMin - a / b * c;
|
|
905
|
+
};
|
|
906
|
+
derivative = (undampedFreq) => {
|
|
907
|
+
const delta = undampedFreq * dampingRatio * duration;
|
|
908
|
+
const d = delta * velocity + velocity;
|
|
909
|
+
const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq, 2) * duration;
|
|
910
|
+
const f = Math.exp(-delta);
|
|
911
|
+
const g = calcAngularFreq(Math.pow(undampedFreq, 2), dampingRatio);
|
|
912
|
+
return (-envelope(undampedFreq) + safeMin > 0 ? -1 : 1) * ((d - e) * f) / g;
|
|
913
|
+
};
|
|
914
|
+
} else {
|
|
915
|
+
/**
|
|
916
|
+
* Critically-damped spring
|
|
917
|
+
*/
|
|
918
|
+
envelope = (undampedFreq) => {
|
|
919
|
+
return -.001 + Math.exp(-undampedFreq * duration) * ((undampedFreq - velocity) * duration + 1);
|
|
920
|
+
};
|
|
921
|
+
derivative = (undampedFreq) => {
|
|
922
|
+
return Math.exp(-undampedFreq * duration) * ((velocity - undampedFreq) * (duration * duration));
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
const initialGuess = 5 / duration;
|
|
926
|
+
const undampedFreq = approximateRoot(envelope, derivative, initialGuess);
|
|
927
|
+
duration = /* @__PURE__ */ secondsToMilliseconds(duration);
|
|
928
|
+
if (isNaN(undampedFreq)) return {
|
|
929
|
+
stiffness: springDefaults.stiffness,
|
|
930
|
+
damping: springDefaults.damping,
|
|
931
|
+
duration
|
|
932
|
+
};
|
|
933
|
+
else {
|
|
934
|
+
const stiffness = Math.pow(undampedFreq, 2) * mass;
|
|
935
|
+
return {
|
|
936
|
+
stiffness,
|
|
937
|
+
damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
|
|
938
|
+
duration
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
var durationKeys = ["duration", "bounce"];
|
|
943
|
+
var physicsKeys = [
|
|
944
|
+
"stiffness",
|
|
945
|
+
"damping",
|
|
946
|
+
"mass"
|
|
947
|
+
];
|
|
948
|
+
function isSpringType(options, keys) {
|
|
949
|
+
return keys.some((key) => options[key] !== void 0);
|
|
950
|
+
}
|
|
951
|
+
function getSpringOptions(options) {
|
|
952
|
+
let springOptions = {
|
|
953
|
+
velocity: springDefaults.velocity,
|
|
954
|
+
stiffness: springDefaults.stiffness,
|
|
955
|
+
damping: springDefaults.damping,
|
|
956
|
+
mass: springDefaults.mass,
|
|
957
|
+
isResolvedFromDuration: false,
|
|
958
|
+
...options
|
|
959
|
+
};
|
|
960
|
+
if (!isSpringType(options, physicsKeys) && isSpringType(options, durationKeys)) {
|
|
961
|
+
springOptions.velocity = 0;
|
|
962
|
+
if (options.visualDuration) {
|
|
963
|
+
const visualDuration = options.visualDuration;
|
|
964
|
+
const root = 2 * Math.PI / (visualDuration * 1.2);
|
|
965
|
+
const stiffness = root * root;
|
|
966
|
+
const damping = 2 * clamp(.05, 1, 1 - (options.bounce || 0)) * Math.sqrt(stiffness);
|
|
967
|
+
springOptions = {
|
|
968
|
+
...springOptions,
|
|
969
|
+
mass: springDefaults.mass,
|
|
970
|
+
stiffness,
|
|
971
|
+
damping
|
|
972
|
+
};
|
|
973
|
+
} else {
|
|
974
|
+
const derived = findSpring({
|
|
975
|
+
...options,
|
|
976
|
+
velocity: 0
|
|
977
|
+
});
|
|
978
|
+
springOptions = {
|
|
979
|
+
...springOptions,
|
|
980
|
+
...derived,
|
|
981
|
+
mass: springDefaults.mass
|
|
982
|
+
};
|
|
983
|
+
springOptions.isResolvedFromDuration = true;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
return springOptions;
|
|
987
|
+
}
|
|
988
|
+
function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
|
|
989
|
+
const options = typeof optionsOrVisualDuration !== "object" ? {
|
|
990
|
+
visualDuration: optionsOrVisualDuration,
|
|
991
|
+
keyframes: [0, 1],
|
|
992
|
+
bounce
|
|
993
|
+
} : optionsOrVisualDuration;
|
|
994
|
+
let { restSpeed, restDelta } = options;
|
|
995
|
+
const origin = options.keyframes[0];
|
|
996
|
+
const target = options.keyframes[options.keyframes.length - 1];
|
|
997
|
+
/**
|
|
998
|
+
* This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
|
|
999
|
+
* to reduce GC during animation.
|
|
1000
|
+
*/
|
|
1001
|
+
const state = {
|
|
1002
|
+
done: false,
|
|
1003
|
+
value: origin
|
|
1004
|
+
};
|
|
1005
|
+
const { stiffness, damping, mass, duration, velocity, isResolvedFromDuration } = getSpringOptions({
|
|
1006
|
+
...options,
|
|
1007
|
+
velocity: -/* @__PURE__ */ millisecondsToSeconds(options.velocity || 0)
|
|
1008
|
+
});
|
|
1009
|
+
const initialVelocity = velocity || 0;
|
|
1010
|
+
const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
|
|
1011
|
+
const initialDelta = target - origin;
|
|
1012
|
+
const undampedAngularFreq = /* @__PURE__ */ millisecondsToSeconds(Math.sqrt(stiffness / mass));
|
|
1013
|
+
/**
|
|
1014
|
+
* If we're working on a granular scale, use smaller defaults for determining
|
|
1015
|
+
* when the spring is finished.
|
|
1016
|
+
*
|
|
1017
|
+
* These defaults have been selected emprically based on what strikes a good
|
|
1018
|
+
* ratio between feeling good and finishing as soon as changes are imperceptible.
|
|
1019
|
+
*/
|
|
1020
|
+
const isGranularScale = Math.abs(initialDelta) < 5;
|
|
1021
|
+
restSpeed || (restSpeed = isGranularScale ? springDefaults.restSpeed.granular : springDefaults.restSpeed.default);
|
|
1022
|
+
restDelta || (restDelta = isGranularScale ? springDefaults.restDelta.granular : springDefaults.restDelta.default);
|
|
1023
|
+
let resolveSpring;
|
|
1024
|
+
let resolveVelocity;
|
|
1025
|
+
let angularFreq;
|
|
1026
|
+
let A;
|
|
1027
|
+
let sinCoeff;
|
|
1028
|
+
let cosCoeff;
|
|
1029
|
+
if (dampingRatio < 1) {
|
|
1030
|
+
angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
|
|
1031
|
+
A = (initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / angularFreq;
|
|
1032
|
+
resolveSpring = (t) => {
|
|
1033
|
+
const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
|
|
1034
|
+
return target - envelope * (A * Math.sin(angularFreq * t) + initialDelta * Math.cos(angularFreq * t));
|
|
1035
|
+
};
|
|
1036
|
+
sinCoeff = dampingRatio * undampedAngularFreq * A + initialDelta * angularFreq;
|
|
1037
|
+
cosCoeff = dampingRatio * undampedAngularFreq * initialDelta - A * angularFreq;
|
|
1038
|
+
resolveVelocity = (t) => {
|
|
1039
|
+
return Math.exp(-dampingRatio * undampedAngularFreq * t) * (sinCoeff * Math.sin(angularFreq * t) + cosCoeff * Math.cos(angularFreq * t));
|
|
1040
|
+
};
|
|
1041
|
+
} else if (dampingRatio === 1) {
|
|
1042
|
+
resolveSpring = (t) => target - Math.exp(-undampedAngularFreq * t) * (initialDelta + (initialVelocity + undampedAngularFreq * initialDelta) * t);
|
|
1043
|
+
const C = initialVelocity + undampedAngularFreq * initialDelta;
|
|
1044
|
+
resolveVelocity = (t) => Math.exp(-undampedAngularFreq * t) * (undampedAngularFreq * C * t - initialVelocity);
|
|
1045
|
+
} else {
|
|
1046
|
+
const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1);
|
|
1047
|
+
resolveSpring = (t) => {
|
|
1048
|
+
const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
|
|
1049
|
+
const freqForT = Math.min(dampedAngularFreq * t, 300);
|
|
1050
|
+
return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) * Math.sinh(freqForT) + dampedAngularFreq * initialDelta * Math.cosh(freqForT)) / dampedAngularFreq;
|
|
1051
|
+
};
|
|
1052
|
+
const P = (initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / dampedAngularFreq;
|
|
1053
|
+
const sinhCoeff = dampingRatio * undampedAngularFreq * P - initialDelta * dampedAngularFreq;
|
|
1054
|
+
const coshCoeff = dampingRatio * undampedAngularFreq * initialDelta - P * dampedAngularFreq;
|
|
1055
|
+
resolveVelocity = (t) => {
|
|
1056
|
+
const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
|
|
1057
|
+
const freqForT = Math.min(dampedAngularFreq * t, 300);
|
|
1058
|
+
return envelope * (sinhCoeff * Math.sinh(freqForT) + coshCoeff * Math.cosh(freqForT));
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
1061
|
+
const generator = {
|
|
1062
|
+
calculatedDuration: isResolvedFromDuration ? duration || null : null,
|
|
1063
|
+
velocity: (t) => /* @__PURE__ */ secondsToMilliseconds(resolveVelocity(t)),
|
|
1064
|
+
next: (t) => {
|
|
1065
|
+
/**
|
|
1066
|
+
* For underdamped physics springs we need both position and
|
|
1067
|
+
* velocity each tick. Compute shared trig values once to avoid
|
|
1068
|
+
* duplicate Math.exp/sin/cos calls on the hot path.
|
|
1069
|
+
*/
|
|
1070
|
+
if (!isResolvedFromDuration && dampingRatio < 1) {
|
|
1071
|
+
const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
|
|
1072
|
+
const sin = Math.sin(angularFreq * t);
|
|
1073
|
+
const cos = Math.cos(angularFreq * t);
|
|
1074
|
+
const current = target - envelope * (A * sin + initialDelta * cos);
|
|
1075
|
+
const currentVelocity = /* @__PURE__ */ secondsToMilliseconds(envelope * (sinCoeff * sin + cosCoeff * cos));
|
|
1076
|
+
state.done = Math.abs(currentVelocity) <= restSpeed && Math.abs(target - current) <= restDelta;
|
|
1077
|
+
state.value = state.done ? target : current;
|
|
1078
|
+
return state;
|
|
1079
|
+
}
|
|
1080
|
+
const current = resolveSpring(t);
|
|
1081
|
+
if (!isResolvedFromDuration) {
|
|
1082
|
+
const currentVelocity = /* @__PURE__ */ secondsToMilliseconds(resolveVelocity(t));
|
|
1083
|
+
state.done = Math.abs(currentVelocity) <= restSpeed && Math.abs(target - current) <= restDelta;
|
|
1084
|
+
} else state.done = t >= duration;
|
|
1085
|
+
state.value = state.done ? target : current;
|
|
1086
|
+
return state;
|
|
1087
|
+
},
|
|
1088
|
+
toString: () => {
|
|
1089
|
+
const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
|
|
1090
|
+
const easing = generateLinearEasing((progress) => generator.next(calculatedDuration * progress).value, calculatedDuration, 30);
|
|
1091
|
+
return calculatedDuration + "ms " + easing;
|
|
1092
|
+
},
|
|
1093
|
+
toTransition: () => {}
|
|
1094
|
+
};
|
|
1095
|
+
return generator;
|
|
1096
|
+
}
|
|
1097
|
+
spring.applyToOptions = (options) => {
|
|
1098
|
+
const generatorOptions = createGeneratorEasing(options, 100, spring);
|
|
1099
|
+
options.ease = generatorOptions.ease;
|
|
1100
|
+
options.duration = /* @__PURE__ */ secondsToMilliseconds(generatorOptions.duration);
|
|
1101
|
+
options.type = "keyframes";
|
|
1102
|
+
return options;
|
|
1103
|
+
};
|
|
1104
|
+
//#endregion
|
|
1105
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/interpolate.mjs
|
|
1106
|
+
function createMixers(output, ease, customMixer) {
|
|
1107
|
+
const mixers = [];
|
|
1108
|
+
const mixerFactory = customMixer || MotionGlobalConfig.mix || mix;
|
|
1109
|
+
const numMixers = output.length - 1;
|
|
1110
|
+
for (let i = 0; i < numMixers; i++) {
|
|
1111
|
+
let mixer = mixerFactory(output[i], output[i + 1]);
|
|
1112
|
+
if (ease) mixer = pipe(Array.isArray(ease) ? ease[i] || noop : ease, mixer);
|
|
1113
|
+
mixers.push(mixer);
|
|
1114
|
+
}
|
|
1115
|
+
return mixers;
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Create a function that maps from a numerical input array to a generic output array.
|
|
1119
|
+
*
|
|
1120
|
+
* Accepts:
|
|
1121
|
+
* - Numbers
|
|
1122
|
+
* - Colors (hex, hsl, hsla, rgb, rgba)
|
|
1123
|
+
* - Complex (combinations of one or more numbers or strings)
|
|
1124
|
+
*
|
|
1125
|
+
* ```jsx
|
|
1126
|
+
* const mixColor = interpolate([0, 1], ['#fff', '#000'])
|
|
1127
|
+
*
|
|
1128
|
+
* mixColor(0.5) // 'rgba(128, 128, 128, 1)'
|
|
1129
|
+
* ```
|
|
1130
|
+
*
|
|
1131
|
+
* TODO Revisit this approach once we've moved to data models for values,
|
|
1132
|
+
* probably not needed to pregenerate mixer functions.
|
|
1133
|
+
*
|
|
1134
|
+
* @public
|
|
1135
|
+
*/
|
|
1136
|
+
function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {}) {
|
|
1137
|
+
const inputLength = input.length;
|
|
1138
|
+
invariant(inputLength === output.length, "Both input and output ranges must be the same length", "range-length");
|
|
1139
|
+
/**
|
|
1140
|
+
* If we're only provided a single input, we can just make a function
|
|
1141
|
+
* that returns the output.
|
|
1142
|
+
*/
|
|
1143
|
+
if (inputLength === 1) return () => output[0];
|
|
1144
|
+
if (inputLength === 2 && output[0] === output[1]) return () => output[1];
|
|
1145
|
+
const isZeroDeltaRange = input[0] === input[1];
|
|
1146
|
+
if (input[0] > input[inputLength - 1]) {
|
|
1147
|
+
input = [...input].reverse();
|
|
1148
|
+
output = [...output].reverse();
|
|
1149
|
+
}
|
|
1150
|
+
const mixers = createMixers(output, ease, mixer);
|
|
1151
|
+
const numMixers = mixers.length;
|
|
1152
|
+
const interpolator = (v) => {
|
|
1153
|
+
if (isZeroDeltaRange && v < input[0]) return output[0];
|
|
1154
|
+
let i = 0;
|
|
1155
|
+
if (numMixers > 1) {
|
|
1156
|
+
for (; i < input.length - 2; i++) if (v < input[i + 1]) break;
|
|
1157
|
+
}
|
|
1158
|
+
const progressInRange = /* @__PURE__ */ progress(input[i], input[i + 1], v);
|
|
1159
|
+
return mixers[i](progressInRange);
|
|
1160
|
+
};
|
|
1161
|
+
return isClamp ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v)) : interpolator;
|
|
1162
|
+
}
|
|
1163
|
+
//#endregion
|
|
1164
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/keyframes/offsets/fill.mjs
|
|
1165
|
+
function fillOffset(offset, remaining) {
|
|
1166
|
+
const min = offset[offset.length - 1];
|
|
1167
|
+
for (let i = 1; i <= remaining; i++) {
|
|
1168
|
+
const offsetProgress = /* @__PURE__ */ progress(0, remaining, i);
|
|
1169
|
+
offset.push(mixNumber$1(min, 1, offsetProgress));
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
//#endregion
|
|
1173
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/keyframes/offsets/default.mjs
|
|
1174
|
+
function defaultOffset(arr) {
|
|
1175
|
+
const offset = [0];
|
|
1176
|
+
fillOffset(offset, arr.length - 1);
|
|
1177
|
+
return offset;
|
|
1178
|
+
}
|
|
1179
|
+
//#endregion
|
|
1180
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/keyframes/offsets/time.mjs
|
|
1181
|
+
function convertOffsetToTimes(offset, duration) {
|
|
1182
|
+
return offset.map((o) => o * duration);
|
|
1183
|
+
}
|
|
1184
|
+
//#endregion
|
|
1185
|
+
//#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/generators/keyframes.mjs
|
|
1186
|
+
function defaultEasing(values, easing) {
|
|
1187
|
+
return values.map(() => easing || easeInOut).splice(0, values.length - 1);
|
|
1188
|
+
}
|
|
1189
|
+
function keyframes({ duration = 300, keyframes: keyframeValues, times, ease = "easeInOut" }) {
|
|
1190
|
+
/**
|
|
1191
|
+
* Easing functions can be externally defined as strings. Here we convert them
|
|
1192
|
+
* into actual functions.
|
|
1193
|
+
*/
|
|
1194
|
+
const easingFunctions = /* @__PURE__ */ isEasingArray(ease) ? ease.map(easingDefinitionToFunction) : easingDefinitionToFunction(ease);
|
|
1195
|
+
/**
|
|
1196
|
+
* This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
|
|
1197
|
+
* to reduce GC during animation.
|
|
1198
|
+
*/
|
|
1199
|
+
const state = {
|
|
1200
|
+
done: false,
|
|
1201
|
+
value: keyframeValues[0]
|
|
1202
|
+
};
|
|
1203
|
+
const mapTimeToKeyframe = interpolate(convertOffsetToTimes(times && times.length === keyframeValues.length ? times : defaultOffset(keyframeValues), duration), keyframeValues, { ease: Array.isArray(easingFunctions) ? easingFunctions : defaultEasing(keyframeValues, easingFunctions) });
|
|
1204
|
+
return {
|
|
1205
|
+
calculatedDuration: duration,
|
|
1206
|
+
next: (t) => {
|
|
1207
|
+
state.value = mapTimeToKeyframe(t);
|
|
1208
|
+
state.done = t >= duration;
|
|
1209
|
+
return state;
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
//#endregion
|
|
1214
|
+
//#region src/engine.ts
|
|
1215
|
+
function validateTransition(t) {
|
|
1216
|
+
if (t.type === "spring" && (t.duration !== void 0 || t.ease !== void 0)) throw new Error("motion: physical springs do not accept duration or ease");
|
|
1217
|
+
const allowed = [
|
|
1218
|
+
"type",
|
|
1219
|
+
"duration",
|
|
1220
|
+
"delay",
|
|
1221
|
+
"ease",
|
|
1222
|
+
"stiffness",
|
|
1223
|
+
"damping",
|
|
1224
|
+
"mass",
|
|
1225
|
+
"velocity",
|
|
1226
|
+
"restSpeed",
|
|
1227
|
+
"restDelta"
|
|
1228
|
+
];
|
|
1229
|
+
for (const key of Object.keys(t)) if (!allowed.includes(key)) throw new Error(`motion: unsupported transition ${key}`);
|
|
1230
|
+
if (t.type !== void 0 && t.type !== "tween" && t.type !== "spring") throw new Error("motion: unsupported transition type");
|
|
1231
|
+
for (const key of [
|
|
1232
|
+
"duration",
|
|
1233
|
+
"delay",
|
|
1234
|
+
"stiffness",
|
|
1235
|
+
"damping",
|
|
1236
|
+
"mass",
|
|
1237
|
+
"velocity",
|
|
1238
|
+
"restSpeed",
|
|
1239
|
+
"restDelta"
|
|
1240
|
+
]) {
|
|
1241
|
+
const value = t[key];
|
|
1242
|
+
if (value !== void 0 && (!Number.isFinite(value) || key !== "velocity" && value < 0)) throw new Error(`motion: invalid ${key}`);
|
|
1243
|
+
}
|
|
1244
|
+
for (const key of [
|
|
1245
|
+
"mass",
|
|
1246
|
+
"stiffness",
|
|
1247
|
+
"damping",
|
|
1248
|
+
"restSpeed",
|
|
1249
|
+
"restDelta"
|
|
1250
|
+
]) if (t[key] === 0) throw new Error(`motion: ${key} must be positive`);
|
|
1251
|
+
if (t.ease !== void 0) {
|
|
1252
|
+
if (Array.isArray(t.ease)) {
|
|
1253
|
+
if (t.ease.length !== 4 || !t.ease.every(Number.isFinite) || t.ease[0] < 0 || t.ease[0] > 1 || t.ease[2] < 0 || t.ease[2] > 1) throw new Error("motion: invalid cubic Bezier");
|
|
1254
|
+
} else if (![
|
|
1255
|
+
"linear",
|
|
1256
|
+
"easeIn",
|
|
1257
|
+
"easeOut",
|
|
1258
|
+
"easeInOut"
|
|
1259
|
+
].includes(t.ease)) throw new Error("motion: unsupported easing");
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
function runAnimation(clock, from, to, transition, update, complete) {
|
|
1263
|
+
validateTransition(transition);
|
|
1264
|
+
let frame = 0;
|
|
1265
|
+
let settled = false;
|
|
1266
|
+
let resolve;
|
|
1267
|
+
const finished = new Promise((done) => {
|
|
1268
|
+
resolve = done;
|
|
1269
|
+
});
|
|
1270
|
+
const settle = (result) => {
|
|
1271
|
+
if (settled) return;
|
|
1272
|
+
settled = true;
|
|
1273
|
+
clock.cancel(frame);
|
|
1274
|
+
resolve(result);
|
|
1275
|
+
if (result === "finished") complete?.();
|
|
1276
|
+
};
|
|
1277
|
+
const duration = transition.duration ?? .3;
|
|
1278
|
+
const generator = transition.type === "spring" ? spring({
|
|
1279
|
+
keyframes: [from, to],
|
|
1280
|
+
stiffness: transition.stiffness ?? 100,
|
|
1281
|
+
damping: transition.damping ?? 10,
|
|
1282
|
+
mass: transition.mass ?? 1,
|
|
1283
|
+
velocity: transition.velocity ?? 0,
|
|
1284
|
+
restSpeed: transition.restSpeed,
|
|
1285
|
+
restDelta: transition.restDelta
|
|
1286
|
+
}) : keyframes({
|
|
1287
|
+
keyframes: [from, to],
|
|
1288
|
+
duration: duration * 1e3,
|
|
1289
|
+
ease: transition.ease ?? "easeInOut"
|
|
1290
|
+
});
|
|
1291
|
+
const start = clock.now() + (transition.delay ?? 0) * 1e3;
|
|
1292
|
+
const tick = () => {
|
|
1293
|
+
if (settled) return;
|
|
1294
|
+
const elapsed = Math.max(0, clock.now() - start);
|
|
1295
|
+
if (clock.now() >= start) {
|
|
1296
|
+
const state = generator.next(elapsed);
|
|
1297
|
+
update(state.done ? to : state.value);
|
|
1298
|
+
if (state.done) {
|
|
1299
|
+
settle("finished");
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
if (!settled) frame = clock.request(tick);
|
|
1304
|
+
};
|
|
1305
|
+
if (transition.type !== "spring" && duration === 0 && !transition.delay) {
|
|
1306
|
+
update(to);
|
|
1307
|
+
settle("finished");
|
|
1308
|
+
} else frame = clock.request(tick);
|
|
1309
|
+
return {
|
|
1310
|
+
finished,
|
|
1311
|
+
stop: (reason = "cancelled") => settle(reason)
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
//#endregion
|
|
1315
|
+
//#region src/value.ts
|
|
1316
|
+
/** Numeric value with direct subscriptions; it does not subscribe Octane renders. */
|
|
1317
|
+
var MotionValue = class {
|
|
1318
|
+
clock;
|
|
1319
|
+
current;
|
|
1320
|
+
previous;
|
|
1321
|
+
velocity = 0;
|
|
1322
|
+
updated;
|
|
1323
|
+
controls;
|
|
1324
|
+
generation = 0;
|
|
1325
|
+
listeners = /* @__PURE__ */ new Map();
|
|
1326
|
+
passive;
|
|
1327
|
+
disposed = false;
|
|
1328
|
+
constructor(initial, clock) {
|
|
1329
|
+
this.clock = clock;
|
|
1330
|
+
this.assert(initial);
|
|
1331
|
+
this.current = this.previous = initial;
|
|
1332
|
+
this.updated = clock.now();
|
|
1333
|
+
}
|
|
1334
|
+
assert(value) {
|
|
1335
|
+
if (!Number.isFinite(value)) throw new Error("motion: values must be finite numbers");
|
|
1336
|
+
}
|
|
1337
|
+
/** Read the current sample. */
|
|
1338
|
+
get() {
|
|
1339
|
+
return this.current;
|
|
1340
|
+
}
|
|
1341
|
+
/** Read the previous sample. */
|
|
1342
|
+
getPrevious() {
|
|
1343
|
+
return this.previous;
|
|
1344
|
+
}
|
|
1345
|
+
/** Velocity in units per second; stale samples have zero velocity. */
|
|
1346
|
+
getVelocity() {
|
|
1347
|
+
return this.clock.now() - this.updated > 30 ? 0 : this.velocity;
|
|
1348
|
+
}
|
|
1349
|
+
/** Set immediately, or animate when this is a useSpring value. */
|
|
1350
|
+
set(value) {
|
|
1351
|
+
this.assert(value);
|
|
1352
|
+
if (this.disposed) return;
|
|
1353
|
+
if (this.passive) this.passive(value);
|
|
1354
|
+
else {
|
|
1355
|
+
this.stop();
|
|
1356
|
+
this.write(value);
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
/** Snap and stop current playback, resetting velocity. */
|
|
1360
|
+
jump(value) {
|
|
1361
|
+
this.assert(value);
|
|
1362
|
+
this.stop();
|
|
1363
|
+
this.write(value);
|
|
1364
|
+
this.velocity = 0;
|
|
1365
|
+
}
|
|
1366
|
+
/** Subscribe without causing a component render. Returns an unsubscribe function. */
|
|
1367
|
+
on(event, callback) {
|
|
1368
|
+
let listeners = this.listeners.get(event);
|
|
1369
|
+
if (!listeners) this.listeners.set(event, listeners = /* @__PURE__ */ new Set());
|
|
1370
|
+
listeners.add(callback);
|
|
1371
|
+
return () => {
|
|
1372
|
+
listeners.delete(callback);
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
emit(event, value) {
|
|
1376
|
+
for (const callback of [...this.listeners.get(event) ?? []]) callback(value);
|
|
1377
|
+
}
|
|
1378
|
+
write(value) {
|
|
1379
|
+
if (this.disposed) return;
|
|
1380
|
+
const now = this.clock.now();
|
|
1381
|
+
const elapsed = now - this.updated;
|
|
1382
|
+
if (elapsed > 0) this.velocity = elapsed > 30 ? 0 : (value - this.current) * 1e3 / elapsed;
|
|
1383
|
+
this.previous = this.current;
|
|
1384
|
+
this.current = value;
|
|
1385
|
+
this.updated = now;
|
|
1386
|
+
if (value !== this.previous) this.emit("change", value);
|
|
1387
|
+
}
|
|
1388
|
+
/** Animate to a destination. New playback replaces old playback. */
|
|
1389
|
+
animate(target, transition = {}) {
|
|
1390
|
+
this.assert(target);
|
|
1391
|
+
validateTransition(transition);
|
|
1392
|
+
if (this.disposed) return {
|
|
1393
|
+
finished: Promise.resolve("cancelled"),
|
|
1394
|
+
stop() {}
|
|
1395
|
+
};
|
|
1396
|
+
const velocity = transition.velocity ?? this.getVelocity();
|
|
1397
|
+
this.stop("replaced");
|
|
1398
|
+
const generation = ++this.generation;
|
|
1399
|
+
this.emit("animationStart");
|
|
1400
|
+
const controls = runAnimation(this.clock, this.current, target, {
|
|
1401
|
+
...transition,
|
|
1402
|
+
velocity
|
|
1403
|
+
}, (value) => this.write(value));
|
|
1404
|
+
this.controls = controls;
|
|
1405
|
+
controls.finished.then((result) => {
|
|
1406
|
+
if (generation !== this.generation || this.disposed) return;
|
|
1407
|
+
this.controls = void 0;
|
|
1408
|
+
if (result === "finished") this.emit("animationComplete");
|
|
1409
|
+
});
|
|
1410
|
+
return controls;
|
|
1411
|
+
}
|
|
1412
|
+
/** Stop playback at its current value. */
|
|
1413
|
+
stop(reason = "cancelled") {
|
|
1414
|
+
++this.generation;
|
|
1415
|
+
if (this.controls) {
|
|
1416
|
+
this.controls.stop(reason);
|
|
1417
|
+
this.controls = void 0;
|
|
1418
|
+
this.emit("animationCancel");
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
/** Release playback and listeners when the owning component unmounts. */
|
|
1422
|
+
destroy() {
|
|
1423
|
+
this.stop();
|
|
1424
|
+
this.emit("destroy");
|
|
1425
|
+
this.listeners.clear();
|
|
1426
|
+
this.passive = void 0;
|
|
1427
|
+
this.disposed = true;
|
|
1428
|
+
}
|
|
1429
|
+
/** @internal Install the useSpring setter interception. */
|
|
1430
|
+
attach(setter) {
|
|
1431
|
+
this.passive = setter;
|
|
1432
|
+
return () => {
|
|
1433
|
+
this.passive = void 0;
|
|
1434
|
+
this.stop();
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
//#endregion
|
|
1439
|
+
//#region src/controller.ts
|
|
1440
|
+
var keys = [
|
|
1441
|
+
"opacity",
|
|
1442
|
+
"x",
|
|
1443
|
+
"y",
|
|
1444
|
+
"scale",
|
|
1445
|
+
"scaleX",
|
|
1446
|
+
"scaleY",
|
|
1447
|
+
"rotate"
|
|
1448
|
+
];
|
|
1449
|
+
var defaults = {
|
|
1450
|
+
opacity: 1,
|
|
1451
|
+
x: 0,
|
|
1452
|
+
y: 0,
|
|
1453
|
+
scale: 1,
|
|
1454
|
+
scaleX: 1,
|
|
1455
|
+
scaleY: 1,
|
|
1456
|
+
rotate: 0
|
|
1457
|
+
};
|
|
1458
|
+
function validateTarget(target) {
|
|
1459
|
+
for (const [key, value] of Object.entries(target ?? {})) if (!keys.includes(key) || !Number.isFinite(value)) throw new Error(`motion: unsupported target ${key}; expected a finite numeric motion channel`);
|
|
1460
|
+
}
|
|
1461
|
+
var Controller = class {
|
|
1462
|
+
clock;
|
|
1463
|
+
values = /* @__PURE__ */ new Map();
|
|
1464
|
+
write;
|
|
1465
|
+
generation = 0;
|
|
1466
|
+
constructor(clock) {
|
|
1467
|
+
this.clock = clock;
|
|
1468
|
+
}
|
|
1469
|
+
value(key) {
|
|
1470
|
+
let value = this.values.get(key);
|
|
1471
|
+
if (!value) {
|
|
1472
|
+
value = new MotionValue(defaults[key], this.clock);
|
|
1473
|
+
this.values.set(key, value);
|
|
1474
|
+
value.on("change", () => this.flush());
|
|
1475
|
+
}
|
|
1476
|
+
return value;
|
|
1477
|
+
}
|
|
1478
|
+
attach(write) {
|
|
1479
|
+
this.write = write;
|
|
1480
|
+
this.flush();
|
|
1481
|
+
}
|
|
1482
|
+
snapshot() {
|
|
1483
|
+
return Object.fromEntries([...this.values].map(([key, value]) => [key, value.get()]));
|
|
1484
|
+
}
|
|
1485
|
+
flush() {
|
|
1486
|
+
this.write?.(Object.fromEntries([...this.values].map(([key, value]) => [key, value.get()])));
|
|
1487
|
+
}
|
|
1488
|
+
set(key, next) {
|
|
1489
|
+
this.value(key).jump(next);
|
|
1490
|
+
}
|
|
1491
|
+
seed(target) {
|
|
1492
|
+
validateTarget(target);
|
|
1493
|
+
for (const [key, value] of Object.entries(target)) this.set(key, value);
|
|
1494
|
+
}
|
|
1495
|
+
async animate(target, transition, reduced) {
|
|
1496
|
+
validateTarget(target);
|
|
1497
|
+
const generation = ++this.generation;
|
|
1498
|
+
for (const value of this.values.values()) value.stop("replaced");
|
|
1499
|
+
const jobs = Object.entries(target).map(([key, to]) => {
|
|
1500
|
+
return this.value(key).animate(to, reduced && key !== "opacity" ? { duration: 0 } : transition).finished;
|
|
1501
|
+
});
|
|
1502
|
+
const results = await Promise.all(jobs);
|
|
1503
|
+
if (generation !== this.generation) return "replaced";
|
|
1504
|
+
return results.every((result) => result === "finished") ? "finished" : "cancelled";
|
|
1505
|
+
}
|
|
1506
|
+
stop() {
|
|
1507
|
+
++this.generation;
|
|
1508
|
+
for (const value of this.values.values()) value.stop();
|
|
1509
|
+
}
|
|
1510
|
+
destroy() {
|
|
1511
|
+
this.stop();
|
|
1512
|
+
for (const value of this.values.values()) value.destroy();
|
|
1513
|
+
this.values.clear();
|
|
1514
|
+
this.write = void 0;
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
//#endregion
|
|
1518
|
+
//#region src/components.tsrx
|
|
1519
|
+
var _t$0 = /* @__PURE__ */ template("<!>", 0, 1);
|
|
1520
|
+
var _hs$$1 = /* @__PURE__ */ hookSlots(16);
|
|
1521
|
+
var _h$0$1 = /* @__PURE__ */ Symbol(_hs$$1);
|
|
1522
|
+
var _h$1$1 = /* @__PURE__ */ Symbol(_hs$$1 + 1);
|
|
1523
|
+
var _h$2$1 = /* @__PURE__ */ Symbol(_hs$$1 + 2);
|
|
1524
|
+
var _h$3$1 = /* @__PURE__ */ Symbol(_hs$$1 + 3);
|
|
1525
|
+
var _h$4$1 = /* @__PURE__ */ Symbol(_hs$$1 + 4);
|
|
1526
|
+
var _h$5$1 = /* @__PURE__ */ Symbol(_hs$$1 + 5);
|
|
1527
|
+
var _h$6$1 = /* @__PURE__ */ Symbol(_hs$$1 + 6);
|
|
1528
|
+
var _h$7$1 = /* @__PURE__ */ Symbol(_hs$$1 + 7);
|
|
1529
|
+
var _h$8 = /* @__PURE__ */ Symbol(_hs$$1 + 8);
|
|
1530
|
+
var _h$9 = /* @__PURE__ */ Symbol(_hs$$1 + 9);
|
|
1531
|
+
var _h$10 = /* @__PURE__ */ Symbol(_hs$$1 + 10);
|
|
1532
|
+
var _h$11 = /* @__PURE__ */ Symbol(_hs$$1 + 11);
|
|
1533
|
+
var _h$12 = /* @__PURE__ */ Symbol(_hs$$1 + 12);
|
|
1534
|
+
var _h$13 = /* @__PURE__ */ Symbol(_hs$$1 + 13);
|
|
1535
|
+
var _h$14 = /* @__PURE__ */ Symbol(_hs$$1 + 14);
|
|
1536
|
+
var _h$15 = /* @__PURE__ */ Symbol(_hs$$1 + 15);
|
|
1537
|
+
var __childrenBody = {};
|
|
1538
|
+
var __childrenBody$ = {};
|
|
1539
|
+
var __childrenBody$2 = {};
|
|
1540
|
+
function useMotion(props) {
|
|
1541
|
+
for (const name of [
|
|
1542
|
+
"drag",
|
|
1543
|
+
"layout",
|
|
1544
|
+
"layoutId",
|
|
1545
|
+
"variants",
|
|
1546
|
+
"whileTap",
|
|
1547
|
+
"whileHover",
|
|
1548
|
+
"whileFocus",
|
|
1549
|
+
"whileInView"
|
|
1550
|
+
]) if (name in props) throw new Error(`motion: ${name} is outside the supported subset`);
|
|
1551
|
+
const presence = useContext(PresenceContext);
|
|
1552
|
+
if (props.exit && !presence) throw new Error("motion: exit requires a mounted Presence boundary");
|
|
1553
|
+
const config = useContext(ConfigContext);
|
|
1554
|
+
const systemReduced = withSlot(_h$0$1, useReducedMotion);
|
|
1555
|
+
const reduced = config.reducedMotion === "always" || config.reducedMotion === "user" && systemReduced;
|
|
1556
|
+
const transition = props.transition ?? config.transition ?? {};
|
|
1557
|
+
validateTransition(transition);
|
|
1558
|
+
validateTarget(props.animate);
|
|
1559
|
+
validateTarget(props.exit);
|
|
1560
|
+
if (props.initial !== false) validateTarget(props.initial);
|
|
1561
|
+
const latest = useRef(props, _h$1$1);
|
|
1562
|
+
latest.current = props;
|
|
1563
|
+
const state = useRef(null, _h$2$1);
|
|
1564
|
+
if (!state.current) state.current = {
|
|
1565
|
+
controller: new Controller(clock),
|
|
1566
|
+
initialized: false
|
|
1567
|
+
};
|
|
1568
|
+
const current = state.current;
|
|
1569
|
+
const style = {};
|
|
1570
|
+
const bindings = [];
|
|
1571
|
+
for (const [key, value] of Object.entries(props.style ?? {})) if (keys.includes(key)) {
|
|
1572
|
+
if (!(value instanceof MotionValue) && (typeof value !== "number" || !Number.isFinite(value))) throw new Error(`motion: invalid style ${key}`);
|
|
1573
|
+
if (value instanceof MotionValue && (props.animate?.[key] !== void 0 || props.exit?.[key] !== void 0 || props.initial && props.initial[key] !== void 0)) throw new Error(`motion: ${key} has both an animate target and a MotionValue writer`);
|
|
1574
|
+
bindings.push([key, value]);
|
|
1575
|
+
} else {
|
|
1576
|
+
if (value instanceof MotionValue || [
|
|
1577
|
+
"transform",
|
|
1578
|
+
"translateX",
|
|
1579
|
+
"translateY",
|
|
1580
|
+
"animation",
|
|
1581
|
+
"transition"
|
|
1582
|
+
].includes(key)) throw new Error(`motion: unsupported or conflicting style ${key}`);
|
|
1583
|
+
style[key] = value;
|
|
1584
|
+
}
|
|
1585
|
+
const previous = useRef(bindings, _h$3$1);
|
|
1586
|
+
const boundKeys = useRef([], _h$4$1);
|
|
1587
|
+
const firstBinding = useRef(true, _h$5$1);
|
|
1588
|
+
const firstAnimation = useRef(true, _h$6$1);
|
|
1589
|
+
if (previous.current.length !== bindings.length || previous.current.some(([key, value], i) => key !== bindings[i][0] || value !== bindings[i][1])) previous.current = bindings;
|
|
1590
|
+
const bind = useRef(() => {}, _h$7$1);
|
|
1591
|
+
bind.current = (host) => {
|
|
1592
|
+
if (!host) return;
|
|
1593
|
+
if (current.host !== host) {
|
|
1594
|
+
current.adapter?.restore();
|
|
1595
|
+
current.host = host;
|
|
1596
|
+
current.adapter = attachHost(host);
|
|
1597
|
+
if (!current.initialized) {
|
|
1598
|
+
const baseline = current.adapter.read();
|
|
1599
|
+
for (const [key, value] of previous.current) baseline[key] = value instanceof MotionValue ? value.get() : value;
|
|
1600
|
+
current.controller.seed(baseline);
|
|
1601
|
+
current.controller.seed(props.initial === false ? props.animate ?? {} : props.initial ?? {});
|
|
1602
|
+
current.initialized = true;
|
|
1603
|
+
}
|
|
1604
|
+
current.controller.attach(current.adapter.write);
|
|
1605
|
+
}
|
|
1606
|
+
current.controller.flush();
|
|
1607
|
+
latest.current.bind?.(host);
|
|
1608
|
+
};
|
|
1609
|
+
const playback = useRef({
|
|
1610
|
+
transition,
|
|
1611
|
+
reduced
|
|
1612
|
+
}, _h$8);
|
|
1613
|
+
playback.current = {
|
|
1614
|
+
transition,
|
|
1615
|
+
reduced
|
|
1616
|
+
};
|
|
1617
|
+
const returning = useRef(null, _h$9);
|
|
1618
|
+
const member = useRef(null, _h$10);
|
|
1619
|
+
if (!member.current) member.current = {
|
|
1620
|
+
exit() {
|
|
1621
|
+
const snapshot = current.controller.snapshot();
|
|
1622
|
+
returning.current ??= {};
|
|
1623
|
+
for (const key of Object.keys(latest.current.exit ?? {})) if (!(key in returning.current)) returning.current[key] = snapshot[key];
|
|
1624
|
+
return current.controller.animate(latest.current.exit ?? {}, playback.current.transition, playback.current.reduced);
|
|
1625
|
+
},
|
|
1626
|
+
enter() {
|
|
1627
|
+
const target = {
|
|
1628
|
+
...returning.current,
|
|
1629
|
+
...latest.current.animate
|
|
1630
|
+
};
|
|
1631
|
+
returning.current = null;
|
|
1632
|
+
current.controller.animate(target, playback.current.transition, playback.current.reduced).then((result) => {
|
|
1633
|
+
if (result === "finished" && current.host && presence?.present) latest.current.onAnimationComplete?.();
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1636
|
+
};
|
|
1637
|
+
useLayoutEffect(() => presence?.register(member.current), [presence], _h$11);
|
|
1638
|
+
const stableBind = useRef((host) => bind.current(host), _h$12).current;
|
|
1639
|
+
useLayoutEffect(() => () => {
|
|
1640
|
+
current.controller.destroy();
|
|
1641
|
+
current.host = void 0;
|
|
1642
|
+
current.adapter = void 0;
|
|
1643
|
+
}, [], _h$13);
|
|
1644
|
+
useLayoutEffect(() => {
|
|
1645
|
+
const off = [];
|
|
1646
|
+
for (const key of boundKeys.current) if (!previous.current.some(([next]) => key === next)) current.controller.set(key, defaults[key]);
|
|
1647
|
+
boundKeys.current = previous.current.map(([key]) => key);
|
|
1648
|
+
for (const [key, value] of previous.current) {
|
|
1649
|
+
if (!firstBinding.current) current.controller.set(key, value instanceof MotionValue ? value.get() : value);
|
|
1650
|
+
if (value instanceof MotionValue) off.push(value.on("change", (next) => current.controller.set(key, next)));
|
|
1651
|
+
}
|
|
1652
|
+
firstBinding.current = false;
|
|
1653
|
+
return () => off.forEach((unsubscribe) => unsubscribe());
|
|
1654
|
+
}, [previous.current], _h$14);
|
|
1655
|
+
useLayoutEffect(() => {
|
|
1656
|
+
let active = true;
|
|
1657
|
+
const skip = firstAnimation.current && props.initial === false;
|
|
1658
|
+
firstAnimation.current = false;
|
|
1659
|
+
if (presence && !presence.present) presence.restart(member.current);
|
|
1660
|
+
else if (props.animate && !skip) current.controller.animate(props.animate, transition, reduced).then((result) => {
|
|
1661
|
+
if (active && result === "finished") latest.current.onAnimationComplete?.();
|
|
1662
|
+
});
|
|
1663
|
+
return () => {
|
|
1664
|
+
active = false;
|
|
1665
|
+
current.controller.stop();
|
|
1666
|
+
};
|
|
1667
|
+
}, [
|
|
1668
|
+
JSON.stringify(props.animate),
|
|
1669
|
+
JSON.stringify(props.exit),
|
|
1670
|
+
JSON.stringify(transition),
|
|
1671
|
+
reduced
|
|
1672
|
+
], _h$15);
|
|
1673
|
+
const { initial, exit, animate, transition: ignoredTransition, onAnimationComplete, style: ignoredStyle, bind: ignoredBind, ...rest } = props;
|
|
1674
|
+
return {
|
|
1675
|
+
...rest,
|
|
1676
|
+
style,
|
|
1677
|
+
bind: stableBind
|
|
1678
|
+
};
|
|
1679
|
+
}
|
|
1680
|
+
var MotionView = function MotionView(props, __s, __extra) {
|
|
1681
|
+
const __block = __s.block;
|
|
1682
|
+
function __children$1(__props, __s, __extra) {
|
|
1683
|
+
const __block = __s.block;
|
|
1684
|
+
let _b = __s.slots[0];
|
|
1685
|
+
if (_b === void 0) {
|
|
1686
|
+
let _m0, _m1;
|
|
1687
|
+
const _root = clone(_t$0);
|
|
1688
|
+
_m0 = __block.parentNode;
|
|
1689
|
+
_m1 = child(_root);
|
|
1690
|
+
drainFrag(_root, __block.parentNode, __block.endMarker);
|
|
1691
|
+
_b = bag4(__s, null, _m0, _m1, null, void 0);
|
|
1692
|
+
}
|
|
1693
|
+
{
|
|
1694
|
+
const _v = props.children;
|
|
1695
|
+
_b.c = textHoleUpdate(__s, 1, _b.a, _v, _b.c, _b.d, _b.b, true, true);
|
|
1696
|
+
_b.d = _v;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
componentSlot(__s, 0, __block.parentNode, View, {
|
|
1700
|
+
...useMotion(props),
|
|
1701
|
+
"children": markChildrenBlock(__children$1, __childrenBody)
|
|
1702
|
+
}, __block.endMarker, void 0, void 0, true, void 0, "c:074db42c");
|
|
1703
|
+
};
|
|
1704
|
+
var MotionRow = function MotionRow(props, __s, __extra) {
|
|
1705
|
+
const __block = __s.block;
|
|
1706
|
+
function __children$4(__props, __s, __extra) {
|
|
1707
|
+
const __block = __s.block;
|
|
1708
|
+
let _b = __s.slots[0];
|
|
1709
|
+
if (_b === void 0) {
|
|
1710
|
+
let _m0, _m1;
|
|
1711
|
+
const _root = clone(_t$0);
|
|
1712
|
+
_m0 = __block.parentNode;
|
|
1713
|
+
_m1 = child(_root);
|
|
1714
|
+
drainFrag(_root, __block.parentNode, __block.endMarker);
|
|
1715
|
+
_b = bag4(__s, null, _m0, _m1, null, void 0);
|
|
1716
|
+
}
|
|
1717
|
+
{
|
|
1718
|
+
const _v = props.children;
|
|
1719
|
+
_b.c = textHoleUpdate(__s, 1, _b.a, _v, _b.c, _b.d, _b.b, true, true);
|
|
1720
|
+
_b.d = _v;
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
componentSlot(__s, 0, __block.parentNode, Row, {
|
|
1724
|
+
...useMotion(props),
|
|
1725
|
+
"children": markChildrenBlock(__children$4, __childrenBody$)
|
|
1726
|
+
}, __block.endMarker, void 0, void 0, true, void 0, "c:bfd4d1a7");
|
|
1727
|
+
};
|
|
1728
|
+
var MotionPressable = function MotionPressable(props, __s, __extra) {
|
|
1729
|
+
const __block = __s.block;
|
|
1730
|
+
function __children$7(__props, __s, __extra) {
|
|
1731
|
+
const __block = __s.block;
|
|
1732
|
+
let _b = __s.slots[0];
|
|
1733
|
+
if (_b === void 0) {
|
|
1734
|
+
let _m0, _m1;
|
|
1735
|
+
const _root = clone(_t$0);
|
|
1736
|
+
_m0 = __block.parentNode;
|
|
1737
|
+
_m1 = child(_root);
|
|
1738
|
+
drainFrag(_root, __block.parentNode, __block.endMarker);
|
|
1739
|
+
_b = bag4(__s, null, _m0, _m1, null, void 0);
|
|
1740
|
+
}
|
|
1741
|
+
{
|
|
1742
|
+
const _v = props.children;
|
|
1743
|
+
_b.c = textHoleUpdate(__s, 1, _b.a, _v, _b.c, _b.d, _b.b, true, true);
|
|
1744
|
+
_b.d = _v;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
componentSlot(__s, 0, __block.parentNode, Pressable, {
|
|
1748
|
+
...useMotion(props),
|
|
1749
|
+
"children": markChildrenBlock(__children$7, __childrenBody$2)
|
|
1750
|
+
}, __block.endMarker, void 0, void 0, true, void 0, "c:55d0b7c5");
|
|
1751
|
+
};
|
|
1752
|
+
//#endregion
|
|
1753
|
+
//#region src/hooks.tsrx
|
|
1754
|
+
var _hs$ = /* @__PURE__ */ hookSlots(8);
|
|
1755
|
+
var _h$0 = /* @__PURE__ */ Symbol(_hs$);
|
|
1756
|
+
var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
|
|
1757
|
+
var _h$2 = /* @__PURE__ */ Symbol(_hs$ + 2);
|
|
1758
|
+
var _h$3 = /* @__PURE__ */ Symbol(_hs$ + 3);
|
|
1759
|
+
var _h$4 = /* @__PURE__ */ Symbol(_hs$ + 4);
|
|
1760
|
+
var _h$5 = /* @__PURE__ */ Symbol(_hs$ + 5);
|
|
1761
|
+
var _h$6 = /* @__PURE__ */ Symbol(_hs$ + 6);
|
|
1762
|
+
var _h$7 = /* @__PURE__ */ Symbol(_hs$ + 7);
|
|
1763
|
+
function useMotionValue(initial) {
|
|
1764
|
+
const ref = useRef(null, _h$0);
|
|
1765
|
+
if (!ref.current) ref.current = new MotionValue(initial, clock);
|
|
1766
|
+
const value = ref.current;
|
|
1767
|
+
useLayoutEffect(() => () => value.destroy(), [], _h$1);
|
|
1768
|
+
return value;
|
|
1769
|
+
}
|
|
1770
|
+
function useMotionValueEvent(value, event, callback) {
|
|
1771
|
+
useLayoutEffect(() => value.on(event, callback), [
|
|
1772
|
+
value,
|
|
1773
|
+
event,
|
|
1774
|
+
callback
|
|
1775
|
+
], _h$2);
|
|
1776
|
+
}
|
|
1777
|
+
function useTransform(source, input, output, options) {
|
|
1778
|
+
const sources = Array.isArray(source) ? source : [source];
|
|
1779
|
+
if (Array.isArray(input) && (!output || input.length !== output.length || input.length < 2)) throw new Error("motion: transform ranges must have matching lengths >= 2");
|
|
1780
|
+
const transform = typeof input === "function" ? input : interpolate(input, output, options);
|
|
1781
|
+
const read = () => transform(Array.isArray(source) ? sources.map((value) => value.get()) : source.get());
|
|
1782
|
+
const value = withSlot(_h$3, useMotionValue, read());
|
|
1783
|
+
const previous = useRef(sources, _h$4);
|
|
1784
|
+
if (previous.current.length !== sources.length || previous.current.some((value, i) => value !== sources[i])) previous.current = sources;
|
|
1785
|
+
useLayoutEffect(() => {
|
|
1786
|
+
const update = () => value.set(read());
|
|
1787
|
+
const off = sources.map((source) => source.on("change", update));
|
|
1788
|
+
update();
|
|
1789
|
+
return () => off.forEach((unsubscribe) => unsubscribe());
|
|
1790
|
+
}, [
|
|
1791
|
+
previous.current,
|
|
1792
|
+
input,
|
|
1793
|
+
output,
|
|
1794
|
+
options?.clamp
|
|
1795
|
+
], _h$5);
|
|
1796
|
+
return value;
|
|
1797
|
+
}
|
|
1798
|
+
function useSpring(source, options = {}) {
|
|
1799
|
+
const value = withSlot(_h$6, useMotionValue, source instanceof MotionValue ? source.get() : source);
|
|
1800
|
+
useLayoutEffect(() => {
|
|
1801
|
+
const follow = (target) => {
|
|
1802
|
+
value.animate(target, {
|
|
1803
|
+
...options,
|
|
1804
|
+
type: "spring"
|
|
1805
|
+
});
|
|
1806
|
+
};
|
|
1807
|
+
const detach = value.attach(follow);
|
|
1808
|
+
const unsubscribe = source instanceof MotionValue ? source.on("change", follow) : void 0;
|
|
1809
|
+
if (source instanceof MotionValue && source.get() !== value.get()) follow(source.get());
|
|
1810
|
+
return () => {
|
|
1811
|
+
unsubscribe?.();
|
|
1812
|
+
detach();
|
|
1813
|
+
};
|
|
1814
|
+
}, [source instanceof MotionValue ? source : null, JSON.stringify(options)], _h$7);
|
|
1815
|
+
return value;
|
|
1816
|
+
}
|
|
1817
|
+
//#endregion
|
|
1818
|
+
//#region src/index.web.ts
|
|
1819
|
+
/** Bounded motion hosts for shared xplat UI primitives. */
|
|
1820
|
+
var motion = {
|
|
1821
|
+
View: MotionView,
|
|
1822
|
+
Row: MotionRow,
|
|
1823
|
+
Pressable: MotionPressable
|
|
1824
|
+
};
|
|
1825
|
+
//#endregion
|
|
1826
|
+
export { MotionConfig, Presence, motion, useMotionValue, useMotionValueEvent, useReducedMotion, useSpring, useTransform };
|