From b1e2c8fd5cb5dfa46bc440a12eafaf56cd844b1c Mon Sep 17 00:00:00 2001 From: Philipp Tanlak Date: Mon, 24 Nov 2025 20:54:57 +0100 Subject: Docs --- .../lib/postcss-plugins/nesting/README.md | 42 ++++++++++ .../lib/postcss-plugins/nesting/index.js | 21 +++++ .../lib/postcss-plugins/nesting/plugin.js | 89 ++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 node_modules/tailwindcss/lib/postcss-plugins/nesting/README.md create mode 100644 node_modules/tailwindcss/lib/postcss-plugins/nesting/index.js create mode 100644 node_modules/tailwindcss/lib/postcss-plugins/nesting/plugin.js (limited to 'node_modules/tailwindcss/lib/postcss-plugins') diff --git a/node_modules/tailwindcss/lib/postcss-plugins/nesting/README.md b/node_modules/tailwindcss/lib/postcss-plugins/nesting/README.md new file mode 100644 index 0000000..49cdbb5 --- /dev/null +++ b/node_modules/tailwindcss/lib/postcss-plugins/nesting/README.md @@ -0,0 +1,42 @@ +# tailwindcss/nesting + +This is a PostCSS plugin that wraps [postcss-nested](https://github.com/postcss/postcss-nested) or [postcss-nesting](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting) and acts as a compatibility layer to make sure your nesting plugin of choice properly understands Tailwind's custom syntax like `@apply` and `@screen`. + +Add it to your PostCSS configuration, somewhere before Tailwind itself: + +```js +// postcss.config.js +module.exports = { + plugins: [ + require('postcss-import'), + require('tailwindcss/nesting'), + require('tailwindcss'), + require('autoprefixer'), + ] +} +``` + +By default, it uses the [postcss-nested](https://github.com/postcss/postcss-nested) plugin under the hood, which uses a Sass-like syntax and is the plugin that powers nesting support in the [Tailwind CSS plugin API](https://tailwindcss.com/docs/plugins#css-in-js-syntax). + +If you'd rather use [postcss-nesting](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside: + +```shell +npm install postcss-nesting +``` + +Then pass the plugin itself as an argument to `tailwindcss/nesting` in your PostCSS configuration: + +```js +// postcss.config.js +module.exports = { + plugins: [ + require('postcss-import'), + require('tailwindcss/nesting')(require('postcss-nesting')), + require('tailwindcss'), + require('autoprefixer'), + ] +} +``` + +This can also be helpful if for whatever reason you need to use a very specific version of `postcss-nested` and want to override the version we bundle with `tailwindcss/nesting` itself. + diff --git a/node_modules/tailwindcss/lib/postcss-plugins/nesting/index.js b/node_modules/tailwindcss/lib/postcss-plugins/nesting/index.js new file mode 100644 index 0000000..afb502e --- /dev/null +++ b/node_modules/tailwindcss/lib/postcss-plugins/nesting/index.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "default", { + enumerable: true, + get: function() { + return _default; + } +}); +const _plugin = require("./plugin"); +const _default = Object.assign(function(opts) { + return { + postcssPlugin: "tailwindcss/nesting", + Once (root, { result }) { + return (0, _plugin.nesting)(opts)(root, result); + } + }; +}, { + postcss: true +}); diff --git a/node_modules/tailwindcss/lib/postcss-plugins/nesting/plugin.js b/node_modules/tailwindcss/lib/postcss-plugins/nesting/plugin.js new file mode 100644 index 0000000..df08907 --- /dev/null +++ b/node_modules/tailwindcss/lib/postcss-plugins/nesting/plugin.js @@ -0,0 +1,89 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "nesting", { + enumerable: true, + get: function() { + return nesting; + } +}); +const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); +const _postcssnested = /*#__PURE__*/ _interop_require_default(require("postcss-nested")); +function _interop_require_default(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; +} +function nesting(opts = _postcssnested.default) { + return (root, result)=>{ + root.walkAtRules("screen", (rule)=>{ + rule.name = "media"; + rule.params = `screen(${rule.params})`; + }); + root.walkAtRules("apply", (rule)=>{ + rule.before(_postcss.default.decl({ + prop: "__apply", + value: rule.params, + source: rule.source + })); + rule.remove(); + }); + let plugin = (()=>{ + var _opts_hasOwnProperty; + if (typeof opts === "function" || typeof opts === "object" && (opts === null || opts === void 0 ? void 0 : (_opts_hasOwnProperty = opts.hasOwnProperty) === null || _opts_hasOwnProperty === void 0 ? void 0 : _opts_hasOwnProperty.call(opts, "postcssPlugin"))) { + return opts; + } + if (typeof opts === "string") { + return require(opts); + } + if (Object.keys(opts).length <= 0) { + return _postcssnested.default; + } + throw new Error("tailwindcss/nesting should be loaded with a nesting plugin."); + })(); + (0, _postcss.default)([ + plugin + ]).process(root, result.opts).sync(); + root.walkDecls("__apply", (decl)=>{ + decl.before(_postcss.default.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