UNPKG

@csstools/postcss-light-dark-function

Version:
2 lines (1 loc) 3.81 kB
"use strict";var e=require("@csstools/postcss-progressive-custom-properties"),o=require("@csstools/css-tokenizer"),t=require("@csstools/utilities"),r=require("@csstools/css-parser-algorithms");const s="--csstools-color-scheme--light",n="initial";function toggleNameGenerator(e){return`--csstools-light-dark-toggle--${e}`}const i=/dark/i,a=/light/i;function colorSchemes(e){const t=o.tokenize({css:e});let r=!1,s=!1;return t.forEach((e=>{o.isTokenIdent(e)&&(a.test(e[4].value)?r=!0:i.test(e[4].value)&&(s=!0))})),[r,s]}const c=/^light-dark$/i;function isComma(e){return r.isTokenNode(e)&&o.isTokenComma(e.value)}function parseLightDark(e){if(!r.isFunctionNode(e)||!c.test(e.getName()))return!1;const o=e.value.filter((e=>!r.isWhitespaceNode(e)&&!r.isCommentNode(e)));if(3!==o.length)return!1;let t=o[0];const s=o[1];let n=o[2];if(!t||!s||!n)return!1;if(!isComma(s))return!1;if(isComma(t)||isComma(n))return!1;if(r.isFunctionNode(t)){const e=[t];r.walk(e,(({node:e,parent:o},t)=>{recurseLightDark(e,o,t,!0)})),[t]=e}if(r.isFunctionNode(n)){const e=[n];r.walk(e,(({node:e,parent:o},t)=>{recurseLightDark(e,o,t,!1)})),[n]=e}return[t,n]}function recurseLightDark(e,o,t,s){if("number"!=typeof t)return;const n=parseLightDark(e);if(!n)return;let i=n[s?0:1];if(r.isFunctionNode(i)){const e=[i];r.walk(e,(({node:e,parent:o},t)=>{recurseLightDark(e,o,t,s)})),[i]=e}o.value[t]=i}function transformLightDark(e,t){const n=new Map,i=r.replaceComponentValues(r.parseCommaSeparatedListOfComponentValues(o.tokenize({css:e})),(e=>{const i=parseLightDark(e);if(!i)return;const[a,c]=i,u=t();return n.set(u,`var(${s}) ${c.toString()}`),new r.FunctionNode([o.TokenType.Function,"var(",-1,-1,{value:"var"}],[o.TokenType.CloseParen,")",-1,-1,void 0],[new r.TokenNode([o.TokenType.Ident,u,-1,-1,{value:u}]),new r.TokenNode([o.TokenType.Comma,",",-1,-1,void 0]),new r.WhitespaceNode([[o.TokenType.Whitespace," ",-1,-1,void 0]]),a])}));return{value:r.stringify(i),toggles:n}}function newNestedRuleWithSupportsNot(e,o,t,r){const s=o({selector:"& *",source:e.source});if(!r)return{inner:s,outer:s};const n=t({name:"supports",params:"not (color: light-dark(tan, tan))",source:e.source});return n.append(s),{inner:s,outer:n}}const u=/^color-scheme$/i,l=/\blight-dark\(/i,basePlugin=e=>({postcssPlugin:"postcss-light-dark-function",prepare(){let o=0;const currentToggleNameGenerator=()=>toggleNameGenerator(o++),r=new Map;return{postcssPlugin:"postcss-light-dark-function",Declaration(o,{atRule:i,rule:a}){const c=o.parent;if(c){if(u.test(o.prop)){if(c.some((e=>"decl"===e.type&&e.prop===s)))return;const[e,t]=colorSchemes(o.value);if(e&&t){o.cloneBefore({prop:s,value:n});const e=c.clone();e.removeAll(),e.append(o.clone({prop:s,value:" "}));const t=i({name:"media",params:"(prefers-color-scheme: dark)",source:c.source});return t.append(e),void c.after(t)}return t?void o.cloneBefore({prop:s,value:" "}):e?void o.cloneBefore({prop:s,value:n}):void 0}if(l.test(o.value)){if(t.hasFallback(o))return;if(t.hasSupportsAtRuleAncestor(o,l))return;const s=transformLightDark(o.value,currentToggleNameGenerator);if(s.value===o.value)return;for(const[e,t]of s.toggles)o.cloneBefore({prop:e,value:t});if(o.cloneBefore({value:s.value}),o.variable&&o.parent){const t=r.get(o.parent)??newNestedRuleWithSupportsNot(o,a,i,e?.preserve);for(const[e,r]of s.toggles)t.inner.append(o.clone({prop:e,value:r}));t.inner.append(o.clone({value:s.value})),r.has(o.parent)||(o.parent.append(t.outer),r.set(o.parent,t))}e?.preserve||o.remove()}}}}}});basePlugin.postcss=!0;const postcssPlugin=o=>{const t=Object.assign({enableProgressiveCustomProperties:!0,preserve:!0},o);return t.enableProgressiveCustomProperties&&t.preserve?{postcssPlugin:"postcss-light-dark-function",plugins:[e(),basePlugin(t)]}:basePlugin(t)};postcssPlugin.postcss=!0,module.exports=postcssPlugin;