@@ -49,69 +49,82 @@ function getHtmlSelector(selector) {
4949}
5050
5151/**
52- * @param {import('postcss').Helpers } helpers
53- * @param {import('postcss').AtRule } atRule
52+ * @typedef Options
53+ * @property {string } name - name of the custom at-rule, default to 'color-scheme'
54+ * @property {'throw' | 'skip' } onInvalidParameter - behavior when an invalid parameter is found, default to 'throw'
5455 */
55- function transform ( helpers , atRule ) {
56- const theme = atRule . params . trim ( ) ;
57- if ( ! theme ) {
58- throw atRule . error ( noParameter ( ) ) ;
59- }
60-
61- if ( ! [ 'light' , 'dark' ] . includes ( theme ) ) {
62- throw atRule . error ( invalidParameter ( theme ) ) ;
63- }
64- const complement = theme === 'dark' ? 'light' : 'dark' ;
65-
66- const firstNonAtRuleParent = findFirstNonAtRuleParent ( atRule ) ;
67-
68- const isAtRoot = ! firstNonAtRuleParent ;
69- const isNestedInHtml = firstNonAtRuleParent && ! ! getHtmlSelector ( firstNonAtRuleParent . selector ) ;
70-
71- let implicitSelector = `:not([data-color-scheme="${ complement } "])` ;
72- let explicitSelector = `[data-color-scheme="${ theme } "]` ;
73- if ( isNestedInHtml ) {
74- implicitSelector = `&${ implicitSelector } ` ;
75- explicitSelector = `&${ explicitSelector } ` ;
76- } else if ( ! isAtRoot ) {
77- implicitSelector = `html${ implicitSelector } &` ;
78- explicitSelector = `html${ explicitSelector } &` ;
79- } else {
80- implicitSelector = `html${ implicitSelector } ` ;
81- explicitSelector = `html${ explicitSelector } ` ;
82- transformFirstChildrenNonAtRule ( helpers , atRule ) ;
83- }
84-
85- const implicitRule = new helpers . Rule ( {
86- selector : implicitSelector ,
87- nodes : atRule . nodes ,
88- } ) ;
89- const implicitAtRule = new helpers . AtRule ( {
90- source : atRule . source ,
91- name : 'media' ,
92- params : `(prefers-color-scheme: ${ theme } )` ,
93- nodes : [ implicitRule ] ,
94- } ) ;
95-
96- const explicitRule = new helpers . Rule ( {
97- selector : explicitSelector ,
98- source : atRule . source ,
99- nodes : atRule . nodes ,
100- } ) ;
101-
102- atRule . replaceWith ( implicitAtRule , explicitRule ) ;
103- }
10456
10557/**
10658 * @namespace
59+ * @param {Partial<Options> } [options]
10760 * @returns {import('postcss').Plugin }
10861 * @property
10962 */
110- function pluginCreator ( ) {
63+ function pluginCreator ( options = { } ) {
64+ const name = options ?. name ?? 'color-scheme' ;
65+ let onInvalidParameter = options ?. onInvalidParameter ;
66+ if ( ! onInvalidParameter ) {
67+ onInvalidParameter = name === 'color-scheme' ? 'throw' : 'skip' ;
68+ }
11169 return {
11270 postcssPlugin : 'postcss-color-scheme' ,
11371 AtRule : {
114- 'color-scheme' : ( atRule , helpers ) => transform ( helpers , atRule ) ,
72+ [ name ] : function ( atRule , helpers ) {
73+ const theme = atRule . params . trim ( ) ;
74+ if ( ! theme ) {
75+ if ( onInvalidParameter === 'throw' ) {
76+ throw atRule . error ( noParameter ( ) ) ;
77+ }
78+ return ;
79+ }
80+
81+ if ( ! [ 'light' , 'dark' ] . includes ( theme ) ) {
82+ if ( onInvalidParameter === 'throw' ) {
83+ throw atRule . error ( invalidParameter ( theme ) ) ;
84+ }
85+ return ;
86+ }
87+ const complement = theme === 'dark' ? 'light' : 'dark' ;
88+
89+ const firstNonAtRuleParent = findFirstNonAtRuleParent ( atRule ) ;
90+
91+ const isAtRoot = ! firstNonAtRuleParent ;
92+ const isNestedInHtml =
93+ firstNonAtRuleParent && ! ! getHtmlSelector ( firstNonAtRuleParent . selector ) ;
94+
95+ let implicitSelector = `:not([data-color-scheme="${ complement } "])` ;
96+ let explicitSelector = `[data-color-scheme="${ theme } "]` ;
97+ if ( isNestedInHtml ) {
98+ implicitSelector = `&${ implicitSelector } ` ;
99+ explicitSelector = `&${ explicitSelector } ` ;
100+ } else if ( ! isAtRoot ) {
101+ implicitSelector = `html${ implicitSelector } &` ;
102+ explicitSelector = `html${ explicitSelector } &` ;
103+ } else {
104+ implicitSelector = `html${ implicitSelector } ` ;
105+ explicitSelector = `html${ explicitSelector } ` ;
106+ transformFirstChildrenNonAtRule ( helpers , atRule ) ;
107+ }
108+
109+ const implicitRule = new helpers . Rule ( {
110+ selector : implicitSelector ,
111+ nodes : atRule . nodes ,
112+ } ) ;
113+ const implicitAtRule = new helpers . AtRule ( {
114+ source : atRule . source ,
115+ name : 'media' ,
116+ params : `(prefers-color-scheme: ${ theme } )` ,
117+ nodes : [ implicitRule ] ,
118+ } ) ;
119+
120+ const explicitRule = new helpers . Rule ( {
121+ selector : explicitSelector ,
122+ source : atRule . source ,
123+ nodes : atRule . nodes ,
124+ } ) ;
125+
126+ atRule . replaceWith ( implicitAtRule , explicitRule ) ;
127+ } ,
115128 } ,
116129 } ;
117130}
0 commit comments