@just-web/css 0.4.0 → 0.6.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 (43) hide show
  1. package/cjs/convertors/px_2_rem.d.ts +21 -0
  2. package/cjs/convertors/px_2_rem.js +17 -0
  3. package/cjs/convertors/rem_2_px.d.ts +21 -0
  4. package/cjs/convertors/rem_2_px.js +17 -0
  5. package/cjs/index.d.ts +2 -0
  6. package/cjs/index.js +22 -0
  7. package/cjs/tailwind.css +1 -1
  8. package/cjs/testing/log-panel.js +1 -1
  9. package/cjs/theme/data-attribute.d.ts +18 -2
  10. package/cjs/theme/data-attribute.js +6 -3
  11. package/cjs/utils/attribute.d.ts +1 -1
  12. package/cjs/utils/data-attribute.d.ts +1 -1
  13. package/esm/convertors/px_2_rem.d.ts +22 -0
  14. package/esm/convertors/px_2_rem.d.ts.map +1 -0
  15. package/esm/convertors/px_2_rem.js +26 -0
  16. package/esm/convertors/px_2_rem.js.map +1 -0
  17. package/esm/convertors/rem_2_px.d.ts +22 -0
  18. package/esm/convertors/rem_2_px.d.ts.map +1 -0
  19. package/esm/convertors/rem_2_px.js +26 -0
  20. package/esm/convertors/rem_2_px.js.map +1 -0
  21. package/esm/index.d.ts +2 -0
  22. package/esm/index.d.ts.map +1 -1
  23. package/esm/index.js +2 -0
  24. package/esm/index.js.map +1 -1
  25. package/esm/testing/log-panel.js +1 -1
  26. package/esm/testing/log-panel.js.map +1 -1
  27. package/esm/theme/data-attribute.d.ts +18 -2
  28. package/esm/theme/data-attribute.d.ts.map +1 -1
  29. package/esm/theme/data-attribute.js +6 -57
  30. package/esm/theme/data-attribute.js.map +1 -1
  31. package/esm/utils/attribute.d.ts +1 -1
  32. package/esm/utils/attribute.d.ts.map +1 -1
  33. package/esm/utils/attribute.js.map +1 -1
  34. package/esm/utils/data-attribute.d.ts +1 -1
  35. package/esm/utils/data-attribute.d.ts.map +1 -1
  36. package/package.json +2 -2
  37. package/src/convertors/px_2_rem.ts +27 -0
  38. package/src/convertors/rem_2_px.ts +27 -0
  39. package/src/index.ts +2 -0
  40. package/src/tailwind.css +3 -1
  41. package/src/testing/log-panel.tsx +1 -1
  42. package/src/theme/data-attribute.ts +39 -5
  43. package/src/utils/attribute.ts +1 -1
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Converts pixel values to rem units.
3
+ *
4
+ * @param px - The pixel value to convert. Can be a number or string (e.g. '16px' or '16')
5
+ * @param options - Optional configuration
6
+ * @param options.base - Base pixel value to calculate rem units from. Defaults to 16
7
+ * @param options.precision - Number of decimal places in the output. Defaults to 4
8
+ * @returns The converted value as a string with 'rem' units
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * px2rem(16) // '1.0000'
13
+ * px2rem('32px') // '2.0000'
14
+ * px2rem(20, { base: 20 }) // '1.0000'
15
+ * px2rem(13, { precision: 2 }) // '0.81'
16
+ * ```
17
+ */
18
+ export declare function px2rem(px: number | string, options?: {
19
+ base?: number | undefined;
20
+ precision?: number | undefined;
21
+ }): string;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.px2rem = px2rem;
7
+ function px2rem(px, options) {
8
+ const {
9
+ base = 16,
10
+ precision = 4
11
+ } = options ?? {};
12
+ if (typeof px === "string") {
13
+ px = px.replace(/px$/, "");
14
+ px = Number.parseFloat(px);
15
+ }
16
+ return (px / base).toFixed(precision);
17
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Converts rem values to pixel units.
3
+ *
4
+ * @param rem - The rem value to convert. Can be a number or string (e.g. '1rem' or '1')
5
+ * @param options - Optional configuration
6
+ * @param options.base - Base pixel value to calculate pixels from. Defaults to 16
7
+ * @param options.precision - Number of decimal places in the output. Defaults to 4
8
+ * @returns The converted value as a string with 'px' units
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * rem2px(1) // '16.0000'
13
+ * rem2px('2rem') // '32.0000'
14
+ * rem2px(1, { base: 20 }) // '20.0000'
15
+ * rem2px(0.8125, { precision: 2 }) // '13.00'
16
+ * ```
17
+ */
18
+ export declare function rem2px(rem: number | string, options?: {
19
+ base?: number | undefined;
20
+ precision?: number | undefined;
21
+ }): string;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.rem2px = rem2px;
7
+ function rem2px(rem, options) {
8
+ const {
9
+ base = 16,
10
+ precision = 4
11
+ } = options ?? {};
12
+ if (typeof rem === "string") {
13
+ rem = rem.replace(/rem$/, "");
14
+ rem = Number.parseFloat(rem);
15
+ }
16
+ return (rem * base).toFixed(precision);
17
+ }
package/cjs/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from './convertors/px_2_rem.ts';
2
+ export * from './convertors/rem_2_px.ts';
1
3
  export * from './css-properties/css-properties.ts';
2
4
  export * from './css-properties/to_dom_style.ts';
3
5
  export * from './props/class-name.ts';
package/cjs/index.js CHANGED
@@ -3,6 +3,28 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ var _px_2_rem = require("./convertors/px_2_rem.ts");
7
+ Object.keys(_px_2_rem).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _px_2_rem[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _px_2_rem[key];
14
+ }
15
+ });
16
+ });
17
+ var _rem_2_px = require("./convertors/rem_2_px.ts");
18
+ Object.keys(_rem_2_px).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _rem_2_px[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _rem_2_px[key];
25
+ }
26
+ });
27
+ });
6
28
  var _cssProperties = require("./css-properties/css-properties.ts");
7
29
  Object.keys(_cssProperties).forEach(function (key) {
8
30
  if (key === "default" || key === "__esModule") return;
package/cjs/tailwind.css CHANGED
@@ -1 +1 @@
1
- @import "tailwindcss";
1
+ @import "tailwindcss";@custom-variant dark (&:where(.dark, .dark *));
@@ -9,7 +9,7 @@ function LogPanel({
9
9
  log
10
10
  }) {
11
11
  return /* @__PURE__ */React.createElement("div", {
12
- className: "bg-neutral-100 p-4 rounded overflow-y-auto"
12
+ className: "bg-neutral-100 dark:bg-neutral-900 p-4 rounded overflow-y-auto"
13
13
  }, /* @__PURE__ */React.createElement("h4", {
14
14
  className: "mb-2"
15
15
  }, title), log.map((entry, i) => /* @__PURE__ */React.createElement("pre", {
@@ -5,6 +5,7 @@
5
5
  * @param options.themes - Record mapping theme keys to their data attribute values
6
6
  * @param options.defaultTheme - Fallback theme key if attribute value doesn't match any theme
7
7
  * @param options.attributeName - Name of the data attribute to check (must start with 'data-')
8
+ * @param options.allowCustom - Whether to allow custom themes value
8
9
  * @returns The matching theme key, or defaultTheme if no match found
9
10
  *
10
11
  * @example
@@ -24,11 +25,18 @@
24
25
  * ```
25
26
  */
26
27
  export declare function getThemeByDataAttribute<Themes extends Record<string, string>>(options: {
27
- themes: Themes;
28
- defaultTheme?: keyof Themes | undefined;
29
28
  attributeName: `data-${string}`;
29
+ defaultTheme?: keyof Themes | undefined;
30
+ themes: Themes;
30
31
  element?: Element | undefined;
31
32
  }): keyof Themes | undefined;
33
+ export declare function getThemeByDataAttribute<Themes extends Record<string, string>>(options: {
34
+ attributeName: `data-${string}`;
35
+ allowCustom: true | undefined;
36
+ defaultTheme?: keyof Themes | undefined;
37
+ themes: Themes;
38
+ element?: Element | undefined;
39
+ }): string | undefined;
32
40
  /**
33
41
  * Observes changes to a theme data attribute and calls a handler when it changes.
34
42
  *
@@ -65,3 +73,11 @@ export declare function observeThemeByDataAttributes<Themes extends Record<strin
65
73
  defaultTheme?: keyof Themes | undefined;
66
74
  element?: Element | undefined;
67
75
  }): MutationObserver;
76
+ export declare function observeThemeByDataAttributes<Themes extends Record<string, string>>(options: {
77
+ attributeName: `data-${string}`;
78
+ themes: Themes;
79
+ handler: (value: string | null) => void;
80
+ allowCustom: true | undefined;
81
+ defaultTheme?: keyof Themes | undefined;
82
+ element?: Element | undefined;
83
+ }): MutationObserver;
@@ -8,9 +8,9 @@ exports.observeThemeByDataAttributes = observeThemeByDataAttributes;
8
8
  var _typePlus = require("type-plus");
9
9
  var _dataAttribute = require("../utils/data-attribute.ts");
10
10
  function getThemeByDataAttribute(options) {
11
- const value = (0, _dataAttribute.getDataAttribute)(options.attributeName, options.element);
11
+ const value = (0, _dataAttribute.getDataAttribute)(options.attributeName, options.element) ?? void 0;
12
12
  const theme = (0, _typePlus.findKey)(options.themes, theme2 => options.themes[theme2] === value);
13
- return theme ?? options.defaultTheme;
13
+ return theme ?? options.defaultTheme ?? (options.allowCustom ? value : void 0);
14
14
  }
15
15
  function observeThemeByDataAttributes(options) {
16
16
  return (0, _dataAttribute.observeDataAttributes)({
@@ -22,9 +22,12 @@ function observeThemeByDataAttributes(options) {
22
22
  for (const name in options.themes) {
23
23
  if (options.themes[name] === value) {
24
24
  options.handler(name);
25
- break;
25
+ return;
26
26
  }
27
27
  }
28
+ if (options.allowCustom) {
29
+ options.handler(value);
30
+ }
28
31
  }
29
32
  }, options.element);
30
33
  }
@@ -14,7 +14,7 @@
14
14
  * const testId = getAttribute('data-testid', element)
15
15
  * ```
16
16
  */
17
- export declare function getAttribute<T extends string>(qualifiedName: T, element?: Element | undefined): T | null;
17
+ export declare function getAttribute<T extends string>(qualifiedName: T, element?: Element | undefined): string | null;
18
18
  /**
19
19
  * Observes attributes changes on an element and calls corresponding handlers.
20
20
  *
@@ -1,4 +1,4 @@
1
- export declare function getDataAttribute<T extends `data-${string}`>(qualifiedName: T, element?: Element | undefined): T | null;
1
+ export declare function getDataAttribute<T extends `data-${string}`>(qualifiedName: T, element?: Element | undefined): string | null;
2
2
  /**
3
3
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
4
4
  *
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Converts pixel values to rem units.
3
+ *
4
+ * @param px - The pixel value to convert. Can be a number or string (e.g. '16px' or '16')
5
+ * @param options - Optional configuration
6
+ * @param options.base - Base pixel value to calculate rem units from. Defaults to 16
7
+ * @param options.precision - Number of decimal places in the output. Defaults to 4
8
+ * @returns The converted value as a string with 'rem' units
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * px2rem(16) // '1.0000'
13
+ * px2rem('32px') // '2.0000'
14
+ * px2rem(20, { base: 20 }) // '1.0000'
15
+ * px2rem(13, { precision: 2 }) // '0.81'
16
+ * ```
17
+ */
18
+ export declare function px2rem(px: number | string, options?: {
19
+ base?: number | undefined;
20
+ precision?: number | undefined;
21
+ }): string;
22
+ //# sourceMappingURL=px_2_rem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"px_2_rem.d.ts","sourceRoot":"","sources":["../../src/convertors/px_2_rem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,UASlH"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Converts pixel values to rem units.
3
+ *
4
+ * @param px - The pixel value to convert. Can be a number or string (e.g. '16px' or '16')
5
+ * @param options - Optional configuration
6
+ * @param options.base - Base pixel value to calculate rem units from. Defaults to 16
7
+ * @param options.precision - Number of decimal places in the output. Defaults to 4
8
+ * @returns The converted value as a string with 'rem' units
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * px2rem(16) // '1.0000'
13
+ * px2rem('32px') // '2.0000'
14
+ * px2rem(20, { base: 20 }) // '1.0000'
15
+ * px2rem(13, { precision: 2 }) // '0.81'
16
+ * ```
17
+ */
18
+ export function px2rem(px, options) {
19
+ const { base = 16, precision = 4 } = options ?? {};
20
+ if (typeof px === 'string') {
21
+ px = px.replace(/px$/, '');
22
+ px = Number.parseFloat(px);
23
+ }
24
+ return (px / base).toFixed(precision);
25
+ }
26
+ //# sourceMappingURL=px_2_rem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"px_2_rem.js","sourceRoot":"","sources":["../../src/convertors/px_2_rem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,MAAM,CAAC,EAAmB,EAAE,OAAuE;IAClH,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,GAAG,CAAC,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAElD,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;QAC5B,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QAC1B,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAC3B,CAAC;IAED,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;AACtC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Converts rem values to pixel units.
3
+ *
4
+ * @param rem - The rem value to convert. Can be a number or string (e.g. '1rem' or '1')
5
+ * @param options - Optional configuration
6
+ * @param options.base - Base pixel value to calculate pixels from. Defaults to 16
7
+ * @param options.precision - Number of decimal places in the output. Defaults to 4
8
+ * @returns The converted value as a string with 'px' units
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * rem2px(1) // '16.0000'
13
+ * rem2px('2rem') // '32.0000'
14
+ * rem2px(1, { base: 20 }) // '20.0000'
15
+ * rem2px(0.8125, { precision: 2 }) // '13.00'
16
+ * ```
17
+ */
18
+ export declare function rem2px(rem: number | string, options?: {
19
+ base?: number | undefined;
20
+ precision?: number | undefined;
21
+ }): string;
22
+ //# sourceMappingURL=rem_2_px.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rem_2_px.d.ts","sourceRoot":"","sources":["../../src/convertors/rem_2_px.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,UASnH"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Converts rem values to pixel units.
3
+ *
4
+ * @param rem - The rem value to convert. Can be a number or string (e.g. '1rem' or '1')
5
+ * @param options - Optional configuration
6
+ * @param options.base - Base pixel value to calculate pixels from. Defaults to 16
7
+ * @param options.precision - Number of decimal places in the output. Defaults to 4
8
+ * @returns The converted value as a string with 'px' units
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * rem2px(1) // '16.0000'
13
+ * rem2px('2rem') // '32.0000'
14
+ * rem2px(1, { base: 20 }) // '20.0000'
15
+ * rem2px(0.8125, { precision: 2 }) // '13.00'
16
+ * ```
17
+ */
18
+ export function rem2px(rem, options) {
19
+ const { base = 16, precision = 4 } = options ?? {};
20
+ if (typeof rem === 'string') {
21
+ rem = rem.replace(/rem$/, '');
22
+ rem = Number.parseFloat(rem);
23
+ }
24
+ return (rem * base).toFixed(precision);
25
+ }
26
+ //# sourceMappingURL=rem_2_px.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rem_2_px.js","sourceRoot":"","sources":["../../src/convertors/rem_2_px.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,MAAM,CAAC,GAAoB,EAAE,OAAuE;IACnH,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,GAAG,CAAC,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAElD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC7B,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QAC7B,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC;IAED,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;AACvC,CAAC"}
package/esm/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from './convertors/px_2_rem.ts';
2
+ export * from './convertors/rem_2_px.ts';
1
3
  export * from './css-properties/css-properties.ts';
2
4
  export * from './css-properties/to_dom_style.ts';
3
5
  export * from './props/class-name.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAA;AAClD,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,oCAAoC,CAAA;AAClD,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA"}
package/esm/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ export * from "./convertors/px_2_rem.js";
2
+ export * from "./convertors/rem_2_px.js";
1
3
  export * from "./css-properties/css-properties.js";
2
4
  export * from "./css-properties/to_dom_style.js";
3
5
  export * from "./props/class-name.js";
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAA;AAClD,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,oCAAoC,CAAA;AAClD,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  export function LogPanel({ title, log }) {
3
- return (_jsxs("div", { className: "bg-neutral-100 p-4 rounded overflow-y-auto", children: [_jsx("h4", { className: "mb-2", children: title }), log.map((entry, i) => (_jsx("pre", { className: "font-mono", children: entry }, i)))] }));
3
+ return (_jsxs("div", { className: "bg-neutral-100 dark:bg-neutral-900 p-4 rounded overflow-y-auto", children: [_jsx("h4", { className: "mb-2", children: title }), log.map((entry, i) => (_jsx("pre", { className: "font-mono", children: entry }, i)))] }));
4
4
  }
5
5
  //# sourceMappingURL=log-panel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"log-panel.js","sourceRoot":"","sources":["../../src/testing/log-panel.tsx"],"names":[],"mappings":";AAAA,MAAM,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,GAAG,EAAoC;IACxE,OAAO,CACN,eAAK,SAAS,EAAC,4CAA4C,aAC1D,aAAI,SAAS,EAAC,MAAM,YAAE,KAAK,GAAM,EAChC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,cAAa,SAAS,EAAC,WAAW,YAChC,KAAK,IADG,CAAC,CAEL,CACN,CAAC,IACG,CACN,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"log-panel.js","sourceRoot":"","sources":["../../src/testing/log-panel.tsx"],"names":[],"mappings":";AAAA,MAAM,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,GAAG,EAAoC;IACxE,OAAO,CACN,eAAK,SAAS,EAAC,gEAAgE,aAC9E,aAAI,SAAS,EAAC,MAAM,YAAE,KAAK,GAAM,EAChC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,cAAa,SAAS,EAAC,WAAW,YAChC,KAAK,IADG,CAAC,CAEL,CACN,CAAC,IACG,CACN,CAAA;AACF,CAAC"}
@@ -5,6 +5,7 @@
5
5
  * @param options.themes - Record mapping theme keys to their data attribute values
6
6
  * @param options.defaultTheme - Fallback theme key if attribute value doesn't match any theme
7
7
  * @param options.attributeName - Name of the data attribute to check (must start with 'data-')
8
+ * @param options.allowCustom - Whether to allow custom themes value
8
9
  * @returns The matching theme key, or defaultTheme if no match found
9
10
  *
10
11
  * @example
@@ -24,11 +25,18 @@
24
25
  * ```
25
26
  */
26
27
  export declare function getThemeByDataAttribute<Themes extends Record<string, string>>(options: {
27
- themes: Themes;
28
- defaultTheme?: keyof Themes | undefined;
29
28
  attributeName: `data-${string}`;
29
+ defaultTheme?: keyof Themes | undefined;
30
+ themes: Themes;
30
31
  element?: Element | undefined;
31
32
  }): keyof Themes | undefined;
33
+ export declare function getThemeByDataAttribute<Themes extends Record<string, string>>(options: {
34
+ attributeName: `data-${string}`;
35
+ allowCustom: true | undefined;
36
+ defaultTheme?: keyof Themes | undefined;
37
+ themes: Themes;
38
+ element?: Element | undefined;
39
+ }): string | undefined;
32
40
  /**
33
41
  * Observes changes to a theme data attribute and calls a handler when it changes.
34
42
  *
@@ -65,4 +73,12 @@ export declare function observeThemeByDataAttributes<Themes extends Record<strin
65
73
  defaultTheme?: keyof Themes | undefined;
66
74
  element?: Element | undefined;
67
75
  }): MutationObserver;
76
+ export declare function observeThemeByDataAttributes<Themes extends Record<string, string>>(options: {
77
+ attributeName: `data-${string}`;
78
+ themes: Themes;
79
+ handler: (value: string | null) => void;
80
+ allowCustom: true | undefined;
81
+ defaultTheme?: keyof Themes | undefined;
82
+ element?: Element | undefined;
83
+ }): MutationObserver;
68
84
  //# sourceMappingURL=data-attribute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-attribute.d.ts","sourceRoot":"","sources":["../../src/theme/data-attribute.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE;IACvF,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACvC,aAAa,EAAE,QAAQ,MAAM,EAAE,CAAA;IAC/B,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7B,GAAG,MAAM,MAAM,GAAG,SAAS,CAM3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE;IAC5F,aAAa,EAAE,QAAQ,MAAM,EAAE,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IACvC,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACvC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7B,oBAmBA"}
1
+ {"version":3,"file":"data-attribute.d.ts","sourceRoot":"","sources":["../../src/theme/data-attribute.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE;IACvF,aAAa,EAAE,QAAQ,MAAM,EAAE,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7B,GAAG,MAAM,MAAM,GAAG,SAAS,CAAA;AAC5B,wBAAgB,uBAAuB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE;IACvF,aAAa,EAAE,QAAQ,MAAM,EAAE,CAAA;IAC/B,WAAW,EAAE,IAAI,GAAG,SAAS,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7B,GAAG,MAAM,GAAG,SAAS,CAAA;AActB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE;IAC5F,aAAa,EAAE,QAAQ,MAAM,EAAE,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IACvC,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACvC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7B,GAAG,gBAAgB,CAAA;AACpB,wBAAgB,4BAA4B,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE;IAC5F,aAAa,EAAE,QAAQ,MAAM,EAAE,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IACvC,WAAW,EAAE,IAAI,GAAG,SAAS,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACvC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7B,GAAG,gBAAgB,CAAA"}
@@ -1,64 +1,10 @@
1
1
  import { findKey } from 'type-plus';
2
2
  import { getDataAttribute, observeDataAttributes } from "../utils/data-attribute.js";
3
- /**
4
- * Gets the theme based on a data attribute value.
5
- *
6
- * @param options - Configuration options
7
- * @param options.themes - Record mapping theme keys to their data attribute values
8
- * @param options.defaultTheme - Fallback theme key if attribute value doesn't match any theme
9
- * @param options.attributeName - Name of the data attribute to check (must start with 'data-')
10
- * @returns The matching theme key, or defaultTheme if no match found
11
- *
12
- * @example
13
- * ```ts
14
- * const themes = {
15
- * light: 'light',
16
- * dark: 'dark',
17
- * system: 'system'
18
- * }
19
- *
20
- * // Get theme from data-theme attribute
21
- * const theme = getThemeByDataAttribute({
22
- * themes,
23
- * defaultTheme: 'system',
24
- * attributeName: 'data-theme'
25
- * })
26
- * ```
27
- */
28
3
  export function getThemeByDataAttribute(options) {
29
- const value = getDataAttribute(options.attributeName, options.element);
4
+ const value = getDataAttribute(options.attributeName, options.element) ?? undefined;
30
5
  const theme = findKey(options.themes, (theme) => options.themes[theme] === value);
31
- return theme ?? options.defaultTheme;
6
+ return theme ?? options.defaultTheme ?? (options.allowCustom ? value : undefined);
32
7
  }
33
- /**
34
- * Observes changes to a theme data attribute and calls a handler when it changes.
35
- *
36
- * @param options - Configuration options
37
- * @param options.themes - Record mapping theme keys to their data attribute values
38
- * @param options.handler - Callback function called with the new theme value or null when removed
39
- * @param options.defaultTheme - Fallback theme key if attribute value doesn't match any theme
40
- * @param options.attributeName - Name of the data attribute to observe (must start with 'data-')
41
- * @returns A MutationObserver that can be disconnected to stop observing
42
- *
43
- * @example
44
- * ```ts
45
- * const themes = {
46
- * light: 'light',
47
- * dark: 'dark'
48
- * }
49
- *
50
- * // Observe data-theme attribute changes
51
- * const observer = observeThemeByDataAttributes({
52
- * themes,
53
- * handler: (theme) => console.log('Theme changed to:', theme),
54
- * defaultTheme: 'light',
55
- * attributeName: 'data-theme'
56
- * })
57
- *
58
- * // Stop observing
59
- * observer.disconnect()
60
- * ```
61
- */
62
8
  export function observeThemeByDataAttributes(options) {
63
9
  return observeDataAttributes({
64
10
  [options.attributeName]: (value) => {
@@ -69,9 +15,12 @@ export function observeThemeByDataAttributes(options) {
69
15
  for (const name in options.themes) {
70
16
  if (options.themes[name] === value) {
71
17
  options.handler(name);
72
- break;
18
+ return;
73
19
  }
74
20
  }
21
+ if (options.allowCustom) {
22
+ options.handler(value);
23
+ }
75
24
  },
76
25
  }, options.element);
77
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"data-attribute.js","sourceRoot":"","sources":["../../src/theme/data-attribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,uBAAuB,CAAwC,OAK9E;IACA,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAEtE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAA;IAEjF,OAAO,KAAK,IAAI,OAAO,CAAC,YAAY,CAAA;AACrC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,4BAA4B,CAAwC,OAMnF;IACA,OAAO,qBAAqB,CAC3B;QACC,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,KAAoB,EAAE,EAAE;YACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,CAAC,OAAO,CAAE,OAAO,CAAC,YAAuB,IAAI,IAAI,CAAC,CAAA;gBACzD,OAAM;YACP,CAAC;YAED,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;oBACpC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;oBACrB,MAAK;gBACN,CAAC;YACF,CAAC;QACF,CAAC;KACD,EACD,OAAO,CAAC,OAAO,CACf,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"data-attribute.js","sourceRoot":"","sources":["../../src/theme/data-attribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAyCpF,MAAM,UAAU,uBAAuB,CAAwC,OAM9E;IACA,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,SAAS,CAAA;IACnF,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAA;IAEjF,OAAO,KAAK,IAAI,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AAClF,CAAC;AA8CD,MAAM,UAAU,4BAA4B,CAAwC,OAOnF;IACA,OAAO,qBAAqB,CAC3B;QACC,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,KAAoB,EAAE,EAAE;YACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,CAAC,OAAO,CAAE,OAAO,CAAC,YAAuB,IAAI,IAAI,CAAC,CAAA;gBACzD,OAAM;YACP,CAAC;YAED,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;oBACpC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;oBACrB,OAAM;gBACP,CAAC;YACF,CAAC;YAED,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;gBACzB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACvB,CAAC;QACF,CAAC;KACD,EACD,OAAO,CAAC,OAAO,CACf,CAAA;AACF,CAAC"}
@@ -14,7 +14,7 @@
14
14
  * const testId = getAttribute('data-testid', element)
15
15
  * ```
16
16
  */
17
- export declare function getAttribute<T extends string>(qualifiedName: T, element?: Element | undefined): T | null;
17
+ export declare function getAttribute<T extends string>(qualifiedName: T, element?: Element | undefined): string | null;
18
18
  /**
19
19
  * Observes attributes changes on an element and calls corresponding handlers.
20
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"attribute.d.ts","sourceRoot":"","sources":["../../src/utils/attribute.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC5C,aAAa,EAAE,CAAC,EAChB,OAAO,GAAE,OAAO,GAAG,SAAoC,GAER,CAAC,GAAG,IAAI,CACvD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EACjD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,EACnD,OAAO,GAAE,OAAO,GAAG,SAAoC,oBAcvD"}
1
+ {"version":3,"file":"attribute.d.ts","sourceRoot":"","sources":["../../src/utils/attribute.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC5C,aAAa,EAAE,CAAC,EAChB,OAAO,GAAE,OAAO,GAAG,SAAoC,iBAGvD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EACjD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,EACnD,OAAO,GAAE,OAAO,GAAG,SAAoC,oBAcvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"attribute.js","sourceRoot":"","sources":["../../src/utils/attribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAEvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAC3B,aAAgB,EAChB,UAA+B,GAAG,CAAC,kBAAkB,EAAE;IAEvD,OAAO,OAAO,EAAE,YAAY,CAAC,aAAa,CAAa,CAAA;AACxD,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,iBAAiB,CAChC,QAAmD,EACnD,UAA+B,GAAG,CAAC,kBAAkB,EAAE;IAEvD,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE;QACnD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAc,CAAA;YACzC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAa,CAAA;YACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;QAC7B,CAAC;IACF,CAAC,CAAC,CAAA;IACF,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;QACzB,UAAU,EAAE,IAAI;QAChB,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;KACtC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AAChB,CAAC"}
1
+ {"version":3,"file":"attribute.js","sourceRoot":"","sources":["../../src/utils/attribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAEvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAC3B,aAAgB,EAChB,UAA+B,GAAG,CAAC,kBAAkB,EAAE;IAEvD,OAAO,OAAO,EAAE,YAAY,CAAC,aAAa,CAAC,CAAA;AAC5C,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,iBAAiB,CAChC,QAAmD,EACnD,UAA+B,GAAG,CAAC,kBAAkB,EAAE;IAEvD,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE;QACnD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAc,CAAA;YACzC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAa,CAAA;YACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;QAC7B,CAAC;IACF,CAAC,CAAC,CAAA;IACF,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;QACzB,UAAU,EAAE,IAAI;QAChB,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;KACtC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AAChB,CAAC"}
@@ -1,4 +1,4 @@
1
- export declare function getDataAttribute<T extends `data-${string}`>(qualifiedName: T, element?: Element | undefined): T | null;
1
+ export declare function getDataAttribute<T extends `data-${string}`>(qualifiedName: T, element?: Element | undefined): string | null;
2
2
  /**
3
3
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"data-attribute.d.ts","sourceRoot":"","sources":["../../src/utils/data-attribute.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,QAAQ,MAAM,EAAE,EAC1D,aAAa,EAAE,CAAC,EAChB,OAAO,GAAE,OAAO,GAAG,SAAoC,YAGvD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,QAAQ,MAAM,EAAE,EACjF,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,EAC9C,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,oBAG7B"}
1
+ {"version":3,"file":"data-attribute.d.ts","sourceRoot":"","sources":["../../src/utils/data-attribute.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,QAAQ,MAAM,EAAE,EAC1D,aAAa,EAAE,CAAC,EAChB,OAAO,GAAE,OAAO,GAAG,SAAoC,iBAGvD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,QAAQ,MAAM,EAAE,EACjF,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,EAC9C,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,oBAG7B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@just-web/css",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "CSS types and utilities",
5
5
  "type": "module",
6
6
  "exports": {
@@ -24,7 +24,7 @@
24
24
  "type-plus": "8.0.0-beta.7"
25
25
  },
26
26
  "devDependencies": {
27
- "@repobuddy/storybook": "^0.9.4",
27
+ "@repobuddy/storybook": "^0.12.0",
28
28
  "@repobuddy/vitest": "^1.2.2",
29
29
  "@storybook/addon-essentials": "^8.6.12",
30
30
  "@storybook/addon-storysource": "^8.6.12",
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Converts pixel values to rem units.
3
+ *
4
+ * @param px - The pixel value to convert. Can be a number or string (e.g. '16px' or '16')
5
+ * @param options - Optional configuration
6
+ * @param options.base - Base pixel value to calculate rem units from. Defaults to 16
7
+ * @param options.precision - Number of decimal places in the output. Defaults to 4
8
+ * @returns The converted value as a string with 'rem' units
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * px2rem(16) // '1.0000'
13
+ * px2rem('32px') // '2.0000'
14
+ * px2rem(20, { base: 20 }) // '1.0000'
15
+ * px2rem(13, { precision: 2 }) // '0.81'
16
+ * ```
17
+ */
18
+ export function px2rem(px: number | string, options?: { base?: number | undefined; precision?: number | undefined }) {
19
+ const { base = 16, precision = 4 } = options ?? {}
20
+
21
+ if (typeof px === 'string') {
22
+ px = px.replace(/px$/, '')
23
+ px = Number.parseFloat(px)
24
+ }
25
+
26
+ return (px / base).toFixed(precision)
27
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Converts rem values to pixel units.
3
+ *
4
+ * @param rem - The rem value to convert. Can be a number or string (e.g. '1rem' or '1')
5
+ * @param options - Optional configuration
6
+ * @param options.base - Base pixel value to calculate pixels from. Defaults to 16
7
+ * @param options.precision - Number of decimal places in the output. Defaults to 4
8
+ * @returns The converted value as a string with 'px' units
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * rem2px(1) // '16.0000'
13
+ * rem2px('2rem') // '32.0000'
14
+ * rem2px(1, { base: 20 }) // '20.0000'
15
+ * rem2px(0.8125, { precision: 2 }) // '13.00'
16
+ * ```
17
+ */
18
+ export function rem2px(rem: number | string, options?: { base?: number | undefined; precision?: number | undefined }) {
19
+ const { base = 16, precision = 4 } = options ?? {}
20
+
21
+ if (typeof rem === 'string') {
22
+ rem = rem.replace(/rem$/, '')
23
+ rem = Number.parseFloat(rem)
24
+ }
25
+
26
+ return (rem * base).toFixed(precision)
27
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from './convertors/px_2_rem.ts'
2
+ export * from './convertors/rem_2_px.ts'
1
3
  export * from './css-properties/css-properties.ts'
2
4
  export * from './css-properties/to_dom_style.ts'
3
5
  export * from './props/class-name.ts'
package/src/tailwind.css CHANGED
@@ -1 +1,3 @@
1
- @import "tailwindcss";
1
+ @import "tailwindcss";
2
+
3
+ @custom-variant dark (&:where(.dark, .dark *));
@@ -1,6 +1,6 @@
1
1
  export function LogPanel({ title, log }: { title: string; log: string[] }) {
2
2
  return (
3
- <div className="bg-neutral-100 p-4 rounded overflow-y-auto">
3
+ <div className="bg-neutral-100 dark:bg-neutral-900 p-4 rounded overflow-y-auto">
4
4
  <h4 className="mb-2">{title}</h4>
5
5
  {log.map((entry, i) => (
6
6
  <pre key={i} className="font-mono">
@@ -8,6 +8,7 @@ import { getDataAttribute, observeDataAttributes } from '../utils/data-attribute
8
8
  * @param options.themes - Record mapping theme keys to their data attribute values
9
9
  * @param options.defaultTheme - Fallback theme key if attribute value doesn't match any theme
10
10
  * @param options.attributeName - Name of the data attribute to check (must start with 'data-')
11
+ * @param options.allowCustom - Whether to allow custom themes value
11
12
  * @returns The matching theme key, or defaultTheme if no match found
12
13
  *
13
14
  * @example
@@ -27,16 +28,29 @@ import { getDataAttribute, observeDataAttributes } from '../utils/data-attribute
27
28
  * ```
28
29
  */
29
30
  export function getThemeByDataAttribute<Themes extends Record<string, string>>(options: {
31
+ attributeName: `data-${string}`
32
+ defaultTheme?: keyof Themes | undefined
30
33
  themes: Themes
34
+ element?: Element | undefined
35
+ }): keyof Themes | undefined
36
+ export function getThemeByDataAttribute<Themes extends Record<string, string>>(options: {
37
+ attributeName: `data-${string}`
38
+ allowCustom: true | undefined
31
39
  defaultTheme?: keyof Themes | undefined
40
+ themes: Themes
41
+ element?: Element | undefined
42
+ }): string | undefined
43
+ export function getThemeByDataAttribute<Themes extends Record<string, string>>(options: {
32
44
  attributeName: `data-${string}`
45
+ allowCustom?: boolean | undefined
46
+ defaultTheme?: keyof Themes | undefined
47
+ themes: Themes
33
48
  element?: Element | undefined
34
49
  }): keyof Themes | undefined {
35
- const value = getDataAttribute(options.attributeName, options.element)
36
-
50
+ const value = getDataAttribute(options.attributeName, options.element) ?? undefined
37
51
  const theme = findKey(options.themes, (theme) => options.themes[theme] === value)
38
52
 
39
- return theme ?? options.defaultTheme
53
+ return theme ?? options.defaultTheme ?? (options.allowCustom ? value : undefined)
40
54
  }
41
55
 
42
56
  /**
@@ -74,7 +88,23 @@ export function observeThemeByDataAttributes<Themes extends Record<string, strin
74
88
  handler: (value: string | null) => void
75
89
  defaultTheme?: keyof Themes | undefined
76
90
  element?: Element | undefined
77
- }) {
91
+ }): MutationObserver
92
+ export function observeThemeByDataAttributes<Themes extends Record<string, string>>(options: {
93
+ attributeName: `data-${string}`
94
+ themes: Themes
95
+ handler: (value: string | null) => void
96
+ allowCustom: true | undefined
97
+ defaultTheme?: keyof Themes | undefined
98
+ element?: Element | undefined
99
+ }): MutationObserver
100
+ export function observeThemeByDataAttributes<Themes extends Record<string, string>>(options: {
101
+ attributeName: `data-${string}`
102
+ themes: Themes
103
+ handler: (value: string | null) => void
104
+ allowCustom?: boolean | undefined
105
+ defaultTheme?: keyof Themes | undefined
106
+ element?: Element | undefined
107
+ }): MutationObserver {
78
108
  return observeDataAttributes(
79
109
  {
80
110
  [options.attributeName]: (value: string | null) => {
@@ -86,9 +116,13 @@ export function observeThemeByDataAttributes<Themes extends Record<string, strin
86
116
  for (const name in options.themes) {
87
117
  if (options.themes[name] === value) {
88
118
  options.handler(name)
89
- break
119
+ return
90
120
  }
91
121
  }
122
+
123
+ if (options.allowCustom) {
124
+ options.handler(value)
125
+ }
92
126
  },
93
127
  },
94
128
  options.element,
@@ -20,7 +20,7 @@ export function getAttribute<T extends string>(
20
20
  qualifiedName: T,
21
21
  element: Element | undefined = ctx.getDocumentElement(),
22
22
  ) {
23
- return element?.getAttribute(qualifiedName) as T | null
23
+ return element?.getAttribute(qualifiedName)
24
24
  }
25
25
 
26
26
  /**