postcss-clampwind 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -305,6 +305,33 @@ But Tailwind by default, will not output in your CSS any custom properties that
305
305
  }
306
306
  ```
307
307
 
308
+ ### Set a default clamp range
309
+
310
+ You can set a default clamp range to use when no breakpoint modifier is used, like this:
311
+
312
+ ```html
313
+ <div class="text-[clamp(16px,50px)]"></div>
314
+ ```
315
+
316
+ To set a default clamp range you need to use the `--breakpoint-clamp-min` and `--breakpoint-clamp-max` custom properties, defined inside the `@theme static` directive.
317
+
318
+ ```css
319
+ @theme static {
320
+ --breakpoint-clamp-min: 600px;
321
+ --breakpoint-clamp-max: 1200px;
322
+ }
323
+ ```
324
+
325
+ This will also apply for utilities that use only one breakpoint modifier. In this example the `md` breakpoint will be used as the minimum breakpoint, and `--breakpoint-clamp-max` will be used as the maximum breakpoint:
326
+
327
+ ```html
328
+ <div class="md:text-[clamp(16px,50px)]"></div>
329
+ ```
330
+
331
+ The default clamp range will let you to simplify your utilities, since usually you don't need to clamp between the smallest and largest Tailwind breakpoints, but only between two breakpoints.
332
+
333
+ You will still be able to clamp between any other Tailwind or custom breakpoints, even if out of the default clamp range.
334
+
308
335
  ### Use custom properties
309
336
 
310
337
  You can use any custom properties in your clamped values, for example:
@@ -1,8 +1,6 @@
1
- var __create = Object.create;
2
1
  var __defProp = Object.defineProperty;
3
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
5
  var __export = (target, all) => {
8
6
  for (var name in all)
@@ -16,14 +14,6 @@ var __copyProps = (to, from, except, desc) => {
16
14
  }
17
15
  return to;
18
16
  };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
18
 
29
19
  // src/clampwind.js
@@ -32,7 +22,6 @@ __export(clampwind_exports, {
32
22
  default: () => clampwind_default
33
23
  });
34
24
  module.exports = __toCommonJS(clampwind_exports);
35
- var import_postcss = __toESM(require("postcss"), 1);
36
25
 
37
26
  // src/screens.js
38
27
  var defaultScreens = {
@@ -75,28 +64,13 @@ var defaultContainerScreens = {
75
64
  "@7xl": "80rem"
76
65
  // 1280px
77
66
  };
78
- var convertSortScreens = (screens, rootFontSize = 16) => {
79
- const convertedScreens = Object.entries(screens).reduce((acc, [key, value]) => {
80
- if (value.includes("px")) {
81
- const pxValue = parseFloat(value);
82
- acc[key] = `${pxValue / rootFontSize}rem`;
83
- } else {
84
- acc[key] = value;
85
- }
86
- return acc;
87
- }, {});
88
- const sortedKeys = Object.keys(convertedScreens).sort((a, b) => {
89
- const aValue = parseFloat(convertedScreens[a]);
90
- const bValue = parseFloat(convertedScreens[b]);
91
- return aValue - bValue;
92
- });
93
- return sortedKeys.reduce((acc, key) => {
94
- acc[key] = convertedScreens[key];
95
- return acc;
96
- }, {});
97
- };
98
67
 
99
68
  // src/utils.js
69
+ var smartRound = (value, maxDecimals = 4) => {
70
+ const precise = value.toFixed(maxDecimals);
71
+ const trimmed = precise.replace(/\.?0+$/, "");
72
+ return trimmed || "0";
73
+ };
100
74
  var extractTwoValidClampArgs = (value) => {
101
75
  const m = value.match(/\bclamp\s*\(\s*(var\([^()]+\)|[^,()]+)\s*,\s*(var\([^()]+\)|[^,()]+)\s*\)$/);
102
76
  return m ? [m[1].trim(), m[2].trim()] : null;
@@ -123,28 +97,28 @@ var convertToRem = (value, rootFontSize, spacingSize, customProperties = {}) =>
123
97
  const spacingSizeInt = parseFloat(spacingSize);
124
98
  const spacingUnit = extractUnit(spacingSize);
125
99
  if (spacingUnit === "px") {
126
- return `${parseFloat(value * spacingSizeInt / rootFontSize).toFixed(4)}rem`;
100
+ return `${smartRound(value * spacingSizeInt / rootFontSize)}rem`;
127
101
  }
128
102
  if (spacingUnit === "rem") {
129
- return `${parseFloat(value * spacingSizeInt).toFixed(4)}rem`;
103
+ return `${smartRound(value * spacingSizeInt)}rem`;
130
104
  }
131
105
  }
132
106
  if (unit === "px") {
133
- return `${parseFloat(value.replace("px", "") / rootFontSize).toFixed(4)}rem`;
107
+ return `${smartRound(value.replace("px", "") / rootFontSize)}rem`;
134
108
  }
135
109
  if (unit === "rem") {
136
110
  return value;
137
111
  }
138
112
  if (customProperties[formattedProperty]) {
139
- return `${customProperties[formattedProperty]}rem`;
113
+ return customProperties[formattedProperty];
140
114
  }
141
115
  if (formattedProperty && !customProperties[formattedProperty] && fallbackValue) {
142
116
  const fallbackUnit = extractUnit(fallbackValue);
143
117
  if (!fallbackUnit) {
144
- return `${parseFloat(fallbackValue * spacingSize).toFixed(4)}rem`;
118
+ return `${smartRound(fallbackValue * spacingSize)}rem`;
145
119
  }
146
120
  if (fallbackUnit === "px") {
147
- return `${parseFloat(fallbackValue.replace("px", "") / rootFontSize).toFixed(4)}rem`;
121
+ return `${smartRound(fallbackValue.replace("px", "") / rootFontSize)}rem`;
148
122
  }
149
123
  if (fallbackUnit === "rem") {
150
124
  return fallbackValue;
@@ -165,10 +139,21 @@ var generateClamp = (lower, upper, minScreen, maxScreen, rootFontSize = 16, spac
165
139
  const min = isDescending ? upper : lower;
166
140
  const max = isDescending ? lower : upper;
167
141
  const widthUnit = containerQuery ? `100cqw` : `100vw`;
168
- const slopeInt = parseFloat(((upperInt - lowerInt) / (maxScreenInt - minScreenInt)).toFixed(4));
142
+ const slopeInt = smartRound((upperInt - lowerInt) / (maxScreenInt - minScreenInt));
169
143
  const clamp = `clamp(${min}, calc(${lower} + ${slopeInt} * (${widthUnit} - ${minScreen})), ${max})`;
170
144
  return clamp;
171
145
  };
146
+ var sortScreens = (screens) => {
147
+ const sortedKeys = Object.keys(screens).sort((a, b) => {
148
+ const aValue = parseFloat(screens[a]);
149
+ const bValue = parseFloat(screens[b]);
150
+ return aValue - bValue;
151
+ });
152
+ return sortedKeys.reduce((acc, key) => {
153
+ acc[key] = screens[key];
154
+ return acc;
155
+ }, {});
156
+ };
172
157
 
173
158
  // src/clampwind.js
174
159
  var clampwind = (opts = {}) => {
@@ -176,13 +161,12 @@ var clampwind = (opts = {}) => {
176
161
  postcssPlugin: "clampwind",
177
162
  prepare() {
178
163
  let rootFontSize = 16;
179
- let spacingSize = "1px";
164
+ let spacingSize = "0.25rem";
180
165
  let customProperties = {};
181
166
  let screens = defaultScreens || {};
182
167
  let containerScreens = defaultContainerScreens || {};
168
+ let defaultClampRange = {};
183
169
  const config = {
184
- defaultLayerBreakpoints: {},
185
- defaultLayerContainerBreakpoints: {},
186
170
  themeLayerBreakpoints: {},
187
171
  themeLayerContainerBreakpoints: {},
188
172
  rootElementBreakpoints: {},
@@ -206,17 +190,48 @@ var clampwind = (opts = {}) => {
206
190
  if (decl.parent?.selector === ":root") {
207
191
  if (decl.prop.startsWith("--breakpoint-")) {
208
192
  const key = decl.prop.replace("--breakpoint-", "");
209
- config.rootElementBreakpoints[key] = decl.value;
193
+ config.rootElementBreakpoints[key] = convertToRem(
194
+ decl.value,
195
+ rootFontSize,
196
+ spacingSize,
197
+ customProperties
198
+ );
210
199
  }
211
200
  if (decl.prop.startsWith("--container-")) {
212
201
  const key = decl.prop.replace("--container-", "@");
213
- config.rootElementContainerBreakpoints[key] = decl.value;
202
+ config.rootElementContainerBreakpoints[key] = convertToRem(
203
+ decl.value,
204
+ rootFontSize,
205
+ spacingSize,
206
+ customProperties
207
+ );
208
+ }
209
+ if (decl.prop === "--breakpoint-clamp-min") {
210
+ defaultClampRange.min = convertToRem(
211
+ decl.value,
212
+ rootFontSize,
213
+ spacingSize,
214
+ customProperties
215
+ );
216
+ }
217
+ if (decl.prop === "--breakpoint-clamp-max") {
218
+ defaultClampRange.max = convertToRem(
219
+ decl.value,
220
+ rootFontSize,
221
+ spacingSize,
222
+ customProperties
223
+ );
214
224
  }
215
225
  if (decl.prop === "--spacing") {
216
226
  spacingSize = decl.value;
217
227
  }
218
228
  if (decl.prop.startsWith("--")) {
219
- const value = parseFloat(convertToRem(decl.value, rootFontSize, spacingSize, customProperties));
229
+ const value = convertToRem(
230
+ decl.value,
231
+ rootFontSize,
232
+ spacingSize,
233
+ customProperties
234
+ );
220
235
  if (value) customProperties[decl.prop] = value;
221
236
  }
222
237
  }
@@ -231,35 +246,52 @@ var clampwind = (opts = {}) => {
231
246
  }
232
247
  });
233
248
  root.walkAtRules("layer", (atRule) => {
234
- if (atRule.params === "default") {
235
- if (!Object.keys(config.defaultLayerBreakpoints).length) {
236
- atRule.walkDecls((decl) => {
237
- if (decl.prop.startsWith("--breakpoint-")) {
238
- const key = decl.prop.replace("--breakpoint-", "");
239
- config.defaultLayerBreakpoints[key] = decl.value;
240
- }
241
- if (decl.prop.startsWith("--container-")) {
242
- const key = decl.prop.replace("--container-", "@");
243
- config.defaultLayerContainerBreakpoints[key] = decl.value;
244
- }
245
- });
246
- }
247
- }
248
249
  if (atRule.params === "theme") {
249
250
  atRule.walkDecls((decl) => {
250
251
  if (decl.prop.startsWith("--breakpoint-")) {
251
252
  const key = decl.prop.replace("--breakpoint-", "");
252
- config.themeLayerBreakpoints[key] = decl.value;
253
+ config.themeLayerBreakpoints[key] = convertToRem(
254
+ decl.value,
255
+ rootFontSize,
256
+ spacingSize,
257
+ customProperties
258
+ );
253
259
  }
254
260
  if (decl.prop.startsWith("--container-")) {
255
261
  const key = decl.prop.replace("--container-", "@");
256
- config.themeLayerContainerBreakpoints[key] = decl.value;
262
+ config.themeLayerContainerBreakpoints[key] = convertToRem(
263
+ decl.value,
264
+ rootFontSize,
265
+ spacingSize,
266
+ customProperties
267
+ );
268
+ }
269
+ if (decl.prop === "--breakpoint-clamp-min") {
270
+ defaultClampRange.min = convertToRem(
271
+ decl.value,
272
+ rootFontSize,
273
+ spacingSize,
274
+ customProperties
275
+ );
276
+ }
277
+ if (decl.prop === "--breakpoint-clamp-max") {
278
+ defaultClampRange.max = convertToRem(
279
+ decl.value,
280
+ rootFontSize,
281
+ spacingSize,
282
+ customProperties
283
+ );
257
284
  }
258
285
  if (decl.prop === "--spacing") {
259
286
  spacingSize = decl.value;
260
287
  }
261
288
  if (decl.prop.startsWith("--")) {
262
- const value = parseFloat(convertToRem(decl.value, rootFontSize, spacingSize, customProperties));
289
+ const value = convertToRem(
290
+ decl.value,
291
+ rootFontSize,
292
+ spacingSize,
293
+ customProperties
294
+ );
263
295
  if (value) customProperties[decl.prop] = value;
264
296
  }
265
297
  });
@@ -272,30 +304,38 @@ var clampwind = (opts = {}) => {
272
304
  screens = Object.assign(
273
305
  {},
274
306
  screens,
275
- config.defaultLayerBreakpoints,
276
307
  config.rootElementBreakpoints,
277
308
  config.themeLayerBreakpoints
278
309
  );
279
- screens = convertSortScreens(screens, rootFontSize);
310
+ screens = sortScreens(screens);
280
311
  containerScreens = Object.assign(
281
312
  {},
282
313
  containerScreens,
283
- config.defaultLayerContainerBreakpoints,
284
314
  config.rootElementContainerBreakpoints,
285
315
  config.themeLayerContainerBreakpoints
286
316
  );
287
- containerScreens = convertSortScreens(containerScreens, rootFontSize);
317
+ containerScreens = sortScreens(containerScreens);
288
318
  config.configReady = true;
289
319
  };
290
320
  const processClampDeclaration = (decl, minScreen, maxScreen, isContainer = false) => {
291
321
  const args = extractTwoValidClampArgs(decl.value);
292
- const [lower, upper] = args.map((val) => convertToRem(val, rootFontSize, spacingSize, customProperties));
322
+ const [lower, upper] = args.map(
323
+ (val) => convertToRem(val, rootFontSize, spacingSize, customProperties)
324
+ );
293
325
  if (!args || !lower || !upper) {
294
326
  console.warn("Invalid clamp() values", { node: decl });
295
327
  decl.value = ` ${decl.value} /* Invalid clamp() values */`;
296
328
  return true;
297
329
  }
298
- const clamp = generateClamp(lower, upper, minScreen, maxScreen, rootFontSize, spacingSize, isContainer);
330
+ const clamp = generateClamp(
331
+ lower,
332
+ upper,
333
+ minScreen,
334
+ maxScreen,
335
+ rootFontSize,
336
+ spacingSize,
337
+ isContainer
338
+ );
299
339
  decl.value = clamp;
300
340
  return true;
301
341
  };
@@ -305,8 +345,6 @@ var clampwind = (opts = {}) => {
305
345
  collectConfig(root);
306
346
  finalizeConfig();
307
347
  root.walkAtRules("media", (atRule) => {
308
- const isNested = atRule.parent?.type === "atrule";
309
- const isSameAtRule = atRule.parent?.name === atRule.name;
310
348
  const clampDecls = [];
311
349
  atRule.walkDecls((decl) => {
312
350
  if (extractTwoValidClampArgs(decl.value)) {
@@ -314,53 +352,56 @@ var clampwind = (opts = {}) => {
314
352
  }
315
353
  });
316
354
  if (!clampDecls.length) return;
317
- if (isNested && isSameAtRule) {
318
- const parentParams = atRule.parent.params;
319
- const currentParams = atRule.params;
320
- let minScreen = null;
321
- let maxScreen = null;
322
- if (parentParams.includes(">")) {
323
- const match = parentParams.match(/>=?\s*([^)]+)/);
324
- if (match) minScreen = match[1].trim();
325
- }
326
- if (currentParams.includes(">") && !minScreen) {
327
- const match = currentParams.match(/>=?\s*([^)]+)/);
328
- if (match) minScreen = match[1].trim();
329
- }
330
- if (parentParams.includes("<")) {
331
- const match = parentParams.match(/<\s*([^)]+)/);
332
- if (match) maxScreen = match[1].trim();
333
- }
334
- if (currentParams.includes("<") && !maxScreen) {
335
- const match = currentParams.match(/<\s*([^)]+)/);
336
- if (match) maxScreen = match[1].trim();
355
+ clampDecls.forEach((decl) => {
356
+ const isNested = decl.parent?.type === "atrule" && decl.parent?.parent.type === "atrule";
357
+ const isSameAtRule = decl.parent?.name === decl.parent?.parent.name;
358
+ if (isNested && isSameAtRule) {
359
+ const currentParams2 = decl.parent.params;
360
+ const parentParams = decl.parent.parent.params;
361
+ let minScreen = null;
362
+ let maxScreen = null;
363
+ if (parentParams.includes(">")) {
364
+ const match = parentParams.match(/>=?\s*([^)]+)/);
365
+ if (match) minScreen = match[1].trim();
366
+ }
367
+ if (currentParams2.includes(">") && !minScreen) {
368
+ const match = currentParams2.match(/>=?\s*([^)]+)/);
369
+ if (match) minScreen = match[1].trim();
370
+ }
371
+ if (parentParams.includes("<")) {
372
+ const match = parentParams.match(/<\s*([^)]+)/);
373
+ if (match) maxScreen = match[1].trim();
374
+ }
375
+ if (currentParams2.includes("<") && !maxScreen) {
376
+ const match = currentParams2.match(/<\s*([^)]+)/);
377
+ if (match) maxScreen = match[1].trim();
378
+ }
379
+ if (minScreen && maxScreen) {
380
+ clampDecls.forEach((decl2) => {
381
+ processClampDeclaration(decl2, minScreen, maxScreen, false);
382
+ });
383
+ }
384
+ return;
337
385
  }
338
- if (minScreen && maxScreen) {
339
- clampDecls.forEach((decl) => {
340
- processClampDeclaration(decl, minScreen, maxScreen, false);
386
+ if (isNested && !isSameAtRule) {
387
+ clampDecls.forEach((decl2) => {
388
+ decl2.value = ` ${decl2.value} /* Invalid nested @media rules */`;
341
389
  });
390
+ return;
342
391
  }
343
- return;
344
- }
345
- if (isNested && !isSameAtRule) {
346
- clampDecls.forEach((decl) => {
347
- decl.value = ` ${decl.value} /* Invalid nested @media rules */`;
348
- });
349
- return;
350
- }
351
- const screenValues = Object.values(screens);
352
- clampDecls.forEach((decl) => {
353
- if (atRule.params.includes(">")) {
354
- const match = atRule.params.match(/>=?\s*([^)]+)/);
392
+ const screenValues = Object.values(screens);
393
+ const currentParams = decl.parent.params;
394
+ if (currentParams.includes(">")) {
395
+ const match = currentParams.match(/>=?\s*([^)]+)/);
355
396
  if (match) {
356
397
  const minScreen = match[1].trim();
357
- const maxScreen = screenValues[screenValues.length - 1];
398
+ const maxScreen = defaultClampRange.max || screenValues[screenValues.length - 1];
358
399
  processClampDeclaration(decl, minScreen, maxScreen, false);
359
400
  }
360
- } else if (atRule.params.includes("<")) {
361
- const match = atRule.params.match(/<\s*([^)]+)/);
401
+ } else if (currentParams.includes("<")) {
402
+ const match = currentParams.match(/<\s*([^)]+)/);
362
403
  if (match) {
363
- const minScreen = screenValues[0];
404
+ const minScreen = defaultClampRange.min || screenValues[0];
364
405
  const maxScreen = match[1].trim();
365
406
  processClampDeclaration(decl, minScreen, maxScreen, false);
366
407
  }
@@ -368,8 +409,6 @@ var clampwind = (opts = {}) => {
368
409
  });
369
410
  });
370
411
  root.walkAtRules("container", (atRule) => {
371
- const isNested = atRule.parent?.type === "atrule";
372
- const isSameAtRule = atRule.parent?.name === atRule.name;
373
412
  const clampDecls = [];
374
413
  atRule.walkDecls((decl) => {
375
414
  if (extractTwoValidClampArgs(decl.value)) {
@@ -377,55 +416,73 @@ var clampwind = (opts = {}) => {
377
416
  }
378
417
  });
379
418
  if (!clampDecls.length) return;
380
- if (isNested && isSameAtRule) {
381
- const parentParams = atRule.parent.params;
382
- const currentParams = atRule.params;
383
- let minContainer = null;
384
- let maxContainer = null;
385
- if (parentParams.includes(">")) {
386
- const match = parentParams.match(/>=?\s*([^)]+)/);
387
- if (match) minContainer = match[1].trim();
388
- }
389
- if (currentParams.includes(">") && !minContainer) {
390
- const match = currentParams.match(/>=?\s*([^)]+)/);
391
- if (match) minContainer = match[1].trim();
392
- }
393
- if (parentParams.includes("<")) {
394
- const match = parentParams.match(/<\s*([^)]+)/);
395
- if (match) maxContainer = match[1].trim();
396
- }
397
- if (currentParams.includes("<") && !maxContainer) {
398
- const match = currentParams.match(/<\s*([^)]+)/);
399
- if (match) maxContainer = match[1].trim();
419
+ clampDecls.forEach((decl) => {
420
+ const isNested = decl.parent?.type === "atrule" && decl.parent?.parent.type === "atrule";
421
+ const isSameAtRule = decl.parent?.name === decl.parent?.parent.name;
422
+ if (isNested && isSameAtRule) {
423
+ const currentParams2 = decl.parent.params;
424
+ const parentParams = decl.parent.parent.params;
425
+ let minContainer = null;
426
+ let maxContainer = null;
427
+ if (parentParams.includes(">")) {
428
+ const match = parentParams.match(/>=?\s*([^)]+)/);
429
+ if (match) minContainer = match[1].trim();
430
+ }
431
+ if (currentParams2.includes(">") && !minContainer) {
432
+ const match = currentParams2.match(/>=?\s*([^)]+)/);
433
+ if (match) minContainer = match[1].trim();
434
+ }
435
+ if (parentParams.includes("<")) {
436
+ const match = parentParams.match(/<\s*([^)]+)/);
437
+ if (match) maxContainer = match[1].trim();
438
+ }
439
+ if (currentParams2.includes("<") && !maxContainer) {
440
+ const match = currentParams2.match(/<\s*([^)]+)/);
441
+ if (match) maxContainer = match[1].trim();
442
+ }
443
+ if (minContainer && maxContainer) {
444
+ clampDecls.forEach((decl2) => {
445
+ processClampDeclaration(
446
+ decl2,
447
+ minContainer,
448
+ maxContainer,
449
+ true
450
+ );
451
+ });
452
+ }
453
+ return;
400
454
  }
401
- if (minContainer && maxContainer) {
402
- clampDecls.forEach((decl) => {
403
- processClampDeclaration(decl, minContainer, maxContainer, true);
455
+ if (isNested && !isSameAtRule) {
456
+ clampDecls.forEach((decl2) => {
457
+ decl2.value = ` ${decl2.value} /* Invalid nested @container rules */`;
404
458
  });
459
+ return;
405
460
  }
406
- return;
407
- }
408
- if (isNested && !isSameAtRule) {
409
- clampDecls.forEach((decl) => {
410
- decl.value = ` ${decl.value} /* Invalid nested @container rules */`;
411
- });
412
- return;
413
- }
414
- const screenValues = Object.values(containerScreens);
415
- clampDecls.forEach((decl) => {
416
- if (atRule.params.includes(">")) {
417
- const match = atRule.params.match(/>=?\s*([^)]+)/);
461
+ const containerValues = Object.values(containerScreens);
462
+ const currentParams = decl.parent.params;
463
+ if (currentParams.includes(">")) {
464
+ const match = currentParams.match(/>=?\s*([^)]+)/);
418
465
  if (match) {
419
466
  const minContainer = match[1].trim();
420
- const maxContainer = screenValues[screenValues.length - 1];
421
- processClampDeclaration(decl, minContainer, maxContainer, true);
467
+ const maxContainer = containerValues[containerValues.length - 1];
468
+ processClampDeclaration(
469
+ decl,
470
+ minContainer,
471
+ maxContainer,
472
+ true
473
+ );
422
474
  }
423
- } else if (atRule.params.includes("<")) {
424
- const match = atRule.params.match(/<\s*([^)]+)/);
475
+ } else if (currentParams.includes("<")) {
476
+ const match = currentParams.match(/<\s*([^)]+)/);
425
477
  if (match) {
426
- const minContainer = screenValues[0];
478
+ const minContainer = containerValues[0];
427
479
  const maxContainer = match[1].trim();
428
- processClampDeclaration(decl, minContainer, maxContainer, true);
480
+ processClampDeclaration(
481
+ decl,
482
+ minContainer,
483
+ maxContainer,
484
+ true
485
+ );
429
486
  }
430
487
  }
431
488
  });
@@ -446,8 +503,8 @@ var clampwind = (opts = {}) => {
446
503
  });
447
504
  if (clampDecls.length === 0) return;
448
505
  const screenValues = Object.values(screens);
449
- const minScreen = screenValues[0];
450
- const maxScreen = screenValues[screenValues.length - 1];
506
+ const minScreen = defaultClampRange.min || screenValues[0];
507
+ const maxScreen = defaultClampRange.max || screenValues[screenValues.length - 1];
451
508
  clampDecls.forEach((decl) => {
452
509
  processClampDeclaration(decl, minScreen, maxScreen, false);
453
510
  });
@@ -1,6 +1,3 @@
1
- // src/clampwind.js
2
- import postcss from "postcss";
3
-
4
1
  // src/screens.js
5
2
  var defaultScreens = {
6
3
  sm: "40rem",
@@ -42,28 +39,13 @@ var defaultContainerScreens = {
42
39
  "@7xl": "80rem"
43
40
  // 1280px
44
41
  };
45
- var convertSortScreens = (screens, rootFontSize = 16) => {
46
- const convertedScreens = Object.entries(screens).reduce((acc, [key, value]) => {
47
- if (value.includes("px")) {
48
- const pxValue = parseFloat(value);
49
- acc[key] = `${pxValue / rootFontSize}rem`;
50
- } else {
51
- acc[key] = value;
52
- }
53
- return acc;
54
- }, {});
55
- const sortedKeys = Object.keys(convertedScreens).sort((a, b) => {
56
- const aValue = parseFloat(convertedScreens[a]);
57
- const bValue = parseFloat(convertedScreens[b]);
58
- return aValue - bValue;
59
- });
60
- return sortedKeys.reduce((acc, key) => {
61
- acc[key] = convertedScreens[key];
62
- return acc;
63
- }, {});
64
- };
65
42
 
66
43
  // src/utils.js
44
+ var smartRound = (value, maxDecimals = 4) => {
45
+ const precise = value.toFixed(maxDecimals);
46
+ const trimmed = precise.replace(/\.?0+$/, "");
47
+ return trimmed || "0";
48
+ };
67
49
  var extractTwoValidClampArgs = (value) => {
68
50
  const m = value.match(/\bclamp\s*\(\s*(var\([^()]+\)|[^,()]+)\s*,\s*(var\([^()]+\)|[^,()]+)\s*\)$/);
69
51
  return m ? [m[1].trim(), m[2].trim()] : null;
@@ -90,28 +72,28 @@ var convertToRem = (value, rootFontSize, spacingSize, customProperties = {}) =>
90
72
  const spacingSizeInt = parseFloat(spacingSize);
91
73
  const spacingUnit = extractUnit(spacingSize);
92
74
  if (spacingUnit === "px") {
93
- return `${parseFloat(value * spacingSizeInt / rootFontSize).toFixed(4)}rem`;
75
+ return `${smartRound(value * spacingSizeInt / rootFontSize)}rem`;
94
76
  }
95
77
  if (spacingUnit === "rem") {
96
- return `${parseFloat(value * spacingSizeInt).toFixed(4)}rem`;
78
+ return `${smartRound(value * spacingSizeInt)}rem`;
97
79
  }
98
80
  }
99
81
  if (unit === "px") {
100
- return `${parseFloat(value.replace("px", "") / rootFontSize).toFixed(4)}rem`;
82
+ return `${smartRound(value.replace("px", "") / rootFontSize)}rem`;
101
83
  }
102
84
  if (unit === "rem") {
103
85
  return value;
104
86
  }
105
87
  if (customProperties[formattedProperty]) {
106
- return `${customProperties[formattedProperty]}rem`;
88
+ return customProperties[formattedProperty];
107
89
  }
108
90
  if (formattedProperty && !customProperties[formattedProperty] && fallbackValue) {
109
91
  const fallbackUnit = extractUnit(fallbackValue);
110
92
  if (!fallbackUnit) {
111
- return `${parseFloat(fallbackValue * spacingSize).toFixed(4)}rem`;
93
+ return `${smartRound(fallbackValue * spacingSize)}rem`;
112
94
  }
113
95
  if (fallbackUnit === "px") {
114
- return `${parseFloat(fallbackValue.replace("px", "") / rootFontSize).toFixed(4)}rem`;
96
+ return `${smartRound(fallbackValue.replace("px", "") / rootFontSize)}rem`;
115
97
  }
116
98
  if (fallbackUnit === "rem") {
117
99
  return fallbackValue;
@@ -132,10 +114,21 @@ var generateClamp = (lower, upper, minScreen, maxScreen, rootFontSize = 16, spac
132
114
  const min = isDescending ? upper : lower;
133
115
  const max = isDescending ? lower : upper;
134
116
  const widthUnit = containerQuery ? `100cqw` : `100vw`;
135
- const slopeInt = parseFloat(((upperInt - lowerInt) / (maxScreenInt - minScreenInt)).toFixed(4));
117
+ const slopeInt = smartRound((upperInt - lowerInt) / (maxScreenInt - minScreenInt));
136
118
  const clamp = `clamp(${min}, calc(${lower} + ${slopeInt} * (${widthUnit} - ${minScreen})), ${max})`;
137
119
  return clamp;
138
120
  };
121
+ var sortScreens = (screens) => {
122
+ const sortedKeys = Object.keys(screens).sort((a, b) => {
123
+ const aValue = parseFloat(screens[a]);
124
+ const bValue = parseFloat(screens[b]);
125
+ return aValue - bValue;
126
+ });
127
+ return sortedKeys.reduce((acc, key) => {
128
+ acc[key] = screens[key];
129
+ return acc;
130
+ }, {});
131
+ };
139
132
 
140
133
  // src/clampwind.js
141
134
  var clampwind = (opts = {}) => {
@@ -143,13 +136,12 @@ var clampwind = (opts = {}) => {
143
136
  postcssPlugin: "clampwind",
144
137
  prepare() {
145
138
  let rootFontSize = 16;
146
- let spacingSize = "1px";
139
+ let spacingSize = "0.25rem";
147
140
  let customProperties = {};
148
141
  let screens = defaultScreens || {};
149
142
  let containerScreens = defaultContainerScreens || {};
143
+ let defaultClampRange = {};
150
144
  const config = {
151
- defaultLayerBreakpoints: {},
152
- defaultLayerContainerBreakpoints: {},
153
145
  themeLayerBreakpoints: {},
154
146
  themeLayerContainerBreakpoints: {},
155
147
  rootElementBreakpoints: {},
@@ -173,17 +165,48 @@ var clampwind = (opts = {}) => {
173
165
  if (decl.parent?.selector === ":root") {
174
166
  if (decl.prop.startsWith("--breakpoint-")) {
175
167
  const key = decl.prop.replace("--breakpoint-", "");
176
- config.rootElementBreakpoints[key] = decl.value;
168
+ config.rootElementBreakpoints[key] = convertToRem(
169
+ decl.value,
170
+ rootFontSize,
171
+ spacingSize,
172
+ customProperties
173
+ );
177
174
  }
178
175
  if (decl.prop.startsWith("--container-")) {
179
176
  const key = decl.prop.replace("--container-", "@");
180
- config.rootElementContainerBreakpoints[key] = decl.value;
177
+ config.rootElementContainerBreakpoints[key] = convertToRem(
178
+ decl.value,
179
+ rootFontSize,
180
+ spacingSize,
181
+ customProperties
182
+ );
183
+ }
184
+ if (decl.prop === "--breakpoint-clamp-min") {
185
+ defaultClampRange.min = convertToRem(
186
+ decl.value,
187
+ rootFontSize,
188
+ spacingSize,
189
+ customProperties
190
+ );
191
+ }
192
+ if (decl.prop === "--breakpoint-clamp-max") {
193
+ defaultClampRange.max = convertToRem(
194
+ decl.value,
195
+ rootFontSize,
196
+ spacingSize,
197
+ customProperties
198
+ );
181
199
  }
182
200
  if (decl.prop === "--spacing") {
183
201
  spacingSize = decl.value;
184
202
  }
185
203
  if (decl.prop.startsWith("--")) {
186
- const value = parseFloat(convertToRem(decl.value, rootFontSize, spacingSize, customProperties));
204
+ const value = convertToRem(
205
+ decl.value,
206
+ rootFontSize,
207
+ spacingSize,
208
+ customProperties
209
+ );
187
210
  if (value) customProperties[decl.prop] = value;
188
211
  }
189
212
  }
@@ -198,35 +221,52 @@ var clampwind = (opts = {}) => {
198
221
  }
199
222
  });
200
223
  root.walkAtRules("layer", (atRule) => {
201
- if (atRule.params === "default") {
202
- if (!Object.keys(config.defaultLayerBreakpoints).length) {
203
- atRule.walkDecls((decl) => {
204
- if (decl.prop.startsWith("--breakpoint-")) {
205
- const key = decl.prop.replace("--breakpoint-", "");
206
- config.defaultLayerBreakpoints[key] = decl.value;
207
- }
208
- if (decl.prop.startsWith("--container-")) {
209
- const key = decl.prop.replace("--container-", "@");
210
- config.defaultLayerContainerBreakpoints[key] = decl.value;
211
- }
212
- });
213
- }
214
- }
215
224
  if (atRule.params === "theme") {
216
225
  atRule.walkDecls((decl) => {
217
226
  if (decl.prop.startsWith("--breakpoint-")) {
218
227
  const key = decl.prop.replace("--breakpoint-", "");
219
- config.themeLayerBreakpoints[key] = decl.value;
228
+ config.themeLayerBreakpoints[key] = convertToRem(
229
+ decl.value,
230
+ rootFontSize,
231
+ spacingSize,
232
+ customProperties
233
+ );
220
234
  }
221
235
  if (decl.prop.startsWith("--container-")) {
222
236
  const key = decl.prop.replace("--container-", "@");
223
- config.themeLayerContainerBreakpoints[key] = decl.value;
237
+ config.themeLayerContainerBreakpoints[key] = convertToRem(
238
+ decl.value,
239
+ rootFontSize,
240
+ spacingSize,
241
+ customProperties
242
+ );
243
+ }
244
+ if (decl.prop === "--breakpoint-clamp-min") {
245
+ defaultClampRange.min = convertToRem(
246
+ decl.value,
247
+ rootFontSize,
248
+ spacingSize,
249
+ customProperties
250
+ );
251
+ }
252
+ if (decl.prop === "--breakpoint-clamp-max") {
253
+ defaultClampRange.max = convertToRem(
254
+ decl.value,
255
+ rootFontSize,
256
+ spacingSize,
257
+ customProperties
258
+ );
224
259
  }
225
260
  if (decl.prop === "--spacing") {
226
261
  spacingSize = decl.value;
227
262
  }
228
263
  if (decl.prop.startsWith("--")) {
229
- const value = parseFloat(convertToRem(decl.value, rootFontSize, spacingSize, customProperties));
264
+ const value = convertToRem(
265
+ decl.value,
266
+ rootFontSize,
267
+ spacingSize,
268
+ customProperties
269
+ );
230
270
  if (value) customProperties[decl.prop] = value;
231
271
  }
232
272
  });
@@ -239,30 +279,38 @@ var clampwind = (opts = {}) => {
239
279
  screens = Object.assign(
240
280
  {},
241
281
  screens,
242
- config.defaultLayerBreakpoints,
243
282
  config.rootElementBreakpoints,
244
283
  config.themeLayerBreakpoints
245
284
  );
246
- screens = convertSortScreens(screens, rootFontSize);
285
+ screens = sortScreens(screens);
247
286
  containerScreens = Object.assign(
248
287
  {},
249
288
  containerScreens,
250
- config.defaultLayerContainerBreakpoints,
251
289
  config.rootElementContainerBreakpoints,
252
290
  config.themeLayerContainerBreakpoints
253
291
  );
254
- containerScreens = convertSortScreens(containerScreens, rootFontSize);
292
+ containerScreens = sortScreens(containerScreens);
255
293
  config.configReady = true;
256
294
  };
257
295
  const processClampDeclaration = (decl, minScreen, maxScreen, isContainer = false) => {
258
296
  const args = extractTwoValidClampArgs(decl.value);
259
- const [lower, upper] = args.map((val) => convertToRem(val, rootFontSize, spacingSize, customProperties));
297
+ const [lower, upper] = args.map(
298
+ (val) => convertToRem(val, rootFontSize, spacingSize, customProperties)
299
+ );
260
300
  if (!args || !lower || !upper) {
261
301
  console.warn("Invalid clamp() values", { node: decl });
262
302
  decl.value = ` ${decl.value} /* Invalid clamp() values */`;
263
303
  return true;
264
304
  }
265
- const clamp = generateClamp(lower, upper, minScreen, maxScreen, rootFontSize, spacingSize, isContainer);
305
+ const clamp = generateClamp(
306
+ lower,
307
+ upper,
308
+ minScreen,
309
+ maxScreen,
310
+ rootFontSize,
311
+ spacingSize,
312
+ isContainer
313
+ );
266
314
  decl.value = clamp;
267
315
  return true;
268
316
  };
@@ -272,8 +320,6 @@ var clampwind = (opts = {}) => {
272
320
  collectConfig(root);
273
321
  finalizeConfig();
274
322
  root.walkAtRules("media", (atRule) => {
275
- const isNested = atRule.parent?.type === "atrule";
276
- const isSameAtRule = atRule.parent?.name === atRule.name;
277
323
  const clampDecls = [];
278
324
  atRule.walkDecls((decl) => {
279
325
  if (extractTwoValidClampArgs(decl.value)) {
@@ -281,53 +327,56 @@ var clampwind = (opts = {}) => {
281
327
  }
282
328
  });
283
329
  if (!clampDecls.length) return;
284
- if (isNested && isSameAtRule) {
285
- const parentParams = atRule.parent.params;
286
- const currentParams = atRule.params;
287
- let minScreen = null;
288
- let maxScreen = null;
289
- if (parentParams.includes(">")) {
290
- const match = parentParams.match(/>=?\s*([^)]+)/);
291
- if (match) minScreen = match[1].trim();
292
- }
293
- if (currentParams.includes(">") && !minScreen) {
294
- const match = currentParams.match(/>=?\s*([^)]+)/);
295
- if (match) minScreen = match[1].trim();
296
- }
297
- if (parentParams.includes("<")) {
298
- const match = parentParams.match(/<\s*([^)]+)/);
299
- if (match) maxScreen = match[1].trim();
300
- }
301
- if (currentParams.includes("<") && !maxScreen) {
302
- const match = currentParams.match(/<\s*([^)]+)/);
303
- if (match) maxScreen = match[1].trim();
330
+ clampDecls.forEach((decl) => {
331
+ const isNested = decl.parent?.type === "atrule" && decl.parent?.parent.type === "atrule";
332
+ const isSameAtRule = decl.parent?.name === decl.parent?.parent.name;
333
+ if (isNested && isSameAtRule) {
334
+ const currentParams2 = decl.parent.params;
335
+ const parentParams = decl.parent.parent.params;
336
+ let minScreen = null;
337
+ let maxScreen = null;
338
+ if (parentParams.includes(">")) {
339
+ const match = parentParams.match(/>=?\s*([^)]+)/);
340
+ if (match) minScreen = match[1].trim();
341
+ }
342
+ if (currentParams2.includes(">") && !minScreen) {
343
+ const match = currentParams2.match(/>=?\s*([^)]+)/);
344
+ if (match) minScreen = match[1].trim();
345
+ }
346
+ if (parentParams.includes("<")) {
347
+ const match = parentParams.match(/<\s*([^)]+)/);
348
+ if (match) maxScreen = match[1].trim();
349
+ }
350
+ if (currentParams2.includes("<") && !maxScreen) {
351
+ const match = currentParams2.match(/<\s*([^)]+)/);
352
+ if (match) maxScreen = match[1].trim();
353
+ }
354
+ if (minScreen && maxScreen) {
355
+ clampDecls.forEach((decl2) => {
356
+ processClampDeclaration(decl2, minScreen, maxScreen, false);
357
+ });
358
+ }
359
+ return;
304
360
  }
305
- if (minScreen && maxScreen) {
306
- clampDecls.forEach((decl) => {
307
- processClampDeclaration(decl, minScreen, maxScreen, false);
361
+ if (isNested && !isSameAtRule) {
362
+ clampDecls.forEach((decl2) => {
363
+ decl2.value = ` ${decl2.value} /* Invalid nested @media rules */`;
308
364
  });
365
+ return;
309
366
  }
310
- return;
311
- }
312
- if (isNested && !isSameAtRule) {
313
- clampDecls.forEach((decl) => {
314
- decl.value = ` ${decl.value} /* Invalid nested @media rules */`;
315
- });
316
- return;
317
- }
318
- const screenValues = Object.values(screens);
319
- clampDecls.forEach((decl) => {
320
- if (atRule.params.includes(">")) {
321
- const match = atRule.params.match(/>=?\s*([^)]+)/);
367
+ const screenValues = Object.values(screens);
368
+ const currentParams = decl.parent.params;
369
+ if (currentParams.includes(">")) {
370
+ const match = currentParams.match(/>=?\s*([^)]+)/);
322
371
  if (match) {
323
372
  const minScreen = match[1].trim();
324
- const maxScreen = screenValues[screenValues.length - 1];
373
+ const maxScreen = defaultClampRange.max || screenValues[screenValues.length - 1];
325
374
  processClampDeclaration(decl, minScreen, maxScreen, false);
326
375
  }
327
- } else if (atRule.params.includes("<")) {
328
- const match = atRule.params.match(/<\s*([^)]+)/);
376
+ } else if (currentParams.includes("<")) {
377
+ const match = currentParams.match(/<\s*([^)]+)/);
329
378
  if (match) {
330
- const minScreen = screenValues[0];
379
+ const minScreen = defaultClampRange.min || screenValues[0];
331
380
  const maxScreen = match[1].trim();
332
381
  processClampDeclaration(decl, minScreen, maxScreen, false);
333
382
  }
@@ -335,8 +384,6 @@ var clampwind = (opts = {}) => {
335
384
  });
336
385
  });
337
386
  root.walkAtRules("container", (atRule) => {
338
- const isNested = atRule.parent?.type === "atrule";
339
- const isSameAtRule = atRule.parent?.name === atRule.name;
340
387
  const clampDecls = [];
341
388
  atRule.walkDecls((decl) => {
342
389
  if (extractTwoValidClampArgs(decl.value)) {
@@ -344,55 +391,73 @@ var clampwind = (opts = {}) => {
344
391
  }
345
392
  });
346
393
  if (!clampDecls.length) return;
347
- if (isNested && isSameAtRule) {
348
- const parentParams = atRule.parent.params;
349
- const currentParams = atRule.params;
350
- let minContainer = null;
351
- let maxContainer = null;
352
- if (parentParams.includes(">")) {
353
- const match = parentParams.match(/>=?\s*([^)]+)/);
354
- if (match) minContainer = match[1].trim();
355
- }
356
- if (currentParams.includes(">") && !minContainer) {
357
- const match = currentParams.match(/>=?\s*([^)]+)/);
358
- if (match) minContainer = match[1].trim();
359
- }
360
- if (parentParams.includes("<")) {
361
- const match = parentParams.match(/<\s*([^)]+)/);
362
- if (match) maxContainer = match[1].trim();
363
- }
364
- if (currentParams.includes("<") && !maxContainer) {
365
- const match = currentParams.match(/<\s*([^)]+)/);
366
- if (match) maxContainer = match[1].trim();
394
+ clampDecls.forEach((decl) => {
395
+ const isNested = decl.parent?.type === "atrule" && decl.parent?.parent.type === "atrule";
396
+ const isSameAtRule = decl.parent?.name === decl.parent?.parent.name;
397
+ if (isNested && isSameAtRule) {
398
+ const currentParams2 = decl.parent.params;
399
+ const parentParams = decl.parent.parent.params;
400
+ let minContainer = null;
401
+ let maxContainer = null;
402
+ if (parentParams.includes(">")) {
403
+ const match = parentParams.match(/>=?\s*([^)]+)/);
404
+ if (match) minContainer = match[1].trim();
405
+ }
406
+ if (currentParams2.includes(">") && !minContainer) {
407
+ const match = currentParams2.match(/>=?\s*([^)]+)/);
408
+ if (match) minContainer = match[1].trim();
409
+ }
410
+ if (parentParams.includes("<")) {
411
+ const match = parentParams.match(/<\s*([^)]+)/);
412
+ if (match) maxContainer = match[1].trim();
413
+ }
414
+ if (currentParams2.includes("<") && !maxContainer) {
415
+ const match = currentParams2.match(/<\s*([^)]+)/);
416
+ if (match) maxContainer = match[1].trim();
417
+ }
418
+ if (minContainer && maxContainer) {
419
+ clampDecls.forEach((decl2) => {
420
+ processClampDeclaration(
421
+ decl2,
422
+ minContainer,
423
+ maxContainer,
424
+ true
425
+ );
426
+ });
427
+ }
428
+ return;
367
429
  }
368
- if (minContainer && maxContainer) {
369
- clampDecls.forEach((decl) => {
370
- processClampDeclaration(decl, minContainer, maxContainer, true);
430
+ if (isNested && !isSameAtRule) {
431
+ clampDecls.forEach((decl2) => {
432
+ decl2.value = ` ${decl2.value} /* Invalid nested @container rules */`;
371
433
  });
434
+ return;
372
435
  }
373
- return;
374
- }
375
- if (isNested && !isSameAtRule) {
376
- clampDecls.forEach((decl) => {
377
- decl.value = ` ${decl.value} /* Invalid nested @container rules */`;
378
- });
379
- return;
380
- }
381
- const screenValues = Object.values(containerScreens);
382
- clampDecls.forEach((decl) => {
383
- if (atRule.params.includes(">")) {
384
- const match = atRule.params.match(/>=?\s*([^)]+)/);
436
+ const containerValues = Object.values(containerScreens);
437
+ const currentParams = decl.parent.params;
438
+ if (currentParams.includes(">")) {
439
+ const match = currentParams.match(/>=?\s*([^)]+)/);
385
440
  if (match) {
386
441
  const minContainer = match[1].trim();
387
- const maxContainer = screenValues[screenValues.length - 1];
388
- processClampDeclaration(decl, minContainer, maxContainer, true);
442
+ const maxContainer = containerValues[containerValues.length - 1];
443
+ processClampDeclaration(
444
+ decl,
445
+ minContainer,
446
+ maxContainer,
447
+ true
448
+ );
389
449
  }
390
- } else if (atRule.params.includes("<")) {
391
- const match = atRule.params.match(/<\s*([^)]+)/);
450
+ } else if (currentParams.includes("<")) {
451
+ const match = currentParams.match(/<\s*([^)]+)/);
392
452
  if (match) {
393
- const minContainer = screenValues[0];
453
+ const minContainer = containerValues[0];
394
454
  const maxContainer = match[1].trim();
395
- processClampDeclaration(decl, minContainer, maxContainer, true);
455
+ processClampDeclaration(
456
+ decl,
457
+ minContainer,
458
+ maxContainer,
459
+ true
460
+ );
396
461
  }
397
462
  }
398
463
  });
@@ -413,8 +478,8 @@ var clampwind = (opts = {}) => {
413
478
  });
414
479
  if (clampDecls.length === 0) return;
415
480
  const screenValues = Object.values(screens);
416
- const minScreen = screenValues[0];
417
- const maxScreen = screenValues[screenValues.length - 1];
481
+ const minScreen = defaultClampRange.min || screenValues[0];
482
+ const maxScreen = defaultClampRange.max || screenValues[screenValues.length - 1];
418
483
  clampDecls.forEach((decl) => {
419
484
  processClampDeclaration(decl, minScreen, maxScreen, false);
420
485
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss-clampwind",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "A PostCSS plugin to create fluid clamp values for any Tailwind CSS utility",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -34,9 +34,6 @@
34
34
  "devDependencies": {
35
35
  "esbuild": "^0.25.6"
36
36
  },
37
- "peerDependencies": {
38
- "postcss": "^8.4.39"
39
- },
40
37
  "scripts": {
41
38
  "dev": "node scripts/build.js --watch",
42
39
  "build": "node scripts/build.js"