@helsenorge/designsystem-react 10.0.2 → 10.2.0

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.
Files changed (181) hide show
  1. package/AnchorLink.js +2 -2
  2. package/AnchorLink.js.map +1 -1
  3. package/Avatar.js +2 -2
  4. package/Avatar.js.map +1 -1
  5. package/Badge.js +3 -3
  6. package/Badge.js.map +1 -1
  7. package/Button.js +4 -4
  8. package/Button.js.map +1 -1
  9. package/CHANGELOG.md +38 -0
  10. package/Checkbox.js +2 -2
  11. package/Checkbox.js.map +1 -1
  12. package/Close.js +2 -2
  13. package/Close.js.map +1 -1
  14. package/ErrorBoundary.js +2 -2
  15. package/ErrorBoundary.js.map +1 -1
  16. package/Expander.js +2 -2
  17. package/Expander.js.map +1 -1
  18. package/FormGroup.js +12 -12
  19. package/FormGroup.js.map +1 -1
  20. package/FormLayout.js +3 -3
  21. package/FormLayout.js.map +1 -1
  22. package/HelpBubble.js +2 -2
  23. package/HelpBubble.js.map +1 -1
  24. package/HighlightPanel.js +2 -2
  25. package/HighlightPanel.js.map +1 -1
  26. package/Icon.js +3 -3
  27. package/Icon.js.map +1 -1
  28. package/Illustration.js +3 -3
  29. package/Illustration.js.map +1 -1
  30. package/Input.js +2 -2
  31. package/Input.js.map +1 -1
  32. package/Label.js +8 -8
  33. package/Label.js.map +1 -1
  34. package/LazyIcon.js +1 -1
  35. package/LazyIllustration.js +3 -3
  36. package/LazyIllustration.js.map +1 -1
  37. package/LinkList.js +6 -6
  38. package/LinkList.js.map +1 -1
  39. package/ListHeader.js +7 -7
  40. package/ListHeader.js.map +1 -1
  41. package/Panel.js +2 -2
  42. package/Panel.js.map +1 -1
  43. package/PopOver.js +2 -2
  44. package/PopOver.js.map +1 -1
  45. package/RadioButton.js +2 -2
  46. package/RadioButton.js.map +1 -1
  47. package/Select.js +2 -2
  48. package/Select.js.map +1 -1
  49. package/Slider.js +3 -3
  50. package/Slider.js.map +1 -1
  51. package/Spacer.js +2 -2
  52. package/Spacer.js.map +1 -1
  53. package/StatusDot.js +1 -1
  54. package/StepButtons.js +4 -4
  55. package/StepButtons.js.map +1 -1
  56. package/TabList.js +4 -4
  57. package/TabList.js.map +1 -1
  58. package/Table.js +2 -2
  59. package/Table.js.map +1 -1
  60. package/TableBody.js +2 -2
  61. package/TableBody.js.map +1 -1
  62. package/TableExpandedRow.js +2 -2
  63. package/TableExpandedRow.js.map +1 -1
  64. package/TableHead.js +2 -2
  65. package/TableHead.js.map +1 -1
  66. package/TableRow.js +2 -2
  67. package/TableRow.js.map +1 -1
  68. package/Textarea.js +2 -2
  69. package/Textarea.js.map +1 -1
  70. package/Title.js +2 -2
  71. package/Title.js.map +1 -1
  72. package/TooltipWord.js +2 -2
  73. package/TooltipWord.js.map +1 -1
  74. package/Trigger.js +3 -3
  75. package/Trigger.js.map +1 -1
  76. package/components/Button/styles.module.scss +5 -0
  77. package/components/DictionaryTrigger/index.js +2 -2
  78. package/components/DictionaryTrigger/index.js.map +1 -1
  79. package/components/Drawer/Drawer.d.ts +41 -0
  80. package/components/Drawer/Drawer.test.d.ts +1 -0
  81. package/components/Drawer/index.d.ts +3 -0
  82. package/components/Drawer/index.js +350 -0
  83. package/components/Drawer/index.js.map +1 -0
  84. package/components/Drawer/styles.module.scss +127 -0
  85. package/components/Drawer/styles.module.scss.d.ts +16 -0
  86. package/components/Dropdown/index.js +3 -3
  87. package/components/Dropdown/index.js.map +1 -1
  88. package/components/Duolist/index.js +4 -4
  89. package/components/Duolist/index.js.map +1 -1
  90. package/components/ExpanderHierarchy/index.js +5 -5
  91. package/components/ExpanderHierarchy/index.js.map +1 -1
  92. package/components/ExpanderList/index.js +8 -8
  93. package/components/ExpanderList/index.js.map +1 -1
  94. package/components/HelpQuestion/index.js +2 -2
  95. package/components/HelpQuestion/index.js.map +1 -1
  96. package/components/HighlightPanel/styles.module.scss +4 -36
  97. package/components/HighlightPanel/styles.module.scss.d.ts +1 -2
  98. package/components/Icons/EuropeanHealthCard.js +1 -1
  99. package/components/Icons/GroupTwins.js +1 -1
  100. package/components/Icons/Inbox.js +1 -1
  101. package/components/Icons/LawBook.js +1 -1
  102. package/components/Icons/PersonCancel.js +1 -1
  103. package/components/Icons/PersonWithBrain.js +1 -1
  104. package/components/Icons/Puzzle.js +1 -1
  105. package/components/Icons/Snapchat.js +1 -1
  106. package/components/Illustrations/IllustrationNames.d.ts +1 -1
  107. package/components/Illustrations/IllustrationNames.js +4 -2
  108. package/components/Illustrations/IllustrationNames.js.map +1 -1
  109. package/components/Illustrations/ReadLetters.d.ts +9 -0
  110. package/components/Illustrations/ReadLetters.js +11 -0
  111. package/components/Illustrations/ReadLetters.js.map +1 -0
  112. package/components/Illustrations/ReadLettersMedium.d.ts +4 -0
  113. package/components/Illustrations/ReadLettersMedium.js +110 -0
  114. package/components/Illustrations/ReadLettersMedium.js.map +1 -0
  115. package/components/Illustrations/Support2.d.ts +9 -0
  116. package/components/Illustrations/Support2.js +11 -0
  117. package/components/Illustrations/Support2.js.map +1 -0
  118. package/components/Illustrations/Support2Medium.d.ts +4 -0
  119. package/components/Illustrations/Support2Medium.js +232 -0
  120. package/components/Illustrations/Support2Medium.js.map +1 -0
  121. package/components/Label/styles.module.scss +16 -12
  122. package/components/Label/styles.module.scss.d.ts +3 -1
  123. package/components/List/styles.module.scss +7 -7
  124. package/components/Modal/index.js +71 -82
  125. package/components/Modal/index.js.map +1 -1
  126. package/components/Modal/styles.module.scss +12 -6
  127. package/components/NotificationPanel/index.js +3 -3
  128. package/components/NotificationPanel/index.js.map +1 -1
  129. package/components/PanelList/index.js +5 -5
  130. package/components/PanelList/index.js.map +1 -1
  131. package/components/PopMenu/index.js +5 -5
  132. package/components/PopMenu/index.js.map +1 -1
  133. package/components/Portal/index.js +3 -3
  134. package/components/Portal/index.js.map +1 -1
  135. package/components/PromoPanel/index.js +2 -2
  136. package/components/PromoPanel/index.js.map +1 -1
  137. package/components/StickyNote/index.js +12 -6
  138. package/components/StickyNote/index.js.map +1 -1
  139. package/components/Tabs/Tabs.d.ts +2 -0
  140. package/components/Tabs/index.js +8 -4
  141. package/components/Tabs/index.js.map +1 -1
  142. package/components/TagList/index.js +2 -2
  143. package/components/TagList/index.js.map +1 -1
  144. package/components/Tile/index.js +6 -6
  145. package/components/Tile/index.js.map +1 -1
  146. package/components/Toggle/index.js +3 -3910
  147. package/components/Toggle/index.js.map +1 -1
  148. package/components/Tooltip/index.js +2 -2
  149. package/components/Tooltip/index.js.map +1 -1
  150. package/components/Validation/index.js +6 -6
  151. package/components/Validation/index.js.map +1 -1
  152. package/constants.d.ts +1 -0
  153. package/constants.js +1 -0
  154. package/constants.js.map +1 -1
  155. package/hoc/withBreakpoint/withBreakpoint.js +2 -2
  156. package/hoc/withBreakpoint/withBreakpoint.js.map +1 -1
  157. package/hooks/useBreakpoint.d.ts +0 -4
  158. package/hooks/useBreakpoint.js +23 -18
  159. package/hooks/useBreakpoint.js.map +1 -1
  160. package/hooks/useEventListenerState.js +3 -3
  161. package/hooks/useEventListenerState.js.map +1 -1
  162. package/hooks/useOutsideEvent.d.ts +4 -4
  163. package/hooks/useOutsideEvent.js +5 -4
  164. package/hooks/useOutsideEvent.js.map +1 -1
  165. package/hooks/useReturnFocusOnUnmount.d.ts +5 -0
  166. package/hooks/useReturnFocusOnUnmount.js +20 -0
  167. package/hooks/useReturnFocusOnUnmount.js.map +1 -0
  168. package/package.json +1 -1
  169. package/scss/_breakpoints.scss +6 -0
  170. package/scss/_font-mixins.scss +55 -0
  171. package/scss/typography.module.scss +24 -0
  172. package/scss/typography.module.scss.d.ts +6 -0
  173. package/scss/typography.stories.tsx +24 -0
  174. package/theme/index.js +2 -2
  175. package/use-animate.js +3952 -0
  176. package/use-animate.js.map +1 -0
  177. package/utils/accessibility.d.ts +1 -0
  178. package/utils/accessibility.js +6 -1
  179. package/utils/accessibility.js.map +1 -1
  180. package/utils/component.js +4 -4
  181. package/utils/component.js.map +1 -1
@@ -1,3918 +1,11 @@
1
- import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
- import { useRef, useEffect, useState } from "react";
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
3
  import classNames from "classnames";
4
4
  import { AnalyticsId } from "../../constants.js";
5
5
  import { usePseudoClasses } from "../../hooks/usePseudoClasses.js";
6
6
  import { useUuid } from "../../hooks/useUuid.js";
7
7
  import styles from "./styles.module.scss";
8
- const warned = /* @__PURE__ */ new Set();
9
- function warnOnce(condition, message, element) {
10
- if (condition || warned.has(message))
11
- return;
12
- console.warn(message);
13
- warned.add(message);
14
- }
15
- function isAnimationControls(v) {
16
- return v !== null && typeof v === "object" && typeof v.start === "function";
17
- }
18
- const isKeyframesTarget = (v) => {
19
- return Array.isArray(v);
20
- };
21
- function isVariantLabel(v) {
22
- return typeof v === "string" || Array.isArray(v);
23
- }
24
- function getValueState(visualElement) {
25
- const state = [{}, {}];
26
- visualElement === null || visualElement === void 0 ? void 0 : visualElement.values.forEach((value, key) => {
27
- state[0][key] = value.get();
28
- state[1][key] = value.getVelocity();
29
- });
30
- return state;
31
- }
32
- function resolveVariantFromProps(props, definition, custom, visualElement) {
33
- if (typeof definition === "function") {
34
- const [current, velocity] = getValueState(visualElement);
35
- definition = definition(custom !== void 0 ? custom : props.custom, current, velocity);
36
- }
37
- if (typeof definition === "string") {
38
- definition = props.variants && props.variants[definition];
39
- }
40
- if (typeof definition === "function") {
41
- const [current, velocity] = getValueState(visualElement);
42
- definition = definition(custom !== void 0 ? custom : props.custom, current, velocity);
43
- }
44
- return definition;
45
- }
46
- function resolveVariant(visualElement, definition, custom) {
47
- const props = visualElement.getProps();
48
- return resolveVariantFromProps(props, definition, props.custom, visualElement);
49
- }
50
- const variantPriorityOrder = [
51
- "animate",
52
- "whileInView",
53
- "whileFocus",
54
- "whileHover",
55
- "whileTap",
56
- "whileDrag",
57
- "exit"
58
- ];
59
- const variantProps = ["initial", ...variantPriorityOrder];
60
- const transformPropOrder = [
61
- "transformPerspective",
62
- "x",
63
- "y",
64
- "z",
65
- "translateX",
66
- "translateY",
67
- "translateZ",
68
- "scale",
69
- "scaleX",
70
- "scaleY",
71
- "rotate",
72
- "rotateX",
73
- "rotateY",
74
- "rotateZ",
75
- "skew",
76
- "skewX",
77
- "skewY"
78
- ];
79
- const transformProps = new Set(transformPropOrder);
80
- const secondsToMilliseconds = (seconds) => seconds * 1e3;
81
- const millisecondsToSeconds = (milliseconds) => milliseconds / 1e3;
82
- const underDampedSpring = {
83
- type: "spring",
84
- stiffness: 500,
85
- damping: 25,
86
- restSpeed: 10
87
- };
88
- const criticallyDampedSpring = (target) => ({
89
- type: "spring",
90
- stiffness: 550,
91
- damping: target === 0 ? 2 * Math.sqrt(550) : 30,
92
- restSpeed: 10
93
- });
94
- const keyframesTransition = {
95
- type: "keyframes",
96
- duration: 0.8
97
- };
98
- const ease = {
99
- type: "keyframes",
100
- ease: [0.25, 0.1, 0.35, 1],
101
- duration: 0.3
102
- };
103
- const getDefaultTransition = (valueKey, { keyframes: keyframes2 }) => {
104
- if (keyframes2.length > 2) {
105
- return keyframesTransition;
106
- } else if (transformProps.has(valueKey)) {
107
- return valueKey.startsWith("scale") ? criticallyDampedSpring(keyframes2[1]) : underDampedSpring;
108
- }
109
- return ease;
110
- };
111
- function getValueTransition$1(transition, key) {
112
- return transition ? transition[key] || transition["default"] || transition : void 0;
113
- }
114
- const MotionGlobalConfig = {
115
- skipAnimations: false,
116
- useManualTiming: false
117
- };
118
- const isNotNull = (value) => value !== null;
119
- function getFinalKeyframe(keyframes2, { repeat, repeatType = "loop" }, finalKeyframe) {
120
- const resolvedKeyframes = keyframes2.filter(isNotNull);
121
- const index = repeat && repeatType !== "loop" && repeat % 2 === 1 ? 0 : resolvedKeyframes.length - 1;
122
- return !index || finalKeyframe === void 0 ? resolvedKeyframes[index] : finalKeyframe;
123
- }
124
- const noop = (any) => any;
125
- let warning = noop;
126
- let invariant = noop;
127
- if (process.env.NODE_ENV !== "production") {
128
- warning = (check, message) => {
129
- if (!check && typeof console !== "undefined") {
130
- console.warn(message);
131
- }
132
- };
133
- invariant = (check, message) => {
134
- if (!check) {
135
- throw new Error(message);
136
- }
137
- };
138
- }
139
- function createRenderStep(runNextFrame) {
140
- let thisFrame = /* @__PURE__ */ new Set();
141
- let nextFrame = /* @__PURE__ */ new Set();
142
- let isProcessing = false;
143
- let flushNextFrame = false;
144
- const toKeepAlive = /* @__PURE__ */ new WeakSet();
145
- let latestFrameData = {
146
- delta: 0,
147
- timestamp: 0,
148
- isProcessing: false
149
- };
150
- function triggerCallback(callback) {
151
- if (toKeepAlive.has(callback)) {
152
- step.schedule(callback);
153
- runNextFrame();
154
- }
155
- callback(latestFrameData);
156
- }
157
- const step = {
158
- /**
159
- * Schedule a process to run on the next frame.
160
- */
161
- schedule: (callback, keepAlive = false, immediate = false) => {
162
- const addToCurrentFrame = immediate && isProcessing;
163
- const queue = addToCurrentFrame ? thisFrame : nextFrame;
164
- if (keepAlive)
165
- toKeepAlive.add(callback);
166
- if (!queue.has(callback))
167
- queue.add(callback);
168
- return callback;
169
- },
170
- /**
171
- * Cancel the provided callback from running on the next frame.
172
- */
173
- cancel: (callback) => {
174
- nextFrame.delete(callback);
175
- toKeepAlive.delete(callback);
176
- },
177
- /**
178
- * Execute all schedule callbacks.
179
- */
180
- process: (frameData2) => {
181
- latestFrameData = frameData2;
182
- if (isProcessing) {
183
- flushNextFrame = true;
184
- return;
185
- }
186
- isProcessing = true;
187
- [thisFrame, nextFrame] = [nextFrame, thisFrame];
188
- nextFrame.clear();
189
- thisFrame.forEach(triggerCallback);
190
- isProcessing = false;
191
- if (flushNextFrame) {
192
- flushNextFrame = false;
193
- step.process(frameData2);
194
- }
195
- }
196
- };
197
- return step;
198
- }
199
- const stepsOrder = [
200
- "read",
201
- // Read
202
- "resolveKeyframes",
203
- // Write/Read/Write/Read
204
- "update",
205
- // Compute
206
- "preRender",
207
- // Compute
208
- "render",
209
- // Write
210
- "postRender"
211
- // Compute
212
- ];
213
- const maxElapsed = 40;
214
- function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
215
- let runNextFrame = false;
216
- let useDefaultElapsed = true;
217
- const state = {
218
- delta: 0,
219
- timestamp: 0,
220
- isProcessing: false
221
- };
222
- const flagRunNextFrame = () => runNextFrame = true;
223
- const steps = stepsOrder.reduce((acc, key) => {
224
- acc[key] = createRenderStep(flagRunNextFrame);
225
- return acc;
226
- }, {});
227
- const { read, resolveKeyframes, update, preRender, render, postRender } = steps;
228
- const processBatch = () => {
229
- const timestamp = performance.now();
230
- runNextFrame = false;
231
- state.delta = useDefaultElapsed ? 1e3 / 60 : Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
232
- state.timestamp = timestamp;
233
- state.isProcessing = true;
234
- read.process(state);
235
- resolveKeyframes.process(state);
236
- update.process(state);
237
- preRender.process(state);
238
- render.process(state);
239
- postRender.process(state);
240
- state.isProcessing = false;
241
- if (runNextFrame && allowKeepAlive) {
242
- useDefaultElapsed = false;
243
- scheduleNextBatch(processBatch);
244
- }
245
- };
246
- const wake = () => {
247
- runNextFrame = true;
248
- useDefaultElapsed = true;
249
- if (!state.isProcessing) {
250
- scheduleNextBatch(processBatch);
251
- }
252
- };
253
- const schedule = stepsOrder.reduce((acc, key) => {
254
- const step = steps[key];
255
- acc[key] = (process2, keepAlive = false, immediate = false) => {
256
- if (!runNextFrame)
257
- wake();
258
- return step.schedule(process2, keepAlive, immediate);
259
- };
260
- return acc;
261
- }, {});
262
- const cancel = (process2) => {
263
- for (let i = 0; i < stepsOrder.length; i++) {
264
- steps[stepsOrder[i]].cancel(process2);
265
- }
266
- };
267
- return { schedule, cancel, state, steps };
268
- }
269
- const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
270
- const calcBezier = (t, a1, a2) => (((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t + 3 * a1) * t;
271
- const subdivisionPrecision = 1e-7;
272
- const subdivisionMaxIterations = 12;
273
- function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
274
- let currentX;
275
- let currentT;
276
- let i = 0;
277
- do {
278
- currentT = lowerBound + (upperBound - lowerBound) / 2;
279
- currentX = calcBezier(currentT, mX1, mX2) - x;
280
- if (currentX > 0) {
281
- upperBound = currentT;
282
- } else {
283
- lowerBound = currentT;
284
- }
285
- } while (Math.abs(currentX) > subdivisionPrecision && ++i < subdivisionMaxIterations);
286
- return currentT;
287
- }
288
- function cubicBezier(mX1, mY1, mX2, mY2) {
289
- if (mX1 === mY1 && mX2 === mY2)
290
- return noop;
291
- const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
292
- return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
293
- }
294
- const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
295
- const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
296
- const backOut = /* @__PURE__ */ cubicBezier(0.33, 1.53, 0.69, 0.99);
297
- const backIn = /* @__PURE__ */ reverseEasing(backOut);
298
- const backInOut = /* @__PURE__ */ mirrorEasing(backIn);
299
- const anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
300
- const circIn = (p) => 1 - Math.sin(Math.acos(p));
301
- const circOut = reverseEasing(circIn);
302
- const circInOut = mirrorEasing(circIn);
303
- const isZeroValueString = (v) => /^0[^.\s]+$/u.test(v);
304
- function isNone(value) {
305
- if (typeof value === "number") {
306
- return value === 0;
307
- } else if (value !== null) {
308
- return value === "none" || value === "0" || isZeroValueString(value);
309
- } else {
310
- return true;
311
- }
312
- }
313
- const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
314
- const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
315
- const isCSSVariableName = /* @__PURE__ */ checkStringStartsWith("--");
316
- const startsAsVariableToken = /* @__PURE__ */ checkStringStartsWith("var(--");
317
- const isCSSVariableToken = (value) => {
318
- const startsWithToken = startsAsVariableToken(value);
319
- if (!startsWithToken)
320
- return false;
321
- return singleCssVariableRegex.test(value.split("/*")[0].trim());
322
- };
323
- const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
324
- const splitCSSVariableRegex = (
325
- // eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
326
- /^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u
327
- );
328
- function parseCSSVariable(current) {
329
- const match = splitCSSVariableRegex.exec(current);
330
- if (!match)
331
- return [,];
332
- const [, token1, token2, fallback] = match;
333
- return [`--${token1 !== null && token1 !== void 0 ? token1 : token2}`, fallback];
334
- }
335
- const maxDepth = 4;
336
- function getVariableValue(current, element, depth = 1) {
337
- invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`);
338
- const [token, fallback] = parseCSSVariable(current);
339
- if (!token)
340
- return;
341
- const resolved = window.getComputedStyle(element).getPropertyValue(token);
342
- if (resolved) {
343
- const trimmed = resolved.trim();
344
- return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
345
- }
346
- return isCSSVariableToken(fallback) ? getVariableValue(fallback, element, depth + 1) : fallback;
347
- }
348
- const clamp = (min, max, v) => {
349
- if (v > max)
350
- return max;
351
- if (v < min)
352
- return min;
353
- return v;
354
- };
355
- const number = {
356
- test: (v) => typeof v === "number",
357
- parse: parseFloat,
358
- transform: (v) => v
359
- };
360
- const alpha = {
361
- ...number,
362
- transform: (v) => clamp(0, 1, v)
363
- };
364
- const scale = {
365
- ...number,
366
- default: 1
367
- };
368
- const createUnitType = (unit) => ({
369
- test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
370
- parse: parseFloat,
371
- transform: (v) => `${v}${unit}`
372
- });
373
- const degrees = /* @__PURE__ */ createUnitType("deg");
374
- const percent = /* @__PURE__ */ createUnitType("%");
375
- const px = /* @__PURE__ */ createUnitType("px");
376
- const vh = /* @__PURE__ */ createUnitType("vh");
377
- const vw = /* @__PURE__ */ createUnitType("vw");
378
- const progressPercentage = {
379
- ...percent,
380
- parse: (v) => percent.parse(v) / 100,
381
- transform: (v) => percent.transform(v * 100)
382
- };
383
- const positionalKeys = /* @__PURE__ */ new Set([
384
- "width",
385
- "height",
386
- "top",
387
- "left",
388
- "right",
389
- "bottom",
390
- "x",
391
- "y",
392
- "translateX",
393
- "translateY"
394
- ]);
395
- const isNumOrPxType = (v) => v === number || v === px;
396
- const getPosFromMatrix = (matrix, pos) => parseFloat(matrix.split(", ")[pos]);
397
- const getTranslateFromMatrix = (pos2, pos3) => (_bbox, { transform }) => {
398
- if (transform === "none" || !transform)
399
- return 0;
400
- const matrix3d = transform.match(/^matrix3d\((.+)\)$/u);
401
- if (matrix3d) {
402
- return getPosFromMatrix(matrix3d[1], pos3);
403
- } else {
404
- const matrix = transform.match(/^matrix\((.+)\)$/u);
405
- if (matrix) {
406
- return getPosFromMatrix(matrix[1], pos2);
407
- } else {
408
- return 0;
409
- }
410
- }
411
- };
412
- const transformKeys = /* @__PURE__ */ new Set(["x", "y", "z"]);
413
- const nonTranslationalTransformKeys = transformPropOrder.filter((key) => !transformKeys.has(key));
414
- function removeNonTranslationalTransform(visualElement) {
415
- const removedTransforms = [];
416
- nonTranslationalTransformKeys.forEach((key) => {
417
- const value = visualElement.getValue(key);
418
- if (value !== void 0) {
419
- removedTransforms.push([key, value.get()]);
420
- value.set(key.startsWith("scale") ? 1 : 0);
421
- }
422
- });
423
- return removedTransforms;
424
- }
425
- const positionalValues = {
426
- // Dimensions
427
- width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) => x.max - x.min - parseFloat(paddingLeft) - parseFloat(paddingRight),
428
- height: ({ y }, { paddingTop = "0", paddingBottom = "0" }) => y.max - y.min - parseFloat(paddingTop) - parseFloat(paddingBottom),
429
- top: (_bbox, { top }) => parseFloat(top),
430
- left: (_bbox, { left }) => parseFloat(left),
431
- bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
432
- right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
433
- // Transform
434
- x: getTranslateFromMatrix(4, 13),
435
- y: getTranslateFromMatrix(5, 14)
436
- };
437
- positionalValues.translateX = positionalValues.x;
438
- positionalValues.translateY = positionalValues.y;
439
- const testValueType = (v) => (type) => type.test(v);
440
- const auto = {
441
- test: (v) => v === "auto",
442
- parse: (v) => v
443
- };
444
- const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
445
- const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
446
- const toResolve = /* @__PURE__ */ new Set();
447
- let isScheduled = false;
448
- let anyNeedsMeasurement = false;
449
- function measureAllKeyframes() {
450
- if (anyNeedsMeasurement) {
451
- const resolversToMeasure = Array.from(toResolve).filter((resolver) => resolver.needsMeasurement);
452
- const elementsToMeasure = new Set(resolversToMeasure.map((resolver) => resolver.element));
453
- const transformsToRestore = /* @__PURE__ */ new Map();
454
- elementsToMeasure.forEach((element) => {
455
- const removedTransforms = removeNonTranslationalTransform(element);
456
- if (!removedTransforms.length)
457
- return;
458
- transformsToRestore.set(element, removedTransforms);
459
- element.render();
460
- });
461
- resolversToMeasure.forEach((resolver) => resolver.measureInitialState());
462
- elementsToMeasure.forEach((element) => {
463
- element.render();
464
- const restore = transformsToRestore.get(element);
465
- if (restore) {
466
- restore.forEach(([key, value]) => {
467
- var _a;
468
- (_a = element.getValue(key)) === null || _a === void 0 ? void 0 : _a.set(value);
469
- });
470
- }
471
- });
472
- resolversToMeasure.forEach((resolver) => resolver.measureEndState());
473
- resolversToMeasure.forEach((resolver) => {
474
- if (resolver.suspendedScrollY !== void 0) {
475
- window.scrollTo(0, resolver.suspendedScrollY);
476
- }
477
- });
478
- }
479
- anyNeedsMeasurement = false;
480
- isScheduled = false;
481
- toResolve.forEach((resolver) => resolver.complete());
482
- toResolve.clear();
483
- }
484
- function readAllKeyframes() {
485
- toResolve.forEach((resolver) => {
486
- resolver.readKeyframes();
487
- if (resolver.needsMeasurement) {
488
- anyNeedsMeasurement = true;
489
- }
490
- });
491
- }
492
- function flushKeyframeResolvers() {
493
- readAllKeyframes();
494
- measureAllKeyframes();
495
- }
496
- class KeyframeResolver {
497
- constructor(unresolvedKeyframes, onComplete, name, motionValue2, element, isAsync = false) {
498
- this.isComplete = false;
499
- this.isAsync = false;
500
- this.needsMeasurement = false;
501
- this.isScheduled = false;
502
- this.unresolvedKeyframes = [...unresolvedKeyframes];
503
- this.onComplete = onComplete;
504
- this.name = name;
505
- this.motionValue = motionValue2;
506
- this.element = element;
507
- this.isAsync = isAsync;
508
- }
509
- scheduleResolve() {
510
- this.isScheduled = true;
511
- if (this.isAsync) {
512
- toResolve.add(this);
513
- if (!isScheduled) {
514
- isScheduled = true;
515
- frame.read(readAllKeyframes);
516
- frame.resolveKeyframes(measureAllKeyframes);
517
- }
518
- } else {
519
- this.readKeyframes();
520
- this.complete();
521
- }
522
- }
523
- readKeyframes() {
524
- const { unresolvedKeyframes, name, element, motionValue: motionValue2 } = this;
525
- for (let i = 0; i < unresolvedKeyframes.length; i++) {
526
- if (unresolvedKeyframes[i] === null) {
527
- if (i === 0) {
528
- const currentValue = motionValue2 === null || motionValue2 === void 0 ? void 0 : motionValue2.get();
529
- const finalKeyframe = unresolvedKeyframes[unresolvedKeyframes.length - 1];
530
- if (currentValue !== void 0) {
531
- unresolvedKeyframes[0] = currentValue;
532
- } else if (element && name) {
533
- const valueAsRead = element.readValue(name, finalKeyframe);
534
- if (valueAsRead !== void 0 && valueAsRead !== null) {
535
- unresolvedKeyframes[0] = valueAsRead;
536
- }
537
- }
538
- if (unresolvedKeyframes[0] === void 0) {
539
- unresolvedKeyframes[0] = finalKeyframe;
540
- }
541
- if (motionValue2 && currentValue === void 0) {
542
- motionValue2.set(unresolvedKeyframes[0]);
543
- }
544
- } else {
545
- unresolvedKeyframes[i] = unresolvedKeyframes[i - 1];
546
- }
547
- }
548
- }
549
- }
550
- setFinalKeyframe() {
551
- }
552
- measureInitialState() {
553
- }
554
- renderEndStyles() {
555
- }
556
- measureEndState() {
557
- }
558
- complete() {
559
- this.isComplete = true;
560
- this.onComplete(this.unresolvedKeyframes, this.finalKeyframe);
561
- toResolve.delete(this);
562
- }
563
- cancel() {
564
- if (!this.isComplete) {
565
- this.isScheduled = false;
566
- toResolve.delete(this);
567
- }
568
- }
569
- resume() {
570
- if (!this.isComplete)
571
- this.scheduleResolve();
572
- }
573
- }
574
- const sanitize = (v) => Math.round(v * 1e5) / 1e5;
575
- const floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
576
- function isNullish(v) {
577
- return v == null;
578
- }
579
- const singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
580
- const isColorString = (type, testProp) => (v) => {
581
- return Boolean(typeof v === "string" && singleColorRegex.test(v) && v.startsWith(type) || testProp && !isNullish(v) && Object.prototype.hasOwnProperty.call(v, testProp));
582
- };
583
- const splitColor = (aName, bName, cName) => (v) => {
584
- if (typeof v !== "string")
585
- return v;
586
- const [a, b, c, alpha2] = v.match(floatRegex);
587
- return {
588
- [aName]: parseFloat(a),
589
- [bName]: parseFloat(b),
590
- [cName]: parseFloat(c),
591
- alpha: alpha2 !== void 0 ? parseFloat(alpha2) : 1
592
- };
593
- };
594
- const clampRgbUnit = (v) => clamp(0, 255, v);
595
- const rgbUnit = {
596
- ...number,
597
- transform: (v) => Math.round(clampRgbUnit(v))
598
- };
599
- const rgba = {
600
- test: /* @__PURE__ */ isColorString("rgb", "red"),
601
- parse: /* @__PURE__ */ splitColor("red", "green", "blue"),
602
- transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" + rgbUnit.transform(red) + ", " + rgbUnit.transform(green) + ", " + rgbUnit.transform(blue) + ", " + sanitize(alpha.transform(alpha$1)) + ")"
603
- };
604
- function parseHex(v) {
605
- let r = "";
606
- let g = "";
607
- let b = "";
608
- let a = "";
609
- if (v.length > 5) {
610
- r = v.substring(1, 3);
611
- g = v.substring(3, 5);
612
- b = v.substring(5, 7);
613
- a = v.substring(7, 9);
614
- } else {
615
- r = v.substring(1, 2);
616
- g = v.substring(2, 3);
617
- b = v.substring(3, 4);
618
- a = v.substring(4, 5);
619
- r += r;
620
- g += g;
621
- b += b;
622
- a += a;
623
- }
624
- return {
625
- red: parseInt(r, 16),
626
- green: parseInt(g, 16),
627
- blue: parseInt(b, 16),
628
- alpha: a ? parseInt(a, 16) / 255 : 1
629
- };
630
- }
631
- const hex = {
632
- test: /* @__PURE__ */ isColorString("#"),
633
- parse: parseHex,
634
- transform: rgba.transform
635
- };
636
- const hsla = {
637
- test: /* @__PURE__ */ isColorString("hsl", "hue"),
638
- parse: /* @__PURE__ */ splitColor("hue", "saturation", "lightness"),
639
- transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
640
- return "hsla(" + Math.round(hue) + ", " + percent.transform(sanitize(saturation)) + ", " + percent.transform(sanitize(lightness)) + ", " + sanitize(alpha.transform(alpha$1)) + ")";
641
- }
642
- };
643
- const color = {
644
- test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
645
- parse: (v) => {
646
- if (rgba.test(v)) {
647
- return rgba.parse(v);
648
- } else if (hsla.test(v)) {
649
- return hsla.parse(v);
650
- } else {
651
- return hex.parse(v);
652
- }
653
- },
654
- transform: (v) => {
655
- return typeof v === "string" ? v : v.hasOwnProperty("red") ? rgba.transform(v) : hsla.transform(v);
656
- }
657
- };
658
- const colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
659
- function test(v) {
660
- var _a, _b;
661
- return isNaN(v) && typeof v === "string" && (((_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) || 0) + (((_b = v.match(colorRegex)) === null || _b === void 0 ? void 0 : _b.length) || 0) > 0;
662
- }
663
- const NUMBER_TOKEN = "number";
664
- const COLOR_TOKEN = "color";
665
- const VAR_TOKEN = "var";
666
- const VAR_FUNCTION_TOKEN = "var(";
667
- const SPLIT_TOKEN = "${}";
668
- const 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;
669
- function analyseComplexValue(value) {
670
- const originalValue = value.toString();
671
- const values = [];
672
- const indexes = {
673
- color: [],
674
- number: [],
675
- var: []
676
- };
677
- const types = [];
678
- let i = 0;
679
- const tokenised = originalValue.replace(complexRegex, (parsedValue) => {
680
- if (color.test(parsedValue)) {
681
- indexes.color.push(i);
682
- types.push(COLOR_TOKEN);
683
- values.push(color.parse(parsedValue));
684
- } else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
685
- indexes.var.push(i);
686
- types.push(VAR_TOKEN);
687
- values.push(parsedValue);
688
- } else {
689
- indexes.number.push(i);
690
- types.push(NUMBER_TOKEN);
691
- values.push(parseFloat(parsedValue));
692
- }
693
- ++i;
694
- return SPLIT_TOKEN;
695
- });
696
- const split = tokenised.split(SPLIT_TOKEN);
697
- return { values, split, indexes, types };
698
- }
699
- function parseComplexValue(v) {
700
- return analyseComplexValue(v).values;
701
- }
702
- function createTransformer(source) {
703
- const { split, types } = analyseComplexValue(source);
704
- const numSections = split.length;
705
- return (v) => {
706
- let output = "";
707
- for (let i = 0; i < numSections; i++) {
708
- output += split[i];
709
- if (v[i] !== void 0) {
710
- const type = types[i];
711
- if (type === NUMBER_TOKEN) {
712
- output += sanitize(v[i]);
713
- } else if (type === COLOR_TOKEN) {
714
- output += color.transform(v[i]);
715
- } else {
716
- output += v[i];
717
- }
718
- }
719
- }
720
- return output;
721
- };
722
- }
723
- const convertNumbersToZero = (v) => typeof v === "number" ? 0 : v;
724
- function getAnimatableNone$1(v) {
725
- const parsed = parseComplexValue(v);
726
- const transformer = createTransformer(v);
727
- return transformer(parsed.map(convertNumbersToZero));
728
- }
729
- const complex = {
730
- test,
731
- parse: parseComplexValue,
732
- createTransformer,
733
- getAnimatableNone: getAnimatableNone$1
734
- };
735
- const maxDefaults = /* @__PURE__ */ new Set(["brightness", "contrast", "saturate", "opacity"]);
736
- function applyDefaultFilter(v) {
737
- const [name, value] = v.slice(0, -1).split("(");
738
- if (name === "drop-shadow")
739
- return v;
740
- const [number2] = value.match(floatRegex) || [];
741
- if (!number2)
742
- return v;
743
- const unit = value.replace(number2, "");
744
- let defaultValue = maxDefaults.has(name) ? 1 : 0;
745
- if (number2 !== value)
746
- defaultValue *= 100;
747
- return name + "(" + defaultValue + unit + ")";
748
- }
749
- const functionRegex = /\b([a-z-]*)\(.*?\)/gu;
750
- const filter = {
751
- ...complex,
752
- getAnimatableNone: (v) => {
753
- const functions = v.match(functionRegex);
754
- return functions ? functions.map(applyDefaultFilter).join(" ") : v;
755
- }
756
- };
757
- const browserNumberValueTypes = {
758
- // Border props
759
- borderWidth: px,
760
- borderTopWidth: px,
761
- borderRightWidth: px,
762
- borderBottomWidth: px,
763
- borderLeftWidth: px,
764
- borderRadius: px,
765
- radius: px,
766
- borderTopLeftRadius: px,
767
- borderTopRightRadius: px,
768
- borderBottomRightRadius: px,
769
- borderBottomLeftRadius: px,
770
- // Positioning props
771
- width: px,
772
- maxWidth: px,
773
- height: px,
774
- maxHeight: px,
775
- top: px,
776
- right: px,
777
- bottom: px,
778
- left: px,
779
- // Spacing props
780
- padding: px,
781
- paddingTop: px,
782
- paddingRight: px,
783
- paddingBottom: px,
784
- paddingLeft: px,
785
- margin: px,
786
- marginTop: px,
787
- marginRight: px,
788
- marginBottom: px,
789
- marginLeft: px,
790
- // Misc
791
- backgroundPositionX: px,
792
- backgroundPositionY: px
793
- };
794
- const transformValueTypes = {
795
- rotate: degrees,
796
- rotateX: degrees,
797
- rotateY: degrees,
798
- rotateZ: degrees,
799
- scale,
800
- scaleX: scale,
801
- scaleY: scale,
802
- scaleZ: scale,
803
- skew: degrees,
804
- skewX: degrees,
805
- skewY: degrees,
806
- distance: px,
807
- translateX: px,
808
- translateY: px,
809
- translateZ: px,
810
- x: px,
811
- y: px,
812
- z: px,
813
- perspective: px,
814
- transformPerspective: px,
815
- opacity: alpha,
816
- originX: progressPercentage,
817
- originY: progressPercentage,
818
- originZ: px
819
- };
820
- const int = {
821
- ...number,
822
- transform: Math.round
823
- };
824
- const numberValueTypes = {
825
- ...browserNumberValueTypes,
826
- ...transformValueTypes,
827
- zIndex: int,
828
- size: px,
829
- // SVG
830
- fillOpacity: alpha,
831
- strokeOpacity: alpha,
832
- numOctaves: int
833
- };
834
- const defaultValueTypes = {
835
- ...numberValueTypes,
836
- // Color props
837
- color,
838
- backgroundColor: color,
839
- outlineColor: color,
840
- fill: color,
841
- stroke: color,
842
- // Border props
843
- borderColor: color,
844
- borderTopColor: color,
845
- borderRightColor: color,
846
- borderBottomColor: color,
847
- borderLeftColor: color,
848
- filter,
849
- WebkitFilter: filter
850
- };
851
- const getDefaultValueType = (key) => defaultValueTypes[key];
852
- function getAnimatableNone(key, value) {
853
- let defaultValueType = getDefaultValueType(key);
854
- if (defaultValueType !== filter)
855
- defaultValueType = complex;
856
- return defaultValueType.getAnimatableNone ? defaultValueType.getAnimatableNone(value) : void 0;
857
- }
858
- const invalidTemplates = /* @__PURE__ */ new Set(["auto", "none", "0"]);
859
- function makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name) {
860
- let i = 0;
861
- let animatableTemplate = void 0;
862
- while (i < unresolvedKeyframes.length && !animatableTemplate) {
863
- const keyframe = unresolvedKeyframes[i];
864
- if (typeof keyframe === "string" && !invalidTemplates.has(keyframe) && analyseComplexValue(keyframe).values.length) {
865
- animatableTemplate = unresolvedKeyframes[i];
866
- }
867
- i++;
868
- }
869
- if (animatableTemplate && name) {
870
- for (const noneIndex of noneKeyframeIndexes) {
871
- unresolvedKeyframes[noneIndex] = getAnimatableNone(name, animatableTemplate);
872
- }
873
- }
874
- }
875
- class DOMKeyframesResolver extends KeyframeResolver {
876
- constructor(unresolvedKeyframes, onComplete, name, motionValue2, element) {
877
- super(unresolvedKeyframes, onComplete, name, motionValue2, element, true);
878
- }
879
- readKeyframes() {
880
- const { unresolvedKeyframes, element, name } = this;
881
- if (!element || !element.current)
882
- return;
883
- super.readKeyframes();
884
- for (let i = 0; i < unresolvedKeyframes.length; i++) {
885
- let keyframe = unresolvedKeyframes[i];
886
- if (typeof keyframe === "string") {
887
- keyframe = keyframe.trim();
888
- if (isCSSVariableToken(keyframe)) {
889
- const resolved = getVariableValue(keyframe, element.current);
890
- if (resolved !== void 0) {
891
- unresolvedKeyframes[i] = resolved;
892
- }
893
- if (i === unresolvedKeyframes.length - 1) {
894
- this.finalKeyframe = keyframe;
895
- }
896
- }
897
- }
898
- }
899
- this.resolveNoneKeyframes();
900
- if (!positionalKeys.has(name) || unresolvedKeyframes.length !== 2) {
901
- return;
902
- }
903
- const [origin, target] = unresolvedKeyframes;
904
- const originType = findDimensionValueType(origin);
905
- const targetType = findDimensionValueType(target);
906
- if (originType === targetType)
907
- return;
908
- if (isNumOrPxType(originType) && isNumOrPxType(targetType)) {
909
- for (let i = 0; i < unresolvedKeyframes.length; i++) {
910
- const value = unresolvedKeyframes[i];
911
- if (typeof value === "string") {
912
- unresolvedKeyframes[i] = parseFloat(value);
913
- }
914
- }
915
- } else {
916
- this.needsMeasurement = true;
917
- }
918
- }
919
- resolveNoneKeyframes() {
920
- const { unresolvedKeyframes, name } = this;
921
- const noneKeyframeIndexes = [];
922
- for (let i = 0; i < unresolvedKeyframes.length; i++) {
923
- if (isNone(unresolvedKeyframes[i])) {
924
- noneKeyframeIndexes.push(i);
925
- }
926
- }
927
- if (noneKeyframeIndexes.length) {
928
- makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name);
929
- }
930
- }
931
- measureInitialState() {
932
- const { element, unresolvedKeyframes, name } = this;
933
- if (!element || !element.current)
934
- return;
935
- if (name === "height") {
936
- this.suspendedScrollY = window.pageYOffset;
937
- }
938
- this.measuredOrigin = positionalValues[name](element.measureViewportBox(), window.getComputedStyle(element.current));
939
- unresolvedKeyframes[0] = this.measuredOrigin;
940
- const measureKeyframe = unresolvedKeyframes[unresolvedKeyframes.length - 1];
941
- if (measureKeyframe !== void 0) {
942
- element.getValue(name, measureKeyframe).jump(measureKeyframe, false);
943
- }
944
- }
945
- measureEndState() {
946
- var _a;
947
- const { element, name, unresolvedKeyframes } = this;
948
- if (!element || !element.current)
949
- return;
950
- const value = element.getValue(name);
951
- value && value.jump(this.measuredOrigin, false);
952
- const finalKeyframeIndex = unresolvedKeyframes.length - 1;
953
- const finalKeyframe = unresolvedKeyframes[finalKeyframeIndex];
954
- unresolvedKeyframes[finalKeyframeIndex] = positionalValues[name](element.measureViewportBox(), window.getComputedStyle(element.current));
955
- if (finalKeyframe !== null && this.finalKeyframe === void 0) {
956
- this.finalKeyframe = finalKeyframe;
957
- }
958
- if ((_a = this.removedTransforms) === null || _a === void 0 ? void 0 : _a.length) {
959
- this.removedTransforms.forEach(([unsetTransformName, unsetTransformValue]) => {
960
- element.getValue(unsetTransformName).set(unsetTransformValue);
961
- });
962
- }
963
- this.resolveNoneKeyframes();
964
- }
965
- }
966
- function isGenerator(type) {
967
- return typeof type === "function";
968
- }
969
- let now;
970
- function clearTime() {
971
- now = void 0;
972
- }
973
- const time = {
974
- now: () => {
975
- if (now === void 0) {
976
- time.set(frameData.isProcessing || MotionGlobalConfig.useManualTiming ? frameData.timestamp : performance.now());
977
- }
978
- return now;
979
- },
980
- set: (newTime) => {
981
- now = newTime;
982
- queueMicrotask(clearTime);
983
- }
984
- };
985
- const isAnimatable = (value, name) => {
986
- if (name === "zIndex")
987
- return false;
988
- if (typeof value === "number" || Array.isArray(value))
989
- return true;
990
- if (typeof value === "string" && // It's animatable if we have a string
991
- (complex.test(value) || value === "0") && // And it contains numbers and/or colors
992
- !value.startsWith("url(")) {
993
- return true;
994
- }
995
- return false;
996
- };
997
- function hasKeyframesChanged(keyframes2) {
998
- const current = keyframes2[0];
999
- if (keyframes2.length === 1)
1000
- return true;
1001
- for (let i = 0; i < keyframes2.length; i++) {
1002
- if (keyframes2[i] !== current)
1003
- return true;
1004
- }
1005
- }
1006
- function canAnimate(keyframes2, name, type, velocity) {
1007
- const originKeyframe = keyframes2[0];
1008
- if (originKeyframe === null)
1009
- return false;
1010
- if (name === "display" || name === "visibility")
1011
- return true;
1012
- const targetKeyframe = keyframes2[keyframes2.length - 1];
1013
- const isOriginAnimatable = isAnimatable(originKeyframe, name);
1014
- const isTargetAnimatable = isAnimatable(targetKeyframe, name);
1015
- warning(isOriginAnimatable === isTargetAnimatable, `You are trying to animate ${name} from "${originKeyframe}" to "${targetKeyframe}". ${originKeyframe} is not an animatable value - to enable this animation set ${originKeyframe} to a value animatable to ${targetKeyframe} via the \`style\` property.`);
1016
- if (!isOriginAnimatable || !isTargetAnimatable) {
1017
- return false;
1018
- }
1019
- return hasKeyframesChanged(keyframes2) || (type === "spring" || isGenerator(type)) && velocity;
1020
- }
1021
- const MAX_RESOLVE_DELAY = 40;
1022
- class BaseAnimation {
1023
- constructor({ autoplay = true, delay = 0, type = "keyframes", repeat = 0, repeatDelay = 0, repeatType = "loop", ...options }) {
1024
- this.isStopped = false;
1025
- this.hasAttemptedResolve = false;
1026
- this.createdAt = time.now();
1027
- this.options = {
1028
- autoplay,
1029
- delay,
1030
- type,
1031
- repeat,
1032
- repeatDelay,
1033
- repeatType,
1034
- ...options
1035
- };
1036
- this.updateFinishedPromise();
1037
- }
1038
- /**
1039
- * This method uses the createdAt and resolvedAt to calculate the
1040
- * animation startTime. *Ideally*, we would use the createdAt time as t=0
1041
- * as the following frame would then be the first frame of the animation in
1042
- * progress, which would feel snappier.
1043
- *
1044
- * However, if there's a delay (main thread work) between the creation of
1045
- * the animation and the first commited frame, we prefer to use resolvedAt
1046
- * to avoid a sudden jump into the animation.
1047
- */
1048
- calcStartTime() {
1049
- if (!this.resolvedAt)
1050
- return this.createdAt;
1051
- return this.resolvedAt - this.createdAt > MAX_RESOLVE_DELAY ? this.resolvedAt : this.createdAt;
1052
- }
1053
- /**
1054
- * A getter for resolved data. If keyframes are not yet resolved, accessing
1055
- * this.resolved will synchronously flush all pending keyframe resolvers.
1056
- * This is a deoptimisation, but at its worst still batches read/writes.
1057
- */
1058
- get resolved() {
1059
- if (!this._resolved && !this.hasAttemptedResolve) {
1060
- flushKeyframeResolvers();
1061
- }
1062
- return this._resolved;
1063
- }
1064
- /**
1065
- * A method to be called when the keyframes resolver completes. This method
1066
- * will check if its possible to run the animation and, if not, skip it.
1067
- * Otherwise, it will call initPlayback on the implementing class.
1068
- */
1069
- onKeyframesResolved(keyframes2, finalKeyframe) {
1070
- this.resolvedAt = time.now();
1071
- this.hasAttemptedResolve = true;
1072
- const { name, type, velocity, delay, onComplete, onUpdate, isGenerator: isGenerator2 } = this.options;
1073
- if (!isGenerator2 && !canAnimate(keyframes2, name, type, velocity)) {
1074
- if (!delay) {
1075
- onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(getFinalKeyframe(keyframes2, this.options, finalKeyframe));
1076
- onComplete === null || onComplete === void 0 ? void 0 : onComplete();
1077
- this.resolveFinishedPromise();
1078
- return;
1079
- } else {
1080
- this.options.duration = 0;
1081
- }
1082
- }
1083
- const resolvedAnimation = this.initPlayback(keyframes2, finalKeyframe);
1084
- if (resolvedAnimation === false)
1085
- return;
1086
- this._resolved = {
1087
- keyframes: keyframes2,
1088
- finalKeyframe,
1089
- ...resolvedAnimation
1090
- };
1091
- this.onPostResolved();
1092
- }
1093
- onPostResolved() {
1094
- }
1095
- /**
1096
- * Allows the returned animation to be awaited or promise-chained. Currently
1097
- * resolves when the animation finishes at all but in a future update could/should
1098
- * reject if its cancels.
1099
- */
1100
- then(resolve, reject) {
1101
- return this.currentFinishedPromise.then(resolve, reject);
1102
- }
1103
- flatten() {
1104
- this.options.type = "keyframes";
1105
- this.options.ease = "linear";
1106
- }
1107
- updateFinishedPromise() {
1108
- this.currentFinishedPromise = new Promise((resolve) => {
1109
- this.resolveFinishedPromise = resolve;
1110
- });
1111
- }
1112
- }
1113
- const progress = (from, to, value) => {
1114
- const toFromDifference = to - from;
1115
- return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
1116
- };
1117
- const generateLinearEasing = (easing, duration, resolution = 10) => {
1118
- let points = "";
1119
- const numPoints = Math.max(Math.round(duration / resolution), 2);
1120
- for (let i = 0; i < numPoints; i++) {
1121
- points += easing(progress(0, numPoints - 1, i)) + ", ";
1122
- }
1123
- return `linear(${points.substring(0, points.length - 2)})`;
1124
- };
1125
- function velocityPerSecond(velocity, frameDuration) {
1126
- return frameDuration ? velocity * (1e3 / frameDuration) : 0;
1127
- }
1128
- const velocitySampleDuration = 5;
1129
- function calcGeneratorVelocity(resolveValue, t, current) {
1130
- const prevT = Math.max(t - velocitySampleDuration, 0);
1131
- return velocityPerSecond(current - resolveValue(prevT), t - prevT);
1132
- }
1133
- const springDefaults = {
1134
- // Default spring physics
1135
- stiffness: 100,
1136
- damping: 10,
1137
- mass: 1,
1138
- velocity: 0,
1139
- // Default duration/bounce-based options
1140
- duration: 800,
1141
- // in ms
1142
- bounce: 0.3,
1143
- visualDuration: 0.3,
1144
- // in seconds
1145
- // Rest thresholds
1146
- restSpeed: {
1147
- granular: 0.01,
1148
- default: 2
1149
- },
1150
- restDelta: {
1151
- granular: 5e-3,
1152
- default: 0.5
1153
- },
1154
- // Limits
1155
- minDuration: 0.01,
1156
- // in seconds
1157
- maxDuration: 10,
1158
- // in seconds
1159
- minDamping: 0.05,
1160
- maxDamping: 1
1161
- };
1162
- const safeMin = 1e-3;
1163
- function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass }) {
1164
- let envelope;
1165
- let derivative;
1166
- warning(duration <= secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less");
1167
- let dampingRatio = 1 - bounce;
1168
- dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
1169
- duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, millisecondsToSeconds(duration));
1170
- if (dampingRatio < 1) {
1171
- envelope = (undampedFreq2) => {
1172
- const exponentialDecay = undampedFreq2 * dampingRatio;
1173
- const delta = exponentialDecay * duration;
1174
- const a = exponentialDecay - velocity;
1175
- const b = calcAngularFreq(undampedFreq2, dampingRatio);
1176
- const c = Math.exp(-delta);
1177
- return safeMin - a / b * c;
1178
- };
1179
- derivative = (undampedFreq2) => {
1180
- const exponentialDecay = undampedFreq2 * dampingRatio;
1181
- const delta = exponentialDecay * duration;
1182
- const d = delta * velocity + velocity;
1183
- const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq2, 2) * duration;
1184
- const f = Math.exp(-delta);
1185
- const g = calcAngularFreq(Math.pow(undampedFreq2, 2), dampingRatio);
1186
- const factor = -envelope(undampedFreq2) + safeMin > 0 ? -1 : 1;
1187
- return factor * ((d - e) * f) / g;
1188
- };
1189
- } else {
1190
- envelope = (undampedFreq2) => {
1191
- const a = Math.exp(-undampedFreq2 * duration);
1192
- const b = (undampedFreq2 - velocity) * duration + 1;
1193
- return -safeMin + a * b;
1194
- };
1195
- derivative = (undampedFreq2) => {
1196
- const a = Math.exp(-undampedFreq2 * duration);
1197
- const b = (velocity - undampedFreq2) * (duration * duration);
1198
- return a * b;
1199
- };
1200
- }
1201
- const initialGuess = 5 / duration;
1202
- const undampedFreq = approximateRoot(envelope, derivative, initialGuess);
1203
- duration = secondsToMilliseconds(duration);
1204
- if (isNaN(undampedFreq)) {
1205
- return {
1206
- stiffness: springDefaults.stiffness,
1207
- damping: springDefaults.damping,
1208
- duration
1209
- };
1210
- } else {
1211
- const stiffness = Math.pow(undampedFreq, 2) * mass;
1212
- return {
1213
- stiffness,
1214
- damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
1215
- duration
1216
- };
1217
- }
1218
- }
1219
- const rootIterations = 12;
1220
- function approximateRoot(envelope, derivative, initialGuess) {
1221
- let result = initialGuess;
1222
- for (let i = 1; i < rootIterations; i++) {
1223
- result = result - envelope(result) / derivative(result);
1224
- }
1225
- return result;
1226
- }
1227
- function calcAngularFreq(undampedFreq, dampingRatio) {
1228
- return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
1229
- }
1230
- const maxGeneratorDuration = 2e4;
1231
- function calcGeneratorDuration(generator) {
1232
- let duration = 0;
1233
- const timeStep = 50;
1234
- let state = generator.next(duration);
1235
- while (!state.done && duration < maxGeneratorDuration) {
1236
- duration += timeStep;
1237
- state = generator.next(duration);
1238
- }
1239
- return duration >= maxGeneratorDuration ? Infinity : duration;
1240
- }
1241
- const durationKeys = ["duration", "bounce"];
1242
- const physicsKeys = ["stiffness", "damping", "mass"];
1243
- function isSpringType(options, keys) {
1244
- return keys.some((key) => options[key] !== void 0);
1245
- }
1246
- function getSpringOptions(options) {
1247
- let springOptions = {
1248
- velocity: springDefaults.velocity,
1249
- stiffness: springDefaults.stiffness,
1250
- damping: springDefaults.damping,
1251
- mass: springDefaults.mass,
1252
- isResolvedFromDuration: false,
1253
- ...options
1254
- };
1255
- if (!isSpringType(options, physicsKeys) && isSpringType(options, durationKeys)) {
1256
- if (options.visualDuration) {
1257
- const visualDuration = options.visualDuration;
1258
- const root = 2 * Math.PI / (visualDuration * 1.2);
1259
- const stiffness = root * root;
1260
- const damping = 2 * clamp(0.05, 1, 1 - options.bounce) * Math.sqrt(stiffness);
1261
- springOptions = {
1262
- ...springOptions,
1263
- mass: springDefaults.mass,
1264
- stiffness,
1265
- damping
1266
- };
1267
- } else {
1268
- const derived = findSpring(options);
1269
- springOptions = {
1270
- ...springOptions,
1271
- ...derived,
1272
- mass: springDefaults.mass
1273
- };
1274
- springOptions.isResolvedFromDuration = true;
1275
- }
1276
- }
1277
- return springOptions;
1278
- }
1279
- function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
1280
- const options = typeof optionsOrVisualDuration !== "object" ? {
1281
- visualDuration: optionsOrVisualDuration,
1282
- keyframes: [0, 1],
1283
- bounce
1284
- } : optionsOrVisualDuration;
1285
- let { restSpeed, restDelta } = options;
1286
- const origin = options.keyframes[0];
1287
- const target = options.keyframes[options.keyframes.length - 1];
1288
- const state = { done: false, value: origin };
1289
- const { stiffness, damping, mass, duration, velocity, isResolvedFromDuration } = getSpringOptions({
1290
- ...options,
1291
- velocity: -millisecondsToSeconds(options.velocity || 0)
1292
- });
1293
- const initialVelocity = velocity || 0;
1294
- const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
1295
- const initialDelta = target - origin;
1296
- const undampedAngularFreq = millisecondsToSeconds(Math.sqrt(stiffness / mass));
1297
- const isGranularScale = Math.abs(initialDelta) < 5;
1298
- restSpeed || (restSpeed = isGranularScale ? springDefaults.restSpeed.granular : springDefaults.restSpeed.default);
1299
- restDelta || (restDelta = isGranularScale ? springDefaults.restDelta.granular : springDefaults.restDelta.default);
1300
- let resolveSpring;
1301
- if (dampingRatio < 1) {
1302
- const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
1303
- resolveSpring = (t) => {
1304
- const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
1305
- return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / angularFreq * Math.sin(angularFreq * t) + initialDelta * Math.cos(angularFreq * t));
1306
- };
1307
- } else if (dampingRatio === 1) {
1308
- resolveSpring = (t) => target - Math.exp(-undampedAngularFreq * t) * (initialDelta + (initialVelocity + undampedAngularFreq * initialDelta) * t);
1309
- } else {
1310
- const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1);
1311
- resolveSpring = (t) => {
1312
- const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
1313
- const freqForT = Math.min(dampedAngularFreq * t, 300);
1314
- return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) * Math.sinh(freqForT) + dampedAngularFreq * initialDelta * Math.cosh(freqForT)) / dampedAngularFreq;
1315
- };
1316
- }
1317
- const generator = {
1318
- calculatedDuration: isResolvedFromDuration ? duration || null : null,
1319
- next: (t) => {
1320
- const current = resolveSpring(t);
1321
- if (!isResolvedFromDuration) {
1322
- let currentVelocity = 0;
1323
- if (dampingRatio < 1) {
1324
- currentVelocity = t === 0 ? secondsToMilliseconds(initialVelocity) : calcGeneratorVelocity(resolveSpring, t, current);
1325
- }
1326
- const isBelowVelocityThreshold = Math.abs(currentVelocity) <= restSpeed;
1327
- const isBelowDisplacementThreshold = Math.abs(target - current) <= restDelta;
1328
- state.done = isBelowVelocityThreshold && isBelowDisplacementThreshold;
1329
- } else {
1330
- state.done = t >= duration;
1331
- }
1332
- state.value = state.done ? target : current;
1333
- return state;
1334
- },
1335
- toString: () => {
1336
- const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
1337
- const easing = generateLinearEasing((progress2) => generator.next(calculatedDuration * progress2).value, calculatedDuration, 30);
1338
- return calculatedDuration + "ms " + easing;
1339
- }
1340
- };
1341
- return generator;
1342
- }
1343
- function inertia({ keyframes: keyframes2, velocity = 0, power = 0.8, timeConstant = 325, bounceDamping = 10, bounceStiffness = 500, modifyTarget, min, max, restDelta = 0.5, restSpeed }) {
1344
- const origin = keyframes2[0];
1345
- const state = {
1346
- done: false,
1347
- value: origin
1348
- };
1349
- const isOutOfBounds = (v) => min !== void 0 && v < min || max !== void 0 && v > max;
1350
- const nearestBoundary = (v) => {
1351
- if (min === void 0)
1352
- return max;
1353
- if (max === void 0)
1354
- return min;
1355
- return Math.abs(min - v) < Math.abs(max - v) ? min : max;
1356
- };
1357
- let amplitude = power * velocity;
1358
- const ideal = origin + amplitude;
1359
- const target = modifyTarget === void 0 ? ideal : modifyTarget(ideal);
1360
- if (target !== ideal)
1361
- amplitude = target - origin;
1362
- const calcDelta = (t) => -amplitude * Math.exp(-t / timeConstant);
1363
- const calcLatest = (t) => target + calcDelta(t);
1364
- const applyFriction = (t) => {
1365
- const delta = calcDelta(t);
1366
- const latest = calcLatest(t);
1367
- state.done = Math.abs(delta) <= restDelta;
1368
- state.value = state.done ? target : latest;
1369
- };
1370
- let timeReachedBoundary;
1371
- let spring$1;
1372
- const checkCatchBoundary = (t) => {
1373
- if (!isOutOfBounds(state.value))
1374
- return;
1375
- timeReachedBoundary = t;
1376
- spring$1 = spring({
1377
- keyframes: [state.value, nearestBoundary(state.value)],
1378
- velocity: calcGeneratorVelocity(calcLatest, t, state.value),
1379
- // TODO: This should be passing * 1000
1380
- damping: bounceDamping,
1381
- stiffness: bounceStiffness,
1382
- restDelta,
1383
- restSpeed
1384
- });
1385
- };
1386
- checkCatchBoundary(0);
1387
- return {
1388
- calculatedDuration: null,
1389
- next: (t) => {
1390
- let hasUpdatedFrame = false;
1391
- if (!spring$1 && timeReachedBoundary === void 0) {
1392
- hasUpdatedFrame = true;
1393
- applyFriction(t);
1394
- checkCatchBoundary(t);
1395
- }
1396
- if (timeReachedBoundary !== void 0 && t >= timeReachedBoundary) {
1397
- return spring$1.next(t - timeReachedBoundary);
1398
- } else {
1399
- !hasUpdatedFrame && applyFriction(t);
1400
- return state;
1401
- }
1402
- }
1403
- };
1404
- }
1405
- const easeIn = /* @__PURE__ */ cubicBezier(0.42, 0, 1, 1);
1406
- const easeOut = /* @__PURE__ */ cubicBezier(0, 0, 0.58, 1);
1407
- const easeInOut = /* @__PURE__ */ cubicBezier(0.42, 0, 0.58, 1);
1408
- const isEasingArray = (ease2) => {
1409
- return Array.isArray(ease2) && typeof ease2[0] !== "number";
1410
- };
1411
- const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
1412
- const easingLookup = {
1413
- linear: noop,
1414
- easeIn,
1415
- easeInOut,
1416
- easeOut,
1417
- circIn,
1418
- circInOut,
1419
- circOut,
1420
- backIn,
1421
- backInOut,
1422
- backOut,
1423
- anticipate
1424
- };
1425
- const easingDefinitionToFunction = (definition) => {
1426
- if (isBezierDefinition(definition)) {
1427
- invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`);
1428
- const [x1, y1, x2, y2] = definition;
1429
- return cubicBezier(x1, y1, x2, y2);
1430
- } else if (typeof definition === "string") {
1431
- invariant(easingLookup[definition] !== void 0, `Invalid easing type '${definition}'`);
1432
- return easingLookup[definition];
1433
- }
1434
- return definition;
1435
- };
1436
- const combineFunctions = (a, b) => (v) => b(a(v));
1437
- const pipe = (...transformers) => transformers.reduce(combineFunctions);
1438
- const mixNumber$1 = (from, to, progress2) => {
1439
- return from + (to - from) * progress2;
1440
- };
1441
- function hueToRgb(p, q, t) {
1442
- if (t < 0)
1443
- t += 1;
1444
- if (t > 1)
1445
- t -= 1;
1446
- if (t < 1 / 6)
1447
- return p + (q - p) * 6 * t;
1448
- if (t < 1 / 2)
1449
- return q;
1450
- if (t < 2 / 3)
1451
- return p + (q - p) * (2 / 3 - t) * 6;
1452
- return p;
1453
- }
1454
- function hslaToRgba({ hue, saturation, lightness, alpha: alpha2 }) {
1455
- hue /= 360;
1456
- saturation /= 100;
1457
- lightness /= 100;
1458
- let red = 0;
1459
- let green = 0;
1460
- let blue = 0;
1461
- if (!saturation) {
1462
- red = green = blue = lightness;
1463
- } else {
1464
- const q = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
1465
- const p = 2 * lightness - q;
1466
- red = hueToRgb(p, q, hue + 1 / 3);
1467
- green = hueToRgb(p, q, hue);
1468
- blue = hueToRgb(p, q, hue - 1 / 3);
1469
- }
1470
- return {
1471
- red: Math.round(red * 255),
1472
- green: Math.round(green * 255),
1473
- blue: Math.round(blue * 255),
1474
- alpha: alpha2
1475
- };
1476
- }
1477
- function mixImmediate(a, b) {
1478
- return (p) => p > 0 ? b : a;
1479
- }
1480
- const mixLinearColor = (from, to, v) => {
1481
- const fromExpo = from * from;
1482
- const expo = v * (to * to - fromExpo) + fromExpo;
1483
- return expo < 0 ? 0 : Math.sqrt(expo);
1484
- };
1485
- const colorTypes = [hex, rgba, hsla];
1486
- const getColorType = (v) => colorTypes.find((type) => type.test(v));
1487
- function asRGBA(color2) {
1488
- const type = getColorType(color2);
1489
- warning(Boolean(type), `'${color2}' is not an animatable color. Use the equivalent color code instead.`);
1490
- if (!Boolean(type))
1491
- return false;
1492
- let model = type.parse(color2);
1493
- if (type === hsla) {
1494
- model = hslaToRgba(model);
1495
- }
1496
- return model;
1497
- }
1498
- const mixColor = (from, to) => {
1499
- const fromRGBA = asRGBA(from);
1500
- const toRGBA = asRGBA(to);
1501
- if (!fromRGBA || !toRGBA) {
1502
- return mixImmediate(from, to);
1503
- }
1504
- const blended = { ...fromRGBA };
1505
- return (v) => {
1506
- blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v);
1507
- blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v);
1508
- blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v);
1509
- blended.alpha = mixNumber$1(fromRGBA.alpha, toRGBA.alpha, v);
1510
- return rgba.transform(blended);
1511
- };
1512
- };
1513
- const invisibleValues = /* @__PURE__ */ new Set(["none", "hidden"]);
1514
- function mixVisibility(origin, target) {
1515
- if (invisibleValues.has(origin)) {
1516
- return (p) => p <= 0 ? origin : target;
1517
- } else {
1518
- return (p) => p >= 1 ? target : origin;
1519
- }
1520
- }
1521
- function mixNumber(a, b) {
1522
- return (p) => mixNumber$1(a, b, p);
1523
- }
1524
- function getMixer(a) {
1525
- if (typeof a === "number") {
1526
- return mixNumber;
1527
- } else if (typeof a === "string") {
1528
- return isCSSVariableToken(a) ? mixImmediate : color.test(a) ? mixColor : mixComplex;
1529
- } else if (Array.isArray(a)) {
1530
- return mixArray;
1531
- } else if (typeof a === "object") {
1532
- return color.test(a) ? mixColor : mixObject;
1533
- }
1534
- return mixImmediate;
1535
- }
1536
- function mixArray(a, b) {
1537
- const output = [...a];
1538
- const numValues = output.length;
1539
- const blendValue = a.map((v, i) => getMixer(v)(v, b[i]));
1540
- return (p) => {
1541
- for (let i = 0; i < numValues; i++) {
1542
- output[i] = blendValue[i](p);
1543
- }
1544
- return output;
1545
- };
1546
- }
1547
- function mixObject(a, b) {
1548
- const output = { ...a, ...b };
1549
- const blendValue = {};
1550
- for (const key in output) {
1551
- if (a[key] !== void 0 && b[key] !== void 0) {
1552
- blendValue[key] = getMixer(a[key])(a[key], b[key]);
1553
- }
1554
- }
1555
- return (v) => {
1556
- for (const key in blendValue) {
1557
- output[key] = blendValue[key](v);
1558
- }
1559
- return output;
1560
- };
1561
- }
1562
- function matchOrder(origin, target) {
1563
- var _a;
1564
- const orderedOrigin = [];
1565
- const pointers = { color: 0, var: 0, number: 0 };
1566
- for (let i = 0; i < target.values.length; i++) {
1567
- const type = target.types[i];
1568
- const originIndex = origin.indexes[type][pointers[type]];
1569
- const originValue = (_a = origin.values[originIndex]) !== null && _a !== void 0 ? _a : 0;
1570
- orderedOrigin[i] = originValue;
1571
- pointers[type]++;
1572
- }
1573
- return orderedOrigin;
1574
- }
1575
- const mixComplex = (origin, target) => {
1576
- const template = complex.createTransformer(target);
1577
- const originStats = analyseComplexValue(origin);
1578
- const targetStats = analyseComplexValue(target);
1579
- const canInterpolate = originStats.indexes.var.length === targetStats.indexes.var.length && originStats.indexes.color.length === targetStats.indexes.color.length && originStats.indexes.number.length >= targetStats.indexes.number.length;
1580
- if (canInterpolate) {
1581
- if (invisibleValues.has(origin) && !targetStats.values.length || invisibleValues.has(target) && !originStats.values.length) {
1582
- return mixVisibility(origin, target);
1583
- }
1584
- return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template);
1585
- } else {
1586
- 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.`);
1587
- return mixImmediate(origin, target);
1588
- }
1589
- };
1590
- function mix(from, to, p) {
1591
- if (typeof from === "number" && typeof to === "number" && typeof p === "number") {
1592
- return mixNumber$1(from, to, p);
1593
- }
1594
- const mixer = getMixer(from);
1595
- return mixer(from, to);
1596
- }
1597
- function createMixers(output, ease2, customMixer) {
1598
- const mixers = [];
1599
- const mixerFactory = customMixer || mix;
1600
- const numMixers = output.length - 1;
1601
- for (let i = 0; i < numMixers; i++) {
1602
- let mixer = mixerFactory(output[i], output[i + 1]);
1603
- if (ease2) {
1604
- const easingFunction = Array.isArray(ease2) ? ease2[i] || noop : ease2;
1605
- mixer = pipe(easingFunction, mixer);
1606
- }
1607
- mixers.push(mixer);
1608
- }
1609
- return mixers;
1610
- }
1611
- function interpolate(input, output, { clamp: isClamp = true, ease: ease2, mixer } = {}) {
1612
- const inputLength = input.length;
1613
- invariant(inputLength === output.length, "Both input and output ranges must be the same length");
1614
- if (inputLength === 1)
1615
- return () => output[0];
1616
- if (inputLength === 2 && input[0] === input[1])
1617
- return () => output[1];
1618
- if (input[0] > input[inputLength - 1]) {
1619
- input = [...input].reverse();
1620
- output = [...output].reverse();
1621
- }
1622
- const mixers = createMixers(output, ease2, mixer);
1623
- const numMixers = mixers.length;
1624
- const interpolator = (v) => {
1625
- let i = 0;
1626
- if (numMixers > 1) {
1627
- for (; i < input.length - 2; i++) {
1628
- if (v < input[i + 1])
1629
- break;
1630
- }
1631
- }
1632
- const progressInRange = progress(input[i], input[i + 1], v);
1633
- return mixers[i](progressInRange);
1634
- };
1635
- return isClamp ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v)) : interpolator;
1636
- }
1637
- function fillOffset(offset, remaining) {
1638
- const min = offset[offset.length - 1];
1639
- for (let i = 1; i <= remaining; i++) {
1640
- const offsetProgress = progress(0, remaining, i);
1641
- offset.push(mixNumber$1(min, 1, offsetProgress));
1642
- }
1643
- }
1644
- function defaultOffset(arr) {
1645
- const offset = [0];
1646
- fillOffset(offset, arr.length - 1);
1647
- return offset;
1648
- }
1649
- function convertOffsetToTimes(offset, duration) {
1650
- return offset.map((o) => o * duration);
1651
- }
1652
- function defaultEasing(values, easing) {
1653
- return values.map(() => easing || easeInOut).splice(0, values.length - 1);
1654
- }
1655
- function keyframes({ duration = 300, keyframes: keyframeValues, times, ease: ease2 = "easeInOut" }) {
1656
- const easingFunctions = isEasingArray(ease2) ? ease2.map(easingDefinitionToFunction) : easingDefinitionToFunction(ease2);
1657
- const state = {
1658
- done: false,
1659
- value: keyframeValues[0]
1660
- };
1661
- const absoluteTimes = convertOffsetToTimes(
1662
- // Only use the provided offsets if they're the correct length
1663
- // TODO Maybe we should warn here if there's a length mismatch
1664
- times && times.length === keyframeValues.length ? times : defaultOffset(keyframeValues),
1665
- duration
1666
- );
1667
- const mapTimeToKeyframe = interpolate(absoluteTimes, keyframeValues, {
1668
- ease: Array.isArray(easingFunctions) ? easingFunctions : defaultEasing(keyframeValues, easingFunctions)
1669
- });
1670
- return {
1671
- calculatedDuration: duration,
1672
- next: (t) => {
1673
- state.value = mapTimeToKeyframe(t);
1674
- state.done = t >= duration;
1675
- return state;
1676
- }
1677
- };
1678
- }
1679
- const frameloopDriver = (update) => {
1680
- const passTimestamp = ({ timestamp }) => update(timestamp);
1681
- return {
1682
- start: () => frame.update(passTimestamp, true),
1683
- stop: () => cancelFrame(passTimestamp),
1684
- /**
1685
- * If we're processing this frame we can use the
1686
- * framelocked timestamp to keep things in sync.
1687
- */
1688
- now: () => frameData.isProcessing ? frameData.timestamp : time.now()
1689
- };
1690
- };
1691
- const generators = {
1692
- decay: inertia,
1693
- inertia,
1694
- tween: keyframes,
1695
- keyframes,
1696
- spring
1697
- };
1698
- const percentToProgress = (percent2) => percent2 / 100;
1699
- class MainThreadAnimation extends BaseAnimation {
1700
- constructor(options) {
1701
- super(options);
1702
- this.holdTime = null;
1703
- this.cancelTime = null;
1704
- this.currentTime = 0;
1705
- this.playbackSpeed = 1;
1706
- this.pendingPlayState = "running";
1707
- this.startTime = null;
1708
- this.state = "idle";
1709
- this.stop = () => {
1710
- this.resolver.cancel();
1711
- this.isStopped = true;
1712
- if (this.state === "idle")
1713
- return;
1714
- this.teardown();
1715
- const { onStop } = this.options;
1716
- onStop && onStop();
1717
- };
1718
- const { name, motionValue: motionValue2, element, keyframes: keyframes2 } = this.options;
1719
- const KeyframeResolver$1 = (element === null || element === void 0 ? void 0 : element.KeyframeResolver) || KeyframeResolver;
1720
- const onResolved = (resolvedKeyframes, finalKeyframe) => this.onKeyframesResolved(resolvedKeyframes, finalKeyframe);
1721
- this.resolver = new KeyframeResolver$1(keyframes2, onResolved, name, motionValue2, element);
1722
- this.resolver.scheduleResolve();
1723
- }
1724
- flatten() {
1725
- super.flatten();
1726
- if (this._resolved) {
1727
- Object.assign(this._resolved, this.initPlayback(this._resolved.keyframes));
1728
- }
1729
- }
1730
- initPlayback(keyframes$1) {
1731
- const { type = "keyframes", repeat = 0, repeatDelay = 0, repeatType, velocity = 0 } = this.options;
1732
- const generatorFactory = isGenerator(type) ? type : generators[type] || keyframes;
1733
- let mapPercentToKeyframes;
1734
- let mirroredGenerator;
1735
- if (generatorFactory !== keyframes && typeof keyframes$1[0] !== "number") {
1736
- if (process.env.NODE_ENV !== "production") {
1737
- invariant(keyframes$1.length === 2, `Only two keyframes currently supported with spring and inertia animations. Trying to animate ${keyframes$1}`);
1738
- }
1739
- mapPercentToKeyframes = pipe(percentToProgress, mix(keyframes$1[0], keyframes$1[1]));
1740
- keyframes$1 = [0, 100];
1741
- }
1742
- const generator = generatorFactory({ ...this.options, keyframes: keyframes$1 });
1743
- if (repeatType === "mirror") {
1744
- mirroredGenerator = generatorFactory({
1745
- ...this.options,
1746
- keyframes: [...keyframes$1].reverse(),
1747
- velocity: -velocity
1748
- });
1749
- }
1750
- if (generator.calculatedDuration === null) {
1751
- generator.calculatedDuration = calcGeneratorDuration(generator);
1752
- }
1753
- const { calculatedDuration } = generator;
1754
- const resolvedDuration = calculatedDuration + repeatDelay;
1755
- const totalDuration = resolvedDuration * (repeat + 1) - repeatDelay;
1756
- return {
1757
- generator,
1758
- mirroredGenerator,
1759
- mapPercentToKeyframes,
1760
- calculatedDuration,
1761
- resolvedDuration,
1762
- totalDuration
1763
- };
1764
- }
1765
- onPostResolved() {
1766
- const { autoplay = true } = this.options;
1767
- this.play();
1768
- if (this.pendingPlayState === "paused" || !autoplay) {
1769
- this.pause();
1770
- } else {
1771
- this.state = this.pendingPlayState;
1772
- }
1773
- }
1774
- tick(timestamp, sample = false) {
1775
- const { resolved } = this;
1776
- if (!resolved) {
1777
- const { keyframes: keyframes3 } = this.options;
1778
- return { done: true, value: keyframes3[keyframes3.length - 1] };
1779
- }
1780
- const { finalKeyframe, generator, mirroredGenerator, mapPercentToKeyframes, keyframes: keyframes2, calculatedDuration, totalDuration, resolvedDuration } = resolved;
1781
- if (this.startTime === null)
1782
- return generator.next(0);
1783
- const { delay, repeat, repeatType, repeatDelay, onUpdate } = this.options;
1784
- if (this.speed > 0) {
1785
- this.startTime = Math.min(this.startTime, timestamp);
1786
- } else if (this.speed < 0) {
1787
- this.startTime = Math.min(timestamp - totalDuration / this.speed, this.startTime);
1788
- }
1789
- if (sample) {
1790
- this.currentTime = timestamp;
1791
- } else if (this.holdTime !== null) {
1792
- this.currentTime = this.holdTime;
1793
- } else {
1794
- this.currentTime = Math.round(timestamp - this.startTime) * this.speed;
1795
- }
1796
- const timeWithoutDelay = this.currentTime - delay * (this.speed >= 0 ? 1 : -1);
1797
- const isInDelayPhase = this.speed >= 0 ? timeWithoutDelay < 0 : timeWithoutDelay > totalDuration;
1798
- this.currentTime = Math.max(timeWithoutDelay, 0);
1799
- if (this.state === "finished" && this.holdTime === null) {
1800
- this.currentTime = totalDuration;
1801
- }
1802
- let elapsed = this.currentTime;
1803
- let frameGenerator = generator;
1804
- if (repeat) {
1805
- const progress2 = Math.min(this.currentTime, totalDuration) / resolvedDuration;
1806
- let currentIteration = Math.floor(progress2);
1807
- let iterationProgress = progress2 % 1;
1808
- if (!iterationProgress && progress2 >= 1) {
1809
- iterationProgress = 1;
1810
- }
1811
- iterationProgress === 1 && currentIteration--;
1812
- currentIteration = Math.min(currentIteration, repeat + 1);
1813
- const isOddIteration = Boolean(currentIteration % 2);
1814
- if (isOddIteration) {
1815
- if (repeatType === "reverse") {
1816
- iterationProgress = 1 - iterationProgress;
1817
- if (repeatDelay) {
1818
- iterationProgress -= repeatDelay / resolvedDuration;
1819
- }
1820
- } else if (repeatType === "mirror") {
1821
- frameGenerator = mirroredGenerator;
1822
- }
1823
- }
1824
- elapsed = clamp(0, 1, iterationProgress) * resolvedDuration;
1825
- }
1826
- const state = isInDelayPhase ? { done: false, value: keyframes2[0] } : frameGenerator.next(elapsed);
1827
- if (mapPercentToKeyframes) {
1828
- state.value = mapPercentToKeyframes(state.value);
1829
- }
1830
- let { done } = state;
1831
- if (!isInDelayPhase && calculatedDuration !== null) {
1832
- done = this.speed >= 0 ? this.currentTime >= totalDuration : this.currentTime <= 0;
1833
- }
1834
- const isAnimationFinished = this.holdTime === null && (this.state === "finished" || this.state === "running" && done);
1835
- if (isAnimationFinished && finalKeyframe !== void 0) {
1836
- state.value = getFinalKeyframe(keyframes2, this.options, finalKeyframe);
1837
- }
1838
- if (onUpdate) {
1839
- onUpdate(state.value);
1840
- }
1841
- if (isAnimationFinished) {
1842
- this.finish();
1843
- }
1844
- return state;
1845
- }
1846
- get duration() {
1847
- const { resolved } = this;
1848
- return resolved ? millisecondsToSeconds(resolved.calculatedDuration) : 0;
1849
- }
1850
- get time() {
1851
- return millisecondsToSeconds(this.currentTime);
1852
- }
1853
- set time(newTime) {
1854
- newTime = secondsToMilliseconds(newTime);
1855
- this.currentTime = newTime;
1856
- if (this.holdTime !== null || this.speed === 0) {
1857
- this.holdTime = newTime;
1858
- } else if (this.driver) {
1859
- this.startTime = this.driver.now() - newTime / this.speed;
1860
- }
1861
- }
1862
- get speed() {
1863
- return this.playbackSpeed;
1864
- }
1865
- set speed(newSpeed) {
1866
- const hasChanged = this.playbackSpeed !== newSpeed;
1867
- this.playbackSpeed = newSpeed;
1868
- if (hasChanged) {
1869
- this.time = millisecondsToSeconds(this.currentTime);
1870
- }
1871
- }
1872
- play() {
1873
- if (!this.resolver.isScheduled) {
1874
- this.resolver.resume();
1875
- }
1876
- if (!this._resolved) {
1877
- this.pendingPlayState = "running";
1878
- return;
1879
- }
1880
- if (this.isStopped)
1881
- return;
1882
- const { driver = frameloopDriver, onPlay, startTime } = this.options;
1883
- if (!this.driver) {
1884
- this.driver = driver((timestamp) => this.tick(timestamp));
1885
- }
1886
- onPlay && onPlay();
1887
- const now2 = this.driver.now();
1888
- if (this.holdTime !== null) {
1889
- this.startTime = now2 - this.holdTime;
1890
- } else if (!this.startTime) {
1891
- this.startTime = startTime !== null && startTime !== void 0 ? startTime : this.calcStartTime();
1892
- } else if (this.state === "finished") {
1893
- this.startTime = now2;
1894
- }
1895
- if (this.state === "finished") {
1896
- this.updateFinishedPromise();
1897
- }
1898
- this.cancelTime = this.startTime;
1899
- this.holdTime = null;
1900
- this.state = "running";
1901
- this.driver.start();
1902
- }
1903
- pause() {
1904
- var _a;
1905
- if (!this._resolved) {
1906
- this.pendingPlayState = "paused";
1907
- return;
1908
- }
1909
- this.state = "paused";
1910
- this.holdTime = (_a = this.currentTime) !== null && _a !== void 0 ? _a : 0;
1911
- }
1912
- complete() {
1913
- if (this.state !== "running") {
1914
- this.play();
1915
- }
1916
- this.pendingPlayState = this.state = "finished";
1917
- this.holdTime = null;
1918
- }
1919
- finish() {
1920
- this.teardown();
1921
- this.state = "finished";
1922
- const { onComplete } = this.options;
1923
- onComplete && onComplete();
1924
- }
1925
- cancel() {
1926
- if (this.cancelTime !== null) {
1927
- this.tick(this.cancelTime);
1928
- }
1929
- this.teardown();
1930
- this.updateFinishedPromise();
1931
- }
1932
- teardown() {
1933
- this.state = "idle";
1934
- this.stopDriver();
1935
- this.resolveFinishedPromise();
1936
- this.updateFinishedPromise();
1937
- this.startTime = this.cancelTime = null;
1938
- this.resolver.cancel();
1939
- }
1940
- stopDriver() {
1941
- if (!this.driver)
1942
- return;
1943
- this.driver.stop();
1944
- this.driver = void 0;
1945
- }
1946
- sample(time2) {
1947
- this.startTime = 0;
1948
- return this.tick(time2, true);
1949
- }
1950
- }
1951
- const acceleratedValues = /* @__PURE__ */ new Set([
1952
- "opacity",
1953
- "clipPath",
1954
- "filter",
1955
- "transform"
1956
- // TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved
1957
- // or until we implement support for linear() easing.
1958
- // "background-color"
1959
- ]);
1960
- function memo(callback) {
1961
- let result;
1962
- return () => {
1963
- if (result === void 0)
1964
- result = callback();
1965
- return result;
1966
- };
1967
- }
1968
- const supportsFlags = {
1969
- linearEasing: void 0
1970
- };
1971
- function memoSupports(callback, supportsFlag) {
1972
- const memoized = memo(callback);
1973
- return () => {
1974
- var _a;
1975
- return (_a = supportsFlags[supportsFlag]) !== null && _a !== void 0 ? _a : memoized();
1976
- };
1977
- }
1978
- const supportsLinearEasing = /* @__PURE__ */ memoSupports(() => {
1979
- try {
1980
- document.createElement("div").animate({ opacity: 0 }, { easing: "linear(0, 1)" });
1981
- } catch (e) {
1982
- return false;
1983
- }
1984
- return true;
1985
- }, "linearEasing");
1986
- function isWaapiSupportedEasing(easing) {
1987
- return Boolean(typeof easing === "function" && supportsLinearEasing() || !easing || typeof easing === "string" && (easing in supportedWaapiEasing || supportsLinearEasing()) || isBezierDefinition(easing) || Array.isArray(easing) && easing.every(isWaapiSupportedEasing));
1988
- }
1989
- const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
1990
- const supportedWaapiEasing = {
1991
- linear: "linear",
1992
- ease: "ease",
1993
- easeIn: "ease-in",
1994
- easeOut: "ease-out",
1995
- easeInOut: "ease-in-out",
1996
- circIn: /* @__PURE__ */ cubicBezierAsString([0, 0.65, 0.55, 1]),
1997
- circOut: /* @__PURE__ */ cubicBezierAsString([0.55, 0, 1, 0.45]),
1998
- backIn: /* @__PURE__ */ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),
1999
- backOut: /* @__PURE__ */ cubicBezierAsString([0.33, 1.53, 0.69, 0.99])
2000
- };
2001
- function mapEasingToNativeEasing(easing, duration) {
2002
- if (!easing) {
2003
- return void 0;
2004
- } else if (typeof easing === "function" && supportsLinearEasing()) {
2005
- return generateLinearEasing(easing, duration);
2006
- } else if (isBezierDefinition(easing)) {
2007
- return cubicBezierAsString(easing);
2008
- } else if (Array.isArray(easing)) {
2009
- return easing.map((segmentEasing) => mapEasingToNativeEasing(segmentEasing, duration) || supportedWaapiEasing.easeOut);
2010
- } else {
2011
- return supportedWaapiEasing[easing];
2012
- }
2013
- }
2014
- function startWaapiAnimation(element, valueName, keyframes2, { delay = 0, duration = 300, repeat = 0, repeatType = "loop", ease: ease2 = "easeInOut", times } = {}) {
2015
- const keyframeOptions = { [valueName]: keyframes2 };
2016
- if (times)
2017
- keyframeOptions.offset = times;
2018
- const easing = mapEasingToNativeEasing(ease2, duration);
2019
- if (Array.isArray(easing))
2020
- keyframeOptions.easing = easing;
2021
- return element.animate(keyframeOptions, {
2022
- delay,
2023
- duration,
2024
- easing: !Array.isArray(easing) ? easing : "linear",
2025
- fill: "both",
2026
- iterations: repeat + 1,
2027
- direction: repeatType === "reverse" ? "alternate" : "normal"
2028
- });
2029
- }
2030
- function attachTimeline(animation, timeline) {
2031
- animation.timeline = timeline;
2032
- animation.onfinish = null;
2033
- }
2034
- const supportsWaapi = /* @__PURE__ */ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
2035
- const sampleDelta = 10;
2036
- const maxDuration = 2e4;
2037
- function requiresPregeneratedKeyframes(options) {
2038
- return isGenerator(options.type) || options.type === "spring" || !isWaapiSupportedEasing(options.ease);
2039
- }
2040
- function pregenerateKeyframes(keyframes2, options) {
2041
- const sampleAnimation = new MainThreadAnimation({
2042
- ...options,
2043
- keyframes: keyframes2,
2044
- repeat: 0,
2045
- delay: 0,
2046
- isGenerator: true
2047
- });
2048
- let state = { done: false, value: keyframes2[0] };
2049
- const pregeneratedKeyframes = [];
2050
- let t = 0;
2051
- while (!state.done && t < maxDuration) {
2052
- state = sampleAnimation.sample(t);
2053
- pregeneratedKeyframes.push(state.value);
2054
- t += sampleDelta;
2055
- }
2056
- return {
2057
- times: void 0,
2058
- keyframes: pregeneratedKeyframes,
2059
- duration: t - sampleDelta,
2060
- ease: "linear"
2061
- };
2062
- }
2063
- const unsupportedEasingFunctions = {
2064
- anticipate,
2065
- backInOut,
2066
- circInOut
2067
- };
2068
- function isUnsupportedEase(key) {
2069
- return key in unsupportedEasingFunctions;
2070
- }
2071
- class AcceleratedAnimation extends BaseAnimation {
2072
- constructor(options) {
2073
- super(options);
2074
- const { name, motionValue: motionValue2, element, keyframes: keyframes2 } = this.options;
2075
- this.resolver = new DOMKeyframesResolver(keyframes2, (resolvedKeyframes, finalKeyframe) => this.onKeyframesResolved(resolvedKeyframes, finalKeyframe), name, motionValue2, element);
2076
- this.resolver.scheduleResolve();
2077
- }
2078
- initPlayback(keyframes2, finalKeyframe) {
2079
- var _a;
2080
- let { duration = 300, times, ease: ease2, type, motionValue: motionValue2, name, startTime } = this.options;
2081
- if (!((_a = motionValue2.owner) === null || _a === void 0 ? void 0 : _a.current)) {
2082
- return false;
2083
- }
2084
- if (typeof ease2 === "string" && supportsLinearEasing() && isUnsupportedEase(ease2)) {
2085
- ease2 = unsupportedEasingFunctions[ease2];
2086
- }
2087
- if (requiresPregeneratedKeyframes(this.options)) {
2088
- const { onComplete, onUpdate, motionValue: motionValue3, element, ...options } = this.options;
2089
- const pregeneratedAnimation = pregenerateKeyframes(keyframes2, options);
2090
- keyframes2 = pregeneratedAnimation.keyframes;
2091
- if (keyframes2.length === 1) {
2092
- keyframes2[1] = keyframes2[0];
2093
- }
2094
- duration = pregeneratedAnimation.duration;
2095
- times = pregeneratedAnimation.times;
2096
- ease2 = pregeneratedAnimation.ease;
2097
- type = "keyframes";
2098
- }
2099
- const animation = startWaapiAnimation(motionValue2.owner.current, name, keyframes2, { ...this.options, duration, times, ease: ease2 });
2100
- animation.startTime = startTime !== null && startTime !== void 0 ? startTime : this.calcStartTime();
2101
- if (this.pendingTimeline) {
2102
- attachTimeline(animation, this.pendingTimeline);
2103
- this.pendingTimeline = void 0;
2104
- } else {
2105
- animation.onfinish = () => {
2106
- const { onComplete } = this.options;
2107
- motionValue2.set(getFinalKeyframe(keyframes2, this.options, finalKeyframe));
2108
- onComplete && onComplete();
2109
- this.cancel();
2110
- this.resolveFinishedPromise();
2111
- };
2112
- }
2113
- return {
2114
- animation,
2115
- duration,
2116
- times,
2117
- type,
2118
- ease: ease2,
2119
- keyframes: keyframes2
2120
- };
2121
- }
2122
- get duration() {
2123
- const { resolved } = this;
2124
- if (!resolved)
2125
- return 0;
2126
- const { duration } = resolved;
2127
- return millisecondsToSeconds(duration);
2128
- }
2129
- get time() {
2130
- const { resolved } = this;
2131
- if (!resolved)
2132
- return 0;
2133
- const { animation } = resolved;
2134
- return millisecondsToSeconds(animation.currentTime || 0);
2135
- }
2136
- set time(newTime) {
2137
- const { resolved } = this;
2138
- if (!resolved)
2139
- return;
2140
- const { animation } = resolved;
2141
- animation.currentTime = secondsToMilliseconds(newTime);
2142
- }
2143
- get speed() {
2144
- const { resolved } = this;
2145
- if (!resolved)
2146
- return 1;
2147
- const { animation } = resolved;
2148
- return animation.playbackRate;
2149
- }
2150
- set speed(newSpeed) {
2151
- const { resolved } = this;
2152
- if (!resolved)
2153
- return;
2154
- const { animation } = resolved;
2155
- animation.playbackRate = newSpeed;
2156
- }
2157
- get state() {
2158
- const { resolved } = this;
2159
- if (!resolved)
2160
- return "idle";
2161
- const { animation } = resolved;
2162
- return animation.playState;
2163
- }
2164
- get startTime() {
2165
- const { resolved } = this;
2166
- if (!resolved)
2167
- return null;
2168
- const { animation } = resolved;
2169
- return animation.startTime;
2170
- }
2171
- /**
2172
- * Replace the default DocumentTimeline with another AnimationTimeline.
2173
- * Currently used for scroll animations.
2174
- */
2175
- attachTimeline(timeline) {
2176
- if (!this._resolved) {
2177
- this.pendingTimeline = timeline;
2178
- } else {
2179
- const { resolved } = this;
2180
- if (!resolved)
2181
- return noop;
2182
- const { animation } = resolved;
2183
- attachTimeline(animation, timeline);
2184
- }
2185
- return noop;
2186
- }
2187
- play() {
2188
- if (this.isStopped)
2189
- return;
2190
- const { resolved } = this;
2191
- if (!resolved)
2192
- return;
2193
- const { animation } = resolved;
2194
- if (animation.playState === "finished") {
2195
- this.updateFinishedPromise();
2196
- }
2197
- animation.play();
2198
- }
2199
- pause() {
2200
- const { resolved } = this;
2201
- if (!resolved)
2202
- return;
2203
- const { animation } = resolved;
2204
- animation.pause();
2205
- }
2206
- stop() {
2207
- this.resolver.cancel();
2208
- this.isStopped = true;
2209
- if (this.state === "idle")
2210
- return;
2211
- this.resolveFinishedPromise();
2212
- this.updateFinishedPromise();
2213
- const { resolved } = this;
2214
- if (!resolved)
2215
- return;
2216
- const { animation, keyframes: keyframes2, duration, type, ease: ease2, times } = resolved;
2217
- if (animation.playState === "idle" || animation.playState === "finished") {
2218
- return;
2219
- }
2220
- if (this.time) {
2221
- const { motionValue: motionValue2, onUpdate, onComplete, element, ...options } = this.options;
2222
- const sampleAnimation = new MainThreadAnimation({
2223
- ...options,
2224
- keyframes: keyframes2,
2225
- duration,
2226
- type,
2227
- ease: ease2,
2228
- times,
2229
- isGenerator: true
2230
- });
2231
- const sampleTime = secondsToMilliseconds(this.time);
2232
- motionValue2.setWithVelocity(sampleAnimation.sample(sampleTime - sampleDelta).value, sampleAnimation.sample(sampleTime).value, sampleDelta);
2233
- }
2234
- const { onStop } = this.options;
2235
- onStop && onStop();
2236
- this.cancel();
2237
- }
2238
- complete() {
2239
- const { resolved } = this;
2240
- if (!resolved)
2241
- return;
2242
- resolved.animation.finish();
2243
- }
2244
- cancel() {
2245
- const { resolved } = this;
2246
- if (!resolved)
2247
- return;
2248
- resolved.animation.cancel();
2249
- }
2250
- static supports(options) {
2251
- const { motionValue: motionValue2, name, repeatDelay, repeatType, damping, type } = options;
2252
- return supportsWaapi() && name && acceleratedValues.has(name) && motionValue2 && motionValue2.owner && motionValue2.owner.current instanceof HTMLElement && /**
2253
- * If we're outputting values to onUpdate then we can't use WAAPI as there's
2254
- * no way to read the value from WAAPI every frame.
2255
- */
2256
- !motionValue2.owner.getProps().onUpdate && !repeatDelay && repeatType !== "mirror" && damping !== 0 && type !== "inertia";
2257
- }
2258
- }
2259
- const supportsScrollTimeline = memo(() => window.ScrollTimeline !== void 0);
2260
- class GroupPlaybackControls {
2261
- constructor(animations) {
2262
- this.stop = () => this.runAll("stop");
2263
- this.animations = animations.filter(Boolean);
2264
- }
2265
- then(onResolve, onReject) {
2266
- return Promise.all(this.animations).then(onResolve).catch(onReject);
2267
- }
2268
- /**
2269
- * TODO: Filter out cancelled or stopped animations before returning
2270
- */
2271
- getAll(propName) {
2272
- return this.animations[0][propName];
2273
- }
2274
- setAll(propName, newValue) {
2275
- for (let i = 0; i < this.animations.length; i++) {
2276
- this.animations[i][propName] = newValue;
2277
- }
2278
- }
2279
- attachTimeline(timeline, fallback) {
2280
- const subscriptions = this.animations.map((animation) => {
2281
- if (supportsScrollTimeline() && animation.attachTimeline) {
2282
- return animation.attachTimeline(timeline);
2283
- } else {
2284
- return fallback(animation);
2285
- }
2286
- });
2287
- return () => {
2288
- subscriptions.forEach((cancel, i) => {
2289
- cancel && cancel();
2290
- this.animations[i].stop();
2291
- });
2292
- };
2293
- }
2294
- get time() {
2295
- return this.getAll("time");
2296
- }
2297
- set time(time2) {
2298
- this.setAll("time", time2);
2299
- }
2300
- get speed() {
2301
- return this.getAll("speed");
2302
- }
2303
- set speed(speed) {
2304
- this.setAll("speed", speed);
2305
- }
2306
- get startTime() {
2307
- return this.getAll("startTime");
2308
- }
2309
- get duration() {
2310
- let max = 0;
2311
- for (let i = 0; i < this.animations.length; i++) {
2312
- max = Math.max(max, this.animations[i].duration);
2313
- }
2314
- return max;
2315
- }
2316
- runAll(methodName) {
2317
- this.animations.forEach((controls) => controls[methodName]());
2318
- }
2319
- flatten() {
2320
- this.runAll("flatten");
2321
- }
2322
- play() {
2323
- this.runAll("play");
2324
- }
2325
- pause() {
2326
- this.runAll("pause");
2327
- }
2328
- cancel() {
2329
- this.runAll("cancel");
2330
- }
2331
- complete() {
2332
- this.runAll("complete");
2333
- }
2334
- }
2335
- function isTransitionDefined({ when, delay: _delay, delayChildren, staggerChildren, staggerDirection, repeat, repeatType, repeatDelay, from, elapsed, ...transition }) {
2336
- return !!Object.keys(transition).length;
2337
- }
2338
- const animateMotionValue = (name, value, target, transition = {}, element, isHandoff) => (onComplete) => {
2339
- const valueTransition = getValueTransition$1(transition, name) || {};
2340
- const delay = valueTransition.delay || transition.delay || 0;
2341
- let { elapsed = 0 } = transition;
2342
- elapsed = elapsed - secondsToMilliseconds(delay);
2343
- let options = {
2344
- keyframes: Array.isArray(target) ? target : [null, target],
2345
- ease: "easeOut",
2346
- velocity: value.getVelocity(),
2347
- ...valueTransition,
2348
- delay: -elapsed,
2349
- onUpdate: (v) => {
2350
- value.set(v);
2351
- valueTransition.onUpdate && valueTransition.onUpdate(v);
2352
- },
2353
- onComplete: () => {
2354
- onComplete();
2355
- valueTransition.onComplete && valueTransition.onComplete();
2356
- },
2357
- name,
2358
- motionValue: value,
2359
- element: isHandoff ? void 0 : element
2360
- };
2361
- if (!isTransitionDefined(valueTransition)) {
2362
- options = {
2363
- ...options,
2364
- ...getDefaultTransition(name, options)
2365
- };
2366
- }
2367
- if (options.duration) {
2368
- options.duration = secondsToMilliseconds(options.duration);
2369
- }
2370
- if (options.repeatDelay) {
2371
- options.repeatDelay = secondsToMilliseconds(options.repeatDelay);
2372
- }
2373
- if (options.from !== void 0) {
2374
- options.keyframes[0] = options.from;
2375
- }
2376
- let shouldSkip = false;
2377
- if (options.type === false || options.duration === 0 && !options.repeatDelay) {
2378
- options.duration = 0;
2379
- if (options.delay === 0) {
2380
- shouldSkip = true;
2381
- }
2382
- }
2383
- if (shouldSkip && !isHandoff && value.get() !== void 0) {
2384
- const finalKeyframe = getFinalKeyframe(options.keyframes, valueTransition);
2385
- if (finalKeyframe !== void 0) {
2386
- frame.update(() => {
2387
- options.onUpdate(finalKeyframe);
2388
- options.onComplete();
2389
- });
2390
- return new GroupPlaybackControls([]);
2391
- }
2392
- }
2393
- if (!isHandoff && AcceleratedAnimation.supports(options)) {
2394
- return new AcceleratedAnimation(options);
2395
- } else {
2396
- return new MainThreadAnimation(options);
2397
- }
2398
- };
2399
- const resolveFinalValueInKeyframes = (v) => {
2400
- return isKeyframesTarget(v) ? v[v.length - 1] || 0 : v;
2401
- };
2402
- function addUniqueItem(arr, item) {
2403
- if (arr.indexOf(item) === -1)
2404
- arr.push(item);
2405
- }
2406
- function removeItem(arr, item) {
2407
- const index = arr.indexOf(item);
2408
- if (index > -1)
2409
- arr.splice(index, 1);
2410
- }
2411
- class SubscriptionManager {
2412
- constructor() {
2413
- this.subscriptions = [];
2414
- }
2415
- add(handler) {
2416
- addUniqueItem(this.subscriptions, handler);
2417
- return () => removeItem(this.subscriptions, handler);
2418
- }
2419
- notify(a, b, c) {
2420
- const numSubscriptions = this.subscriptions.length;
2421
- if (!numSubscriptions)
2422
- return;
2423
- if (numSubscriptions === 1) {
2424
- this.subscriptions[0](a, b, c);
2425
- } else {
2426
- for (let i = 0; i < numSubscriptions; i++) {
2427
- const handler = this.subscriptions[i];
2428
- handler && handler(a, b, c);
2429
- }
2430
- }
2431
- }
2432
- getSize() {
2433
- return this.subscriptions.length;
2434
- }
2435
- clear() {
2436
- this.subscriptions.length = 0;
2437
- }
2438
- }
2439
- const MAX_VELOCITY_DELTA = 30;
2440
- const isFloat = (value) => {
2441
- return !isNaN(parseFloat(value));
2442
- };
2443
- class MotionValue {
2444
- /**
2445
- * @param init - The initiating value
2446
- * @param config - Optional configuration options
2447
- *
2448
- * - `transformer`: A function to transform incoming values with.
2449
- *
2450
- * @internal
2451
- */
2452
- constructor(init, options = {}) {
2453
- this.version = "11.14.3";
2454
- this.canTrackVelocity = null;
2455
- this.events = {};
2456
- this.updateAndNotify = (v, render = true) => {
2457
- const currentTime = time.now();
2458
- if (this.updatedAt !== currentTime) {
2459
- this.setPrevFrameValue();
2460
- }
2461
- this.prev = this.current;
2462
- this.setCurrent(v);
2463
- if (this.current !== this.prev && this.events.change) {
2464
- this.events.change.notify(this.current);
2465
- }
2466
- if (render && this.events.renderRequest) {
2467
- this.events.renderRequest.notify(this.current);
2468
- }
2469
- };
2470
- this.hasAnimated = false;
2471
- this.setCurrent(init);
2472
- this.owner = options.owner;
2473
- }
2474
- setCurrent(current) {
2475
- this.current = current;
2476
- this.updatedAt = time.now();
2477
- if (this.canTrackVelocity === null && current !== void 0) {
2478
- this.canTrackVelocity = isFloat(this.current);
2479
- }
2480
- }
2481
- setPrevFrameValue(prevFrameValue = this.current) {
2482
- this.prevFrameValue = prevFrameValue;
2483
- this.prevUpdatedAt = this.updatedAt;
2484
- }
2485
- /**
2486
- * Adds a function that will be notified when the `MotionValue` is updated.
2487
- *
2488
- * It returns a function that, when called, will cancel the subscription.
2489
- *
2490
- * When calling `onChange` inside a React component, it should be wrapped with the
2491
- * `useEffect` hook. As it returns an unsubscribe function, this should be returned
2492
- * from the `useEffect` function to ensure you don't add duplicate subscribers..
2493
- *
2494
- * ```jsx
2495
- * export const MyComponent = () => {
2496
- * const x = useMotionValue(0)
2497
- * const y = useMotionValue(0)
2498
- * const opacity = useMotionValue(1)
2499
- *
2500
- * useEffect(() => {
2501
- * function updateOpacity() {
2502
- * const maxXY = Math.max(x.get(), y.get())
2503
- * const newOpacity = transform(maxXY, [0, 100], [1, 0])
2504
- * opacity.set(newOpacity)
2505
- * }
2506
- *
2507
- * const unsubscribeX = x.on("change", updateOpacity)
2508
- * const unsubscribeY = y.on("change", updateOpacity)
2509
- *
2510
- * return () => {
2511
- * unsubscribeX()
2512
- * unsubscribeY()
2513
- * }
2514
- * }, [])
2515
- *
2516
- * return <motion.div style={{ x }} />
2517
- * }
2518
- * ```
2519
- *
2520
- * @param subscriber - A function that receives the latest value.
2521
- * @returns A function that, when called, will cancel this subscription.
2522
- *
2523
- * @deprecated
2524
- */
2525
- onChange(subscription) {
2526
- if (process.env.NODE_ENV !== "production") {
2527
- warnOnce(false, `value.onChange(callback) is deprecated. Switch to value.on("change", callback).`);
2528
- }
2529
- return this.on("change", subscription);
2530
- }
2531
- on(eventName, callback) {
2532
- if (!this.events[eventName]) {
2533
- this.events[eventName] = new SubscriptionManager();
2534
- }
2535
- const unsubscribe = this.events[eventName].add(callback);
2536
- if (eventName === "change") {
2537
- return () => {
2538
- unsubscribe();
2539
- frame.read(() => {
2540
- if (!this.events.change.getSize()) {
2541
- this.stop();
2542
- }
2543
- });
2544
- };
2545
- }
2546
- return unsubscribe;
2547
- }
2548
- clearListeners() {
2549
- for (const eventManagers in this.events) {
2550
- this.events[eventManagers].clear();
2551
- }
2552
- }
2553
- /**
2554
- * Attaches a passive effect to the `MotionValue`.
2555
- *
2556
- * @internal
2557
- */
2558
- attach(passiveEffect, stopPassiveEffect) {
2559
- this.passiveEffect = passiveEffect;
2560
- this.stopPassiveEffect = stopPassiveEffect;
2561
- }
2562
- /**
2563
- * Sets the state of the `MotionValue`.
2564
- *
2565
- * @remarks
2566
- *
2567
- * ```jsx
2568
- * const x = useMotionValue(0)
2569
- * x.set(10)
2570
- * ```
2571
- *
2572
- * @param latest - Latest value to set.
2573
- * @param render - Whether to notify render subscribers. Defaults to `true`
2574
- *
2575
- * @public
2576
- */
2577
- set(v, render = true) {
2578
- if (!render || !this.passiveEffect) {
2579
- this.updateAndNotify(v, render);
2580
- } else {
2581
- this.passiveEffect(v, this.updateAndNotify);
2582
- }
2583
- }
2584
- setWithVelocity(prev, current, delta) {
2585
- this.set(current);
2586
- this.prev = void 0;
2587
- this.prevFrameValue = prev;
2588
- this.prevUpdatedAt = this.updatedAt - delta;
2589
- }
2590
- /**
2591
- * Set the state of the `MotionValue`, stopping any active animations,
2592
- * effects, and resets velocity to `0`.
2593
- */
2594
- jump(v, endAnimation = true) {
2595
- this.updateAndNotify(v);
2596
- this.prev = v;
2597
- this.prevUpdatedAt = this.prevFrameValue = void 0;
2598
- endAnimation && this.stop();
2599
- if (this.stopPassiveEffect)
2600
- this.stopPassiveEffect();
2601
- }
2602
- /**
2603
- * Returns the latest state of `MotionValue`
2604
- *
2605
- * @returns - The latest state of `MotionValue`
2606
- *
2607
- * @public
2608
- */
2609
- get() {
2610
- return this.current;
2611
- }
2612
- /**
2613
- * @public
2614
- */
2615
- getPrevious() {
2616
- return this.prev;
2617
- }
2618
- /**
2619
- * Returns the latest velocity of `MotionValue`
2620
- *
2621
- * @returns - The latest velocity of `MotionValue`. Returns `0` if the state is non-numerical.
2622
- *
2623
- * @public
2624
- */
2625
- getVelocity() {
2626
- const currentTime = time.now();
2627
- if (!this.canTrackVelocity || this.prevFrameValue === void 0 || currentTime - this.updatedAt > MAX_VELOCITY_DELTA) {
2628
- return 0;
2629
- }
2630
- const delta = Math.min(this.updatedAt - this.prevUpdatedAt, MAX_VELOCITY_DELTA);
2631
- return velocityPerSecond(parseFloat(this.current) - parseFloat(this.prevFrameValue), delta);
2632
- }
2633
- /**
2634
- * Registers a new animation to control this `MotionValue`. Only one
2635
- * animation can drive a `MotionValue` at one time.
2636
- *
2637
- * ```jsx
2638
- * value.start()
2639
- * ```
2640
- *
2641
- * @param animation - A function that starts the provided animation
2642
- *
2643
- * @internal
2644
- */
2645
- start(startAnimation) {
2646
- this.stop();
2647
- return new Promise((resolve) => {
2648
- this.hasAnimated = true;
2649
- this.animation = startAnimation(resolve);
2650
- if (this.events.animationStart) {
2651
- this.events.animationStart.notify();
2652
- }
2653
- }).then(() => {
2654
- if (this.events.animationComplete) {
2655
- this.events.animationComplete.notify();
2656
- }
2657
- this.clearAnimation();
2658
- });
2659
- }
2660
- /**
2661
- * Stop the currently active animation.
2662
- *
2663
- * @public
2664
- */
2665
- stop() {
2666
- if (this.animation) {
2667
- this.animation.stop();
2668
- if (this.events.animationCancel) {
2669
- this.events.animationCancel.notify();
2670
- }
2671
- }
2672
- this.clearAnimation();
2673
- }
2674
- /**
2675
- * Returns `true` if this value is currently animating.
2676
- *
2677
- * @public
2678
- */
2679
- isAnimating() {
2680
- return !!this.animation;
2681
- }
2682
- clearAnimation() {
2683
- delete this.animation;
2684
- }
2685
- /**
2686
- * Destroy and clean up subscribers to this `MotionValue`.
2687
- *
2688
- * The `MotionValue` hooks like `useMotionValue` and `useTransform` automatically
2689
- * handle the lifecycle of the returned `MotionValue`, so this method is only necessary if you've manually
2690
- * created a `MotionValue` via the `motionValue` function.
2691
- *
2692
- * @public
2693
- */
2694
- destroy() {
2695
- this.clearListeners();
2696
- this.stop();
2697
- if (this.stopPassiveEffect) {
2698
- this.stopPassiveEffect();
2699
- }
2700
- }
2701
- }
2702
- function motionValue(init, options) {
2703
- return new MotionValue(init, options);
2704
- }
2705
- function setMotionValue(visualElement, key, value) {
2706
- if (visualElement.hasValue(key)) {
2707
- visualElement.getValue(key).set(value);
2708
- } else {
2709
- visualElement.addValue(key, motionValue(value));
2710
- }
2711
- }
2712
- function setTarget(visualElement, definition) {
2713
- const resolved = resolveVariant(visualElement, definition);
2714
- let { transitionEnd = {}, transition = {}, ...target } = resolved || {};
2715
- target = { ...target, ...transitionEnd };
2716
- for (const key in target) {
2717
- const value = resolveFinalValueInKeyframes(target[key]);
2718
- setMotionValue(visualElement, key, value);
2719
- }
2720
- }
2721
- const camelToDash = (str) => str.replace(/([a-z])([A-Z])/gu, "$1-$2").toLowerCase();
2722
- const optimizedAppearDataId = "framerAppearId";
2723
- const optimizedAppearDataAttribute = "data-" + camelToDash(optimizedAppearDataId);
2724
- function getOptimisedAppearId(visualElement) {
2725
- return visualElement.props[optimizedAppearDataAttribute];
2726
- }
2727
- const isMotionValue = (value) => Boolean(value && value.getVelocity);
2728
- function isWillChangeMotionValue(value) {
2729
- return Boolean(isMotionValue(value) && value.add);
2730
- }
2731
- function addValueToWillChange(visualElement, key) {
2732
- const willChange = visualElement.getValue("willChange");
2733
- if (isWillChangeMotionValue(willChange)) {
2734
- return willChange.add(key);
2735
- }
2736
- }
2737
- function shouldBlockAnimation({ protectedKeys, needsAnimating }, key) {
2738
- const shouldBlock = protectedKeys.hasOwnProperty(key) && needsAnimating[key] !== true;
2739
- needsAnimating[key] = false;
2740
- return shouldBlock;
2741
- }
2742
- function animateTarget(visualElement, targetAndTransition, { delay = 0, transitionOverride, type } = {}) {
2743
- var _a;
2744
- let { transition = visualElement.getDefaultTransition(), transitionEnd, ...target } = targetAndTransition;
2745
- if (transitionOverride)
2746
- transition = transitionOverride;
2747
- const animations = [];
2748
- const animationTypeState = type && visualElement.animationState && visualElement.animationState.getState()[type];
2749
- for (const key in target) {
2750
- const value = visualElement.getValue(key, (_a = visualElement.latestValues[key]) !== null && _a !== void 0 ? _a : null);
2751
- const valueTarget = target[key];
2752
- if (valueTarget === void 0 || animationTypeState && shouldBlockAnimation(animationTypeState, key)) {
2753
- continue;
2754
- }
2755
- const valueTransition = {
2756
- delay,
2757
- ...getValueTransition$1(transition || {}, key)
2758
- };
2759
- let isHandoff = false;
2760
- if (window.MotionHandoffAnimation) {
2761
- const appearId = getOptimisedAppearId(visualElement);
2762
- if (appearId) {
2763
- const startTime = window.MotionHandoffAnimation(appearId, key, frame);
2764
- if (startTime !== null) {
2765
- valueTransition.startTime = startTime;
2766
- isHandoff = true;
2767
- }
2768
- }
2769
- }
2770
- addValueToWillChange(visualElement, key);
2771
- value.start(animateMotionValue(key, value, valueTarget, visualElement.shouldReduceMotion && transformProps.has(key) ? { type: false } : valueTransition, visualElement, isHandoff));
2772
- const animation = value.animation;
2773
- if (animation) {
2774
- animations.push(animation);
2775
- }
2776
- }
2777
- if (transitionEnd) {
2778
- Promise.all(animations).then(() => {
2779
- frame.update(() => {
2780
- transitionEnd && setTarget(visualElement, transitionEnd);
2781
- });
2782
- });
2783
- }
2784
- return animations;
2785
- }
2786
- const createAxis = () => ({ min: 0, max: 0 });
2787
- const createBox = () => ({
2788
- x: createAxis(),
2789
- y: createAxis()
2790
- });
2791
- function convertBoundingBoxToBox({ top, left, right, bottom }) {
2792
- return {
2793
- x: { min: left, max: right },
2794
- y: { min: top, max: bottom }
2795
- };
2796
- }
2797
- function transformBoxPoints(point, transformPoint) {
2798
- if (!transformPoint)
2799
- return point;
2800
- const topLeft = transformPoint({ x: point.left, y: point.top });
2801
- const bottomRight = transformPoint({ x: point.right, y: point.bottom });
2802
- return {
2803
- top: topLeft.y,
2804
- left: topLeft.x,
2805
- bottom: bottomRight.y,
2806
- right: bottomRight.x
2807
- };
2808
- }
2809
- function measureViewportBox(instance, transformPoint) {
2810
- return convertBoundingBoxToBox(transformBoxPoints(instance.getBoundingClientRect(), transformPoint));
2811
- }
2812
- const scaleCorrectors = {};
2813
- function isSVGElement(element) {
2814
- return element instanceof SVGElement && element.tagName !== "svg";
2815
- }
2816
- function animateSingleValue(value, keyframes2, options) {
2817
- const motionValue$1 = isMotionValue(value) ? value : motionValue(value);
2818
- motionValue$1.start(animateMotionValue("", motionValue$1, keyframes2, options));
2819
- return motionValue$1.animation;
2820
- }
2821
- function resolveElements(elementOrSelector, scope, selectorCache) {
2822
- var _a;
2823
- if (elementOrSelector instanceof Element) {
2824
- return [elementOrSelector];
2825
- } else if (typeof elementOrSelector === "string") {
2826
- let root = document;
2827
- if (scope) {
2828
- root = scope.current;
2829
- }
2830
- const elements = (_a = selectorCache === null || selectorCache === void 0 ? void 0 : selectorCache[elementOrSelector]) !== null && _a !== void 0 ? _a : root.querySelectorAll(elementOrSelector);
2831
- return elements ? Array.from(elements) : [];
2832
- }
2833
- return Array.from(elementOrSelector);
2834
- }
2835
- const isBrowser = typeof window !== "undefined";
2836
- function isControllingVariants(props) {
2837
- return isAnimationControls(props.animate) || variantProps.some((name) => isVariantLabel(props[name]));
2838
- }
2839
- function isVariantNode(props) {
2840
- return Boolean(isControllingVariants(props) || props.variants);
2841
- }
2842
- const featureProps = {
2843
- animation: [
2844
- "animate",
2845
- "variants",
2846
- "whileHover",
2847
- "whileTap",
2848
- "exit",
2849
- "whileInView",
2850
- "whileFocus",
2851
- "whileDrag"
2852
- ],
2853
- exit: ["exit"],
2854
- drag: ["drag", "dragControls"],
2855
- focus: ["whileFocus"],
2856
- hover: ["whileHover", "onHoverStart", "onHoverEnd"],
2857
- tap: ["whileTap", "onTap", "onTapStart", "onTapCancel"],
2858
- pan: ["onPan", "onPanStart", "onPanSessionStart", "onPanEnd"],
2859
- inView: ["whileInView", "onViewportEnter", "onViewportLeave"],
2860
- layout: ["layout", "layoutId"]
2861
- };
2862
- const featureDefinitions = {};
2863
- for (const key in featureProps) {
2864
- featureDefinitions[key] = {
2865
- isEnabled: (props) => featureProps[key].some((name) => !!props[name])
2866
- };
2867
- }
2868
- function renderHTML(element, { style, vars }, styleProp, projection) {
2869
- Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
2870
- for (const key in vars) {
2871
- element.style.setProperty(key, vars[key]);
2872
- }
2873
- }
2874
- const camelCaseAttributes = /* @__PURE__ */ new Set([
2875
- "baseFrequency",
2876
- "diffuseConstant",
2877
- "kernelMatrix",
2878
- "kernelUnitLength",
2879
- "keySplines",
2880
- "keyTimes",
2881
- "limitingConeAngle",
2882
- "markerHeight",
2883
- "markerWidth",
2884
- "numOctaves",
2885
- "targetX",
2886
- "targetY",
2887
- "surfaceScale",
2888
- "specularConstant",
2889
- "specularExponent",
2890
- "stdDeviation",
2891
- "tableValues",
2892
- "viewBox",
2893
- "gradientTransform",
2894
- "pathLength",
2895
- "startOffset",
2896
- "textLength",
2897
- "lengthAdjust"
2898
- ]);
2899
- function renderSVG(element, renderState, _styleProp, projection) {
2900
- renderHTML(element, renderState, void 0, projection);
2901
- for (const key in renderState.attrs) {
2902
- element.setAttribute(!camelCaseAttributes.has(key) ? camelToDash(key) : key, renderState.attrs[key]);
2903
- }
2904
- }
2905
- function isForcedMotionValue(key, { layout, layoutId }) {
2906
- return transformProps.has(key) || key.startsWith("origin") || (layout || layoutId !== void 0) && (!!scaleCorrectors[key] || key === "opacity");
2907
- }
2908
- function scrapeMotionValuesFromProps$1(props, prevProps, visualElement) {
2909
- var _a;
2910
- const { style } = props;
2911
- const newValues = {};
2912
- for (const key in style) {
2913
- if (isMotionValue(style[key]) || prevProps.style && isMotionValue(prevProps.style[key]) || isForcedMotionValue(key, props) || ((_a = visualElement === null || visualElement === void 0 ? void 0 : visualElement.getValue(key)) === null || _a === void 0 ? void 0 : _a.liveStyle) !== void 0) {
2914
- newValues[key] = style[key];
2915
- }
2916
- }
2917
- return newValues;
2918
- }
2919
- function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
2920
- const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
2921
- for (const key in props) {
2922
- if (isMotionValue(props[key]) || isMotionValue(prevProps[key])) {
2923
- const targetKey = transformPropOrder.indexOf(key) !== -1 ? "attr" + key.charAt(0).toUpperCase() + key.substring(1) : key;
2924
- newValues[targetKey] = props[key];
2925
- }
2926
- }
2927
- return newValues;
2928
- }
2929
- function useConstant(init) {
2930
- const ref = useRef(null);
2931
- if (ref.current === null) {
2932
- ref.current = init();
2933
- }
2934
- return ref.current;
2935
- }
2936
- const getValueAsType = (value, type) => {
2937
- return type && typeof value === "number" ? type.transform(value) : value;
2938
- };
2939
- const translateAlias = {
2940
- x: "translateX",
2941
- y: "translateY",
2942
- z: "translateZ",
2943
- transformPerspective: "perspective"
2944
- };
2945
- const numTransforms = transformPropOrder.length;
2946
- function buildTransform(latestValues, transform, transformTemplate) {
2947
- let transformString = "";
2948
- let transformIsDefault = true;
2949
- for (let i = 0; i < numTransforms; i++) {
2950
- const key = transformPropOrder[i];
2951
- const value = latestValues[key];
2952
- if (value === void 0)
2953
- continue;
2954
- let valueIsDefault = true;
2955
- if (typeof value === "number") {
2956
- valueIsDefault = value === (key.startsWith("scale") ? 1 : 0);
2957
- } else {
2958
- valueIsDefault = parseFloat(value) === 0;
2959
- }
2960
- if (!valueIsDefault || transformTemplate) {
2961
- const valueAsType = getValueAsType(value, numberValueTypes[key]);
2962
- if (!valueIsDefault) {
2963
- transformIsDefault = false;
2964
- const transformName = translateAlias[key] || key;
2965
- transformString += `${transformName}(${valueAsType}) `;
2966
- }
2967
- if (transformTemplate) {
2968
- transform[key] = valueAsType;
2969
- }
2970
- }
2971
- }
2972
- transformString = transformString.trim();
2973
- if (transformTemplate) {
2974
- transformString = transformTemplate(transform, transformIsDefault ? "" : transformString);
2975
- } else if (transformIsDefault) {
2976
- transformString = "none";
2977
- }
2978
- return transformString;
2979
- }
2980
- function buildHTMLStyles(state, latestValues, transformTemplate) {
2981
- const { style, vars, transformOrigin } = state;
2982
- let hasTransform = false;
2983
- let hasTransformOrigin = false;
2984
- for (const key in latestValues) {
2985
- const value = latestValues[key];
2986
- if (transformProps.has(key)) {
2987
- hasTransform = true;
2988
- continue;
2989
- } else if (isCSSVariableName(key)) {
2990
- vars[key] = value;
2991
- continue;
2992
- } else {
2993
- const valueAsType = getValueAsType(value, numberValueTypes[key]);
2994
- if (key.startsWith("origin")) {
2995
- hasTransformOrigin = true;
2996
- transformOrigin[key] = valueAsType;
2997
- } else {
2998
- style[key] = valueAsType;
2999
- }
3000
- }
3001
- }
3002
- if (!latestValues.transform) {
3003
- if (hasTransform || transformTemplate) {
3004
- style.transform = buildTransform(latestValues, state.transform, transformTemplate);
3005
- } else if (style.transform) {
3006
- style.transform = "none";
3007
- }
3008
- }
3009
- if (hasTransformOrigin) {
3010
- const { originX = "50%", originY = "50%", originZ = 0 } = transformOrigin;
3011
- style.transformOrigin = `${originX} ${originY} ${originZ}`;
3012
- }
3013
- }
3014
- function calcOrigin(origin, offset, size) {
3015
- return typeof origin === "string" ? origin : px.transform(offset + size * origin);
3016
- }
3017
- function calcSVGTransformOrigin(dimensions, originX, originY) {
3018
- const pxOriginX = calcOrigin(originX, dimensions.x, dimensions.width);
3019
- const pxOriginY = calcOrigin(originY, dimensions.y, dimensions.height);
3020
- return `${pxOriginX} ${pxOriginY}`;
3021
- }
3022
- const dashKeys = {
3023
- offset: "stroke-dashoffset",
3024
- array: "stroke-dasharray"
3025
- };
3026
- const camelKeys = {
3027
- offset: "strokeDashoffset",
3028
- array: "strokeDasharray"
3029
- };
3030
- function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
3031
- attrs.pathLength = 1;
3032
- const keys = useDashCase ? dashKeys : camelKeys;
3033
- attrs[keys.offset] = px.transform(-offset);
3034
- const pathLength = px.transform(length);
3035
- const pathSpacing = px.transform(spacing);
3036
- attrs[keys.array] = `${pathLength} ${pathSpacing}`;
3037
- }
3038
- function buildSVGAttrs(state, {
3039
- attrX,
3040
- attrY,
3041
- attrScale,
3042
- originX,
3043
- originY,
3044
- pathLength,
3045
- pathSpacing = 1,
3046
- pathOffset = 0,
3047
- // This is object creation, which we try to avoid per-frame.
3048
- ...latest
3049
- }, isSVGTag2, transformTemplate) {
3050
- buildHTMLStyles(state, latest, transformTemplate);
3051
- if (isSVGTag2) {
3052
- if (state.style.viewBox) {
3053
- state.attrs.viewBox = state.style.viewBox;
3054
- }
3055
- return;
3056
- }
3057
- state.attrs = state.style;
3058
- state.style = {};
3059
- const { attrs, style, dimensions } = state;
3060
- if (attrs.transform) {
3061
- if (dimensions)
3062
- style.transform = attrs.transform;
3063
- delete attrs.transform;
3064
- }
3065
- if (dimensions && (originX !== void 0 || originY !== void 0 || style.transform)) {
3066
- style.transformOrigin = calcSVGTransformOrigin(dimensions, originX !== void 0 ? originX : 0.5, originY !== void 0 ? originY : 0.5);
3067
- }
3068
- if (attrX !== void 0)
3069
- attrs.x = attrX;
3070
- if (attrY !== void 0)
3071
- attrs.y = attrY;
3072
- if (attrScale !== void 0)
3073
- attrs.scale = attrScale;
3074
- if (pathLength !== void 0) {
3075
- buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
3076
- }
3077
- }
3078
- const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
3079
- const prefersReducedMotion = { current: null };
3080
- const hasReducedMotionListener = { current: false };
3081
- function initPrefersReducedMotion() {
3082
- hasReducedMotionListener.current = true;
3083
- if (!isBrowser)
3084
- return;
3085
- if (window.matchMedia) {
3086
- const motionMediaQuery = window.matchMedia("(prefers-reduced-motion)");
3087
- const setReducedMotionPreferences = () => prefersReducedMotion.current = motionMediaQuery.matches;
3088
- motionMediaQuery.addListener(setReducedMotionPreferences);
3089
- setReducedMotionPreferences();
3090
- } else {
3091
- prefersReducedMotion.current = false;
3092
- }
3093
- }
3094
- function updateMotionValuesFromProps(element, next, prev) {
3095
- for (const key in next) {
3096
- const nextValue = next[key];
3097
- const prevValue = prev[key];
3098
- if (isMotionValue(nextValue)) {
3099
- element.addValue(key, nextValue);
3100
- if (process.env.NODE_ENV === "development") {
3101
- warnOnce(nextValue.version === "11.14.3", `Attempting to mix Motion versions ${nextValue.version} with 11.14.3 may not work as expected.`);
3102
- }
3103
- } else if (isMotionValue(prevValue)) {
3104
- element.addValue(key, motionValue(nextValue, { owner: element }));
3105
- } else if (prevValue !== nextValue) {
3106
- if (element.hasValue(key)) {
3107
- const existingValue = element.getValue(key);
3108
- if (existingValue.liveStyle === true) {
3109
- existingValue.jump(nextValue);
3110
- } else if (!existingValue.hasAnimated) {
3111
- existingValue.set(nextValue);
3112
- }
3113
- } else {
3114
- const latestValue = element.getStaticValue(key);
3115
- element.addValue(key, motionValue(latestValue !== void 0 ? latestValue : nextValue, { owner: element }));
3116
- }
3117
- }
3118
- }
3119
- for (const key in prev) {
3120
- if (next[key] === void 0)
3121
- element.removeValue(key);
3122
- }
3123
- return next;
3124
- }
3125
- const visualElementStore = /* @__PURE__ */ new WeakMap();
3126
- const valueTypes = [...dimensionValueTypes, color, complex];
3127
- const findValueType = (v) => valueTypes.find(testValueType(v));
3128
- const propEventHandlers = [
3129
- "AnimationStart",
3130
- "AnimationComplete",
3131
- "Update",
3132
- "BeforeLayoutMeasure",
3133
- "LayoutMeasure",
3134
- "LayoutAnimationStart",
3135
- "LayoutAnimationComplete"
3136
- ];
3137
- class VisualElement {
3138
- /**
3139
- * This method takes React props and returns found MotionValues. For example, HTML
3140
- * MotionValues will be found within the style prop, whereas for Three.js within attribute arrays.
3141
- *
3142
- * This isn't an abstract method as it needs calling in the constructor, but it is
3143
- * intended to be one.
3144
- */
3145
- scrapeMotionValuesFromProps(_props, _prevProps, _visualElement) {
3146
- return {};
3147
- }
3148
- constructor({ parent, props, presenceContext, reducedMotionConfig, blockInitialAnimation, visualState }, options = {}) {
3149
- this.current = null;
3150
- this.children = /* @__PURE__ */ new Set();
3151
- this.isVariantNode = false;
3152
- this.isControllingVariants = false;
3153
- this.shouldReduceMotion = null;
3154
- this.values = /* @__PURE__ */ new Map();
3155
- this.KeyframeResolver = KeyframeResolver;
3156
- this.features = {};
3157
- this.valueSubscriptions = /* @__PURE__ */ new Map();
3158
- this.prevMotionValues = {};
3159
- this.events = {};
3160
- this.propEventSubscriptions = {};
3161
- this.notifyUpdate = () => this.notify("Update", this.latestValues);
3162
- this.render = () => {
3163
- if (!this.current)
3164
- return;
3165
- this.triggerBuild();
3166
- this.renderInstance(this.current, this.renderState, this.props.style, this.projection);
3167
- };
3168
- this.renderScheduledAt = 0;
3169
- this.scheduleRender = () => {
3170
- const now2 = time.now();
3171
- if (this.renderScheduledAt < now2) {
3172
- this.renderScheduledAt = now2;
3173
- frame.render(this.render, false, true);
3174
- }
3175
- };
3176
- const { latestValues, renderState } = visualState;
3177
- this.latestValues = latestValues;
3178
- this.baseTarget = { ...latestValues };
3179
- this.initialValues = props.initial ? { ...latestValues } : {};
3180
- this.renderState = renderState;
3181
- this.parent = parent;
3182
- this.props = props;
3183
- this.presenceContext = presenceContext;
3184
- this.depth = parent ? parent.depth + 1 : 0;
3185
- this.reducedMotionConfig = reducedMotionConfig;
3186
- this.options = options;
3187
- this.blockInitialAnimation = Boolean(blockInitialAnimation);
3188
- this.isControllingVariants = isControllingVariants(props);
3189
- this.isVariantNode = isVariantNode(props);
3190
- if (this.isVariantNode) {
3191
- this.variantChildren = /* @__PURE__ */ new Set();
3192
- }
3193
- this.manuallyAnimateOnMount = Boolean(parent && parent.current);
3194
- const { willChange, ...initialMotionValues } = this.scrapeMotionValuesFromProps(props, {}, this);
3195
- for (const key in initialMotionValues) {
3196
- const value = initialMotionValues[key];
3197
- if (latestValues[key] !== void 0 && isMotionValue(value)) {
3198
- value.set(latestValues[key], false);
3199
- }
3200
- }
3201
- }
3202
- mount(instance) {
3203
- this.current = instance;
3204
- visualElementStore.set(instance, this);
3205
- if (this.projection && !this.projection.instance) {
3206
- this.projection.mount(instance);
3207
- }
3208
- if (this.parent && this.isVariantNode && !this.isControllingVariants) {
3209
- this.removeFromVariantTree = this.parent.addVariantChild(this);
3210
- }
3211
- this.values.forEach((value, key) => this.bindToMotionValue(key, value));
3212
- if (!hasReducedMotionListener.current) {
3213
- initPrefersReducedMotion();
3214
- }
3215
- this.shouldReduceMotion = this.reducedMotionConfig === "never" ? false : this.reducedMotionConfig === "always" ? true : prefersReducedMotion.current;
3216
- if (process.env.NODE_ENV !== "production") {
3217
- warnOnce(this.shouldReduceMotion !== true, "You have Reduced Motion enabled on your device. Animations may not appear as expected.");
3218
- }
3219
- if (this.parent)
3220
- this.parent.children.add(this);
3221
- this.update(this.props, this.presenceContext);
3222
- }
3223
- unmount() {
3224
- visualElementStore.delete(this.current);
3225
- this.projection && this.projection.unmount();
3226
- cancelFrame(this.notifyUpdate);
3227
- cancelFrame(this.render);
3228
- this.valueSubscriptions.forEach((remove) => remove());
3229
- this.valueSubscriptions.clear();
3230
- this.removeFromVariantTree && this.removeFromVariantTree();
3231
- this.parent && this.parent.children.delete(this);
3232
- for (const key in this.events) {
3233
- this.events[key].clear();
3234
- }
3235
- for (const key in this.features) {
3236
- const feature = this.features[key];
3237
- if (feature) {
3238
- feature.unmount();
3239
- feature.isMounted = false;
3240
- }
3241
- }
3242
- this.current = null;
3243
- }
3244
- bindToMotionValue(key, value) {
3245
- if (this.valueSubscriptions.has(key)) {
3246
- this.valueSubscriptions.get(key)();
3247
- }
3248
- const valueIsTransform = transformProps.has(key);
3249
- const removeOnChange = value.on("change", (latestValue) => {
3250
- this.latestValues[key] = latestValue;
3251
- this.props.onUpdate && frame.preRender(this.notifyUpdate);
3252
- if (valueIsTransform && this.projection) {
3253
- this.projection.isTransformDirty = true;
3254
- }
3255
- });
3256
- const removeOnRenderRequest = value.on("renderRequest", this.scheduleRender);
3257
- let removeSyncCheck;
3258
- if (window.MotionCheckAppearSync) {
3259
- removeSyncCheck = window.MotionCheckAppearSync(this, key, value);
3260
- }
3261
- this.valueSubscriptions.set(key, () => {
3262
- removeOnChange();
3263
- removeOnRenderRequest();
3264
- if (removeSyncCheck)
3265
- removeSyncCheck();
3266
- if (value.owner)
3267
- value.stop();
3268
- });
3269
- }
3270
- sortNodePosition(other) {
3271
- if (!this.current || !this.sortInstanceNodePosition || this.type !== other.type) {
3272
- return 0;
3273
- }
3274
- return this.sortInstanceNodePosition(this.current, other.current);
3275
- }
3276
- updateFeatures() {
3277
- let key = "animation";
3278
- for (key in featureDefinitions) {
3279
- const featureDefinition = featureDefinitions[key];
3280
- if (!featureDefinition)
3281
- continue;
3282
- const { isEnabled, Feature: FeatureConstructor } = featureDefinition;
3283
- if (!this.features[key] && FeatureConstructor && isEnabled(this.props)) {
3284
- this.features[key] = new FeatureConstructor(this);
3285
- }
3286
- if (this.features[key]) {
3287
- const feature = this.features[key];
3288
- if (feature.isMounted) {
3289
- feature.update();
3290
- } else {
3291
- feature.mount();
3292
- feature.isMounted = true;
3293
- }
3294
- }
3295
- }
3296
- }
3297
- triggerBuild() {
3298
- this.build(this.renderState, this.latestValues, this.props);
3299
- }
3300
- /**
3301
- * Measure the current viewport box with or without transforms.
3302
- * Only measures axis-aligned boxes, rotate and skew must be manually
3303
- * removed with a re-render to work.
3304
- */
3305
- measureViewportBox() {
3306
- return this.current ? this.measureInstanceViewportBox(this.current, this.props) : createBox();
3307
- }
3308
- getStaticValue(key) {
3309
- return this.latestValues[key];
3310
- }
3311
- setStaticValue(key, value) {
3312
- this.latestValues[key] = value;
3313
- }
3314
- /**
3315
- * Update the provided props. Ensure any newly-added motion values are
3316
- * added to our map, old ones removed, and listeners updated.
3317
- */
3318
- update(props, presenceContext) {
3319
- if (props.transformTemplate || this.props.transformTemplate) {
3320
- this.scheduleRender();
3321
- }
3322
- this.prevProps = this.props;
3323
- this.props = props;
3324
- this.prevPresenceContext = this.presenceContext;
3325
- this.presenceContext = presenceContext;
3326
- for (let i = 0; i < propEventHandlers.length; i++) {
3327
- const key = propEventHandlers[i];
3328
- if (this.propEventSubscriptions[key]) {
3329
- this.propEventSubscriptions[key]();
3330
- delete this.propEventSubscriptions[key];
3331
- }
3332
- const listenerName = "on" + key;
3333
- const listener = props[listenerName];
3334
- if (listener) {
3335
- this.propEventSubscriptions[key] = this.on(key, listener);
3336
- }
3337
- }
3338
- this.prevMotionValues = updateMotionValuesFromProps(this, this.scrapeMotionValuesFromProps(props, this.prevProps, this), this.prevMotionValues);
3339
- if (this.handleChildMotionValue) {
3340
- this.handleChildMotionValue();
3341
- }
3342
- }
3343
- getProps() {
3344
- return this.props;
3345
- }
3346
- /**
3347
- * Returns the variant definition with a given name.
3348
- */
3349
- getVariant(name) {
3350
- return this.props.variants ? this.props.variants[name] : void 0;
3351
- }
3352
- /**
3353
- * Returns the defined default transition on this component.
3354
- */
3355
- getDefaultTransition() {
3356
- return this.props.transition;
3357
- }
3358
- getTransformPagePoint() {
3359
- return this.props.transformPagePoint;
3360
- }
3361
- getClosestVariantNode() {
3362
- return this.isVariantNode ? this : this.parent ? this.parent.getClosestVariantNode() : void 0;
3363
- }
3364
- /**
3365
- * Add a child visual element to our set of children.
3366
- */
3367
- addVariantChild(child) {
3368
- const closestVariantNode = this.getClosestVariantNode();
3369
- if (closestVariantNode) {
3370
- closestVariantNode.variantChildren && closestVariantNode.variantChildren.add(child);
3371
- return () => closestVariantNode.variantChildren.delete(child);
3372
- }
3373
- }
3374
- /**
3375
- * Add a motion value and bind it to this visual element.
3376
- */
3377
- addValue(key, value) {
3378
- const existingValue = this.values.get(key);
3379
- if (value !== existingValue) {
3380
- if (existingValue)
3381
- this.removeValue(key);
3382
- this.bindToMotionValue(key, value);
3383
- this.values.set(key, value);
3384
- this.latestValues[key] = value.get();
3385
- }
3386
- }
3387
- /**
3388
- * Remove a motion value and unbind any active subscriptions.
3389
- */
3390
- removeValue(key) {
3391
- this.values.delete(key);
3392
- const unsubscribe = this.valueSubscriptions.get(key);
3393
- if (unsubscribe) {
3394
- unsubscribe();
3395
- this.valueSubscriptions.delete(key);
3396
- }
3397
- delete this.latestValues[key];
3398
- this.removeValueFromRenderState(key, this.renderState);
3399
- }
3400
- /**
3401
- * Check whether we have a motion value for this key
3402
- */
3403
- hasValue(key) {
3404
- return this.values.has(key);
3405
- }
3406
- getValue(key, defaultValue) {
3407
- if (this.props.values && this.props.values[key]) {
3408
- return this.props.values[key];
3409
- }
3410
- let value = this.values.get(key);
3411
- if (value === void 0 && defaultValue !== void 0) {
3412
- value = motionValue(defaultValue === null ? void 0 : defaultValue, { owner: this });
3413
- this.addValue(key, value);
3414
- }
3415
- return value;
3416
- }
3417
- /**
3418
- * If we're trying to animate to a previously unencountered value,
3419
- * we need to check for it in our state and as a last resort read it
3420
- * directly from the instance (which might have performance implications).
3421
- */
3422
- readValue(key, target) {
3423
- var _a;
3424
- let value = this.latestValues[key] !== void 0 || !this.current ? this.latestValues[key] : (_a = this.getBaseTargetFromProps(this.props, key)) !== null && _a !== void 0 ? _a : this.readValueFromInstance(this.current, key, this.options);
3425
- if (value !== void 0 && value !== null) {
3426
- if (typeof value === "string" && (isNumericalString(value) || isZeroValueString(value))) {
3427
- value = parseFloat(value);
3428
- } else if (!findValueType(value) && complex.test(target)) {
3429
- value = getAnimatableNone(key, target);
3430
- }
3431
- this.setBaseTarget(key, isMotionValue(value) ? value.get() : value);
3432
- }
3433
- return isMotionValue(value) ? value.get() : value;
3434
- }
3435
- /**
3436
- * Set the base target to later animate back to. This is currently
3437
- * only hydrated on creation and when we first read a value.
3438
- */
3439
- setBaseTarget(key, value) {
3440
- this.baseTarget[key] = value;
3441
- }
3442
- /**
3443
- * Find the base target for a value thats been removed from all animation
3444
- * props.
3445
- */
3446
- getBaseTarget(key) {
3447
- var _a;
3448
- const { initial } = this.props;
3449
- let valueFromInitial;
3450
- if (typeof initial === "string" || typeof initial === "object") {
3451
- const variant = resolveVariantFromProps(this.props, initial, (_a = this.presenceContext) === null || _a === void 0 ? void 0 : _a.custom);
3452
- if (variant) {
3453
- valueFromInitial = variant[key];
3454
- }
3455
- }
3456
- if (initial && valueFromInitial !== void 0) {
3457
- return valueFromInitial;
3458
- }
3459
- const target = this.getBaseTargetFromProps(this.props, key);
3460
- if (target !== void 0 && !isMotionValue(target))
3461
- return target;
3462
- return this.initialValues[key] !== void 0 && valueFromInitial === void 0 ? void 0 : this.baseTarget[key];
3463
- }
3464
- on(eventName, callback) {
3465
- if (!this.events[eventName]) {
3466
- this.events[eventName] = new SubscriptionManager();
3467
- }
3468
- return this.events[eventName].add(callback);
3469
- }
3470
- notify(eventName, ...args) {
3471
- if (this.events[eventName]) {
3472
- this.events[eventName].notify(...args);
3473
- }
3474
- }
3475
- }
3476
- class DOMVisualElement extends VisualElement {
3477
- constructor() {
3478
- super(...arguments);
3479
- this.KeyframeResolver = DOMKeyframesResolver;
3480
- }
3481
- sortInstanceNodePosition(a, b) {
3482
- return a.compareDocumentPosition(b) & 2 ? 1 : -1;
3483
- }
3484
- getBaseTargetFromProps(props, key) {
3485
- return props.style ? props.style[key] : void 0;
3486
- }
3487
- removeValueFromRenderState(key, { vars, style }) {
3488
- delete vars[key];
3489
- delete style[key];
3490
- }
3491
- handleChildMotionValue() {
3492
- if (this.childSubscription) {
3493
- this.childSubscription();
3494
- delete this.childSubscription;
3495
- }
3496
- const { children } = this.props;
3497
- if (isMotionValue(children)) {
3498
- this.childSubscription = children.on("change", (latest) => {
3499
- if (this.current) {
3500
- this.current.textContent = `${latest}`;
3501
- }
3502
- });
3503
- }
3504
- }
3505
- }
3506
- function getComputedStyle(element) {
3507
- return window.getComputedStyle(element);
3508
- }
3509
- class HTMLVisualElement extends DOMVisualElement {
3510
- constructor() {
3511
- super(...arguments);
3512
- this.type = "html";
3513
- this.renderInstance = renderHTML;
3514
- }
3515
- readValueFromInstance(instance, key) {
3516
- if (transformProps.has(key)) {
3517
- const defaultType = getDefaultValueType(key);
3518
- return defaultType ? defaultType.default || 0 : 0;
3519
- } else {
3520
- const computedStyle = getComputedStyle(instance);
3521
- const value = (isCSSVariableName(key) ? computedStyle.getPropertyValue(key) : computedStyle[key]) || 0;
3522
- return typeof value === "string" ? value.trim() : value;
3523
- }
3524
- }
3525
- measureInstanceViewportBox(instance, { transformPagePoint }) {
3526
- return measureViewportBox(instance, transformPagePoint);
3527
- }
3528
- build(renderState, latestValues, props) {
3529
- buildHTMLStyles(renderState, latestValues, props.transformTemplate);
3530
- }
3531
- scrapeMotionValuesFromProps(props, prevProps, visualElement) {
3532
- return scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
3533
- }
3534
- }
3535
- class SVGVisualElement extends DOMVisualElement {
3536
- constructor() {
3537
- super(...arguments);
3538
- this.type = "svg";
3539
- this.isSVGTag = false;
3540
- this.measureInstanceViewportBox = createBox;
3541
- }
3542
- getBaseTargetFromProps(props, key) {
3543
- return props[key];
3544
- }
3545
- readValueFromInstance(instance, key) {
3546
- if (transformProps.has(key)) {
3547
- const defaultType = getDefaultValueType(key);
3548
- return defaultType ? defaultType.default || 0 : 0;
3549
- }
3550
- key = !camelCaseAttributes.has(key) ? camelToDash(key) : key;
3551
- return instance.getAttribute(key);
3552
- }
3553
- scrapeMotionValuesFromProps(props, prevProps, visualElement) {
3554
- return scrapeMotionValuesFromProps(props, prevProps, visualElement);
3555
- }
3556
- build(renderState, latestValues, props) {
3557
- buildSVGAttrs(renderState, latestValues, this.isSVGTag, props.transformTemplate);
3558
- }
3559
- renderInstance(instance, renderState, styleProp, projection) {
3560
- renderSVG(instance, renderState, styleProp, projection);
3561
- }
3562
- mount(instance) {
3563
- this.isSVGTag = isSVGTag(instance.tagName);
3564
- super.mount(instance);
3565
- }
3566
- }
3567
- function useUnmountEffect(callback) {
3568
- return useEffect(() => () => callback(), []);
3569
- }
3570
- function createGeneratorEasing(options, scale2 = 100, createGenerator) {
3571
- const generator = createGenerator({ ...options, keyframes: [0, scale2] });
3572
- const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
3573
- return {
3574
- type: "keyframes",
3575
- ease: (progress2) => generator.next(duration * progress2).value / scale2,
3576
- duration: millisecondsToSeconds(duration)
3577
- };
3578
- }
3579
- function isDOMKeyframes(keyframes2) {
3580
- return typeof keyframes2 === "object" && !Array.isArray(keyframes2);
3581
- }
3582
- function resolveSubjects(subject, keyframes2, scope, selectorCache) {
3583
- if (typeof subject === "string" && isDOMKeyframes(keyframes2)) {
3584
- return resolveElements(subject, scope, selectorCache);
3585
- } else if (subject instanceof NodeList) {
3586
- return Array.from(subject);
3587
- } else if (Array.isArray(subject)) {
3588
- return subject;
3589
- } else {
3590
- return [subject];
3591
- }
3592
- }
3593
- function calcNextTime(current, next, prev, labels) {
3594
- var _a;
3595
- if (typeof next === "number") {
3596
- return next;
3597
- } else if (next.startsWith("-") || next.startsWith("+")) {
3598
- return Math.max(0, current + parseFloat(next));
3599
- } else if (next === "<") {
3600
- return prev;
3601
- } else {
3602
- return (_a = labels.get(next)) !== null && _a !== void 0 ? _a : current;
3603
- }
3604
- }
3605
- const wrap = (min, max, v) => {
3606
- const rangeSize = max - min;
3607
- return ((v - min) % rangeSize + rangeSize) % rangeSize + min;
3608
- };
3609
- function getEasingForSegment(easing, i) {
3610
- return isEasingArray(easing) ? easing[wrap(0, easing.length, i)] : easing;
3611
- }
3612
- function eraseKeyframes(sequence, startTime, endTime) {
3613
- for (let i = 0; i < sequence.length; i++) {
3614
- const keyframe = sequence[i];
3615
- if (keyframe.at > startTime && keyframe.at < endTime) {
3616
- removeItem(sequence, keyframe);
3617
- i--;
3618
- }
3619
- }
3620
- }
3621
- function addKeyframes(sequence, keyframes2, easing, offset, startTime, endTime) {
3622
- eraseKeyframes(sequence, startTime, endTime);
3623
- for (let i = 0; i < keyframes2.length; i++) {
3624
- sequence.push({
3625
- value: keyframes2[i],
3626
- at: mixNumber$1(startTime, endTime, offset[i]),
3627
- easing: getEasingForSegment(easing, i)
3628
- });
3629
- }
3630
- }
3631
- function compareByTime(a, b) {
3632
- if (a.at === b.at) {
3633
- if (a.value === null)
3634
- return 1;
3635
- if (b.value === null)
3636
- return -1;
3637
- return 0;
3638
- } else {
3639
- return a.at - b.at;
3640
- }
3641
- }
3642
- const defaultSegmentEasing = "easeInOut";
3643
- function createAnimationsFromSequence(sequence, { defaultTransition = {}, ...sequenceTransition } = {}, scope, generators2) {
3644
- const defaultDuration = defaultTransition.duration || 0.3;
3645
- const animationDefinitions = /* @__PURE__ */ new Map();
3646
- const sequences = /* @__PURE__ */ new Map();
3647
- const elementCache = {};
3648
- const timeLabels = /* @__PURE__ */ new Map();
3649
- let prevTime = 0;
3650
- let currentTime = 0;
3651
- let totalDuration = 0;
3652
- for (let i = 0; i < sequence.length; i++) {
3653
- const segment = sequence[i];
3654
- if (typeof segment === "string") {
3655
- timeLabels.set(segment, currentTime);
3656
- continue;
3657
- } else if (!Array.isArray(segment)) {
3658
- timeLabels.set(segment.name, calcNextTime(currentTime, segment.at, prevTime, timeLabels));
3659
- continue;
3660
- }
3661
- let [subject, keyframes2, transition = {}] = segment;
3662
- if (transition.at !== void 0) {
3663
- currentTime = calcNextTime(currentTime, transition.at, prevTime, timeLabels);
3664
- }
3665
- let maxDuration2 = 0;
3666
- const resolveValueSequence = (valueKeyframes, valueTransition, valueSequence, elementIndex = 0, numSubjects = 0) => {
3667
- const valueKeyframesAsList = keyframesAsList(valueKeyframes);
3668
- const { delay = 0, times = defaultOffset(valueKeyframesAsList), type = "keyframes", ...remainingTransition } = valueTransition;
3669
- let { ease: ease2 = defaultTransition.ease || "easeOut", duration } = valueTransition;
3670
- const calculatedDelay = typeof delay === "function" ? delay(elementIndex, numSubjects) : delay;
3671
- const numKeyframes = valueKeyframesAsList.length;
3672
- const createGenerator = isGenerator(type) ? type : generators2 === null || generators2 === void 0 ? void 0 : generators2[type];
3673
- if (numKeyframes <= 2 && createGenerator) {
3674
- let absoluteDelta = 100;
3675
- if (numKeyframes === 2 && isNumberKeyframesArray(valueKeyframesAsList)) {
3676
- const delta = valueKeyframesAsList[1] - valueKeyframesAsList[0];
3677
- absoluteDelta = Math.abs(delta);
3678
- }
3679
- const springTransition = { ...remainingTransition };
3680
- if (duration !== void 0) {
3681
- springTransition.duration = secondsToMilliseconds(duration);
3682
- }
3683
- const springEasing = createGeneratorEasing(springTransition, absoluteDelta, createGenerator);
3684
- ease2 = springEasing.ease;
3685
- duration = springEasing.duration;
3686
- }
3687
- duration !== null && duration !== void 0 ? duration : duration = defaultDuration;
3688
- const startTime = currentTime + calculatedDelay;
3689
- const targetTime = startTime + duration;
3690
- if (times.length === 1 && times[0] === 0) {
3691
- times[1] = 1;
3692
- }
3693
- const remainder = times.length - valueKeyframesAsList.length;
3694
- remainder > 0 && fillOffset(times, remainder);
3695
- valueKeyframesAsList.length === 1 && valueKeyframesAsList.unshift(null);
3696
- addKeyframes(valueSequence, valueKeyframesAsList, ease2, times, startTime, targetTime);
3697
- maxDuration2 = Math.max(calculatedDelay + duration, maxDuration2);
3698
- totalDuration = Math.max(targetTime, totalDuration);
3699
- };
3700
- if (isMotionValue(subject)) {
3701
- const subjectSequence = getSubjectSequence(subject, sequences);
3702
- resolveValueSequence(keyframes2, transition, getValueSequence("default", subjectSequence));
3703
- } else {
3704
- const subjects = resolveSubjects(subject, keyframes2, scope, elementCache);
3705
- const numSubjects = subjects.length;
3706
- for (let subjectIndex = 0; subjectIndex < numSubjects; subjectIndex++) {
3707
- keyframes2 = keyframes2;
3708
- transition = transition;
3709
- const thisSubject = subjects[subjectIndex];
3710
- const subjectSequence = getSubjectSequence(thisSubject, sequences);
3711
- for (const key in keyframes2) {
3712
- resolveValueSequence(keyframes2[key], getValueTransition(transition, key), getValueSequence(key, subjectSequence), subjectIndex, numSubjects);
3713
- }
3714
- }
3715
- }
3716
- prevTime = currentTime;
3717
- currentTime += maxDuration2;
3718
- }
3719
- sequences.forEach((valueSequences, element) => {
3720
- for (const key in valueSequences) {
3721
- const valueSequence = valueSequences[key];
3722
- valueSequence.sort(compareByTime);
3723
- const keyframes2 = [];
3724
- const valueOffset = [];
3725
- const valueEasing = [];
3726
- for (let i = 0; i < valueSequence.length; i++) {
3727
- const { at, value, easing } = valueSequence[i];
3728
- keyframes2.push(value);
3729
- valueOffset.push(progress(0, totalDuration, at));
3730
- valueEasing.push(easing || "easeOut");
3731
- }
3732
- if (valueOffset[0] !== 0) {
3733
- valueOffset.unshift(0);
3734
- keyframes2.unshift(keyframes2[0]);
3735
- valueEasing.unshift(defaultSegmentEasing);
3736
- }
3737
- if (valueOffset[valueOffset.length - 1] !== 1) {
3738
- valueOffset.push(1);
3739
- keyframes2.push(null);
3740
- }
3741
- if (!animationDefinitions.has(element)) {
3742
- animationDefinitions.set(element, {
3743
- keyframes: {},
3744
- transition: {}
3745
- });
3746
- }
3747
- const definition = animationDefinitions.get(element);
3748
- definition.keyframes[key] = keyframes2;
3749
- definition.transition[key] = {
3750
- ...defaultTransition,
3751
- duration: totalDuration,
3752
- ease: valueEasing,
3753
- times: valueOffset,
3754
- ...sequenceTransition
3755
- };
3756
- }
3757
- });
3758
- return animationDefinitions;
3759
- }
3760
- function getSubjectSequence(subject, sequences) {
3761
- !sequences.has(subject) && sequences.set(subject, {});
3762
- return sequences.get(subject);
3763
- }
3764
- function getValueSequence(name, sequences) {
3765
- if (!sequences[name])
3766
- sequences[name] = [];
3767
- return sequences[name];
3768
- }
3769
- function keyframesAsList(keyframes2) {
3770
- return Array.isArray(keyframes2) ? keyframes2 : [keyframes2];
3771
- }
3772
- function getValueTransition(transition, key) {
3773
- return transition && transition[key] ? {
3774
- ...transition,
3775
- ...transition[key]
3776
- } : { ...transition };
3777
- }
3778
- const isNumber = (keyframe) => typeof keyframe === "number";
3779
- const isNumberKeyframesArray = (keyframes2) => keyframes2.every(isNumber);
3780
- function isObjectKey(key, object) {
3781
- return key in object;
3782
- }
3783
- class ObjectVisualElement extends VisualElement {
3784
- constructor() {
3785
- super(...arguments);
3786
- this.type = "object";
3787
- }
3788
- readValueFromInstance(instance, key) {
3789
- if (isObjectKey(key, instance)) {
3790
- const value = instance[key];
3791
- if (typeof value === "string" || typeof value === "number") {
3792
- return value;
3793
- }
3794
- }
3795
- return void 0;
3796
- }
3797
- getBaseTargetFromProps() {
3798
- return void 0;
3799
- }
3800
- removeValueFromRenderState(key, renderState) {
3801
- delete renderState.output[key];
3802
- }
3803
- measureInstanceViewportBox() {
3804
- return createBox();
3805
- }
3806
- build(renderState, latestValues) {
3807
- Object.assign(renderState.output, latestValues);
3808
- }
3809
- renderInstance(instance, { output }) {
3810
- Object.assign(instance, output);
3811
- }
3812
- sortInstanceNodePosition() {
3813
- return 0;
3814
- }
3815
- }
3816
- function createDOMVisualElement(element) {
3817
- const options = {
3818
- presenceContext: null,
3819
- props: {},
3820
- visualState: {
3821
- renderState: {
3822
- transform: {},
3823
- transformOrigin: {},
3824
- style: {},
3825
- vars: {},
3826
- attrs: {}
3827
- },
3828
- latestValues: {}
3829
- }
3830
- };
3831
- const node = isSVGElement(element) ? new SVGVisualElement(options) : new HTMLVisualElement(options);
3832
- node.mount(element);
3833
- visualElementStore.set(element, node);
3834
- }
3835
- function createObjectVisualElement(subject) {
3836
- const options = {
3837
- presenceContext: null,
3838
- props: {},
3839
- visualState: {
3840
- renderState: {
3841
- output: {}
3842
- },
3843
- latestValues: {}
3844
- }
3845
- };
3846
- const node = new ObjectVisualElement(options);
3847
- node.mount(subject);
3848
- visualElementStore.set(subject, node);
3849
- }
3850
- function isSingleValue(subject, keyframes2) {
3851
- return isMotionValue(subject) || typeof subject === "number" || typeof subject === "string" && !isDOMKeyframes(keyframes2);
3852
- }
3853
- function animateSubject(subject, keyframes2, options, scope) {
3854
- const animations = [];
3855
- if (isSingleValue(subject, keyframes2)) {
3856
- animations.push(animateSingleValue(subject, isDOMKeyframes(keyframes2) ? keyframes2.default || keyframes2 : keyframes2, options ? options.default || options : options));
3857
- } else {
3858
- const subjects = resolveSubjects(subject, keyframes2, scope);
3859
- const numSubjects = subjects.length;
3860
- invariant(Boolean(numSubjects), "No valid elements provided.");
3861
- for (let i = 0; i < numSubjects; i++) {
3862
- const thisSubject = subjects[i];
3863
- const createVisualElement = thisSubject instanceof Element ? createDOMVisualElement : createObjectVisualElement;
3864
- if (!visualElementStore.has(thisSubject)) {
3865
- createVisualElement(thisSubject);
3866
- }
3867
- const visualElement = visualElementStore.get(thisSubject);
3868
- const transition = { ...options };
3869
- if ("delay" in transition && typeof transition.delay === "function") {
3870
- transition.delay = transition.delay(i, numSubjects);
3871
- }
3872
- animations.push(...animateTarget(visualElement, { ...keyframes2, transition }, {}));
3873
- }
3874
- }
3875
- return animations;
3876
- }
3877
- function animateSequence(sequence, options, scope) {
3878
- const animations = [];
3879
- const animationDefinitions = createAnimationsFromSequence(sequence, options, scope, { spring });
3880
- animationDefinitions.forEach(({ keyframes: keyframes2, transition }, subject) => {
3881
- animations.push(...animateSubject(subject, keyframes2, transition));
3882
- });
3883
- return animations;
3884
- }
3885
- function isSequence(value) {
3886
- return Array.isArray(value) && Array.isArray(value[0]);
3887
- }
3888
- function createScopedAnimate(scope) {
3889
- function scopedAnimate(subjectOrSequence, optionsOrKeyframes, options) {
3890
- let animations = [];
3891
- if (isSequence(subjectOrSequence)) {
3892
- animations = animateSequence(subjectOrSequence, optionsOrKeyframes, scope);
3893
- } else {
3894
- animations = animateSubject(subjectOrSequence, optionsOrKeyframes, options, scope);
3895
- }
3896
- const animation = new GroupPlaybackControls(animations);
3897
- if (scope) {
3898
- scope.animations.push(animation);
3899
- }
3900
- return animation;
3901
- }
3902
- return scopedAnimate;
3903
- }
3904
- function useAnimate() {
3905
- const scope = useConstant(() => ({
3906
- current: null,
3907
- // Will be hydrated by React
3908
- animations: []
3909
- }));
3910
- const animate = useConstant(() => createScopedAnimate(scope));
3911
- useUnmountEffect(() => {
3912
- scope.animations.forEach((animation) => animation.stop());
3913
- });
3914
- return [scope, animate];
3915
- }
8
+ import { u as useAnimate } from "../../use-animate.js";
3916
9
  var TogglePosition = /* @__PURE__ */ ((TogglePosition2) => {
3917
10
  TogglePosition2["left"] = "left";
3918
11
  TogglePosition2["right"] = "right";