Skip to content

Commit 4f7096d

Browse files
committed
feat: add unitList option to control processed units and enhance documentation
1 parent 7e4372b commit 4f7096d

File tree

5 files changed

+350
-68
lines changed

5 files changed

+350
-68
lines changed

CLAUDE.md

Lines changed: 0 additions & 58 deletions
This file was deleted.

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,28 @@ fs.writeFile('main-new.css', processedCss, function (err) {
3838
});
3939
```
4040

41+
### unitList Examples
42+
43+
```js
44+
// Only process rem units
45+
unitProcessor({
46+
processor: (value, unit) => value,
47+
unitList: ['rem']
48+
})
49+
50+
// Process all units except rem
51+
unitProcessor({
52+
processor: (value, unit) => value,
53+
unitList: ['!rem']
54+
})
55+
56+
// Process only rem and px units
57+
unitProcessor({
58+
processor: (value, unit) => value,
59+
unitList: ['rem', 'px']
60+
})
61+
```
62+
4163
### options
4264

4365
Type: `Object | Null`
@@ -47,6 +69,7 @@ Default:
4769
processor: (value) => value,
4870
unitPrecision: 5,
4971
propList: ['*'],
72+
unitList: ['*'],
5073
selectorBlackList: [],
5174
replace: true,
5275
mediaQuery: false,
@@ -65,6 +88,11 @@ Default:
6588
- If the Number is returned, the unit value is directly replaced, and the unit name remains unchanged.
6689
- If an object is returned, the `value` of the object replaces the value, and the `unit` replaces the name.
6790
- `unitPrecision` (Number) The decimal numbers to allow the processed units to grow to.
91+
- `unitList` (Array) The units that can be changed by the processor function.
92+
- Values need to be exact matches.
93+
- Use wildcard `*` to enable all units. Example: `['*']`
94+
- Use `!` to not match a unit. Example: `['*', '!rem']`
95+
- Combine multiple units: `['rem', 'px', 'vw']`
6896
- `propList` (Array) The properties that can be changed by the processor function.
6997
- Values need to be exact matches.
7098
- Use wildcard `*` to enable all properties. Example: `['*']`

index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ declare namespace PostcssUnitProcessor {
5353
* @default []
5454
*/
5555
customUnitList?: string[];
56+
57+
/**
58+
* List of units to process. Supports wildcards and negation.
59+
* @default ['*']
60+
*/
61+
unitList?: string[];
5662
}
5763
}
5864

index.js

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,15 @@ const defaults = {
4949
replace: true,
5050
mediaQuery: false,
5151
exclude: /node_modules/i,
52-
customUnitList: []
52+
customUnitList: [],
53+
unitList: ['*']
5354
};
5455

5556
function escapeRegExp(string) {
5657
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
5758
}
5859

59-
function createUnitRegex(customUnitList) {
60+
function createUnitRegex(customUnitList, unitList) {
6061
let userUnits = Array.isArray(customUnitList)
6162
? customUnitList.filter(
6263
(u) => typeof u === 'string' && u.trim() && /^[a-zA-Z%]+$/.test(u)
@@ -68,7 +69,27 @@ function createUnitRegex(customUnitList) {
6869
unitSet.add(u);
6970
}
7071

71-
const unitStr = Array.from(unitSet).map(escapeRegExp).join('|');
72+
// Filter units based on unitList if provided
73+
let filteredUnits = Array.from(unitSet);
74+
if (Array.isArray(unitList)) {
75+
if (unitList.length === 0) {
76+
// Empty unitList means no units should be processed
77+
filteredUnits = [];
78+
} else {
79+
const satisfyUnitList = createUnitListMatcher(unitList);
80+
filteredUnits = filteredUnits.filter(unit => satisfyUnitList(unit));
81+
}
82+
}
83+
84+
const unitStr = filteredUnits.map(escapeRegExp).join('|');
85+
86+
// If no units to process, create a regex that won't match any units
87+
if (unitStr === '') {
88+
return new RegExp(
89+
`"[^"]+"|'[^']+'|url\\([^)]+\\)|var\\([^)]+\\)`,
90+
'g'
91+
);
92+
}
7293

7394
return new RegExp(
7495
`"[^"]+"|'[^']+'|url\\([^)]+\\)|var\\([^)]+\\)|(\\d*\\.?\\d+)(${unitStr})`,
@@ -102,7 +123,7 @@ function createUnitReplace(processor, unitPrecision, root) {
102123

103124
const fixedVal = toFixed(newValue, unitPrecision);
104125

105-
return fixedVal === 0 ? "0" : fixedVal + newUnit;
126+
return fixedVal + newUnit;
106127
};
107128
}
108129

@@ -174,15 +195,63 @@ function createPropListMatcher(propList) {
174195
};
175196
}
176197

198+
function createUnitListMatcher(unitList) {
199+
const hasWild = unitList.indexOf("*") > -1;
200+
const matchAll = hasWild && unitList.length === 1;
201+
const lists = {
202+
exact: filterPropList.exact(unitList),
203+
contain: filterPropList.contain(unitList),
204+
startWith: filterPropList.startWith(unitList),
205+
endWith: filterPropList.endWith(unitList),
206+
notExact: filterPropList.notExact(unitList),
207+
notContain: filterPropList.notContain(unitList),
208+
notStartWith: filterPropList.notStartWith(unitList),
209+
notEndWith: filterPropList.notEndWith(unitList)
210+
};
211+
212+
return unit => {
213+
if (matchAll) {
214+
return true;
215+
}
216+
217+
return (
218+
(hasWild ||
219+
lists.exact.indexOf(unit) > -1 ||
220+
lists.contain.some(function(m) {
221+
return unit.indexOf(m) > -1;
222+
}) ||
223+
lists.startWith.some(function(m) {
224+
return unit.indexOf(m) === 0;
225+
}) ||
226+
lists.endWith.some(function(m) {
227+
return unit.indexOf(m) === unit.length - m.length;
228+
})) &&
229+
!(
230+
lists.notExact.indexOf(unit) > -1 ||
231+
lists.notContain.some(function(m) {
232+
return unit.indexOf(m) > -1;
233+
}) ||
234+
lists.notStartWith.some(function(m) {
235+
return unit.indexOf(m) === 0;
236+
}) ||
237+
lists.notEndWith.some(function(m) {
238+
return unit.indexOf(m) === unit.length - m.length;
239+
})
240+
)
241+
);
242+
};
243+
}
244+
177245
module.exports = (options = {}) => {
178246
const opts = Object.assign({}, defaults, options);
179247
const satisfyPropList = createPropListMatcher(opts.propList);
180248
const exclude = opts.exclude;
181-
const customUnitList = opts.customUnitList
249+
const customUnitList = opts.customUnitList;
250+
const unitList = opts.unitList;
182251
let isExcludeFile = false;
183252
let unitReplace;
184253

185-
const unitRegex = createUnitRegex(customUnitList);
254+
const unitRegex = createUnitRegex(customUnitList, unitList);
186255

187256
return {
188257
postcssPlugin: "postcss-unit-processor",

0 commit comments

Comments
 (0)