motion 13.5.0 → 14.0.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 +260 -442
- package/dist/motion.js +1 -1
- package/package.json +3 -3
package/dist/motion.dev.js
CHANGED
|
@@ -4381,36 +4381,29 @@
|
|
|
4381
4381
|
return state;
|
|
4382
4382
|
}
|
|
4383
4383
|
function resolveVariantFromProps(props, definition, custom, visualElement) {
|
|
4384
|
+
const resolveFunction = (def) => typeof def === "function"
|
|
4385
|
+
? def(custom !== undefined ? custom : props.custom, ...getValueState(visualElement))
|
|
4386
|
+
: def;
|
|
4384
4387
|
/**
|
|
4385
|
-
*
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
const [current, velocity] = getValueState(visualElement);
|
|
4389
|
-
definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
|
|
4390
|
-
}
|
|
4391
|
-
/**
|
|
4392
|
-
* If the variant definition is a variant label, or
|
|
4393
|
-
* the function returned a variant label, resolve.
|
|
4388
|
+
* Resolve a function, then a variant label (which the function may have
|
|
4389
|
+
* returned), then a function again as the label may point to one. The
|
|
4390
|
+
* final function can only return a target object.
|
|
4394
4391
|
*/
|
|
4392
|
+
definition = resolveFunction(definition);
|
|
4395
4393
|
if (typeof definition === "string") {
|
|
4396
4394
|
definition = props.variants && props.variants[definition];
|
|
4397
4395
|
}
|
|
4398
|
-
|
|
4399
|
-
* At this point we've resolved both functions and variant labels,
|
|
4400
|
-
* but the resolved variant label might itself have been a function.
|
|
4401
|
-
* If so, resolve. This can only have returned a valid target object.
|
|
4402
|
-
*/
|
|
4403
|
-
if (typeof definition === "function") {
|
|
4404
|
-
const [current, velocity] = getValueState(visualElement);
|
|
4405
|
-
definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
|
|
4406
|
-
}
|
|
4407
|
-
return definition;
|
|
4396
|
+
return resolveFunction(definition);
|
|
4408
4397
|
}
|
|
4409
4398
|
|
|
4410
4399
|
function resolveVariant(visualElement, definition, custom) {
|
|
4411
|
-
|
|
4412
|
-
return resolveVariantFromProps(props, definition, custom !== undefined ? custom : props.custom, visualElement);
|
|
4400
|
+
return resolveVariantFromProps(visualElement.getProps(), definition, custom, visualElement);
|
|
4413
4401
|
}
|
|
4402
|
+
/**
|
|
4403
|
+
* Exit variants resolve with AnimatePresence's custom, every other type
|
|
4404
|
+
* with the element's own.
|
|
4405
|
+
*/
|
|
4406
|
+
const getTypeCustom = (visualElement, type) => type === "exit" ? visualElement.presenceContext?.custom : undefined;
|
|
4414
4407
|
|
|
4415
4408
|
const positionalKeys = new Set([
|
|
4416
4409
|
"width",
|
|
@@ -4493,7 +4486,7 @@
|
|
|
4493
4486
|
* had been set to true in the meantime.
|
|
4494
4487
|
*/
|
|
4495
4488
|
function shouldBlockAnimation({ protectedKeys, needsAnimating }, key) {
|
|
4496
|
-
const shouldBlock =
|
|
4489
|
+
const shouldBlock = key in protectedKeys && !needsAnimating[key];
|
|
4497
4490
|
needsAnimating[key] = false;
|
|
4498
4491
|
return shouldBlock;
|
|
4499
4492
|
}
|
|
@@ -4508,9 +4501,7 @@
|
|
|
4508
4501
|
if (transitionOverride)
|
|
4509
4502
|
transition = transitionOverride;
|
|
4510
4503
|
const animations = [];
|
|
4511
|
-
const animationTypeState = type &&
|
|
4512
|
-
visualElement.animationState &&
|
|
4513
|
-
visualElement.animationState.getState()[type];
|
|
4504
|
+
const animationTypeState = type && visualElement.animationState?.getState()[type];
|
|
4514
4505
|
const path = transition?.path;
|
|
4515
4506
|
if (path) {
|
|
4516
4507
|
// path mutates `target` to claim x/y; loop below skips them.
|
|
@@ -4584,75 +4575,46 @@
|
|
|
4584
4575
|
}
|
|
4585
4576
|
|
|
4586
4577
|
function animateVariant(visualElement, variant, options = {}) {
|
|
4587
|
-
const resolved = resolveVariant(visualElement, variant, options.type
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
return animateChildren(visualElement, variant, forwardDelay, delayChildren, staggerChildren, staggerDirection, options);
|
|
4609
|
-
}
|
|
4610
|
-
: () => Promise.resolve();
|
|
4578
|
+
const resolved = resolveVariant(visualElement, variant, getTypeCustom(visualElement, options.type));
|
|
4579
|
+
const transition = options.transitionOverride ||
|
|
4580
|
+
(resolved?.transition ?? (visualElement.getDefaultTransition() || {}));
|
|
4581
|
+
const getAnimation = () => Promise.all(resolved ? animateTarget(visualElement, resolved, options) : []);
|
|
4582
|
+
const getChildAnimations = (delay = 0) => {
|
|
4583
|
+
const { variantChildren } = visualElement;
|
|
4584
|
+
const { delayChildren = 0, staggerChildren, staggerDirection, } = transition;
|
|
4585
|
+
const animations = [];
|
|
4586
|
+
variantChildren?.forEach((child) => {
|
|
4587
|
+
child.notify("AnimationStart", variant);
|
|
4588
|
+
animations.push(animateVariant(child, variant, {
|
|
4589
|
+
...options,
|
|
4590
|
+
delay: delay +
|
|
4591
|
+
(typeof delayChildren === "function"
|
|
4592
|
+
? 0
|
|
4593
|
+
: delayChildren) +
|
|
4594
|
+
calcChildStagger(variantChildren, child, delayChildren, staggerChildren, staggerDirection),
|
|
4595
|
+
}).then(() => child.notify("AnimationComplete", variant)));
|
|
4596
|
+
});
|
|
4597
|
+
return Promise.all(animations);
|
|
4598
|
+
};
|
|
4611
4599
|
/**
|
|
4612
|
-
*
|
|
4613
|
-
*
|
|
4600
|
+
* when: "beforeChildren" | "afterChildren" runs this element's animation
|
|
4601
|
+
* and its children's in sequence.
|
|
4614
4602
|
*/
|
|
4615
4603
|
const { when } = transition;
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
?
|
|
4619
|
-
:
|
|
4620
|
-
|
|
4621
|
-
}
|
|
4622
|
-
else {
|
|
4623
|
-
return Promise.all([getAnimation(), getChildAnimations(options.delay)]);
|
|
4624
|
-
}
|
|
4625
|
-
}
|
|
4626
|
-
function animateChildren(visualElement, variant, delay = 0, delayChildren = 0, staggerChildren = 0, staggerDirection = 1, options) {
|
|
4627
|
-
const animations = [];
|
|
4628
|
-
for (const child of visualElement.variantChildren) {
|
|
4629
|
-
child.notify("AnimationStart", variant);
|
|
4630
|
-
animations.push(animateVariant(child, variant, {
|
|
4631
|
-
...options,
|
|
4632
|
-
delay: delay +
|
|
4633
|
-
(typeof delayChildren === "function" ? 0 : delayChildren) +
|
|
4634
|
-
calcChildStagger(visualElement.variantChildren, child, delayChildren, staggerChildren, staggerDirection),
|
|
4635
|
-
}).then(() => child.notify("AnimationComplete", variant)));
|
|
4636
|
-
}
|
|
4637
|
-
return Promise.all(animations);
|
|
4604
|
+
return when
|
|
4605
|
+
? when === "beforeChildren"
|
|
4606
|
+
? getAnimation().then(() => getChildAnimations())
|
|
4607
|
+
: getChildAnimations().then(getAnimation)
|
|
4608
|
+
: Promise.all([getAnimation(), getChildAnimations(options.delay)]);
|
|
4638
4609
|
}
|
|
4639
4610
|
|
|
4640
4611
|
function animateVisualElement(visualElement, definition, options = {}) {
|
|
4641
4612
|
visualElement.notify("AnimationStart", definition);
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
else if (typeof definition === "string") {
|
|
4648
|
-
animation = animateVariant(visualElement, definition, options);
|
|
4649
|
-
}
|
|
4650
|
-
else {
|
|
4651
|
-
const resolvedDefinition = typeof definition === "function"
|
|
4652
|
-
? resolveVariant(visualElement, definition, options.custom)
|
|
4653
|
-
: definition;
|
|
4654
|
-
animation = Promise.all(animateTarget(visualElement, resolvedDefinition, options));
|
|
4655
|
-
}
|
|
4613
|
+
const animation = Array.isArray(definition)
|
|
4614
|
+
? Promise.all(definition.map((variant) => animateVariant(visualElement, variant, options)))
|
|
4615
|
+
: typeof definition === "string"
|
|
4616
|
+
? animateVariant(visualElement, definition, options)
|
|
4617
|
+
: Promise.all(animateTarget(visualElement, resolveVariant(visualElement, definition, options.custom), options));
|
|
4656
4618
|
return animation.then(() => {
|
|
4657
4619
|
visualElement.notify("AnimationComplete", definition);
|
|
4658
4620
|
});
|
|
@@ -5178,7 +5140,12 @@
|
|
|
5178
5140
|
const onRemove = () => {
|
|
5179
5141
|
cancelOnChange();
|
|
5180
5142
|
render && !computed && this.cancel(render);
|
|
5181
|
-
|
|
5143
|
+
/**
|
|
5144
|
+
* A later set() of the same name has already removed this
|
|
5145
|
+
* entry, so leave the one that replaced it.
|
|
5146
|
+
*/
|
|
5147
|
+
this.values.get(name)?.onRemove === onRemove &&
|
|
5148
|
+
this.values.delete(name);
|
|
5182
5149
|
};
|
|
5183
5150
|
this.values.set(name, {
|
|
5184
5151
|
value,
|
|
@@ -5657,24 +5624,35 @@
|
|
|
5657
5624
|
else if (key.startsWith("attr")) {
|
|
5658
5625
|
return addAttrValue(element, state, key, value, convertAttrKey(key));
|
|
5659
5626
|
}
|
|
5660
|
-
|
|
5627
|
+
/**
|
|
5628
|
+
* Transforms and origins aren't CSS properties (bar `x`/`y` in some
|
|
5629
|
+
* browsers), so check them by name rather than `key in element.style`.
|
|
5630
|
+
*/
|
|
5631
|
+
const handler = transformProps.has(key) ||
|
|
5632
|
+
originProps.has(key) ||
|
|
5633
|
+
isCSSVar(key) ||
|
|
5634
|
+
key in element.style
|
|
5635
|
+
? addStyleValue
|
|
5636
|
+
: addAttrValue;
|
|
5661
5637
|
return handler(element, state, key, value);
|
|
5662
5638
|
};
|
|
5663
5639
|
/**
|
|
5664
5640
|
* Reads the current value of `key` from an SVG element as the origin of
|
|
5665
5641
|
* an animation, as the SVG VisualElement does: transforms start from
|
|
5666
5642
|
* their defaults, CSS variables and the few CSS-only properties come from
|
|
5667
|
-
* computed style
|
|
5668
|
-
* and everything else is read from the
|
|
5669
|
-
* (`strokeWidth` -> `stroke-width`) or, failing
|
|
5670
|
-
* (`baseFrequency`).
|
|
5643
|
+
* computed style, falling back to the attribute when that's empty (e.g.
|
|
5644
|
+
* the element isn't rendered), and everything else is read from the
|
|
5645
|
+
* attribute, dash-cased (`strokeWidth` -> `stroke-width`) or, failing
|
|
5646
|
+
* that, as written (`baseFrequency`).
|
|
5671
5647
|
*/
|
|
5672
5648
|
const readSVGValue = (element, key) => {
|
|
5673
5649
|
if (transformProps.has(key)) {
|
|
5674
5650
|
return numberValueTypes[key]?.default || 0;
|
|
5675
5651
|
}
|
|
5676
5652
|
if (isCSSVar(key) || cssStyleProperties.includes(key)) {
|
|
5677
|
-
return readStyleValue(element, key)
|
|
5653
|
+
return (readStyleValue(element, key) ||
|
|
5654
|
+
element.getAttribute(camelToDash(key)) ||
|
|
5655
|
+
0);
|
|
5678
5656
|
}
|
|
5679
5657
|
key = convertAttrKey(key);
|
|
5680
5658
|
return (element.getAttribute(camelToDash(key)) ??
|
|
@@ -8259,8 +8237,20 @@
|
|
|
8259
8237
|
if (this.projection && !this.projection.instance) {
|
|
8260
8238
|
this.projection.mount(instance);
|
|
8261
8239
|
}
|
|
8262
|
-
|
|
8263
|
-
|
|
8240
|
+
/**
|
|
8241
|
+
* Join the closest variant node above, so its variant changes
|
|
8242
|
+
* propagate here, unless inherit={false} cuts the chain.
|
|
8243
|
+
*/
|
|
8244
|
+
if (this.isVariantNode && !this.isControllingVariants) {
|
|
8245
|
+
let node = this;
|
|
8246
|
+
do
|
|
8247
|
+
node = node.props.inherit !== false && node.parent;
|
|
8248
|
+
while (node && !node.isVariantNode);
|
|
8249
|
+
if (node) {
|
|
8250
|
+
const { variantChildren } = node;
|
|
8251
|
+
variantChildren.add(this);
|
|
8252
|
+
this.removeFromVariantTree = () => variantChildren.delete(this);
|
|
8253
|
+
}
|
|
8264
8254
|
}
|
|
8265
8255
|
this.values.forEach((value, key) => this.bindToMotionValue(key, value));
|
|
8266
8256
|
/**
|
|
@@ -8370,9 +8360,11 @@
|
|
|
8370
8360
|
}
|
|
8371
8361
|
sortNodePosition(other) {
|
|
8372
8362
|
/**
|
|
8373
|
-
* If
|
|
8363
|
+
* If either node isn't mounted, or they aren't even of the same type,
|
|
8364
|
+
* we can't compare their document order.
|
|
8374
8365
|
*/
|
|
8375
8366
|
if (!this.current ||
|
|
8367
|
+
!other.current ||
|
|
8376
8368
|
!this.sortInstanceNodePosition ||
|
|
8377
8369
|
this.type !== other.type) {
|
|
8378
8370
|
return 0;
|
|
@@ -8478,24 +8470,6 @@
|
|
|
8478
8470
|
getTransformPagePoint() {
|
|
8479
8471
|
return this.props.transformPagePoint;
|
|
8480
8472
|
}
|
|
8481
|
-
getClosestVariantNode() {
|
|
8482
|
-
return this.isVariantNode
|
|
8483
|
-
? this
|
|
8484
|
-
: this.parent
|
|
8485
|
-
? this.parent.getClosestVariantNode()
|
|
8486
|
-
: undefined;
|
|
8487
|
-
}
|
|
8488
|
-
/**
|
|
8489
|
-
* Add a child visual element to our set of children.
|
|
8490
|
-
*/
|
|
8491
|
-
addVariantChild(child) {
|
|
8492
|
-
const closestVariantNode = this.getClosestVariantNode();
|
|
8493
|
-
if (closestVariantNode) {
|
|
8494
|
-
closestVariantNode.variantChildren &&
|
|
8495
|
-
closestVariantNode.variantChildren.add(child);
|
|
8496
|
-
return () => closestVariantNode.variantChildren.delete(child);
|
|
8497
|
-
}
|
|
8498
|
-
}
|
|
8499
8473
|
/**
|
|
8500
8474
|
* Add a motion value and bind it to this visual element.
|
|
8501
8475
|
*/
|
|
@@ -8590,41 +8564,6 @@
|
|
|
8590
8564
|
setBaseTarget(key, value) {
|
|
8591
8565
|
this.baseTarget[key] = value;
|
|
8592
8566
|
}
|
|
8593
|
-
/**
|
|
8594
|
-
* Find the base target for a value thats been removed from all animation
|
|
8595
|
-
* props.
|
|
8596
|
-
*/
|
|
8597
|
-
getBaseTarget(key) {
|
|
8598
|
-
const { initial } = this.props;
|
|
8599
|
-
let valueFromInitial;
|
|
8600
|
-
if (typeof initial === "string" || typeof initial === "object") {
|
|
8601
|
-
const variant = resolveVariantFromProps(this.props, initial, this.presenceContext?.custom);
|
|
8602
|
-
if (variant) {
|
|
8603
|
-
valueFromInitial = variant[key];
|
|
8604
|
-
}
|
|
8605
|
-
}
|
|
8606
|
-
/**
|
|
8607
|
-
* If this value still exists in the current initial variant, read that.
|
|
8608
|
-
*/
|
|
8609
|
-
if (initial && valueFromInitial !== undefined) {
|
|
8610
|
-
return valueFromInitial;
|
|
8611
|
-
}
|
|
8612
|
-
/**
|
|
8613
|
-
* Alternatively, if this VisualElement config has defined a getBaseTarget
|
|
8614
|
-
* so we can read the value from an alternative source, try that.
|
|
8615
|
-
*/
|
|
8616
|
-
const target = this.getBaseTargetFromProps(this.props, key);
|
|
8617
|
-
if (target !== undefined && !isMotionValue(target))
|
|
8618
|
-
return target;
|
|
8619
|
-
/**
|
|
8620
|
-
* If the value was initially defined on initial, but it doesn't any more,
|
|
8621
|
-
* return undefined. Otherwise return the value as initially read from the DOM.
|
|
8622
|
-
*/
|
|
8623
|
-
return this.initialValues[key] !== undefined &&
|
|
8624
|
-
valueFromInitial === undefined
|
|
8625
|
-
? undefined
|
|
8626
|
-
: this.baseTarget[key];
|
|
8627
|
-
}
|
|
8628
8567
|
on(eventName, callback) {
|
|
8629
8568
|
if (!this.events[eventName]) {
|
|
8630
8569
|
this.events[eventName] = new SubscriptionManager();
|
|
@@ -8929,34 +8868,6 @@
|
|
|
8929
8868
|
}
|
|
8930
8869
|
}
|
|
8931
8870
|
|
|
8932
|
-
const numVariantProps = variantProps.length;
|
|
8933
|
-
/**
|
|
8934
|
-
* Get variant context from a visual element's parent chain.
|
|
8935
|
-
* Uses `any` type for visualElement to avoid circular dependencies.
|
|
8936
|
-
*/
|
|
8937
|
-
function getVariantContext(visualElement) {
|
|
8938
|
-
if (!visualElement)
|
|
8939
|
-
return undefined;
|
|
8940
|
-
if (!visualElement.isControllingVariants) {
|
|
8941
|
-
const context = visualElement.parent
|
|
8942
|
-
? getVariantContext(visualElement.parent) || {}
|
|
8943
|
-
: {};
|
|
8944
|
-
if (visualElement.props.initial !== undefined) {
|
|
8945
|
-
context.initial = visualElement.props.initial;
|
|
8946
|
-
}
|
|
8947
|
-
return context;
|
|
8948
|
-
}
|
|
8949
|
-
const context = {};
|
|
8950
|
-
for (let i = 0; i < numVariantProps; i++) {
|
|
8951
|
-
const name = variantProps[i];
|
|
8952
|
-
const prop = visualElement.props[name];
|
|
8953
|
-
if (isVariantLabel(prop) || prop === false) {
|
|
8954
|
-
context[name] = prop;
|
|
8955
|
-
}
|
|
8956
|
-
}
|
|
8957
|
-
return context;
|
|
8958
|
-
}
|
|
8959
|
-
|
|
8960
8871
|
function shallowCompare(next, prev) {
|
|
8961
8872
|
if (!Array.isArray(prev))
|
|
8962
8873
|
return false;
|
|
@@ -8971,332 +8882,211 @@
|
|
|
8971
8882
|
}
|
|
8972
8883
|
|
|
8973
8884
|
const reversePriorityOrder = [...variantPriorityOrder].reverse();
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8885
|
+
/**
|
|
8886
|
+
* Diffs the element's animation props (one layer per AnimationType, highest
|
|
8887
|
+
* priority wins each value) against the previous call and starts animations
|
|
8888
|
+
* for what changed.
|
|
8889
|
+
*
|
|
8890
|
+
* Uses `any` type for visualElement to avoid circular dependencies. It reads
|
|
8891
|
+
* props, parent, presenceContext, variantChildren, enteringChildren,
|
|
8892
|
+
* manuallyAnimateOnMount, blockInitialAnimation, getValue(),
|
|
8893
|
+
* getBaseTargetFromProps(), baseTarget and initialValues.
|
|
8894
|
+
*/
|
|
8980
8895
|
function createAnimationState(visualElement) {
|
|
8981
|
-
let animate =
|
|
8896
|
+
let animate = (animations) => Promise.all(animations.map(({ animation, options }) => animateVisualElement(visualElement, animation, options)));
|
|
8982
8897
|
let state = createState();
|
|
8983
8898
|
let isInitialRender = true;
|
|
8984
8899
|
/**
|
|
8985
|
-
*
|
|
8986
|
-
*
|
|
8987
|
-
* animateChanges() call after a reset we need to behave like the initial
|
|
8988
|
-
* render for variant-inheritance checks, even though isInitialRender is
|
|
8989
|
-
* already false.
|
|
8900
|
+
* After a reset (StrictMode, Suspense, AnimatePresence re-entry) the next
|
|
8901
|
+
* animateChanges() mounts again, but initial={false} no longer applies.
|
|
8990
8902
|
*/
|
|
8991
8903
|
let wasReset = false;
|
|
8992
|
-
/**
|
|
8993
|
-
* This function will be used to reduce the animation definitions for
|
|
8994
|
-
* each active animation type into an object of resolved values for it.
|
|
8995
|
-
*/
|
|
8996
|
-
const buildResolvedTypeValues = (type) => (acc, definition) => {
|
|
8997
|
-
const resolved = resolveVariant(visualElement, definition, type === "exit"
|
|
8998
|
-
? visualElement.presenceContext?.custom
|
|
8999
|
-
: undefined);
|
|
9000
|
-
if (resolved) {
|
|
9001
|
-
const { transition, transitionEnd, ...target } = resolved;
|
|
9002
|
-
acc = { ...acc, ...target, ...transitionEnd };
|
|
9003
|
-
}
|
|
9004
|
-
return acc;
|
|
9005
|
-
};
|
|
9006
|
-
/**
|
|
9007
|
-
* This just allows us to inject mocked animation functions
|
|
9008
|
-
* @internal
|
|
9009
|
-
*/
|
|
9010
|
-
function setAnimateFunction(makeAnimator) {
|
|
9011
|
-
animate = makeAnimator(visualElement);
|
|
9012
|
-
}
|
|
9013
|
-
/**
|
|
9014
|
-
* When we receive new props, we need to:
|
|
9015
|
-
* 1. Create a list of protected keys for each type. This is a directory of
|
|
9016
|
-
* value keys that are currently being "handled" by types of a higher priority
|
|
9017
|
-
* so that whenever an animation is played of a given type, these values are
|
|
9018
|
-
* protected from being animated.
|
|
9019
|
-
* 2. Determine if an animation type needs animating.
|
|
9020
|
-
* 3. Determine if any values have been removed from a type and figure out
|
|
9021
|
-
* what to animate those to.
|
|
9022
|
-
*/
|
|
9023
8904
|
function animateChanges(changedActiveType) {
|
|
9024
|
-
const { props } = visualElement;
|
|
9025
|
-
const
|
|
9026
|
-
/**
|
|
9027
|
-
* A list of animations that we'll build into as we iterate through the animation
|
|
9028
|
-
* types. This will get executed at the end of the function.
|
|
9029
|
-
*/
|
|
8905
|
+
const { props, parent, manuallyAnimateOnMount } = visualElement;
|
|
8906
|
+
const isMounting = isInitialRender || wasReset;
|
|
9030
8907
|
const animations = [];
|
|
9031
8908
|
/**
|
|
9032
|
-
*
|
|
9033
|
-
*
|
|
8909
|
+
* Values removed from a type. A lower-priority type that defines
|
|
8910
|
+
* them animates them back, otherwise they fall back to a base target.
|
|
9034
8911
|
*/
|
|
9035
8912
|
const removedKeys = new Set();
|
|
9036
8913
|
/**
|
|
9037
|
-
*
|
|
9038
|
-
* copy it without iteration. Each time we hit an animation type we set its protected
|
|
9039
|
-
* keys - the keys its not allowed to animate - to the latest version of this object.
|
|
8914
|
+
* Values claimed by active, higher-priority types.
|
|
9040
8915
|
*/
|
|
9041
8916
|
let encounteredKeys = {};
|
|
9042
8917
|
/**
|
|
9043
|
-
*
|
|
9044
|
-
*
|
|
8918
|
+
* Once a type has been deactivated, lower-priority variant labels
|
|
8919
|
+
* re-animate so variant children animate back too.
|
|
9045
8920
|
*/
|
|
9046
8921
|
let removedVariantIndex = Infinity;
|
|
9047
8922
|
/**
|
|
9048
|
-
*
|
|
9049
|
-
*
|
|
9050
|
-
* need to be animated). If any values have been removed, we want to detect those in
|
|
9051
|
-
* lower priority props and flag for animation.
|
|
8923
|
+
* Variant labels are inherited from the closest variant-controlling
|
|
8924
|
+
* ancestor, unless an element on the way has inherit={false}.
|
|
9052
8925
|
*/
|
|
9053
|
-
|
|
9054
|
-
|
|
8926
|
+
let source = visualElement;
|
|
8927
|
+
do
|
|
8928
|
+
source = source.props.inherit !== false && source.parent;
|
|
8929
|
+
while (source && !source.isControllingVariants);
|
|
8930
|
+
reversePriorityOrder.forEach((type, i) => {
|
|
9055
8931
|
const typeState = state[type];
|
|
9056
|
-
const
|
|
9057
|
-
|
|
9058
|
-
|
|
8932
|
+
const ownProp = props[type];
|
|
8933
|
+
const inheritedProp = source && source.props[type];
|
|
8934
|
+
const prop = ownProp !== undefined
|
|
8935
|
+
? ownProp
|
|
8936
|
+
: isVariantLabel(inheritedProp) || inheritedProp === false
|
|
8937
|
+
? inheritedProp
|
|
8938
|
+
: undefined;
|
|
9059
8939
|
const propIsVariant = isVariantLabel(prop);
|
|
9060
|
-
/**
|
|
9061
|
-
* If this type has *just* changed isActive status, set activeDelta
|
|
9062
|
-
* to that status. Otherwise set to null.
|
|
9063
|
-
*/
|
|
9064
8940
|
const activeDelta = type === changedActiveType ? typeState.isActive : null;
|
|
9065
8941
|
if (activeDelta === false)
|
|
9066
8942
|
removedVariantIndex = i;
|
|
9067
8943
|
/**
|
|
9068
|
-
*
|
|
9069
|
-
*
|
|
9070
|
-
*
|
|
9071
|
-
* TODO: Can probably change this to a !isControllingVariants check
|
|
9072
|
-
*/
|
|
9073
|
-
let isInherited = prop === context[type] &&
|
|
9074
|
-
prop !== props[type] &&
|
|
9075
|
-
propIsVariant;
|
|
9076
|
-
if (isInherited &&
|
|
9077
|
-
(isInitialRender || wasReset) &&
|
|
9078
|
-
visualElement.manuallyAnimateOnMount) {
|
|
9079
|
-
isInherited = false;
|
|
9080
|
-
}
|
|
9081
|
-
/**
|
|
9082
|
-
* Set all encountered keys so far as the protected keys for this type. This will
|
|
9083
|
-
* be any key that has been animated or otherwise handled by active, higher-priority types.
|
|
8944
|
+
* Inherited labels are animated by the parent through
|
|
8945
|
+
* variantChildren, unless this element mounted after its parent.
|
|
9084
8946
|
*/
|
|
8947
|
+
const isInherited = propIsVariant &&
|
|
8948
|
+
ownProp === undefined &&
|
|
8949
|
+
!(isMounting && manuallyAnimateOnMount);
|
|
9085
8950
|
typeState.protectedKeys = { ...encounteredKeys };
|
|
9086
|
-
|
|
9087
|
-
if (
|
|
9088
|
-
// If it isn't active and hasn't *just* been set as inactive
|
|
9089
|
-
(!typeState.isActive && activeDelta === null) ||
|
|
9090
|
-
// If we didn't and don't have any defined prop for this animation type
|
|
8951
|
+
if ((!typeState.isActive && activeDelta === null) ||
|
|
9091
8952
|
(!prop && !typeState.prevProp) ||
|
|
9092
|
-
// Or if the prop doesn't define an animation
|
|
9093
8953
|
isAnimationControls(prop) ||
|
|
9094
8954
|
typeof prop === "boolean") {
|
|
9095
|
-
|
|
8955
|
+
return;
|
|
9096
8956
|
}
|
|
9097
8957
|
/**
|
|
9098
|
-
*
|
|
9099
|
-
*
|
|
9100
|
-
*
|
|
9101
|
-
* value animations that stop the originals, leaving the exit
|
|
9102
|
-
* animation promise unresolved and the component stuck in the DOM.
|
|
8958
|
+
* Don't re-resolve a running exit: a changed custom would start
|
|
8959
|
+
* new value animations that stop the originals, leaving the exit
|
|
8960
|
+
* promise unresolved and the element stuck in the DOM.
|
|
9103
8961
|
*/
|
|
9104
8962
|
if (type === "exit" && typeState.isActive && activeDelta !== true) {
|
|
9105
|
-
|
|
9106
|
-
encounteredKeys
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
}
|
|
9111
|
-
continue;
|
|
8963
|
+
encounteredKeys = {
|
|
8964
|
+
...encounteredKeys,
|
|
8965
|
+
...typeState.prevResolvedValues,
|
|
8966
|
+
};
|
|
8967
|
+
return;
|
|
9112
8968
|
}
|
|
9113
|
-
/**
|
|
9114
|
-
* As we go look through the values defined on this type, if we detect
|
|
9115
|
-
* a changed value or a value that was removed in a higher priority, we set
|
|
9116
|
-
* this to true and add this prop to the animation list.
|
|
9117
|
-
*/
|
|
9118
8969
|
const variantDidChange = checkVariantsDidChange(typeState.prevProp, prop);
|
|
9119
8970
|
let shouldAnimateType = variantDidChange ||
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
typeState.isActive &&
|
|
9123
|
-
!isInherited &&
|
|
9124
|
-
propIsVariant) ||
|
|
9125
|
-
// If we removed a higher-priority variant (i is in reverse order)
|
|
9126
|
-
(i > removedVariantIndex && propIsVariant);
|
|
8971
|
+
(propIsVariant &&
|
|
8972
|
+
((activeDelta && !isInherited) || i > removedVariantIndex));
|
|
9127
8973
|
let handledRemovedValues = false;
|
|
9128
|
-
/**
|
|
9129
|
-
* As animations can be set as variant lists, variants or target objects, we
|
|
9130
|
-
* coerce everything to an array if it isn't one already
|
|
9131
|
-
*/
|
|
9132
8974
|
const definitionList = Array.isArray(prop) ? prop : [prop];
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9136
|
-
|
|
9137
|
-
|
|
9138
|
-
|
|
9139
|
-
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
* and decide:
|
|
9143
|
-
* 1. If the value has changed, and needs animating
|
|
9144
|
-
* 2. If it has been removed, and needs adding to the removedKeys set
|
|
9145
|
-
* 3. If it has been removed in a higher priority type and needs animating
|
|
9146
|
-
* 4. If it hasn't been removed in a higher priority but hasn't changed, and
|
|
9147
|
-
* needs adding to the type's protectedKeys list.
|
|
9148
|
-
*/
|
|
9149
|
-
const { prevResolvedValues = {} } = typeState;
|
|
9150
|
-
const allKeys = {
|
|
9151
|
-
...prevResolvedValues,
|
|
9152
|
-
...resolvedValues,
|
|
9153
|
-
};
|
|
9154
|
-
const markToAnimate = (key) => {
|
|
9155
|
-
shouldAnimateType = true;
|
|
9156
|
-
if (removedKeys.has(key)) {
|
|
9157
|
-
handledRemovedValues = true;
|
|
9158
|
-
removedKeys.delete(key);
|
|
8975
|
+
let resolvedValues = {};
|
|
8976
|
+
if (activeDelta !== false) {
|
|
8977
|
+
for (const definition of definitionList) {
|
|
8978
|
+
const { transition, transitionEnd, ...target } = resolveVariant(visualElement, definition, getTypeCustom(visualElement, type)) || {};
|
|
8979
|
+
resolvedValues = {
|
|
8980
|
+
...resolvedValues,
|
|
8981
|
+
...target,
|
|
8982
|
+
...transitionEnd,
|
|
8983
|
+
};
|
|
9159
8984
|
}
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
for (const key in allKeys) {
|
|
8985
|
+
}
|
|
8986
|
+
const { prevResolvedValues } = typeState;
|
|
8987
|
+
for (const key in { ...prevResolvedValues, ...resolvedValues }) {
|
|
8988
|
+
if (key in encounteredKeys)
|
|
8989
|
+
continue;
|
|
9166
8990
|
const next = resolvedValues[key];
|
|
9167
8991
|
const prev = prevResolvedValues[key];
|
|
9168
|
-
// If we've already handled this we can just skip ahead
|
|
9169
|
-
if (encounteredKeys.hasOwnProperty(key))
|
|
9170
|
-
continue;
|
|
9171
8992
|
/**
|
|
9172
|
-
*
|
|
8993
|
+
* Keyframes compare by value, but replay whenever the
|
|
8994
|
+
* variant label changed.
|
|
9173
8995
|
*/
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
valueHasChanged = next !== prev;
|
|
9181
|
-
}
|
|
9182
|
-
if (valueHasChanged) {
|
|
9183
|
-
if (next !== undefined && next !== null) {
|
|
9184
|
-
// If next is defined and doesn't equal prev, it needs animating
|
|
9185
|
-
markToAnimate(key);
|
|
9186
|
-
}
|
|
9187
|
-
else {
|
|
9188
|
-
// If it's undefined, it's been removed.
|
|
9189
|
-
removedKeys.add(key);
|
|
9190
|
-
}
|
|
8996
|
+
const valueHasChanged = Array.isArray(next) && Array.isArray(prev)
|
|
8997
|
+
? !shallowCompare(next, prev) || variantDidChange
|
|
8998
|
+
: next !== prev;
|
|
8999
|
+
if (valueHasChanged &&
|
|
9000
|
+
(next === undefined || next === null)) {
|
|
9001
|
+
removedKeys.add(key);
|
|
9191
9002
|
}
|
|
9192
|
-
else if (
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9003
|
+
else if (valueHasChanged ||
|
|
9004
|
+
(next !== undefined && removedKeys.has(key))) {
|
|
9005
|
+
shouldAnimateType = true;
|
|
9006
|
+
if (removedKeys.delete(key))
|
|
9007
|
+
handledRemovedValues = true;
|
|
9008
|
+
typeState.needsAnimating[key] = true;
|
|
9009
|
+
const motionValue = visualElement.getValue(key);
|
|
9010
|
+
if (motionValue)
|
|
9011
|
+
motionValue.liveStyle = false;
|
|
9198
9012
|
}
|
|
9199
9013
|
else {
|
|
9200
|
-
/**
|
|
9201
|
-
* If it hasn't changed, we add it to the list of protected values
|
|
9202
|
-
* to ensure it doesn't get animated.
|
|
9203
|
-
*/
|
|
9204
9014
|
typeState.protectedKeys[key] = true;
|
|
9205
9015
|
}
|
|
9206
9016
|
}
|
|
9207
|
-
/**
|
|
9208
|
-
* Update the typeState so next time animateChanges is called we can compare the
|
|
9209
|
-
* latest prop and resolvedValues to these.
|
|
9210
|
-
*/
|
|
9211
9017
|
typeState.prevProp = prop;
|
|
9212
9018
|
typeState.prevResolvedValues = resolvedValues;
|
|
9213
9019
|
if (typeState.isActive) {
|
|
9214
9020
|
encounteredKeys = { ...encounteredKeys, ...resolvedValues };
|
|
9215
9021
|
}
|
|
9216
|
-
if (
|
|
9217
|
-
|
|
9218
|
-
|
|
9219
|
-
}
|
|
9220
|
-
/**
|
|
9221
|
-
* If this is an inherited prop we want to skip this animation
|
|
9222
|
-
* unless the inherited variants haven't changed on this render.
|
|
9223
|
-
*/
|
|
9224
|
-
const willAnimateViaParent = isInherited && variantDidChange;
|
|
9225
|
-
const needsAnimating = !willAnimateViaParent || handledRemovedValues;
|
|
9226
|
-
if (shouldAnimateType && needsAnimating) {
|
|
9227
|
-
animations.push(...definitionList.map((animation) => {
|
|
9022
|
+
if (shouldAnimateType &&
|
|
9023
|
+
(!(isInherited && variantDidChange) || handledRemovedValues)) {
|
|
9024
|
+
for (const animation of definitionList) {
|
|
9228
9025
|
const options = { type };
|
|
9229
9026
|
/**
|
|
9230
|
-
*
|
|
9231
|
-
*
|
|
9232
|
-
*
|
|
9027
|
+
* Elements that mount into an already-mounted parent
|
|
9028
|
+
* animate themselves, staggered by the parent variant's
|
|
9029
|
+
* delayChildren.
|
|
9233
9030
|
*/
|
|
9234
9031
|
if (typeof animation === "string" &&
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
if (parent.enteringChildren && parentVariant) {
|
|
9242
|
-
const { delayChildren } = parentVariant.transition || {};
|
|
9243
|
-
options.delay = calcChildStagger(parent.enteringChildren, visualElement, delayChildren);
|
|
9244
|
-
}
|
|
9032
|
+
isMounting &&
|
|
9033
|
+
manuallyAnimateOnMount &&
|
|
9034
|
+
parent?.enteringChildren) {
|
|
9035
|
+
const delayChildren = resolveVariant(parent, animation)
|
|
9036
|
+
?.transition?.delayChildren;
|
|
9037
|
+
options.delay = calcChildStagger(parent.enteringChildren, visualElement, delayChildren);
|
|
9245
9038
|
}
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
options,
|
|
9249
|
-
};
|
|
9250
|
-
}));
|
|
9039
|
+
animations.push({ animation, options });
|
|
9040
|
+
}
|
|
9251
9041
|
}
|
|
9252
|
-
}
|
|
9042
|
+
});
|
|
9253
9043
|
/**
|
|
9254
|
-
*
|
|
9255
|
-
*
|
|
9256
|
-
*
|
|
9044
|
+
* Removed values that no lower-priority type defines animate back to
|
|
9045
|
+
* initial, then style, then the value as first read. If initial no
|
|
9046
|
+
* longer defines a value it once did, it stays where it is.
|
|
9257
9047
|
*/
|
|
9258
9048
|
if (removedKeys.size) {
|
|
9049
|
+
const { initial } = props;
|
|
9259
9050
|
const fallbackAnimation = {};
|
|
9260
|
-
|
|
9261
|
-
|
|
9262
|
-
|
|
9263
|
-
|
|
9264
|
-
if (typeof props.initial !== "boolean") {
|
|
9265
|
-
const initialTransition = resolveVariant(visualElement, Array.isArray(props.initial)
|
|
9266
|
-
? props.initial[0]
|
|
9267
|
-
: props.initial);
|
|
9268
|
-
if (initialTransition && initialTransition.transition) {
|
|
9269
|
-
fallbackAnimation.transition = initialTransition.transition;
|
|
9270
|
-
}
|
|
9051
|
+
const resolvedInitial = typeof initial !== "boolean" &&
|
|
9052
|
+
resolveVariant(visualElement, Array.isArray(initial) ? initial[0] : initial, visualElement.presenceContext?.custom);
|
|
9053
|
+
if (resolvedInitial && resolvedInitial.transition) {
|
|
9054
|
+
fallbackAnimation.transition = resolvedInitial.transition;
|
|
9271
9055
|
}
|
|
9272
9056
|
removedKeys.forEach((key) => {
|
|
9273
|
-
const fallbackTarget = visualElement.getBaseTarget(key);
|
|
9274
9057
|
const motionValue = visualElement.getValue(key);
|
|
9275
9058
|
if (motionValue)
|
|
9276
9059
|
motionValue.liveStyle = true;
|
|
9277
|
-
|
|
9278
|
-
|
|
9060
|
+
const fromInitial = resolvedInitial && !Array.isArray(initial)
|
|
9061
|
+
? resolvedInitial[key]
|
|
9062
|
+
: undefined;
|
|
9063
|
+
const fromProps = visualElement.getBaseTargetFromProps(props, key);
|
|
9064
|
+
fallbackAnimation[key] =
|
|
9065
|
+
(fromInitial !== undefined
|
|
9066
|
+
? fromInitial
|
|
9067
|
+
: fromProps !== undefined && !isMotionValue(fromProps)
|
|
9068
|
+
? fromProps
|
|
9069
|
+
: visualElement.initialValues[key] === undefined
|
|
9070
|
+
? visualElement.baseTarget[key]
|
|
9071
|
+
: undefined) ?? null;
|
|
9279
9072
|
});
|
|
9280
9073
|
animations.push({ animation: fallbackAnimation });
|
|
9281
9074
|
}
|
|
9282
|
-
|
|
9283
|
-
|
|
9284
|
-
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
return shouldAnimate ? animate(animations) : Promise.resolve();
|
|
9075
|
+
const blockAnimation = (isMounting && visualElement.blockInitialAnimation) ||
|
|
9076
|
+
(isInitialRender &&
|
|
9077
|
+
!manuallyAnimateOnMount &&
|
|
9078
|
+
(props.initial === false || props.initial === props.animate));
|
|
9079
|
+
isInitialRender = wasReset = false;
|
|
9080
|
+
return !blockAnimation && animations.length
|
|
9081
|
+
? animate(animations)
|
|
9082
|
+
: Promise.resolve();
|
|
9291
9083
|
}
|
|
9292
9084
|
/**
|
|
9293
9085
|
* Change whether a certain animation type is active.
|
|
9294
9086
|
*/
|
|
9295
9087
|
function setActive(type, isActive) {
|
|
9296
|
-
// If the active state hasn't changed, we can safely do nothing here
|
|
9297
9088
|
if (state[type].isActive === isActive)
|
|
9298
9089
|
return Promise.resolve();
|
|
9299
|
-
// Propagate active change to children
|
|
9300
9090
|
visualElement.variantChildren?.forEach((child) => child.animationState?.setActive(type, isActive));
|
|
9301
9091
|
state[type].isActive = isActive;
|
|
9302
9092
|
const animations = animateChanges(type);
|
|
@@ -9308,7 +9098,13 @@
|
|
|
9308
9098
|
return {
|
|
9309
9099
|
animateChanges,
|
|
9310
9100
|
setActive,
|
|
9311
|
-
|
|
9101
|
+
/**
|
|
9102
|
+
* Allows tests to inject a mocked animate function.
|
|
9103
|
+
* @internal
|
|
9104
|
+
*/
|
|
9105
|
+
setAnimateFunction: (makeAnimator) => {
|
|
9106
|
+
animate = makeAnimator(visualElement);
|
|
9107
|
+
},
|
|
9312
9108
|
getState: () => state,
|
|
9313
9109
|
reset: () => {
|
|
9314
9110
|
state = createState();
|
|
@@ -9325,24 +9121,45 @@
|
|
|
9325
9121
|
}
|
|
9326
9122
|
return false;
|
|
9327
9123
|
}
|
|
9328
|
-
function createTypeState(isActive = false) {
|
|
9329
|
-
return {
|
|
9330
|
-
isActive,
|
|
9331
|
-
protectedKeys: {},
|
|
9332
|
-
needsAnimating: {},
|
|
9333
|
-
prevResolvedValues: {},
|
|
9334
|
-
};
|
|
9335
|
-
}
|
|
9336
9124
|
function createState() {
|
|
9337
|
-
|
|
9338
|
-
|
|
9339
|
-
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
|
|
9343
|
-
|
|
9344
|
-
|
|
9345
|
-
}
|
|
9125
|
+
const state = {};
|
|
9126
|
+
for (const type of variantPriorityOrder) {
|
|
9127
|
+
state[type] = {
|
|
9128
|
+
isActive: type === "animate",
|
|
9129
|
+
protectedKeys: {},
|
|
9130
|
+
needsAnimating: {},
|
|
9131
|
+
prevResolvedValues: {},
|
|
9132
|
+
};
|
|
9133
|
+
}
|
|
9134
|
+
return state;
|
|
9135
|
+
}
|
|
9136
|
+
|
|
9137
|
+
const numVariantProps = variantProps.length;
|
|
9138
|
+
/**
|
|
9139
|
+
* Get variant context from a visual element's parent chain.
|
|
9140
|
+
* Uses `any` type for visualElement to avoid circular dependencies.
|
|
9141
|
+
*/
|
|
9142
|
+
function getVariantContext(visualElement) {
|
|
9143
|
+
if (!visualElement)
|
|
9144
|
+
return undefined;
|
|
9145
|
+
if (!visualElement.isControllingVariants) {
|
|
9146
|
+
const context = visualElement.parent
|
|
9147
|
+
? getVariantContext(visualElement.parent) || {}
|
|
9148
|
+
: {};
|
|
9149
|
+
if (visualElement.props.initial !== undefined) {
|
|
9150
|
+
context.initial = visualElement.props.initial;
|
|
9151
|
+
}
|
|
9152
|
+
return context;
|
|
9153
|
+
}
|
|
9154
|
+
const context = {};
|
|
9155
|
+
for (let i = 0; i < numVariantProps; i++) {
|
|
9156
|
+
const name = variantProps[i];
|
|
9157
|
+
const prop = visualElement.props[name];
|
|
9158
|
+
if (isVariantLabel(prop) || prop === false) {
|
|
9159
|
+
context[name] = prop;
|
|
9160
|
+
}
|
|
9161
|
+
}
|
|
9162
|
+
return context;
|
|
9346
9163
|
}
|
|
9347
9164
|
|
|
9348
9165
|
/**
|
|
@@ -13471,6 +13288,7 @@
|
|
|
13471
13288
|
exports.numberValueTypes = numberValueTypes;
|
|
13472
13289
|
exports.optimizedAppearDataAttribute = optimizedAppearDataAttribute;
|
|
13473
13290
|
exports.optimizedAppearDataId = optimizedAppearDataId;
|
|
13291
|
+
exports.originProps = originProps;
|
|
13474
13292
|
exports.parseAnimateLayoutArgs = parseAnimateLayoutArgs;
|
|
13475
13293
|
exports.parseCSSVariable = parseCSSVariable;
|
|
13476
13294
|
exports.parseValueFromTransform = parseValueFromTransform;
|