diff --git a/apps/test-examples/index.tsx b/apps/test-examples/index.tsx index 14a79e1cb..dfb67d039 100644 --- a/apps/test-examples/index.tsx +++ b/apps/test-examples/index.tsx @@ -26,6 +26,7 @@ import Test2327 from './src/Test2327'; import Test2233 from './src/Test2233'; import Test2363 from './src/Test2363'; import Test2366 from './src/Test2366'; +import Test2380 from './src/Test2380'; import Test2397 from './src/Test2397'; import Test2403 from './src/Test2403'; import Test2407 from './src/Test2407'; diff --git a/apps/test-examples/src/Test2380.tsx b/apps/test-examples/src/Test2380.tsx new file mode 100644 index 000000000..a1e0b74bf --- /dev/null +++ b/apps/test-examples/src/Test2380.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import {View} from 'react-native'; +import {SvgCss} from 'react-native-svg/css'; + +const xml = ` + + + + + + + + + + + + + + + Hello + + + + +`; + +export default function SvgComponent() { + return ( + + + + ); +} diff --git a/src/css/css.tsx b/src/css/css.tsx index b60a4c3c6..fba0e416c 100644 --- a/src/css/css.tsx +++ b/src/css/css.tsx @@ -592,6 +592,64 @@ const parseProps = { * @author strarsis * @author modified by: msand */ + +function extractVariables(stylesheet: CssNode): Map { + const variables = new Map(); + + csstree.walk(stylesheet, { + visit: 'Declaration', + enter(node) { + const { property, value } = node as Declaration; + if (property.startsWith('--')) { + const variableName = property.trim(); + const variableValue = csstree.generate(value).trim(); + variables.set(variableName, variableValue); + } + }, + }); + + return variables; +} + +function resolveVariables( + value: string | CssNode | undefined, + variables: Map +): string { + if (value === undefined) { + return ''; + } + const valueStr = typeof value === 'string' ? value : csstree.generate(value); + return valueStr.replace( + /var\((--[^,)]+)(?:,\s*([^)]+))?\)/g, + (_, variableName, fallback) => { + const resolvedValue = variables.get(variableName); + if (resolvedValue !== undefined) { + return resolveVariables(resolvedValue, variables); + } + return fallback ? resolveVariables(fallback, variables) : ''; + } + ); +} + +const propsToResolve = [ + 'color', + 'fill', + 'floodColor', + 'lightingColor', + 'stopColor', + 'stroke', +]; +const resolveElementVariables = ( + element: XmlAST, + variables: Map +) => + propsToResolve.forEach((prop) => { + const value = element.props[prop] as string; + if (value && value.startsWith('var(')) { + element.props[prop] = resolveVariables(value, variables); + } + }); + export const inlineStyles: Middleware = function inlineStyles( document: XmlAST ) { @@ -604,6 +662,7 @@ export const inlineStyles: Middleware = function inlineStyles( } const selectors: FlatSelectorList = []; + let variables = new Map(); for (const element of styleElements) { const { children } = element; @@ -615,7 +674,10 @@ export const inlineStyles: Middleware = function inlineStyles( // collect