@kudzujs/core 0.6.10 → 0.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -208,6 +208,14 @@ Regular attributes use the same expressions without an allowlist:
208
208
 
209
209
  Kudzu compiles derived expressions to external ESM and patches only the bound DOM attribute or property. `aria-*` and `data-*` boolean values serialize as `"true"` or `"false"`; ordinary false values remove the attribute. Object `style` values use React-shaped camelCase properties, add `px` to nonzero dimensional numbers, and preserve unitless properties and CSS custom properties. Reactive `dangerouslySetInnerHTML` remains unsupported.
210
210
 
211
+ Inline SVG accepts React-shaped presentation props for static and reactive values. Kudzu preserves native camelCase SVG names such as `viewBox` while mapping common aliases such as `fillRule`, `clipRule`, `strokeWidth`, `strokeLinecap`, `strokeLinejoin`, opacity/color props, `textAnchor`, and `vectorEffect` to their SVG attribute names:
212
+
213
+ ```tsx
214
+ <svg viewBox="0 0 24 24">
215
+ <path fillRule="evenodd" strokeWidth={active ? 2 : 1} strokeLinecap="round" />
216
+ </svg>
217
+ ```
218
+
211
219
  ## DOM Refs
212
220
 
213
221
  Use an object ref to access an element from a normal event handler:
@@ -544,6 +552,7 @@ Supported:
544
552
  - Direct text DOM patches
545
553
  - Reactive standard, `aria-*`, and `data-*` attributes
546
554
  - Reactive object `style` attributes
555
+ - Static and reactive React-shaped SVG presentation attributes
547
556
  - Object DOM refs in native event handlers
548
557
  - Default, nested, and reactive context providers
549
558
  - Controlled `value` and `checked` form properties
@@ -21,6 +21,8 @@ Exact relative `.worker.ts` constructors in inline effects are validated and bun
21
21
 
22
22
  Page `metadata` can emit description, canonical, favicon, manifest, Open Graph, and Twitter Card tags without a client runtime. Source CSS and global `kudzu.config` styles are emitted in document heads before `afterBuild()` runs; static stylesheet links in component JSX fail compilation instead of loading from the body.
23
23
 
24
+ Inline SVG rendering normalizes an explicit set of common React presentation aliases before static serialization and binding descriptor creation. Reactive aliases therefore use the existing generic `setAttribute` path; static SVG adds no JavaScript and reactive SVG adds no SVG-specific runtime.
25
+
24
26
  Same-file and relative-imported components receiving a direct local-state array prop are specialized to intrinsic JSX before keyed-list analysis, so their component function is not retained in the browser. Handler modules are emitted only when a rendered descriptor references them, preventing specialized imported components from adding dead browser assets. Direct JSON-safe primitive keyed-item dependencies subscribe each row record to its owning list commit and compare selected fields after `list-runtime.js` synchronously refreshes the row marker. Only changed rows rerun with the complete latest item; reorder compares equal, unrelated fields do nothing, and key changes remain remove plus mount. Builds without item dependencies emit no item reader or list-state subscription code.
25
27
 
26
28
  The reduced `useReducer` form reuses ordinary state slots. A direct dispatch in a compiled handler becomes a functional `set` whose reducer is bundled from a relative TypeScript module into that handler graph. Reducer-free routes and shared runtimes are unchanged; no reducer runtime or browser component instance exists.
@@ -17,6 +17,28 @@ const contextMarker = Symbol("kudzu.context")
17
17
  const contextProviderMarker = Symbol("kudzu.contextProvider")
18
18
  const routeScopeMarker = Symbol("kudzu.routeScope")
19
19
  const noSelectValue = Symbol("kudzu.no-select-value")
20
+ const svgAttributeAliases = {
21
+ clipRule: "clip-rule",
22
+ colorInterpolation: "color-interpolation",
23
+ colorInterpolationFilters: "color-interpolation-filters",
24
+ dominantBaseline: "dominant-baseline",
25
+ fillOpacity: "fill-opacity",
26
+ fillRule: "fill-rule",
27
+ floodColor: "flood-color",
28
+ floodOpacity: "flood-opacity",
29
+ shapeRendering: "shape-rendering",
30
+ stopColor: "stop-color",
31
+ stopOpacity: "stop-opacity",
32
+ strokeDasharray: "stroke-dasharray",
33
+ strokeDashoffset: "stroke-dashoffset",
34
+ strokeLinecap: "stroke-linecap",
35
+ strokeLinejoin: "stroke-linejoin",
36
+ strokeMiterlimit: "stroke-miterlimit",
37
+ strokeOpacity: "stroke-opacity",
38
+ strokeWidth: "stroke-width",
39
+ textAnchor: "text-anchor",
40
+ vectorEffect: "vector-effect"
41
+ }
20
42
 
21
43
  let renderContext
22
44
 
@@ -576,6 +598,7 @@ async function renderNode(node, namespace, selectValue = noSelectValue) {
576
598
  const childNamespace = tag === "svg" || tag === "math"
577
599
  ? tag
578
600
  : namespace === "svg" && tag === "foreignObject" ? undefined : namespace
601
+ const svg = tag === "svg" || namespace === "svg"
579
602
  let attributes = ""
580
603
  const attributeBindings = []
581
604
  const listAttributes = []
@@ -636,7 +659,7 @@ async function renderNode(node, namespace, selectValue = noSelectValue) {
636
659
  continue
637
660
  }
638
661
 
639
- const name = rawName === "className" ? "class" : rawName === "htmlFor" ? "for" : rawName
662
+ const name = rawName === "className" ? "class" : rawName === "htmlFor" ? "for" : svg ? svgAttributeAliases[rawName] ?? rawName : rawName
640
663
  const propertyTarget = name === "class" || name === "disabled" || name === "value" || name === "checked" || name === "style"
641
664
  if (value?.[listFieldMarker]) {
642
665
  attributes += renderAttribute(name, value.value)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kudzujs/core",
3
- "version": "0.6.10",
3
+ "version": "0.6.11",
4
4
  "description": "HTML-first TSX framework with synchronous state semantics and no virtual DOM",
5
5
  "type": "module",
6
6
  "license": "MIT",