Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/__tests__/native/variables.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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; }`);
Expand Down Expand Up @@ -230,3 +230,18 @@ test("ratio values", () => {

expect(component.props.style).toStrictEqual({ aspectRatio: "16 / 9" });
});

test("VariableContextProvider", () => {
registerCSS(`
.test { color: var(--my-var); }
`);

render(
<VariableContextProvider value={{ "--my-var": "red" }}>
<View testID={testID} className="test" />
</VariableContextProvider>,
);

const component = screen.getByTestId(testID);
expect(component.props.style).toStrictEqual({ color: "red" });
});
1 change: 1 addition & 0 deletions src/__tests__/native/vars.test.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
35 changes: 31 additions & 4 deletions src/runtime/native/api.ts → src/runtime/native/api.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -18,6 +18,7 @@ import {
VariableContext,
type Effect,
type Getter,
type VariableContextValue,
} from "./reactivity";
import { resolveValue } from "./styles/resolve";

Expand Down Expand Up @@ -102,7 +103,33 @@ export function useNativeVariable(name: string) {
return resolveValue([{}, "var", [name]], effect.get, { inheritedVariables });
}

/**
* @deprecated Use `<VariableContextProvider />` instead.
*/
export function vars(variables: Record<string, StyleDescriptor>) {
(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 <VariableContext value={value}>{props.children}</VariableContext>;
}
30 changes: 28 additions & 2 deletions src/runtime/web/api.ts → src/runtime/web/api.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -24,7 +29,7 @@ export const styled = <
};
};

export const useCssElement = <const C extends ReactComponent>(
export const useCssElement = <C extends ReactComponent>(
component: C,
incomingProps: Props,
mapping: StyledConfiguration<C>,
Expand Down Expand Up @@ -66,6 +71,9 @@ export const colorScheme: ColorScheme = {
},
};

/**
* @deprecated Use `<VariableContextProvider />` instead.
*/
export function vars(variables: Record<string, string | number>) {
const $variables: Record<string, string> = {};

Expand All @@ -79,6 +87,24 @@ export function vars(variables: Record<string, string | number>) {
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 <div style={style}>{props.children}</div>;
}

export const useNativeVariable = () => {
throw new Error("useNativeVariable is not supported in web");
};
Expand Down
Loading