Skip to content

Commit

Permalink
Transform layers feature, bumped deps (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
salceson authored Feb 14, 2024
1 parent 60c5c3a commit c34ffe5
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 88 deletions.
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# PostCSS Remove Declaration

[PostCSS](https://postcss.org) plugin to remove declarations by selector.
[PostCSS](https://postcss.org) plugin to remove declarations by selector and to transform layered rules to unlayered
ones.

## 💿 Installation

Expand All @@ -18,19 +19,20 @@ $ yarn add @evidenceprime/postcss-remove-declaration --dev

## 🚀 Usage

Once you have done the installation, you will need to configure plugin by creating a `postcss.config.js` file in the root of your project. As an example:
Once you have done the installation, you will need to configure plugin by creating a `postcss.config.js` file in the
root of your project. As an example:

```javascript
module.exports = {
plugins: [
require("@evidenceprime/postcss-remove-declaration")({
require('@evidenceprime/postcss-remove-declaration')({
remove: {
".a": "*",
".b": "color",
".c": ["color", "background-color"],
".d": {
color: "crimson",
"background-color": "tomato",
'.a': '*',
'.b': 'color',
'.c': ['color', 'background-color'],
'.d': {
color: 'crimson',
'background-color': 'tomato',
},
},
}),
Expand All @@ -40,9 +42,10 @@ module.exports = {

## ⚙️ Properties

| Property | Required | Type | Description |
| -------- | -------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| remove | `true` | `String`, `Array`, `Object` | An object where each specified key is a CSS selector and each value is either `"*"` indicating that all rules for that selector should be removed, a string matching the CSS property name to remove (e.g. `color`), an array of strings containing CSS properties to be removed (e.g. `["color", "background-color"]`), or an object where each entry specifies declaration in which key is a `CSS` property and value is a `CSS` value (e.g `{ color: "cyan" }`). In the object mode you can also define whether you want to only target css declarations where !important is set. Eg. `{ color: "cyan" }` will target all declarations where color is cyan but `{ color: "cyan !important" }` will only target declarations in which have !important set.|
| Property | Required | Type | Default | Description |
|-------------------------------|----------|-----------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| remove | `false` | `String`, `Array`, `Object` | `{}` | An object where each specified key is a CSS selector and each value is either `"*"` indicating that all rules for that selector should be removed, a string matching the CSS property name to remove (e.g. `color`), an array of strings containing CSS properties to be removed (e.g. `["color", "background-color"]`), or an object where each entry specifies declaration in which key is a `CSS` property and value is a `CSS` value (e.g `{ color: "cyan" }`). In the object mode you can also define whether you want to only target css declarations where !important is set. Eg. `{ color: "cyan" }` will target all declarations where color is cyan but `{ color: "cyan !important" }` will only target declarations in which have !important set. |
| transformLayersToNormalStyles | `false` | `Boolean`, `String[]` | `false` | You can transform rules inside all layers (by setting to `true`) or specific ones (by setting to e.g. `["test"]`) to an unlayered rules. |

## Powered by

Expand Down
19 changes: 17 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,34 @@ export type PostCssRemoveObjectType = {
export type PostCssRemoveArrayOrObjectType = string[] | PostCssRemoveObjectType;

export type PostCssRemoveDeclarationOptions = {
remove: {
remove?: {
[selector: string]: string | PostCssRemoveArrayOrObjectType;
};
transformLayersToNormalStyles?: boolean | string[];
};

export const PostCssRemoveDeclarationPlugin: PluginCreator<PostCssRemoveDeclarationOptions> = (
options?: PostCssRemoveDeclarationOptions
): Plugin => {
const { remove: selectorsToRemove } = options || { remove: {} };
const { remove: selectorsToRemove = {}, transformLayersToNormalStyles = false } = options || {};
const transformLayersToNormalStylesTrimmed: PostCssRemoveDeclarationOptions['transformLayersToNormalStyles'] =
Array.isArray(transformLayersToNormalStyles)
? transformLayersToNormalStyles.map((layer) => layer.trim())
: transformLayersToNormalStyles;

return {
postcssPlugin: 'postcss-remove-declaration',
prepare: (css: Result) => {
css.root.walkAtRules('layer', (atRule) => {
if (
(Array.isArray(transformLayersToNormalStylesTrimmed) &&
transformLayersToNormalStylesTrimmed.includes(atRule.params.trim())) ||
transformLayersToNormalStylesTrimmed === true
) {
atRule.before(atRule.nodes);
atRule.remove();
}
});
css.root.walkRules((rule: Rule) => {
const toRemoveForRule = selectorsToRemove[removeLineBreaks(rule.selector)];
if (!toRemoveForRule) {
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@
"postcss": ">= 8.0.0"
},
"devDependencies": {
"@types/jest": "^29.5.11",
"@types/node": "^20.10.5",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@types/jest": "^29.5.12",
"@types/node": "^20.11.17",
"@typescript-eslint/eslint-plugin": "^7.0.1",
"@typescript-eslint/parser": "^7.0.1",
"eslint": "^8.56.0",
"jest": "^29.7.0",
"jest-junit": "^16.0.0",
"postcss": "^8.4.32",
"prettier": "^3.1.1",
"ts-jest": "^29.1.1",
"postcss": "^8.4.35",
"prettier": "^3.2.5",
"ts-jest": "^29.1.2",
"typescript": "^5.3.3"
},
"jest-junit": {
Expand Down
26 changes: 26 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,30 @@ describe('PostCssRemoveDeclarationPlugin', () => {
const p = await postcss(plugins).process(css, { from: undefined });
expect(p.css).toMatchInlineSnapshot(`".a { font-size: 14px; } .b { color: red }"`);
});

it('should correctly transform layers to normal styles', async () => {
const css = '@layer test { .a { color: red; font-size: 14px; } .b { color: red } }';
const expectedCss = `" .a { color: red; font-size: 14px; } .b { color: red }"`;
const plugins = [
PostCssRemoveDeclarationPlugin({
remove: {},
transformLayersToNormalStyles: true,
}),
];
const p = await postcss(plugins).process(css, { from: undefined });
expect(p.css).toMatchInlineSnapshot(expectedCss);
});

it('should correctly transform only passed layers to normal styles', async () => {
const css = '@layer test { .a { color: red; font-size: 14px; } } @layer troll { .b { color: red } }';
const expectedCss = `" .a { color: red; font-size: 14px; } @layer troll { .b { color: red } }"`;
const plugins = [
PostCssRemoveDeclarationPlugin({
remove: {},
transformLayersToNormalStyles: ['test'],
}),
];
const p = await postcss(plugins).process(css, { from: undefined });
expect(p.css).toMatchInlineSnapshot(expectedCss);
});
});
Loading

0 comments on commit c34ffe5

Please sign in to comment.