diff --git a/packages/react-strict-dom/src/native/css/customProperties.js b/packages/react-strict-dom/src/native/css/customProperties.js
index 7389215f..e21787e0 100644
--- a/packages/react-strict-dom/src/native/css/customProperties.js
+++ b/packages/react-strict-dom/src/native/css/customProperties.js
@@ -40,6 +40,28 @@ export function stringContainsVariables(input: string): boolean {
return input.includes('var(');
}
+function stringContainsLightDark(input: string): boolean {
+ return input.includes('light-dark(');
+}
+
+const RE_LIGHT_DARK = /^light-dark\(\s*(.+?)\s*,\s*(.+?)\s*\)$/i;
+
+function resolveLightDarkValue(
+ variableValue: string,
+ colorScheme: 'light' | 'dark'
+) {
+ const match = RE_LIGHT_DARK.exec(variableValue);
+
+ if (match == null) {
+ warnMsg(`Invalid light-dark syntax: "${variableValue}"`);
+ return null;
+ }
+
+ const [, lightStr, darkStr] = match;
+
+ return colorScheme === 'dark' ? darkStr.trim() : lightStr.trim();
+}
+
function resolveVariableReferenceValue(
propName: string,
variable: CSSVariableReferenceValue,
@@ -66,7 +88,15 @@ function resolveVariableReferenceValue(
}
if (variableValue != null) {
- if (typeof variableValue === 'object' && variableValue.default != null) {
+ if (
+ typeof variableValue === 'string' &&
+ stringContainsLightDark(variableValue)
+ ) {
+ variableValue = resolveLightDarkValue(variableValue, colorScheme);
+ } else if (
+ typeof variableValue === 'object' &&
+ variableValue.default != null
+ ) {
let defaultValue = variableValue.default;
if (colorScheme === 'dark') {
defaultValue = variableValue['@media (prefers-color-scheme: dark)'];
diff --git a/packages/react-strict-dom/tests/css/__snapshots__/css-themes-test.native.js.snap b/packages/react-strict-dom/tests/css/__snapshots__/css-themes-test.native.js.snap
index 926b3997..e01bebb6 100644
--- a/packages/react-strict-dom/tests/css/__snapshots__/css-themes-test.native.js.snap
+++ b/packages/react-strict-dom/tests/css/__snapshots__/css-themes-test.native.js.snap
@@ -3,7 +3,7 @@
exports[`css.* themes css.createTheme: theme 1`] = `
{
"$$theme": "theme",
- "rootColor__id__3": "green",
+ "rootColor__id__4": "green",
}
`;
@@ -16,6 +16,7 @@ exports[`css.* themes css.defineConsts: constants 1`] = `
exports[`css.* themes css.defineVars: tokens 1`] = `
{
+ "lightDarkColor": "var(--lightDarkColor__id__3)",
"rootColor": "var(--rootColor__id__1)",
"themeAwareColor": "var(--themeAwareColor__id__2)",
}
diff --git a/packages/react-strict-dom/tests/css/css-themes-test.native.js b/packages/react-strict-dom/tests/css/css-themes-test.native.js
index 9186d0d7..a30763ea 100644
--- a/packages/react-strict-dom/tests/css/css-themes-test.native.js
+++ b/packages/react-strict-dom/tests/css/css-themes-test.native.js
@@ -43,7 +43,8 @@ describe('css.* themes', () => {
themeAwareColor: {
default: 'blue',
'@media (prefers-color-scheme: dark)': 'green'
- }
+ },
+ lightDarkColor: 'light-dark(blue, green)'
});
expect(tokens).toMatchSnapshot('tokens');
@@ -54,6 +55,9 @@ describe('css.* themes', () => {
},
themeAwareColor: {
color: tokens.themeAwareColor
+ },
+ lightDarkColor: {
+ color: tokens.lightDarkColor
}
});
@@ -66,6 +70,10 @@ describe('css.* themes', () => {
root = create();
});
expect(root.toJSON().props.style.color).toBe('blue');
+ act(() => {
+ root = create();
+ });
+ expect(root.toJSON().props.style.color).toBe('blue');
// dark theme
ReactNative.useColorScheme.mockReturnValue('dark');
@@ -73,6 +81,10 @@ describe('css.* themes', () => {
root = create();
});
expect(root.toJSON().props.style.color).toBe('green');
+ act(() => {
+ root = create();
+ });
+ expect(root.toJSON().props.style.color).toBe('green');
});
test('css.createTheme', () => {