From 561d0e79ab2b9960ce1bc4813b466370f5692546 Mon Sep 17 00:00:00 2001 From: Hubert Bieszczad Date: Thu, 14 May 2026 12:26:30 +0200 Subject: [PATCH] fix: deeply find themed variables --- .../src/metro/addMetaToStylesTemplate.ts | 32 +++++++++++---- .../tests/native/styles-parsing/meta.test.ts | 39 +++++++++++++++++++ packages/uniwind/tests/test.css | 3 ++ 3 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 packages/uniwind/tests/native/styles-parsing/meta.test.ts diff --git a/packages/uniwind/src/metro/addMetaToStylesTemplate.ts b/packages/uniwind/src/metro/addMetaToStylesTemplate.ts index 2f38636c..97a82fb9 100644 --- a/packages/uniwind/src/metro/addMetaToStylesTemplate.ts +++ b/packages/uniwind/src/metro/addMetaToStylesTemplate.ts @@ -29,6 +29,30 @@ const makeSafeForSerialization = (value: any) => { return value } +const hasThemedVarDependency = (varName: string, Processor: ProcessorBuilder, visited = new Set()): boolean => { + if (visited.has(varName)) { + return false + } + + visited.add(varName) + + const isScopedVar = Object.values(Processor.scopedVars).some(scopedVars => varName in scopedVars) + + if (isScopedVar) { + return true + } + + const globalVarValue = Processor.vars[varName] + + if (typeof globalVarValue !== 'string') { + return false + } + + return extractVarsFromString(globalVarValue).some(usedVarName => { + return hasThemedVarDependency(usedVarName, Processor, visited) + }) +} + export const addMetaToStylesTemplate = (Processor: ProcessorBuilder, currentPlatform: Platform) => { const stylesheetsEntries = Object.entries(Processor.stylesheets as StyleSheetTemplate) .map(([className, stylesPerMediaQuery]) => { @@ -70,13 +94,7 @@ export const addMetaToStylesTemplate = (Processor: ProcessorBuilder, currentPlat const dependencies: Array = [] const stringifiedEntries = JSON.stringify(entries) const usedVars = extractVarsFromString(stringifiedEntries) - const isUsingThemedVar = usedVars.some(usedVarName => { - return Object.values(Processor.scopedVars).some(scopedVars => { - const scopedVarsNames = Object.keys(scopedVars) - - return scopedVarsNames.includes(usedVarName) - }) - }) + const isUsingThemedVar = usedVars.some(usedVarName => hasThemedVarDependency(usedVarName, Processor)) if (usedVars.length > 0) { dependencies.push(StyleDependency.Variables) diff --git a/packages/uniwind/tests/native/styles-parsing/meta.test.ts b/packages/uniwind/tests/native/styles-parsing/meta.test.ts new file mode 100644 index 00000000..5921701d --- /dev/null +++ b/packages/uniwind/tests/native/styles-parsing/meta.test.ts @@ -0,0 +1,39 @@ +import { readFileSync } from 'fs' +import { resolve } from 'path' +import { Platform } from '../../../src/common/consts' +import { StyleSheets } from '../../../src/core/types' +import { compileVirtual } from '../../../src/metro/compileVirtual' +import { StyleDependency } from '../../../src/types' + +type CompiledResult = { + stylesheet: StyleSheets +} + +const compileMetadata = async (candidates: Array): Promise => { + const cssPath = resolve('./tests/test.css') + const css = readFileSync(cssPath, 'utf-8') + const virtualCode = await compileVirtual({ + css, + cssPath, + debug: false, + platform: Platform.iOS, + themes: ['light', 'dark'], + polyfills: undefined, + candidates, + }) + + // oxlint-disable-next-line no-unused-vars + const rt = {} + + // oxlint-disable-next-line no-eval + return eval(`(${virtualCode})`) +} + +describe('Styles Metadata', () => { + test('Theme Style Dependency', async () => { + const { stylesheet } = await compileMetadata(['bg-background', 'bg-foreground']) + + expect(stylesheet['bg-background'][0].dependencies).toContain(StyleDependency.Theme) + expect(stylesheet['bg-foreground'][0].dependencies).toContain(StyleDependency.Theme) + }) +}) diff --git a/packages/uniwind/tests/test.css b/packages/uniwind/tests/test.css index b3898a05..3bd6f8b4 100644 --- a/packages/uniwind/tests/test.css +++ b/packages/uniwind/tests/test.css @@ -13,16 +13,19 @@ --spacing-test: 123px; --color-background: unset; --color-p3: color(display-p3 1 0.84 0.04); + --color-foreground: var(--app-foreground); } @layer theme { :root { @variant dark { --color-background: black; + --app-foreground: white; } @variant light { --color-background: white; + --app-foreground: black; } } }