svelte-motion
Version:
Svelte animation library based on the React library framer-motion.
95 lines (92 loc) • 3.54 kB
JavaScript
/**
based on framer-motion@4.0.3,
Copyright (c) 2018 Framer B.V.
*/
import { __rest, __read } from 'tslib';
//import { invariant } from 'hey-listen';
function isCSSVariable(value) {
return typeof value === "string" && value.startsWith("var(--");
}
/**
* Parse Framer's special CSS variable format into a CSS token and a fallback.
*
* ```
* `var(--foo, #fff)` => [`--foo`, '#fff']
* ```
*
* @param current
*/
var cssVariableRegex = /var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/;
function parseCSSVariable(current) {
var match = cssVariableRegex.exec(current);
if (!match)
return [,];
var _a = __read(match, 3), token = _a[1], fallback = _a[2];
return [token, fallback];
}
var maxDepth = 4;
function getVariableValue(current, element, depth) {
if (depth === void 0) { depth = 1; }
//invariant(depth <= maxDepth, "Max CSS variable fallback depth detected in property \"" + current + "\". This may indicate a circular fallback dependency.");
var _a = __read(parseCSSVariable(current), 2), token = _a[0], fallback = _a[1];
// No CSS variable detected
if (!token)
return;
// Attempt to read this CSS variable off the element
var resolved = window.getComputedStyle(element).getPropertyValue(token);
if (resolved) {
return resolved.trim();
}
else if (isCSSVariable(fallback)) {
// The fallback might itself be a CSS variable, in which case we attempt to resolve it too.
return getVariableValue(fallback, element, depth + 1);
}
else {
return fallback;
}
}
/**
* Resolve CSS variables from
*
* @internal
*/
function resolveCSSVariables(visualElement, _a, transitionEnd) {
var _b;
var target = __rest(_a, []);
var element = visualElement.getInstance();
if (!(element instanceof HTMLElement))
return { target: target, transitionEnd: transitionEnd };
// If `transitionEnd` isn't `undefined`, clone it. We could clone `target` and `transitionEnd`
// only if they change but I think this reads clearer and this isn't a performance-critical path.
if (transitionEnd) {
transitionEnd = Object.assign({}, transitionEnd);
}
// Go through existing `MotionValue`s and ensure any existing CSS variables are resolved
visualElement.forEachValue(function (value) {
var current = value.get();
if (!isCSSVariable(current))
return;
var resolved = getVariableValue(current, element);
if (resolved)
value.set(resolved);
});
// Cycle through every target property and resolve CSS variables. Currently
// we only read single-var properties like `var(--foo)`, not `calc(var(--foo) + 20px)`
for (var key in target) {
var current = target[key];
if (!isCSSVariable(current))
continue;
var resolved = getVariableValue(current, element);
if (!resolved)
continue;
// Clone target if it hasn't already been
target[key] = resolved;
// If the user hasn't already set this key on `transitionEnd`, set it to the unresolved
// CSS variable. This will ensure that after the animation the component will reflect
// changes in the value of the CSS variable.
if (transitionEnd)
(_b = transitionEnd[key]) !== null && _b !== void 0 ? _b : (transitionEnd[key] = current);
}
return { target: target, transitionEnd: transitionEnd };
}
export { cssVariableRegex, parseCSSVariable, resolveCSSVariables };