nodality 1.2.6 → 1.2.8
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/dist/animator.cjs.js +1 -1
- package/dist/animator.cjs.js.LICENSE.txt +1 -1
- package/dist/animator.esm.js +1 -1
- package/dist/animator.esm.js.LICENSE.txt +1 -1
- package/dist/audionew.cjs.js +1 -1
- package/dist/audionew.cjs.js.LICENSE.txt +1 -1
- package/dist/audionew.esm.js +1 -1
- package/dist/audionew.esm.js.LICENSE.txt +1 -1
- package/dist/base.cjs.js +1 -1
- package/dist/base.cjs.js.LICENSE.txt +1 -1
- package/dist/base.esm.js +1 -1
- package/dist/base.esm.js.LICENSE.txt +1 -1
- package/dist/beta-desktop-bar.cjs.js +1 -1
- package/dist/beta-desktop-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/beta-desktop-bar.esm.js +1 -1
- package/dist/beta-desktop-bar.esm.js.LICENSE.txt +1 -1
- package/dist/beta-mobile-bar.cjs.js +1 -1
- package/dist/beta-mobile-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/beta-mobile-bar.esm.js +1 -1
- package/dist/beta-mobile-bar.esm.js.LICENSE.txt +1 -1
- package/dist/bundle.umd.js +1 -1
- package/dist/bundle.umd.js.LICENSE.txt +1 -1
- package/dist/button.cjs.js +1 -1
- package/dist/button.cjs.js.LICENSE.txt +1 -1
- package/dist/button.esm.js +1 -1
- package/dist/button.esm.js.LICENSE.txt +1 -1
- package/dist/card-getter.cjs.js.LICENSE.txt +1 -1
- package/dist/card-getter.esm.js.LICENSE.txt +1 -1
- package/dist/center.cjs.js +1 -1
- package/dist/center.cjs.js.LICENSE.txt +1 -1
- package/dist/center.esm.js +1 -1
- package/dist/center.esm.js.LICENSE.txt +1 -1
- package/dist/checkbox.cjs.js +1 -1
- package/dist/checkbox.cjs.js.LICENSE.txt +1 -1
- package/dist/checkbox.esm.js +1 -1
- package/dist/checkbox.esm.js.LICENSE.txt +1 -1
- package/dist/code.cjs.js +1 -1
- package/dist/code.cjs.js.LICENSE.txt +1 -1
- package/dist/code.esm.js +1 -1
- package/dist/code.esm.js.LICENSE.txt +1 -1
- package/dist/container.cjs.js +1 -1
- package/dist/container.cjs.js.LICENSE.txt +1 -1
- package/dist/container.esm.js +1 -1
- package/dist/container.esm.js.LICENSE.txt +1 -1
- package/dist/data-list.cjs.js +1 -1
- package/dist/data-list.cjs.js.LICENSE.txt +1 -1
- package/dist/data-list.esm.js.LICENSE.txt +1 -1
- package/dist/designer.cjs.js +1 -1
- package/dist/designer.cjs.js.LICENSE.txt +1 -1
- package/dist/designer.esm.js +1 -1
- package/dist/designer.esm.js.LICENSE.txt +1 -1
- package/dist/element-mapper.cjs.js +1 -1
- package/dist/element-mapper.cjs.js.LICENSE.txt +1 -1
- package/dist/element-mapper.esm.js +1 -1
- package/dist/element-mapper.esm.js.LICENSE.txt +1 -1
- package/dist/finalresult.esm.js +1 -1
- package/dist/finalresult.esm.js.LICENSE.txt +1 -1
- package/dist/flex-card.cjs.js +1 -1
- package/dist/flex-card.cjs.js.LICENSE.txt +1 -1
- package/dist/flex-card.esm.js +1 -1
- package/dist/flex-card.esm.js.LICENSE.txt +1 -1
- package/dist/flex-grid.cjs.js +1 -1
- package/dist/flex-grid.cjs.js.LICENSE.txt +1 -1
- package/dist/flex-grid.esm.js +1 -1
- package/dist/flex-grid.esm.js.LICENSE.txt +1 -1
- package/dist/flex-row.cjs.js +1 -1
- package/dist/flex-row.cjs.js.LICENSE.txt +1 -1
- package/dist/flex-row.esm.js +1 -1
- package/dist/flex-row.esm.js.LICENSE.txt +1 -1
- package/dist/floating-input.cjs.js +1 -1
- package/dist/floating-input.cjs.js.LICENSE.txt +1 -1
- package/dist/floating-input.esm.js +1 -1
- package/dist/floating-input.esm.js.LICENSE.txt +1 -1
- package/dist/free.cjs.js +1 -1
- package/dist/free.cjs.js.LICENSE.txt +1 -1
- package/dist/free.esm.js +1 -1
- package/dist/free.esm.js.LICENSE.txt +1 -1
- package/dist/horizontal-scroller.cjs.js.LICENSE.txt +1 -1
- package/dist/horizontal-scroller.esm.js.LICENSE.txt +1 -1
- package/dist/image-picker.cjs.js +1 -1
- package/dist/image-picker.cjs.js.LICENSE.txt +1 -1
- package/dist/image-picker.esm.js +1 -1
- package/dist/image-picker.esm.js.LICENSE.txt +1 -1
- package/dist/image.cjs.js +1 -1
- package/dist/image.cjs.js.LICENSE.txt +1 -1
- package/dist/image.esm.js +1 -1
- package/dist/image.esm.js.LICENSE.txt +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.LICENSE.txt +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.LICENSE.txt +1 -1
- package/dist/keyframe-animation.cjs.js.LICENSE.txt +1 -1
- package/dist/keyframe-animation.esm.js.LICENSE.txt +1 -1
- package/dist/link-getter.cjs.js +1 -1
- package/dist/link-getter.cjs.js.LICENSE.txt +1 -1
- package/dist/link-getter.esm.js +1 -1
- package/dist/link-getter.esm.js.LICENSE.txt +1 -1
- package/dist/link.cjs.js +1 -1
- package/dist/link.cjs.js.LICENSE.txt +1 -1
- package/dist/link.esm.js +1 -1
- package/dist/link.esm.js.LICENSE.txt +1 -1
- package/dist/meta-adder.cjs.js +1 -1
- package/dist/meta-adder.cjs.js.LICENSE.txt +1 -1
- package/dist/meta-adder.esm.js +1 -1
- package/dist/meta-adder.esm.js.LICENSE.txt +1 -1
- package/dist/modal-2025.cjs.js +1 -1
- package/dist/modal-2025.cjs.js.LICENSE.txt +1 -1
- package/dist/modal-2025.esm.js +1 -1
- package/dist/modal-2025.esm.js.LICENSE.txt +1 -1
- package/dist/multiswitcher.cjs.js +1 -1
- package/dist/multiswitcher.cjs.js.LICENSE.txt +1 -1
- package/dist/multiswitcher.esm.js +1 -1
- package/dist/multiswitcher.esm.js.LICENSE.txt +1 -1
- package/dist/new-nav-bar.cjs.js +1 -1
- package/dist/new-nav-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/new-nav-bar.esm.js +1 -1
- package/dist/new-nav-bar.esm.js.LICENSE.txt +1 -1
- package/dist/picker.cjs.js +1 -1
- package/dist/picker.cjs.js.LICENSE.txt +1 -1
- package/dist/picker.esm.js +1 -1
- package/dist/picker.esm.js.LICENSE.txt +1 -1
- package/dist/progress.cjs.js +1 -1
- package/dist/progress.cjs.js.LICENSE.txt +1 -1
- package/dist/progress.esm.js +1 -1
- package/dist/progress.esm.js.LICENSE.txt +1 -1
- package/dist/radio.cjs.js +1 -1
- package/dist/radio.cjs.js.LICENSE.txt +1 -1
- package/dist/radio.esm.js.LICENSE.txt +1 -1
- package/dist/range.cjs.js +1 -1
- package/dist/range.cjs.js.LICENSE.txt +1 -1
- package/dist/range.esm.js.LICENSE.txt +1 -1
- package/dist/scroll-video.cjs.js.LICENSE.txt +1 -1
- package/dist/scroll-video.esm.js.LICENSE.txt +1 -1
- package/dist/side-bar.cjs.js +1 -1
- package/dist/side-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/side-bar.esm.js +1 -1
- package/dist/side-bar.esm.js.LICENSE.txt +1 -1
- package/dist/side-nav-bar.cjs.js +1 -1
- package/dist/side-nav-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/side-nav-bar.esm.js +1 -1
- package/dist/side-nav-bar.esm.js.LICENSE.txt +1 -1
- package/dist/simple-bar.cjs.js +1 -1
- package/dist/simple-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/simple-bar.esm.js +1 -1
- package/dist/simple-bar.esm.js.LICENSE.txt +1 -1
- package/dist/slider-2025.cjs.js +1 -1
- package/dist/slider-2025.cjs.js.LICENSE.txt +1 -1
- package/dist/slider-2025.esm.js +1 -1
- package/dist/slider-2025.esm.js.LICENSE.txt +1 -1
- package/dist/spacer.cjs.js +1 -1
- package/dist/spacer.cjs.js.LICENSE.txt +1 -1
- package/dist/spacer.esm.js +1 -1
- package/dist/spacer.esm.js.LICENSE.txt +1 -1
- package/dist/stack.cjs.js +1 -1
- package/dist/stack.cjs.js.LICENSE.txt +1 -1
- package/dist/stack.esm.js +1 -1
- package/dist/stack.esm.js.LICENSE.txt +1 -1
- package/dist/stacker.cjs.js.LICENSE.txt +1 -1
- package/dist/stacker.esm.js.LICENSE.txt +1 -1
- package/dist/table.cjs.js +1 -1
- package/dist/table.cjs.js.LICENSE.txt +1 -1
- package/dist/table.esm.js +1 -1
- package/dist/table.esm.js.LICENSE.txt +1 -1
- package/dist/text-field.cjs.js +1 -1
- package/dist/text-field.cjs.js.LICENSE.txt +1 -1
- package/dist/text-field.esm.js +1 -1
- package/dist/text-field.esm.js.LICENSE.txt +1 -1
- package/dist/text.cjs.js +1 -1
- package/dist/text.cjs.js.LICENSE.txt +1 -1
- package/dist/text.esm.js +1 -1
- package/dist/text.esm.js.LICENSE.txt +1 -1
- package/dist/theme.cjs.js.LICENSE.txt +1 -1
- package/dist/theme.esm.js.LICENSE.txt +1 -1
- package/dist/transform-anim.cjs.js.LICENSE.txt +1 -1
- package/dist/transform-anim.esm.js.LICENSE.txt +1 -1
- package/dist/ulist.cjs.js +1 -1
- package/dist/ulist.cjs.js.LICENSE.txt +1 -1
- package/dist/ulist.esm.js +1 -1
- package/dist/ulist.esm.js.LICENSE.txt +1 -1
- package/dist/video.cjs.js +1 -1
- package/dist/video.cjs.js.LICENSE.txt +1 -1
- package/dist/video.esm.js +1 -1
- package/dist/video.esm.js.LICENSE.txt +1 -1
- package/dist/wrap.cjs.js +1 -1
- package/dist/wrap.cjs.js.LICENSE.txt +1 -1
- package/dist/wrap.esm.js +1 -1
- package/dist/wrap.esm.js.LICENSE.txt +1 -1
- package/dist/zoom-card.cjs.js +1 -1
- package/dist/zoom-card.cjs.js.LICENSE.txt +1 -1
- package/dist/zoom-card.esm.js +1 -1
- package/dist/zoom-card.esm.js.LICENSE.txt +1 -1
- package/layout/animator.js +13 -2
- package/layout/audio.js +1 -1
- package/layout/audionew.js +1 -1
- package/layout/base.js +1 -1
- package/layout/beta-desktop-bar.js +1 -1
- package/layout/beta-mobile-bar.js +1 -1
- package/layout/button.js +1 -1
- package/layout/center.js +1 -1
- package/layout/checkbox.js +1 -1
- package/layout/circle.js +1 -1
- package/layout/code.js +1 -1
- package/layout/container.js +1 -1
- package/layout/dropdown-2025.js +1 -1
- package/layout/flex-card.js +1 -1
- package/layout/flex-grid.js +1 -1
- package/layout/flex-row.js +1 -1
- package/layout/form-components/custom.js +1 -1
- package/layout/form-components/data-list.js +1 -1
- package/layout/form-components/floating-input.js +1 -1
- package/layout/form-components/form-all.js +1 -1
- package/layout/form-components/form.js +1 -1
- package/layout/form-components/image-picker.js +1 -1
- package/layout/form-components/picker.js +1 -1
- package/layout/form-components/radio.js +1 -1
- package/layout/form-components/radiogroup.js +1 -1
- package/layout/form-components/range.js +1 -1
- package/layout/free.js +1 -1
- package/layout/grid-switcher.js +1 -1
- package/layout/grid.js +1 -1
- package/layout/horizontal-scroller.js +1 -1
- package/layout/image.js +1 -1
- package/layout/index.js +1 -1
- package/layout/link.js +1 -1
- package/layout/list.js +1 -1
- package/layout/meta-adder.js +1 -1
- package/layout/modal-2025.js +1 -1
- package/layout/morph.js +1 -1
- package/layout/multiswitcher.js +1 -1
- package/layout/nav-bar.js +1 -1
- package/layout/nav-factor/custom-div.js +1 -1
- package/layout/new-nav-bar.js +1 -1
- package/layout/polygon.js +1 -1
- package/layout/prerender-site.js +1 -1
- package/layout/prerender.js +1 -1
- package/layout/progress.js +1 -1
- package/layout/row.js +1 -1
- package/layout/scroll-video.js +1 -1
- package/layout/side-bar.js +1 -1
- package/layout/side-nav-bar.js +1 -1
- package/layout/simple-bar.js +1 -1
- package/layout/slider-2025.js +1 -1
- package/layout/spacer.js +1 -1
- package/layout/stack.js +1 -1
- package/layout/svg.js +1 -1
- package/layout/switcher.js +1 -1
- package/layout/table.js +1 -1
- package/layout/text-field.js +1 -1
- package/layout/text.js +1 -1
- package/layout/ulist.js +1 -1
- package/layout/video.js +1 -1
- package/layout/wrap.js +1 -1
- package/layout/zoom-card.js +1 -1
- package/lib/agent-surface.js +1 -1
- package/lib/card-getter.js +1 -1
- package/lib/codegen.js +1 -1
- package/lib/data.js +1 -1
- package/lib/designer.js +1 -1
- package/lib/element-mapper.js +1 -1
- package/lib/keyframe-animation.js +1 -1
- package/lib/link-getter.js +1 -1
- package/lib/morph-node.js +1 -1
- package/lib/raster-inspect.js +1 -1
- package/lib/raster-ops.js +19 -2
- package/lib/raster-presets.js +1 -1
- package/lib/scroll-video.js +1 -1
- package/lib/seo.js +1 -1
- package/lib/stacker.js +1 -1
- package/lib/suggest.js +1 -1
- package/lib/theme.js +1 -1
- package/lib/transform-anim.js +1 -1
- package/lib/transition.js +1 -1
- package/lib/validate-nodes.js +107 -2
- package/lib/webmcp-adapter.js +1 -1
- package/package.json +1 -1
- package/skills/nodality/SKILL.md +21 -10
package/layout/side-bar.js
CHANGED
package/layout/side-nav-bar.js
CHANGED
package/layout/simple-bar.js
CHANGED
package/layout/slider-2025.js
CHANGED
package/layout/spacer.js
CHANGED
package/layout/stack.js
CHANGED
package/layout/svg.js
CHANGED
package/layout/switcher.js
CHANGED
package/layout/table.js
CHANGED
package/layout/text-field.js
CHANGED
package/layout/text.js
CHANGED
package/layout/ulist.js
CHANGED
package/layout/video.js
CHANGED
package/layout/wrap.js
CHANGED
package/layout/zoom-card.js
CHANGED
package/lib/agent-surface.js
CHANGED
package/lib/card-getter.js
CHANGED
package/lib/codegen.js
CHANGED
package/lib/data.js
CHANGED
package/lib/designer.js
CHANGED
package/lib/element-mapper.js
CHANGED
package/lib/link-getter.js
CHANGED
package/lib/morph-node.js
CHANGED
package/lib/raster-inspect.js
CHANGED
package/lib/raster-ops.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* nodality v1.2.
|
|
2
|
+
* nodality v1.2.8
|
|
3
3
|
* (c) 2026 Filip Vabrousek
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -839,7 +839,9 @@ ${NB.map(([x, y]) => probe(x, y)).join("")}
|
|
|
839
839
|
count: {
|
|
840
840
|
default: 5, unit: "count", structural: true,
|
|
841
841
|
summary: "stamps arranged in a ring around the focus. The loop is "
|
|
842
|
-
+ "unrolled at compile time, so this rebuilds — not something to animate."
|
|
842
|
+
+ "unrolled at compile time, so this rebuilds — not something to animate. "
|
|
843
|
+
+ "This default is the shader's; the DOM path that an element of type "
|
|
844
|
+
+ "\"copy\" takes uses 3 instead.",
|
|
843
845
|
},
|
|
844
846
|
points: {
|
|
845
847
|
default: null, unit: "point", structural: true,
|
|
@@ -851,6 +853,21 @@ ${NB.map(([x, y]) => probe(x, y)).join("")}
|
|
|
851
853
|
rotate: { default: 0, unit: "deg", summary: "rotation applied per copy" },
|
|
852
854
|
fade: { default: 1, unit: "ratio", summary: "opacity falloff across the set" },
|
|
853
855
|
amount: { default: 1, unit: "ratio", summary: "overall blend of the copies over the original" },
|
|
856
|
+
animation: {
|
|
857
|
+
default: false, unit: "bool",
|
|
858
|
+
// Read by ElementMapper.mapCopy, not by this file. The
|
|
859
|
+
// doc-consistency check scans raster-ops.js for
|
|
860
|
+
// `node.<key>` and would otherwise call this a param that
|
|
861
|
+
// nothing reads; naming the reader moves that check to the
|
|
862
|
+
// right source instead of switching it off.
|
|
863
|
+
readBy: "element-mapper",
|
|
864
|
+
summary: "DOM path only. An element of type \"copy\" is built by the "
|
|
865
|
+
+ "mapper rather than by the shader, and this asks that mapper for "
|
|
866
|
+
+ "animated copies; the shader path ignores it. Declared because "
|
|
867
|
+
+ "the mapper has always read it and the docs have always taught "
|
|
868
|
+
+ "it, while the registry did not list it – so the validator "
|
|
869
|
+
+ "reported a documented, working node as an unknown parameter.",
|
|
870
|
+
},
|
|
854
871
|
},
|
|
855
872
|
},
|
|
856
873
|
// `count`/`points` unroll the stamp loop at compile time.
|
package/lib/raster-presets.js
CHANGED
package/lib/scroll-video.js
CHANGED
package/lib/seo.js
CHANGED
package/lib/stacker.js
CHANGED
package/lib/suggest.js
CHANGED
package/lib/theme.js
CHANGED
package/lib/transform-anim.js
CHANGED
package/lib/transition.js
CHANGED
package/lib/validate-nodes.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* nodality v1.2.
|
|
2
|
+
* nodality v1.2.8
|
|
3
3
|
* (c) 2026 Filip Vabrousek
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -59,6 +59,59 @@ const EDGE_FIELDS = [
|
|
|
59
59
|
*/
|
|
60
60
|
const AGENT_SURFACE_FIELDS = ["op", "name", "forms", "exclude"];
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Design ops that may be written as a BARE STRING, `{ op: "gradient" }`,
|
|
64
|
+
* and are expanded against a table of defaults by `Des.add`. This list is
|
|
65
|
+
* that table's key set (`ops` in designer.js) and must track it: a string
|
|
66
|
+
* outside it is never expanded, so it reaches the renderer as a node
|
|
67
|
+
* nothing matches and does nothing at all.
|
|
68
|
+
*
|
|
69
|
+
* None of these collide with a raster op name, which is what makes the
|
|
70
|
+
* two string families separable at all.
|
|
71
|
+
*/
|
|
72
|
+
const BARE_DESIGN_OPS = [
|
|
73
|
+
"blast", "gradient", "shadow", "filter", "animation", "transform", "span",
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Design ops written in object form, `{ op: { name: "gradient", … } }`.
|
|
78
|
+
*
|
|
79
|
+
* Assembled from the dispatch sites rather than from the documentation,
|
|
80
|
+
* because the two disagree: the reference calls one of these "LinkStyle"
|
|
81
|
+
* while the runtime matches `"link-style"`. Deliberately generous — a
|
|
82
|
+
* name missing from this list produces a false UNKNOWN_DESIGN_OP on a
|
|
83
|
+
* node that works, and `preview` refuses to render an invalid pair, so
|
|
84
|
+
* over-reporting costs more than under-reporting.
|
|
85
|
+
*/
|
|
86
|
+
const DESIGN_OP_NAMES = [
|
|
87
|
+
"animation", "background", "blast", "card-style", "filter", "gradient",
|
|
88
|
+
"layout", "link-style", "margin", "navStyle", "shadow", "slayout",
|
|
89
|
+
"span", "transform",
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Every top-level key a design node reads.
|
|
94
|
+
*
|
|
95
|
+
* Both forms read `op`, `target`, `range`, and — from the loop that runs
|
|
96
|
+
* over every node, not just the expanded ones — `style` and `duration`.
|
|
97
|
+
* Anything else on the object form is ignored in silence, which is
|
|
98
|
+
* precisely how the README's `colors: [...]` survived.
|
|
99
|
+
*
|
|
100
|
+
* The bare-string form reads four more, because its expansion lifts them
|
|
101
|
+
* INTO the op it substitutes: that is how
|
|
102
|
+
* `{ op: "gradient", gradient: "linear-gradient(…)" }` customises the
|
|
103
|
+
* default, and it is documented, so the two forms cannot share one list.
|
|
104
|
+
*
|
|
105
|
+
* Assembled by reading every `customOptions[i].x` and `protoOptions[i].x`
|
|
106
|
+
* in designer.js, then swept against the e2e fixtures — which is how
|
|
107
|
+
* `style` and `duration` were caught. Guessing this list produces false
|
|
108
|
+
* positives on working pages, and `preview` refuses an invalid pair.
|
|
109
|
+
*/
|
|
110
|
+
const DESIGN_FIELDS = ["op", "target", "range", "style", "duration"];
|
|
111
|
+
const BARE_DESIGN_FIELDS = [
|
|
112
|
+
...DESIGN_FIELDS, "filter", "gradient", "color", "width",
|
|
113
|
+
];
|
|
114
|
+
|
|
62
115
|
/** Node families, told apart exactly the way the runtime tells them apart. */
|
|
63
116
|
const familyOf = (node) => {
|
|
64
117
|
if (!node || typeof node !== "object") return "invalid";
|
|
@@ -66,6 +119,12 @@ const familyOf = (node) => {
|
|
|
66
119
|
if (typeof op === "string") {
|
|
67
120
|
if (op === "morph") return "morph";
|
|
68
121
|
if (op === "agent-surface") return "agent-surface";
|
|
122
|
+
// Checked BEFORE falling through to raster. A bare-string design
|
|
123
|
+
// op is not a raster op, and reporting it as an unknown one was a
|
|
124
|
+
// false positive on documented usage: `{ op: "gradient" }` is on
|
|
125
|
+
// the gradient page, renders the default gradient, and validated
|
|
126
|
+
// as UNKNOWN_OP suggesting a raster op that would not do it.
|
|
127
|
+
if (BARE_DESIGN_OPS.includes(op)) return "design";
|
|
69
128
|
return "raster";
|
|
70
129
|
}
|
|
71
130
|
if (op && typeof op === "object" && typeof op.name === "string") return "design";
|
|
@@ -174,7 +233,53 @@ export function validateNodes(nodes, elements) {
|
|
|
174
233
|
|
|
175
234
|
checkTargets(node.target, `${path}.target`);
|
|
176
235
|
|
|
177
|
-
if (family === "design")
|
|
236
|
+
if (family === "design") {
|
|
237
|
+
// Was `return` — "design nodes carry their own vocabulary", which
|
|
238
|
+
// was true and yet left the whole family unchecked. The cost was
|
|
239
|
+
// paid in the reference: a design option written in the wrong
|
|
240
|
+
// place is not a no-op with a warning, it is a no-op in silence,
|
|
241
|
+
// and the gradient one made the target INVISIBLE. Checked here at
|
|
242
|
+
// the two levels the runtime actually reads.
|
|
243
|
+
const bare = typeof node.op === "string";
|
|
244
|
+
const name = bare ? node.op : node.op.name;
|
|
245
|
+
|
|
246
|
+
if (!bare && !DESIGN_OP_NAMES.includes(name)) {
|
|
247
|
+
push("UNKNOWN_DESIGN_OP", `${path}.op.name`, name,
|
|
248
|
+
suggest(name, DESIGN_OP_NAMES), DESIGN_OP_NAMES);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Top-level keys. The object form reads three; the bare-string
|
|
252
|
+
// form reads four more because its expansion lifts them into the
|
|
253
|
+
// op it substitutes.
|
|
254
|
+
const allowed = bare ? BARE_DESIGN_FIELDS : DESIGN_FIELDS;
|
|
255
|
+
for (const key in node) {
|
|
256
|
+
if (allowed.includes(key)) continue;
|
|
257
|
+
// A near miss of a real top-level field is a typo and gets
|
|
258
|
+
// the usual suggestion. Anything else, on the object form,
|
|
259
|
+
// is almost always an option written one level too high —
|
|
260
|
+
// design options live INSIDE `op` — so say where it goes
|
|
261
|
+
// rather than only listing what may sit out here. That is
|
|
262
|
+
// the whole of the README's `colors` mistake.
|
|
263
|
+
const near = suggest(key, allowed);
|
|
264
|
+
const hint = near.length || bare ? near : [`op.${key}`];
|
|
265
|
+
push("UNKNOWN_PARAM", `${path}.${key}`, key, hint, allowed);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// A gradient with nothing to paint. `op.gradient` is the CSS
|
|
269
|
+
// string and `op.direction: "radial"` substitutes a built-in
|
|
270
|
+
// one; with neither, the node names an effect that cannot
|
|
271
|
+
// happen. It renders as nothing since 1.2.7 and rendered as an
|
|
272
|
+
// invisible element before that, so it is worth a report either
|
|
273
|
+
// way. The bare-string form is exempt: its whole purpose is to
|
|
274
|
+
// take the default.
|
|
275
|
+
if (!bare && name === "gradient" &&
|
|
276
|
+
node.op.gradient === undefined && node.op.direction === undefined) {
|
|
277
|
+
push("MISSING_FIELD", `${path}.op.gradient`, undefined, [],
|
|
278
|
+
["a CSS gradient, e.g. \"linear-gradient(#1d6fe0, #7fd1ff)\"",
|
|
279
|
+
"or direction: \"radial\" to take the built-in one"]);
|
|
280
|
+
}
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
178
283
|
|
|
179
284
|
if (family === "agent-surface") {
|
|
180
285
|
// The ids this node names must exist, for the usual reason:
|
package/lib/webmcp-adapter.js
CHANGED
package/package.json
CHANGED
package/skills/nodality/SKILL.md
CHANGED
|
@@ -68,11 +68,19 @@ Told apart by the shape of `op`:
|
|
|
68
68
|
|
|
69
69
|
| Family | Shape | Example |
|
|
70
70
|
|---|---|---|
|
|
71
|
-
| Design | `op` is an object | `{ op: { name: "shadow" }, target: ["card"] }` |
|
|
72
|
-
| Raster | `op` is
|
|
71
|
+
| Design | `op` is an object, or one of seven shorthand strings | `{ op: { name: "shadow" }, target: ["card"] }` |
|
|
72
|
+
| Raster | `op` is any other string | `{ op: "dither", target: ["hero"], levels: 6 }` |
|
|
73
73
|
| Morph | `op: "morph"` | one transition, or a whole graph via `chain` |
|
|
74
74
|
| Agent surface | `op: "agent-surface"` | exposes the page to AI agents as tools |
|
|
75
75
|
|
|
76
|
+
**The design family has two shapes.** The object form takes its options
|
|
77
|
+
inside `op`. The seven shorthand names – `blast`, `gradient`, `shadow`,
|
|
78
|
+
`filter`, `animation`, `transform`, `span` – expand against a table of
|
|
79
|
+
defaults, so `{ op: "gradient" }` is a whole valid node. Only the
|
|
80
|
+
shorthand accepts `gradient`, `filter`, `color` and `width` as top-level
|
|
81
|
+
keys, because its expansion lifts them into the op it substitutes. Any
|
|
82
|
+
other string is a raster op.
|
|
83
|
+
|
|
76
84
|
Rules that are not obvious from the schema:
|
|
77
85
|
|
|
78
86
|
- **Raster ops compose.** Several raster nodes aimed at the same element
|
|
@@ -111,14 +119,17 @@ A complete navigation graph is one node:
|
|
|
111
119
|
- **Every element that a node targets needs an `id`.** Short and stable
|
|
112
120
|
(`"hero"`, `"topnav"`); ids are the joint between the two arrays and
|
|
113
121
|
appear in generated code.
|
|
114
|
-
- **
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
- **Know where options live.** Raster-op options sit on the node
|
|
123
|
+
(`levels: 6`); design-node options sit INSIDE the `op` object
|
|
124
|
+
(`op: { name: "gradient", gradient: "linear-gradient(...)" }`).
|
|
125
|
+
Putting a design option at the top level is the single most common
|
|
126
|
+
mistake with this library – the project's own README shipped
|
|
127
|
+
`colors: [...]` there and rendered its headline invisible. Since 1.2.7
|
|
128
|
+
`validate_nodes` reports it and tells you where it belongs, so run the
|
|
129
|
+
validator rather than trusting the shape by eye.
|
|
130
|
+
- **Do not invent options.** An option that no op declares is ignored in
|
|
131
|
+
silence rather than reported. If `list_ops` does not name it, it does
|
|
132
|
+
not exist.
|
|
122
133
|
- **Codegen:** the on-page panel showing the imperative equivalent of
|
|
123
134
|
the pair is on by default; pass `code: false` (and `elements: false`)
|
|
124
135
|
to `.set()` to hide it on a production page. From the CLI,
|