@adia-ai/web-modules 0.8.20 → 0.8.21
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.
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://adiaui.dev/a2ui/v0_9/components/FormPopover.json",
|
|
4
4
|
"title": "FormPopover",
|
|
5
|
-
"description": "Module-tier \"form fragment in a popover\" (operator mock, 2026-07-27): a\nselect-style summary trigger that opens an anchored panel holding ANY\nform primitives — check-ui groups, radio-ui groups, input-ui,\ndivider-ui, field-ui — slotted as ordinary light-DOM children. The\nmodule owns the trigger + popover packaging and a live selection\nsummary; the slotted controls keep their own name/value/event\ncontracts untouched.\n\nSummary contract
|
|
5
|
+
"description": "Module-tier \"form fragment in a popover\" (operator mock, 2026-07-27): a\nselect-style summary trigger that opens an anchored panel holding ANY\nform primitives — check-ui groups, radio-ui groups, input-ui,\ndivider-ui, field-ui — slotted as ordinary light-DOM children. The\nmodule owns the trigger + popover packaging and a live selection\nsummary; the slotted controls keep their own name/value/event\ncontracts untouched.\n\nSummary contract (gh#474 — identical to select-ui[summary-label], so the\ntwo multi-select triggers speak one language): none checked reads just\n`{label}` (which doubles as the placeholder, since [label] is required\nhere), exactly one reads THAT check-ui's own label, and more than one\nreads `{label} (N)`. Radio groups, inputs, and other controls\ndeliberately do not count — checkboxes are the only selection semantic\nthat reads unambiguously in a summary.\n\nDecision rule vs adjacent surfaces (inherits popover-ui's): a pure\naction list is menu-ui; a single-value choice is select-ui (which owns\nits option list — do NOT rebuild select inside this module); an\nedge-anchored multi-field form is drawer-ui. form-popover-ui is for the\nin-between: a small anchored fragment mixing selection controls and\ninputs, e.g. a filter panel or a quick-save form.\n",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"allOf": [
|
|
8
8
|
{
|
|
@@ -66,12 +66,16 @@ class FormPopover extends UIElement {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
/**
|
|
69
|
+
/**
|
|
70
|
+
* { selected, total, checked } over the slotted check-ui population.
|
|
71
|
+
* `checked` is the checked elements themselves — the summary needs the
|
|
72
|
+
* single-selection element to read its own label (gh#474).
|
|
73
|
+
*/
|
|
70
74
|
get summary() {
|
|
71
75
|
const boxes = this.#bodyEl ? this.#bodyEl.querySelectorAll('check-ui') : [];
|
|
72
|
-
|
|
73
|
-
for (const box of boxes) if (box.hasAttribute('checked') || box.checked)
|
|
74
|
-
return { selected, total: boxes.length };
|
|
76
|
+
const checked = [];
|
|
77
|
+
for (const box of boxes) if (box.hasAttribute('checked') || box.checked) checked.push(box);
|
|
78
|
+
return { selected: checked.length, total: boxes.length, checked };
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
#stamp() {
|
|
@@ -113,14 +117,23 @@ class FormPopover extends UIElement {
|
|
|
113
117
|
el.textContent = this.heading;
|
|
114
118
|
}
|
|
115
119
|
|
|
120
|
+
/** The own label of a slotted check-ui — [label] prop, else its text. */
|
|
121
|
+
#labelOf(box) {
|
|
122
|
+
return (box.getAttribute('label') || box.label || box.textContent || '').trim();
|
|
123
|
+
}
|
|
124
|
+
|
|
116
125
|
#updateSummary() {
|
|
117
126
|
if (!this.#triggerEl) return;
|
|
118
|
-
const { selected, total } = this.summary;
|
|
127
|
+
const { selected, total, checked } = this.summary;
|
|
128
|
+
// gh#474 — ONE summary contract across the two multi-select triggers:
|
|
129
|
+
// none → the label alone (it doubles as select-ui's placeholder, since
|
|
130
|
+
// [label] is required here), one → that control's own label, more →
|
|
131
|
+
// "Label (N)". Was "Label · N selected", which contradicted
|
|
132
|
+
// select-ui[summary-label]'s ruled format (gh#442) and blocked
|
|
133
|
+
// consumers from swapping a hand-rolled composition for this module.
|
|
119
134
|
let text = this.label;
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
text = text ? `${text} · ${count}` : count;
|
|
123
|
-
}
|
|
135
|
+
if (selected === 1 && checked[0]) text = this.#labelOf(checked[0]) || text;
|
|
136
|
+
else if (selected > 1) text = text ? `${text} (${selected})` : `${selected}`;
|
|
124
137
|
// [label] is required by contract; this fallback only guards the
|
|
125
138
|
// no-label + no-checkbox misuse so the trigger never renders as an
|
|
126
139
|
// empty, nameless button (a11y — CodeRabbit finding on #441).
|
|
@@ -15,12 +15,13 @@ description: |
|
|
|
15
15
|
summary; the slotted controls keep their own name/value/event
|
|
16
16
|
contracts untouched.
|
|
17
17
|
|
|
18
|
-
Summary contract
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
check-ui
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
Summary contract (gh#474 — identical to select-ui[summary-label], so the
|
|
19
|
+
two multi-select triggers speak one language): none checked reads just
|
|
20
|
+
`{label}` (which doubles as the placeholder, since [label] is required
|
|
21
|
+
here), exactly one reads THAT check-ui's own label, and more than one
|
|
22
|
+
reads `{label} (N)`. Radio groups, inputs, and other controls
|
|
23
|
+
deliberately do not count — checkboxes are the only selection semantic
|
|
24
|
+
that reads unambiguously in a summary.
|
|
24
25
|
|
|
25
26
|
Decision rule vs adjacent surfaces (inherits popover-ui's): a pure
|
|
26
27
|
action list is menu-ui; a single-value choice is select-ui (which owns
|
|
@@ -97,12 +98,13 @@ a2ui:
|
|
|
97
98
|
small MIXED fragment (checks + radios + an input) behind a summary
|
|
98
99
|
trigger.
|
|
99
100
|
- >-
|
|
100
|
-
The trigger summary counts CheckBox children only
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
The trigger summary counts CheckBox children only — one checked
|
|
102
|
+
shows its own label, more show "Label (N)", none shows the bare
|
|
103
|
+
label (same contract as Select[summary-label]); Radio and Input
|
|
104
|
+
children never count. Give every Radio child one shared name per
|
|
105
|
+
group or the browser treats them as independent.
|
|
104
106
|
props:
|
|
105
|
-
label: { type: string, description: "Summary-trigger prefix
|
|
107
|
+
label: { type: string, description: "Summary-trigger text — shown alone when nothing is checked (its placeholder role) and as the \"Label (N)\" prefix when more than one is" }
|
|
106
108
|
heading: { type: string, description: "Optional panel heading" }
|
|
107
109
|
placement: { type: string, description: "Popover placement (default bottom-start)" }
|
|
108
110
|
children: form primitives (CheckBox, Radio, Input, Divider, Field)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/web-modules",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.21",
|
|
4
4
|
"description": "AdiaUI composite custom elements \u2014 shell, chat, editor, runtime clusters built from @adia-ai/web-components primitives. Subpath exports per cluster.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|