From b1e2c8fd5cb5dfa46bc440a12eafaf56cd844b1c Mon Sep 17 00:00:00 2001 From: Philipp Tanlak Date: Mon, 24 Nov 2025 20:54:57 +0100 Subject: Docs --- .../src/postcss-plugins/nesting/plugin.js | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 node_modules/tailwindcss/src/postcss-plugins/nesting/plugin.js (limited to 'node_modules/tailwindcss/src/postcss-plugins/nesting/plugin.js') diff --git a/node_modules/tailwindcss/src/postcss-plugins/nesting/plugin.js b/node_modules/tailwindcss/src/postcss-plugins/nesting/plugin.js new file mode 100644 index 0000000..a13cfd4 --- /dev/null +++ b/node_modules/tailwindcss/src/postcss-plugins/nesting/plugin.js @@ -0,0 +1,80 @@ +import postcss from 'postcss' +import postcssNested from 'postcss-nested' + +export function nesting(opts = postcssNested) { + return (root, result) => { + root.walkAtRules('screen', (rule) => { + rule.name = 'media' + rule.params = `screen(${rule.params})` + }) + + root.walkAtRules('apply', (rule) => { + rule.before(postcss.decl({ prop: '__apply', value: rule.params, source: rule.source })) + rule.remove() + }) + + let plugin = (() => { + if ( + typeof opts === 'function' || + (typeof opts === 'object' && opts?.hasOwnProperty?.('postcssPlugin')) + ) { + return opts + } + + if (typeof opts === 'string') { + return require(opts) + } + + if (Object.keys(opts).length <= 0) { + return postcssNested + } + + throw new Error('tailwindcss/nesting should be loaded with a nesting plugin.') + })() + + postcss([plugin]).process(root, result.opts).sync() + + root.walkDecls('__apply', (decl) => { + decl.before(postcss.atRule({ name: 'apply', params: decl.value, source: decl.source })) + decl.remove() + }) + + /** + * Use a private PostCSS API to remove the "clean" flag from the entire AST. + * This is done because running process() on the AST will set the "clean" + * flag on all nodes, which we don't want. + * + * This causes downstream plugins using the visitor API to be skipped. + * + * This is guarded because the PostCSS API is not public + * and may change in future versions of PostCSS. + * + * See https://github.com/postcss/postcss/issues/1712 for more details + * + * @param {import('postcss').Node} node + */ + function markDirty(node) { + if (!('markDirty' in node)) { + return + } + + // Traverse the tree down to the leaf nodes + if (node.nodes) { + node.nodes.forEach((n) => markDirty(n)) + } + + // If it's a leaf node mark it as dirty + // We do this here because marking a node as dirty + // will walk up the tree and mark all parents as dirty + // resulting in a lot of unnecessary work if we did this + // for every single node + if (!node.nodes) { + node.markDirty() + } + } + + markDirty(root) + + return root + } +} -- cgit v1.2.3