Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const targetValue = target[key]
let value: string | number | null = null
// If this is a keyframes value, we can attempt to use the first value in the
// array as that's going to be the first value of the animation anyway
if (Array.isArray(targetValue)) {
value = targetValue[0]
}
// If it isn't a keyframes or the first keyframes value was set as `null`, read the
// value from the DOM. It might be worth investigating whether to check props (for SVG)
// or props.style (for HTML) if the value exists there before attempting to read.
if (value === null) {
value = this.readValueFromSource(key)
invariant(
value !== null,
`No initial value for "${key}" can be inferred. Ensure an initial value for "${key}" is defined on the component.`
)
}
if (typeof value === "string" && isNumericalString(value)) {
// If this is a number read as a string, ie "0" or "200", convert it to a number
value = parseFloat(value)
} else if (!getValueType(value) && complex.test(targetValue)) {
// If value is not recognised as animatable, ie "none", create an animatable version origin based on the target
value = complex.getAnimatableNone(targetValue as string)
}
this.values.set(key, motionValue(value))
this.baseTarget[key] = value
}
poseList.reverse().forEach(poseKey => {
if (poseKey === "default" && config[poseKey] === undefined) {
return
}
invariant(config[poseKey] !== undefined, `Pose with name ${poseKey} not found.`)
const poseDefinition = config[poseKey]
let pose: Pose = isTargetResolver(poseDefinition)
? poseDefinition(props, resolveCurrent(values), resolveVelocity(values))
: poseDefinition
checkForNewValues(pose, values, ref)
// This feels like a good candidate to inject a transform function via
// a `PluginContext`, or perhaps a factory function, that can take a pose,
// maybe run side-effects (ie DOM measurement), and return a new one
// We may need a second `checkForNewValues` after this if we open it up in case
// new values are created.
pose = transformPose(pose, values, ref)
const { transition, transitionEnd, ...remainingPoseValues } = pose
export function applyExitProps<p>(
props: P & MotionProps,
{ initial, isExiting, custom, onExitComplete }: ExitProps
): P & MotionProps {
if (isExiting) {
invariant(!!props.exit, "No exit animation defined.")
return {
...props,
/**
* Overwrite user-defined `custom` with the one incoming from `AnimatePresence`.
* This will only be defined when a component is exiting and it allows a user
* to update `custom` even when a component has been removed from the tree.
*/
custom: custom !== undefined ? custom : props.custom,
// Animate to `exit` just by overwriting `animate`.
animate: props.exit,
onAnimationComplete: () => {
onExitComplete && onExitComplete()
props.onAnimationComplete && props.onAnimationComplete()
},
}</p>
export default (from: Color | string, to: Color | string) => {
const fromColorType = getColorType(from);
const toColorType = getColorType(to);
invariant(!!fromColorType, notAnimatable(from));
invariant(!!toColorType, notAnimatable(to));
invariant(
fromColorType.transform === toColorType.transform,
'Both colors must be hex/RGBA, OR both must be HSLA.'
);
const fromColor = fromColorType.parse(from);
const toColor = toColorType.parse(to);
const blended = { ...fromColor };
// Only use the linear blending function for rgba and hex
const mixFunc = fromColorType === hsla ? mix : mixLinearColor;
return (v: number) => {
for (const key in blended) {
if (key !== 'alpha') {
// as it'd be doing multiple resize-remeasure operations.
if (isKeyframesTarget(to)) {
const numKeyframes = to.length
for (let i = to[0] === null ? 1 : 0; i < numKeyframes; i++) {
if (!toType) {
toType = getDimensionValueType(to[i])
invariant(
toType === fromType ||
(isNumOrPxType(fromType) &&
isNumOrPxType(toType)),
"Keyframes must be of the same dimension as the current value"
)
} else {
invariant(
getDimensionValueType(to[i]) === toType,
"All keyframes must be of the same type"
)
}
}
} else {
toType = getDimensionValueType(to)
}
if (fromType !== toType) {
// If they're both just number or px, convert them both to numbers rather than
// relying on resize/remeasure to convert (which is wasteful in this situation)
if (isNumOrPxType(fromType) && isNumOrPxType(toType)) {
const current = value.get()
if (typeof current === "string") {
value.set(parseFloat(current))
function interpolate(
input: number[],
output: T[],
{ clamp = true, ease, mixer }: InterpolateOptions = {}
): Mix {
const inputLength = input.length;
invariant(
inputLength === output.length,
'Both input and output ranges must be the same length'
);
invariant(
!ease || !Array.isArray(ease) || ease.length === inputLength - 1,
'Array of easing functions must be of length `input.length - 1`, as it applies to the transitions **between** the defined values.'
);
// If input runs highest -> lowest, reverse both arrays
if (input[0] > input[inputLength - 1]) {
input = [].concat(input);
output = [].concat(output);
input.reverse();
output.reverse();
}
const mixers = createMixers(output, ease, mixer);
const interpolator =
inputLength === 2
const parseText = (text: string) => {
invariant(typeof text === 'string', 'Child of SplitText must be a string');
return {
text,
numChars: text.length,
splitText: text.split(' ').map(word => word.split(''))
};
};
export const bindValuesToRef = (
values: MotionValueMap,
ref: RefObject<element>
) => {
invariant(
ref.current !== null,
"No DOM reference found. Ensure custom components use `forwardRef` to forward the `ref` property to the host DOM component."
)
if (!ref.current) return
const domStyler = styler(ref.current, { preparseOutput: false })
values.forEach((value, key) => {
if (!value.hasOnRender()) {
value.setOnRender((v: any) => domStyler.set(key, v))
}
})
}
</element>
const createDOMStyler = (node: Element | Window, props?: Props) => {
let styler: Styler;
if (node instanceof HTMLElement) {
styler = css(node, props);
} else if (node instanceof SVGElement) {
styler = svg(node);
} else if (node === window) {
styler = viewport(node);
}
invariant(
styler !== undefined,
'No valid node provided. Node must be HTMLElement, SVGElement or window.'
);
cache.set(node, styler);
return styler;
};