Skip to content

Commit cf6bfb5

Browse files
committed
feat: modifyPreflightStyles option to hook into the preflight styles
1 parent 26bc43a commit cf6bfb5

File tree

4 files changed

+78
-25
lines changed

4 files changed

+78
-25
lines changed

README.md

+30-12
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Starting from version 3 it provides a powerful configuration to (optionally):
2121

2222
- 🤌 precisely control CSS selectors;
2323
- 💨 flexibly remove some CSS rules, if you need;
24-
- 🔎 or even remove particular CSS properties (if you have some specific conflicts).
24+
- 🔎 or even remove (or change) particular CSS properties (if you have some specific conflicts).
2525

2626
For ease of use, there are 3 pre-bundled isolation strategies available (as named imports) that cover 99% cases:
2727

@@ -92,15 +92,36 @@ const config = {
9292
// it's also possible to filter out some properties:
9393
// return false to remove the property,
9494
// any other value (including true and undefined) will leave the prop intact
95+
// (propsFilter is DEPRECATED - prefer using modifyPreflightStyles instead of propFilter)
9596
propsFilter: ({ selectorSet, property, value }) =>
97+
// return false to remove the property. Any other value (including true and undefined) will leave the prop intact
9698
![
9799
// removes the margin reset from a body rule
98100
selectorSet.has('body') && ['margin'].includes(property),
99101
// removes the box-sizing: border-box whenever it's found
100102
property === 'box-sizing' && value === 'border-box',
101103
// removes the font-family (except inherit) from all the rules
102104
property === 'font-family' && value !== 'inherit',
103-
].some(Boolean), // yep, "some" approach is a bit slower because it will evaluate all array conditions anyway, but it's more readable without || operators
105+
].some(Boolean),
106+
// preferred way to modify the preflight styles
107+
modifyPreflightStyles: ({ selectorSet, property, value }) => {
108+
// let's say you want to override the font family
109+
if (property === 'font-family' && value !== 'inherit') {
110+
return '"Open Sans", sans-serif';
111+
}
112+
// or body margin
113+
if (selectorSet.has('body') && property === 'margin') {
114+
return '0 4px';
115+
}
116+
// if you want to remove some property - return null
117+
if (selectorSet.has('html') && property === 'line-height') {
118+
return null;
119+
}
120+
// to keep the property as it is - you may return the original value;
121+
// but returning undefined would have the same effect,
122+
// so you may just omit such default return
123+
return value;
124+
},
104125
}),
105126
],
106127
};
@@ -199,16 +220,13 @@ const config = {
199220
? `${ruleSelector} .twp` // some custom transformation for html, :host and body
200221
: isolateForComponents('.twp')(ruleSelector), // otherwise, transform it as per components strategy (just for example)
201222

202-
// just for demo purpose - let's also filter out some properties
203-
propsFilter: ({ selectorSet, property, value }) =>
204-
![
205-
// removes the margin reset from a body rule
206-
selectorSet.has('body') && ['margin'].includes(property),
207-
// removes the box-sizing: border-box whenever it's found
208-
property === 'box-sizing' && value === 'border-box',
209-
// removes the font-family (except inherit) from all the rules
210-
property === 'font-family' && value !== 'inherit',
211-
].some(Boolean), // yep, "some" approach is a bit slower because it will evaluate all array conditions anyway, but it's more readable without || operators
223+
// just for demo purpose
224+
modifyPreflightStyles: ({ selectorSet, property, value }) => {
225+
// let's say you want to override the font family
226+
if (property === 'font-family' && value !== 'inherit') {
227+
return '"Open Sans", sans-serif';
228+
}
229+
},
212230
}),
213231
],
214232
};

demo/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</head>
1010
<body>
1111
<div class="twp bg-zinc-300 text-sky-700 m-2">
12-
<div class="border rounded border-black/50 p-4">
12+
<div class="font-mono border rounded border-black/50 p-4">
1313
<h1 class="text-3xl font-bold">Inside</h1>
1414
</div>
1515
</div>

demo/tailwind.config.js

+23-2
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,37 @@ module.exports = {
2323
// ? ruleSelector // keeps the original selector
2424
// : enableForSelector(".twp")(ruleSelector), // otherwise, transforms selector as per selected behaviour (scoped to .twp)
2525

26-
// it's also possible to filter out some properties - return false to remove the property. Any other value (including true and undefined) will leave the prop intact
26+
// it's also possible to filter out some properties
27+
// (deprecated - prefer using modifyPreflightStyles instead of propFilter)
2728
propsFilter: ({ selectorSet, property, value }) =>
29+
// return false to remove the property. Any other value (including true and undefined) will leave the prop intact
2830
![
2931
// removes the margin reset from a body rule
3032
selectorSet.has('body') && ['margin'].includes(property),
3133
// removes the box-sizing: border-box whenever it's found
3234
property === 'box-sizing' && value === 'border-box',
3335
// removes the font-family (except inherit) from all the rules
3436
property === 'font-family' && value !== 'inherit',
35-
].some(Boolean), // yep, "some" approach is a bit slower because it will evaluate all array conditions anyway, but it's more readable without || operators
37+
].some(Boolean),
38+
// preferred way to modify the preflight styles
39+
modifyPreflightStyles: ({ selectorSet, property, value }) => {
40+
// let's say you want to override the font family
41+
if (property === 'font-family' && value !== 'inherit') {
42+
return '"Open Sans", sans-serif';
43+
}
44+
// or body margin
45+
if (selectorSet.has('body') && property === 'margin') {
46+
return '0 4px';
47+
}
48+
// if you want to remove some property - return null
49+
if (selectorSet.has('html') && property === 'line-height') {
50+
return null;
51+
}
52+
// to keep the property as it is - you may return the original value;
53+
// but returning undefined would have the same effect,
54+
// so you may just omit such default return
55+
return value;
56+
},
3657
}),
3758
],
3859
};

src/index.ts

+24-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ export type CSSRuleSelectorTransformer = (info: { ruleSelector: string }) => str
1313

1414
interface PluginOptions {
1515
isolationStrategy: CSSRuleSelectorTransformer;
16+
/** @deprecated prefer using modifyPreflightStyles */
1617
propsFilter?: (input: PropsFilterInput) => boolean | undefined;
18+
modifyPreflightStyles?: (input: PropsFilterInput) => string | null | undefined;
1719
}
1820

1921
/**
@@ -22,11 +24,13 @@ interface PluginOptions {
2224
* import {@link https://www.npmjs.com/package/tailwindcss-scoped-preflight#isolate-inside-of-container isolateInsideOfContainer},
2325
* {@link https://www.npmjs.com/package/tailwindcss-scoped-preflight#isolate-outside-of-container isolateOutsideOfContainer},
2426
* {@link https://www.npmjs.com/package/tailwindcss-scoped-preflight#update-your-tailwind-css-configuration isolateForComponents} or write {@link https://www.npmjs.com/package/tailwindcss-scoped-preflight#your-owncustom-isolation-strategy your own}
27+
* @deprecated prefer using modifyPreflightStyles
2528
* @param propsFilter - function to filter the preflight CSS properties and values, return false to remove the property. Any other value (including true and undefined) will leave the prop intact
29+
* @param modifyPreflightStyles - function to modify the preflight CSS properties and their values, return null to remove the property. Any other returned value will be used as a new value for the property. If you don't want to change it - return the old value (provided in argument object as `value`).
2630
* @link https://www.npmjs.com/package/tailwindcss-scoped-preflight (documentation)
2731
*/
2832
export const scopedPreflightStyles = withOptions<PluginOptions>(
29-
({ isolationStrategy, propsFilter }) =>
33+
({ isolationStrategy, propsFilter, modifyPreflightStyles }) =>
3034
({ addBase, corePlugins }) => {
3135
const baseCssPath = require.resolve('tailwindcss/lib/css/preflight.css');
3236
const baseCssStyles = postcss.parse(readFileSync(baseCssPath, 'utf8'));
@@ -44,21 +48,31 @@ export const scopedPreflightStyles = withOptions<PluginOptions>(
4448
}
4549

4650
baseCssStyles.walkRules((rule) => {
47-
if (propsFilter) {
51+
if (propsFilter || modifyPreflightStyles) {
4852
const selectorSet = new Set(rule.selectors);
49-
5053
rule.nodes = rule.nodes?.map((node) => {
5154
if (node instanceof postcss.Declaration) {
52-
if (
53-
propsFilter({
54-
selectorSet,
55-
property: node.prop,
56-
value: node.value,
57-
}) === false
58-
) {
55+
const newValue = modifyPreflightStyles
56+
? modifyPreflightStyles({
57+
selectorSet,
58+
property: node.prop,
59+
value: node.value,
60+
})
61+
: node.value;
62+
63+
const filterValue = propsFilter
64+
? propsFilter({
65+
selectorSet,
66+
property: node.prop,
67+
value: node.value,
68+
})
69+
: true;
70+
if (filterValue === false || newValue === null) {
5971
return postcss.comment({
6072
text: node.toString(),
6173
});
74+
} else if (typeof newValue !== 'undefined' && newValue !== node.value) {
75+
node.value = newValue;
6276
}
6377
}
6478
return node;

0 commit comments

Comments
 (0)