diff --git a/src/__tests__/native/variables.test.tsx b/src/__tests__/native/variables.test.tsx index e61340b5..55fced31 100644 --- a/src/__tests__/native/variables.test.tsx +++ b/src/__tests__/native/variables.test.tsx @@ -242,6 +242,60 @@ test("VariableContextProvider", () => { expect(component.props.style).toStrictEqual({ color: "red" }); }); +test("VariableContextProvider later provides a :root variable", () => { + registerCSS( + ` + :root { --my-var: red; } + .test { color: var(--my-var); } + `, + { inlineVariables: false }, + ); + + const child = ; + + const { rerender } = render( + {child}, + ); + + expect(screen.getByTestId(testID).props.style).toStrictEqual({ + color: "red", + }); + + rerender( + + {child} + , + ); + + expect(screen.getByTestId(testID).props.style).toStrictEqual({ + color: "blue", + }); +}); + +test("VariableContextProvider later provides a variable with a fallback", () => { + registerCSS(`.test { color: var(--my-var, red); }`); + + const child = ; + + const { rerender } = render( + {child}, + ); + + expect(screen.getByTestId(testID).props.style).toStrictEqual({ + color: "red", + }); + + rerender( + + {child} + , + ); + + expect(screen.getByTestId(testID).props.style).toStrictEqual({ + color: "blue", + }); +}); + test("variable overriding with classes", () => { registerCSS(` :root { diff --git a/src/native/styles/variables.ts b/src/native/styles/variables.ts index 0b785645..07f3fd90 100644 --- a/src/native/styles/variables.ts +++ b/src/native/styles/variables.ts @@ -83,6 +83,10 @@ export function varResolver( return variableCycles.has(name) ? resolve(fallback) : value; } + // Guard the absence too, so an ancestor that later provides the variable + // replaces the :root / fallback value. + renderGuards?.push(["v", name, undefined]); + value = resolve(get(rootVariables(name))); if (variableCycles.has(name)) return resolve(fallback); if (value !== undefined) {