Skip to content

Commit 5fe1744

Browse files
committed
feat: support light-dark (#35)
1 parent 541511b commit 5fe1744

File tree

3 files changed

+165
-48
lines changed

3 files changed

+165
-48
lines changed

src/compiler/__tests__/compiler.test.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,37 @@ test("breaks apart comma separated variables", () => {
246246
vr: [["test", [["blue", "green"]]]],
247247
});
248248
});
249+
250+
test("light-dark()", () => {
251+
const compiled = compile(`
252+
.my-class {
253+
background-color: light-dark(#333b3c, #efefec);
254+
}`);
255+
256+
expect(compiled).toStrictEqual({
257+
s: [
258+
[
259+
"my-class",
260+
[
261+
{
262+
d: [
263+
{
264+
backgroundColor: "#333b3c",
265+
},
266+
],
267+
s: [1, 1],
268+
},
269+
{
270+
d: [
271+
{
272+
backgroundColor: "#efefec",
273+
},
274+
],
275+
m: [["=", "prefers-color-scheme", "dark"]],
276+
s: [1, 1],
277+
},
278+
],
279+
],
280+
],
281+
});
282+
});

src/compiler/declarations.ts

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ import type {
3535
UnresolvedColor,
3636
} from "lightningcss";
3737

38-
import type { StyleDescriptor, StyleFunction } from "./compiler.types";
38+
import type {
39+
StyleDescriptor,
40+
StyleFunction,
41+
StyleRule,
42+
} from "./compiler.types";
3943
import { parseEasingFunction, parseIterationCount } from "./keyframes";
4044
import { toRNProperty } from "./selectors";
4145
import type { StylesheetBuilder } from "./stylesheet";
@@ -47,9 +51,10 @@ type DeclarationType<P extends Declaration["property"]> = Extract<
4751
{ property: P }
4852
>;
4953

50-
type Parser<T extends Declaration["property"]> = (
54+
type Parser<T extends Declaration["property"] = Declaration["property"]> = (
5155
declaration: Extract<Declaration, { property: T }>,
5256
builder: StylesheetBuilder,
57+
propertyName: string,
5358
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
5459
) => StyleDescriptor | void;
5560

@@ -225,8 +230,8 @@ const parsers: {
225230
};
226231

227232
// This is missing LightningCSS types
228-
(parsers as Record<string, Parser<Declaration["property"]>>)["pointer-events"] =
229-
parsePointerEvents as Parser<Declaration["property"]>;
233+
(parsers as Record<string, Parser>)["pointer-events"] =
234+
parsePointerEvents as Parser;
230235

231236
const validProperties = new Set(Object.keys(parsers));
232237

@@ -250,34 +255,30 @@ export function parseDeclaration(
250255

251256
if (declaration.property === "unparsed") {
252257
parseDeclarationUnparsed(declaration, builder);
253-
return;
254258
} else if (declaration.property === "custom") {
255259
parseDeclarationCustom(declaration, builder);
256-
return;
260+
} else {
261+
parseWithParser(declaration, builder);
257262
}
263+
}
258264

265+
function parseWithParser(declaration: Declaration, builder: StylesheetBuilder) {
259266
if (declaration.property in parsers) {
260-
const property =
261-
propertyRename[declaration.property] ?? declaration.property;
267+
const parser = parsers[declaration.property] as Parser;
262268

263-
const parser = parsers[
264-
declaration.property as keyof typeof parsers
265-
] as unknown as (
266-
b: typeof declaration,
267-
builder: StylesheetBuilder,
268-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
269-
) => StyleDescriptor | void;
269+
builder.descriptorProperty = declaration.property;
270270

271-
const value = parser(declaration, builder);
271+
const value = parser(declaration, builder, declaration.property);
272272

273273
if (value !== undefined) {
274-
builder.addDescriptor(property, value);
274+
builder.addDescriptor(
275+
propertyRename[declaration.property] ?? declaration.property,
276+
value,
277+
);
275278
}
276279
} else {
277-
builder.addWarning("property", (declaration as Declaration).property);
280+
builder.addWarning("property", declaration.property);
278281
}
279-
280-
return;
281282
}
282283

283284
function parseInsetBlock(
@@ -803,14 +804,16 @@ export function parseDeclarationUnparsed(
803804
/**
804805
* React Native doesn't support all the logical properties
805806
*/
806-
const rename = propertyRename[declaration.value.propertyId.property];
807+
const rename = propertyRename[property];
807808
if (rename) {
808809
property = rename;
809810
}
810811

811812
/**
812813
* Unparsed shorthand properties need to be parsed at runtime
813814
*/
815+
builder.descriptorProperty = property;
816+
814817
if (unparsedRuntimeParsing.has(property)) {
815818
const args = parseUnparsed(declaration.value.value, builder);
816819

@@ -1369,9 +1372,20 @@ export function parseColor(cssColor: CssColor, builder: StylesheetBuilder) {
13691372
switch (cssColor.type) {
13701373
case "currentcolor":
13711374
return [{}, "var", "__rn-css-current-color"] as const;
1372-
case "light-dark":
1373-
// TODO: Handle light-dark colors
1374-
return;
1375+
case "light-dark": {
1376+
const extraRule: StyleRule = {
1377+
s: [],
1378+
m: [["=", "prefers-color-scheme", "dark"]],
1379+
};
1380+
1381+
builder.addUnnamedDescriptor(
1382+
parseColor(cssColor.dark, builder),
1383+
false,
1384+
extraRule,
1385+
);
1386+
builder.addExtraRule(extraRule);
1387+
return parseColor(cssColor.light, builder);
1388+
}
13751389
case "rgb": {
13761390
color = new Color({
13771391
space: "sRGB",
@@ -2451,8 +2465,18 @@ export function parseUnresolvedColor(
24512465
color.type,
24522466
[color.h, color.s, color.l, parseUnparsed(color.alpha, builder)],
24532467
];
2454-
case "light-dark":
2455-
return undefined;
2468+
case "light-dark": {
2469+
const extraRule = builder.extendRule({
2470+
m: [["=", "prefers-color-scheme", "dark"]],
2471+
});
2472+
builder.addUnnamedDescriptor(
2473+
reduceParseUnparsed(color.dark, builder),
2474+
false,
2475+
extraRule,
2476+
);
2477+
builder.addExtraRule(extraRule);
2478+
return reduceParseUnparsed(color.light, builder);
2479+
}
24562480
default:
24572481
color satisfies never;
24582482
}

0 commit comments

Comments
 (0)