-
-
Notifications
You must be signed in to change notification settings - Fork 136
/
Copy pathpostcss-optimize-default-theme.mjs
60 lines (50 loc) · 1.65 KB
/
postcss-optimize-default-theme.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import postcssSelectorParser from 'postcss-selector-parser'
const defaultThemeMatcher = /@theme +default/
const colorThemeMatcher = /prefers-color-scheme:\s+(light|dark)/i
export const postcssOptimizeDefaultTheme = () => {
let shouldProcess = false
return {
postcssPlugin: 'postcss-optimize-default-theme',
Once: (css) => {
shouldProcess = defaultThemeMatcher.test(css.source.input.css)
},
AtRule: {
media: (rule) => {
if (!shouldProcess) return
const matched = rule.params.match(colorThemeMatcher)
if (matched) {
if (matched[1] === 'dark') {
rule.walkRules((rule) => {
postcssSelectorParser((selectorRoot) => {
selectorRoot.walkTags((tag) => {
const normalizedTagName = tag.value.toLowerCase()
if (normalizedTagName === 'section') {
tag.parent.insertAfter(
tag,
postcssSelectorParser.pseudo({
value: ':where(.invert)',
}),
)
}
})
}).processSync(rule, { updateSelector: true })
})
// Append a rule of dark theme after the light theme
rule.next().after(rule.nodes)
}
rule.replaceWith(rule.nodes)
}
},
},
Rule(rule) {
if (!shouldProcess) return
const ss = rule.selectors.filter((s) => !s.startsWith('.markdown-body'))
if (ss.length > 0) {
rule.selectors = ss
} else {
rule.remove()
}
},
}
}
postcssOptimizeDefaultTheme.postcss = true