@jsenv/navi 0.5.1 → 0.5.3

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.
@@ -20636,12 +20636,17 @@ const parseStyleString = (styleString) => {
20636
20636
  const value = declaration.slice(colonIndex + 1).trim();
20637
20637
 
20638
20638
  if (property && value) {
20639
- // Convert kebab-case to camelCase (e.g., "font-size" -> "fontSize")
20640
- const camelCaseProperty = property.replace(/-([a-z])/g, (match, letter) =>
20641
- letter.toUpperCase(),
20642
- );
20643
-
20644
- style[camelCaseProperty] = value;
20639
+ // CSS custom properties (starting with --) should NOT be converted to camelCase
20640
+ if (property.startsWith("--")) {
20641
+ style[property] = value;
20642
+ } else {
20643
+ // Convert kebab-case to camelCase (e.g., "font-size" -> "fontSize")
20644
+ const camelCaseProperty = property.replace(
20645
+ /-([a-z])/g,
20646
+ (match, letter) => letter.toUpperCase(),
20647
+ );
20648
+ style[camelCaseProperty] = value;
20649
+ }
20645
20650
  }
20646
20651
  }
20647
20652
 
@@ -27749,28 +27754,17 @@ const useSignalSync = (value, initialValue = value) => {
27749
27754
  return signal;
27750
27755
  };
27751
27756
 
27752
- /**
27753
- * FontSizedSvg component
27754
- *
27755
- * This component wraps an SVG element to make it inherit the current font size.
27756
- * It creates a container that's exactly 1em × 1em in size, allowing the SVG to scale
27757
- * proportionally with the surrounding text.
27758
- *
27759
- * Usage:
27760
- * ```jsx
27761
- * <FontSizedSvg>
27762
- * <svg width="100%" height="100%" viewBox="...">
27763
- * <path d="..." />
27764
- * </svg>
27765
- * </FontSizedSvg>
27766
- * ```
27767
- *
27768
- * Notes:
27769
- * - The wrapped SVG should use width="100%" and height="100%" to fill the container
27770
- * - This ensures SVG icons match the current text size without additional styling
27771
- * - Useful for inline icons that should respect the parent's font-size
27772
- */
27773
-
27757
+ installImportMetaCss(import.meta);import.meta.css = /* css */`
27758
+ .navi_font_sized_svg {
27759
+ display: flex;
27760
+ width: 1em;
27761
+ height: 1em;
27762
+ flex-shrink: 0;
27763
+ align-items: center;
27764
+ justify-self: center;
27765
+ line-height: 1em;
27766
+ }
27767
+ `;
27774
27768
  const FontSizedSvg = ({
27775
27769
  width = "1em",
27776
27770
  height = "1em",
@@ -27780,16 +27774,11 @@ const FontSizedSvg = ({
27780
27774
  }) => {
27781
27775
  return jsx("span", {
27782
27776
  ...props,
27783
- style: {
27784
- ...style,
27785
- display: "flex",
27786
- alignItems: "center",
27787
- width,
27788
- height,
27789
- justifySelf: "center",
27790
- lineHeight: "1em",
27791
- flexShrink: 0
27792
- },
27777
+ className: "navi_font_sized_svg",
27778
+ style: withPropsStyle({
27779
+ width: width === "1em" ? undefined : width,
27780
+ height: height === "1em" ? undefined : height
27781
+ }, style),
27793
27782
  children: children
27794
27783
  });
27795
27784
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Library of components including navigation to create frontend applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,81 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>withPropsStyle Demo - Minimalist</title>
6
+ <style>
7
+ button {
8
+ padding: 12px 20px;
9
+ font-family: system-ui, sans-serif;
10
+ border: 1px solid #ccc;
11
+ border-radius: 4px;
12
+ cursor: pointer;
13
+ }
14
+ </style>
15
+ </head>
16
+ <body>
17
+ <div id="app"></div>
18
+ <script type="module" jsenv-type="module/jsx">
19
+ /* eslint-disable no-unused-vars */
20
+ import { render } from "preact";
21
+ import { withPropsStyle } from "../with_props_style.js";
22
+
23
+ const Button = ({ style, children, ...rest }) => (
24
+ <button
25
+ style={withPropsStyle(
26
+ {
27
+ backgroundColor: "var(--background-color, #f8f9fa)",
28
+ },
29
+ style,
30
+ )}
31
+ {...rest}
32
+ >
33
+ {children}
34
+ </button>
35
+ );
36
+
37
+ const Demo = () => {
38
+ return (
39
+ <div style={{ padding: "20px", fontFamily: "system-ui, sans-serif" }}>
40
+ <h1>withPropsStyle Demo</h1>
41
+
42
+ <section style={{ marginBottom: "30px" }}>
43
+ <h2>1. Default Button</h2>
44
+ <div>
45
+ <Button>Default</Button>
46
+ </div>
47
+ </section>
48
+
49
+ <section style={{ marginBottom: "30px" }}>
50
+ <h2>2. Override via style + background-color</h2>
51
+ <div style={{ display: "flex", gap: "10px", flexWrap: "wrap" }}>
52
+ <Button style={{ backgroundColor: "#007bff" }}>
53
+ Object notation
54
+ </Button>
55
+
56
+ <Button style="background-color: #28a745;">
57
+ String notation
58
+ </Button>
59
+ </div>
60
+ </section>
61
+
62
+ <section>
63
+ <h2>3. Override via style + CSS var</h2>
64
+ <div style={{ display: "flex", gap: "10px", flexWrap: "wrap" }}>
65
+ <Button style={{ "--background-color": "#dc3545" }}>
66
+ Object notation
67
+ </Button>
68
+
69
+ <Button style="--background-color: #ffc107;">
70
+ String notation
71
+ </Button>
72
+ </div>
73
+ </section>
74
+ </div>
75
+ );
76
+ };
77
+
78
+ render(<Demo />, document.getElementById("app"));
79
+ </script>
80
+ </body>
81
+ </html>
@@ -68,12 +68,17 @@ const parseStyleString = (styleString) => {
68
68
  const value = declaration.slice(colonIndex + 1).trim();
69
69
 
70
70
  if (property && value) {
71
- // Convert kebab-case to camelCase (e.g., "font-size" -> "fontSize")
72
- const camelCaseProperty = property.replace(/-([a-z])/g, (match, letter) =>
73
- letter.toUpperCase(),
74
- );
75
-
76
- style[camelCaseProperty] = value;
71
+ // CSS custom properties (starting with --) should NOT be converted to camelCase
72
+ if (property.startsWith("--")) {
73
+ style[property] = value;
74
+ } else {
75
+ // Convert kebab-case to camelCase (e.g., "font-size" -> "fontSize")
76
+ const camelCaseProperty = property.replace(
77
+ /-([a-z])/g,
78
+ (match, letter) => letter.toUpperCase(),
79
+ );
80
+ style[camelCaseProperty] = value;
81
+ }
77
82
  }
78
83
  }
79
84
 
@@ -20,6 +20,20 @@
20
20
  * - Useful for inline icons that should respect the parent's font-size
21
21
  */
22
22
 
23
+ import { withPropsStyle } from "../props_composition/with_props_style.js";
24
+
25
+ import.meta.css = /* css */ `
26
+ .navi_font_sized_svg {
27
+ display: flex;
28
+ width: 1em;
29
+ height: 1em;
30
+ flex-shrink: 0;
31
+ align-items: center;
32
+ justify-self: center;
33
+ line-height: 1em;
34
+ }
35
+ `;
36
+
23
37
  export const FontSizedSvg = ({
24
38
  width = "1em",
25
39
  height = "1em",
@@ -30,16 +44,14 @@ export const FontSizedSvg = ({
30
44
  return (
31
45
  <span
32
46
  {...props}
33
- style={{
34
- ...style,
35
- display: "flex",
36
- alignItems: "center",
37
- width,
38
- height,
39
- justifySelf: "center",
40
- lineHeight: "1em",
41
- flexShrink: 0,
42
- }}
47
+ className="navi_font_sized_svg"
48
+ style={withPropsStyle(
49
+ {
50
+ width: width === "1em" ? undefined : width,
51
+ height: height === "1em" ? undefined : height,
52
+ },
53
+ style,
54
+ )}
43
55
  >
44
56
  {children}
45
57
  </span>