From 2f5d2425c19a88d09e81217e241705d56929ff67 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Mon, 12 Feb 2024 09:36:36 -0500 Subject: [PATCH] Breaking: Turn rule config into array (#2) Fixes https://github.com/DefinedNet/postcss-assign-layer/issues/1 This changes the config from a single object into an array of objects. This allows more flexibility if you have multiple different kinds of files that you want to wrap in layers (though if you only have a few, you should probably just add the layers to the files themselves for extra clarity when editing). --- README.md | 25 ++++++++++++--- index.js | 46 ++++++++++++++++++++-------- index.test.mjs | 83 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 131 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index ff56fd5..7143654 100644 --- a/README.md +++ b/README.md @@ -73,17 +73,32 @@ If you do not use PostCSS, add it according to [official docs] and set this plug module.exports = { plugins: [ require('autoprefixer'), -+ require('postcss-assign-layer')({ -+ include: '**/*.module.css', -+ layerName: 'components', -+ }), ++ require('postcss-assign-layer')(/* Optional configuration */), ], } ``` ### **Step 4:** Configure the plugin -It's possible to configure the include glob, as well as the layer name. +It's possible to configure the include glob and the layer name, and more than one set of rules can be provided. + +```diff +module.exports = { + plugins: [ + require('autoprefixer'), ++ require('postcss-assign-layer')([ ++ { ++ include: '**/*.module.css', ++ layerName: 'components', ++ }, ++ { ++ include: 'global/*.css', ++ layerName: 'base', ++ }, ++ ]), + ], +} +``` #### `include` diff --git a/index.js b/index.js index 248d774..b880f7d 100644 --- a/index.js +++ b/index.js @@ -1,27 +1,47 @@ const { createFilter } = require("@rollup/pluginutils"); +const DEFAULT_INCLUDE = "**/*.module.css"; +const DEFAULT_LAYERNAME = "components"; + /** * @type {import('postcss').PluginCreator} */ -module.exports = ({ - include = "**/*.module.css", - layerName = "components", -} = {}) => { - const filter = createFilter(include); +module.exports = ( + configItems = [ + { + include: DEFAULT_INCLUDE, + layerName: DEFAULT_LAYERNAME, + }, + ] +) => { + const filters = []; + + for (const config of configItems) { + const filter = createFilter(config.include ?? DEFAULT_INCLUDE); + filters.push({ filter, layerName: config.layerName ?? DEFAULT_LAYERNAME }); + } return { postcssPlugin: "postcss-assign-layers", async Once(root, { AtRule }) { const inputFile = root.source.input.file; - if (!filter(inputFile)) return; + const layerNames = []; + + for (const { filter, layerName } of filters) { + if (filter(inputFile)) { + layerNames.push(layerName); + } + } - const layer = new AtRule({ - name: "layer", - params: layerName, - nodes: root.nodes, - }); - root.removeAll(); - root.append(layer); + for (const layerName of layerNames) { + const layer = new AtRule({ + name: "layer", + params: layerName, + nodes: root.nodes, + }); + root.removeAll(); + root.append(layer); + } }, }; }; diff --git a/index.test.mjs b/index.test.mjs index ca6a3d3..679915b 100644 --- a/index.test.mjs +++ b/index.test.mjs @@ -53,7 +53,7 @@ describe("postcss-assign-layer", () => { color: WhiteSmoke; } }`, - { layerName: "custom" }, + [{ layerName: "custom" }], { from: filePath, } @@ -85,9 +85,11 @@ describe("postcss-assign-layer", () => { color: FireBrick; } }`, - { - include: "**/base.css", - }, + [ + { + include: "**/base.css", + }, + ], { from: filePath, } @@ -106,11 +108,82 @@ describe("postcss-assign-layer", () => { i { color: WhiteSmoke; }`, + [ + { + include: "**/base.css", + }, + ], + { + from: filePath, + } + ); + }); + + it("allows specifying layer name and pattern", async () => { + const filePath = path.resolve("test/fixtures/base.css"); + const file = readFileSync(filePath, "utf-8"); + await run( + file, + `@layer styles { + a { + color: FireBrick; + } + }`, + [ + { + include: "**/base.css", + layerName: "styles", + }, + ], + { + from: filePath, + } + ); + }); + + it("allows multiple patterns and layers", async () => { + const basePath = path.resolve("test/fixtures/base.css"); + const componentPath = path.resolve("test/fixtures/component.module.css"); + const baseFile = readFileSync(basePath, "utf-8"); + const componentFile = readFileSync(componentPath, "utf-8"); + const config = [ { include: "**/base.css", + layerName: "styles", }, { - from: filePath, + // include: "**/*.module.css", <- the default is still used for unspecified properties + layerName: "components", + }, + ]; + + await run( + baseFile, + `@layer styles { + a { + color: FireBrick; + } + }`, + config, + { + from: basePath, + } + ); + + await run( + componentFile, + `@layer components { + a { + color: BurlyWood; + } + + i { + color: WhiteSmoke; + } + }`, + config, + { + from: componentPath, } ); });