@just-web/toolkits 2.1.0 → 3.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.
Files changed (130) hide show
  1. package/dist/attributes/observe-attribute.cjs +10 -7
  2. package/dist/attributes/observe-attribute.cjs.map +1 -1
  3. package/dist/attributes/observe-attribute.d.cts +6 -6
  4. package/dist/attributes/observe-attribute.d.cts.map +1 -1
  5. package/dist/attributes/observe-attribute.d.mts +6 -6
  6. package/dist/attributes/observe-attribute.d.mts.map +1 -1
  7. package/dist/attributes/observe-attribute.mjs +10 -7
  8. package/dist/attributes/observe-attribute.mjs.map +1 -1
  9. package/dist/attributes/observe-data-attribute.cjs +7 -10
  10. package/dist/attributes/observe-data-attribute.cjs.map +1 -1
  11. package/dist/attributes/observe-data-attribute.d.cts +8 -11
  12. package/dist/attributes/observe-data-attribute.d.cts.map +1 -1
  13. package/dist/attributes/observe-data-attribute.d.mts +8 -11
  14. package/dist/attributes/observe-data-attribute.d.mts.map +1 -1
  15. package/dist/attributes/observe-data-attribute.mjs +7 -10
  16. package/dist/attributes/observe-data-attribute.mjs.map +1 -1
  17. package/dist/index.cjs +13 -2
  18. package/dist/index.d.cts +8 -2
  19. package/dist/index.d.mts +8 -2
  20. package/dist/index.mjs +7 -2
  21. package/dist/react/hooks/use-attribute.cjs +1 -2
  22. package/dist/react/hooks/use-attribute.cjs.map +1 -1
  23. package/dist/react/hooks/use-attribute.mjs +1 -2
  24. package/dist/react/hooks/use-attribute.mjs.map +1 -1
  25. package/dist/style/css-properties.d.cts +2 -1
  26. package/dist/style/css-properties.d.cts.map +1 -1
  27. package/dist/style/css-properties.d.mts +2 -1
  28. package/dist/style/css-properties.d.mts.map +1 -1
  29. package/dist/theme/class-name/subscribe-class-name.cjs +1 -2
  30. package/dist/theme/class-name/subscribe-class-name.cjs.map +1 -1
  31. package/dist/theme/class-name/subscribe-class-name.mjs +1 -2
  32. package/dist/theme/class-name/subscribe-class-name.mjs.map +1 -1
  33. package/dist/theme/data-attribute/subscribe-data-attribute.cjs +1 -2
  34. package/dist/theme/data-attribute/subscribe-data-attribute.cjs.map +1 -1
  35. package/dist/theme/data-attribute/subscribe-data-attribute.mjs +1 -2
  36. package/dist/theme/data-attribute/subscribe-data-attribute.mjs.map +1 -1
  37. package/dist/units/convert-css-unit.cjs +173 -0
  38. package/dist/units/convert-css-unit.cjs.map +1 -0
  39. package/dist/units/convert-css-unit.d.cts +25 -0
  40. package/dist/units/convert-css-unit.d.cts.map +1 -0
  41. package/dist/units/convert-css-unit.d.mts +25 -0
  42. package/dist/units/convert-css-unit.d.mts.map +1 -0
  43. package/dist/units/convert-css-unit.mjs +173 -0
  44. package/dist/units/convert-css-unit.mjs.map +1 -0
  45. package/dist/units/create-css-unit-converter.cjs +33 -0
  46. package/dist/units/create-css-unit-converter.cjs.map +1 -0
  47. package/dist/units/create-css-unit-converter.d.cts +28 -0
  48. package/dist/units/create-css-unit-converter.d.cts.map +1 -0
  49. package/dist/units/create-css-unit-converter.d.mts +28 -0
  50. package/dist/units/create-css-unit-converter.d.mts.map +1 -0
  51. package/dist/units/create-css-unit-converter.mjs +33 -0
  52. package/dist/units/create-css-unit-converter.mjs.map +1 -0
  53. package/dist/units/css-unit-converter.types.d.cts +35 -0
  54. package/dist/units/css-unit-converter.types.d.cts.map +1 -0
  55. package/dist/units/css-unit-converter.types.d.mts +35 -0
  56. package/dist/units/css-unit-converter.types.d.mts.map +1 -0
  57. package/dist/units/get-css-unit.cjs +29 -0
  58. package/dist/units/get-css-unit.cjs.map +1 -0
  59. package/dist/units/get-css-unit.d.cts +23 -0
  60. package/dist/units/get-css-unit.d.cts.map +1 -0
  61. package/dist/units/get-css-unit.d.mts +23 -0
  62. package/dist/units/get-css-unit.d.mts.map +1 -0
  63. package/dist/units/get-css-unit.mjs +29 -0
  64. package/dist/units/get-css-unit.mjs.map +1 -0
  65. package/dist/units/is-effectively-zero.cjs +35 -0
  66. package/dist/units/is-effectively-zero.cjs.map +1 -0
  67. package/dist/units/is-effectively-zero.d.cts +28 -0
  68. package/dist/units/is-effectively-zero.d.cts.map +1 -0
  69. package/dist/units/is-effectively-zero.d.mts +28 -0
  70. package/dist/units/is-effectively-zero.d.mts.map +1 -0
  71. package/dist/units/is-effectively-zero.mjs +35 -0
  72. package/dist/units/is-effectively-zero.mjs.map +1 -0
  73. package/dist/units/parse-css-number.cjs +29 -0
  74. package/dist/units/parse-css-number.cjs.map +1 -0
  75. package/dist/units/parse-css-number.d.cts +24 -0
  76. package/dist/units/parse-css-number.d.cts.map +1 -0
  77. package/dist/units/parse-css-number.d.mts +24 -0
  78. package/dist/units/parse-css-number.d.mts.map +1 -0
  79. package/dist/units/parse-css-number.mjs +29 -0
  80. package/dist/units/parse-css-number.mjs.map +1 -0
  81. package/dist/units/parse-css-value.cjs +32 -0
  82. package/dist/units/parse-css-value.cjs.map +1 -0
  83. package/dist/units/parse-css-value.d.cts +22 -0
  84. package/dist/units/parse-css-value.d.cts.map +1 -0
  85. package/dist/units/parse-css-value.d.mts +22 -0
  86. package/dist/units/parse-css-value.d.mts.map +1 -0
  87. package/dist/units/parse-css-value.mjs +31 -0
  88. package/dist/units/parse-css-value.mjs.map +1 -0
  89. package/dist/units/px-2-rem.cjs +8 -5
  90. package/dist/units/px-2-rem.cjs.map +1 -1
  91. package/dist/units/px-2-rem.d.cts +9 -7
  92. package/dist/units/px-2-rem.d.cts.map +1 -1
  93. package/dist/units/px-2-rem.d.mts +9 -7
  94. package/dist/units/px-2-rem.d.mts.map +1 -1
  95. package/dist/units/px-2-rem.mjs +8 -5
  96. package/dist/units/px-2-rem.mjs.map +1 -1
  97. package/dist/units/rem-2-px.cjs +8 -5
  98. package/dist/units/rem-2-px.cjs.map +1 -1
  99. package/dist/units/rem-2-px.d.cts +9 -7
  100. package/dist/units/rem-2-px.d.cts.map +1 -1
  101. package/dist/units/rem-2-px.d.mts +9 -7
  102. package/dist/units/rem-2-px.d.mts.map +1 -1
  103. package/dist/units/rem-2-px.mjs +8 -5
  104. package/dist/units/rem-2-px.mjs.map +1 -1
  105. package/package.json +1 -1
  106. package/src/attributes/observe-attribute.ts +13 -8
  107. package/src/attributes/observe-data-attribute.ts +7 -10
  108. package/src/index.ts +7 -0
  109. package/src/react/hooks/use-attribute.ts +1 -2
  110. package/src/style/css-properties.ts +3 -1
  111. package/src/theme/class-name/subscribe-class-name.ts +1 -2
  112. package/src/theme/data-attribute/subscribe-data-attribute.ts +1 -2
  113. package/src/units/convert-css-unit.ts +292 -0
  114. package/src/units/create-css-unit-converter.ts +30 -0
  115. package/src/units/css-unit-converter.types.ts +49 -0
  116. package/src/units/get-css-unit.ts +24 -0
  117. package/src/units/is-effectively-zero.ts +35 -0
  118. package/src/units/parse-css-number.ts +26 -0
  119. package/src/units/parse-css-value.ts +35 -0
  120. package/src/units/px-2-num.ts +5 -4
  121. package/src/units/px-2-rem.ts +12 -8
  122. package/src/units/rem-2-px.ts +11 -9
  123. package/dist/units/px-2-num.cjs +0 -23
  124. package/dist/units/px-2-num.cjs.map +0 -1
  125. package/dist/units/px-2-num.d.cts +0 -19
  126. package/dist/units/px-2-num.d.cts.map +0 -1
  127. package/dist/units/px-2-num.d.mts +0 -19
  128. package/dist/units/px-2-num.d.mts.map +0 -1
  129. package/dist/units/px-2-num.mjs +0 -22
  130. package/dist/units/px-2-num.mjs.map +0 -1
@@ -0,0 +1,31 @@
1
+ //#region src/units/parse-css-value.ts
2
+ /**
3
+ * Parses a CSS value in one pass and returns both the numeric part and the unit.
4
+ * Powers parseCssNumber, getCssUnit, and isEffectivelyZero.
5
+ *
6
+ * @param value - The CSS value to parse. Can be a number or string (e.g. '16px', '1.5rem', '100%')
7
+ * @returns A tuple of [number, unit | undefined]. Unit is undefined for numbers or unitless strings.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * parseCssValue('16px') // [16, 'px']
12
+ * parseCssValue('1.5rem') // [1.5, 'rem']
13
+ * parseCssValue('100%') // [100, '%']
14
+ * parseCssValue('0') // [0, undefined]
15
+ * parseCssValue(16) // [16, undefined]
16
+ * parseCssValue('abc') // [NaN, undefined]
17
+ * ```
18
+ */
19
+ function parseCssValue(value) {
20
+ if (value === void 0 || value === null) return [value, void 0];
21
+ if (typeof value === "number") return [value, void 0];
22
+ const match = String(value).trim().match(/^(-?\d*\.?\d+)\s*(.*)$/);
23
+ if (!match) return [NaN, void 0];
24
+ const num = Number.parseFloat(match[1] ?? "");
25
+ const unit = (match[2] ?? "").trim();
26
+ return [num, unit === "" ? void 0 : unit];
27
+ }
28
+
29
+ //#endregion
30
+ export { parseCssValue };
31
+ //# sourceMappingURL=parse-css-value.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-css-value.mjs","names":[],"sources":["../../src/units/parse-css-value.ts"],"sourcesContent":["/**\n * Parses a CSS value in one pass and returns both the numeric part and the unit.\n * Powers parseCssNumber, getCssUnit, and isEffectivelyZero.\n *\n * @param value - The CSS value to parse. Can be a number or string (e.g. '16px', '1.5rem', '100%')\n * @returns A tuple of [number, unit | undefined]. Unit is undefined for numbers or unitless strings.\n *\n * @example\n * ```ts\n * parseCssValue('16px') // [16, 'px']\n * parseCssValue('1.5rem') // [1.5, 'rem']\n * parseCssValue('100%') // [100, '%']\n * parseCssValue('0') // [0, undefined]\n * parseCssValue(16) // [16, undefined]\n * parseCssValue('abc') // [NaN, undefined]\n * ```\n */\nexport function parseCssValue(\n\tvalue: number | string | null | undefined\n): [number | null | undefined, string | undefined] {\n\tif (value === undefined || value === null) {\n\t\treturn [value, undefined]\n\t}\n\tif (typeof value === 'number') {\n\t\treturn [value, undefined]\n\t}\n\tconst s = String(value).trim()\n\tconst match = s.match(/^(-?\\d*\\.?\\d+)\\s*(.*)$/)\n\tif (!match) {\n\t\treturn [Number.NaN, undefined]\n\t}\n\tconst num = Number.parseFloat(match[1] ?? '')\n\tconst unit = (match[2] ?? '').trim()\n\treturn [num, unit === '' ? undefined : unit]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,SAAgB,cACf,OACkD;AAClD,KAAI,UAAU,UAAa,UAAU,KACpC,QAAO,CAAC,OAAO,OAAU;AAE1B,KAAI,OAAO,UAAU,SACpB,QAAO,CAAC,OAAO,OAAU;CAG1B,MAAM,QADI,OAAO,MAAM,CAAC,MAAM,CACd,MAAM,yBAAyB;AAC/C,KAAI,CAAC,MACJ,QAAO,CAAC,KAAY,OAAU;CAE/B,MAAM,MAAM,OAAO,WAAW,MAAM,MAAM,GAAG;CAC7C,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM;AACpC,QAAO,CAAC,KAAK,SAAS,KAAK,SAAY,KAAK"}
@@ -7,17 +7,20 @@
7
7
  * @param options - Optional configuration
8
8
  * @param options.base - Base pixel value to calculate rem units from. Defaults to 16
9
9
  * @param options.precision - Number of decimal places in the output. Defaults to 4
10
- * @returns The converted value as a string with 'rem' units
10
+ * @returns The converted value, or null/undefined if input is null/undefined
11
11
  *
12
12
  * @example
13
13
  * ```ts
14
- * px2rem(16) // '1.0000'
15
- * px2rem('32px') // '2.0000'
16
- * px2rem(20, { base: 20 }) // '1.0000'
17
- * px2rem(13, { precision: 2 }) // '0.81'
14
+ * px2rem(16) // 1
15
+ * px2rem('32px') // 2
16
+ * px2rem(20, { base: 20 }) // 1
17
+ * px2rem(13, { precision: 2 }) // 0.81
18
+ * px2rem(null) // null
19
+ * px2rem(undefined) // undefined
18
20
  * ```
19
21
  */
20
22
  function px2rem(px, options) {
23
+ if (px === null || px === void 0) return px;
21
24
  const { base = 16, precision = 4 } = options ?? {};
22
25
  if (typeof px === "string") {
23
26
  px = px.replace(/px$/, "");
@@ -1 +1 @@
1
- {"version":3,"file":"px-2-rem.cjs","names":[],"sources":["../../src/units/px-2-rem.ts"],"sourcesContent":["/**\n * Converts pixel values to rem units.\n *\n * @param px - The pixel value to convert. Can be a number or string (e.g. '16px' or '16')\n * @param options - Optional configuration\n * @param options.base - Base pixel value to calculate rem units from. Defaults to 16\n * @param options.precision - Number of decimal places in the output. Defaults to 4\n * @returns The converted value as a string with 'rem' units\n *\n * @example\n * ```ts\n * px2rem(16) // '1.0000'\n * px2rem('32px') // '2.0000'\n * px2rem(20, { base: 20 }) // '1.0000'\n * px2rem(13, { precision: 2 }) // '0.81'\n * ```\n */\nexport function px2rem(\n\tpx: number | string,\n\toptions?: { base?: number | undefined; precision?: number | undefined }\n): number {\n\tconst { base = 16, precision = 4 } = options ?? {}\n\n\tif (typeof px === 'string') {\n\t\tpx = px.replace(/px$/, '')\n\t\tpx = Number.parseFloat(px)\n\t}\n\n\treturn Number((px / base).toFixed(precision))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiBA,SAAgB,OACf,IACA,SACS;CACT,MAAM,EAAE,OAAO,IAAI,YAAY,MAAM,WAAW,EAAE;AAElD,KAAI,OAAO,OAAO,UAAU;AAC3B,OAAK,GAAG,QAAQ,OAAO,GAAG;AAC1B,OAAK,OAAO,WAAW,GAAG;;AAG3B,QAAO,QAAQ,KAAK,MAAM,QAAQ,UAAU,CAAC"}
1
+ {"version":3,"file":"px-2-rem.cjs","names":[],"sources":["../../src/units/px-2-rem.ts"],"sourcesContent":["/**\n * Converts pixel values to rem units.\n *\n * @param px - The pixel value to convert. Can be a number or string (e.g. '16px' or '16')\n * @param options - Optional configuration\n * @param options.base - Base pixel value to calculate rem units from. Defaults to 16\n * @param options.precision - Number of decimal places in the output. Defaults to 4\n * @returns The converted value, or null/undefined if input is null/undefined\n *\n * @example\n * ```ts\n * px2rem(16) // 1\n * px2rem('32px') // 2\n * px2rem(20, { base: 20 }) // 1\n * px2rem(13, { precision: 2 }) // 0.81\n * px2rem(null) // null\n * px2rem(undefined) // undefined\n * ```\n */\nexport function px2rem(\n\tpx: number | string | null | undefined,\n\toptions?: { base?: number | undefined; precision?: number | undefined } | undefined\n): number | null | undefined {\n\tif (px === null || px === undefined) return px\n\n\tconst { base = 16, precision = 4 } = options ?? {}\n\n\tif (typeof px === 'string') {\n\t\tpx = px.replace(/px$/, '')\n\t\tpx = Number.parseFloat(px)\n\t}\n\n\treturn Number((px / base).toFixed(precision))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,OACf,IACA,SAC4B;AAC5B,KAAI,OAAO,QAAQ,OAAO,OAAW,QAAO;CAE5C,MAAM,EAAE,OAAO,IAAI,YAAY,MAAM,WAAW,EAAE;AAElD,KAAI,OAAO,OAAO,UAAU;AAC3B,OAAK,GAAG,QAAQ,OAAO,GAAG;AAC1B,OAAK,OAAO,WAAW,GAAG;;AAG3B,QAAO,QAAQ,KAAK,MAAM,QAAQ,UAAU,CAAC"}
@@ -6,20 +6,22 @@
6
6
  * @param options - Optional configuration
7
7
  * @param options.base - Base pixel value to calculate rem units from. Defaults to 16
8
8
  * @param options.precision - Number of decimal places in the output. Defaults to 4
9
- * @returns The converted value as a string with 'rem' units
9
+ * @returns The converted value, or null/undefined if input is null/undefined
10
10
  *
11
11
  * @example
12
12
  * ```ts
13
- * px2rem(16) // '1.0000'
14
- * px2rem('32px') // '2.0000'
15
- * px2rem(20, { base: 20 }) // '1.0000'
16
- * px2rem(13, { precision: 2 }) // '0.81'
13
+ * px2rem(16) // 1
14
+ * px2rem('32px') // 2
15
+ * px2rem(20, { base: 20 }) // 1
16
+ * px2rem(13, { precision: 2 }) // 0.81
17
+ * px2rem(null) // null
18
+ * px2rem(undefined) // undefined
17
19
  * ```
18
20
  */
19
- declare function px2rem(px: number | string, options?: {
21
+ declare function px2rem(px: number | string | null | undefined, options?: {
20
22
  base?: number | undefined;
21
23
  precision?: number | undefined;
22
- }): number;
24
+ } | undefined): number | null | undefined;
23
25
  //#endregion
24
26
  export { px2rem };
25
27
  //# sourceMappingURL=px-2-rem.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"px-2-rem.d.cts","names":[],"sources":["../../src/units/px-2-rem.ts"],"sourcesContent":[],"mappings":";;AAiBA;;;;;;;;;;;;;;;;iBAAgB,MAAA"}
1
+ {"version":3,"file":"px-2-rem.d.cts","names":[],"sources":["../../src/units/px-2-rem.ts"],"sourcesContent":[],"mappings":";;AAmBA;;;;;;;;;;;;;;;;;;iBAAgB,MAAA"}
@@ -6,20 +6,22 @@
6
6
  * @param options - Optional configuration
7
7
  * @param options.base - Base pixel value to calculate rem units from. Defaults to 16
8
8
  * @param options.precision - Number of decimal places in the output. Defaults to 4
9
- * @returns The converted value as a string with 'rem' units
9
+ * @returns The converted value, or null/undefined if input is null/undefined
10
10
  *
11
11
  * @example
12
12
  * ```ts
13
- * px2rem(16) // '1.0000'
14
- * px2rem('32px') // '2.0000'
15
- * px2rem(20, { base: 20 }) // '1.0000'
16
- * px2rem(13, { precision: 2 }) // '0.81'
13
+ * px2rem(16) // 1
14
+ * px2rem('32px') // 2
15
+ * px2rem(20, { base: 20 }) // 1
16
+ * px2rem(13, { precision: 2 }) // 0.81
17
+ * px2rem(null) // null
18
+ * px2rem(undefined) // undefined
17
19
  * ```
18
20
  */
19
- declare function px2rem(px: number | string, options?: {
21
+ declare function px2rem(px: number | string | null | undefined, options?: {
20
22
  base?: number | undefined;
21
23
  precision?: number | undefined;
22
- }): number;
24
+ } | undefined): number | null | undefined;
23
25
  //#endregion
24
26
  export { px2rem };
25
27
  //# sourceMappingURL=px-2-rem.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"px-2-rem.d.mts","names":[],"sources":["../../src/units/px-2-rem.ts"],"sourcesContent":[],"mappings":";;AAiBA;;;;;;;;;;;;;;;;iBAAgB,MAAA"}
1
+ {"version":3,"file":"px-2-rem.d.mts","names":[],"sources":["../../src/units/px-2-rem.ts"],"sourcesContent":[],"mappings":";;AAmBA;;;;;;;;;;;;;;;;;;iBAAgB,MAAA"}
@@ -6,17 +6,20 @@
6
6
  * @param options - Optional configuration
7
7
  * @param options.base - Base pixel value to calculate rem units from. Defaults to 16
8
8
  * @param options.precision - Number of decimal places in the output. Defaults to 4
9
- * @returns The converted value as a string with 'rem' units
9
+ * @returns The converted value, or null/undefined if input is null/undefined
10
10
  *
11
11
  * @example
12
12
  * ```ts
13
- * px2rem(16) // '1.0000'
14
- * px2rem('32px') // '2.0000'
15
- * px2rem(20, { base: 20 }) // '1.0000'
16
- * px2rem(13, { precision: 2 }) // '0.81'
13
+ * px2rem(16) // 1
14
+ * px2rem('32px') // 2
15
+ * px2rem(20, { base: 20 }) // 1
16
+ * px2rem(13, { precision: 2 }) // 0.81
17
+ * px2rem(null) // null
18
+ * px2rem(undefined) // undefined
17
19
  * ```
18
20
  */
19
21
  function px2rem(px, options) {
22
+ if (px === null || px === void 0) return px;
20
23
  const { base = 16, precision = 4 } = options ?? {};
21
24
  if (typeof px === "string") {
22
25
  px = px.replace(/px$/, "");
@@ -1 +1 @@
1
- {"version":3,"file":"px-2-rem.mjs","names":[],"sources":["../../src/units/px-2-rem.ts"],"sourcesContent":["/**\n * Converts pixel values to rem units.\n *\n * @param px - The pixel value to convert. Can be a number or string (e.g. '16px' or '16')\n * @param options - Optional configuration\n * @param options.base - Base pixel value to calculate rem units from. Defaults to 16\n * @param options.precision - Number of decimal places in the output. Defaults to 4\n * @returns The converted value as a string with 'rem' units\n *\n * @example\n * ```ts\n * px2rem(16) // '1.0000'\n * px2rem('32px') // '2.0000'\n * px2rem(20, { base: 20 }) // '1.0000'\n * px2rem(13, { precision: 2 }) // '0.81'\n * ```\n */\nexport function px2rem(\n\tpx: number | string,\n\toptions?: { base?: number | undefined; precision?: number | undefined }\n): number {\n\tconst { base = 16, precision = 4 } = options ?? {}\n\n\tif (typeof px === 'string') {\n\t\tpx = px.replace(/px$/, '')\n\t\tpx = Number.parseFloat(px)\n\t}\n\n\treturn Number((px / base).toFixed(precision))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,SAAgB,OACf,IACA,SACS;CACT,MAAM,EAAE,OAAO,IAAI,YAAY,MAAM,WAAW,EAAE;AAElD,KAAI,OAAO,OAAO,UAAU;AAC3B,OAAK,GAAG,QAAQ,OAAO,GAAG;AAC1B,OAAK,OAAO,WAAW,GAAG;;AAG3B,QAAO,QAAQ,KAAK,MAAM,QAAQ,UAAU,CAAC"}
1
+ {"version":3,"file":"px-2-rem.mjs","names":[],"sources":["../../src/units/px-2-rem.ts"],"sourcesContent":["/**\n * Converts pixel values to rem units.\n *\n * @param px - The pixel value to convert. Can be a number or string (e.g. '16px' or '16')\n * @param options - Optional configuration\n * @param options.base - Base pixel value to calculate rem units from. Defaults to 16\n * @param options.precision - Number of decimal places in the output. Defaults to 4\n * @returns The converted value, or null/undefined if input is null/undefined\n *\n * @example\n * ```ts\n * px2rem(16) // 1\n * px2rem('32px') // 2\n * px2rem(20, { base: 20 }) // 1\n * px2rem(13, { precision: 2 }) // 0.81\n * px2rem(null) // null\n * px2rem(undefined) // undefined\n * ```\n */\nexport function px2rem(\n\tpx: number | string | null | undefined,\n\toptions?: { base?: number | undefined; precision?: number | undefined } | undefined\n): number | null | undefined {\n\tif (px === null || px === undefined) return px\n\n\tconst { base = 16, precision = 4 } = options ?? {}\n\n\tif (typeof px === 'string') {\n\t\tpx = px.replace(/px$/, '')\n\t\tpx = Number.parseFloat(px)\n\t}\n\n\treturn Number((px / base).toFixed(precision))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,OACf,IACA,SAC4B;AAC5B,KAAI,OAAO,QAAQ,OAAO,OAAW,QAAO;CAE5C,MAAM,EAAE,OAAO,IAAI,YAAY,MAAM,WAAW,EAAE;AAElD,KAAI,OAAO,OAAO,UAAU;AAC3B,OAAK,GAAG,QAAQ,OAAO,GAAG;AAC1B,OAAK,OAAO,WAAW,GAAG;;AAG3B,QAAO,QAAQ,KAAK,MAAM,QAAQ,UAAU,CAAC"}
@@ -7,17 +7,20 @@
7
7
  * @param options - Optional configuration
8
8
  * @param options.base - Base pixel value to calculate pixels from. Defaults to 16
9
9
  * @param options.precision - Number of decimal places in the output. Defaults to 4
10
- * @returns The converted value as a string with 'px' units
10
+ * @returns The converted value, or null/undefined if input is null/undefined
11
11
  *
12
12
  * @example
13
13
  * ```ts
14
- * rem2px(1) // '16.0000'
15
- * rem2px('2rem') // '32.0000'
16
- * rem2px(1, { base: 20 }) // '20.0000'
17
- * rem2px(0.8125, { precision: 2 }) // '13.00'
14
+ * rem2px(1) // 16
15
+ * rem2px('2rem') // 32
16
+ * rem2px(1, { base: 20 }) // 20
17
+ * rem2px(0.8125, { precision: 2 }) // 13
18
+ * rem2px(null) // null
19
+ * rem2px(undefined) // undefined
18
20
  * ```
19
21
  */
20
22
  function rem2px(rem, options) {
23
+ if (rem === null || rem === void 0) return rem;
21
24
  const { base = 16, precision = 4 } = options ?? {};
22
25
  if (typeof rem === "string") {
23
26
  rem = rem.replace(/rem$/, "");
@@ -1 +1 @@
1
- {"version":3,"file":"rem-2-px.cjs","names":[],"sources":["../../src/units/rem-2-px.ts"],"sourcesContent":["/**\n * Converts rem values to pixel units.\n *\n * @param rem - The rem value to convert. Can be a number or string (e.g. '1rem' or '1')\n * @param options - Optional configuration\n * @param options.base - Base pixel value to calculate pixels from. Defaults to 16\n * @param options.precision - Number of decimal places in the output. Defaults to 4\n * @returns The converted value as a string with 'px' units\n *\n * @example\n * ```ts\n * rem2px(1) // '16.0000'\n * rem2px('2rem') // '32.0000'\n * rem2px(1, { base: 20 }) // '20.0000'\n * rem2px(0.8125, { precision: 2 }) // '13.00'\n * ```\n */\nexport function rem2px(\n\trem: number | string,\n\toptions?: { base?: number | undefined; precision?: number | undefined }\n): number {\n\tconst { base = 16, precision = 4 } = options ?? {}\n\n\tif (typeof rem === 'string') {\n\t\trem = rem.replace(/rem$/, '')\n\t\trem = Number.parseFloat(rem)\n\t}\n\n\treturn Number((rem * base).toFixed(precision))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiBA,SAAgB,OACf,KACA,SACS;CACT,MAAM,EAAE,OAAO,IAAI,YAAY,MAAM,WAAW,EAAE;AAElD,KAAI,OAAO,QAAQ,UAAU;AAC5B,QAAM,IAAI,QAAQ,QAAQ,GAAG;AAC7B,QAAM,OAAO,WAAW,IAAI;;AAG7B,QAAO,QAAQ,MAAM,MAAM,QAAQ,UAAU,CAAC"}
1
+ {"version":3,"file":"rem-2-px.cjs","names":[],"sources":["../../src/units/rem-2-px.ts"],"sourcesContent":["/**\n * Converts rem values to pixel units.\n *\n * @param rem - The rem value to convert. Can be a number or string (e.g. '1rem' or '1')\n * @param options - Optional configuration\n * @param options.base - Base pixel value to calculate pixels from. Defaults to 16\n * @param options.precision - Number of decimal places in the output. Defaults to 4\n * @returns The converted value, or null/undefined if input is null/undefined\n *\n * @example\n * ```ts\n * rem2px(1) // 16\n * rem2px('2rem') // 32\n * rem2px(1, { base: 20 }) // 20\n * rem2px(0.8125, { precision: 2 }) // 13\n * rem2px(null) // null\n * rem2px(undefined) // undefined\n * ```\n */\nexport function rem2px(\n\trem: number | string | null | undefined,\n\toptions?: { base?: number | undefined; precision?: number | undefined }\n): number | null | undefined {\n\tif (rem === null || rem === undefined) return rem\n\n\tconst { base = 16, precision = 4 } = options ?? {}\n\tif (typeof rem === 'string') {\n\t\trem = rem.replace(/rem$/, '')\n\t\trem = Number.parseFloat(rem)\n\t}\n\treturn Number((rem * base).toFixed(precision))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,OACf,KACA,SAC4B;AAC5B,KAAI,QAAQ,QAAQ,QAAQ,OAAW,QAAO;CAE9C,MAAM,EAAE,OAAO,IAAI,YAAY,MAAM,WAAW,EAAE;AAClD,KAAI,OAAO,QAAQ,UAAU;AAC5B,QAAM,IAAI,QAAQ,QAAQ,GAAG;AAC7B,QAAM,OAAO,WAAW,IAAI;;AAE7B,QAAO,QAAQ,MAAM,MAAM,QAAQ,UAAU,CAAC"}
@@ -6,20 +6,22 @@
6
6
  * @param options - Optional configuration
7
7
  * @param options.base - Base pixel value to calculate pixels from. Defaults to 16
8
8
  * @param options.precision - Number of decimal places in the output. Defaults to 4
9
- * @returns The converted value as a string with 'px' units
9
+ * @returns The converted value, or null/undefined if input is null/undefined
10
10
  *
11
11
  * @example
12
12
  * ```ts
13
- * rem2px(1) // '16.0000'
14
- * rem2px('2rem') // '32.0000'
15
- * rem2px(1, { base: 20 }) // '20.0000'
16
- * rem2px(0.8125, { precision: 2 }) // '13.00'
13
+ * rem2px(1) // 16
14
+ * rem2px('2rem') // 32
15
+ * rem2px(1, { base: 20 }) // 20
16
+ * rem2px(0.8125, { precision: 2 }) // 13
17
+ * rem2px(null) // null
18
+ * rem2px(undefined) // undefined
17
19
  * ```
18
20
  */
19
- declare function rem2px(rem: number | string, options?: {
21
+ declare function rem2px(rem: number | string | null | undefined, options?: {
20
22
  base?: number | undefined;
21
23
  precision?: number | undefined;
22
- }): number;
24
+ }): number | null | undefined;
23
25
  //#endregion
24
26
  export { rem2px };
25
27
  //# sourceMappingURL=rem-2-px.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rem-2-px.d.cts","names":[],"sources":["../../src/units/rem-2-px.ts"],"sourcesContent":[],"mappings":";;AAiBA;;;;;;;;;;;;;;;;iBAAgB,MAAA"}
1
+ {"version":3,"file":"rem-2-px.d.cts","names":[],"sources":["../../src/units/rem-2-px.ts"],"sourcesContent":[],"mappings":";;AAmBA;;;;;;;;;;;;;;;;;;iBAAgB,MAAA"}
@@ -6,20 +6,22 @@
6
6
  * @param options - Optional configuration
7
7
  * @param options.base - Base pixel value to calculate pixels from. Defaults to 16
8
8
  * @param options.precision - Number of decimal places in the output. Defaults to 4
9
- * @returns The converted value as a string with 'px' units
9
+ * @returns The converted value, or null/undefined if input is null/undefined
10
10
  *
11
11
  * @example
12
12
  * ```ts
13
- * rem2px(1) // '16.0000'
14
- * rem2px('2rem') // '32.0000'
15
- * rem2px(1, { base: 20 }) // '20.0000'
16
- * rem2px(0.8125, { precision: 2 }) // '13.00'
13
+ * rem2px(1) // 16
14
+ * rem2px('2rem') // 32
15
+ * rem2px(1, { base: 20 }) // 20
16
+ * rem2px(0.8125, { precision: 2 }) // 13
17
+ * rem2px(null) // null
18
+ * rem2px(undefined) // undefined
17
19
  * ```
18
20
  */
19
- declare function rem2px(rem: number | string, options?: {
21
+ declare function rem2px(rem: number | string | null | undefined, options?: {
20
22
  base?: number | undefined;
21
23
  precision?: number | undefined;
22
- }): number;
24
+ }): number | null | undefined;
23
25
  //#endregion
24
26
  export { rem2px };
25
27
  //# sourceMappingURL=rem-2-px.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rem-2-px.d.mts","names":[],"sources":["../../src/units/rem-2-px.ts"],"sourcesContent":[],"mappings":";;AAiBA;;;;;;;;;;;;;;;;iBAAgB,MAAA"}
1
+ {"version":3,"file":"rem-2-px.d.mts","names":[],"sources":["../../src/units/rem-2-px.ts"],"sourcesContent":[],"mappings":";;AAmBA;;;;;;;;;;;;;;;;;;iBAAgB,MAAA"}
@@ -6,17 +6,20 @@
6
6
  * @param options - Optional configuration
7
7
  * @param options.base - Base pixel value to calculate pixels from. Defaults to 16
8
8
  * @param options.precision - Number of decimal places in the output. Defaults to 4
9
- * @returns The converted value as a string with 'px' units
9
+ * @returns The converted value, or null/undefined if input is null/undefined
10
10
  *
11
11
  * @example
12
12
  * ```ts
13
- * rem2px(1) // '16.0000'
14
- * rem2px('2rem') // '32.0000'
15
- * rem2px(1, { base: 20 }) // '20.0000'
16
- * rem2px(0.8125, { precision: 2 }) // '13.00'
13
+ * rem2px(1) // 16
14
+ * rem2px('2rem') // 32
15
+ * rem2px(1, { base: 20 }) // 20
16
+ * rem2px(0.8125, { precision: 2 }) // 13
17
+ * rem2px(null) // null
18
+ * rem2px(undefined) // undefined
17
19
  * ```
18
20
  */
19
21
  function rem2px(rem, options) {
22
+ if (rem === null || rem === void 0) return rem;
20
23
  const { base = 16, precision = 4 } = options ?? {};
21
24
  if (typeof rem === "string") {
22
25
  rem = rem.replace(/rem$/, "");
@@ -1 +1 @@
1
- {"version":3,"file":"rem-2-px.mjs","names":[],"sources":["../../src/units/rem-2-px.ts"],"sourcesContent":["/**\n * Converts rem values to pixel units.\n *\n * @param rem - The rem value to convert. Can be a number or string (e.g. '1rem' or '1')\n * @param options - Optional configuration\n * @param options.base - Base pixel value to calculate pixels from. Defaults to 16\n * @param options.precision - Number of decimal places in the output. Defaults to 4\n * @returns The converted value as a string with 'px' units\n *\n * @example\n * ```ts\n * rem2px(1) // '16.0000'\n * rem2px('2rem') // '32.0000'\n * rem2px(1, { base: 20 }) // '20.0000'\n * rem2px(0.8125, { precision: 2 }) // '13.00'\n * ```\n */\nexport function rem2px(\n\trem: number | string,\n\toptions?: { base?: number | undefined; precision?: number | undefined }\n): number {\n\tconst { base = 16, precision = 4 } = options ?? {}\n\n\tif (typeof rem === 'string') {\n\t\trem = rem.replace(/rem$/, '')\n\t\trem = Number.parseFloat(rem)\n\t}\n\n\treturn Number((rem * base).toFixed(precision))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,SAAgB,OACf,KACA,SACS;CACT,MAAM,EAAE,OAAO,IAAI,YAAY,MAAM,WAAW,EAAE;AAElD,KAAI,OAAO,QAAQ,UAAU;AAC5B,QAAM,IAAI,QAAQ,QAAQ,GAAG;AAC7B,QAAM,OAAO,WAAW,IAAI;;AAG7B,QAAO,QAAQ,MAAM,MAAM,QAAQ,UAAU,CAAC"}
1
+ {"version":3,"file":"rem-2-px.mjs","names":[],"sources":["../../src/units/rem-2-px.ts"],"sourcesContent":["/**\n * Converts rem values to pixel units.\n *\n * @param rem - The rem value to convert. Can be a number or string (e.g. '1rem' or '1')\n * @param options - Optional configuration\n * @param options.base - Base pixel value to calculate pixels from. Defaults to 16\n * @param options.precision - Number of decimal places in the output. Defaults to 4\n * @returns The converted value, or null/undefined if input is null/undefined\n *\n * @example\n * ```ts\n * rem2px(1) // 16\n * rem2px('2rem') // 32\n * rem2px(1, { base: 20 }) // 20\n * rem2px(0.8125, { precision: 2 }) // 13\n * rem2px(null) // null\n * rem2px(undefined) // undefined\n * ```\n */\nexport function rem2px(\n\trem: number | string | null | undefined,\n\toptions?: { base?: number | undefined; precision?: number | undefined }\n): number | null | undefined {\n\tif (rem === null || rem === undefined) return rem\n\n\tconst { base = 16, precision = 4 } = options ?? {}\n\tif (typeof rem === 'string') {\n\t\trem = rem.replace(/rem$/, '')\n\t\trem = Number.parseFloat(rem)\n\t}\n\treturn Number((rem * base).toFixed(precision))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,OACf,KACA,SAC4B;AAC5B,KAAI,QAAQ,QAAQ,QAAQ,OAAW,QAAO;CAE9C,MAAM,EAAE,OAAO,IAAI,YAAY,MAAM,WAAW,EAAE;AAClD,KAAI,OAAO,QAAQ,UAAU;AAC5B,QAAM,IAAI,QAAQ,QAAQ,GAAG;AAC7B,QAAM,OAAO,WAAW,IAAI;;AAE7B,QAAO,QAAQ,MAAM,MAAM,QAAQ,UAAU,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@just-web/toolkits",
3
- "version": "2.1.0",
3
+ "version": "3.1.0",
4
4
  "description": "Toolkits for web applications",
5
5
  "homepage": "https://github.com/justland/just-web-foundation/tree/main/libs/toolkits",
6
6
  "repository": {
@@ -3,24 +3,29 @@
3
3
  *
4
4
  * @param handlers - An object mapping attribute names to handler functions.
5
5
  * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.
6
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.
6
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
7
7
  *
8
8
  * @example
9
9
  * ```ts
10
- * const observer = observeAttributes({
11
- * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),
12
- * 'class': (attr, value) => console.log(`class changed to: ${value}`)
10
+ * const unsubscribe = observeAttributes({
11
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
12
+ * 'class': (value) => console.log(`class changed to: ${value}`)
13
13
  * });
14
14
  *
15
15
  * // Later, to stop observing:
16
- * observer.disconnect();
16
+ * unsubscribe();
17
17
  * ```
18
18
  */
19
19
  export function observeAttributes<T extends string>(
20
20
  handlers: Record<string, (value: T | null) => void>,
21
21
  element?: Element | null | undefined
22
- ) {
23
- element = element ?? globalThis.document.documentElement
22
+ ): () => void {
23
+ /* c8 ignore start */
24
+ if (typeof document === 'undefined') {
25
+ return () => {}
26
+ }
27
+ /* c8 ignore end */
28
+ element = element ?? document.documentElement
24
29
  const observer = new MutationObserver((mutations) => {
25
30
  for (const mutation of mutations) {
26
31
  const attribute = mutation.attributeName
@@ -33,5 +38,5 @@ export function observeAttributes<T extends string>(
33
38
  attributes: true,
34
39
  attributeFilter: Object.keys(handlers)
35
40
  })
36
- return observer
41
+ return () => observer.disconnect()
37
42
  }
@@ -3,22 +3,19 @@ import { observeAttributes } from './observe-attribute.ts'
3
3
  /**
4
4
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
5
5
  *
6
- * @param options - Configuration options
7
- * @param options.handlers - An object mapping `data-*` attribute names to handler functions.
8
- * @param options.element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
9
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer
6
+ * @param handlers - An object mapping `data-*` attribute names to handler functions.
7
+ * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
8
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
10
9
  *
11
10
  * @example
12
11
  * ```ts
13
- * const observer = observeDataAttributes({
14
- * handlers: {
15
- * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
16
- * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
17
- * }
12
+ * const unsubscribe = observeDataAttributes({
13
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
14
+ * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
18
15
  * });
19
16
  *
20
17
  * // Later, to stop observing:
21
- * observer.disconnect();
18
+ * unsubscribe();
22
19
  * ```
23
20
  */
24
21
  export function observeDataAttributes<T extends string, K extends `data-${string}`>(
package/src/index.ts CHANGED
@@ -19,7 +19,14 @@ export * from './style/just-style.ts'
19
19
  export * from './style/resolve-style.ts'
20
20
  export * from './style/style-props.ts'
21
21
  export * from './style/to-dom-style.ts'
22
+ export * from './units/convert-css-unit.ts'
23
+ export * from './units/create-css-unit-converter.ts'
24
+ export * from './units/css-unit-converter.types.ts'
25
+ export * from './units/get-css-unit.ts'
22
26
  export * from './units/get-rem-to-px-scale.ts'
27
+ export * from './units/is-effectively-zero.ts'
28
+ export * from './units/parse-css-number.ts'
29
+ export * from './units/parse-css-value.ts'
23
30
  export * from './units/px-2-num.ts'
24
31
  export * from './units/px-2-rem.ts'
25
32
  export * from './units/rem-2-px.ts'
@@ -32,7 +32,7 @@ export function useAttribute(
32
32
 
33
33
  setValueState(element.getAttribute(attributeName) ?? undefined)
34
34
 
35
- const observer = observeAttributes(
35
+ return observeAttributes(
36
36
  {
37
37
  [attributeName]: (next) => {
38
38
  setValueState(next ?? undefined)
@@ -40,7 +40,6 @@ export function useAttribute(
40
40
  },
41
41
  element
42
42
  )
43
- return () => observer.disconnect()
44
43
  }, [element, attributeName])
45
44
 
46
45
  const setValue = useCallback(
@@ -1,6 +1,7 @@
1
1
  import type { Properties } from 'csstype'
2
2
 
3
3
  declare module 'csstype' {
4
+ // biome-ignore lint/correctness/noUnusedVariables: TLength and TTime are used in the extended Properties type
4
5
  interface Properties<TLength = (string & {}) | 0, TTime = string & {}> extends CustomProperties {}
5
6
  }
6
7
 
@@ -13,7 +14,8 @@ interface CustomProperties {
13
14
  * Widens CSS properties to support custom properties.
14
15
  * Allows for string or number values for standard properties,
15
16
  * and string values for custom properties with '--' prefix.
16
- * Defined as a union so plain Properties (e.g. from React) are assignable.
17
+ *
18
+ * Note that `React.CSSProperties` (using `csstype`) is augmented so you can use it directly without this type.
17
19
  */
18
20
  export interface CSSProperties<TLength = string | number, TTime = string & {}>
19
21
  extends Properties<TLength, TTime>,
@@ -23,7 +23,7 @@ export function subscribeClassName<Themes extends ThemeMap>(
23
23
  if (!element) return () => {}
24
24
  const parse = options?.parse ?? parseClassName
25
25
  let lastEmitted: keyof Themes | undefined | null = null
26
- const observer = observeAttributes(
26
+ return observeAttributes(
27
27
  {
28
28
  class: (value) => {
29
29
  const entry = parse(themes, value ?? undefined)
@@ -35,5 +35,4 @@ export function subscribeClassName<Themes extends ThemeMap>(
35
35
  },
36
36
  element
37
37
  )
38
- return () => observer.disconnect()
39
38
  }
@@ -26,7 +26,7 @@ export function subscribeDataAttribute<Themes extends ThemeMap>(
26
26
  if (!element) return () => {}
27
27
  const parse =
28
28
  options?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }))
29
- const observer = observeDataAttributes<string, `data-${string}`>(
29
+ return observeDataAttributes<string, `data-${string}`>(
30
30
  {
31
31
  [attributeName]: (value) => {
32
32
  const entry = parse(themes, value ?? undefined)
@@ -35,5 +35,4 @@ export function subscribeDataAttribute<Themes extends ThemeMap>(
35
35
  },
36
36
  element
37
37
  )
38
- return () => observer.disconnect()
39
38
  }