@helsenorge/designsystem-react 12.9.0 → 12.10.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.
@@ -0,0 +1,3531 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import React__default, { createContext, useContext, useMemo, useCallback, useRef, useInsertionEffect, useEffect, forwardRef, Fragment, createElement, Component } from "react";
3
+ import { mergeRefs } from "../../utils/refs.js";
4
+ import { T as Toast } from "../../Toast.js";
5
+ import styles from "./styles.module.scss";
6
+ import { P as PresenceContext, M as MotionConfigContext, a as useIsomorphicLayoutEffect, L as LayoutGroupContext, u as usePresence, A as AnimatePresence } from "../../index2.js";
7
+ import { w as featureDefinitions, x as warnOnce, y as isControllingVariants, z as isVariantLabel, A as createRenderBatcher, B as optimizedAppearDataAttribute, i as isBrowser, C as warning, k as invariant, f as isMotionValue, D as isCustomValue, u as useConstant, E as isVariantNode, F as isAnimationControls, I as resolveVariantFromProps, J as scrapeMotionValuesFromProps, K as transformProps, L as frame, M as buildSVGAttrs, N as isSVGTag, O as renderSVG, P as scrapeMotionValuesFromProps$1, Q as isForcedMotionValue, R as buildHTMLStyles, T as resolveVariant, q as animateTarget, U as variantProps, W as isKeyframesTarget, X as variantPriorityOrder, Y as frameData, Z as pipe, _ as cancelFrame, s as secondsToMilliseconds, a as millisecondsToSeconds, d as mixNumber, p as progress, l as createBox, $ as measurePageBox, a0 as convertBoxToBoundingBox, a1 as convertBoundingBoxToBox, a2 as addValueToWillChange, a3 as animateMotionValue, a4 as percent, a5 as noop, a6 as px, a7 as complex, a8 as addScaleCorrector, a9 as addUniqueItem, e as removeItem, aa as time, ab as circOut, ac as scalePoint, ad as SubscriptionManager, n as isSVGElement, ae as getValueTransition, af as frameSteps, ag as hasTransform, ah as translateAxis, ai as transformBox, aj as hasScale, ak as applyBoxDelta, al as has2DTranslate, am as applyTreeDeltas, an as createDelta, o as animateSingleValue, ao as scaleCorrectors, ap as getOptimisedAppearId, r as resolveElements, S as SVGVisualElement, H as HTMLVisualElement } from "../../SVGVisualElement.js";
8
+ import { c as clamp } from "../../clamp.js";
9
+ const LazyContext = createContext({ strict: false });
10
+ function loadFeatures(features) {
11
+ for (const key in features) {
12
+ featureDefinitions[key] = {
13
+ ...featureDefinitions[key],
14
+ ...features[key]
15
+ };
16
+ }
17
+ }
18
+ const validMotionProps = /* @__PURE__ */ new Set([
19
+ "animate",
20
+ "exit",
21
+ "variants",
22
+ "initial",
23
+ "style",
24
+ "values",
25
+ "variants",
26
+ "transition",
27
+ "transformTemplate",
28
+ "custom",
29
+ "inherit",
30
+ "onBeforeLayoutMeasure",
31
+ "onAnimationStart",
32
+ "onAnimationComplete",
33
+ "onUpdate",
34
+ "onDragStart",
35
+ "onDrag",
36
+ "onDragEnd",
37
+ "onMeasureDragConstraints",
38
+ "onDirectionLock",
39
+ "onDragTransitionEnd",
40
+ "_dragX",
41
+ "_dragY",
42
+ "onHoverStart",
43
+ "onHoverEnd",
44
+ "onViewportEnter",
45
+ "onViewportLeave",
46
+ "globalTapTarget",
47
+ "ignoreStrict",
48
+ "viewport"
49
+ ]);
50
+ function isValidMotionProp(key) {
51
+ return key.startsWith("while") || key.startsWith("drag") && key !== "draggable" || key.startsWith("layout") || key.startsWith("onTap") || key.startsWith("onPan") || key.startsWith("onLayout") || validMotionProps.has(key);
52
+ }
53
+ let shouldForward = (key) => !isValidMotionProp(key);
54
+ function loadExternalIsValidProp(isValidProp) {
55
+ if (!isValidProp)
56
+ return;
57
+ shouldForward = (key) => key.startsWith("on") ? !isValidMotionProp(key) : isValidProp(key);
58
+ }
59
+ try {
60
+ loadExternalIsValidProp(require("@emotion/is-prop-valid").default);
61
+ } catch (_a) {
62
+ }
63
+ function filterProps(props, isDom, forwardMotionProps) {
64
+ const filteredProps = {};
65
+ for (const key in props) {
66
+ if (key === "values" && typeof props.values === "object")
67
+ continue;
68
+ if (shouldForward(key) || forwardMotionProps === true && isValidMotionProp(key) || !isDom && !isValidMotionProp(key) || // If trying to use native HTML drag events, forward drag listeners
69
+ props["draggable"] && key.startsWith("onDrag")) {
70
+ filteredProps[key] = props[key];
71
+ }
72
+ }
73
+ return filteredProps;
74
+ }
75
+ function createDOMMotionComponentProxy(componentFactory) {
76
+ if (typeof Proxy === "undefined") {
77
+ return componentFactory;
78
+ }
79
+ const componentCache = /* @__PURE__ */ new Map();
80
+ const deprecatedFactoryFunction = (...args) => {
81
+ if (process.env.NODE_ENV !== "production") {
82
+ warnOnce(false, "motion() is deprecated. Use motion.create() instead.");
83
+ }
84
+ return componentFactory(...args);
85
+ };
86
+ return new Proxy(deprecatedFactoryFunction, {
87
+ /**
88
+ * Called when `motion` is referenced with a prop: `motion.div`, `motion.input` etc.
89
+ * The prop name is passed through as `key` and we can use that to generate a `motion`
90
+ * DOM component with that name.
91
+ */
92
+ get: (_target, key) => {
93
+ if (key === "create")
94
+ return componentFactory;
95
+ if (!componentCache.has(key)) {
96
+ componentCache.set(key, componentFactory(key));
97
+ }
98
+ return componentCache.get(key);
99
+ }
100
+ });
101
+ }
102
+ const MotionContext = createContext({});
103
+ function getCurrentTreeVariants(props, context) {
104
+ if (isControllingVariants(props)) {
105
+ const { initial, animate } = props;
106
+ return {
107
+ initial: initial === false || isVariantLabel(initial) ? initial : void 0,
108
+ animate: isVariantLabel(animate) ? animate : void 0
109
+ };
110
+ }
111
+ return props.inherit !== false ? context : {};
112
+ }
113
+ function useCreateMotionContext(props) {
114
+ const { initial, animate } = getCurrentTreeVariants(props, useContext(MotionContext));
115
+ return useMemo(() => ({ initial, animate }), [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]);
116
+ }
117
+ function variantLabelsAsDependency(prop) {
118
+ return Array.isArray(prop) ? prop.join(" ") : prop;
119
+ }
120
+ const motionComponentSymbol = Symbol.for("motionComponentSymbol");
121
+ function isRefObject(ref) {
122
+ return ref && typeof ref === "object" && Object.prototype.hasOwnProperty.call(ref, "current");
123
+ }
124
+ function useMotionRef(visualState, visualElement, externalRef) {
125
+ return useCallback(
126
+ (instance) => {
127
+ if (instance) {
128
+ visualState.onMount && visualState.onMount(instance);
129
+ }
130
+ if (visualElement) {
131
+ if (instance) {
132
+ visualElement.mount(instance);
133
+ } else {
134
+ visualElement.unmount();
135
+ }
136
+ }
137
+ if (externalRef) {
138
+ if (typeof externalRef === "function") {
139
+ externalRef(instance);
140
+ } else if (isRefObject(externalRef)) {
141
+ externalRef.current = instance;
142
+ }
143
+ }
144
+ },
145
+ /**
146
+ * Only pass a new ref callback to React if we've received a visual element
147
+ * factory. Otherwise we'll be mounting/remounting every time externalRef
148
+ * or other dependencies change.
149
+ */
150
+ [visualElement]
151
+ );
152
+ }
153
+ const { schedule: microtask } = createRenderBatcher(queueMicrotask, false);
154
+ const SwitchLayoutGroupContext = createContext({});
155
+ function useVisualElement(Component2, visualState, props, createVisualElement, ProjectionNodeConstructor) {
156
+ var _a, _b;
157
+ const { visualElement: parent } = useContext(MotionContext);
158
+ const lazyContext = useContext(LazyContext);
159
+ const presenceContext = useContext(PresenceContext);
160
+ const reducedMotionConfig = useContext(MotionConfigContext).reducedMotion;
161
+ const visualElementRef = useRef(null);
162
+ createVisualElement = createVisualElement || lazyContext.renderer;
163
+ if (!visualElementRef.current && createVisualElement) {
164
+ visualElementRef.current = createVisualElement(Component2, {
165
+ visualState,
166
+ parent,
167
+ props,
168
+ presenceContext,
169
+ blockInitialAnimation: presenceContext ? presenceContext.initial === false : false,
170
+ reducedMotionConfig
171
+ });
172
+ }
173
+ const visualElement = visualElementRef.current;
174
+ const initialLayoutGroupConfig = useContext(SwitchLayoutGroupContext);
175
+ if (visualElement && !visualElement.projection && ProjectionNodeConstructor && (visualElement.type === "html" || visualElement.type === "svg")) {
176
+ createProjectionNode$1(visualElementRef.current, props, ProjectionNodeConstructor, initialLayoutGroupConfig);
177
+ }
178
+ const isMounted = useRef(false);
179
+ useInsertionEffect(() => {
180
+ if (visualElement && isMounted.current) {
181
+ visualElement.update(props, presenceContext);
182
+ }
183
+ });
184
+ const optimisedAppearId = props[optimizedAppearDataAttribute];
185
+ const wantsHandoff = useRef(Boolean(optimisedAppearId) && !((_a = window.MotionHandoffIsComplete) === null || _a === void 0 ? void 0 : _a.call(window, optimisedAppearId)) && ((_b = window.MotionHasOptimisedAnimation) === null || _b === void 0 ? void 0 : _b.call(window, optimisedAppearId)));
186
+ useIsomorphicLayoutEffect(() => {
187
+ if (!visualElement)
188
+ return;
189
+ isMounted.current = true;
190
+ window.MotionIsMounted = true;
191
+ visualElement.updateFeatures();
192
+ microtask.render(visualElement.render);
193
+ if (wantsHandoff.current && visualElement.animationState) {
194
+ visualElement.animationState.animateChanges();
195
+ }
196
+ });
197
+ useEffect(() => {
198
+ if (!visualElement)
199
+ return;
200
+ if (!wantsHandoff.current && visualElement.animationState) {
201
+ visualElement.animationState.animateChanges();
202
+ }
203
+ if (wantsHandoff.current) {
204
+ queueMicrotask(() => {
205
+ var _a2;
206
+ (_a2 = window.MotionHandoffMarkAsComplete) === null || _a2 === void 0 ? void 0 : _a2.call(window, optimisedAppearId);
207
+ });
208
+ wantsHandoff.current = false;
209
+ }
210
+ });
211
+ return visualElement;
212
+ }
213
+ function createProjectionNode$1(visualElement, props, ProjectionNodeConstructor, initialPromotionConfig) {
214
+ const { layoutId, layout: layout2, drag: drag2, dragConstraints, layoutScroll, layoutRoot } = props;
215
+ visualElement.projection = new ProjectionNodeConstructor(visualElement.latestValues, props["data-framer-portal-id"] ? void 0 : getClosestProjectingNode(visualElement.parent));
216
+ visualElement.projection.setOptions({
217
+ layoutId,
218
+ layout: layout2,
219
+ alwaysMeasureLayout: Boolean(drag2) || dragConstraints && isRefObject(dragConstraints),
220
+ visualElement,
221
+ /**
222
+ * TODO: Update options in an effect. This could be tricky as it'll be too late
223
+ * to update by the time layout animations run.
224
+ * We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
225
+ * ensuring it gets called if there's no potential layout animations.
226
+ *
227
+ */
228
+ animationType: typeof layout2 === "string" ? layout2 : "both",
229
+ initialPromotionConfig,
230
+ layoutScroll,
231
+ layoutRoot
232
+ });
233
+ }
234
+ function getClosestProjectingNode(visualElement) {
235
+ if (!visualElement)
236
+ return void 0;
237
+ return visualElement.options.allowProjection !== false ? visualElement.projection : getClosestProjectingNode(visualElement.parent);
238
+ }
239
+ function createRendererMotionComponent({ preloadedFeatures, createVisualElement, useRender, useVisualState, Component: Component2 }) {
240
+ var _a, _b;
241
+ preloadedFeatures && loadFeatures(preloadedFeatures);
242
+ function MotionComponent(props, externalRef) {
243
+ let MeasureLayout2;
244
+ const configAndProps = {
245
+ ...useContext(MotionConfigContext),
246
+ ...props,
247
+ layoutId: useLayoutId(props)
248
+ };
249
+ const { isStatic } = configAndProps;
250
+ const context = useCreateMotionContext(props);
251
+ const visualState = useVisualState(props, isStatic);
252
+ if (!isStatic && isBrowser) {
253
+ useStrictMode(configAndProps, preloadedFeatures);
254
+ const layoutProjection = getProjectionFunctionality(configAndProps);
255
+ MeasureLayout2 = layoutProjection.MeasureLayout;
256
+ context.visualElement = useVisualElement(Component2, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode);
257
+ }
258
+ return jsxs(MotionContext.Provider, { value: context, children: [MeasureLayout2 && context.visualElement ? jsx(MeasureLayout2, { visualElement: context.visualElement, ...configAndProps }) : null, useRender(Component2, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, context.visualElement)] });
259
+ }
260
+ MotionComponent.displayName = `motion.${typeof Component2 === "string" ? Component2 : `create(${(_b = (_a = Component2.displayName) !== null && _a !== void 0 ? _a : Component2.name) !== null && _b !== void 0 ? _b : ""})`}`;
261
+ const ForwardRefMotionComponent = forwardRef(MotionComponent);
262
+ ForwardRefMotionComponent[motionComponentSymbol] = Component2;
263
+ return ForwardRefMotionComponent;
264
+ }
265
+ function useLayoutId({ layoutId }) {
266
+ const layoutGroupId = useContext(LayoutGroupContext).id;
267
+ return layoutGroupId && layoutId !== void 0 ? layoutGroupId + "-" + layoutId : layoutId;
268
+ }
269
+ function useStrictMode(configAndProps, preloadedFeatures) {
270
+ const isStrict = useContext(LazyContext).strict;
271
+ if (process.env.NODE_ENV !== "production" && preloadedFeatures && isStrict) {
272
+ const strictMessage = "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.";
273
+ configAndProps.ignoreStrict ? warning(false, strictMessage) : invariant(false, strictMessage);
274
+ }
275
+ }
276
+ function getProjectionFunctionality(props) {
277
+ const { drag: drag2, layout: layout2 } = featureDefinitions;
278
+ if (!drag2 && !layout2)
279
+ return {};
280
+ const combined = { ...drag2, ...layout2 };
281
+ return {
282
+ MeasureLayout: (drag2 === null || drag2 === void 0 ? void 0 : drag2.isEnabled(props)) || (layout2 === null || layout2 === void 0 ? void 0 : layout2.isEnabled(props)) ? combined.MeasureLayout : void 0,
283
+ ProjectionNode: combined.ProjectionNode
284
+ };
285
+ }
286
+ const lowercaseSVGElements = [
287
+ "animate",
288
+ "circle",
289
+ "defs",
290
+ "desc",
291
+ "ellipse",
292
+ "g",
293
+ "image",
294
+ "line",
295
+ "filter",
296
+ "marker",
297
+ "mask",
298
+ "metadata",
299
+ "path",
300
+ "pattern",
301
+ "polygon",
302
+ "polyline",
303
+ "rect",
304
+ "stop",
305
+ "switch",
306
+ "symbol",
307
+ "svg",
308
+ "text",
309
+ "tspan",
310
+ "use",
311
+ "view"
312
+ ];
313
+ function isSVGComponent(Component2) {
314
+ if (
315
+ /**
316
+ * If it's not a string, it's a custom React component. Currently we only support
317
+ * HTML custom React components.
318
+ */
319
+ typeof Component2 !== "string" || /**
320
+ * If it contains a dash, the element is a custom HTML webcomponent.
321
+ */
322
+ Component2.includes("-")
323
+ ) {
324
+ return false;
325
+ } else if (
326
+ /**
327
+ * If it's in our list of lowercase SVG tags, it's an SVG component
328
+ */
329
+ lowercaseSVGElements.indexOf(Component2) > -1 || /**
330
+ * If it contains a capital letter, it's an SVG component
331
+ */
332
+ /[A-Z]/u.test(Component2)
333
+ ) {
334
+ return true;
335
+ }
336
+ return false;
337
+ }
338
+ function resolveMotionValue(value) {
339
+ const unwrappedValue = isMotionValue(value) ? value.get() : value;
340
+ return isCustomValue(unwrappedValue) ? unwrappedValue.toValue() : unwrappedValue;
341
+ }
342
+ function makeState({ scrapeMotionValuesFromProps: scrapeMotionValuesFromProps2, createRenderState, onUpdate }, props, context, presenceContext) {
343
+ const state = {
344
+ latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps2),
345
+ renderState: createRenderState()
346
+ };
347
+ if (onUpdate) {
348
+ state.onMount = (instance) => onUpdate({ props, current: instance, ...state });
349
+ state.onUpdate = (visualElement) => onUpdate(visualElement);
350
+ }
351
+ return state;
352
+ }
353
+ const makeUseVisualState = (config) => (props, isStatic) => {
354
+ const context = useContext(MotionContext);
355
+ const presenceContext = useContext(PresenceContext);
356
+ const make = () => makeState(config, props, context, presenceContext);
357
+ return isStatic ? make() : useConstant(make);
358
+ };
359
+ function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
360
+ const values = {};
361
+ const motionValues = scrapeMotionValues(props, {});
362
+ for (const key in motionValues) {
363
+ values[key] = resolveMotionValue(motionValues[key]);
364
+ }
365
+ let { initial, animate } = props;
366
+ const isControllingVariants$1 = isControllingVariants(props);
367
+ const isVariantNode$1 = isVariantNode(props);
368
+ if (context && isVariantNode$1 && !isControllingVariants$1 && props.inherit !== false) {
369
+ if (initial === void 0)
370
+ initial = context.initial;
371
+ if (animate === void 0)
372
+ animate = context.animate;
373
+ }
374
+ let isInitialAnimationBlocked = presenceContext ? presenceContext.initial === false : false;
375
+ isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false;
376
+ const variantToSet = isInitialAnimationBlocked ? animate : initial;
377
+ if (variantToSet && typeof variantToSet !== "boolean" && !isAnimationControls(variantToSet)) {
378
+ const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
379
+ for (let i = 0; i < list.length; i++) {
380
+ const resolved = resolveVariantFromProps(props, list[i]);
381
+ if (resolved) {
382
+ const { transitionEnd, transition, ...target } = resolved;
383
+ for (const key in target) {
384
+ let valueTarget = target[key];
385
+ if (Array.isArray(valueTarget)) {
386
+ const index = isInitialAnimationBlocked ? valueTarget.length - 1 : 0;
387
+ valueTarget = valueTarget[index];
388
+ }
389
+ if (valueTarget !== null) {
390
+ values[key] = valueTarget;
391
+ }
392
+ }
393
+ for (const key in transitionEnd) {
394
+ values[key] = transitionEnd[key];
395
+ }
396
+ }
397
+ }
398
+ }
399
+ return values;
400
+ }
401
+ const createHtmlRenderState = () => ({
402
+ style: {},
403
+ transform: {},
404
+ transformOrigin: {},
405
+ vars: {}
406
+ });
407
+ const createSvgRenderState = () => ({
408
+ ...createHtmlRenderState(),
409
+ attrs: {}
410
+ });
411
+ function updateSVGDimensions(instance, renderState) {
412
+ try {
413
+ renderState.dimensions = typeof instance.getBBox === "function" ? instance.getBBox() : instance.getBoundingClientRect();
414
+ } catch (e) {
415
+ renderState.dimensions = {
416
+ x: 0,
417
+ y: 0,
418
+ width: 0,
419
+ height: 0
420
+ };
421
+ }
422
+ }
423
+ const layoutProps = ["x", "y", "width", "height", "cx", "cy", "r"];
424
+ const svgMotionConfig = {
425
+ useVisualState: makeUseVisualState({
426
+ scrapeMotionValuesFromProps,
427
+ createRenderState: createSvgRenderState,
428
+ onUpdate: ({ props, prevProps, current, renderState, latestValues }) => {
429
+ if (!current)
430
+ return;
431
+ let hasTransform2 = !!props.drag;
432
+ if (!hasTransform2) {
433
+ for (const key in latestValues) {
434
+ if (transformProps.has(key)) {
435
+ hasTransform2 = true;
436
+ break;
437
+ }
438
+ }
439
+ }
440
+ if (!hasTransform2)
441
+ return;
442
+ let needsMeasure = !prevProps;
443
+ if (prevProps) {
444
+ for (let i = 0; i < layoutProps.length; i++) {
445
+ const key = layoutProps[i];
446
+ if (props[key] !== prevProps[key]) {
447
+ needsMeasure = true;
448
+ }
449
+ }
450
+ }
451
+ if (!needsMeasure)
452
+ return;
453
+ frame.read(() => {
454
+ updateSVGDimensions(current, renderState);
455
+ frame.render(() => {
456
+ buildSVGAttrs(renderState, latestValues, isSVGTag(current.tagName), props.transformTemplate);
457
+ renderSVG(current, renderState);
458
+ });
459
+ });
460
+ }
461
+ })
462
+ };
463
+ const htmlMotionConfig = {
464
+ useVisualState: makeUseVisualState({
465
+ scrapeMotionValuesFromProps: scrapeMotionValuesFromProps$1,
466
+ createRenderState: createHtmlRenderState
467
+ })
468
+ };
469
+ function copyRawValuesOnly(target, source, props) {
470
+ for (const key in source) {
471
+ if (!isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {
472
+ target[key] = source[key];
473
+ }
474
+ }
475
+ }
476
+ function useInitialMotionValues({ transformTemplate }, visualState) {
477
+ return useMemo(() => {
478
+ const state = createHtmlRenderState();
479
+ buildHTMLStyles(state, visualState, transformTemplate);
480
+ return Object.assign({}, state.vars, state.style);
481
+ }, [visualState]);
482
+ }
483
+ function useStyle(props, visualState) {
484
+ const styleProp = props.style || {};
485
+ const style = {};
486
+ copyRawValuesOnly(style, styleProp, props);
487
+ Object.assign(style, useInitialMotionValues(props, visualState));
488
+ return style;
489
+ }
490
+ function useHTMLProps(props, visualState) {
491
+ const htmlProps = {};
492
+ const style = useStyle(props, visualState);
493
+ if (props.drag && props.dragListener !== false) {
494
+ htmlProps.draggable = false;
495
+ style.userSelect = style.WebkitUserSelect = style.WebkitTouchCallout = "none";
496
+ style.touchAction = props.drag === true ? "none" : `pan-${props.drag === "x" ? "y" : "x"}`;
497
+ }
498
+ if (props.tabIndex === void 0 && (props.onTap || props.onTapStart || props.whileTap)) {
499
+ htmlProps.tabIndex = 0;
500
+ }
501
+ htmlProps.style = style;
502
+ return htmlProps;
503
+ }
504
+ function useSVGProps(props, visualState, _isStatic, Component2) {
505
+ const visualProps = useMemo(() => {
506
+ const state = createSvgRenderState();
507
+ buildSVGAttrs(state, visualState, isSVGTag(Component2), props.transformTemplate);
508
+ return {
509
+ ...state.attrs,
510
+ style: { ...state.style }
511
+ };
512
+ }, [visualState]);
513
+ if (props.style) {
514
+ const rawStyles = {};
515
+ copyRawValuesOnly(rawStyles, props.style, props);
516
+ visualProps.style = { ...rawStyles, ...visualProps.style };
517
+ }
518
+ return visualProps;
519
+ }
520
+ function createUseRender(forwardMotionProps = false) {
521
+ const useRender = (Component2, props, ref, { latestValues }, isStatic) => {
522
+ const useVisualProps = isSVGComponent(Component2) ? useSVGProps : useHTMLProps;
523
+ const visualProps = useVisualProps(props, latestValues, isStatic, Component2);
524
+ const filteredProps = filterProps(props, typeof Component2 === "string", forwardMotionProps);
525
+ const elementProps = Component2 !== Fragment ? { ...filteredProps, ...visualProps, ref } : {};
526
+ const { children } = props;
527
+ const renderedChildren = useMemo(() => isMotionValue(children) ? children.get() : children, [children]);
528
+ return createElement(Component2, {
529
+ ...elementProps,
530
+ children: renderedChildren
531
+ });
532
+ };
533
+ return useRender;
534
+ }
535
+ function createMotionComponentFactory(preloadedFeatures, createVisualElement) {
536
+ return function createMotionComponent2(Component2, { forwardMotionProps } = { forwardMotionProps: false }) {
537
+ const baseConfig = isSVGComponent(Component2) ? svgMotionConfig : htmlMotionConfig;
538
+ const config = {
539
+ ...baseConfig,
540
+ preloadedFeatures,
541
+ useRender: createUseRender(forwardMotionProps),
542
+ createVisualElement,
543
+ Component: Component2
544
+ };
545
+ return createRendererMotionComponent(config);
546
+ };
547
+ }
548
+ function shallowCompare(next, prev) {
549
+ if (!Array.isArray(prev))
550
+ return false;
551
+ const prevLength = prev.length;
552
+ if (prevLength !== next.length)
553
+ return false;
554
+ for (let i = 0; i < prevLength; i++) {
555
+ if (prev[i] !== next[i])
556
+ return false;
557
+ }
558
+ return true;
559
+ }
560
+ function animateVariant(visualElement, variant, options = {}) {
561
+ var _a;
562
+ const resolved = resolveVariant(visualElement, variant, options.type === "exit" ? (_a = visualElement.presenceContext) === null || _a === void 0 ? void 0 : _a.custom : void 0);
563
+ let { transition = visualElement.getDefaultTransition() || {} } = resolved || {};
564
+ if (options.transitionOverride) {
565
+ transition = options.transitionOverride;
566
+ }
567
+ const getAnimation = resolved ? () => Promise.all(animateTarget(visualElement, resolved, options)) : () => Promise.resolve();
568
+ const getChildAnimations = visualElement.variantChildren && visualElement.variantChildren.size ? (forwardDelay = 0) => {
569
+ const { delayChildren = 0, staggerChildren, staggerDirection } = transition;
570
+ return animateChildren(visualElement, variant, delayChildren + forwardDelay, staggerChildren, staggerDirection, options);
571
+ } : () => Promise.resolve();
572
+ const { when } = transition;
573
+ if (when) {
574
+ const [first, last] = when === "beforeChildren" ? [getAnimation, getChildAnimations] : [getChildAnimations, getAnimation];
575
+ return first().then(() => last());
576
+ } else {
577
+ return Promise.all([getAnimation(), getChildAnimations(options.delay)]);
578
+ }
579
+ }
580
+ function animateChildren(visualElement, variant, delayChildren = 0, staggerChildren = 0, staggerDirection = 1, options) {
581
+ const animations2 = [];
582
+ const maxStaggerDuration = (visualElement.variantChildren.size - 1) * staggerChildren;
583
+ const generateStaggerDuration = staggerDirection === 1 ? (i = 0) => i * staggerChildren : (i = 0) => maxStaggerDuration - i * staggerChildren;
584
+ Array.from(visualElement.variantChildren).sort(sortByTreeOrder).forEach((child, i) => {
585
+ child.notify("AnimationStart", variant);
586
+ animations2.push(animateVariant(child, variant, {
587
+ ...options,
588
+ delay: delayChildren + generateStaggerDuration(i)
589
+ }).then(() => child.notify("AnimationComplete", variant)));
590
+ });
591
+ return Promise.all(animations2);
592
+ }
593
+ function sortByTreeOrder(a, b) {
594
+ return a.sortNodePosition(b);
595
+ }
596
+ function animateVisualElement(visualElement, definition, options = {}) {
597
+ visualElement.notify("AnimationStart", definition);
598
+ let animation;
599
+ if (Array.isArray(definition)) {
600
+ const animations2 = definition.map((variant) => animateVariant(visualElement, variant, options));
601
+ animation = Promise.all(animations2);
602
+ } else if (typeof definition === "string") {
603
+ animation = animateVariant(visualElement, definition, options);
604
+ } else {
605
+ const resolvedDefinition = typeof definition === "function" ? resolveVariant(visualElement, definition, options.custom) : definition;
606
+ animation = Promise.all(animateTarget(visualElement, resolvedDefinition, options));
607
+ }
608
+ return animation.then(() => {
609
+ visualElement.notify("AnimationComplete", definition);
610
+ });
611
+ }
612
+ const numVariantProps = variantProps.length;
613
+ function getVariantContext(visualElement) {
614
+ if (!visualElement)
615
+ return void 0;
616
+ if (!visualElement.isControllingVariants) {
617
+ const context2 = visualElement.parent ? getVariantContext(visualElement.parent) || {} : {};
618
+ if (visualElement.props.initial !== void 0) {
619
+ context2.initial = visualElement.props.initial;
620
+ }
621
+ return context2;
622
+ }
623
+ const context = {};
624
+ for (let i = 0; i < numVariantProps; i++) {
625
+ const name = variantProps[i];
626
+ const prop = visualElement.props[name];
627
+ if (isVariantLabel(prop) || prop === false) {
628
+ context[name] = prop;
629
+ }
630
+ }
631
+ return context;
632
+ }
633
+ const reversePriorityOrder = [...variantPriorityOrder].reverse();
634
+ const numAnimationTypes = variantPriorityOrder.length;
635
+ function animateList(visualElement) {
636
+ return (animations2) => Promise.all(animations2.map(({ animation, options }) => animateVisualElement(visualElement, animation, options)));
637
+ }
638
+ function createAnimationState(visualElement) {
639
+ let animate = animateList(visualElement);
640
+ let state = createState();
641
+ let isInitialRender = true;
642
+ const buildResolvedTypeValues = (type) => (acc, definition) => {
643
+ var _a;
644
+ const resolved = resolveVariant(visualElement, definition, type === "exit" ? (_a = visualElement.presenceContext) === null || _a === void 0 ? void 0 : _a.custom : void 0);
645
+ if (resolved) {
646
+ const { transition, transitionEnd, ...target } = resolved;
647
+ acc = { ...acc, ...target, ...transitionEnd };
648
+ }
649
+ return acc;
650
+ };
651
+ function setAnimateFunction(makeAnimator) {
652
+ animate = makeAnimator(visualElement);
653
+ }
654
+ function animateChanges(changedActiveType) {
655
+ const { props } = visualElement;
656
+ const context = getVariantContext(visualElement.parent) || {};
657
+ const animations2 = [];
658
+ const removedKeys = /* @__PURE__ */ new Set();
659
+ let encounteredKeys = {};
660
+ let removedVariantIndex = Infinity;
661
+ for (let i = 0; i < numAnimationTypes; i++) {
662
+ const type = reversePriorityOrder[i];
663
+ const typeState = state[type];
664
+ const prop = props[type] !== void 0 ? props[type] : context[type];
665
+ const propIsVariant = isVariantLabel(prop);
666
+ const activeDelta = type === changedActiveType ? typeState.isActive : null;
667
+ if (activeDelta === false)
668
+ removedVariantIndex = i;
669
+ let isInherited = prop === context[type] && prop !== props[type] && propIsVariant;
670
+ if (isInherited && isInitialRender && visualElement.manuallyAnimateOnMount) {
671
+ isInherited = false;
672
+ }
673
+ typeState.protectedKeys = { ...encounteredKeys };
674
+ if (
675
+ // If it isn't active and hasn't *just* been set as inactive
676
+ !typeState.isActive && activeDelta === null || // If we didn't and don't have any defined prop for this animation type
677
+ !prop && !typeState.prevProp || // Or if the prop doesn't define an animation
678
+ isAnimationControls(prop) || typeof prop === "boolean"
679
+ ) {
680
+ continue;
681
+ }
682
+ const variantDidChange = checkVariantsDidChange(typeState.prevProp, prop);
683
+ let shouldAnimateType = variantDidChange || // If we're making this variant active, we want to always make it active
684
+ type === changedActiveType && typeState.isActive && !isInherited && propIsVariant || // If we removed a higher-priority variant (i is in reverse order)
685
+ i > removedVariantIndex && propIsVariant;
686
+ let handledRemovedValues = false;
687
+ const definitionList = Array.isArray(prop) ? prop : [prop];
688
+ let resolvedValues = definitionList.reduce(buildResolvedTypeValues(type), {});
689
+ if (activeDelta === false)
690
+ resolvedValues = {};
691
+ const { prevResolvedValues = {} } = typeState;
692
+ const allKeys = {
693
+ ...prevResolvedValues,
694
+ ...resolvedValues
695
+ };
696
+ const markToAnimate = (key) => {
697
+ shouldAnimateType = true;
698
+ if (removedKeys.has(key)) {
699
+ handledRemovedValues = true;
700
+ removedKeys.delete(key);
701
+ }
702
+ typeState.needsAnimating[key] = true;
703
+ const motionValue = visualElement.getValue(key);
704
+ if (motionValue)
705
+ motionValue.liveStyle = false;
706
+ };
707
+ for (const key in allKeys) {
708
+ const next = resolvedValues[key];
709
+ const prev = prevResolvedValues[key];
710
+ if (encounteredKeys.hasOwnProperty(key))
711
+ continue;
712
+ let valueHasChanged = false;
713
+ if (isKeyframesTarget(next) && isKeyframesTarget(prev)) {
714
+ valueHasChanged = !shallowCompare(next, prev);
715
+ } else {
716
+ valueHasChanged = next !== prev;
717
+ }
718
+ if (valueHasChanged) {
719
+ if (next !== void 0 && next !== null) {
720
+ markToAnimate(key);
721
+ } else {
722
+ removedKeys.add(key);
723
+ }
724
+ } else if (next !== void 0 && removedKeys.has(key)) {
725
+ markToAnimate(key);
726
+ } else {
727
+ typeState.protectedKeys[key] = true;
728
+ }
729
+ }
730
+ typeState.prevProp = prop;
731
+ typeState.prevResolvedValues = resolvedValues;
732
+ if (typeState.isActive) {
733
+ encounteredKeys = { ...encounteredKeys, ...resolvedValues };
734
+ }
735
+ if (isInitialRender && visualElement.blockInitialAnimation) {
736
+ shouldAnimateType = false;
737
+ }
738
+ const willAnimateViaParent = isInherited && variantDidChange;
739
+ const needsAnimating = !willAnimateViaParent || handledRemovedValues;
740
+ if (shouldAnimateType && needsAnimating) {
741
+ animations2.push(...definitionList.map((animation) => ({
742
+ animation,
743
+ options: { type }
744
+ })));
745
+ }
746
+ }
747
+ if (removedKeys.size) {
748
+ const fallbackAnimation = {};
749
+ removedKeys.forEach((key) => {
750
+ const fallbackTarget = visualElement.getBaseTarget(key);
751
+ const motionValue = visualElement.getValue(key);
752
+ if (motionValue)
753
+ motionValue.liveStyle = true;
754
+ fallbackAnimation[key] = fallbackTarget !== null && fallbackTarget !== void 0 ? fallbackTarget : null;
755
+ });
756
+ animations2.push({ animation: fallbackAnimation });
757
+ }
758
+ let shouldAnimate = Boolean(animations2.length);
759
+ if (isInitialRender && (props.initial === false || props.initial === props.animate) && !visualElement.manuallyAnimateOnMount) {
760
+ shouldAnimate = false;
761
+ }
762
+ isInitialRender = false;
763
+ return shouldAnimate ? animate(animations2) : Promise.resolve();
764
+ }
765
+ function setActive(type, isActive) {
766
+ var _a;
767
+ if (state[type].isActive === isActive)
768
+ return Promise.resolve();
769
+ (_a = visualElement.variantChildren) === null || _a === void 0 ? void 0 : _a.forEach((child) => {
770
+ var _a2;
771
+ return (_a2 = child.animationState) === null || _a2 === void 0 ? void 0 : _a2.setActive(type, isActive);
772
+ });
773
+ state[type].isActive = isActive;
774
+ const animations2 = animateChanges(type);
775
+ for (const key in state) {
776
+ state[key].protectedKeys = {};
777
+ }
778
+ return animations2;
779
+ }
780
+ return {
781
+ animateChanges,
782
+ setActive,
783
+ setAnimateFunction,
784
+ getState: () => state,
785
+ reset: () => {
786
+ state = createState();
787
+ isInitialRender = true;
788
+ }
789
+ };
790
+ }
791
+ function checkVariantsDidChange(prev, next) {
792
+ if (typeof next === "string") {
793
+ return next !== prev;
794
+ } else if (Array.isArray(next)) {
795
+ return !shallowCompare(next, prev);
796
+ }
797
+ return false;
798
+ }
799
+ function createTypeState(isActive = false) {
800
+ return {
801
+ isActive,
802
+ protectedKeys: {},
803
+ needsAnimating: {},
804
+ prevResolvedValues: {}
805
+ };
806
+ }
807
+ function createState() {
808
+ return {
809
+ animate: createTypeState(true),
810
+ whileInView: createTypeState(),
811
+ whileHover: createTypeState(),
812
+ whileTap: createTypeState(),
813
+ whileDrag: createTypeState(),
814
+ whileFocus: createTypeState(),
815
+ exit: createTypeState()
816
+ };
817
+ }
818
+ class Feature {
819
+ constructor(node) {
820
+ this.isMounted = false;
821
+ this.node = node;
822
+ }
823
+ update() {
824
+ }
825
+ }
826
+ class AnimationFeature extends Feature {
827
+ /**
828
+ * We dynamically generate the AnimationState manager as it contains a reference
829
+ * to the underlying animation library. We only want to load that if we load this,
830
+ * so people can optionally code split it out using the `m` component.
831
+ */
832
+ constructor(node) {
833
+ super(node);
834
+ node.animationState || (node.animationState = createAnimationState(node));
835
+ }
836
+ updateAnimationControlsSubscription() {
837
+ const { animate } = this.node.getProps();
838
+ if (isAnimationControls(animate)) {
839
+ this.unmountControls = animate.subscribe(this.node);
840
+ }
841
+ }
842
+ /**
843
+ * Subscribe any provided AnimationControls to the component's VisualElement
844
+ */
845
+ mount() {
846
+ this.updateAnimationControlsSubscription();
847
+ }
848
+ update() {
849
+ const { animate } = this.node.getProps();
850
+ const { animate: prevAnimate } = this.node.prevProps || {};
851
+ if (animate !== prevAnimate) {
852
+ this.updateAnimationControlsSubscription();
853
+ }
854
+ }
855
+ unmount() {
856
+ var _a;
857
+ this.node.animationState.reset();
858
+ (_a = this.unmountControls) === null || _a === void 0 ? void 0 : _a.call(this);
859
+ }
860
+ }
861
+ let id$1 = 0;
862
+ class ExitAnimationFeature extends Feature {
863
+ constructor() {
864
+ super(...arguments);
865
+ this.id = id$1++;
866
+ }
867
+ update() {
868
+ if (!this.node.presenceContext)
869
+ return;
870
+ const { isPresent, onExitComplete } = this.node.presenceContext;
871
+ const { isPresent: prevIsPresent } = this.node.prevPresenceContext || {};
872
+ if (!this.node.animationState || isPresent === prevIsPresent) {
873
+ return;
874
+ }
875
+ const exitAnimation = this.node.animationState.setActive("exit", !isPresent);
876
+ if (onExitComplete && !isPresent) {
877
+ exitAnimation.then(() => onExitComplete(this.id));
878
+ }
879
+ }
880
+ mount() {
881
+ const { register } = this.node.presenceContext || {};
882
+ if (register) {
883
+ this.unmount = register(this.id);
884
+ }
885
+ }
886
+ unmount() {
887
+ }
888
+ }
889
+ const animations = {
890
+ animation: {
891
+ Feature: AnimationFeature
892
+ },
893
+ exit: {
894
+ Feature: ExitAnimationFeature
895
+ }
896
+ };
897
+ const isDragging = {
898
+ x: false,
899
+ y: false
900
+ };
901
+ function isDragActive() {
902
+ return isDragging.x || isDragging.y;
903
+ }
904
+ function setDragLock(axis) {
905
+ if (axis === "x" || axis === "y") {
906
+ if (isDragging[axis]) {
907
+ return null;
908
+ } else {
909
+ isDragging[axis] = true;
910
+ return () => {
911
+ isDragging[axis] = false;
912
+ };
913
+ }
914
+ } else {
915
+ if (isDragging.x || isDragging.y) {
916
+ return null;
917
+ } else {
918
+ isDragging.x = isDragging.y = true;
919
+ return () => {
920
+ isDragging.x = isDragging.y = false;
921
+ };
922
+ }
923
+ }
924
+ }
925
+ const isPrimaryPointer = (event) => {
926
+ if (event.pointerType === "mouse") {
927
+ return typeof event.button !== "number" || event.button <= 0;
928
+ } else {
929
+ return event.isPrimary !== false;
930
+ }
931
+ };
932
+ function addDomEvent(target, eventName, handler, options = { passive: true }) {
933
+ target.addEventListener(eventName, handler, options);
934
+ return () => target.removeEventListener(eventName, handler);
935
+ }
936
+ function extractEventInfo(event) {
937
+ return {
938
+ point: {
939
+ x: event.pageX,
940
+ y: event.pageY
941
+ }
942
+ };
943
+ }
944
+ const addPointerInfo = (handler) => {
945
+ return (event) => isPrimaryPointer(event) && handler(event, extractEventInfo(event));
946
+ };
947
+ function addPointerEvent(target, eventName, handler, options) {
948
+ return addDomEvent(target, eventName, addPointerInfo(handler), options);
949
+ }
950
+ const distance = (a, b) => Math.abs(a - b);
951
+ function distance2D(a, b) {
952
+ const xDelta = distance(a.x, b.x);
953
+ const yDelta = distance(a.y, b.y);
954
+ return Math.sqrt(xDelta ** 2 + yDelta ** 2);
955
+ }
956
+ class PanSession {
957
+ constructor(event, handlers, { transformPagePoint, contextWindow, dragSnapToOrigin = false } = {}) {
958
+ this.startEvent = null;
959
+ this.lastMoveEvent = null;
960
+ this.lastMoveEventInfo = null;
961
+ this.handlers = {};
962
+ this.contextWindow = window;
963
+ this.updatePoint = () => {
964
+ if (!(this.lastMoveEvent && this.lastMoveEventInfo))
965
+ return;
966
+ const info2 = getPanInfo(this.lastMoveEventInfo, this.history);
967
+ const isPanStarted = this.startEvent !== null;
968
+ const isDistancePastThreshold = distance2D(info2.offset, { x: 0, y: 0 }) >= 3;
969
+ if (!isPanStarted && !isDistancePastThreshold)
970
+ return;
971
+ const { point: point2 } = info2;
972
+ const { timestamp: timestamp2 } = frameData;
973
+ this.history.push({ ...point2, timestamp: timestamp2 });
974
+ const { onStart, onMove } = this.handlers;
975
+ if (!isPanStarted) {
976
+ onStart && onStart(this.lastMoveEvent, info2);
977
+ this.startEvent = this.lastMoveEvent;
978
+ }
979
+ onMove && onMove(this.lastMoveEvent, info2);
980
+ };
981
+ this.handlePointerMove = (event2, info2) => {
982
+ this.lastMoveEvent = event2;
983
+ this.lastMoveEventInfo = transformPoint(info2, this.transformPagePoint);
984
+ frame.update(this.updatePoint, true);
985
+ };
986
+ this.handlePointerUp = (event2, info2) => {
987
+ this.end();
988
+ const { onEnd, onSessionEnd, resumeAnimation } = this.handlers;
989
+ if (this.dragSnapToOrigin)
990
+ resumeAnimation && resumeAnimation();
991
+ if (!(this.lastMoveEvent && this.lastMoveEventInfo))
992
+ return;
993
+ const panInfo = getPanInfo(event2.type === "pointercancel" ? this.lastMoveEventInfo : transformPoint(info2, this.transformPagePoint), this.history);
994
+ if (this.startEvent && onEnd) {
995
+ onEnd(event2, panInfo);
996
+ }
997
+ onSessionEnd && onSessionEnd(event2, panInfo);
998
+ };
999
+ if (!isPrimaryPointer(event))
1000
+ return;
1001
+ this.dragSnapToOrigin = dragSnapToOrigin;
1002
+ this.handlers = handlers;
1003
+ this.transformPagePoint = transformPagePoint;
1004
+ this.contextWindow = contextWindow || window;
1005
+ const info = extractEventInfo(event);
1006
+ const initialInfo = transformPoint(info, this.transformPagePoint);
1007
+ const { point } = initialInfo;
1008
+ const { timestamp } = frameData;
1009
+ this.history = [{ ...point, timestamp }];
1010
+ const { onSessionStart } = handlers;
1011
+ onSessionStart && onSessionStart(event, getPanInfo(initialInfo, this.history));
1012
+ this.removeListeners = pipe(addPointerEvent(this.contextWindow, "pointermove", this.handlePointerMove), addPointerEvent(this.contextWindow, "pointerup", this.handlePointerUp), addPointerEvent(this.contextWindow, "pointercancel", this.handlePointerUp));
1013
+ }
1014
+ updateHandlers(handlers) {
1015
+ this.handlers = handlers;
1016
+ }
1017
+ end() {
1018
+ this.removeListeners && this.removeListeners();
1019
+ cancelFrame(this.updatePoint);
1020
+ }
1021
+ }
1022
+ function transformPoint(info, transformPagePoint) {
1023
+ return transformPagePoint ? { point: transformPagePoint(info.point) } : info;
1024
+ }
1025
+ function subtractPoint(a, b) {
1026
+ return { x: a.x - b.x, y: a.y - b.y };
1027
+ }
1028
+ function getPanInfo({ point }, history) {
1029
+ return {
1030
+ point,
1031
+ delta: subtractPoint(point, lastDevicePoint(history)),
1032
+ offset: subtractPoint(point, startDevicePoint(history)),
1033
+ velocity: getVelocity(history, 0.1)
1034
+ };
1035
+ }
1036
+ function startDevicePoint(history) {
1037
+ return history[0];
1038
+ }
1039
+ function lastDevicePoint(history) {
1040
+ return history[history.length - 1];
1041
+ }
1042
+ function getVelocity(history, timeDelta) {
1043
+ if (history.length < 2) {
1044
+ return { x: 0, y: 0 };
1045
+ }
1046
+ let i = history.length - 1;
1047
+ let timestampedPoint = null;
1048
+ const lastPoint = lastDevicePoint(history);
1049
+ while (i >= 0) {
1050
+ timestampedPoint = history[i];
1051
+ if (lastPoint.timestamp - timestampedPoint.timestamp > secondsToMilliseconds(timeDelta)) {
1052
+ break;
1053
+ }
1054
+ i--;
1055
+ }
1056
+ if (!timestampedPoint) {
1057
+ return { x: 0, y: 0 };
1058
+ }
1059
+ const time2 = millisecondsToSeconds(lastPoint.timestamp - timestampedPoint.timestamp);
1060
+ if (time2 === 0) {
1061
+ return { x: 0, y: 0 };
1062
+ }
1063
+ const currentVelocity = {
1064
+ x: (lastPoint.x - timestampedPoint.x) / time2,
1065
+ y: (lastPoint.y - timestampedPoint.y) / time2
1066
+ };
1067
+ if (currentVelocity.x === Infinity) {
1068
+ currentVelocity.x = 0;
1069
+ }
1070
+ if (currentVelocity.y === Infinity) {
1071
+ currentVelocity.y = 0;
1072
+ }
1073
+ return currentVelocity;
1074
+ }
1075
+ const SCALE_PRECISION = 1e-4;
1076
+ const SCALE_MIN = 1 - SCALE_PRECISION;
1077
+ const SCALE_MAX = 1 + SCALE_PRECISION;
1078
+ const TRANSLATE_PRECISION = 0.01;
1079
+ const TRANSLATE_MIN = 0 - TRANSLATE_PRECISION;
1080
+ const TRANSLATE_MAX = 0 + TRANSLATE_PRECISION;
1081
+ function calcLength(axis) {
1082
+ return axis.max - axis.min;
1083
+ }
1084
+ function isNear(value, target, maxDistance) {
1085
+ return Math.abs(value - target) <= maxDistance;
1086
+ }
1087
+ function calcAxisDelta(delta, source, target, origin = 0.5) {
1088
+ delta.origin = origin;
1089
+ delta.originPoint = mixNumber(source.min, source.max, delta.origin);
1090
+ delta.scale = calcLength(target) / calcLength(source);
1091
+ delta.translate = mixNumber(target.min, target.max, delta.origin) - delta.originPoint;
1092
+ if (delta.scale >= SCALE_MIN && delta.scale <= SCALE_MAX || isNaN(delta.scale)) {
1093
+ delta.scale = 1;
1094
+ }
1095
+ if (delta.translate >= TRANSLATE_MIN && delta.translate <= TRANSLATE_MAX || isNaN(delta.translate)) {
1096
+ delta.translate = 0;
1097
+ }
1098
+ }
1099
+ function calcBoxDelta(delta, source, target, origin) {
1100
+ calcAxisDelta(delta.x, source.x, target.x, origin ? origin.originX : void 0);
1101
+ calcAxisDelta(delta.y, source.y, target.y, origin ? origin.originY : void 0);
1102
+ }
1103
+ function calcRelativeAxis(target, relative, parent) {
1104
+ target.min = parent.min + relative.min;
1105
+ target.max = target.min + calcLength(relative);
1106
+ }
1107
+ function calcRelativeBox(target, relative, parent) {
1108
+ calcRelativeAxis(target.x, relative.x, parent.x);
1109
+ calcRelativeAxis(target.y, relative.y, parent.y);
1110
+ }
1111
+ function calcRelativeAxisPosition(target, layout2, parent) {
1112
+ target.min = layout2.min - parent.min;
1113
+ target.max = target.min + calcLength(layout2);
1114
+ }
1115
+ function calcRelativePosition(target, layout2, parent) {
1116
+ calcRelativeAxisPosition(target.x, layout2.x, parent.x);
1117
+ calcRelativeAxisPosition(target.y, layout2.y, parent.y);
1118
+ }
1119
+ function applyConstraints(point, { min, max }, elastic) {
1120
+ if (min !== void 0 && point < min) {
1121
+ point = elastic ? mixNumber(min, point, elastic.min) : Math.max(point, min);
1122
+ } else if (max !== void 0 && point > max) {
1123
+ point = elastic ? mixNumber(max, point, elastic.max) : Math.min(point, max);
1124
+ }
1125
+ return point;
1126
+ }
1127
+ function calcRelativeAxisConstraints(axis, min, max) {
1128
+ return {
1129
+ min: min !== void 0 ? axis.min + min : void 0,
1130
+ max: max !== void 0 ? axis.max + max - (axis.max - axis.min) : void 0
1131
+ };
1132
+ }
1133
+ function calcRelativeConstraints(layoutBox, { top, left, bottom, right }) {
1134
+ return {
1135
+ x: calcRelativeAxisConstraints(layoutBox.x, left, right),
1136
+ y: calcRelativeAxisConstraints(layoutBox.y, top, bottom)
1137
+ };
1138
+ }
1139
+ function calcViewportAxisConstraints(layoutAxis, constraintsAxis) {
1140
+ let min = constraintsAxis.min - layoutAxis.min;
1141
+ let max = constraintsAxis.max - layoutAxis.max;
1142
+ if (constraintsAxis.max - constraintsAxis.min < layoutAxis.max - layoutAxis.min) {
1143
+ [min, max] = [max, min];
1144
+ }
1145
+ return { min, max };
1146
+ }
1147
+ function calcViewportConstraints(layoutBox, constraintsBox) {
1148
+ return {
1149
+ x: calcViewportAxisConstraints(layoutBox.x, constraintsBox.x),
1150
+ y: calcViewportAxisConstraints(layoutBox.y, constraintsBox.y)
1151
+ };
1152
+ }
1153
+ function calcOrigin(source, target) {
1154
+ let origin = 0.5;
1155
+ const sourceLength = calcLength(source);
1156
+ const targetLength = calcLength(target);
1157
+ if (targetLength > sourceLength) {
1158
+ origin = progress(target.min, target.max - sourceLength, source.min);
1159
+ } else if (sourceLength > targetLength) {
1160
+ origin = progress(source.min, source.max - targetLength, target.min);
1161
+ }
1162
+ return clamp(0, 1, origin);
1163
+ }
1164
+ function rebaseAxisConstraints(layout2, constraints) {
1165
+ const relativeConstraints = {};
1166
+ if (constraints.min !== void 0) {
1167
+ relativeConstraints.min = constraints.min - layout2.min;
1168
+ }
1169
+ if (constraints.max !== void 0) {
1170
+ relativeConstraints.max = constraints.max - layout2.min;
1171
+ }
1172
+ return relativeConstraints;
1173
+ }
1174
+ const defaultElastic = 0.35;
1175
+ function resolveDragElastic(dragElastic = defaultElastic) {
1176
+ if (dragElastic === false) {
1177
+ dragElastic = 0;
1178
+ } else if (dragElastic === true) {
1179
+ dragElastic = defaultElastic;
1180
+ }
1181
+ return {
1182
+ x: resolveAxisElastic(dragElastic, "left", "right"),
1183
+ y: resolveAxisElastic(dragElastic, "top", "bottom")
1184
+ };
1185
+ }
1186
+ function resolveAxisElastic(dragElastic, minLabel, maxLabel) {
1187
+ return {
1188
+ min: resolvePointElastic(dragElastic, minLabel),
1189
+ max: resolvePointElastic(dragElastic, maxLabel)
1190
+ };
1191
+ }
1192
+ function resolvePointElastic(dragElastic, label) {
1193
+ return typeof dragElastic === "number" ? dragElastic : dragElastic[label] || 0;
1194
+ }
1195
+ function eachAxis(callback) {
1196
+ return [callback("x"), callback("y")];
1197
+ }
1198
+ const getContextWindow = ({ current }) => {
1199
+ return current ? current.ownerDocument.defaultView : null;
1200
+ };
1201
+ const elementDragControls = /* @__PURE__ */ new WeakMap();
1202
+ class VisualElementDragControls {
1203
+ constructor(visualElement) {
1204
+ this.openDragLock = null;
1205
+ this.isDragging = false;
1206
+ this.currentDirection = null;
1207
+ this.originPoint = { x: 0, y: 0 };
1208
+ this.constraints = false;
1209
+ this.hasMutatedConstraints = false;
1210
+ this.elastic = createBox();
1211
+ this.visualElement = visualElement;
1212
+ }
1213
+ start(originEvent, { snapToCursor = false } = {}) {
1214
+ const { presenceContext } = this.visualElement;
1215
+ if (presenceContext && presenceContext.isPresent === false)
1216
+ return;
1217
+ const onSessionStart = (event) => {
1218
+ const { dragSnapToOrigin: dragSnapToOrigin2 } = this.getProps();
1219
+ dragSnapToOrigin2 ? this.pauseAnimation() : this.stopAnimation();
1220
+ if (snapToCursor) {
1221
+ this.snapToCursor(extractEventInfo(event).point);
1222
+ }
1223
+ };
1224
+ const onStart = (event, info) => {
1225
+ const { drag: drag2, dragPropagation, onDragStart } = this.getProps();
1226
+ if (drag2 && !dragPropagation) {
1227
+ if (this.openDragLock)
1228
+ this.openDragLock();
1229
+ this.openDragLock = setDragLock(drag2);
1230
+ if (!this.openDragLock)
1231
+ return;
1232
+ }
1233
+ this.isDragging = true;
1234
+ this.currentDirection = null;
1235
+ this.resolveConstraints();
1236
+ if (this.visualElement.projection) {
1237
+ this.visualElement.projection.isAnimationBlocked = true;
1238
+ this.visualElement.projection.target = void 0;
1239
+ }
1240
+ eachAxis((axis) => {
1241
+ let current = this.getAxisMotionValue(axis).get() || 0;
1242
+ if (percent.test(current)) {
1243
+ const { projection } = this.visualElement;
1244
+ if (projection && projection.layout) {
1245
+ const measuredAxis = projection.layout.layoutBox[axis];
1246
+ if (measuredAxis) {
1247
+ const length = calcLength(measuredAxis);
1248
+ current = length * (parseFloat(current) / 100);
1249
+ }
1250
+ }
1251
+ }
1252
+ this.originPoint[axis] = current;
1253
+ });
1254
+ if (onDragStart) {
1255
+ frame.postRender(() => onDragStart(event, info));
1256
+ }
1257
+ addValueToWillChange(this.visualElement, "transform");
1258
+ const { animationState } = this.visualElement;
1259
+ animationState && animationState.setActive("whileDrag", true);
1260
+ };
1261
+ const onMove = (event, info) => {
1262
+ const { dragPropagation, dragDirectionLock, onDirectionLock, onDrag } = this.getProps();
1263
+ if (!dragPropagation && !this.openDragLock)
1264
+ return;
1265
+ const { offset } = info;
1266
+ if (dragDirectionLock && this.currentDirection === null) {
1267
+ this.currentDirection = getCurrentDirection(offset);
1268
+ if (this.currentDirection !== null) {
1269
+ onDirectionLock && onDirectionLock(this.currentDirection);
1270
+ }
1271
+ return;
1272
+ }
1273
+ this.updateAxis("x", info.point, offset);
1274
+ this.updateAxis("y", info.point, offset);
1275
+ this.visualElement.render();
1276
+ onDrag && onDrag(event, info);
1277
+ };
1278
+ const onSessionEnd = (event, info) => this.stop(event, info);
1279
+ const resumeAnimation = () => eachAxis((axis) => {
1280
+ var _a;
1281
+ return this.getAnimationState(axis) === "paused" && ((_a = this.getAxisMotionValue(axis).animation) === null || _a === void 0 ? void 0 : _a.play());
1282
+ });
1283
+ const { dragSnapToOrigin } = this.getProps();
1284
+ this.panSession = new PanSession(originEvent, {
1285
+ onSessionStart,
1286
+ onStart,
1287
+ onMove,
1288
+ onSessionEnd,
1289
+ resumeAnimation
1290
+ }, {
1291
+ transformPagePoint: this.visualElement.getTransformPagePoint(),
1292
+ dragSnapToOrigin,
1293
+ contextWindow: getContextWindow(this.visualElement)
1294
+ });
1295
+ }
1296
+ stop(event, info) {
1297
+ const isDragging2 = this.isDragging;
1298
+ this.cancel();
1299
+ if (!isDragging2)
1300
+ return;
1301
+ const { velocity } = info;
1302
+ this.startAnimation(velocity);
1303
+ const { onDragEnd } = this.getProps();
1304
+ if (onDragEnd) {
1305
+ frame.postRender(() => onDragEnd(event, info));
1306
+ }
1307
+ }
1308
+ cancel() {
1309
+ this.isDragging = false;
1310
+ const { projection, animationState } = this.visualElement;
1311
+ if (projection) {
1312
+ projection.isAnimationBlocked = false;
1313
+ }
1314
+ this.panSession && this.panSession.end();
1315
+ this.panSession = void 0;
1316
+ const { dragPropagation } = this.getProps();
1317
+ if (!dragPropagation && this.openDragLock) {
1318
+ this.openDragLock();
1319
+ this.openDragLock = null;
1320
+ }
1321
+ animationState && animationState.setActive("whileDrag", false);
1322
+ }
1323
+ updateAxis(axis, _point, offset) {
1324
+ const { drag: drag2 } = this.getProps();
1325
+ if (!offset || !shouldDrag(axis, drag2, this.currentDirection))
1326
+ return;
1327
+ const axisValue = this.getAxisMotionValue(axis);
1328
+ let next = this.originPoint[axis] + offset[axis];
1329
+ if (this.constraints && this.constraints[axis]) {
1330
+ next = applyConstraints(next, this.constraints[axis], this.elastic[axis]);
1331
+ }
1332
+ axisValue.set(next);
1333
+ }
1334
+ resolveConstraints() {
1335
+ var _a;
1336
+ const { dragConstraints, dragElastic } = this.getProps();
1337
+ const layout2 = this.visualElement.projection && !this.visualElement.projection.layout ? this.visualElement.projection.measure(false) : (_a = this.visualElement.projection) === null || _a === void 0 ? void 0 : _a.layout;
1338
+ const prevConstraints = this.constraints;
1339
+ if (dragConstraints && isRefObject(dragConstraints)) {
1340
+ if (!this.constraints) {
1341
+ this.constraints = this.resolveRefConstraints();
1342
+ }
1343
+ } else {
1344
+ if (dragConstraints && layout2) {
1345
+ this.constraints = calcRelativeConstraints(layout2.layoutBox, dragConstraints);
1346
+ } else {
1347
+ this.constraints = false;
1348
+ }
1349
+ }
1350
+ this.elastic = resolveDragElastic(dragElastic);
1351
+ if (prevConstraints !== this.constraints && layout2 && this.constraints && !this.hasMutatedConstraints) {
1352
+ eachAxis((axis) => {
1353
+ if (this.constraints !== false && this.getAxisMotionValue(axis)) {
1354
+ this.constraints[axis] = rebaseAxisConstraints(layout2.layoutBox[axis], this.constraints[axis]);
1355
+ }
1356
+ });
1357
+ }
1358
+ }
1359
+ resolveRefConstraints() {
1360
+ const { dragConstraints: constraints, onMeasureDragConstraints } = this.getProps();
1361
+ if (!constraints || !isRefObject(constraints))
1362
+ return false;
1363
+ const constraintsElement = constraints.current;
1364
+ invariant(constraintsElement !== null, "If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.");
1365
+ const { projection } = this.visualElement;
1366
+ if (!projection || !projection.layout)
1367
+ return false;
1368
+ const constraintsBox = measurePageBox(constraintsElement, projection.root, this.visualElement.getTransformPagePoint());
1369
+ let measuredConstraints = calcViewportConstraints(projection.layout.layoutBox, constraintsBox);
1370
+ if (onMeasureDragConstraints) {
1371
+ const userConstraints = onMeasureDragConstraints(convertBoxToBoundingBox(measuredConstraints));
1372
+ this.hasMutatedConstraints = !!userConstraints;
1373
+ if (userConstraints) {
1374
+ measuredConstraints = convertBoundingBoxToBox(userConstraints);
1375
+ }
1376
+ }
1377
+ return measuredConstraints;
1378
+ }
1379
+ startAnimation(velocity) {
1380
+ const { drag: drag2, dragMomentum, dragElastic, dragTransition, dragSnapToOrigin, onDragTransitionEnd } = this.getProps();
1381
+ const constraints = this.constraints || {};
1382
+ const momentumAnimations = eachAxis((axis) => {
1383
+ if (!shouldDrag(axis, drag2, this.currentDirection)) {
1384
+ return;
1385
+ }
1386
+ let transition = constraints && constraints[axis] || {};
1387
+ if (dragSnapToOrigin)
1388
+ transition = { min: 0, max: 0 };
1389
+ const bounceStiffness = dragElastic ? 200 : 1e6;
1390
+ const bounceDamping = dragElastic ? 40 : 1e7;
1391
+ const inertia = {
1392
+ type: "inertia",
1393
+ velocity: dragMomentum ? velocity[axis] : 0,
1394
+ bounceStiffness,
1395
+ bounceDamping,
1396
+ timeConstant: 750,
1397
+ restDelta: 1,
1398
+ restSpeed: 10,
1399
+ ...dragTransition,
1400
+ ...transition
1401
+ };
1402
+ return this.startAxisValueAnimation(axis, inertia);
1403
+ });
1404
+ return Promise.all(momentumAnimations).then(onDragTransitionEnd);
1405
+ }
1406
+ startAxisValueAnimation(axis, transition) {
1407
+ const axisValue = this.getAxisMotionValue(axis);
1408
+ addValueToWillChange(this.visualElement, axis);
1409
+ return axisValue.start(animateMotionValue(axis, axisValue, 0, transition, this.visualElement, false));
1410
+ }
1411
+ stopAnimation() {
1412
+ eachAxis((axis) => this.getAxisMotionValue(axis).stop());
1413
+ }
1414
+ pauseAnimation() {
1415
+ eachAxis((axis) => {
1416
+ var _a;
1417
+ return (_a = this.getAxisMotionValue(axis).animation) === null || _a === void 0 ? void 0 : _a.pause();
1418
+ });
1419
+ }
1420
+ getAnimationState(axis) {
1421
+ var _a;
1422
+ return (_a = this.getAxisMotionValue(axis).animation) === null || _a === void 0 ? void 0 : _a.state;
1423
+ }
1424
+ /**
1425
+ * Drag works differently depending on which props are provided.
1426
+ *
1427
+ * - If _dragX and _dragY are provided, we output the gesture delta directly to those motion values.
1428
+ * - Otherwise, we apply the delta to the x/y motion values.
1429
+ */
1430
+ getAxisMotionValue(axis) {
1431
+ const dragKey = `_drag${axis.toUpperCase()}`;
1432
+ const props = this.visualElement.getProps();
1433
+ const externalMotionValue = props[dragKey];
1434
+ return externalMotionValue ? externalMotionValue : this.visualElement.getValue(axis, (props.initial ? props.initial[axis] : void 0) || 0);
1435
+ }
1436
+ snapToCursor(point) {
1437
+ eachAxis((axis) => {
1438
+ const { drag: drag2 } = this.getProps();
1439
+ if (!shouldDrag(axis, drag2, this.currentDirection))
1440
+ return;
1441
+ const { projection } = this.visualElement;
1442
+ const axisValue = this.getAxisMotionValue(axis);
1443
+ if (projection && projection.layout) {
1444
+ const { min, max } = projection.layout.layoutBox[axis];
1445
+ axisValue.set(point[axis] - mixNumber(min, max, 0.5));
1446
+ }
1447
+ });
1448
+ }
1449
+ /**
1450
+ * When the viewport resizes we want to check if the measured constraints
1451
+ * have changed and, if so, reposition the element within those new constraints
1452
+ * relative to where it was before the resize.
1453
+ */
1454
+ scalePositionWithinConstraints() {
1455
+ if (!this.visualElement.current)
1456
+ return;
1457
+ const { drag: drag2, dragConstraints } = this.getProps();
1458
+ const { projection } = this.visualElement;
1459
+ if (!isRefObject(dragConstraints) || !projection || !this.constraints)
1460
+ return;
1461
+ this.stopAnimation();
1462
+ const boxProgress = { x: 0, y: 0 };
1463
+ eachAxis((axis) => {
1464
+ const axisValue = this.getAxisMotionValue(axis);
1465
+ if (axisValue && this.constraints !== false) {
1466
+ const latest = axisValue.get();
1467
+ boxProgress[axis] = calcOrigin({ min: latest, max: latest }, this.constraints[axis]);
1468
+ }
1469
+ });
1470
+ const { transformTemplate } = this.visualElement.getProps();
1471
+ this.visualElement.current.style.transform = transformTemplate ? transformTemplate({}, "") : "none";
1472
+ projection.root && projection.root.updateScroll();
1473
+ projection.updateLayout();
1474
+ this.resolveConstraints();
1475
+ eachAxis((axis) => {
1476
+ if (!shouldDrag(axis, drag2, null))
1477
+ return;
1478
+ const axisValue = this.getAxisMotionValue(axis);
1479
+ const { min, max } = this.constraints[axis];
1480
+ axisValue.set(mixNumber(min, max, boxProgress[axis]));
1481
+ });
1482
+ }
1483
+ addListeners() {
1484
+ if (!this.visualElement.current)
1485
+ return;
1486
+ elementDragControls.set(this.visualElement, this);
1487
+ const element = this.visualElement.current;
1488
+ const stopPointerListener = addPointerEvent(element, "pointerdown", (event) => {
1489
+ const { drag: drag2, dragListener = true } = this.getProps();
1490
+ drag2 && dragListener && this.start(event);
1491
+ });
1492
+ const measureDragConstraints = () => {
1493
+ const { dragConstraints } = this.getProps();
1494
+ if (isRefObject(dragConstraints) && dragConstraints.current) {
1495
+ this.constraints = this.resolveRefConstraints();
1496
+ }
1497
+ };
1498
+ const { projection } = this.visualElement;
1499
+ const stopMeasureLayoutListener = projection.addEventListener("measure", measureDragConstraints);
1500
+ if (projection && !projection.layout) {
1501
+ projection.root && projection.root.updateScroll();
1502
+ projection.updateLayout();
1503
+ }
1504
+ frame.read(measureDragConstraints);
1505
+ const stopResizeListener = addDomEvent(window, "resize", () => this.scalePositionWithinConstraints());
1506
+ const stopLayoutUpdateListener = projection.addEventListener("didUpdate", (({ delta, hasLayoutChanged }) => {
1507
+ if (this.isDragging && hasLayoutChanged) {
1508
+ eachAxis((axis) => {
1509
+ const motionValue = this.getAxisMotionValue(axis);
1510
+ if (!motionValue)
1511
+ return;
1512
+ this.originPoint[axis] += delta[axis].translate;
1513
+ motionValue.set(motionValue.get() + delta[axis].translate);
1514
+ });
1515
+ this.visualElement.render();
1516
+ }
1517
+ }));
1518
+ return () => {
1519
+ stopResizeListener();
1520
+ stopPointerListener();
1521
+ stopMeasureLayoutListener();
1522
+ stopLayoutUpdateListener && stopLayoutUpdateListener();
1523
+ };
1524
+ }
1525
+ getProps() {
1526
+ const props = this.visualElement.getProps();
1527
+ const { drag: drag2 = false, dragDirectionLock = false, dragPropagation = false, dragConstraints = false, dragElastic = defaultElastic, dragMomentum = true } = props;
1528
+ return {
1529
+ ...props,
1530
+ drag: drag2,
1531
+ dragDirectionLock,
1532
+ dragPropagation,
1533
+ dragConstraints,
1534
+ dragElastic,
1535
+ dragMomentum
1536
+ };
1537
+ }
1538
+ }
1539
+ function shouldDrag(direction, drag2, currentDirection) {
1540
+ return (drag2 === true || drag2 === direction) && (currentDirection === null || currentDirection === direction);
1541
+ }
1542
+ function getCurrentDirection(offset, lockThreshold = 10) {
1543
+ let direction = null;
1544
+ if (Math.abs(offset.y) > lockThreshold) {
1545
+ direction = "y";
1546
+ } else if (Math.abs(offset.x) > lockThreshold) {
1547
+ direction = "x";
1548
+ }
1549
+ return direction;
1550
+ }
1551
+ class DragGesture extends Feature {
1552
+ constructor(node) {
1553
+ super(node);
1554
+ this.removeGroupControls = noop;
1555
+ this.removeListeners = noop;
1556
+ this.controls = new VisualElementDragControls(node);
1557
+ }
1558
+ mount() {
1559
+ const { dragControls } = this.node.getProps();
1560
+ if (dragControls) {
1561
+ this.removeGroupControls = dragControls.subscribe(this.controls);
1562
+ }
1563
+ this.removeListeners = this.controls.addListeners() || noop;
1564
+ }
1565
+ unmount() {
1566
+ this.removeGroupControls();
1567
+ this.removeListeners();
1568
+ }
1569
+ }
1570
+ const asyncHandler = (handler) => (event, info) => {
1571
+ if (handler) {
1572
+ frame.postRender(() => handler(event, info));
1573
+ }
1574
+ };
1575
+ class PanGesture extends Feature {
1576
+ constructor() {
1577
+ super(...arguments);
1578
+ this.removePointerDownListener = noop;
1579
+ }
1580
+ onPointerDown(pointerDownEvent) {
1581
+ this.session = new PanSession(pointerDownEvent, this.createPanHandlers(), {
1582
+ transformPagePoint: this.node.getTransformPagePoint(),
1583
+ contextWindow: getContextWindow(this.node)
1584
+ });
1585
+ }
1586
+ createPanHandlers() {
1587
+ const { onPanSessionStart, onPanStart, onPan, onPanEnd } = this.node.getProps();
1588
+ return {
1589
+ onSessionStart: asyncHandler(onPanSessionStart),
1590
+ onStart: asyncHandler(onPanStart),
1591
+ onMove: onPan,
1592
+ onEnd: (event, info) => {
1593
+ delete this.session;
1594
+ if (onPanEnd) {
1595
+ frame.postRender(() => onPanEnd(event, info));
1596
+ }
1597
+ }
1598
+ };
1599
+ }
1600
+ mount() {
1601
+ this.removePointerDownListener = addPointerEvent(this.node.current, "pointerdown", (event) => this.onPointerDown(event));
1602
+ }
1603
+ update() {
1604
+ this.session && this.session.updateHandlers(this.createPanHandlers());
1605
+ }
1606
+ unmount() {
1607
+ this.removePointerDownListener();
1608
+ this.session && this.session.end();
1609
+ }
1610
+ }
1611
+ const globalProjectionState = {
1612
+ /**
1613
+ * Global flag as to whether the tree has animated since the last time
1614
+ * we resized the window
1615
+ */
1616
+ hasAnimatedSinceResize: true,
1617
+ /**
1618
+ * We set this to true once, on the first update. Any nodes added to the tree beyond that
1619
+ * update will be given a `data-projection-id` attribute.
1620
+ */
1621
+ hasEverUpdated: false
1622
+ };
1623
+ function pixelsToPercent(pixels, axis) {
1624
+ if (axis.max === axis.min)
1625
+ return 0;
1626
+ return pixels / (axis.max - axis.min) * 100;
1627
+ }
1628
+ const correctBorderRadius = {
1629
+ correct: (latest, node) => {
1630
+ if (!node.target)
1631
+ return latest;
1632
+ if (typeof latest === "string") {
1633
+ if (px.test(latest)) {
1634
+ latest = parseFloat(latest);
1635
+ } else {
1636
+ return latest;
1637
+ }
1638
+ }
1639
+ const x = pixelsToPercent(latest, node.target.x);
1640
+ const y = pixelsToPercent(latest, node.target.y);
1641
+ return `${x}% ${y}%`;
1642
+ }
1643
+ };
1644
+ const correctBoxShadow = {
1645
+ correct: (latest, { treeScale, projectionDelta }) => {
1646
+ const original = latest;
1647
+ const shadow = complex.parse(latest);
1648
+ if (shadow.length > 5)
1649
+ return original;
1650
+ const template = complex.createTransformer(latest);
1651
+ const offset = typeof shadow[0] !== "number" ? 1 : 0;
1652
+ const xScale = projectionDelta.x.scale * treeScale.x;
1653
+ const yScale = projectionDelta.y.scale * treeScale.y;
1654
+ shadow[0 + offset] /= xScale;
1655
+ shadow[1 + offset] /= yScale;
1656
+ const averageScale = mixNumber(xScale, yScale, 0.5);
1657
+ if (typeof shadow[2 + offset] === "number")
1658
+ shadow[2 + offset] /= averageScale;
1659
+ if (typeof shadow[3 + offset] === "number")
1660
+ shadow[3 + offset] /= averageScale;
1661
+ return template(shadow);
1662
+ }
1663
+ };
1664
+ class MeasureLayoutWithContext extends Component {
1665
+ /**
1666
+ * This only mounts projection nodes for components that
1667
+ * need measuring, we might want to do it for all components
1668
+ * in order to incorporate transforms
1669
+ */
1670
+ componentDidMount() {
1671
+ const { visualElement, layoutGroup, switchLayoutGroup, layoutId } = this.props;
1672
+ const { projection } = visualElement;
1673
+ addScaleCorrector(defaultScaleCorrectors);
1674
+ if (projection) {
1675
+ if (layoutGroup.group)
1676
+ layoutGroup.group.add(projection);
1677
+ if (switchLayoutGroup && switchLayoutGroup.register && layoutId) {
1678
+ switchLayoutGroup.register(projection);
1679
+ }
1680
+ projection.root.didUpdate();
1681
+ projection.addEventListener("animationComplete", () => {
1682
+ this.safeToRemove();
1683
+ });
1684
+ projection.setOptions({
1685
+ ...projection.options,
1686
+ onExitComplete: () => this.safeToRemove()
1687
+ });
1688
+ }
1689
+ globalProjectionState.hasEverUpdated = true;
1690
+ }
1691
+ getSnapshotBeforeUpdate(prevProps) {
1692
+ const { layoutDependency, visualElement, drag: drag2, isPresent } = this.props;
1693
+ const projection = visualElement.projection;
1694
+ if (!projection)
1695
+ return null;
1696
+ projection.isPresent = isPresent;
1697
+ if (drag2 || prevProps.layoutDependency !== layoutDependency || layoutDependency === void 0) {
1698
+ projection.willUpdate();
1699
+ } else {
1700
+ this.safeToRemove();
1701
+ }
1702
+ if (prevProps.isPresent !== isPresent) {
1703
+ if (isPresent) {
1704
+ projection.promote();
1705
+ } else if (!projection.relegate()) {
1706
+ frame.postRender(() => {
1707
+ const stack = projection.getStack();
1708
+ if (!stack || !stack.members.length) {
1709
+ this.safeToRemove();
1710
+ }
1711
+ });
1712
+ }
1713
+ }
1714
+ return null;
1715
+ }
1716
+ componentDidUpdate() {
1717
+ const { projection } = this.props.visualElement;
1718
+ if (projection) {
1719
+ projection.root.didUpdate();
1720
+ microtask.postRender(() => {
1721
+ if (!projection.currentAnimation && projection.isLead()) {
1722
+ this.safeToRemove();
1723
+ }
1724
+ });
1725
+ }
1726
+ }
1727
+ componentWillUnmount() {
1728
+ const { visualElement, layoutGroup, switchLayoutGroup: promoteContext } = this.props;
1729
+ const { projection } = visualElement;
1730
+ if (projection) {
1731
+ projection.scheduleCheckAfterUnmount();
1732
+ if (layoutGroup && layoutGroup.group)
1733
+ layoutGroup.group.remove(projection);
1734
+ if (promoteContext && promoteContext.deregister)
1735
+ promoteContext.deregister(projection);
1736
+ }
1737
+ }
1738
+ safeToRemove() {
1739
+ const { safeToRemove } = this.props;
1740
+ safeToRemove && safeToRemove();
1741
+ }
1742
+ render() {
1743
+ return null;
1744
+ }
1745
+ }
1746
+ function MeasureLayout(props) {
1747
+ const [isPresent, safeToRemove] = usePresence();
1748
+ const layoutGroup = useContext(LayoutGroupContext);
1749
+ return jsx(MeasureLayoutWithContext, { ...props, layoutGroup, switchLayoutGroup: useContext(SwitchLayoutGroupContext), isPresent, safeToRemove });
1750
+ }
1751
+ const defaultScaleCorrectors = {
1752
+ borderRadius: {
1753
+ ...correctBorderRadius,
1754
+ applyTo: [
1755
+ "borderTopLeftRadius",
1756
+ "borderTopRightRadius",
1757
+ "borderBottomLeftRadius",
1758
+ "borderBottomRightRadius"
1759
+ ]
1760
+ },
1761
+ borderTopLeftRadius: correctBorderRadius,
1762
+ borderTopRightRadius: correctBorderRadius,
1763
+ borderBottomLeftRadius: correctBorderRadius,
1764
+ borderBottomRightRadius: correctBorderRadius,
1765
+ boxShadow: correctBoxShadow
1766
+ };
1767
+ const compareByDepth = (a, b) => a.depth - b.depth;
1768
+ class FlatTree {
1769
+ constructor() {
1770
+ this.children = [];
1771
+ this.isDirty = false;
1772
+ }
1773
+ add(child) {
1774
+ addUniqueItem(this.children, child);
1775
+ this.isDirty = true;
1776
+ }
1777
+ remove(child) {
1778
+ removeItem(this.children, child);
1779
+ this.isDirty = true;
1780
+ }
1781
+ forEach(callback) {
1782
+ this.isDirty && this.children.sort(compareByDepth);
1783
+ this.isDirty = false;
1784
+ this.children.forEach(callback);
1785
+ }
1786
+ }
1787
+ function delay(callback, timeout) {
1788
+ const start = time.now();
1789
+ const checkElapsed = ({ timestamp }) => {
1790
+ const elapsed = timestamp - start;
1791
+ if (elapsed >= timeout) {
1792
+ cancelFrame(checkElapsed);
1793
+ callback(elapsed - timeout);
1794
+ }
1795
+ };
1796
+ frame.read(checkElapsed, true);
1797
+ return () => cancelFrame(checkElapsed);
1798
+ }
1799
+ const borders = ["TopLeft", "TopRight", "BottomLeft", "BottomRight"];
1800
+ const numBorders = borders.length;
1801
+ const asNumber = (value) => typeof value === "string" ? parseFloat(value) : value;
1802
+ const isPx = (value) => typeof value === "number" || px.test(value);
1803
+ function mixValues(target, follow, lead, progress2, shouldCrossfadeOpacity, isOnlyMember) {
1804
+ if (shouldCrossfadeOpacity) {
1805
+ target.opacity = mixNumber(
1806
+ 0,
1807
+ // TODO Reinstate this if only child
1808
+ lead.opacity !== void 0 ? lead.opacity : 1,
1809
+ easeCrossfadeIn(progress2)
1810
+ );
1811
+ target.opacityExit = mixNumber(follow.opacity !== void 0 ? follow.opacity : 1, 0, easeCrossfadeOut(progress2));
1812
+ } else if (isOnlyMember) {
1813
+ target.opacity = mixNumber(follow.opacity !== void 0 ? follow.opacity : 1, lead.opacity !== void 0 ? lead.opacity : 1, progress2);
1814
+ }
1815
+ for (let i = 0; i < numBorders; i++) {
1816
+ const borderLabel = `border${borders[i]}Radius`;
1817
+ let followRadius = getRadius(follow, borderLabel);
1818
+ let leadRadius = getRadius(lead, borderLabel);
1819
+ if (followRadius === void 0 && leadRadius === void 0)
1820
+ continue;
1821
+ followRadius || (followRadius = 0);
1822
+ leadRadius || (leadRadius = 0);
1823
+ const canMix = followRadius === 0 || leadRadius === 0 || isPx(followRadius) === isPx(leadRadius);
1824
+ if (canMix) {
1825
+ target[borderLabel] = Math.max(mixNumber(asNumber(followRadius), asNumber(leadRadius), progress2), 0);
1826
+ if (percent.test(leadRadius) || percent.test(followRadius)) {
1827
+ target[borderLabel] += "%";
1828
+ }
1829
+ } else {
1830
+ target[borderLabel] = leadRadius;
1831
+ }
1832
+ }
1833
+ if (follow.rotate || lead.rotate) {
1834
+ target.rotate = mixNumber(follow.rotate || 0, lead.rotate || 0, progress2);
1835
+ }
1836
+ }
1837
+ function getRadius(values, radiusName) {
1838
+ return values[radiusName] !== void 0 ? values[radiusName] : values.borderRadius;
1839
+ }
1840
+ const easeCrossfadeIn = /* @__PURE__ */ compress(0, 0.5, circOut);
1841
+ const easeCrossfadeOut = /* @__PURE__ */ compress(0.5, 0.95, noop);
1842
+ function compress(min, max, easing) {
1843
+ return (p) => {
1844
+ if (p < min)
1845
+ return 0;
1846
+ if (p > max)
1847
+ return 1;
1848
+ return easing(progress(min, max, p));
1849
+ };
1850
+ }
1851
+ function copyAxisInto(axis, originAxis) {
1852
+ axis.min = originAxis.min;
1853
+ axis.max = originAxis.max;
1854
+ }
1855
+ function copyBoxInto(box, originBox) {
1856
+ copyAxisInto(box.x, originBox.x);
1857
+ copyAxisInto(box.y, originBox.y);
1858
+ }
1859
+ function copyAxisDeltaInto(delta, originDelta) {
1860
+ delta.translate = originDelta.translate;
1861
+ delta.scale = originDelta.scale;
1862
+ delta.originPoint = originDelta.originPoint;
1863
+ delta.origin = originDelta.origin;
1864
+ }
1865
+ function removePointDelta(point, translate, scale, originPoint, boxScale) {
1866
+ point -= translate;
1867
+ point = scalePoint(point, 1 / scale, originPoint);
1868
+ if (boxScale !== void 0) {
1869
+ point = scalePoint(point, 1 / boxScale, originPoint);
1870
+ }
1871
+ return point;
1872
+ }
1873
+ function removeAxisDelta(axis, translate = 0, scale = 1, origin = 0.5, boxScale, originAxis = axis, sourceAxis = axis) {
1874
+ if (percent.test(translate)) {
1875
+ translate = parseFloat(translate);
1876
+ const relativeProgress = mixNumber(sourceAxis.min, sourceAxis.max, translate / 100);
1877
+ translate = relativeProgress - sourceAxis.min;
1878
+ }
1879
+ if (typeof translate !== "number")
1880
+ return;
1881
+ let originPoint = mixNumber(originAxis.min, originAxis.max, origin);
1882
+ if (axis === originAxis)
1883
+ originPoint -= translate;
1884
+ axis.min = removePointDelta(axis.min, translate, scale, originPoint, boxScale);
1885
+ axis.max = removePointDelta(axis.max, translate, scale, originPoint, boxScale);
1886
+ }
1887
+ function removeAxisTransforms(axis, transforms, [key, scaleKey, originKey], origin, sourceAxis) {
1888
+ removeAxisDelta(axis, transforms[key], transforms[scaleKey], transforms[originKey], transforms.scale, origin, sourceAxis);
1889
+ }
1890
+ const xKeys = ["x", "scaleX", "originX"];
1891
+ const yKeys = ["y", "scaleY", "originY"];
1892
+ function removeBoxTransforms(box, transforms, originBox, sourceBox) {
1893
+ removeAxisTransforms(box.x, transforms, xKeys, originBox ? originBox.x : void 0, sourceBox ? sourceBox.x : void 0);
1894
+ removeAxisTransforms(box.y, transforms, yKeys, originBox ? originBox.y : void 0, sourceBox ? sourceBox.y : void 0);
1895
+ }
1896
+ function isAxisDeltaZero(delta) {
1897
+ return delta.translate === 0 && delta.scale === 1;
1898
+ }
1899
+ function isDeltaZero(delta) {
1900
+ return isAxisDeltaZero(delta.x) && isAxisDeltaZero(delta.y);
1901
+ }
1902
+ function axisEquals(a, b) {
1903
+ return a.min === b.min && a.max === b.max;
1904
+ }
1905
+ function boxEquals(a, b) {
1906
+ return axisEquals(a.x, b.x) && axisEquals(a.y, b.y);
1907
+ }
1908
+ function axisEqualsRounded(a, b) {
1909
+ return Math.round(a.min) === Math.round(b.min) && Math.round(a.max) === Math.round(b.max);
1910
+ }
1911
+ function boxEqualsRounded(a, b) {
1912
+ return axisEqualsRounded(a.x, b.x) && axisEqualsRounded(a.y, b.y);
1913
+ }
1914
+ function aspectRatio(box) {
1915
+ return calcLength(box.x) / calcLength(box.y);
1916
+ }
1917
+ function axisDeltaEquals(a, b) {
1918
+ return a.translate === b.translate && a.scale === b.scale && a.originPoint === b.originPoint;
1919
+ }
1920
+ class NodeStack {
1921
+ constructor() {
1922
+ this.members = [];
1923
+ }
1924
+ add(node) {
1925
+ addUniqueItem(this.members, node);
1926
+ node.scheduleRender();
1927
+ }
1928
+ remove(node) {
1929
+ removeItem(this.members, node);
1930
+ if (node === this.prevLead) {
1931
+ this.prevLead = void 0;
1932
+ }
1933
+ if (node === this.lead) {
1934
+ const prevLead = this.members[this.members.length - 1];
1935
+ if (prevLead) {
1936
+ this.promote(prevLead);
1937
+ }
1938
+ }
1939
+ }
1940
+ relegate(node) {
1941
+ const indexOfNode = this.members.findIndex((member) => node === member);
1942
+ if (indexOfNode === 0)
1943
+ return false;
1944
+ let prevLead;
1945
+ for (let i = indexOfNode; i >= 0; i--) {
1946
+ const member = this.members[i];
1947
+ if (member.isPresent !== false) {
1948
+ prevLead = member;
1949
+ break;
1950
+ }
1951
+ }
1952
+ if (prevLead) {
1953
+ this.promote(prevLead);
1954
+ return true;
1955
+ } else {
1956
+ return false;
1957
+ }
1958
+ }
1959
+ promote(node, preserveFollowOpacity) {
1960
+ const prevLead = this.lead;
1961
+ if (node === prevLead)
1962
+ return;
1963
+ this.prevLead = prevLead;
1964
+ this.lead = node;
1965
+ node.show();
1966
+ if (prevLead) {
1967
+ prevLead.instance && prevLead.scheduleRender();
1968
+ node.scheduleRender();
1969
+ node.resumeFrom = prevLead;
1970
+ if (preserveFollowOpacity) {
1971
+ node.resumeFrom.preserveOpacity = true;
1972
+ }
1973
+ if (prevLead.snapshot) {
1974
+ node.snapshot = prevLead.snapshot;
1975
+ node.snapshot.latestValues = prevLead.animationValues || prevLead.latestValues;
1976
+ }
1977
+ if (node.root && node.root.isUpdating) {
1978
+ node.isLayoutDirty = true;
1979
+ }
1980
+ const { crossfade } = node.options;
1981
+ if (crossfade === false) {
1982
+ prevLead.hide();
1983
+ }
1984
+ }
1985
+ }
1986
+ exitAnimationComplete() {
1987
+ this.members.forEach((node) => {
1988
+ const { options, resumingFrom } = node;
1989
+ options.onExitComplete && options.onExitComplete();
1990
+ if (resumingFrom) {
1991
+ resumingFrom.options.onExitComplete && resumingFrom.options.onExitComplete();
1992
+ }
1993
+ });
1994
+ }
1995
+ scheduleRender() {
1996
+ this.members.forEach((node) => {
1997
+ node.instance && node.scheduleRender(false);
1998
+ });
1999
+ }
2000
+ /**
2001
+ * Clear any leads that have been removed this render to prevent them from being
2002
+ * used in future animations and to prevent memory leaks
2003
+ */
2004
+ removeLeadSnapshot() {
2005
+ if (this.lead && this.lead.snapshot) {
2006
+ this.lead.snapshot = void 0;
2007
+ }
2008
+ }
2009
+ }
2010
+ function buildProjectionTransform(delta, treeScale, latestTransform) {
2011
+ let transform = "";
2012
+ const xTranslate = delta.x.translate / treeScale.x;
2013
+ const yTranslate = delta.y.translate / treeScale.y;
2014
+ const zTranslate = (latestTransform === null || latestTransform === void 0 ? void 0 : latestTransform.z) || 0;
2015
+ if (xTranslate || yTranslate || zTranslate) {
2016
+ transform = `translate3d(${xTranslate}px, ${yTranslate}px, ${zTranslate}px) `;
2017
+ }
2018
+ if (treeScale.x !== 1 || treeScale.y !== 1) {
2019
+ transform += `scale(${1 / treeScale.x}, ${1 / treeScale.y}) `;
2020
+ }
2021
+ if (latestTransform) {
2022
+ const { transformPerspective, rotate, rotateX, rotateY, skewX, skewY } = latestTransform;
2023
+ if (transformPerspective)
2024
+ transform = `perspective(${transformPerspective}px) ${transform}`;
2025
+ if (rotate)
2026
+ transform += `rotate(${rotate}deg) `;
2027
+ if (rotateX)
2028
+ transform += `rotateX(${rotateX}deg) `;
2029
+ if (rotateY)
2030
+ transform += `rotateY(${rotateY}deg) `;
2031
+ if (skewX)
2032
+ transform += `skewX(${skewX}deg) `;
2033
+ if (skewY)
2034
+ transform += `skewY(${skewY}deg) `;
2035
+ }
2036
+ const elementScaleX = delta.x.scale * treeScale.x;
2037
+ const elementScaleY = delta.y.scale * treeScale.y;
2038
+ if (elementScaleX !== 1 || elementScaleY !== 1) {
2039
+ transform += `scale(${elementScaleX}, ${elementScaleY})`;
2040
+ }
2041
+ return transform || "none";
2042
+ }
2043
+ const metrics = {
2044
+ type: "projectionFrame",
2045
+ totalNodes: 0,
2046
+ resolvedTargetDeltas: 0,
2047
+ recalculatedProjection: 0
2048
+ };
2049
+ const isDebug = typeof window !== "undefined" && window.MotionDebug !== void 0;
2050
+ const transformAxes = ["", "X", "Y", "Z"];
2051
+ const hiddenVisibility = { visibility: "hidden" };
2052
+ const animationTarget = 1e3;
2053
+ let id = 0;
2054
+ function resetDistortingTransform(key, visualElement, values, sharedAnimationValues) {
2055
+ const { latestValues } = visualElement;
2056
+ if (latestValues[key]) {
2057
+ values[key] = latestValues[key];
2058
+ visualElement.setStaticValue(key, 0);
2059
+ if (sharedAnimationValues) {
2060
+ sharedAnimationValues[key] = 0;
2061
+ }
2062
+ }
2063
+ }
2064
+ function cancelTreeOptimisedTransformAnimations(projectionNode) {
2065
+ projectionNode.hasCheckedOptimisedAppear = true;
2066
+ if (projectionNode.root === projectionNode)
2067
+ return;
2068
+ const { visualElement } = projectionNode.options;
2069
+ if (!visualElement)
2070
+ return;
2071
+ const appearId = getOptimisedAppearId(visualElement);
2072
+ if (window.MotionHasOptimisedAnimation(appearId, "transform")) {
2073
+ const { layout: layout2, layoutId } = projectionNode.options;
2074
+ window.MotionCancelOptimisedAnimation(appearId, "transform", frame, !(layout2 || layoutId));
2075
+ }
2076
+ const { parent } = projectionNode;
2077
+ if (parent && !parent.hasCheckedOptimisedAppear) {
2078
+ cancelTreeOptimisedTransformAnimations(parent);
2079
+ }
2080
+ }
2081
+ function createProjectionNode({ attachResizeListener, defaultParent, measureScroll, checkIsScrollRoot, resetTransform }) {
2082
+ return class ProjectionNode {
2083
+ constructor(latestValues = {}, parent = defaultParent === null || defaultParent === void 0 ? void 0 : defaultParent()) {
2084
+ this.id = id++;
2085
+ this.animationId = 0;
2086
+ this.children = /* @__PURE__ */ new Set();
2087
+ this.options = {};
2088
+ this.isTreeAnimating = false;
2089
+ this.isAnimationBlocked = false;
2090
+ this.isLayoutDirty = false;
2091
+ this.isProjectionDirty = false;
2092
+ this.isSharedProjectionDirty = false;
2093
+ this.isTransformDirty = false;
2094
+ this.updateManuallyBlocked = false;
2095
+ this.updateBlockedByResize = false;
2096
+ this.isUpdating = false;
2097
+ this.isSVG = false;
2098
+ this.needsReset = false;
2099
+ this.shouldResetTransform = false;
2100
+ this.hasCheckedOptimisedAppear = false;
2101
+ this.treeScale = { x: 1, y: 1 };
2102
+ this.eventHandlers = /* @__PURE__ */ new Map();
2103
+ this.hasTreeAnimated = false;
2104
+ this.updateScheduled = false;
2105
+ this.scheduleUpdate = () => this.update();
2106
+ this.projectionUpdateScheduled = false;
2107
+ this.checkUpdateFailed = () => {
2108
+ if (this.isUpdating) {
2109
+ this.isUpdating = false;
2110
+ this.clearAllSnapshots();
2111
+ }
2112
+ };
2113
+ this.updateProjection = () => {
2114
+ this.projectionUpdateScheduled = false;
2115
+ if (isDebug) {
2116
+ metrics.totalNodes = metrics.resolvedTargetDeltas = metrics.recalculatedProjection = 0;
2117
+ }
2118
+ this.nodes.forEach(propagateDirtyNodes);
2119
+ this.nodes.forEach(resolveTargetDelta);
2120
+ this.nodes.forEach(calcProjection);
2121
+ this.nodes.forEach(cleanDirtyNodes);
2122
+ if (isDebug) {
2123
+ window.MotionDebug.record(metrics);
2124
+ }
2125
+ };
2126
+ this.resolvedRelativeTargetAt = 0;
2127
+ this.hasProjected = false;
2128
+ this.isVisible = true;
2129
+ this.animationProgress = 0;
2130
+ this.sharedNodes = /* @__PURE__ */ new Map();
2131
+ this.latestValues = latestValues;
2132
+ this.root = parent ? parent.root || parent : this;
2133
+ this.path = parent ? [...parent.path, parent] : [];
2134
+ this.parent = parent;
2135
+ this.depth = parent ? parent.depth + 1 : 0;
2136
+ for (let i = 0; i < this.path.length; i++) {
2137
+ this.path[i].shouldResetTransform = true;
2138
+ }
2139
+ if (this.root === this)
2140
+ this.nodes = new FlatTree();
2141
+ }
2142
+ addEventListener(name, handler) {
2143
+ if (!this.eventHandlers.has(name)) {
2144
+ this.eventHandlers.set(name, new SubscriptionManager());
2145
+ }
2146
+ return this.eventHandlers.get(name).add(handler);
2147
+ }
2148
+ notifyListeners(name, ...args) {
2149
+ const subscriptionManager = this.eventHandlers.get(name);
2150
+ subscriptionManager && subscriptionManager.notify(...args);
2151
+ }
2152
+ hasListeners(name) {
2153
+ return this.eventHandlers.has(name);
2154
+ }
2155
+ /**
2156
+ * Lifecycles
2157
+ */
2158
+ mount(instance, isLayoutDirty = this.root.hasTreeAnimated) {
2159
+ if (this.instance)
2160
+ return;
2161
+ this.isSVG = isSVGElement(instance);
2162
+ this.instance = instance;
2163
+ const { layoutId, layout: layout2, visualElement } = this.options;
2164
+ if (visualElement && !visualElement.current) {
2165
+ visualElement.mount(instance);
2166
+ }
2167
+ this.root.nodes.add(this);
2168
+ this.parent && this.parent.children.add(this);
2169
+ if (isLayoutDirty && (layout2 || layoutId)) {
2170
+ this.isLayoutDirty = true;
2171
+ }
2172
+ if (attachResizeListener) {
2173
+ let cancelDelay;
2174
+ const resizeUnblockUpdate = () => this.root.updateBlockedByResize = false;
2175
+ attachResizeListener(instance, () => {
2176
+ this.root.updateBlockedByResize = true;
2177
+ cancelDelay && cancelDelay();
2178
+ cancelDelay = delay(resizeUnblockUpdate, 250);
2179
+ if (globalProjectionState.hasAnimatedSinceResize) {
2180
+ globalProjectionState.hasAnimatedSinceResize = false;
2181
+ this.nodes.forEach(finishAnimation);
2182
+ }
2183
+ });
2184
+ }
2185
+ if (layoutId) {
2186
+ this.root.registerSharedNode(layoutId, this);
2187
+ }
2188
+ if (this.options.animate !== false && visualElement && (layoutId || layout2)) {
2189
+ this.addEventListener("didUpdate", ({ delta, hasLayoutChanged, hasRelativeTargetChanged, layout: newLayout }) => {
2190
+ if (this.isTreeAnimationBlocked()) {
2191
+ this.target = void 0;
2192
+ this.relativeTarget = void 0;
2193
+ return;
2194
+ }
2195
+ const layoutTransition = this.options.transition || visualElement.getDefaultTransition() || defaultLayoutTransition;
2196
+ const { onLayoutAnimationStart, onLayoutAnimationComplete } = visualElement.getProps();
2197
+ const targetChanged = !this.targetLayout || !boxEqualsRounded(this.targetLayout, newLayout) || hasRelativeTargetChanged;
2198
+ const hasOnlyRelativeTargetChanged = !hasLayoutChanged && hasRelativeTargetChanged;
2199
+ if (this.options.layoutRoot || this.resumeFrom && this.resumeFrom.instance || hasOnlyRelativeTargetChanged || hasLayoutChanged && (targetChanged || !this.currentAnimation)) {
2200
+ if (this.resumeFrom) {
2201
+ this.resumingFrom = this.resumeFrom;
2202
+ this.resumingFrom.resumingFrom = void 0;
2203
+ }
2204
+ this.setAnimationOrigin(delta, hasOnlyRelativeTargetChanged);
2205
+ const animationOptions = {
2206
+ ...getValueTransition(layoutTransition, "layout"),
2207
+ onPlay: onLayoutAnimationStart,
2208
+ onComplete: onLayoutAnimationComplete
2209
+ };
2210
+ if (visualElement.shouldReduceMotion || this.options.layoutRoot) {
2211
+ animationOptions.delay = 0;
2212
+ animationOptions.type = false;
2213
+ }
2214
+ this.startAnimation(animationOptions);
2215
+ } else {
2216
+ if (!hasLayoutChanged) {
2217
+ finishAnimation(this);
2218
+ }
2219
+ if (this.isLead() && this.options.onExitComplete) {
2220
+ this.options.onExitComplete();
2221
+ }
2222
+ }
2223
+ this.targetLayout = newLayout;
2224
+ });
2225
+ }
2226
+ }
2227
+ unmount() {
2228
+ this.options.layoutId && this.willUpdate();
2229
+ this.root.nodes.remove(this);
2230
+ const stack = this.getStack();
2231
+ stack && stack.remove(this);
2232
+ this.parent && this.parent.children.delete(this);
2233
+ this.instance = void 0;
2234
+ cancelFrame(this.updateProjection);
2235
+ }
2236
+ // only on the root
2237
+ blockUpdate() {
2238
+ this.updateManuallyBlocked = true;
2239
+ }
2240
+ unblockUpdate() {
2241
+ this.updateManuallyBlocked = false;
2242
+ }
2243
+ isUpdateBlocked() {
2244
+ return this.updateManuallyBlocked || this.updateBlockedByResize;
2245
+ }
2246
+ isTreeAnimationBlocked() {
2247
+ return this.isAnimationBlocked || this.parent && this.parent.isTreeAnimationBlocked() || false;
2248
+ }
2249
+ // Note: currently only running on root node
2250
+ startUpdate() {
2251
+ if (this.isUpdateBlocked())
2252
+ return;
2253
+ this.isUpdating = true;
2254
+ this.nodes && this.nodes.forEach(resetSkewAndRotation);
2255
+ this.animationId++;
2256
+ }
2257
+ getTransformTemplate() {
2258
+ const { visualElement } = this.options;
2259
+ return visualElement && visualElement.getProps().transformTemplate;
2260
+ }
2261
+ willUpdate(shouldNotifyListeners = true) {
2262
+ this.root.hasTreeAnimated = true;
2263
+ if (this.root.isUpdateBlocked()) {
2264
+ this.options.onExitComplete && this.options.onExitComplete();
2265
+ return;
2266
+ }
2267
+ if (window.MotionCancelOptimisedAnimation && !this.hasCheckedOptimisedAppear) {
2268
+ cancelTreeOptimisedTransformAnimations(this);
2269
+ }
2270
+ !this.root.isUpdating && this.root.startUpdate();
2271
+ if (this.isLayoutDirty)
2272
+ return;
2273
+ this.isLayoutDirty = true;
2274
+ for (let i = 0; i < this.path.length; i++) {
2275
+ const node = this.path[i];
2276
+ node.shouldResetTransform = true;
2277
+ node.updateScroll("snapshot");
2278
+ if (node.options.layoutRoot) {
2279
+ node.willUpdate(false);
2280
+ }
2281
+ }
2282
+ const { layoutId, layout: layout2 } = this.options;
2283
+ if (layoutId === void 0 && !layout2)
2284
+ return;
2285
+ const transformTemplate = this.getTransformTemplate();
2286
+ this.prevTransformTemplateValue = transformTemplate ? transformTemplate(this.latestValues, "") : void 0;
2287
+ this.updateSnapshot();
2288
+ shouldNotifyListeners && this.notifyListeners("willUpdate");
2289
+ }
2290
+ update() {
2291
+ this.updateScheduled = false;
2292
+ const updateWasBlocked = this.isUpdateBlocked();
2293
+ if (updateWasBlocked) {
2294
+ this.unblockUpdate();
2295
+ this.clearAllSnapshots();
2296
+ this.nodes.forEach(clearMeasurements);
2297
+ return;
2298
+ }
2299
+ if (!this.isUpdating) {
2300
+ this.nodes.forEach(clearIsLayoutDirty);
2301
+ }
2302
+ this.isUpdating = false;
2303
+ this.nodes.forEach(resetTransformStyle);
2304
+ this.nodes.forEach(updateLayout);
2305
+ this.nodes.forEach(notifyLayoutUpdate);
2306
+ this.clearAllSnapshots();
2307
+ const now = time.now();
2308
+ frameData.delta = clamp(0, 1e3 / 60, now - frameData.timestamp);
2309
+ frameData.timestamp = now;
2310
+ frameData.isProcessing = true;
2311
+ frameSteps.update.process(frameData);
2312
+ frameSteps.preRender.process(frameData);
2313
+ frameSteps.render.process(frameData);
2314
+ frameData.isProcessing = false;
2315
+ }
2316
+ didUpdate() {
2317
+ if (!this.updateScheduled) {
2318
+ this.updateScheduled = true;
2319
+ microtask.read(this.scheduleUpdate);
2320
+ }
2321
+ }
2322
+ clearAllSnapshots() {
2323
+ this.nodes.forEach(clearSnapshot);
2324
+ this.sharedNodes.forEach(removeLeadSnapshots);
2325
+ }
2326
+ scheduleUpdateProjection() {
2327
+ if (!this.projectionUpdateScheduled) {
2328
+ this.projectionUpdateScheduled = true;
2329
+ frame.preRender(this.updateProjection, false, true);
2330
+ }
2331
+ }
2332
+ scheduleCheckAfterUnmount() {
2333
+ frame.postRender(() => {
2334
+ if (this.isLayoutDirty) {
2335
+ this.root.didUpdate();
2336
+ } else {
2337
+ this.root.checkUpdateFailed();
2338
+ }
2339
+ });
2340
+ }
2341
+ /**
2342
+ * Update measurements
2343
+ */
2344
+ updateSnapshot() {
2345
+ if (this.snapshot || !this.instance)
2346
+ return;
2347
+ this.snapshot = this.measure();
2348
+ }
2349
+ updateLayout() {
2350
+ if (!this.instance)
2351
+ return;
2352
+ this.updateScroll();
2353
+ if (!(this.options.alwaysMeasureLayout && this.isLead()) && !this.isLayoutDirty) {
2354
+ return;
2355
+ }
2356
+ if (this.resumeFrom && !this.resumeFrom.instance) {
2357
+ for (let i = 0; i < this.path.length; i++) {
2358
+ const node = this.path[i];
2359
+ node.updateScroll();
2360
+ }
2361
+ }
2362
+ const prevLayout = this.layout;
2363
+ this.layout = this.measure(false);
2364
+ this.layoutCorrected = createBox();
2365
+ this.isLayoutDirty = false;
2366
+ this.projectionDelta = void 0;
2367
+ this.notifyListeners("measure", this.layout.layoutBox);
2368
+ const { visualElement } = this.options;
2369
+ visualElement && visualElement.notify("LayoutMeasure", this.layout.layoutBox, prevLayout ? prevLayout.layoutBox : void 0);
2370
+ }
2371
+ updateScroll(phase = "measure") {
2372
+ let needsMeasurement = Boolean(this.options.layoutScroll && this.instance);
2373
+ if (this.scroll && this.scroll.animationId === this.root.animationId && this.scroll.phase === phase) {
2374
+ needsMeasurement = false;
2375
+ }
2376
+ if (needsMeasurement) {
2377
+ const isRoot = checkIsScrollRoot(this.instance);
2378
+ this.scroll = {
2379
+ animationId: this.root.animationId,
2380
+ phase,
2381
+ isRoot,
2382
+ offset: measureScroll(this.instance),
2383
+ wasRoot: this.scroll ? this.scroll.isRoot : isRoot
2384
+ };
2385
+ }
2386
+ }
2387
+ resetTransform() {
2388
+ if (!resetTransform)
2389
+ return;
2390
+ const isResetRequested = this.isLayoutDirty || this.shouldResetTransform || this.options.alwaysMeasureLayout;
2391
+ const hasProjection = this.projectionDelta && !isDeltaZero(this.projectionDelta);
2392
+ const transformTemplate = this.getTransformTemplate();
2393
+ const transformTemplateValue = transformTemplate ? transformTemplate(this.latestValues, "") : void 0;
2394
+ const transformTemplateHasChanged = transformTemplateValue !== this.prevTransformTemplateValue;
2395
+ if (isResetRequested && (hasProjection || hasTransform(this.latestValues) || transformTemplateHasChanged)) {
2396
+ resetTransform(this.instance, transformTemplateValue);
2397
+ this.shouldResetTransform = false;
2398
+ this.scheduleRender();
2399
+ }
2400
+ }
2401
+ measure(removeTransform = true) {
2402
+ const pageBox = this.measurePageBox();
2403
+ let layoutBox = this.removeElementScroll(pageBox);
2404
+ if (removeTransform) {
2405
+ layoutBox = this.removeTransform(layoutBox);
2406
+ }
2407
+ roundBox(layoutBox);
2408
+ return {
2409
+ animationId: this.root.animationId,
2410
+ measuredBox: pageBox,
2411
+ layoutBox,
2412
+ latestValues: {},
2413
+ source: this.id
2414
+ };
2415
+ }
2416
+ measurePageBox() {
2417
+ var _a;
2418
+ const { visualElement } = this.options;
2419
+ if (!visualElement)
2420
+ return createBox();
2421
+ const box = visualElement.measureViewportBox();
2422
+ const wasInScrollRoot = ((_a = this.scroll) === null || _a === void 0 ? void 0 : _a.wasRoot) || this.path.some(checkNodeWasScrollRoot);
2423
+ if (!wasInScrollRoot) {
2424
+ const { scroll } = this.root;
2425
+ if (scroll) {
2426
+ translateAxis(box.x, scroll.offset.x);
2427
+ translateAxis(box.y, scroll.offset.y);
2428
+ }
2429
+ }
2430
+ return box;
2431
+ }
2432
+ removeElementScroll(box) {
2433
+ var _a;
2434
+ const boxWithoutScroll = createBox();
2435
+ copyBoxInto(boxWithoutScroll, box);
2436
+ if ((_a = this.scroll) === null || _a === void 0 ? void 0 : _a.wasRoot) {
2437
+ return boxWithoutScroll;
2438
+ }
2439
+ for (let i = 0; i < this.path.length; i++) {
2440
+ const node = this.path[i];
2441
+ const { scroll, options } = node;
2442
+ if (node !== this.root && scroll && options.layoutScroll) {
2443
+ if (scroll.wasRoot) {
2444
+ copyBoxInto(boxWithoutScroll, box);
2445
+ }
2446
+ translateAxis(boxWithoutScroll.x, scroll.offset.x);
2447
+ translateAxis(boxWithoutScroll.y, scroll.offset.y);
2448
+ }
2449
+ }
2450
+ return boxWithoutScroll;
2451
+ }
2452
+ applyTransform(box, transformOnly = false) {
2453
+ const withTransforms = createBox();
2454
+ copyBoxInto(withTransforms, box);
2455
+ for (let i = 0; i < this.path.length; i++) {
2456
+ const node = this.path[i];
2457
+ if (!transformOnly && node.options.layoutScroll && node.scroll && node !== node.root) {
2458
+ transformBox(withTransforms, {
2459
+ x: -node.scroll.offset.x,
2460
+ y: -node.scroll.offset.y
2461
+ });
2462
+ }
2463
+ if (!hasTransform(node.latestValues))
2464
+ continue;
2465
+ transformBox(withTransforms, node.latestValues);
2466
+ }
2467
+ if (hasTransform(this.latestValues)) {
2468
+ transformBox(withTransforms, this.latestValues);
2469
+ }
2470
+ return withTransforms;
2471
+ }
2472
+ removeTransform(box) {
2473
+ const boxWithoutTransform = createBox();
2474
+ copyBoxInto(boxWithoutTransform, box);
2475
+ for (let i = 0; i < this.path.length; i++) {
2476
+ const node = this.path[i];
2477
+ if (!node.instance)
2478
+ continue;
2479
+ if (!hasTransform(node.latestValues))
2480
+ continue;
2481
+ hasScale(node.latestValues) && node.updateSnapshot();
2482
+ const sourceBox = createBox();
2483
+ const nodeBox = node.measurePageBox();
2484
+ copyBoxInto(sourceBox, nodeBox);
2485
+ removeBoxTransforms(boxWithoutTransform, node.latestValues, node.snapshot ? node.snapshot.layoutBox : void 0, sourceBox);
2486
+ }
2487
+ if (hasTransform(this.latestValues)) {
2488
+ removeBoxTransforms(boxWithoutTransform, this.latestValues);
2489
+ }
2490
+ return boxWithoutTransform;
2491
+ }
2492
+ setTargetDelta(delta) {
2493
+ this.targetDelta = delta;
2494
+ this.root.scheduleUpdateProjection();
2495
+ this.isProjectionDirty = true;
2496
+ }
2497
+ setOptions(options) {
2498
+ this.options = {
2499
+ ...this.options,
2500
+ ...options,
2501
+ crossfade: options.crossfade !== void 0 ? options.crossfade : true
2502
+ };
2503
+ }
2504
+ clearMeasurements() {
2505
+ this.scroll = void 0;
2506
+ this.layout = void 0;
2507
+ this.snapshot = void 0;
2508
+ this.prevTransformTemplateValue = void 0;
2509
+ this.targetDelta = void 0;
2510
+ this.target = void 0;
2511
+ this.isLayoutDirty = false;
2512
+ }
2513
+ forceRelativeParentToResolveTarget() {
2514
+ if (!this.relativeParent)
2515
+ return;
2516
+ if (this.relativeParent.resolvedRelativeTargetAt !== frameData.timestamp) {
2517
+ this.relativeParent.resolveTargetDelta(true);
2518
+ }
2519
+ }
2520
+ resolveTargetDelta(forceRecalculation = false) {
2521
+ var _a;
2522
+ const lead = this.getLead();
2523
+ this.isProjectionDirty || (this.isProjectionDirty = lead.isProjectionDirty);
2524
+ this.isTransformDirty || (this.isTransformDirty = lead.isTransformDirty);
2525
+ this.isSharedProjectionDirty || (this.isSharedProjectionDirty = lead.isSharedProjectionDirty);
2526
+ const isShared = Boolean(this.resumingFrom) || this !== lead;
2527
+ const canSkip = !(forceRecalculation || isShared && this.isSharedProjectionDirty || this.isProjectionDirty || ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.isProjectionDirty) || this.attemptToResolveRelativeTarget || this.root.updateBlockedByResize);
2528
+ if (canSkip)
2529
+ return;
2530
+ const { layout: layout2, layoutId } = this.options;
2531
+ if (!this.layout || !(layout2 || layoutId))
2532
+ return;
2533
+ this.resolvedRelativeTargetAt = frameData.timestamp;
2534
+ if (!this.targetDelta && !this.relativeTarget) {
2535
+ const relativeParent = this.getClosestProjectingParent();
2536
+ if (relativeParent && relativeParent.layout && this.animationProgress !== 1) {
2537
+ this.relativeParent = relativeParent;
2538
+ this.forceRelativeParentToResolveTarget();
2539
+ this.relativeTarget = createBox();
2540
+ this.relativeTargetOrigin = createBox();
2541
+ calcRelativePosition(this.relativeTargetOrigin, this.layout.layoutBox, relativeParent.layout.layoutBox);
2542
+ copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
2543
+ } else {
2544
+ this.relativeParent = this.relativeTarget = void 0;
2545
+ }
2546
+ }
2547
+ if (!this.relativeTarget && !this.targetDelta)
2548
+ return;
2549
+ if (!this.target) {
2550
+ this.target = createBox();
2551
+ this.targetWithTransforms = createBox();
2552
+ }
2553
+ if (this.relativeTarget && this.relativeTargetOrigin && this.relativeParent && this.relativeParent.target) {
2554
+ this.forceRelativeParentToResolveTarget();
2555
+ calcRelativeBox(this.target, this.relativeTarget, this.relativeParent.target);
2556
+ } else if (this.targetDelta) {
2557
+ if (Boolean(this.resumingFrom)) {
2558
+ this.target = this.applyTransform(this.layout.layoutBox);
2559
+ } else {
2560
+ copyBoxInto(this.target, this.layout.layoutBox);
2561
+ }
2562
+ applyBoxDelta(this.target, this.targetDelta);
2563
+ } else {
2564
+ copyBoxInto(this.target, this.layout.layoutBox);
2565
+ }
2566
+ if (this.attemptToResolveRelativeTarget) {
2567
+ this.attemptToResolveRelativeTarget = false;
2568
+ const relativeParent = this.getClosestProjectingParent();
2569
+ if (relativeParent && Boolean(relativeParent.resumingFrom) === Boolean(this.resumingFrom) && !relativeParent.options.layoutScroll && relativeParent.target && this.animationProgress !== 1) {
2570
+ this.relativeParent = relativeParent;
2571
+ this.forceRelativeParentToResolveTarget();
2572
+ this.relativeTarget = createBox();
2573
+ this.relativeTargetOrigin = createBox();
2574
+ calcRelativePosition(this.relativeTargetOrigin, this.target, relativeParent.target);
2575
+ copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
2576
+ } else {
2577
+ this.relativeParent = this.relativeTarget = void 0;
2578
+ }
2579
+ }
2580
+ if (isDebug) {
2581
+ metrics.resolvedTargetDeltas++;
2582
+ }
2583
+ }
2584
+ getClosestProjectingParent() {
2585
+ if (!this.parent || hasScale(this.parent.latestValues) || has2DTranslate(this.parent.latestValues)) {
2586
+ return void 0;
2587
+ }
2588
+ if (this.parent.isProjecting()) {
2589
+ return this.parent;
2590
+ } else {
2591
+ return this.parent.getClosestProjectingParent();
2592
+ }
2593
+ }
2594
+ isProjecting() {
2595
+ return Boolean((this.relativeTarget || this.targetDelta || this.options.layoutRoot) && this.layout);
2596
+ }
2597
+ calcProjection() {
2598
+ var _a;
2599
+ const lead = this.getLead();
2600
+ const isShared = Boolean(this.resumingFrom) || this !== lead;
2601
+ let canSkip = true;
2602
+ if (this.isProjectionDirty || ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.isProjectionDirty)) {
2603
+ canSkip = false;
2604
+ }
2605
+ if (isShared && (this.isSharedProjectionDirty || this.isTransformDirty)) {
2606
+ canSkip = false;
2607
+ }
2608
+ if (this.resolvedRelativeTargetAt === frameData.timestamp) {
2609
+ canSkip = false;
2610
+ }
2611
+ if (canSkip)
2612
+ return;
2613
+ const { layout: layout2, layoutId } = this.options;
2614
+ this.isTreeAnimating = Boolean(this.parent && this.parent.isTreeAnimating || this.currentAnimation || this.pendingAnimation);
2615
+ if (!this.isTreeAnimating) {
2616
+ this.targetDelta = this.relativeTarget = void 0;
2617
+ }
2618
+ if (!this.layout || !(layout2 || layoutId))
2619
+ return;
2620
+ copyBoxInto(this.layoutCorrected, this.layout.layoutBox);
2621
+ const prevTreeScaleX = this.treeScale.x;
2622
+ const prevTreeScaleY = this.treeScale.y;
2623
+ applyTreeDeltas(this.layoutCorrected, this.treeScale, this.path, isShared);
2624
+ if (lead.layout && !lead.target && (this.treeScale.x !== 1 || this.treeScale.y !== 1)) {
2625
+ lead.target = lead.layout.layoutBox;
2626
+ lead.targetWithTransforms = createBox();
2627
+ }
2628
+ const { target } = lead;
2629
+ if (!target) {
2630
+ if (this.prevProjectionDelta) {
2631
+ this.createProjectionDeltas();
2632
+ this.scheduleRender();
2633
+ }
2634
+ return;
2635
+ }
2636
+ if (!this.projectionDelta || !this.prevProjectionDelta) {
2637
+ this.createProjectionDeltas();
2638
+ } else {
2639
+ copyAxisDeltaInto(this.prevProjectionDelta.x, this.projectionDelta.x);
2640
+ copyAxisDeltaInto(this.prevProjectionDelta.y, this.projectionDelta.y);
2641
+ }
2642
+ calcBoxDelta(this.projectionDelta, this.layoutCorrected, target, this.latestValues);
2643
+ if (this.treeScale.x !== prevTreeScaleX || this.treeScale.y !== prevTreeScaleY || !axisDeltaEquals(this.projectionDelta.x, this.prevProjectionDelta.x) || !axisDeltaEquals(this.projectionDelta.y, this.prevProjectionDelta.y)) {
2644
+ this.hasProjected = true;
2645
+ this.scheduleRender();
2646
+ this.notifyListeners("projectionUpdate", target);
2647
+ }
2648
+ if (isDebug) {
2649
+ metrics.recalculatedProjection++;
2650
+ }
2651
+ }
2652
+ hide() {
2653
+ this.isVisible = false;
2654
+ }
2655
+ show() {
2656
+ this.isVisible = true;
2657
+ }
2658
+ scheduleRender(notifyAll = true) {
2659
+ var _a;
2660
+ (_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.scheduleRender();
2661
+ if (notifyAll) {
2662
+ const stack = this.getStack();
2663
+ stack && stack.scheduleRender();
2664
+ }
2665
+ if (this.resumingFrom && !this.resumingFrom.instance) {
2666
+ this.resumingFrom = void 0;
2667
+ }
2668
+ }
2669
+ createProjectionDeltas() {
2670
+ this.prevProjectionDelta = createDelta();
2671
+ this.projectionDelta = createDelta();
2672
+ this.projectionDeltaWithTransform = createDelta();
2673
+ }
2674
+ setAnimationOrigin(delta, hasOnlyRelativeTargetChanged = false) {
2675
+ const snapshot = this.snapshot;
2676
+ const snapshotLatestValues = snapshot ? snapshot.latestValues : {};
2677
+ const mixedValues = { ...this.latestValues };
2678
+ const targetDelta = createDelta();
2679
+ if (!this.relativeParent || !this.relativeParent.options.layoutRoot) {
2680
+ this.relativeTarget = this.relativeTargetOrigin = void 0;
2681
+ }
2682
+ this.attemptToResolveRelativeTarget = !hasOnlyRelativeTargetChanged;
2683
+ const relativeLayout = createBox();
2684
+ const snapshotSource = snapshot ? snapshot.source : void 0;
2685
+ const layoutSource = this.layout ? this.layout.source : void 0;
2686
+ const isSharedLayoutAnimation = snapshotSource !== layoutSource;
2687
+ const stack = this.getStack();
2688
+ const isOnlyMember = !stack || stack.members.length <= 1;
2689
+ const shouldCrossfadeOpacity = Boolean(isSharedLayoutAnimation && !isOnlyMember && this.options.crossfade === true && !this.path.some(hasOpacityCrossfade));
2690
+ this.animationProgress = 0;
2691
+ let prevRelativeTarget;
2692
+ this.mixTargetDelta = (latest) => {
2693
+ const progress2 = latest / 1e3;
2694
+ mixAxisDelta(targetDelta.x, delta.x, progress2);
2695
+ mixAxisDelta(targetDelta.y, delta.y, progress2);
2696
+ this.setTargetDelta(targetDelta);
2697
+ if (this.relativeTarget && this.relativeTargetOrigin && this.layout && this.relativeParent && this.relativeParent.layout) {
2698
+ calcRelativePosition(relativeLayout, this.layout.layoutBox, this.relativeParent.layout.layoutBox);
2699
+ mixBox(this.relativeTarget, this.relativeTargetOrigin, relativeLayout, progress2);
2700
+ if (prevRelativeTarget && boxEquals(this.relativeTarget, prevRelativeTarget)) {
2701
+ this.isProjectionDirty = false;
2702
+ }
2703
+ if (!prevRelativeTarget)
2704
+ prevRelativeTarget = createBox();
2705
+ copyBoxInto(prevRelativeTarget, this.relativeTarget);
2706
+ }
2707
+ if (isSharedLayoutAnimation) {
2708
+ this.animationValues = mixedValues;
2709
+ mixValues(mixedValues, snapshotLatestValues, this.latestValues, progress2, shouldCrossfadeOpacity, isOnlyMember);
2710
+ }
2711
+ this.root.scheduleUpdateProjection();
2712
+ this.scheduleRender();
2713
+ this.animationProgress = progress2;
2714
+ };
2715
+ this.mixTargetDelta(this.options.layoutRoot ? 1e3 : 0);
2716
+ }
2717
+ startAnimation(options) {
2718
+ this.notifyListeners("animationStart");
2719
+ this.currentAnimation && this.currentAnimation.stop();
2720
+ if (this.resumingFrom && this.resumingFrom.currentAnimation) {
2721
+ this.resumingFrom.currentAnimation.stop();
2722
+ }
2723
+ if (this.pendingAnimation) {
2724
+ cancelFrame(this.pendingAnimation);
2725
+ this.pendingAnimation = void 0;
2726
+ }
2727
+ this.pendingAnimation = frame.update(() => {
2728
+ globalProjectionState.hasAnimatedSinceResize = true;
2729
+ this.currentAnimation = animateSingleValue(0, animationTarget, {
2730
+ ...options,
2731
+ onUpdate: (latest) => {
2732
+ this.mixTargetDelta(latest);
2733
+ options.onUpdate && options.onUpdate(latest);
2734
+ },
2735
+ onComplete: () => {
2736
+ options.onComplete && options.onComplete();
2737
+ this.completeAnimation();
2738
+ }
2739
+ });
2740
+ if (this.resumingFrom) {
2741
+ this.resumingFrom.currentAnimation = this.currentAnimation;
2742
+ }
2743
+ this.pendingAnimation = void 0;
2744
+ });
2745
+ }
2746
+ completeAnimation() {
2747
+ if (this.resumingFrom) {
2748
+ this.resumingFrom.currentAnimation = void 0;
2749
+ this.resumingFrom.preserveOpacity = void 0;
2750
+ }
2751
+ const stack = this.getStack();
2752
+ stack && stack.exitAnimationComplete();
2753
+ this.resumingFrom = this.currentAnimation = this.animationValues = void 0;
2754
+ this.notifyListeners("animationComplete");
2755
+ }
2756
+ finishAnimation() {
2757
+ if (this.currentAnimation) {
2758
+ this.mixTargetDelta && this.mixTargetDelta(animationTarget);
2759
+ this.currentAnimation.stop();
2760
+ }
2761
+ this.completeAnimation();
2762
+ }
2763
+ applyTransformsToTarget() {
2764
+ const lead = this.getLead();
2765
+ let { targetWithTransforms, target, layout: layout2, latestValues } = lead;
2766
+ if (!targetWithTransforms || !target || !layout2)
2767
+ return;
2768
+ if (this !== lead && this.layout && layout2 && shouldAnimatePositionOnly(this.options.animationType, this.layout.layoutBox, layout2.layoutBox)) {
2769
+ target = this.target || createBox();
2770
+ const xLength = calcLength(this.layout.layoutBox.x);
2771
+ target.x.min = lead.target.x.min;
2772
+ target.x.max = target.x.min + xLength;
2773
+ const yLength = calcLength(this.layout.layoutBox.y);
2774
+ target.y.min = lead.target.y.min;
2775
+ target.y.max = target.y.min + yLength;
2776
+ }
2777
+ copyBoxInto(targetWithTransforms, target);
2778
+ transformBox(targetWithTransforms, latestValues);
2779
+ calcBoxDelta(this.projectionDeltaWithTransform, this.layoutCorrected, targetWithTransforms, latestValues);
2780
+ }
2781
+ registerSharedNode(layoutId, node) {
2782
+ if (!this.sharedNodes.has(layoutId)) {
2783
+ this.sharedNodes.set(layoutId, new NodeStack());
2784
+ }
2785
+ const stack = this.sharedNodes.get(layoutId);
2786
+ stack.add(node);
2787
+ const config = node.options.initialPromotionConfig;
2788
+ node.promote({
2789
+ transition: config ? config.transition : void 0,
2790
+ preserveFollowOpacity: config && config.shouldPreserveFollowOpacity ? config.shouldPreserveFollowOpacity(node) : void 0
2791
+ });
2792
+ }
2793
+ isLead() {
2794
+ const stack = this.getStack();
2795
+ return stack ? stack.lead === this : true;
2796
+ }
2797
+ getLead() {
2798
+ var _a;
2799
+ const { layoutId } = this.options;
2800
+ return layoutId ? ((_a = this.getStack()) === null || _a === void 0 ? void 0 : _a.lead) || this : this;
2801
+ }
2802
+ getPrevLead() {
2803
+ var _a;
2804
+ const { layoutId } = this.options;
2805
+ return layoutId ? (_a = this.getStack()) === null || _a === void 0 ? void 0 : _a.prevLead : void 0;
2806
+ }
2807
+ getStack() {
2808
+ const { layoutId } = this.options;
2809
+ if (layoutId)
2810
+ return this.root.sharedNodes.get(layoutId);
2811
+ }
2812
+ promote({ needsReset, transition, preserveFollowOpacity } = {}) {
2813
+ const stack = this.getStack();
2814
+ if (stack)
2815
+ stack.promote(this, preserveFollowOpacity);
2816
+ if (needsReset) {
2817
+ this.projectionDelta = void 0;
2818
+ this.needsReset = true;
2819
+ }
2820
+ if (transition)
2821
+ this.setOptions({ transition });
2822
+ }
2823
+ relegate() {
2824
+ const stack = this.getStack();
2825
+ if (stack) {
2826
+ return stack.relegate(this);
2827
+ } else {
2828
+ return false;
2829
+ }
2830
+ }
2831
+ resetSkewAndRotation() {
2832
+ const { visualElement } = this.options;
2833
+ if (!visualElement)
2834
+ return;
2835
+ let hasDistortingTransform = false;
2836
+ const { latestValues } = visualElement;
2837
+ if (latestValues.z || latestValues.rotate || latestValues.rotateX || latestValues.rotateY || latestValues.rotateZ || latestValues.skewX || latestValues.skewY) {
2838
+ hasDistortingTransform = true;
2839
+ }
2840
+ if (!hasDistortingTransform)
2841
+ return;
2842
+ const resetValues = {};
2843
+ if (latestValues.z) {
2844
+ resetDistortingTransform("z", visualElement, resetValues, this.animationValues);
2845
+ }
2846
+ for (let i = 0; i < transformAxes.length; i++) {
2847
+ resetDistortingTransform(`rotate${transformAxes[i]}`, visualElement, resetValues, this.animationValues);
2848
+ resetDistortingTransform(`skew${transformAxes[i]}`, visualElement, resetValues, this.animationValues);
2849
+ }
2850
+ visualElement.render();
2851
+ for (const key in resetValues) {
2852
+ visualElement.setStaticValue(key, resetValues[key]);
2853
+ if (this.animationValues) {
2854
+ this.animationValues[key] = resetValues[key];
2855
+ }
2856
+ }
2857
+ visualElement.scheduleRender();
2858
+ }
2859
+ getProjectionStyles(styleProp) {
2860
+ var _a, _b;
2861
+ if (!this.instance || this.isSVG)
2862
+ return void 0;
2863
+ if (!this.isVisible) {
2864
+ return hiddenVisibility;
2865
+ }
2866
+ const styles2 = {
2867
+ visibility: ""
2868
+ };
2869
+ const transformTemplate = this.getTransformTemplate();
2870
+ if (this.needsReset) {
2871
+ this.needsReset = false;
2872
+ styles2.opacity = "";
2873
+ styles2.pointerEvents = resolveMotionValue(styleProp === null || styleProp === void 0 ? void 0 : styleProp.pointerEvents) || "";
2874
+ styles2.transform = transformTemplate ? transformTemplate(this.latestValues, "") : "none";
2875
+ return styles2;
2876
+ }
2877
+ const lead = this.getLead();
2878
+ if (!this.projectionDelta || !this.layout || !lead.target) {
2879
+ const emptyStyles = {};
2880
+ if (this.options.layoutId) {
2881
+ emptyStyles.opacity = this.latestValues.opacity !== void 0 ? this.latestValues.opacity : 1;
2882
+ emptyStyles.pointerEvents = resolveMotionValue(styleProp === null || styleProp === void 0 ? void 0 : styleProp.pointerEvents) || "";
2883
+ }
2884
+ if (this.hasProjected && !hasTransform(this.latestValues)) {
2885
+ emptyStyles.transform = transformTemplate ? transformTemplate({}, "") : "none";
2886
+ this.hasProjected = false;
2887
+ }
2888
+ return emptyStyles;
2889
+ }
2890
+ const valuesToRender = lead.animationValues || lead.latestValues;
2891
+ this.applyTransformsToTarget();
2892
+ styles2.transform = buildProjectionTransform(this.projectionDeltaWithTransform, this.treeScale, valuesToRender);
2893
+ if (transformTemplate) {
2894
+ styles2.transform = transformTemplate(valuesToRender, styles2.transform);
2895
+ }
2896
+ const { x, y } = this.projectionDelta;
2897
+ styles2.transformOrigin = `${x.origin * 100}% ${y.origin * 100}% 0`;
2898
+ if (lead.animationValues) {
2899
+ styles2.opacity = lead === this ? (_b = (_a = valuesToRender.opacity) !== null && _a !== void 0 ? _a : this.latestValues.opacity) !== null && _b !== void 0 ? _b : 1 : this.preserveOpacity ? this.latestValues.opacity : valuesToRender.opacityExit;
2900
+ } else {
2901
+ styles2.opacity = lead === this ? valuesToRender.opacity !== void 0 ? valuesToRender.opacity : "" : valuesToRender.opacityExit !== void 0 ? valuesToRender.opacityExit : 0;
2902
+ }
2903
+ for (const key in scaleCorrectors) {
2904
+ if (valuesToRender[key] === void 0)
2905
+ continue;
2906
+ const { correct, applyTo } = scaleCorrectors[key];
2907
+ const corrected = styles2.transform === "none" ? valuesToRender[key] : correct(valuesToRender[key], lead);
2908
+ if (applyTo) {
2909
+ const num = applyTo.length;
2910
+ for (let i = 0; i < num; i++) {
2911
+ styles2[applyTo[i]] = corrected;
2912
+ }
2913
+ } else {
2914
+ styles2[key] = corrected;
2915
+ }
2916
+ }
2917
+ if (this.options.layoutId) {
2918
+ styles2.pointerEvents = lead === this ? resolveMotionValue(styleProp === null || styleProp === void 0 ? void 0 : styleProp.pointerEvents) || "" : "none";
2919
+ }
2920
+ return styles2;
2921
+ }
2922
+ clearSnapshot() {
2923
+ this.resumeFrom = this.snapshot = void 0;
2924
+ }
2925
+ // Only run on root
2926
+ resetTree() {
2927
+ this.root.nodes.forEach((node) => {
2928
+ var _a;
2929
+ return (_a = node.currentAnimation) === null || _a === void 0 ? void 0 : _a.stop();
2930
+ });
2931
+ this.root.nodes.forEach(clearMeasurements);
2932
+ this.root.sharedNodes.clear();
2933
+ }
2934
+ };
2935
+ }
2936
+ function updateLayout(node) {
2937
+ node.updateLayout();
2938
+ }
2939
+ function notifyLayoutUpdate(node) {
2940
+ var _a;
2941
+ const snapshot = ((_a = node.resumeFrom) === null || _a === void 0 ? void 0 : _a.snapshot) || node.snapshot;
2942
+ if (node.isLead() && node.layout && snapshot && node.hasListeners("didUpdate")) {
2943
+ const { layoutBox: layout2, measuredBox: measuredLayout } = node.layout;
2944
+ const { animationType } = node.options;
2945
+ const isShared = snapshot.source !== node.layout.source;
2946
+ if (animationType === "size") {
2947
+ eachAxis((axis) => {
2948
+ const axisSnapshot = isShared ? snapshot.measuredBox[axis] : snapshot.layoutBox[axis];
2949
+ const length = calcLength(axisSnapshot);
2950
+ axisSnapshot.min = layout2[axis].min;
2951
+ axisSnapshot.max = axisSnapshot.min + length;
2952
+ });
2953
+ } else if (shouldAnimatePositionOnly(animationType, snapshot.layoutBox, layout2)) {
2954
+ eachAxis((axis) => {
2955
+ const axisSnapshot = isShared ? snapshot.measuredBox[axis] : snapshot.layoutBox[axis];
2956
+ const length = calcLength(layout2[axis]);
2957
+ axisSnapshot.max = axisSnapshot.min + length;
2958
+ if (node.relativeTarget && !node.currentAnimation) {
2959
+ node.isProjectionDirty = true;
2960
+ node.relativeTarget[axis].max = node.relativeTarget[axis].min + length;
2961
+ }
2962
+ });
2963
+ }
2964
+ const layoutDelta = createDelta();
2965
+ calcBoxDelta(layoutDelta, layout2, snapshot.layoutBox);
2966
+ const visualDelta = createDelta();
2967
+ if (isShared) {
2968
+ calcBoxDelta(visualDelta, node.applyTransform(measuredLayout, true), snapshot.measuredBox);
2969
+ } else {
2970
+ calcBoxDelta(visualDelta, layout2, snapshot.layoutBox);
2971
+ }
2972
+ const hasLayoutChanged = !isDeltaZero(layoutDelta);
2973
+ let hasRelativeTargetChanged = false;
2974
+ if (!node.resumeFrom) {
2975
+ const relativeParent = node.getClosestProjectingParent();
2976
+ if (relativeParent && !relativeParent.resumeFrom) {
2977
+ const { snapshot: parentSnapshot, layout: parentLayout } = relativeParent;
2978
+ if (parentSnapshot && parentLayout) {
2979
+ const relativeSnapshot = createBox();
2980
+ calcRelativePosition(relativeSnapshot, snapshot.layoutBox, parentSnapshot.layoutBox);
2981
+ const relativeLayout = createBox();
2982
+ calcRelativePosition(relativeLayout, layout2, parentLayout.layoutBox);
2983
+ if (!boxEqualsRounded(relativeSnapshot, relativeLayout)) {
2984
+ hasRelativeTargetChanged = true;
2985
+ }
2986
+ if (relativeParent.options.layoutRoot) {
2987
+ node.relativeTarget = relativeLayout;
2988
+ node.relativeTargetOrigin = relativeSnapshot;
2989
+ node.relativeParent = relativeParent;
2990
+ }
2991
+ }
2992
+ }
2993
+ }
2994
+ node.notifyListeners("didUpdate", {
2995
+ layout: layout2,
2996
+ snapshot,
2997
+ delta: visualDelta,
2998
+ layoutDelta,
2999
+ hasLayoutChanged,
3000
+ hasRelativeTargetChanged
3001
+ });
3002
+ } else if (node.isLead()) {
3003
+ const { onExitComplete } = node.options;
3004
+ onExitComplete && onExitComplete();
3005
+ }
3006
+ node.options.transition = void 0;
3007
+ }
3008
+ function propagateDirtyNodes(node) {
3009
+ if (isDebug) {
3010
+ metrics.totalNodes++;
3011
+ }
3012
+ if (!node.parent)
3013
+ return;
3014
+ if (!node.isProjecting()) {
3015
+ node.isProjectionDirty = node.parent.isProjectionDirty;
3016
+ }
3017
+ node.isSharedProjectionDirty || (node.isSharedProjectionDirty = Boolean(node.isProjectionDirty || node.parent.isProjectionDirty || node.parent.isSharedProjectionDirty));
3018
+ node.isTransformDirty || (node.isTransformDirty = node.parent.isTransformDirty);
3019
+ }
3020
+ function cleanDirtyNodes(node) {
3021
+ node.isProjectionDirty = node.isSharedProjectionDirty = node.isTransformDirty = false;
3022
+ }
3023
+ function clearSnapshot(node) {
3024
+ node.clearSnapshot();
3025
+ }
3026
+ function clearMeasurements(node) {
3027
+ node.clearMeasurements();
3028
+ }
3029
+ function clearIsLayoutDirty(node) {
3030
+ node.isLayoutDirty = false;
3031
+ }
3032
+ function resetTransformStyle(node) {
3033
+ const { visualElement } = node.options;
3034
+ if (visualElement && visualElement.getProps().onBeforeLayoutMeasure) {
3035
+ visualElement.notify("BeforeLayoutMeasure");
3036
+ }
3037
+ node.resetTransform();
3038
+ }
3039
+ function finishAnimation(node) {
3040
+ node.finishAnimation();
3041
+ node.targetDelta = node.relativeTarget = node.target = void 0;
3042
+ node.isProjectionDirty = true;
3043
+ }
3044
+ function resolveTargetDelta(node) {
3045
+ node.resolveTargetDelta();
3046
+ }
3047
+ function calcProjection(node) {
3048
+ node.calcProjection();
3049
+ }
3050
+ function resetSkewAndRotation(node) {
3051
+ node.resetSkewAndRotation();
3052
+ }
3053
+ function removeLeadSnapshots(stack) {
3054
+ stack.removeLeadSnapshot();
3055
+ }
3056
+ function mixAxisDelta(output, delta, p) {
3057
+ output.translate = mixNumber(delta.translate, 0, p);
3058
+ output.scale = mixNumber(delta.scale, 1, p);
3059
+ output.origin = delta.origin;
3060
+ output.originPoint = delta.originPoint;
3061
+ }
3062
+ function mixAxis(output, from, to, p) {
3063
+ output.min = mixNumber(from.min, to.min, p);
3064
+ output.max = mixNumber(from.max, to.max, p);
3065
+ }
3066
+ function mixBox(output, from, to, p) {
3067
+ mixAxis(output.x, from.x, to.x, p);
3068
+ mixAxis(output.y, from.y, to.y, p);
3069
+ }
3070
+ function hasOpacityCrossfade(node) {
3071
+ return node.animationValues && node.animationValues.opacityExit !== void 0;
3072
+ }
3073
+ const defaultLayoutTransition = {
3074
+ duration: 0.45,
3075
+ ease: [0.4, 0, 0.1, 1]
3076
+ };
3077
+ const userAgentContains = (string) => typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().includes(string);
3078
+ const roundPoint = userAgentContains("applewebkit/") && !userAgentContains("chrome/") ? Math.round : noop;
3079
+ function roundAxis(axis) {
3080
+ axis.min = roundPoint(axis.min);
3081
+ axis.max = roundPoint(axis.max);
3082
+ }
3083
+ function roundBox(box) {
3084
+ roundAxis(box.x);
3085
+ roundAxis(box.y);
3086
+ }
3087
+ function shouldAnimatePositionOnly(animationType, snapshot, layout2) {
3088
+ return animationType === "position" || animationType === "preserve-aspect" && !isNear(aspectRatio(snapshot), aspectRatio(layout2), 0.2);
3089
+ }
3090
+ function checkNodeWasScrollRoot(node) {
3091
+ var _a;
3092
+ return node !== node.root && ((_a = node.scroll) === null || _a === void 0 ? void 0 : _a.wasRoot);
3093
+ }
3094
+ const DocumentProjectionNode = createProjectionNode({
3095
+ attachResizeListener: (ref, notify) => addDomEvent(ref, "resize", notify),
3096
+ measureScroll: () => ({
3097
+ x: document.documentElement.scrollLeft || document.body.scrollLeft,
3098
+ y: document.documentElement.scrollTop || document.body.scrollTop
3099
+ }),
3100
+ checkIsScrollRoot: () => true
3101
+ });
3102
+ const rootProjectionNode = {
3103
+ current: void 0
3104
+ };
3105
+ const HTMLProjectionNode = createProjectionNode({
3106
+ measureScroll: (instance) => ({
3107
+ x: instance.scrollLeft,
3108
+ y: instance.scrollTop
3109
+ }),
3110
+ defaultParent: () => {
3111
+ if (!rootProjectionNode.current) {
3112
+ const documentNode = new DocumentProjectionNode({});
3113
+ documentNode.mount(window);
3114
+ documentNode.setOptions({ layoutScroll: true });
3115
+ rootProjectionNode.current = documentNode;
3116
+ }
3117
+ return rootProjectionNode.current;
3118
+ },
3119
+ resetTransform: (instance, value) => {
3120
+ instance.style.transform = value !== void 0 ? value : "none";
3121
+ },
3122
+ checkIsScrollRoot: (instance) => Boolean(window.getComputedStyle(instance).position === "fixed")
3123
+ });
3124
+ const drag = {
3125
+ pan: {
3126
+ Feature: PanGesture
3127
+ },
3128
+ drag: {
3129
+ Feature: DragGesture,
3130
+ ProjectionNode: HTMLProjectionNode,
3131
+ MeasureLayout
3132
+ }
3133
+ };
3134
+ function setupGesture(elementOrSelector, options) {
3135
+ const elements = resolveElements(elementOrSelector);
3136
+ const gestureAbortController = new AbortController();
3137
+ const eventOptions = {
3138
+ passive: true,
3139
+ ...options,
3140
+ signal: gestureAbortController.signal
3141
+ };
3142
+ const cancel = () => gestureAbortController.abort();
3143
+ return [elements, eventOptions, cancel];
3144
+ }
3145
+ function filterEvents$1(callback) {
3146
+ return (event) => {
3147
+ if (event.pointerType === "touch" || isDragActive())
3148
+ return;
3149
+ callback(event);
3150
+ };
3151
+ }
3152
+ function hover(elementOrSelector, onHoverStart, options = {}) {
3153
+ const [elements, eventOptions, cancel] = setupGesture(elementOrSelector, options);
3154
+ const onPointerEnter = filterEvents$1((enterEvent) => {
3155
+ const { target } = enterEvent;
3156
+ const onHoverEnd = onHoverStart(enterEvent);
3157
+ if (typeof onHoverEnd !== "function" || !target)
3158
+ return;
3159
+ const onPointerLeave = filterEvents$1((leaveEvent) => {
3160
+ onHoverEnd(leaveEvent);
3161
+ target.removeEventListener("pointerleave", onPointerLeave);
3162
+ });
3163
+ target.addEventListener("pointerleave", onPointerLeave, eventOptions);
3164
+ });
3165
+ elements.forEach((element) => {
3166
+ element.addEventListener("pointerenter", onPointerEnter, eventOptions);
3167
+ });
3168
+ return cancel;
3169
+ }
3170
+ function handleHoverEvent(node, event, lifecycle) {
3171
+ const { props } = node;
3172
+ if (node.animationState && props.whileHover) {
3173
+ node.animationState.setActive("whileHover", lifecycle === "Start");
3174
+ }
3175
+ const eventName = "onHover" + lifecycle;
3176
+ const callback = props[eventName];
3177
+ if (callback) {
3178
+ frame.postRender(() => callback(event, extractEventInfo(event)));
3179
+ }
3180
+ }
3181
+ class HoverGesture extends Feature {
3182
+ mount() {
3183
+ const { current } = this.node;
3184
+ if (!current)
3185
+ return;
3186
+ this.unmount = hover(current, (startEvent) => {
3187
+ handleHoverEvent(this.node, startEvent, "Start");
3188
+ return (endEvent) => handleHoverEvent(this.node, endEvent, "End");
3189
+ });
3190
+ }
3191
+ unmount() {
3192
+ }
3193
+ }
3194
+ class FocusGesture extends Feature {
3195
+ constructor() {
3196
+ super(...arguments);
3197
+ this.isActive = false;
3198
+ }
3199
+ onFocus() {
3200
+ let isFocusVisible = false;
3201
+ try {
3202
+ isFocusVisible = this.node.current.matches(":focus-visible");
3203
+ } catch (e) {
3204
+ isFocusVisible = true;
3205
+ }
3206
+ if (!isFocusVisible || !this.node.animationState)
3207
+ return;
3208
+ this.node.animationState.setActive("whileFocus", true);
3209
+ this.isActive = true;
3210
+ }
3211
+ onBlur() {
3212
+ if (!this.isActive || !this.node.animationState)
3213
+ return;
3214
+ this.node.animationState.setActive("whileFocus", false);
3215
+ this.isActive = false;
3216
+ }
3217
+ mount() {
3218
+ this.unmount = pipe(addDomEvent(this.node.current, "focus", () => this.onFocus()), addDomEvent(this.node.current, "blur", () => this.onBlur()));
3219
+ }
3220
+ unmount() {
3221
+ }
3222
+ }
3223
+ const isNodeOrChild = (parent, child) => {
3224
+ if (!child) {
3225
+ return false;
3226
+ } else if (parent === child) {
3227
+ return true;
3228
+ } else {
3229
+ return isNodeOrChild(parent, child.parentElement);
3230
+ }
3231
+ };
3232
+ const focusableElements = /* @__PURE__ */ new Set([
3233
+ "BUTTON",
3234
+ "INPUT",
3235
+ "SELECT",
3236
+ "TEXTAREA",
3237
+ "A"
3238
+ ]);
3239
+ function isElementKeyboardAccessible(element) {
3240
+ return focusableElements.has(element.tagName) || element.tabIndex !== -1;
3241
+ }
3242
+ const isPressing = /* @__PURE__ */ new WeakSet();
3243
+ function filterEvents(callback) {
3244
+ return (event) => {
3245
+ if (event.key !== "Enter")
3246
+ return;
3247
+ callback(event);
3248
+ };
3249
+ }
3250
+ function firePointerEvent(target, type) {
3251
+ target.dispatchEvent(new PointerEvent("pointer" + type, { isPrimary: true, bubbles: true }));
3252
+ }
3253
+ const enableKeyboardPress = (focusEvent, eventOptions) => {
3254
+ const element = focusEvent.currentTarget;
3255
+ if (!element)
3256
+ return;
3257
+ const handleKeydown = filterEvents(() => {
3258
+ if (isPressing.has(element))
3259
+ return;
3260
+ firePointerEvent(element, "down");
3261
+ const handleKeyup = filterEvents(() => {
3262
+ firePointerEvent(element, "up");
3263
+ });
3264
+ const handleBlur = () => firePointerEvent(element, "cancel");
3265
+ element.addEventListener("keyup", handleKeyup, eventOptions);
3266
+ element.addEventListener("blur", handleBlur, eventOptions);
3267
+ });
3268
+ element.addEventListener("keydown", handleKeydown, eventOptions);
3269
+ element.addEventListener("blur", () => element.removeEventListener("keydown", handleKeydown), eventOptions);
3270
+ };
3271
+ function isValidPressEvent(event) {
3272
+ return isPrimaryPointer(event) && !isDragActive();
3273
+ }
3274
+ function press(elementOrSelector, onPressStart, options = {}) {
3275
+ const [elements, eventOptions, cancelEvents] = setupGesture(elementOrSelector, options);
3276
+ const startPress = (startEvent) => {
3277
+ const element = startEvent.currentTarget;
3278
+ if (!isValidPressEvent(startEvent) || isPressing.has(element))
3279
+ return;
3280
+ isPressing.add(element);
3281
+ const onPressEnd = onPressStart(startEvent);
3282
+ const onPointerEnd = (endEvent, success) => {
3283
+ window.removeEventListener("pointerup", onPointerUp);
3284
+ window.removeEventListener("pointercancel", onPointerCancel);
3285
+ if (!isValidPressEvent(endEvent) || !isPressing.has(element)) {
3286
+ return;
3287
+ }
3288
+ isPressing.delete(element);
3289
+ if (typeof onPressEnd === "function") {
3290
+ onPressEnd(endEvent, { success });
3291
+ }
3292
+ };
3293
+ const onPointerUp = (upEvent) => {
3294
+ onPointerEnd(upEvent, options.useGlobalTarget || isNodeOrChild(element, upEvent.target));
3295
+ };
3296
+ const onPointerCancel = (cancelEvent) => {
3297
+ onPointerEnd(cancelEvent, false);
3298
+ };
3299
+ window.addEventListener("pointerup", onPointerUp, eventOptions);
3300
+ window.addEventListener("pointercancel", onPointerCancel, eventOptions);
3301
+ };
3302
+ elements.forEach((element) => {
3303
+ if (!isElementKeyboardAccessible(element) && element.getAttribute("tabindex") === null) {
3304
+ element.tabIndex = 0;
3305
+ }
3306
+ const target = options.useGlobalTarget ? window : element;
3307
+ target.addEventListener("pointerdown", startPress, eventOptions);
3308
+ element.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions), eventOptions);
3309
+ });
3310
+ return cancelEvents;
3311
+ }
3312
+ function handlePressEvent(node, event, lifecycle) {
3313
+ const { props } = node;
3314
+ if (node.animationState && props.whileTap) {
3315
+ node.animationState.setActive("whileTap", lifecycle === "Start");
3316
+ }
3317
+ const eventName = "onTap" + (lifecycle === "End" ? "" : lifecycle);
3318
+ const callback = props[eventName];
3319
+ if (callback) {
3320
+ frame.postRender(() => callback(event, extractEventInfo(event)));
3321
+ }
3322
+ }
3323
+ class PressGesture extends Feature {
3324
+ mount() {
3325
+ const { current } = this.node;
3326
+ if (!current)
3327
+ return;
3328
+ this.unmount = press(current, (startEvent) => {
3329
+ handlePressEvent(this.node, startEvent, "Start");
3330
+ return (endEvent, { success }) => handlePressEvent(this.node, endEvent, success ? "End" : "Cancel");
3331
+ }, { useGlobalTarget: this.node.props.globalTapTarget });
3332
+ }
3333
+ unmount() {
3334
+ }
3335
+ }
3336
+ const observerCallbacks = /* @__PURE__ */ new WeakMap();
3337
+ const observers = /* @__PURE__ */ new WeakMap();
3338
+ const fireObserverCallback = (entry) => {
3339
+ const callback = observerCallbacks.get(entry.target);
3340
+ callback && callback(entry);
3341
+ };
3342
+ const fireAllObserverCallbacks = (entries) => {
3343
+ entries.forEach(fireObserverCallback);
3344
+ };
3345
+ function initIntersectionObserver({ root, ...options }) {
3346
+ const lookupRoot = root || document;
3347
+ if (!observers.has(lookupRoot)) {
3348
+ observers.set(lookupRoot, {});
3349
+ }
3350
+ const rootObservers = observers.get(lookupRoot);
3351
+ const key = JSON.stringify(options);
3352
+ if (!rootObservers[key]) {
3353
+ rootObservers[key] = new IntersectionObserver(fireAllObserverCallbacks, { root, ...options });
3354
+ }
3355
+ return rootObservers[key];
3356
+ }
3357
+ function observeIntersection(element, options, callback) {
3358
+ const rootInteresectionObserver = initIntersectionObserver(options);
3359
+ observerCallbacks.set(element, callback);
3360
+ rootInteresectionObserver.observe(element);
3361
+ return () => {
3362
+ observerCallbacks.delete(element);
3363
+ rootInteresectionObserver.unobserve(element);
3364
+ };
3365
+ }
3366
+ const thresholdNames = {
3367
+ some: 0,
3368
+ all: 1
3369
+ };
3370
+ class InViewFeature extends Feature {
3371
+ constructor() {
3372
+ super(...arguments);
3373
+ this.hasEnteredView = false;
3374
+ this.isInView = false;
3375
+ }
3376
+ startObserver() {
3377
+ this.unmount();
3378
+ const { viewport = {} } = this.node.getProps();
3379
+ const { root, margin: rootMargin, amount = "some", once } = viewport;
3380
+ const options = {
3381
+ root: root ? root.current : void 0,
3382
+ rootMargin,
3383
+ threshold: typeof amount === "number" ? amount : thresholdNames[amount]
3384
+ };
3385
+ const onIntersectionUpdate = (entry) => {
3386
+ const { isIntersecting } = entry;
3387
+ if (this.isInView === isIntersecting)
3388
+ return;
3389
+ this.isInView = isIntersecting;
3390
+ if (once && !isIntersecting && this.hasEnteredView) {
3391
+ return;
3392
+ } else if (isIntersecting) {
3393
+ this.hasEnteredView = true;
3394
+ }
3395
+ if (this.node.animationState) {
3396
+ this.node.animationState.setActive("whileInView", isIntersecting);
3397
+ }
3398
+ const { onViewportEnter, onViewportLeave } = this.node.getProps();
3399
+ const callback = isIntersecting ? onViewportEnter : onViewportLeave;
3400
+ callback && callback(entry);
3401
+ };
3402
+ return observeIntersection(this.node.current, options, onIntersectionUpdate);
3403
+ }
3404
+ mount() {
3405
+ this.startObserver();
3406
+ }
3407
+ update() {
3408
+ if (typeof IntersectionObserver === "undefined")
3409
+ return;
3410
+ const { props, prevProps } = this.node;
3411
+ const hasOptionsChanged = ["amount", "margin", "root"].some(hasViewportOptionChanged(props, prevProps));
3412
+ if (hasOptionsChanged) {
3413
+ this.startObserver();
3414
+ }
3415
+ }
3416
+ unmount() {
3417
+ }
3418
+ }
3419
+ function hasViewportOptionChanged({ viewport = {} }, { viewport: prevViewport = {} } = {}) {
3420
+ return (name) => viewport[name] !== prevViewport[name];
3421
+ }
3422
+ const gestureAnimations = {
3423
+ inView: {
3424
+ Feature: InViewFeature
3425
+ },
3426
+ tap: {
3427
+ Feature: PressGesture
3428
+ },
3429
+ focus: {
3430
+ Feature: FocusGesture
3431
+ },
3432
+ hover: {
3433
+ Feature: HoverGesture
3434
+ }
3435
+ };
3436
+ const layout = {
3437
+ layout: {
3438
+ ProjectionNode: HTMLProjectionNode,
3439
+ MeasureLayout
3440
+ }
3441
+ };
3442
+ const createDomVisualElement = (Component2, options) => {
3443
+ return isSVGComponent(Component2) ? new SVGVisualElement(options) : new HTMLVisualElement(options, {
3444
+ allowProjection: Component2 !== Fragment
3445
+ });
3446
+ };
3447
+ const createMotionComponent = /* @__PURE__ */ createMotionComponentFactory({
3448
+ ...animations,
3449
+ ...gestureAnimations,
3450
+ ...drag,
3451
+ ...layout
3452
+ }, createDomVisualElement);
3453
+ const motion = /* @__PURE__ */ createDOMMotionComponentProxy(createMotionComponent);
3454
+ const DURATION = 8e3;
3455
+ const ToastList = React__default.forwardRef((props, ref) => {
3456
+ const { testId, toasts = [] } = props;
3457
+ const internalRef = React__default.useRef(null);
3458
+ const [visibleToasts, setVisibleToasts] = React__default.useState([]);
3459
+ const [removedToastIds, setRemovedToastIds] = React__default.useState(/* @__PURE__ */ new Set());
3460
+ const timeoutRefs = React__default.useRef(/* @__PURE__ */ new Map());
3461
+ React__default.useEffect(() => {
3462
+ const newToasts = toasts.filter((toast) => !visibleToasts.some((vt) => vt.id === toast.id) && !removedToastIds.has(toast.id));
3463
+ if (newToasts.length > 0) {
3464
+ setVisibleToasts((prev) => [...prev, ...newToasts]);
3465
+ }
3466
+ }, [toasts, visibleToasts, removedToastIds]);
3467
+ const handleRemoveToast = React__default.useCallback((id2) => {
3468
+ setVisibleToasts((prev) => prev.filter((t) => t.id !== id2));
3469
+ setRemovedToastIds((prev) => /* @__PURE__ */ new Set([...prev, id2]));
3470
+ const timeout = timeoutRefs.current.get(id2);
3471
+ if (timeout) {
3472
+ clearTimeout(timeout);
3473
+ timeoutRefs.current.delete(id2);
3474
+ }
3475
+ }, []);
3476
+ React__default.useEffect(() => {
3477
+ const timeouts = timeoutRefs.current;
3478
+ visibleToasts.forEach((toast) => {
3479
+ if (!timeouts.has(toast.id)) {
3480
+ const timeout = setTimeout(() => {
3481
+ handleRemoveToast(toast.id);
3482
+ }, DURATION);
3483
+ timeouts.set(toast.id, timeout);
3484
+ }
3485
+ });
3486
+ }, [visibleToasts, handleRemoveToast]);
3487
+ React__default.useEffect(() => {
3488
+ const timeouts = timeoutRefs.current;
3489
+ const currentToastIds = new Set(visibleToasts.map((t) => t.id));
3490
+ timeouts.forEach((timeout, id2) => {
3491
+ if (!currentToastIds.has(id2)) {
3492
+ clearTimeout(timeout);
3493
+ timeouts.delete(id2);
3494
+ }
3495
+ });
3496
+ }, [visibleToasts]);
3497
+ React__default.useEffect(() => {
3498
+ return () => {
3499
+ timeoutRefs.current.forEach((timeout) => clearTimeout(timeout));
3500
+ timeoutRefs.current.clear();
3501
+ };
3502
+ }, []);
3503
+ const setRefs = mergeRefs([internalRef, ref]);
3504
+ return /* @__PURE__ */ jsx("section", { ref: setRefs, className: styles["toast-list"], "data-testid": testId, children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "popLayout", children: visibleToasts.map((toast) => /* @__PURE__ */ jsx(
3505
+ motion.div,
3506
+ {
3507
+ layout: true,
3508
+ initial: { opacity: 0, y: 50 },
3509
+ animate: { opacity: 1, y: 0 },
3510
+ exit: { opacity: 0, y: -20 },
3511
+ transition: {
3512
+ layout: { type: "spring", duration: 0.4, bounce: 0.1 }
3513
+ },
3514
+ children: /* @__PURE__ */ jsx(
3515
+ Toast,
3516
+ {
3517
+ testId: `${testId}-${toast.id}`,
3518
+ title: toast.title,
3519
+ message: toast.message,
3520
+ onClose: () => handleRemoveToast(toast.id)
3521
+ }
3522
+ )
3523
+ },
3524
+ toast.id
3525
+ )) }) });
3526
+ });
3527
+ ToastList.displayName = "ToastList";
3528
+ export {
3529
+ ToastList as default
3530
+ };
3531
+ //# sourceMappingURL=index.js.map