82 lines
3.4 KiB
JavaScript
82 lines
3.4 KiB
JavaScript
import { useContext } from 'react';
|
|
import { isAnimationControls } from '../../animation/utils/is-animation-controls.mjs';
|
|
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
|
import { resolveVariantFromProps } from '../../render/utils/resolve-variants.mjs';
|
|
import { useConstant } from '../../utils/use-constant.mjs';
|
|
import { resolveMotionValue } from '../../value/utils/resolve-motion-value.mjs';
|
|
import { MotionContext } from '../../context/MotionContext/index.mjs';
|
|
import { isControllingVariants, isVariantNode } from '../../render/utils/is-controlling-variants.mjs';
|
|
|
|
function makeState({ scrapeMotionValuesFromProps, createRenderState, onMount, }, props, context, presenceContext) {
|
|
const state = {
|
|
latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
|
|
renderState: createRenderState(),
|
|
};
|
|
if (onMount) {
|
|
state.mount = (instance) => onMount(props, instance, state);
|
|
}
|
|
return state;
|
|
}
|
|
const makeUseVisualState = (config) => (props, isStatic) => {
|
|
const context = useContext(MotionContext);
|
|
const presenceContext = useContext(PresenceContext);
|
|
const make = () => makeState(config, props, context, presenceContext);
|
|
return isStatic ? make() : useConstant(make);
|
|
};
|
|
function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
|
|
const values = {};
|
|
const motionValues = scrapeMotionValues(props, {});
|
|
for (const key in motionValues) {
|
|
values[key] = resolveMotionValue(motionValues[key]);
|
|
}
|
|
let { initial, animate } = props;
|
|
const isControllingVariants$1 = isControllingVariants(props);
|
|
const isVariantNode$1 = isVariantNode(props);
|
|
if (context &&
|
|
isVariantNode$1 &&
|
|
!isControllingVariants$1 &&
|
|
props.inherit !== false) {
|
|
if (initial === undefined)
|
|
initial = context.initial;
|
|
if (animate === undefined)
|
|
animate = context.animate;
|
|
}
|
|
let isInitialAnimationBlocked = presenceContext
|
|
? presenceContext.initial === false
|
|
: false;
|
|
isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false;
|
|
const variantToSet = isInitialAnimationBlocked ? animate : initial;
|
|
if (variantToSet &&
|
|
typeof variantToSet !== "boolean" &&
|
|
!isAnimationControls(variantToSet)) {
|
|
const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
|
|
list.forEach((definition) => {
|
|
const resolved = resolveVariantFromProps(props, definition);
|
|
if (!resolved)
|
|
return;
|
|
const { transitionEnd, transition, ...target } = resolved;
|
|
for (const key in target) {
|
|
let valueTarget = target[key];
|
|
if (Array.isArray(valueTarget)) {
|
|
/**
|
|
* Take final keyframe if the initial animation is blocked because
|
|
* we want to initialise at the end of that blocked animation.
|
|
*/
|
|
const index = isInitialAnimationBlocked
|
|
? valueTarget.length - 1
|
|
: 0;
|
|
valueTarget = valueTarget[index];
|
|
}
|
|
if (valueTarget !== null) {
|
|
values[key] = valueTarget;
|
|
}
|
|
}
|
|
for (const key in transitionEnd)
|
|
values[key] = transitionEnd[key];
|
|
});
|
|
}
|
|
return values;
|
|
}
|
|
|
|
export { makeUseVisualState };
|