nodality 1.3.1 → 1.3.2
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.LICENSE.txt +1 -1
- package/dist/animator.esm.js.LICENSE.txt +1 -1
- package/dist/audionew.cjs.js.LICENSE.txt +1 -1
- package/dist/audionew.esm.js.LICENSE.txt +1 -1
- package/dist/base.cjs.js.LICENSE.txt +1 -1
- package/dist/base.esm.js.LICENSE.txt +1 -1
- package/dist/beta-desktop-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/beta-desktop-bar.esm.js.LICENSE.txt +1 -1
- package/dist/beta-mobile-bar.cjs.js.LICENSE.txt +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.LICENSE.txt +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.LICENSE.txt +1 -1
- package/dist/center.esm.js.LICENSE.txt +1 -1
- package/dist/checkbox.cjs.js.LICENSE.txt +1 -1
- package/dist/checkbox.esm.js.LICENSE.txt +1 -1
- package/dist/code.cjs.js.LICENSE.txt +1 -1
- package/dist/code.esm.js.LICENSE.txt +1 -1
- package/dist/container.cjs.js.LICENSE.txt +1 -1
- package/dist/container.esm.js.LICENSE.txt +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.LICENSE.txt +1 -1
- package/dist/flex-card.esm.js.LICENSE.txt +1 -1
- package/dist/flex-grid.cjs.js.LICENSE.txt +1 -1
- package/dist/flex-grid.esm.js.LICENSE.txt +1 -1
- package/dist/flex-row.cjs.js.LICENSE.txt +1 -1
- package/dist/flex-row.esm.js.LICENSE.txt +1 -1
- package/dist/floating-input.cjs.js.LICENSE.txt +1 -1
- package/dist/floating-input.esm.js.LICENSE.txt +1 -1
- package/dist/free.cjs.js.LICENSE.txt +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.LICENSE.txt +1 -1
- package/dist/image-picker.esm.js.LICENSE.txt +1 -1
- package/dist/image.cjs.js.LICENSE.txt +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.LICENSE.txt +1 -1
- package/dist/link-getter.esm.js.LICENSE.txt +1 -1
- package/dist/link.cjs.js.LICENSE.txt +1 -1
- package/dist/link.esm.js.LICENSE.txt +1 -1
- package/dist/meta-adder.cjs.js.LICENSE.txt +1 -1
- package/dist/meta-adder.esm.js.LICENSE.txt +1 -1
- package/dist/modal-2025.cjs.js.LICENSE.txt +1 -1
- package/dist/modal-2025.esm.js.LICENSE.txt +1 -1
- package/dist/multiswitcher.cjs.js.LICENSE.txt +1 -1
- package/dist/multiswitcher.esm.js.LICENSE.txt +1 -1
- package/dist/new-nav-bar.cjs.js.LICENSE.txt +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.LICENSE.txt +1 -1
- package/dist/progress.esm.js.LICENSE.txt +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.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.LICENSE.txt +1 -1
- package/dist/side-bar.esm.js.LICENSE.txt +1 -1
- package/dist/side-nav-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/side-nav-bar.esm.js.LICENSE.txt +1 -1
- package/dist/simple-bar.cjs.js.LICENSE.txt +1 -1
- package/dist/simple-bar.esm.js.LICENSE.txt +1 -1
- package/dist/slider-2025.cjs.js.LICENSE.txt +1 -1
- package/dist/slider-2025.esm.js.LICENSE.txt +1 -1
- package/dist/spacer.cjs.js.LICENSE.txt +1 -1
- package/dist/spacer.esm.js.LICENSE.txt +1 -1
- package/dist/stack.cjs.js.LICENSE.txt +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.LICENSE.txt +1 -1
- package/dist/table.esm.js.LICENSE.txt +1 -1
- package/dist/text-field.cjs.js.LICENSE.txt +1 -1
- package/dist/text-field.esm.js.LICENSE.txt +1 -1
- package/dist/text.cjs.js.LICENSE.txt +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.LICENSE.txt +1 -1
- package/dist/ulist.esm.js.LICENSE.txt +1 -1
- package/dist/video.cjs.js.LICENSE.txt +1 -1
- package/dist/video.esm.js.LICENSE.txt +1 -1
- package/dist/wrap.cjs.js.LICENSE.txt +1 -1
- package/dist/wrap.esm.js.LICENSE.txt +1 -1
- package/dist/zoom-card.cjs.js.LICENSE.txt +1 -1
- package/dist/zoom-card.esm.js.LICENSE.txt +1 -1
- package/layout/animator.js +1 -1
- 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 +37 -2
- 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/check-page.js +45 -5
- 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/element-params.generated.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/normalize-spec.js +1 -1
- package/lib/parse-html.js +1 -1
- package/lib/raster-inspect.js +1 -1
- package/lib/raster-ops.js +1 -1
- package/lib/raster-presets.js +1 -1
- package/lib/resolve-refs.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 +1 -1
- package/lib/webmcp-adapter.js +71 -6
- package/package.json +1 -1
- package/schema.json +7 -0
package/layout/circle.js
CHANGED
package/layout/code.js
CHANGED
package/layout/container.js
CHANGED
package/layout/dropdown-2025.js
CHANGED
package/layout/flex-card.js
CHANGED
package/layout/flex-grid.js
CHANGED
package/layout/flex-row.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* nodality v1.3.
|
|
2
|
+
* nodality v1.3.2
|
|
3
3
|
* (c) 2026 Filip Vabrousek
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -52,7 +52,26 @@ class Picker extends Animator {
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
for (var i = 0; i < obj.length; i++){
|
|
55
|
-
|
|
55
|
+
// An item is a [value, text] PAIR, or a plain string that is
|
|
56
|
+
// both. The string form was not handled and did not fail: a
|
|
57
|
+
// string is indexable, so `obj[i][0]` and `obj[i][1]` were its
|
|
58
|
+
// first two CHARACTERS. `items: ["Sales", "Support"]` rendered
|
|
59
|
+
// two options both valued "S", reading "a" and "u".
|
|
60
|
+
//
|
|
61
|
+
// It stayed hidden because the two halves of the library
|
|
62
|
+
// disagreed in opposite directions. `deriveSurface` builds a
|
|
63
|
+
// picker's enum from `items.filter(i => typeof i === "string")`
|
|
64
|
+
// — it requires the STRING form, and a unit test pins it — while
|
|
65
|
+
// this loop required the PAIR form, so no value of `items`
|
|
66
|
+
// satisfied both. The agent-facing manifest therefore advertised
|
|
67
|
+
// `enum: ["Sales", "Support"]` over a control whose only
|
|
68
|
+
// selectable values were "S" and "S", and an agent submitting
|
|
69
|
+
// "Sales" had the field silently dropped from the payload.
|
|
70
|
+
const it = obj[i];
|
|
71
|
+
const pair = (typeof it === "string" || typeof it === "number")
|
|
72
|
+
? [String(it), String(it)]
|
|
73
|
+
: [it && it[0], it && it[1]];
|
|
74
|
+
card.appendChild(this.addNode(pair[0], pair[1]));
|
|
56
75
|
}
|
|
57
76
|
|
|
58
77
|
/*card.appendChild(this.addNode("audi", "Audi"));
|
|
@@ -80,6 +99,22 @@ class Picker extends Animator {
|
|
|
80
99
|
obj.radius && (this.el.style.borderRadius = obj.radius);
|
|
81
100
|
obj.background && (this.el.style.background = obj.background);
|
|
82
101
|
|
|
102
|
+
// A <select> with no adjacent text has no accessible name, and this
|
|
103
|
+
// component had no way to be given one. `label` already reached here
|
|
104
|
+
// — `elOpts` forwards it — and nothing read it, so every picker on
|
|
105
|
+
// every page reported CONTROL_WITHOUT_LABEL from `check_page` and the
|
|
106
|
+
// finding was UNREPAIRABLE through the descriptor vocabulary: there
|
|
107
|
+
// was no spelling of the fix. Declared and ignored, which is the
|
|
108
|
+
// failure this library spent six stages removing.
|
|
109
|
+
//
|
|
110
|
+
// `label` is the accessible name here, as it is on `input`; `title`
|
|
111
|
+
// is accepted too, since FloatingInput calls it that and a caller
|
|
112
|
+
// moving between the two form types should not have to notice.
|
|
113
|
+
const named = obj.label !== undefined ? obj.label : obj.title;
|
|
114
|
+
if (named !== undefined && named !== null && !this.el.getAttribute("aria-label")) {
|
|
115
|
+
this.el.setAttribute("aria-label", String(named));
|
|
116
|
+
}
|
|
117
|
+
|
|
83
118
|
// Same dispatch Text and Wrapper use, so a Picker can be given a
|
|
84
119
|
// border, height, font size or cursor through set() instead of the
|
|
85
120
|
// caller styling the <select> by hand.
|
package/layout/free.js
CHANGED
package/layout/grid-switcher.js
CHANGED
package/layout/grid.js
CHANGED
package/layout/image.js
CHANGED
package/layout/index.js
CHANGED
package/layout/link.js
CHANGED
package/layout/list.js
CHANGED
package/layout/meta-adder.js
CHANGED
package/layout/modal-2025.js
CHANGED
package/layout/morph.js
CHANGED
package/layout/multiswitcher.js
CHANGED
package/layout/nav-bar.js
CHANGED
package/layout/new-nav-bar.js
CHANGED
package/layout/polygon.js
CHANGED
package/layout/prerender-site.js
CHANGED
package/layout/prerender.js
CHANGED
package/layout/progress.js
CHANGED
package/layout/row.js
CHANGED
package/layout/scroll-video.js
CHANGED
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/check-page.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* nodality v1.3.
|
|
2
|
+
* nodality v1.3.2
|
|
3
3
|
* (c) 2026 Filip Vabrousek
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -100,6 +100,32 @@ const IN_PAGE = () => {
|
|
|
100
100
|
});
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
+
/**
|
|
104
|
+
* A name assistive technology can announce.
|
|
105
|
+
*
|
|
106
|
+
* Was `aria-label` alone, which is only one of the four ways to give one
|
|
107
|
+
* and the least used. A control correctly labelled by a `<label for>` —
|
|
108
|
+
* the ordinary HTML way — was reported as unnamed, and a false finding
|
|
109
|
+
* sends a repair at something that was never broken, which this file
|
|
110
|
+
* argues elsewhere is worse than a miss.
|
|
111
|
+
*/
|
|
112
|
+
const hasName = (el) => {
|
|
113
|
+
if ((el.getAttribute("aria-label") || "").trim()) return true;
|
|
114
|
+
if ((el.getAttribute("title") || "").trim()) return true;
|
|
115
|
+
const by = (el.getAttribute("aria-labelledby") || "").trim();
|
|
116
|
+
if (by && by.split(/\s+/).some((id) => {
|
|
117
|
+
const t = document.getElementById(id);
|
|
118
|
+
return t && (t.textContent || "").trim();
|
|
119
|
+
})) return true;
|
|
120
|
+
if (el.id) {
|
|
121
|
+
const l = document.querySelector(`label[for="${CSS.escape(el.id)}"]`);
|
|
122
|
+
if (l && (l.textContent || "").trim()) return true;
|
|
123
|
+
}
|
|
124
|
+
const wrap = el.closest && el.closest("label");
|
|
125
|
+
if (wrap && (wrap.textContent || "").trim()) return true;
|
|
126
|
+
return false;
|
|
127
|
+
};
|
|
128
|
+
|
|
103
129
|
const all = [...document.body.querySelectorAll("*")];
|
|
104
130
|
const vw = window.innerWidth;
|
|
105
131
|
|
|
@@ -143,16 +169,30 @@ const IN_PAGE = () => {
|
|
|
143
169
|
}
|
|
144
170
|
|
|
145
171
|
// 5. A target too small to hit. 24px is the WCAG 2.2 AA minimum.
|
|
172
|
+
//
|
|
173
|
+
// `select` and `textarea` were both missing from this set, so neither
|
|
174
|
+
// check below ever ran on one. A picker could not be given an
|
|
175
|
+
// accessible name at all — `label` reached the component and nothing
|
|
176
|
+
// read it — and no report said so, because the checker was not
|
|
177
|
+
// looking. Two blind spots that hid each other.
|
|
146
178
|
const interactive = tag === "a" || tag === "button" ||
|
|
147
|
-
(tag === "input" && el.type !== "hidden") ||
|
|
179
|
+
(tag === "input" && el.type !== "hidden") ||
|
|
180
|
+
tag === "select" || tag === "textarea" ||
|
|
181
|
+
el.getAttribute("role") === "button";
|
|
148
182
|
if (interactive && r.width > 0 && (r.width < 24 || r.height < 24)) {
|
|
149
183
|
add("TAP_TARGET_TOO_SMALL", el, `${Math.round(r.width)}x${Math.round(r.height)}`,
|
|
150
184
|
"below the 24x24 minimum");
|
|
151
185
|
}
|
|
152
186
|
|
|
153
187
|
// 6. A control with nothing to announce.
|
|
154
|
-
|
|
155
|
-
|
|
188
|
+
//
|
|
189
|
+
// A <select>'s own text is its OPTIONS and a <textarea>'s is its
|
|
190
|
+
// VALUE. Neither names the control, so the textContent shortcut that
|
|
191
|
+
// clears a button by its caption must not clear these.
|
|
192
|
+
const ownText = (tag === "select" || tag === "textarea")
|
|
193
|
+
? "" : (el.textContent || "").trim();
|
|
194
|
+
if (interactive && !ownText && !hasName(el) &&
|
|
195
|
+
!el.querySelector("img[alt]:not([alt=''])")) {
|
|
156
196
|
add("CONTROL_WITHOUT_LABEL", el, tag, "no text and no accessible name");
|
|
157
197
|
}
|
|
158
198
|
}
|
|
@@ -235,7 +275,7 @@ const REPAIRS = {
|
|
|
235
275
|
valid: ["at least 24x24 CSS pixels, per WCAG 2.2 AA target size (minimum)"],
|
|
236
276
|
},
|
|
237
277
|
CONTROL_WITHOUT_LABEL: {
|
|
238
|
-
suggestions: [`label: "<what the field is for>" (labelInput)`,
|
|
278
|
+
suggestions: [`label: "<what the field is for>" (input, labelInput, picker)`,
|
|
239
279
|
`text: "<what the control does>" (button, a)`],
|
|
240
280
|
valid: ["every control needs a name assistive technology can announce; " +
|
|
241
281
|
"a placeholder is not one"],
|
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