| 123456789101112131415161718192021222324252627282930313233343536373839404142 |
- import { invariant } from 'motion-utils';
- import { isNumericalString } from '../../../utils/is-numerical-string.mjs';
- import { isCSSVariableToken } from './is-css-variable.mjs';
- /**
- * Parse Framer's special CSS variable format into a CSS token and a fallback.
- *
- * ```
- * `var(--foo, #fff)` => [`--foo`, '#fff']
- * ```
- *
- * @param current
- */
- const splitCSSVariableRegex =
- // eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
- /^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;
- function parseCSSVariable(current) {
- const match = splitCSSVariableRegex.exec(current);
- if (!match)
- return [,];
- const [, token1, token2, fallback] = match;
- return [`--${token1 ?? token2}`, fallback];
- }
- const maxDepth = 4;
- function getVariableValue(current, element, depth = 1) {
- invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`);
- const [token, fallback] = parseCSSVariable(current);
- // No CSS variable detected
- if (!token)
- return;
- // Attempt to read this CSS variable off the element
- const resolved = window.getComputedStyle(element).getPropertyValue(token);
- if (resolved) {
- const trimmed = resolved.trim();
- return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
- }
- return isCSSVariableToken(fallback)
- ? getVariableValue(fallback, element, depth + 1)
- : fallback;
- }
- export { getVariableValue, parseCSSVariable };
|