@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 +9 -0
- package/framework/README.md +2 -0
- package/framework/core.mjs +24 -1
- package/package.json +1 -1
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
|
package/framework/README.md
CHANGED
|
@@ -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.
|
package/framework/core.mjs
CHANGED
|
@@ -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)
|