Skip to content

Commit 2b39ee9

Browse files
author
Quang Phan
committed
feat: support for usage in html
1 parent aa57e28 commit 2b39ee9

5 files changed

Lines changed: 122 additions & 16 deletions

File tree

.changeset/good-eyes-complain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'postcss-color-scheme': patch
3+
---
4+
5+
added support when nested in html itself

lib/color-scheme.js

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,32 @@ function findRootOrMediaNode(node) {
1212
return findRootOrMediaNode(parent);
1313
}
1414

15+
/**
16+
* @param {import('postcss').Helpers} helpers
17+
* @param {import('postcss').Container} parent
18+
* @param {string} additionalChunk
19+
* @param {boolean} global
20+
* @returns {string}
21+
*/
22+
function constructSelector(helpers, parent, additionalChunk, global) {
23+
const parentSelectors = helpers.list.comma(/** @type {import('postcss').Rule} */(parent).selector);
24+
/** @type {string[]} */
25+
let selectors = [];
26+
for (const selector of parentSelectors) {
27+
let joinedSelector = '';
28+
if (selector.startsWith('html')) {
29+
joinedSelector = `html${additionalChunk}${selector.substring('html'.length)}`;
30+
if (global) joinedSelector = `:global(${joinedSelector})`;
31+
} else {
32+
let chunkToAdd = `html${additionalChunk}`;
33+
if (global) chunkToAdd = `:global(${chunkToAdd})`;
34+
joinedSelector = `${chunkToAdd} ${selector}`;
35+
}
36+
selectors.push(joinedSelector);
37+
}
38+
return selectors.join(', ');
39+
}
40+
1541
/**
1642
* @param {import('postcss').Helpers} helpers
1743
* @param {import('postcss').AtRule} atRule
@@ -30,15 +56,9 @@ function transform(helpers, atRule, theme, config = {}) {
3056
}
3157
const container = findRootOrMediaNode(parent);
3258

33-
let htmlSelectorChunk = `html:not([data-color-scheme="${theme === 'dark' ? 'light' : 'dark'}"])`;
34-
if (global) {
35-
htmlSelectorChunk = `:global(${htmlSelectorChunk})`;
36-
}
59+
let selectorColorSchemeChunk = `:not([data-color-scheme="${theme === 'dark' ? 'light' : 'dark'}"])`;
3760
const implicitRule = new helpers.Rule({
38-
selector: helpers.list
39-
.comma(/** @type {import('postcss').Rule} */(parent).selector)
40-
.map((s) => `${htmlSelectorChunk} ${s}`)
41-
.join(', '),
61+
selector: constructSelector(helpers, parent, selectorColorSchemeChunk, global),
4262
nodes: atRule.nodes,
4363
});
4464
const implicitAtRule = new helpers.AtRule({
@@ -56,15 +76,9 @@ function transform(helpers, atRule, theme, config = {}) {
5676
container.append(implicitAtRule);
5777
}
5878

59-
htmlSelectorChunk = `html[data-color-scheme="${theme}"]`;
60-
if (global) {
61-
htmlSelectorChunk = `:global(${htmlSelectorChunk})`;
62-
}
79+
selectorColorSchemeChunk = `[data-color-scheme="${theme}"]`;
6380
const explicitRule = new helpers.Rule({
64-
selector: helpers.list
65-
.comma(/** @type {import('postcss').Rule} */(parent).selector)
66-
.map((s) => `${htmlSelectorChunk} ${s}`)
67-
.join(', '),
81+
selector: constructSelector(helpers, parent, selectorColorSchemeChunk, global),
6882
source: atRule.source,
6983
nodes: atRule.nodes,
7084
});

lib/color-scheme.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,14 @@ test('unsupported parameter', async () => {
106106
processor.process(input, { from: undefined })
107107
).rejects.toThrowError(/Invalid parameter/);
108108
});
109+
110+
test('selector is html itself', async () => {
111+
const input = readCSS('./tests/selector-is-html.input.css');
112+
const output = readCSS('./tests/selector-is-html.output.css');
113+
114+
/** @type {any} */
115+
const processor = postcss([postcssNesting, plugin()]);
116+
const result = await processor.process(input, { from: undefined });
117+
118+
compareCSS(output, result.css);
119+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
html {
2+
color: blue;
3+
4+
@light {
5+
color: white;
6+
}
7+
8+
@dark {
9+
color: black;
10+
}
11+
12+
&.nested, &[nested] {
13+
@dark {
14+
color: yellow;
15+
}
16+
}
17+
}
18+
19+
html.class {
20+
@dark {
21+
color: red;
22+
}
23+
}
24+
25+
html[lang="en"] {
26+
@light {
27+
color: blue;
28+
}
29+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
html {
2+
color: blue;
3+
}
4+
5+
html[data-color-scheme="dark"].nested, html[data-color-scheme="dark"][nested] {
6+
color: yellow
7+
}
8+
9+
html[data-color-scheme="dark"] {
10+
color: black;
11+
}
12+
13+
html[data-color-scheme="light"] {
14+
color: white;
15+
}
16+
17+
html[data-color-scheme="dark"].class {
18+
color: red;
19+
}
20+
21+
html[data-color-scheme="light"][lang="en"] {
22+
color: blue;
23+
}
24+
25+
@media (prefers-color-scheme: dark) {
26+
html:not([data-color-scheme="light"]) {
27+
color: black;
28+
}
29+
30+
html:not([data-color-scheme="light"]).class {
31+
color: red;
32+
}
33+
34+
html:not([data-color-scheme="light"]).nested, html:not([data-color-scheme="light"])[nested] {
35+
color: yellow
36+
}
37+
}
38+
39+
@media (prefers-color-scheme: light) {
40+
html:not([data-color-scheme="dark"]) {
41+
color: white;
42+
}
43+
44+
html:not([data-color-scheme="dark"])[lang="en"] {
45+
color: blue;
46+
}
47+
}

0 commit comments

Comments
 (0)