diff --git a/src/__tests__/native/variables.test.tsx b/src/__tests__/native/variables.test.tsx
index a824f800..6a4a7d23 100644
--- a/src/__tests__/native/variables.test.tsx
+++ b/src/__tests__/native/variables.test.tsx
@@ -4,7 +4,7 @@ import type { ViewProps } from "react-native";
import { render, screen } from "@testing-library/react-native";
import { View } from "react-native-css/components/View";
import { registerCSS, testID } from "react-native-css/jest";
-import { styled } from "react-native-css/runtime";
+import { styled, VariableContextProvider } from "react-native-css/runtime";
test("inline variable", () => {
registerCSS(`.my-class { width: var(--my-var); --my-var: 10px; }`);
@@ -230,3 +230,18 @@ test("ratio values", () => {
expect(component.props.style).toStrictEqual({ aspectRatio: "16 / 9" });
});
+
+test("VariableContextProvider", () => {
+ registerCSS(`
+ .test { color: var(--my-var); }
+ `);
+
+ render(
+
+
+ ,
+ );
+
+ const component = screen.getByTestId(testID);
+ expect(component.props.style).toStrictEqual({ color: "red" });
+});
diff --git a/src/__tests__/native/vars.test.tsx b/src/__tests__/native/vars.test.tsx
index 19df5490..d87eb7c4 100644
--- a/src/__tests__/native/vars.test.tsx
+++ b/src/__tests__/native/vars.test.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-deprecated */
import { render, screen } from "@testing-library/react-native";
import { View } from "react-native-css/components/View";
import { registerCSS, testID } from "react-native-css/jest";
diff --git a/src/runtime/native/api.ts b/src/runtime/native/api.tsx
similarity index 74%
rename from src/runtime/native/api.ts
rename to src/runtime/native/api.tsx
index 2c877204..689d49f8 100644
--- a/src/runtime/native/api.ts
+++ b/src/runtime/native/api.tsx
@@ -1,8 +1,8 @@
/* eslint-disable */
-import { useContext, useState } from "react";
+import { useContext, useMemo, useState, type PropsWithChildren } from "react";
import { Appearance } from "react-native";
-import type { InlineVariable, StyleDescriptor } from "../../compiler";
+import type { StyleDescriptor } from "../../compiler";
import type {
ColorScheme,
Props,
@@ -18,6 +18,7 @@ import {
VariableContext,
type Effect,
type Getter,
+ type VariableContextValue,
} from "./reactivity";
import { resolveValue } from "./styles/resolve";
@@ -102,7 +103,33 @@ export function useNativeVariable(name: string) {
return resolveValue([{}, "var", [name]], effect.get, { inheritedVariables });
}
+/**
+ * @deprecated Use `` instead.
+ */
export function vars(variables: Record) {
- (variables as InlineVariable)[VAR_SYMBOL] = "inline";
- return variables;
+ return Object.assign(
+ { [VAR_SYMBOL]: "inline" },
+ Object.fromEntries(
+ Object.entries(variables).map(([k, v]) => [k.replace(/^--/, ""), v]),
+ ),
+ );
+}
+
+export function VariableContextProvider(
+ props: PropsWithChildren<{ value: Record<`--${string}`, StyleDescriptor> }>,
+) {
+ const inheritedVariables = useContext(VariableContext);
+
+ const value: VariableContextValue = useMemo(
+ () => ({
+ ...inheritedVariables,
+ ...Object.fromEntries(
+ Object.entries(props.value).map(([k, v]) => [k.replace(/^--/, ""), v]),
+ ),
+ [VAR_SYMBOL]: true,
+ }),
+ [inheritedVariables, props.value],
+ );
+
+ return {props.children};
}
diff --git a/src/runtime/web/api.ts b/src/runtime/web/api.tsx
similarity index 74%
rename from src/runtime/web/api.ts
rename to src/runtime/web/api.tsx
index 65935ac5..189c249c 100644
--- a/src/runtime/web/api.ts
+++ b/src/runtime/web/api.tsx
@@ -1,4 +1,9 @@
-import { createElement, type ComponentProps } from "react";
+import {
+ createElement,
+ useMemo,
+ type ComponentProps,
+ type PropsWithChildren,
+} from "react";
import { Appearance } from "react-native";
import type {
@@ -24,7 +29,7 @@ export const styled = <
};
};
-export const useCssElement = (
+export const useCssElement = (
component: C,
incomingProps: Props,
mapping: StyledConfiguration,
@@ -66,6 +71,9 @@ export const colorScheme: ColorScheme = {
},
};
+/**
+ * @deprecated Use `` instead.
+ */
export function vars(variables: Record) {
const $variables: Record = {};
@@ -79,6 +87,24 @@ export function vars(variables: Record) {
return $variables;
}
+export function VariableContextProvider(
+ props: PropsWithChildren<{ value: Record<`--${string}`, string> }>,
+) {
+ const style = useMemo(() => {
+ return {
+ display: "content",
+ ...Object.fromEntries(
+ Object.entries(props.value).map(([key, value]) => [
+ key.startsWith("--") ? key : `--${key}`,
+ value,
+ ]),
+ ),
+ };
+ }, [props.value]);
+
+ return {props.children}
;
+}
+
export const useNativeVariable = () => {
throw new Error("useNativeVariable is not supported in web");
};