@csstools/postcss-stepped-value-functions 2.0.0 → 2.1.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changes to PostCSS Stepped Value Functions
2
2
 
3
+ ### 2.1.0 (February 21, 2023)
4
+
5
+ - Removed: warnings on `var()` or otherwise unconvertible values (doesn't affect the output, non-breaking)
6
+ - Added: `@csstools/css-calc`
7
+ - Added: unit conversions (`mod(735ms, 0.1s)`)
8
+
9
+ ### 2.0.1 (January 28, 2023)
10
+
11
+ - Improve `types` declaration in `package.json`
12
+
3
13
  ### 2.0.0 (January 24, 2023)
4
14
 
5
15
  - Updated: Support for Node v14+ (major).
package/README.md CHANGED
@@ -106,26 +106,6 @@ postcssSteppedValueFunctions({ preserve: true })
106
106
  }
107
107
  ```
108
108
 
109
- ### onInvalid
110
-
111
- `onInvalid` option allows you to assign the `warn` value so you can get warnings when the usage of the functions is wrong.
112
-
113
- ```js
114
- postcssSteppedValueFunctions({ onInvalid: 'warn' })
115
- ```
116
-
117
- ```pcss
118
- .invalid {
119
- font-size: mod(18px, 5rem);
120
- }
121
- ```
122
-
123
- Will produce on the terminal:
124
-
125
- ```txt
126
- [postcss-stepped-value-functions]: Failed to transform mod(18px, 5rem) as the units don't match
127
- ```
128
-
129
109
  [cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
130
110
  [css-url]: https://cssdb.org/#stepped-value-functions
131
111
  [discord]: https://discord.gg/bUadyRwkJS
package/dist/calc.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function calc(css: string): string;
@@ -0,0 +1 @@
1
+ export declare const checks: string[];
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("postcss-value-parser");function isVarNode(e){return"function"===e.type&&"var"===e.value.toLowerCase()}function validateArgumentsAndTypes(n,t,o,r){const u=[];let a=!1;if(n.nodes.forEach((e=>{"word"!==e.type?isVarNode(e)&&(a=!0):u.push(e)})),a)return void optionallyWarn(t,o,`Failed to transform ${t.value} as variables can't be processed.`,r);if(2!==u.length)return void optionallyWarn(t,o,`Failed to transform ${t.value} as it's expecting 2 arguments instead of ${u.length}`,r);const s=e.unit(u[0].value),i=e.unit(u[1].value);if(s&&i){if(s.unit===i.unit)return[s,i];optionallyWarn(t,o,`Failed to transform ${t.value} as the units don't match`,r)}}function optionallyWarn(e,n,t,o){"warn"===o.onInvalid&&e.warn(n,t)}function functionNodeToWordNode(e){delete e.nodes;const n=e;return n.type="word",n}const n="mod(";function transformModFunction(n,t,o){const r=e(n.value);return r.walk((e=>{if("function"!==e.type||"mod"!==e.value.toLowerCase())return;const r=validateArgumentsAndTypes(e,n,t,o);if(!r)return;const[u,a]=r,s=Number(u.number),i=Number(a.number),l=(s%i+i)%i;if("number"!=typeof l||isNaN(l))return;functionNodeToWordNode(e).value=0===l?"0":`${l}${u.unit}`}),!0),r.toString()}const t="rem(";function transformRemFunction(n,t,o){const r=e(n.value);return r.walk((e=>{if("function"!==e.type||"rem"!==e.value.toLowerCase())return;const r=validateArgumentsAndTypes(e,n,t,o);if(!r)return;const[u,a]=r,s=Number(u.number)%Number(a.number);if("number"!=typeof s&&!isNaN(s))return;functionNodeToWordNode(e).value=0===s?"0":`${s}${u.unit}`}),!0),r.toString()}const o="round(";var r;!function(e){e.Nearest="nearest",e.Up="up",e.Down="down",e.ToZero="to-zero"}(r||(r={}));const u=/^[a-z|-]+$/i;function transformRoundFunction(n,t,o){const a=e(n.value);return a.walk((a=>{if("function"!==a.type||"round"!==a.value.toLowerCase())return;if(3!==a.nodes.length&&5!==a.nodes.length)return void optionallyWarn(n,t,`Failed to transform ${n.value} as the amount of arguments isn't valid`,o);const s=a.nodes.filter((e=>"word"===e.type)),i=s[0].value;let l,c,d;if(u.test(i.toLowerCase())){var f,v;if(!Object.values(r).includes(i.toLowerCase()))return void optionallyWarn(n,t,`Failed to transform ${n.value} as ${i} is not a valid rounding strategy.`,o);l=i.toLowerCase(),c=e.unit((null==s||null==(f=s[1])?void 0:f.value)||""),d=e.unit((null==s||null==(v=s[2])?void 0:v.value)||"")}else{var m,p;l=r.Nearest,c=e.unit((null==s||null==(m=s[0])?void 0:m.value)||""),d=e.unit((null==s||null==(p=s[1])?void 0:p.value)||"")}if(!c||!d)return;if(c.unit!==d.unit)return void optionallyWarn(n,t,`Failed to transform ${n.value} as the units don't match`,o);const N=Number(c.number),b=Number(d.number);let w;switch(l){case r.Down:w=Math.floor(N/b)*b;break;case r.Up:w=Math.ceil(N/b)*b;break;case r.ToZero:w=Math.trunc(N/b)*b;break;case r.Nearest:default:w=Math.round(N/b)*b}if("number"!=typeof w||isNaN(w))return;functionNodeToWordNode(a).value=0===w?"0":`${w}${c.unit}`}),!0),a.toString()}const creator=e=>{const r=Object.assign({preserve:!1,onInvalid:""},e);return{postcssPlugin:"postcss-stepped-value-functions",Declaration(e,{result:u}){const a=[n,t,o].some((n=>e.value.toLowerCase().includes(n)));if(!e||!a)return;const s=e.clone();if(s.value.toLowerCase().includes(n)){const e=transformModFunction(s,u,r);e&&(s.value=e)}if(s.value.toLowerCase().includes(t)){const e=transformRemFunction(s,u,r);e&&(s.value=e)}if(s.value.toLowerCase().includes(o)){const e=transformRoundFunction(s,u,r);e&&(s.value=e)}e.value!==s.value&&(e.before(s),r.preserve||e.remove())}}};creator.postcss=!0,module.exports=creator;
1
+ "use strict";var e=require("@csstools/css-calc"),o=require("@csstools/css-parser-algorithms"),s=require("@csstools/css-tokenizer");const n=["mod(","rem(","round("];function calc(t){const r=s.tokenizer({css:t}),c=[];for(;!r.endOfFile();)c.push(r.nextToken());c.push(r.nextToken());const i=o.parseCommaSeparatedListOfComponentValues(c,{});let a=!1;for(let e=0;e<i.length;e++){const s=i[e];for(let e=0;e<s.length;e++){const t=s[e];if(o.isFunctionNode(t)&&n.includes(t.getName().toLowerCase()+"(")){a=!0;break}(o.isSimpleBlockNode(t)||o.isFunctionNode(t))&&t.walk(((e,s)=>{if("number"!=typeof s)return;const t=e.node;return o.isFunctionNode(t)&&n.includes(t.getName().toLowerCase()+"(")?(a=!0,!1):void 0}))}}return a?e.calcFromComponentValues(i,{precision:5,toCanonicalUnits:!0}).map((e=>e.map((e=>s.stringify(...e.tokens()))).join(""))).join(","):t}const creator=e=>{const o=Object.assign({preserve:!1,onInvalid:""},e);return{postcssPlugin:"postcss-stepped-value-functions",Declaration(e){if(!n.some((o=>e.value.toLowerCase().includes(o))))return;const s=calc(e.value);s!==e.value&&(e.cloneBefore({value:s}),o.preserve||e.remove())}}};creator.postcss=!0,module.exports=creator;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import type { PluginCreator } from 'postcss';
2
- import type { pluginOptions } from './options';
3
- export type { pluginOptions } from './options';
2
+ /** postcss-stepped-value-functions plugin options */
3
+ export type pluginOptions = {
4
+ /** Preserve the original notation. default: false */
5
+ preserve?: boolean;
6
+ };
4
7
  declare const creator: PluginCreator<pluginOptions>;
5
8
  export default creator;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import e from"postcss-value-parser";function isVarNode(e){return"function"===e.type&&"var"===e.value.toLowerCase()}function validateArgumentsAndTypes(n,t,o,r){const a=[];let u=!1;if(n.nodes.forEach((e=>{"word"!==e.type?isVarNode(e)&&(u=!0):a.push(e)})),u)return void optionallyWarn(t,o,`Failed to transform ${t.value} as variables can't be processed.`,r);if(2!==a.length)return void optionallyWarn(t,o,`Failed to transform ${t.value} as it's expecting 2 arguments instead of ${a.length}`,r);const s=e.unit(a[0].value),i=e.unit(a[1].value);if(s&&i){if(s.unit===i.unit)return[s,i];optionallyWarn(t,o,`Failed to transform ${t.value} as the units don't match`,r)}}function optionallyWarn(e,n,t,o){"warn"===o.onInvalid&&e.warn(n,t)}function functionNodeToWordNode(e){delete e.nodes;const n=e;return n.type="word",n}const n="mod(";function transformModFunction(n,t,o){const r=e(n.value);return r.walk((e=>{if("function"!==e.type||"mod"!==e.value.toLowerCase())return;const r=validateArgumentsAndTypes(e,n,t,o);if(!r)return;const[a,u]=r,s=Number(a.number),i=Number(u.number),l=(s%i+i)%i;if("number"!=typeof l||isNaN(l))return;functionNodeToWordNode(e).value=0===l?"0":`${l}${a.unit}`}),!0),r.toString()}const t="rem(";function transformRemFunction(n,t,o){const r=e(n.value);return r.walk((e=>{if("function"!==e.type||"rem"!==e.value.toLowerCase())return;const r=validateArgumentsAndTypes(e,n,t,o);if(!r)return;const[a,u]=r,s=Number(a.number)%Number(u.number);if("number"!=typeof s&&!isNaN(s))return;functionNodeToWordNode(e).value=0===s?"0":`${s}${a.unit}`}),!0),r.toString()}const o="round(";var r;!function(e){e.Nearest="nearest",e.Up="up",e.Down="down",e.ToZero="to-zero"}(r||(r={}));const a=/^[a-z|-]+$/i;function transformRoundFunction(n,t,o){const u=e(n.value);return u.walk((u=>{if("function"!==u.type||"round"!==u.value.toLowerCase())return;if(3!==u.nodes.length&&5!==u.nodes.length)return void optionallyWarn(n,t,`Failed to transform ${n.value} as the amount of arguments isn't valid`,o);const s=u.nodes.filter((e=>"word"===e.type)),i=s[0].value;let l,c,d;if(a.test(i.toLowerCase())){var f,v;if(!Object.values(r).includes(i.toLowerCase()))return void optionallyWarn(n,t,`Failed to transform ${n.value} as ${i} is not a valid rounding strategy.`,o);l=i.toLowerCase(),c=e.unit((null==s||null==(f=s[1])?void 0:f.value)||""),d=e.unit((null==s||null==(v=s[2])?void 0:v.value)||"")}else{var m,p;l=r.Nearest,c=e.unit((null==s||null==(m=s[0])?void 0:m.value)||""),d=e.unit((null==s||null==(p=s[1])?void 0:p.value)||"")}if(!c||!d)return;if(c.unit!==d.unit)return void optionallyWarn(n,t,`Failed to transform ${n.value} as the units don't match`,o);const N=Number(c.number),b=Number(d.number);let w;switch(l){case r.Down:w=Math.floor(N/b)*b;break;case r.Up:w=Math.ceil(N/b)*b;break;case r.ToZero:w=Math.trunc(N/b)*b;break;case r.Nearest:default:w=Math.round(N/b)*b}if("number"!=typeof w||isNaN(w))return;functionNodeToWordNode(u).value=0===w?"0":`${w}${c.unit}`}),!0),u.toString()}const creator=e=>{const r=Object.assign({preserve:!1,onInvalid:""},e);return{postcssPlugin:"postcss-stepped-value-functions",Declaration(e,{result:a}){const u=[n,t,o].some((n=>e.value.toLowerCase().includes(n)));if(!e||!u)return;const s=e.clone();if(s.value.toLowerCase().includes(n)){const e=transformModFunction(s,a,r);e&&(s.value=e)}if(s.value.toLowerCase().includes(t)){const e=transformRemFunction(s,a,r);e&&(s.value=e)}if(s.value.toLowerCase().includes(o)){const e=transformRoundFunction(s,a,r);e&&(s.value=e)}e.value!==s.value&&(e.before(s),r.preserve||e.remove())}}};creator.postcss=!0;export{creator as default};
1
+ import{calcFromComponentValues as e}from"@csstools/css-calc";import{parseCommaSeparatedListOfComponentValues as o,isFunctionNode as s,isSimpleBlockNode as t}from"@csstools/css-parser-algorithms";import{tokenizer as n,stringify as r}from"@csstools/css-tokenizer";const c=["mod(","rem(","round("];function calc(l){const a=n({css:l}),i=[];for(;!a.endOfFile();)i.push(a.nextToken());i.push(a.nextToken());const u=o(i,{});let p=!1;for(let e=0;e<u.length;e++){const o=u[e];for(let e=0;e<o.length;e++){const n=o[e];if(s(n)&&c.includes(n.getName().toLowerCase()+"(")){p=!0;break}(t(n)||s(n))&&n.walk(((e,o)=>{if("number"!=typeof o)return;const t=e.node;return s(t)&&c.includes(t.getName().toLowerCase()+"(")?(p=!0,!1):void 0}))}}return p?e(u,{precision:5,toCanonicalUnits:!0}).map((e=>e.map((e=>r(...e.tokens()))).join(""))).join(","):l}const creator=e=>{const o=Object.assign({preserve:!1,onInvalid:""},e);return{postcssPlugin:"postcss-stepped-value-functions",Declaration(e){if(!c.some((o=>e.value.toLowerCase().includes(o))))return;const s=calc(e.value);s!==e.value&&(e.cloneBefore({value:s}),o.preserve||e.remove())}}};creator.postcss=!0;export{creator as default};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@csstools/postcss-stepped-value-functions",
3
3
  "description": "Use round, rem and mod functions in CSS",
4
- "version": "2.0.0",
4
+ "version": "2.1.0",
5
5
  "contributors": [
6
6
  {
7
7
  "name": "Antonio Laguna",
@@ -26,6 +26,7 @@
26
26
  "types": "dist/index.d.ts",
27
27
  "exports": {
28
28
  ".": {
29
+ "types": "./dist/index.d.ts",
29
30
  "import": "./dist/index.mjs",
30
31
  "require": "./dist/index.cjs",
31
32
  "default": "./dist/index.mjs"
@@ -38,7 +39,9 @@
38
39
  "dist"
39
40
  ],
40
41
  "dependencies": {
41
- "postcss-value-parser": "^4.2.0"
42
+ "@csstools/css-calc": "^1.0.0",
43
+ "@csstools/css-parser-algorithms": "^2.0.1",
44
+ "@csstools/css-tokenizer": "^2.0.1"
42
45
  },
43
46
  "peerDependencies": {
44
47
  "postcss": "^8.4"
package/dist/mod.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { Declaration, Result } from 'postcss';
2
- import type { pluginOptions } from './options';
3
- declare const modFunctionCheck = "mod(";
4
- declare function transformModFunction(decl: Declaration, result: Result, options: pluginOptions): string | undefined;
5
- export { modFunctionCheck, transformModFunction };
package/dist/options.d.ts DELETED
@@ -1,10 +0,0 @@
1
- /** postcss-stepped-value-functions plugin options */
2
- export type pluginOptions = {
3
- /** Preserve the original notation. default: false */
4
- preserve?: boolean;
5
- /**
6
- * Set `warn` to get warnings when the usage of the functions is incorrect.
7
- * default: _not set_
8
- */
9
- onInvalid?: 'warn';
10
- };
package/dist/rem.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { Declaration, Result } from 'postcss';
2
- import type { pluginOptions } from './options';
3
- declare const remFunctionCheck = "rem(";
4
- declare function transformRemFunction(decl: Declaration, result: Result, options: pluginOptions): string | undefined;
5
- export { remFunctionCheck, transformRemFunction };
package/dist/round.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { Declaration, Result } from 'postcss';
2
- import type { pluginOptions } from './options';
3
- declare const roundFunctionCheck = "round(";
4
- declare function transformRoundFunction(decl: Declaration, result: Result, options: pluginOptions): string | undefined;
5
- export { roundFunctionCheck, transformRoundFunction };
package/dist/utils.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import valueParser from 'postcss-value-parser';
2
- import type { FunctionNode, Node, WordNode } from 'postcss-value-parser';
3
- import type { Declaration, Result } from 'postcss';
4
- import type { pluginOptions } from './options';
5
- export declare function isVarNode(node: Node): boolean;
6
- export declare function validateArgumentsAndTypes(node: FunctionNode, decl: Declaration, result: Result, options: pluginOptions): valueParser.Dimension[] | undefined;
7
- export declare function optionallyWarn(decl: Declaration, result: Result, message: string, options: pluginOptions): void;
8
- export declare function functionNodeToWordNode(fn: FunctionNode): WordNode;