motion 12.27.0-alpha.5 → 12.27.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.
- package/dist/motion.dev.js +272 -536
- package/dist/motion.js +1 -1
- package/package.json +3 -3
package/dist/motion.dev.js
CHANGED
|
@@ -2963,6 +2963,20 @@
|
|
|
2963
2963
|
return map;
|
|
2964
2964
|
}
|
|
2965
2965
|
|
|
2966
|
+
function calcChildStagger(children, child, delayChildren, staggerChildren = 0, staggerDirection = 1) {
|
|
2967
|
+
const index = Array.from(children)
|
|
2968
|
+
.sort((a, b) => a.sortNodePosition(b))
|
|
2969
|
+
.indexOf(child);
|
|
2970
|
+
const numChildren = children.size;
|
|
2971
|
+
const maxStaggerDuration = (numChildren - 1) * staggerChildren;
|
|
2972
|
+
const delayIsFunction = typeof delayChildren === "function";
|
|
2973
|
+
return delayIsFunction
|
|
2974
|
+
? delayChildren(index, numChildren)
|
|
2975
|
+
: staggerDirection === 1
|
|
2976
|
+
? index * staggerChildren
|
|
2977
|
+
: maxStaggerDuration - index * staggerChildren;
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2966
2980
|
/**
|
|
2967
2981
|
* Parse Framer's special CSS variable format into a CSS token and a fallback.
|
|
2968
2982
|
*
|
|
@@ -3000,12 +3014,6 @@
|
|
|
3000
3014
|
: fallback;
|
|
3001
3015
|
}
|
|
3002
3016
|
|
|
3003
|
-
function getValueTransition$1(transition, key) {
|
|
3004
|
-
return (transition?.[key] ??
|
|
3005
|
-
transition?.["default"] ??
|
|
3006
|
-
transition);
|
|
3007
|
-
}
|
|
3008
|
-
|
|
3009
3017
|
const underDampedSpring = {
|
|
3010
3018
|
type: "spring",
|
|
3011
3019
|
stiffness: 500,
|
|
@@ -3043,15 +3051,6 @@
|
|
|
3043
3051
|
return ease;
|
|
3044
3052
|
};
|
|
3045
3053
|
|
|
3046
|
-
/**
|
|
3047
|
-
* Decide whether a transition is defined on a given Transition.
|
|
3048
|
-
* This filters out orchestration options and returns true
|
|
3049
|
-
* if any options are left.
|
|
3050
|
-
*/
|
|
3051
|
-
function isTransitionDefined({ when, delay: _delay, delayChildren, staggerChildren, staggerDirection, repeat, repeatType, repeatDelay, from, elapsed, ...transition }) {
|
|
3052
|
-
return !!Object.keys(transition).length;
|
|
3053
|
-
}
|
|
3054
|
-
|
|
3055
3054
|
const isNotNull = (value) => value !== null;
|
|
3056
3055
|
function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe) {
|
|
3057
3056
|
const resolvedKeyframes = keyframes.filter(isNotNull);
|
|
@@ -3063,18 +3062,19 @@
|
|
|
3063
3062
|
: finalKeyframe;
|
|
3064
3063
|
}
|
|
3065
3064
|
|
|
3066
|
-
function
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3065
|
+
function getValueTransition$1(transition, key) {
|
|
3066
|
+
return (transition?.[key] ??
|
|
3067
|
+
transition?.["default"] ??
|
|
3068
|
+
transition);
|
|
3069
|
+
}
|
|
3070
|
+
|
|
3071
|
+
/**
|
|
3072
|
+
* Decide whether a transition is defined on a given Transition.
|
|
3073
|
+
* This filters out orchestration options and returns true
|
|
3074
|
+
* if any options are left.
|
|
3075
|
+
*/
|
|
3076
|
+
function isTransitionDefined({ when, delay: _delay, delayChildren, staggerChildren, staggerDirection, repeat, repeatType, repeatDelay, from, elapsed, ...transition }) {
|
|
3077
|
+
return !!Object.keys(transition).length;
|
|
3078
3078
|
}
|
|
3079
3079
|
|
|
3080
3080
|
const animateMotionValue = (name, value, target, transition = {}, element, isHandoff) => (onComplete) => {
|
|
@@ -3168,6 +3168,46 @@
|
|
|
3168
3168
|
: new AsyncMotionValueAnimation(options);
|
|
3169
3169
|
};
|
|
3170
3170
|
|
|
3171
|
+
function getValueState(visualElement) {
|
|
3172
|
+
const state = [{}, {}];
|
|
3173
|
+
visualElement?.values.forEach((value, key) => {
|
|
3174
|
+
state[0][key] = value.get();
|
|
3175
|
+
state[1][key] = value.getVelocity();
|
|
3176
|
+
});
|
|
3177
|
+
return state;
|
|
3178
|
+
}
|
|
3179
|
+
function resolveVariantFromProps(props, definition, custom, visualElement) {
|
|
3180
|
+
/**
|
|
3181
|
+
* If the variant definition is a function, resolve.
|
|
3182
|
+
*/
|
|
3183
|
+
if (typeof definition === "function") {
|
|
3184
|
+
const [current, velocity] = getValueState(visualElement);
|
|
3185
|
+
definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
|
|
3186
|
+
}
|
|
3187
|
+
/**
|
|
3188
|
+
* If the variant definition is a variant label, or
|
|
3189
|
+
* the function returned a variant label, resolve.
|
|
3190
|
+
*/
|
|
3191
|
+
if (typeof definition === "string") {
|
|
3192
|
+
definition = props.variants && props.variants[definition];
|
|
3193
|
+
}
|
|
3194
|
+
/**
|
|
3195
|
+
* At this point we've resolved both functions and variant labels,
|
|
3196
|
+
* but the resolved variant label might itself have been a function.
|
|
3197
|
+
* If so, resolve. This can only have returned a valid target object.
|
|
3198
|
+
*/
|
|
3199
|
+
if (typeof definition === "function") {
|
|
3200
|
+
const [current, velocity] = getValueState(visualElement);
|
|
3201
|
+
definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
|
|
3202
|
+
}
|
|
3203
|
+
return definition;
|
|
3204
|
+
}
|
|
3205
|
+
|
|
3206
|
+
function resolveVariant(visualElement, definition, custom) {
|
|
3207
|
+
const props = visualElement.getProps();
|
|
3208
|
+
return resolveVariantFromProps(props, definition, custom !== undefined ? custom : props.custom, visualElement);
|
|
3209
|
+
}
|
|
3210
|
+
|
|
3171
3211
|
const positionalKeys = new Set([
|
|
3172
3212
|
"width",
|
|
3173
3213
|
"height",
|
|
@@ -3496,46 +3536,6 @@
|
|
|
3496
3536
|
return new MotionValue(init, options);
|
|
3497
3537
|
}
|
|
3498
3538
|
|
|
3499
|
-
function getValueState(visualElement) {
|
|
3500
|
-
const state = [{}, {}];
|
|
3501
|
-
visualElement?.values.forEach((value, key) => {
|
|
3502
|
-
state[0][key] = value.get();
|
|
3503
|
-
state[1][key] = value.getVelocity();
|
|
3504
|
-
});
|
|
3505
|
-
return state;
|
|
3506
|
-
}
|
|
3507
|
-
function resolveVariantFromProps(props, definition, custom, visualElement) {
|
|
3508
|
-
/**
|
|
3509
|
-
* If the variant definition is a function, resolve.
|
|
3510
|
-
*/
|
|
3511
|
-
if (typeof definition === "function") {
|
|
3512
|
-
const [current, velocity] = getValueState(visualElement);
|
|
3513
|
-
definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
|
|
3514
|
-
}
|
|
3515
|
-
/**
|
|
3516
|
-
* If the variant definition is a variant label, or
|
|
3517
|
-
* the function returned a variant label, resolve.
|
|
3518
|
-
*/
|
|
3519
|
-
if (typeof definition === "string") {
|
|
3520
|
-
definition = props.variants && props.variants[definition];
|
|
3521
|
-
}
|
|
3522
|
-
/**
|
|
3523
|
-
* At this point we've resolved both functions and variant labels,
|
|
3524
|
-
* but the resolved variant label might itself have been a function.
|
|
3525
|
-
* If so, resolve. This can only have returned a valid target object.
|
|
3526
|
-
*/
|
|
3527
|
-
if (typeof definition === "function") {
|
|
3528
|
-
const [current, velocity] = getValueState(visualElement);
|
|
3529
|
-
definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
|
|
3530
|
-
}
|
|
3531
|
-
return definition;
|
|
3532
|
-
}
|
|
3533
|
-
|
|
3534
|
-
function resolveVariant(visualElement, definition, custom) {
|
|
3535
|
-
const props = visualElement.getProps();
|
|
3536
|
-
return resolveVariantFromProps(props, definition, custom !== undefined ? custom : props.custom, visualElement);
|
|
3537
|
-
}
|
|
3538
|
-
|
|
3539
3539
|
const isKeyframesTarget = (v) => {
|
|
3540
3540
|
return Array.isArray(v);
|
|
3541
3541
|
};
|
|
@@ -6066,19 +6066,6 @@
|
|
|
6066
6066
|
}
|
|
6067
6067
|
}
|
|
6068
6068
|
|
|
6069
|
-
/**
|
|
6070
|
-
* Feature base class for extending VisualElement functionality.
|
|
6071
|
-
* Features are plugins that can be mounted/unmounted to add behavior
|
|
6072
|
-
* like gestures, animations, or layout tracking.
|
|
6073
|
-
*/
|
|
6074
|
-
class Feature {
|
|
6075
|
-
constructor(node) {
|
|
6076
|
-
this.isMounted = false;
|
|
6077
|
-
this.node = node;
|
|
6078
|
-
}
|
|
6079
|
-
update() { }
|
|
6080
|
-
}
|
|
6081
|
-
|
|
6082
6069
|
class DOMVisualElement extends VisualElement {
|
|
6083
6070
|
constructor() {
|
|
6084
6071
|
super(...arguments);
|
|
@@ -6116,6 +6103,19 @@
|
|
|
6116
6103
|
}
|
|
6117
6104
|
}
|
|
6118
6105
|
|
|
6106
|
+
/**
|
|
6107
|
+
* Feature base class for extending VisualElement functionality.
|
|
6108
|
+
* Features are plugins that can be mounted/unmounted to add behavior
|
|
6109
|
+
* like gestures, animations, or layout tracking.
|
|
6110
|
+
*/
|
|
6111
|
+
class Feature {
|
|
6112
|
+
constructor(node) {
|
|
6113
|
+
this.isMounted = false;
|
|
6114
|
+
this.node = node;
|
|
6115
|
+
}
|
|
6116
|
+
update() { }
|
|
6117
|
+
}
|
|
6118
|
+
|
|
6119
6119
|
/**
|
|
6120
6120
|
* Bounding boxes tend to be defined as top, left, right, bottom. For various operations
|
|
6121
6121
|
* it's easier to consider each axis individually. This function returns a bounding box
|
|
@@ -6584,6 +6584,43 @@
|
|
|
6584
6584
|
}
|
|
6585
6585
|
}
|
|
6586
6586
|
|
|
6587
|
+
function isObjectKey(key, object) {
|
|
6588
|
+
return key in object;
|
|
6589
|
+
}
|
|
6590
|
+
class ObjectVisualElement extends VisualElement {
|
|
6591
|
+
constructor() {
|
|
6592
|
+
super(...arguments);
|
|
6593
|
+
this.type = "object";
|
|
6594
|
+
}
|
|
6595
|
+
readValueFromInstance(instance, key) {
|
|
6596
|
+
if (isObjectKey(key, instance)) {
|
|
6597
|
+
const value = instance[key];
|
|
6598
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
6599
|
+
return value;
|
|
6600
|
+
}
|
|
6601
|
+
}
|
|
6602
|
+
return undefined;
|
|
6603
|
+
}
|
|
6604
|
+
getBaseTargetFromProps() {
|
|
6605
|
+
return undefined;
|
|
6606
|
+
}
|
|
6607
|
+
removeValueFromRenderState(key, renderState) {
|
|
6608
|
+
delete renderState.output[key];
|
|
6609
|
+
}
|
|
6610
|
+
measureInstanceViewportBox() {
|
|
6611
|
+
return createBox();
|
|
6612
|
+
}
|
|
6613
|
+
build(renderState, latestValues) {
|
|
6614
|
+
Object.assign(renderState.output, latestValues);
|
|
6615
|
+
}
|
|
6616
|
+
renderInstance(instance, { output }) {
|
|
6617
|
+
Object.assign(instance, output);
|
|
6618
|
+
}
|
|
6619
|
+
sortInstanceNodePosition() {
|
|
6620
|
+
return 0;
|
|
6621
|
+
}
|
|
6622
|
+
}
|
|
6623
|
+
|
|
6587
6624
|
const dashKeys = {
|
|
6588
6625
|
offset: "stroke-dashoffset",
|
|
6589
6626
|
array: "stroke-dasharray",
|
|
@@ -6766,43 +6803,6 @@
|
|
|
6766
6803
|
}
|
|
6767
6804
|
}
|
|
6768
6805
|
|
|
6769
|
-
function isObjectKey(key, object) {
|
|
6770
|
-
return key in object;
|
|
6771
|
-
}
|
|
6772
|
-
class ObjectVisualElement extends VisualElement {
|
|
6773
|
-
constructor() {
|
|
6774
|
-
super(...arguments);
|
|
6775
|
-
this.type = "object";
|
|
6776
|
-
}
|
|
6777
|
-
readValueFromInstance(instance, key) {
|
|
6778
|
-
if (isObjectKey(key, instance)) {
|
|
6779
|
-
const value = instance[key];
|
|
6780
|
-
if (typeof value === "string" || typeof value === "number") {
|
|
6781
|
-
return value;
|
|
6782
|
-
}
|
|
6783
|
-
}
|
|
6784
|
-
return undefined;
|
|
6785
|
-
}
|
|
6786
|
-
getBaseTargetFromProps() {
|
|
6787
|
-
return undefined;
|
|
6788
|
-
}
|
|
6789
|
-
removeValueFromRenderState(key, renderState) {
|
|
6790
|
-
delete renderState.output[key];
|
|
6791
|
-
}
|
|
6792
|
-
measureInstanceViewportBox() {
|
|
6793
|
-
return createBox();
|
|
6794
|
-
}
|
|
6795
|
-
build(renderState, latestValues) {
|
|
6796
|
-
Object.assign(renderState.output, latestValues);
|
|
6797
|
-
}
|
|
6798
|
-
renderInstance(instance, { output }) {
|
|
6799
|
-
Object.assign(instance, output);
|
|
6800
|
-
}
|
|
6801
|
-
sortInstanceNodePosition() {
|
|
6802
|
-
return 0;
|
|
6803
|
-
}
|
|
6804
|
-
}
|
|
6805
|
-
|
|
6806
6806
|
const numVariantProps = variantProps.length;
|
|
6807
6807
|
/**
|
|
6808
6808
|
* Get variant context from a visual element's parent chain.
|
|
@@ -7197,6 +7197,36 @@
|
|
|
7197
7197
|
};
|
|
7198
7198
|
}
|
|
7199
7199
|
|
|
7200
|
+
/**
|
|
7201
|
+
* Reset an axis to the provided origin box.
|
|
7202
|
+
*
|
|
7203
|
+
* This is a mutative operation.
|
|
7204
|
+
*/
|
|
7205
|
+
function copyAxisInto(axis, originAxis) {
|
|
7206
|
+
axis.min = originAxis.min;
|
|
7207
|
+
axis.max = originAxis.max;
|
|
7208
|
+
}
|
|
7209
|
+
/**
|
|
7210
|
+
* Reset a box to the provided origin box.
|
|
7211
|
+
*
|
|
7212
|
+
* This is a mutative operation.
|
|
7213
|
+
*/
|
|
7214
|
+
function copyBoxInto(box, originBox) {
|
|
7215
|
+
copyAxisInto(box.x, originBox.x);
|
|
7216
|
+
copyAxisInto(box.y, originBox.y);
|
|
7217
|
+
}
|
|
7218
|
+
/**
|
|
7219
|
+
* Reset a delta to the provided origin box.
|
|
7220
|
+
*
|
|
7221
|
+
* This is a mutative operation.
|
|
7222
|
+
*/
|
|
7223
|
+
function copyAxisDeltaInto(delta, originDelta) {
|
|
7224
|
+
delta.translate = originDelta.translate;
|
|
7225
|
+
delta.scale = originDelta.scale;
|
|
7226
|
+
delta.originPoint = originDelta.originPoint;
|
|
7227
|
+
delta.origin = originDelta.origin;
|
|
7228
|
+
}
|
|
7229
|
+
|
|
7200
7230
|
const SCALE_PRECISION = 0.0001;
|
|
7201
7231
|
const SCALE_MIN = 1 - SCALE_PRECISION;
|
|
7202
7232
|
const SCALE_MAX = 1 + SCALE_PRECISION;
|
|
@@ -7295,36 +7325,6 @@
|
|
|
7295
7325
|
removeAxisTransforms(box.y, transforms, yKeys, originBox ? originBox.y : undefined, sourceBox ? sourceBox.y : undefined);
|
|
7296
7326
|
}
|
|
7297
7327
|
|
|
7298
|
-
/**
|
|
7299
|
-
* Reset an axis to the provided origin box.
|
|
7300
|
-
*
|
|
7301
|
-
* This is a mutative operation.
|
|
7302
|
-
*/
|
|
7303
|
-
function copyAxisInto(axis, originAxis) {
|
|
7304
|
-
axis.min = originAxis.min;
|
|
7305
|
-
axis.max = originAxis.max;
|
|
7306
|
-
}
|
|
7307
|
-
/**
|
|
7308
|
-
* Reset a box to the provided origin box.
|
|
7309
|
-
*
|
|
7310
|
-
* This is a mutative operation.
|
|
7311
|
-
*/
|
|
7312
|
-
function copyBoxInto(box, originBox) {
|
|
7313
|
-
copyAxisInto(box.x, originBox.x);
|
|
7314
|
-
copyAxisInto(box.y, originBox.y);
|
|
7315
|
-
}
|
|
7316
|
-
/**
|
|
7317
|
-
* Reset a delta to the provided origin box.
|
|
7318
|
-
*
|
|
7319
|
-
* This is a mutative operation.
|
|
7320
|
-
*/
|
|
7321
|
-
function copyAxisDeltaInto(delta, originDelta) {
|
|
7322
|
-
delta.translate = originDelta.translate;
|
|
7323
|
-
delta.scale = originDelta.scale;
|
|
7324
|
-
delta.originPoint = originDelta.originPoint;
|
|
7325
|
-
delta.origin = originDelta.origin;
|
|
7326
|
-
}
|
|
7327
|
-
|
|
7328
7328
|
function isAxisDeltaZero(delta) {
|
|
7329
7329
|
return delta.translate === 0 && delta.scale === 1;
|
|
7330
7330
|
}
|
|
@@ -7466,23 +7466,10 @@
|
|
|
7466
7466
|
};
|
|
7467
7467
|
}
|
|
7468
7468
|
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
const start = time.now();
|
|
7474
|
-
const checkElapsed = ({ timestamp }) => {
|
|
7475
|
-
const elapsed = timestamp - start;
|
|
7476
|
-
if (elapsed >= timeout) {
|
|
7477
|
-
cancelFrame(checkElapsed);
|
|
7478
|
-
callback(elapsed - timeout);
|
|
7479
|
-
}
|
|
7480
|
-
};
|
|
7481
|
-
frame.setup(checkElapsed, true);
|
|
7482
|
-
return () => cancelFrame(checkElapsed);
|
|
7483
|
-
}
|
|
7484
|
-
function delayInSeconds(callback, timeout) {
|
|
7485
|
-
return delay(callback, secondsToMilliseconds(timeout));
|
|
7469
|
+
function animateSingleValue(value, keyframes, options) {
|
|
7470
|
+
const motionValue$1 = isMotionValue(value) ? value : motionValue(value);
|
|
7471
|
+
motionValue$1.start(animateMotionValue("", motionValue$1, keyframes, options));
|
|
7472
|
+
return motionValue$1.animation;
|
|
7486
7473
|
}
|
|
7487
7474
|
|
|
7488
7475
|
function addDomEvent(target, eventName, handler, options = { passive: true }) {
|
|
@@ -7490,19 +7477,6 @@
|
|
|
7490
7477
|
return () => target.removeEventListener(eventName, handler);
|
|
7491
7478
|
}
|
|
7492
7479
|
|
|
7493
|
-
/**
|
|
7494
|
-
* If the provided value is a MotionValue, this returns the actual value, otherwise just the value itself
|
|
7495
|
-
*/
|
|
7496
|
-
function resolveMotionValue(value) {
|
|
7497
|
-
return isMotionValue(value) ? value.get() : value;
|
|
7498
|
-
}
|
|
7499
|
-
|
|
7500
|
-
function animateSingleValue(value, keyframes, options) {
|
|
7501
|
-
const motionValue$1 = isMotionValue(value) ? value : motionValue(value);
|
|
7502
|
-
motionValue$1.start(animateMotionValue("", motionValue$1, keyframes, options));
|
|
7503
|
-
return motionValue$1.animation;
|
|
7504
|
-
}
|
|
7505
|
-
|
|
7506
7480
|
const compareByDepth = (a, b) => a.depth - b.depth;
|
|
7507
7481
|
|
|
7508
7482
|
class FlatTree {
|
|
@@ -7525,6 +7499,32 @@
|
|
|
7525
7499
|
}
|
|
7526
7500
|
}
|
|
7527
7501
|
|
|
7502
|
+
/**
|
|
7503
|
+
* Timeout defined in ms
|
|
7504
|
+
*/
|
|
7505
|
+
function delay(callback, timeout) {
|
|
7506
|
+
const start = time.now();
|
|
7507
|
+
const checkElapsed = ({ timestamp }) => {
|
|
7508
|
+
const elapsed = timestamp - start;
|
|
7509
|
+
if (elapsed >= timeout) {
|
|
7510
|
+
cancelFrame(checkElapsed);
|
|
7511
|
+
callback(elapsed - timeout);
|
|
7512
|
+
}
|
|
7513
|
+
};
|
|
7514
|
+
frame.setup(checkElapsed, true);
|
|
7515
|
+
return () => cancelFrame(checkElapsed);
|
|
7516
|
+
}
|
|
7517
|
+
function delayInSeconds(callback, timeout) {
|
|
7518
|
+
return delay(callback, secondsToMilliseconds(timeout));
|
|
7519
|
+
}
|
|
7520
|
+
|
|
7521
|
+
/**
|
|
7522
|
+
* If the provided value is a MotionValue, this returns the actual value, otherwise just the value itself
|
|
7523
|
+
*/
|
|
7524
|
+
function resolveMotionValue(value) {
|
|
7525
|
+
return isMotionValue(value) ? value.get() : value;
|
|
7526
|
+
}
|
|
7527
|
+
|
|
7528
7528
|
class NodeStack {
|
|
7529
7529
|
constructor() {
|
|
7530
7530
|
this.members = [];
|
|
@@ -9246,29 +9246,6 @@
|
|
|
9246
9246
|
checkIsScrollRoot: () => true,
|
|
9247
9247
|
});
|
|
9248
9248
|
|
|
9249
|
-
const rootProjectionNode = {
|
|
9250
|
-
current: undefined,
|
|
9251
|
-
};
|
|
9252
|
-
const HTMLProjectionNode = createProjectionNode$1({
|
|
9253
|
-
measureScroll: (instance) => ({
|
|
9254
|
-
x: instance.scrollLeft,
|
|
9255
|
-
y: instance.scrollTop,
|
|
9256
|
-
}),
|
|
9257
|
-
defaultParent: () => {
|
|
9258
|
-
if (!rootProjectionNode.current) {
|
|
9259
|
-
const documentNode = new DocumentProjectionNode({});
|
|
9260
|
-
documentNode.mount(window);
|
|
9261
|
-
documentNode.setOptions({ layoutScroll: true });
|
|
9262
|
-
rootProjectionNode.current = documentNode;
|
|
9263
|
-
}
|
|
9264
|
-
return rootProjectionNode.current;
|
|
9265
|
-
},
|
|
9266
|
-
resetTransform: (instance, value) => {
|
|
9267
|
-
instance.style.transform = value !== undefined ? value : "none";
|
|
9268
|
-
},
|
|
9269
|
-
checkIsScrollRoot: (instance) => Boolean(window.getComputedStyle(instance).position === "fixed"),
|
|
9270
|
-
});
|
|
9271
|
-
|
|
9272
9249
|
const notify = (node) => !node.isLayoutDirty && node.willUpdate(false);
|
|
9273
9250
|
function nodeGroup() {
|
|
9274
9251
|
const nodes = new Set();
|
|
@@ -9292,6 +9269,29 @@
|
|
|
9292
9269
|
};
|
|
9293
9270
|
}
|
|
9294
9271
|
|
|
9272
|
+
const rootProjectionNode = {
|
|
9273
|
+
current: undefined,
|
|
9274
|
+
};
|
|
9275
|
+
const HTMLProjectionNode = createProjectionNode$1({
|
|
9276
|
+
measureScroll: (instance) => ({
|
|
9277
|
+
x: instance.scrollLeft,
|
|
9278
|
+
y: instance.scrollTop,
|
|
9279
|
+
}),
|
|
9280
|
+
defaultParent: () => {
|
|
9281
|
+
if (!rootProjectionNode.current) {
|
|
9282
|
+
const documentNode = new DocumentProjectionNode({});
|
|
9283
|
+
documentNode.mount(window);
|
|
9284
|
+
documentNode.setOptions({ layoutScroll: true });
|
|
9285
|
+
rootProjectionNode.current = documentNode;
|
|
9286
|
+
}
|
|
9287
|
+
return rootProjectionNode.current;
|
|
9288
|
+
},
|
|
9289
|
+
resetTransform: (instance, value) => {
|
|
9290
|
+
instance.style.transform = value !== undefined ? value : "none";
|
|
9291
|
+
},
|
|
9292
|
+
checkIsScrollRoot: (instance) => Boolean(window.getComputedStyle(instance).position === "fixed"),
|
|
9293
|
+
});
|
|
9294
|
+
|
|
9295
9295
|
const LAYOUT_SELECTOR = "[data-layout], [data-layout-id]";
|
|
9296
9296
|
function getLayoutElements(scope) {
|
|
9297
9297
|
const elements = Array.from(scope.querySelectorAll(LAYOUT_SELECTOR));
|
|
@@ -9308,93 +9308,6 @@
|
|
|
9308
9308
|
return (element.hasAttribute("data-layout") ||
|
|
9309
9309
|
element.hasAttribute("data-layout-id"));
|
|
9310
9310
|
}
|
|
9311
|
-
/**
|
|
9312
|
-
* Track layout elements before mutation.
|
|
9313
|
-
* Does NOT measure bounds - that's handled by the projection system via willUpdate().
|
|
9314
|
-
*/
|
|
9315
|
-
function trackLayoutElements(scope) {
|
|
9316
|
-
const elements = getLayoutElements(scope);
|
|
9317
|
-
const records = new Map();
|
|
9318
|
-
for (const element of elements) {
|
|
9319
|
-
records.set(element, {
|
|
9320
|
-
element,
|
|
9321
|
-
parentElement: element.parentElement,
|
|
9322
|
-
nextSibling: element.nextSibling,
|
|
9323
|
-
layoutId: getLayoutId(element),
|
|
9324
|
-
});
|
|
9325
|
-
}
|
|
9326
|
-
return records;
|
|
9327
|
-
}
|
|
9328
|
-
/**
|
|
9329
|
-
* Compare before/after records to detect entering/exiting/persisting elements
|
|
9330
|
-
*/
|
|
9331
|
-
function detectMutations(beforeRecords, scope) {
|
|
9332
|
-
const afterElements = new Set(getLayoutElements(scope));
|
|
9333
|
-
const beforeElements = new Set(beforeRecords.keys());
|
|
9334
|
-
const entering = [];
|
|
9335
|
-
const exiting = [];
|
|
9336
|
-
const persisting = [];
|
|
9337
|
-
const sharedEntering = new Map();
|
|
9338
|
-
const sharedExiting = new Map();
|
|
9339
|
-
// Find exiting elements (were in before, not in after)
|
|
9340
|
-
for (const element of beforeElements) {
|
|
9341
|
-
if (!afterElements.has(element)) {
|
|
9342
|
-
const record = beforeRecords.get(element);
|
|
9343
|
-
exiting.push({
|
|
9344
|
-
element,
|
|
9345
|
-
parentElement: record.parentElement,
|
|
9346
|
-
nextSibling: record.nextSibling,
|
|
9347
|
-
});
|
|
9348
|
-
if (record.layoutId) {
|
|
9349
|
-
sharedExiting.set(record.layoutId, element);
|
|
9350
|
-
}
|
|
9351
|
-
}
|
|
9352
|
-
}
|
|
9353
|
-
// Find entering and persisting elements
|
|
9354
|
-
for (const element of afterElements) {
|
|
9355
|
-
if (!beforeElements.has(element)) {
|
|
9356
|
-
entering.push(element);
|
|
9357
|
-
const layoutId = getLayoutId(element);
|
|
9358
|
-
if (layoutId) {
|
|
9359
|
-
sharedEntering.set(layoutId, element);
|
|
9360
|
-
}
|
|
9361
|
-
}
|
|
9362
|
-
else {
|
|
9363
|
-
persisting.push(element);
|
|
9364
|
-
}
|
|
9365
|
-
}
|
|
9366
|
-
return {
|
|
9367
|
-
entering,
|
|
9368
|
-
exiting,
|
|
9369
|
-
persisting,
|
|
9370
|
-
sharedEntering,
|
|
9371
|
-
sharedExiting,
|
|
9372
|
-
};
|
|
9373
|
-
}
|
|
9374
|
-
/**
|
|
9375
|
-
* Check if an element is a "root" entering element (no entering ancestors)
|
|
9376
|
-
*/
|
|
9377
|
-
function isRootEnteringElement(element, allEntering) {
|
|
9378
|
-
let parent = element.parentElement;
|
|
9379
|
-
while (parent) {
|
|
9380
|
-
if (allEntering.has(parent))
|
|
9381
|
-
return false;
|
|
9382
|
-
parent = parent.parentElement;
|
|
9383
|
-
}
|
|
9384
|
-
return true;
|
|
9385
|
-
}
|
|
9386
|
-
/**
|
|
9387
|
-
* Check if an element is a "root" exiting element (no exiting ancestors)
|
|
9388
|
-
*/
|
|
9389
|
-
function isRootExitingElement(element, allExiting) {
|
|
9390
|
-
let parent = element.parentElement;
|
|
9391
|
-
while (parent) {
|
|
9392
|
-
if (allExiting.has(parent))
|
|
9393
|
-
return false;
|
|
9394
|
-
parent = parent.parentElement;
|
|
9395
|
-
}
|
|
9396
|
-
return true;
|
|
9397
|
-
}
|
|
9398
9311
|
|
|
9399
9312
|
let scaleCorrectorAdded = false;
|
|
9400
9313
|
/**
|
|
@@ -9468,6 +9381,11 @@
|
|
|
9468
9381
|
transition: nodeTransition,
|
|
9469
9382
|
...options,
|
|
9470
9383
|
});
|
|
9384
|
+
// Re-mount the node if it was previously unmounted
|
|
9385
|
+
// This re-adds it to root.nodes so didUpdate() will process it
|
|
9386
|
+
if (!existingNode.instance) {
|
|
9387
|
+
existingNode.mount(element);
|
|
9388
|
+
}
|
|
9471
9389
|
return { node: existingNode, visualElement };
|
|
9472
9390
|
}
|
|
9473
9391
|
// No existing node - create a new one
|
|
@@ -9559,10 +9477,16 @@
|
|
|
9559
9477
|
return "both";
|
|
9560
9478
|
}
|
|
9561
9479
|
/**
|
|
9562
|
-
* Clean up projection nodes
|
|
9480
|
+
* Clean up projection nodes for specific elements.
|
|
9481
|
+
* If elementsToCleanup is provided, only those elements are cleaned up.
|
|
9482
|
+
* If not provided, all nodes are cleaned up.
|
|
9483
|
+
*
|
|
9484
|
+
* This allows persisting elements to keep their nodes between animations,
|
|
9485
|
+
* matching React's behavior where nodes persist for elements that remain in the DOM.
|
|
9563
9486
|
*/
|
|
9564
|
-
function cleanupProjectionTree(context) {
|
|
9565
|
-
|
|
9487
|
+
function cleanupProjectionTree(context, elementsToCleanup) {
|
|
9488
|
+
const elementsToProcess = [...context.nodes.entries()];
|
|
9489
|
+
for (const [element, node] of elementsToProcess) {
|
|
9566
9490
|
context.group.remove(node);
|
|
9567
9491
|
node.unmount();
|
|
9568
9492
|
// Only clear from activeProjectionNodes if this is still the active node.
|
|
@@ -9570,9 +9494,9 @@
|
|
|
9570
9494
|
if (activeProjectionNodes.get(element) === node) {
|
|
9571
9495
|
activeProjectionNodes.delete(element);
|
|
9572
9496
|
}
|
|
9497
|
+
context.nodes.delete(element);
|
|
9498
|
+
context.visualElements.delete(element);
|
|
9573
9499
|
}
|
|
9574
|
-
context.nodes.clear();
|
|
9575
|
-
context.visualElements.clear();
|
|
9576
9500
|
}
|
|
9577
9501
|
|
|
9578
9502
|
class LayoutAnimationBuilder {
|
|
@@ -9589,22 +9513,8 @@
|
|
|
9589
9513
|
// Queue execution on microtask to allow builder methods to be called
|
|
9590
9514
|
queueMicrotask(() => this.execute());
|
|
9591
9515
|
}
|
|
9592
|
-
|
|
9593
|
-
this.
|
|
9594
|
-
this.enterOptions = options;
|
|
9595
|
-
return this;
|
|
9596
|
-
}
|
|
9597
|
-
exit(keyframes, options) {
|
|
9598
|
-
this.exitKeyframes = keyframes;
|
|
9599
|
-
this.exitOptions = options;
|
|
9600
|
-
return this;
|
|
9601
|
-
}
|
|
9602
|
-
shared(layoutIdOrOptions, options) {
|
|
9603
|
-
if (typeof layoutIdOrOptions === "string") {
|
|
9604
|
-
this.sharedTransitions.set(layoutIdOrOptions, options);
|
|
9605
|
-
}
|
|
9606
|
-
// For now, we ignore default shared options as the projection system
|
|
9607
|
-
// handles shared transitions automatically
|
|
9516
|
+
shared(id, options) {
|
|
9517
|
+
this.sharedTransitions.set(id, options);
|
|
9608
9518
|
return this;
|
|
9609
9519
|
}
|
|
9610
9520
|
then(onfulfilled, onrejected) {
|
|
@@ -9614,200 +9524,67 @@
|
|
|
9614
9524
|
if (this.executed)
|
|
9615
9525
|
return;
|
|
9616
9526
|
this.executed = true;
|
|
9617
|
-
const animations = [];
|
|
9618
9527
|
let context;
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
// Reattach exiting elements that are NOT part of shared transitions
|
|
9646
|
-
// Shared elements are handled by the projection system via resumeFrom
|
|
9647
|
-
const nonSharedExiting = mutationResult.exiting.filter(({ element }) => {
|
|
9648
|
-
const layoutId = element.getAttribute("data-layout-id");
|
|
9649
|
-
return !layoutId || !mutationResult.sharedEntering.has(layoutId);
|
|
9650
|
-
});
|
|
9651
|
-
this.reattachExitingElements(nonSharedExiting, context);
|
|
9652
|
-
// Build projection nodes for entering elements
|
|
9653
|
-
if (mutationResult.entering.length > 0) {
|
|
9654
|
-
context = buildProjectionTree(mutationResult.entering, context, this.getBuildOptions());
|
|
9655
|
-
}
|
|
9656
|
-
// Also ensure persisting elements have nodes if context didn't exist
|
|
9657
|
-
if (!context && mutationResult.persisting.length > 0) {
|
|
9658
|
-
context = buildProjectionTree(mutationResult.persisting, undefined, this.getBuildOptions());
|
|
9659
|
-
}
|
|
9660
|
-
// Build set of shared exiting elements to exclude from animation collection
|
|
9661
|
-
// Their nodes are still in the tree for resumeFrom relationship, but we don't animate them
|
|
9662
|
-
const sharedExitingElements = new Set();
|
|
9663
|
-
for (const [layoutId] of mutationResult.sharedEntering) {
|
|
9664
|
-
const exitingElement = mutationResult.sharedExiting.get(layoutId);
|
|
9665
|
-
if (exitingElement) {
|
|
9666
|
-
sharedExitingElements.add(exitingElement);
|
|
9667
|
-
// Remove the exiting node from the shared stack so that crossfade
|
|
9668
|
-
// doesn't trigger. When an element is removed from the DOM, it can't
|
|
9669
|
-
// participate in crossfade (no element to fade out). The entering
|
|
9670
|
-
// element still has resumeFrom set for position morphing.
|
|
9671
|
-
const exitingNode = context?.nodes.get(exitingElement);
|
|
9672
|
-
if (exitingNode) {
|
|
9673
|
-
const stack = exitingNode.getStack();
|
|
9674
|
-
if (stack) {
|
|
9675
|
-
stack.remove(exitingNode);
|
|
9676
|
-
}
|
|
9677
|
-
}
|
|
9678
|
-
}
|
|
9679
|
-
}
|
|
9680
|
-
// Phase 4: Animate
|
|
9681
|
-
if (context) {
|
|
9682
|
-
// Trigger layout animations via didUpdate
|
|
9683
|
-
context.root.didUpdate();
|
|
9684
|
-
// Wait for animations to be created (they're scheduled via frame.update)
|
|
9685
|
-
await new Promise((resolve) => frame.postRender(() => resolve()));
|
|
9686
|
-
// Collect layout animations from projection nodes (excluding shared exiting elements)
|
|
9687
|
-
for (const [element, node] of context.nodes.entries()) {
|
|
9688
|
-
if (sharedExitingElements.has(element))
|
|
9689
|
-
continue;
|
|
9690
|
-
if (node.currentAnimation) {
|
|
9691
|
-
animations.push(node.currentAnimation);
|
|
9692
|
-
}
|
|
9693
|
-
}
|
|
9694
|
-
// Apply enter keyframes to root entering elements
|
|
9695
|
-
if (this.enterKeyframes) {
|
|
9696
|
-
const enterAnimations = this.animateEntering(mutationResult, context);
|
|
9697
|
-
animations.push(...enterAnimations);
|
|
9698
|
-
}
|
|
9699
|
-
// Apply exit keyframes to root exiting elements
|
|
9700
|
-
if (this.exitKeyframes) {
|
|
9701
|
-
const exitAnimations = this.animateExiting(mutationResult, context);
|
|
9702
|
-
animations.push(...exitAnimations);
|
|
9703
|
-
}
|
|
9704
|
-
}
|
|
9705
|
-
// Create and return group animation
|
|
9706
|
-
const groupAnimation = new GroupAnimation(animations);
|
|
9707
|
-
// Phase 5: Setup cleanup on complete
|
|
9708
|
-
groupAnimation.finished.then(() => {
|
|
9709
|
-
// Only clean up non-shared exiting elements (those we reattached)
|
|
9710
|
-
this.cleanupExitingElements(nonSharedExiting);
|
|
9711
|
-
if (context) {
|
|
9712
|
-
cleanupProjectionTree(context);
|
|
9713
|
-
}
|
|
9714
|
-
});
|
|
9715
|
-
this.notifyReady(groupAnimation);
|
|
9528
|
+
// Phase 1: Pre-mutation - Build projection tree and take snapshots
|
|
9529
|
+
const beforeElements = getLayoutElements(this.scope);
|
|
9530
|
+
if (beforeElements.length > 0) {
|
|
9531
|
+
context = buildProjectionTree(beforeElements, undefined, this.getBuildOptions());
|
|
9532
|
+
context.root.startUpdate();
|
|
9533
|
+
for (const node of context.nodes.values()) {
|
|
9534
|
+
node.isLayoutDirty = false;
|
|
9535
|
+
node.willUpdate();
|
|
9536
|
+
}
|
|
9537
|
+
}
|
|
9538
|
+
// Phase 2: Execute DOM update
|
|
9539
|
+
this.updateDom();
|
|
9540
|
+
// Phase 3: Post-mutation - Compare before/after elements
|
|
9541
|
+
const afterElements = getLayoutElements(this.scope);
|
|
9542
|
+
const beforeSet = new Set(beforeElements);
|
|
9543
|
+
const afterSet = new Set(afterElements);
|
|
9544
|
+
const entering = afterElements.filter((el) => !beforeSet.has(el));
|
|
9545
|
+
const exiting = beforeElements.filter((el) => !afterSet.has(el));
|
|
9546
|
+
// Build projection nodes for entering elements
|
|
9547
|
+
if (entering.length > 0) {
|
|
9548
|
+
context = buildProjectionTree(entering, context, this.getBuildOptions());
|
|
9549
|
+
}
|
|
9550
|
+
// No layout elements - return empty animation
|
|
9551
|
+
if (!context) {
|
|
9552
|
+
this.notifyReady(new GroupAnimation([]));
|
|
9553
|
+
return;
|
|
9716
9554
|
}
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
}
|
|
9722
|
-
throw error;
|
|
9555
|
+
// Handle shared elements
|
|
9556
|
+
for (const element of exiting) {
|
|
9557
|
+
const node = context.nodes.get(element);
|
|
9558
|
+
node?.getStack()?.remove(node);
|
|
9723
9559
|
}
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
return {
|
|
9727
|
-
defaultTransition: this.defaultOptions || { duration: 0.3, ease: "easeOut" },
|
|
9728
|
-
sharedTransitions: this.sharedTransitions.size > 0 ? this.sharedTransitions : undefined,
|
|
9729
|
-
};
|
|
9730
|
-
}
|
|
9731
|
-
reattachExitingElements(exiting, context) {
|
|
9732
|
-
for (const { element, parentElement, nextSibling } of exiting) {
|
|
9733
|
-
// Check if parent still exists in DOM
|
|
9734
|
-
if (!parentElement.isConnected)
|
|
9735
|
-
continue;
|
|
9736
|
-
// Get bounds from projection node snapshot (measured correctly via projection system)
|
|
9737
|
-
const node = context?.nodes.get(element);
|
|
9738
|
-
const snapshot = node?.snapshot;
|
|
9739
|
-
if (!snapshot)
|
|
9740
|
-
continue;
|
|
9741
|
-
const { layoutBox } = snapshot;
|
|
9742
|
-
// Reattach element
|
|
9743
|
-
if (nextSibling && nextSibling.parentNode === parentElement) {
|
|
9744
|
-
parentElement.insertBefore(element, nextSibling);
|
|
9745
|
-
}
|
|
9746
|
-
else {
|
|
9747
|
-
parentElement.appendChild(element);
|
|
9748
|
-
}
|
|
9749
|
-
// Apply absolute positioning to prevent layout shift
|
|
9750
|
-
// Use layoutBox from projection system which has transform-free measurements
|
|
9751
|
-
const htmlElement = element;
|
|
9752
|
-
htmlElement.style.position = "absolute";
|
|
9753
|
-
htmlElement.style.top = `${layoutBox.y.min}px`;
|
|
9754
|
-
htmlElement.style.left = `${layoutBox.x.min}px`;
|
|
9755
|
-
htmlElement.style.width = `${layoutBox.x.max - layoutBox.x.min}px`;
|
|
9756
|
-
htmlElement.style.height = `${layoutBox.y.max - layoutBox.y.min}px`;
|
|
9757
|
-
htmlElement.style.margin = "0";
|
|
9758
|
-
htmlElement.style.pointerEvents = "none";
|
|
9560
|
+
for (const element of entering) {
|
|
9561
|
+
context.nodes.get(element)?.promote();
|
|
9759
9562
|
}
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
if (element.parentElement) {
|
|
9764
|
-
element.parentElement.removeChild(element);
|
|
9765
|
-
}
|
|
9766
|
-
}
|
|
9767
|
-
}
|
|
9768
|
-
animateEntering(mutationResult, context) {
|
|
9769
|
-
const enteringSet = new Set(mutationResult.entering);
|
|
9770
|
-
// Find root entering elements
|
|
9771
|
-
const rootEntering = mutationResult.entering.filter((el) => isRootEnteringElement(el, enteringSet));
|
|
9563
|
+
// Phase 4: Animate
|
|
9564
|
+
context.root.didUpdate();
|
|
9565
|
+
await new Promise((resolve) => frame.postRender(() => resolve()));
|
|
9772
9566
|
const animations = [];
|
|
9773
|
-
for (const
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
continue;
|
|
9777
|
-
// If entering with opacity: 1, start from opacity: 0
|
|
9778
|
-
const keyframes = { ...this.enterKeyframes };
|
|
9779
|
-
if (keyframes.opacity !== undefined) {
|
|
9780
|
-
const targetOpacity = Array.isArray(keyframes.opacity)
|
|
9781
|
-
? keyframes.opacity[keyframes.opacity.length - 1]
|
|
9782
|
-
: keyframes.opacity;
|
|
9783
|
-
if (targetOpacity === 1) {
|
|
9784
|
-
element.style.opacity = "0";
|
|
9785
|
-
}
|
|
9567
|
+
for (const node of context.nodes.values()) {
|
|
9568
|
+
if (node.currentAnimation) {
|
|
9569
|
+
animations.push(node.currentAnimation);
|
|
9786
9570
|
}
|
|
9787
|
-
const options = this.enterOptions || this.defaultOptions || {};
|
|
9788
|
-
const enterAnims = animateTarget(visualElement, keyframes, {
|
|
9789
|
-
transitionOverride: options,
|
|
9790
|
-
});
|
|
9791
|
-
animations.push(...enterAnims);
|
|
9792
9571
|
}
|
|
9793
|
-
|
|
9572
|
+
const groupAnimation = new GroupAnimation(animations);
|
|
9573
|
+
groupAnimation.finished.then(() => {
|
|
9574
|
+
cleanupProjectionTree(context);
|
|
9575
|
+
});
|
|
9576
|
+
this.notifyReady(groupAnimation);
|
|
9794
9577
|
}
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
const exitAnims = animateTarget(visualElement, this.exitKeyframes, {
|
|
9806
|
-
transitionOverride: options,
|
|
9807
|
-
});
|
|
9808
|
-
animations.push(...exitAnims);
|
|
9809
|
-
}
|
|
9810
|
-
return animations;
|
|
9578
|
+
getBuildOptions() {
|
|
9579
|
+
return {
|
|
9580
|
+
defaultTransition: this.defaultOptions || {
|
|
9581
|
+
duration: 0.3,
|
|
9582
|
+
ease: "easeOut",
|
|
9583
|
+
},
|
|
9584
|
+
sharedTransitions: this.sharedTransitions.size > 0
|
|
9585
|
+
? this.sharedTransitions
|
|
9586
|
+
: undefined,
|
|
9587
|
+
};
|
|
9811
9588
|
}
|
|
9812
9589
|
}
|
|
9813
9590
|
/**
|
|
@@ -9832,47 +9609,6 @@
|
|
|
9832
9609
|
};
|
|
9833
9610
|
}
|
|
9834
9611
|
|
|
9835
|
-
/**
|
|
9836
|
-
* Animate layout changes within a DOM tree.
|
|
9837
|
-
*
|
|
9838
|
-
* @example
|
|
9839
|
-
* ```typescript
|
|
9840
|
-
* // Basic usage - animates all elements with data-layout or data-layout-id
|
|
9841
|
-
* await animateLayout(() => {
|
|
9842
|
-
* container.innerHTML = newContent
|
|
9843
|
-
* })
|
|
9844
|
-
*
|
|
9845
|
-
* // With scope - only animates within the container
|
|
9846
|
-
* await animateLayout(".container", () => {
|
|
9847
|
-
* updateContent()
|
|
9848
|
-
* })
|
|
9849
|
-
*
|
|
9850
|
-
* // With options
|
|
9851
|
-
* await animateLayout(() => update(), { duration: 0.5 })
|
|
9852
|
-
*
|
|
9853
|
-
* // Builder pattern for enter/exit animations
|
|
9854
|
-
* animateLayout(".cards", () => {
|
|
9855
|
-
* container.innerHTML = newCards
|
|
9856
|
-
* }, { duration: 0.3 })
|
|
9857
|
-
* .enter({ opacity: 1, scale: 1 }, { duration: 0.2 })
|
|
9858
|
-
* .exit({ opacity: 0, scale: 0.8 })
|
|
9859
|
-
* .shared("hero", { type: "spring" })
|
|
9860
|
-
* ```
|
|
9861
|
-
*
|
|
9862
|
-
* Elements are animated if they have:
|
|
9863
|
-
* - `data-layout` attribute (layout animation only)
|
|
9864
|
-
* - `data-layout-id` attribute (shared element transitions)
|
|
9865
|
-
*
|
|
9866
|
-
* @param scopeOrUpdateDom - Either a scope selector/element, or the DOM update function
|
|
9867
|
-
* @param updateDomOrOptions - Either the DOM update function or animation options
|
|
9868
|
-
* @param options - Animation options (when scope is provided)
|
|
9869
|
-
* @returns A builder that resolves to animation controls
|
|
9870
|
-
*/
|
|
9871
|
-
function unstable_animateLayout(scopeOrUpdateDom, updateDomOrOptions, options) {
|
|
9872
|
-
const { scope, updateDom, defaultOptions } = parseAnimateLayoutArgs(scopeOrUpdateDom, updateDomOrOptions, options);
|
|
9873
|
-
return new LayoutAnimationBuilder(scope, updateDom, defaultOptions);
|
|
9874
|
-
}
|
|
9875
|
-
|
|
9876
9612
|
/**
|
|
9877
9613
|
* @deprecated
|
|
9878
9614
|
*
|
|
@@ -11164,6 +10900,7 @@
|
|
|
11164
10900
|
exports.observeTimeline = observeTimeline;
|
|
11165
10901
|
exports.optimizedAppearDataAttribute = optimizedAppearDataAttribute;
|
|
11166
10902
|
exports.optimizedAppearDataId = optimizedAppearDataId;
|
|
10903
|
+
exports.parseAnimateLayoutArgs = parseAnimateLayoutArgs;
|
|
11167
10904
|
exports.parseCSSVariable = parseCSSVariable;
|
|
11168
10905
|
exports.parseValueFromTransform = parseValueFromTransform;
|
|
11169
10906
|
exports.percent = percent;
|
|
@@ -11233,7 +10970,6 @@
|
|
|
11233
10970
|
exports.transformValue = transformValue;
|
|
11234
10971
|
exports.transformValueTypes = transformValueTypes;
|
|
11235
10972
|
exports.translateAxis = translateAxis;
|
|
11236
|
-
exports.unstable_animateLayout = unstable_animateLayout;
|
|
11237
10973
|
exports.updateMotionValuesFromProps = updateMotionValuesFromProps;
|
|
11238
10974
|
exports.variantPriorityOrder = variantPriorityOrder;
|
|
11239
10975
|
exports.variantProps = variantProps;
|