postcss-color-scheme
Advanced tools
Comparing version 0.3.0 to 0.3.1
# Changelog | ||
## 0.3.1 | ||
### Patch Changes | ||
- [`2b39ee9`](https://github.com/vnphanquang/postcss-color-scheme/commit/2b39ee9f65633d39155e00883b69cc96e1d5e173) Thanks [@vnphanquang](https://github.com/vnphanquang)! - added support when nested in html itself | ||
## 0.3.0 | ||
@@ -4,0 +10,0 @@ |
/** @typedef {{ global?: boolean }} ColorSchemeTransformConfig */ | ||
/** | ||
* @param {import('postcss').Node} node | ||
* @param {import('postcss').Container | import('postcss').Document} node | ||
* @returns {import('postcss').Container} | ||
*/ | ||
function findRootOrMediaNode(node) { | ||
const parent = node.parent; | ||
if (parent.type === 'root' || (parent.type === 'atrule' && parent.name === 'media')) { | ||
const parent = /** @type {import('postcss').Container} */(node.parent); | ||
if (parent.type === 'root' || (parent.type === 'atrule' && /** @type {import('postcss').AtRule} */(parent).name === 'media')) { | ||
return parent; | ||
@@ -17,2 +17,28 @@ } | ||
* @param {import('postcss').Helpers} helpers | ||
* @param {import('postcss').Container} parent | ||
* @param {string} additionalChunk | ||
* @param {boolean} global | ||
* @returns {string} | ||
*/ | ||
function constructSelector(helpers, parent, additionalChunk, global) { | ||
const parentSelectors = helpers.list.comma(/** @type {import('postcss').Rule} */(parent).selector); | ||
/** @type {string[]} */ | ||
let selectors = []; | ||
for (const selector of parentSelectors) { | ||
let joinedSelector = ''; | ||
if (selector.startsWith('html')) { | ||
joinedSelector = `html${additionalChunk}${selector.substring('html'.length)}`; | ||
if (global) joinedSelector = `:global(${joinedSelector})`; | ||
} else { | ||
let chunkToAdd = `html${additionalChunk}`; | ||
if (global) chunkToAdd = `:global(${chunkToAdd})`; | ||
joinedSelector = `${chunkToAdd} ${selector}`; | ||
} | ||
selectors.push(joinedSelector); | ||
} | ||
return selectors.join(', '); | ||
} | ||
/** | ||
* @param {import('postcss').Helpers} helpers | ||
* @param {import('postcss').AtRule} atRule | ||
@@ -29,15 +55,12 @@ * @param {'dark' | 'light'} theme | ||
const parent = atRule.parent; | ||
if (!parent) { | ||
throw atRule.error(`Expect @${theme} to be nested in a selector or a media query.`); | ||
} | ||
const container = findRootOrMediaNode(parent); | ||
let htmlSelectorChunk = `html:not([data-color-scheme="${theme === 'dark' ? 'light' : 'dark'}"])`; | ||
if (global) { | ||
htmlSelectorChunk = `:global(${htmlSelectorChunk})`; | ||
} | ||
let selectorColorSchemeChunk = `:not([data-color-scheme="${theme === 'dark' ? 'light' : 'dark'}"])`; | ||
const implicitRule = new helpers.Rule({ | ||
selector: helpers.list | ||
.comma(parent.selector) | ||
.map((s) => `${htmlSelectorChunk} ${s}`) | ||
.join(', '), | ||
selector: constructSelector(helpers, parent, selectorColorSchemeChunk, global), | ||
nodes: atRule.nodes, | ||
}) | ||
}); | ||
const implicitAtRule = new helpers.AtRule({ | ||
@@ -49,5 +72,5 @@ source: atRule.source, | ||
}); | ||
const existingAtRule = container.nodes.find((node) => { | ||
const existingAtRule = /** @type {import('postcss').Rule} */(container.nodes.find((node) => { | ||
return node.type === implicitAtRule.type && node.name === implicitAtRule.name && node.params === implicitAtRule.params; | ||
}); | ||
})); | ||
if (existingAtRule) { | ||
@@ -59,11 +82,5 @@ existingAtRule.append(implicitRule); | ||
htmlSelectorChunk = `html[data-color-scheme="${theme}"]`; | ||
if (global) { | ||
htmlSelectorChunk = `:global(${htmlSelectorChunk})`; | ||
} | ||
selectorColorSchemeChunk = `[data-color-scheme="${theme}"]`; | ||
const explicitRule = new helpers.Rule({ | ||
selector: helpers.list | ||
.comma(parent.selector) | ||
.map((s) => `${htmlSelectorChunk} ${s}`) | ||
.join(', '), | ||
selector: constructSelector(helpers, parent, selectorColorSchemeChunk, global), | ||
source: atRule.source, | ||
@@ -79,5 +96,8 @@ nodes: atRule.nodes, | ||
/** | ||
* @type {import('postcss').PluginCreator} | ||
* @namespace | ||
* @param {{}} _opts | ||
* @returns {import('postcss').Plugin} | ||
* @property | ||
*/ | ||
module.exports = function (opts = {}) { | ||
function pluginCreator(_opts = {}) { | ||
return { | ||
@@ -90,4 +110,9 @@ postcssPlugin: 'postcss-color-scheme', | ||
}; | ||
}; | ||
} | ||
module.exports.postcss = true; | ||
/** | ||
* @memberof pluginCreator | ||
*/ | ||
pluginCreator.postcss = true; | ||
module.exports = pluginCreator; |
{ | ||
"name": "postcss-color-scheme", | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"description": "postcss plugin for handling prefers-color-scheme", | ||
@@ -29,13 +29,16 @@ "main": "lib/index.js", | ||
"@changesets/changelog-github": "^0.4.8", | ||
"@changesets/cli": "^2.26.1", | ||
"@vitest/coverage-istanbul": "^0.29.8", | ||
"@vitest/ui": "^0.29.8", | ||
"@changesets/cli": "^2.26.2", | ||
"@types/postcss-js": "^4.0.1", | ||
"@vitest/coverage-istanbul": "^0.33.0", | ||
"@vitest/ui": "^0.33.0", | ||
"@vnphanquang/eslint-config": "^2.0.0", | ||
"@vnphanquang/prettierrc": "^1.0.1", | ||
"postcss": "^8.4.21", | ||
"postcss": "^8.4.26", | ||
"postcss-js": "^4.0.1", | ||
"postcss-nested": "^6.0.1", | ||
"postcss-nesting": "^11.2.2", | ||
"prettier": "^2.8.7", | ||
"tailwindcss": "^3.3.1", | ||
"vitest": "^0.29.8" | ||
"postcss-nesting": "^12.0.0", | ||
"prettier": "^3.0.0", | ||
"tailwindcss": "^3.3.3", | ||
"typescript": "^5.1.6", | ||
"vitest": "^0.33.0" | ||
}, | ||
@@ -46,7 +49,11 @@ "peerDependencies": { | ||
"engines": { | ||
"pnpm": ">=8.0.0", | ||
"node": ">=16.15.0" | ||
"pnpm": ">=8.6.0", | ||
"node": ">=18.16.0" | ||
}, | ||
"packageManager": "pnpm@8.1.1", | ||
"packageManager": "pnpm@8.6.7", | ||
"volta": { | ||
"node": "18.17.0" | ||
}, | ||
"scripts": { | ||
"lint": "eslint --ignore-path .gitignore \"./**/*/*{ts,js,cjs}\"", | ||
"test": "vitest --ui --coverage", | ||
@@ -53,0 +60,0 @@ "ci:test": "vitest run --coverage", |
@@ -5,14 +5,2 @@ # postcss-color-scheme | ||
## Table of Contents | ||
- [postcss-color-scheme](#postcss-color-scheme) | ||
- [Table of Contents](#table-of-contents) | ||
- [Changelog](#changelog) | ||
- [Installation](#installation) | ||
- [Design Decisions](#design-decisions) | ||
- [Supported At Rules](#supported-at-rules) | ||
- [Global Variant](#global-variant) | ||
- [Test Cases \& Examples](#test-cases--examples) | ||
- [Tailwind Support](#tailwind-support) | ||
## [Changelog][changelog] | ||
@@ -113,2 +101,12 @@ | ||
```mermaid | ||
flowchart TD | ||
A[Has user explicitly selected theme?] -->|Yes| B[Which mode?] | ||
B --> Light | ||
B --> Dark | ||
A -->|No| C[prefers-color-scheme?] | ||
C -->Light | ||
C --->Dark | ||
``` | ||
## Supported At Rules | ||
@@ -148,3 +146,3 @@ | ||
The following table lists test cases covered by this plugin, please refer to [tests][tests] for details and to test input css as examples | ||
The following table lists test cases covered by this plugin, please refer to [tests][tests] for details and to tests' input css as examples | ||
@@ -151,0 +149,0 @@ | Test Case | Description | Input | Output | |
17056
152
15
208