@adia-ai/web-modules 0.8.39 → 0.8.41
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/CHANGELOG.md +37 -0
- package/README.md +6 -6
- package/agent-admin/admin-roster/admin-roster.a2ui.json +1 -0
- package/agent-admin/admin-roster/admin-roster.css +10 -2
- package/agent-admin/admin-roster/admin-roster.js +70 -22
- package/agent-admin/admin-settings/admin-settings.a2ui.json +1 -0
- package/agent-admin/agent-admin/agent-admin.a2ui.json +1 -0
- package/billing/billing-overview/billing-overview.a2ui.json +10 -1
- package/billing/billing-overview/billing-overview.class.js +142 -73
- package/billing/billing-overview/billing-overview.css +70 -57
- package/billing/billing-overview/billing-overview.yaml +5 -0
- package/billing/invoice-detail/invoice-detail.a2ui.json +9 -4
- package/billing/invoice-detail/invoice-detail.class.js +22 -5
- package/billing/invoice-detail/invoice-detail.yaml +9 -4
- package/billing/invoice-history/invoice-history.a2ui.json +7 -4
- package/billing/invoice-history/invoice-history.class.js +45 -12
- package/billing/invoice-history/invoice-history.css +18 -15
- package/billing/invoice-history/invoice-history.yaml +10 -4
- package/billing/payment-method-form/payment-method-form.a2ui.json +1 -0
- package/billing/payment-method-form/payment-method-form.class.js +3 -3
- package/billing/payment-method-form/payment-method-form.css +4 -4
- package/billing/payment-method-list/payment-method-list.a2ui.json +4 -0
- package/billing/payment-method-list/payment-method-list.class.js +31 -11
- package/billing/payment-method-list/payment-method-list.css +13 -10
- package/billing/payment-method-list/payment-method-list.yaml +3 -0
- package/billing/plan-picker/plan-picker.a2ui.json +6 -0
- package/billing/plan-picker/plan-picker.class.js +70 -22
- package/billing/plan-picker/plan-picker.css +21 -38
- package/billing/plan-picker/plan-picker.yaml +5 -0
- package/chat/chat-composer/chat-composer.a2ui.json +1 -0
- package/chat/chat-empty/chat-empty.a2ui.json +4 -0
- package/chat/chat-empty/chat-empty.yaml +2 -0
- package/chat/chat-header/chat-header.a2ui.json +5 -0
- package/chat/chat-header/chat-header.yaml +3 -0
- package/chat/chat-shell/chat-shell.a2ui.json +4 -0
- package/chat/chat-shell/chat-shell.yaml +2 -0
- package/chat/chat-shell/css/chat-shell.tokens.css +1 -1
- package/chat/chat-sidebar/chat-sidebar.a2ui.json +4 -0
- package/chat/chat-sidebar/chat-sidebar.yaml +2 -0
- package/chat/chat-status/chat-status.a2ui.json +4 -0
- package/chat/chat-status/chat-status.yaml +2 -0
- package/chat/chat-thread/chat-thread.a2ui.json +4 -0
- package/chat/chat-thread/chat-thread.yaml +2 -0
- package/dashboard/dashboard-layout/dashboard-layout.a2ui.json +8 -8
- package/dashboard/dashboard-layout/dashboard-layout.css +4 -4
- package/dashboard/dashboard-layout/dashboard-layout.js +10 -9
- package/dashboard/dashboard-layout/dashboard-layout.yaml +19 -7
- package/dashboard/date-range-selector/date-range-selector.a2ui.json +4 -3
- package/dashboard/date-range-selector/date-range-selector.yaml +6 -4
- package/dist/chat/chat-shell.min.css +1 -1
- package/dist/chat/chat-shell.min.js +25 -25
- package/dist/editor/editor-shell.min.js +3 -3
- package/dist/everything.min.js +118 -131
- package/dist/shell/admin-shell.min.css +1 -1
- package/dist/shell/admin-shell.min.js +6 -6
- package/dist/simple/simple-shell.min.js +5 -5
- package/dist/web-modules.min.css +1 -1
- package/dist/web-modules.sheet.js +1 -1
- package/editor/editor-canvas/editor-canvas.a2ui.json +4 -0
- package/editor/editor-canvas/editor-canvas.yaml +2 -0
- package/editor/editor-canvas-empty/editor-canvas-empty.a2ui.json +4 -0
- package/editor/editor-canvas-empty/editor-canvas-empty.yaml +2 -0
- package/editor/editor-canvas-toolbar/editor-canvas-toolbar.a2ui.json +4 -0
- package/editor/editor-canvas-toolbar/editor-canvas-toolbar.yaml +2 -0
- package/editor/editor-shell/editor-shell.a2ui.json +5 -0
- package/editor/editor-shell/editor-shell.yaml +3 -0
- package/editor/editor-sidebar/editor-sidebar.a2ui.json +4 -0
- package/editor/editor-sidebar/editor-sidebar.yaml +2 -0
- package/editor/editor-statusbar/editor-statusbar.a2ui.json +4 -0
- package/editor/editor-statusbar/editor-statusbar.yaml +2 -0
- package/editor/editor-toolbar/editor-toolbar.a2ui.json +4 -0
- package/editor/editor-toolbar/editor-toolbar.yaml +2 -0
- package/feedback/confirm-dialog/confirm-dialog.a2ui.json +1 -0
- package/form/form-popover/form-popover.a2ui.json +1 -0
- package/onboarding/onboarding-checklist/onboarding-checklist.a2ui.json +2 -1
- package/onboarding/onboarding-checklist/onboarding-checklist.js +2 -2
- package/onboarding/onboarding-checklist/onboarding-checklist.yaml +1 -1
- package/package.json +6 -6
- package/runtime/a2ui-root/a2ui-root.a2ui.json +6 -5
- package/runtime/a2ui-root/a2ui-root.css +75 -0
- package/runtime/a2ui-root/a2ui-root.js +118 -10
- package/runtime/a2ui-root/a2ui-root.yaml +7 -2
- package/runtime/gen-root/gen-root.a2ui.json +6 -5
- package/runtime/gen-root/gen-root.yaml +10 -2
- package/settings/integrations-page/integrations-page.a2ui.json +3 -2
- package/settings/integrations-page/integrations-page.js +8 -8
- package/settings/integrations-page/integrations-page.yaml +2 -2
- package/settings/notification-preferences/notification-preferences.a2ui.json +1 -0
- package/shell/admin-command/admin-command.a2ui.json +5 -1
- package/shell/admin-command/admin-command.yaml +3 -1
- package/shell/admin-content/admin-content.a2ui.json +4 -0
- package/shell/admin-content/admin-content.yaml +2 -0
- package/shell/admin-entity-item/admin-entity-item.a2ui.json +1 -0
- package/shell/admin-page/admin-page.a2ui.json +5 -0
- package/shell/admin-page/admin-page.yaml +3 -0
- package/shell/admin-page-body/admin-page-body.a2ui.json +4 -0
- package/shell/admin-page-body/admin-page-body.yaml +2 -0
- package/shell/admin-page-footer/admin-page-footer.a2ui.json +4 -0
- package/shell/admin-page-footer/admin-page-footer.yaml +2 -0
- package/shell/admin-page-header/admin-page-header.a2ui.json +4 -0
- package/shell/admin-page-header/admin-page-header.yaml +2 -0
- package/shell/admin-scroll/admin-scroll.a2ui.json +4 -0
- package/shell/admin-scroll/admin-scroll.yaml +2 -0
- package/shell/admin-shell/admin-shell.a2ui.json +7 -3
- package/shell/admin-shell/admin-shell.yaml +3 -1
- package/shell/admin-shell/css/admin-shell.sidebar.css +2 -2
- package/shell/admin-sidebar/admin-sidebar.a2ui.json +4 -0
- package/shell/admin-sidebar/admin-sidebar.yaml +2 -0
- package/shell/admin-statusbar/admin-statusbar.a2ui.json +6 -0
- package/shell/admin-statusbar/admin-statusbar.yaml +4 -0
- package/shell/admin-topbar/admin-topbar.a2ui.json +6 -0
- package/shell/admin-topbar/admin-topbar.yaml +4 -0
- package/shell/embed-shell/embed-shell.a2ui.json +1 -0
- package/simple/simple-content/simple-content.a2ui.json +4 -0
- package/simple/simple-content/simple-content.yaml +2 -0
- package/simple/simple-hero/simple-hero.a2ui.json +4 -0
- package/simple/simple-hero/simple-hero.yaml +2 -0
- package/simple/simple-shell/simple-shell.a2ui.json +4 -0
- package/simple/simple-shell/simple-shell.yaml +2 -0
- package/theme/theme-panel/theme-panel.a2ui.json +1 -0
|
@@ -5,15 +5,25 @@
|
|
|
5
5
|
* marketing pricing page (SPEC-012). Each plan card is composed from
|
|
6
6
|
* <option-card-ui> (radio semantics) decorated with a price block,
|
|
7
7
|
* feature list, and CTA button derived from the plan record. The
|
|
8
|
-
* optional cycle toggle is a <
|
|
9
|
-
*
|
|
8
|
+
* optional cycle toggle is a <field-ui label="Billing interval">
|
|
9
|
+
* wrapping a <segmented-ui> — the canonical billing-interval chain
|
|
10
|
+
* from apps/saas/app/billing/billing.contents.html — that swaps
|
|
11
|
+
* monthly / annual prices in place across every card.
|
|
12
|
+
*
|
|
13
|
+
* Internal layout composes the framework layout primitives (gh#1519):
|
|
14
|
+
* the plans host is a <grid-ui columns="auto-fit">, each card body is
|
|
15
|
+
* a <col-ui> of <row-ui data-price-row> + <divider-ui> + a
|
|
16
|
+
* <col-ui data-features> of <row-ui> feature lines — mirroring the
|
|
17
|
+
* canonical's col-ui/row-ui feature-list grammar instead of raw
|
|
18
|
+
* div/ul/li.
|
|
10
19
|
*
|
|
11
20
|
* SPEC: .claude/docs/specs/implementation-ready/SPEC-011-plan-picker-in-app-upgrade.md
|
|
12
21
|
* WAI-APG: https://www.w3.org/WAI/ARIA/apg/patterns/radio/
|
|
13
22
|
*
|
|
14
23
|
* Architecture (light-DOM, ADR-0033):
|
|
15
|
-
* This composite stamps a
|
|
16
|
-
* [data-toggle] · [data-
|
|
24
|
+
* This composite stamps a region skeleton once on first connect:
|
|
25
|
+
* [data-toggle] · [data-toggle-divider] · [data-plans] ·
|
|
26
|
+
* [data-skeleton] · [data-empty]
|
|
17
27
|
* Then mutates per-card DOM by id-keyed in-place diff on every
|
|
18
28
|
* `plans` / `value` / `current` / `cycle` change. The diff preserves
|
|
19
29
|
* focus-within during re-render (replacing children would break the
|
|
@@ -116,8 +126,10 @@ export class PlanPicker extends UIFormElement {
|
|
|
116
126
|
#stamped = false;
|
|
117
127
|
#cleanups = [];
|
|
118
128
|
#toggleHost = null; // <div data-toggle> wrapper
|
|
119
|
-
#
|
|
120
|
-
#
|
|
129
|
+
#toggleField = null; // <field-ui> inside toggle host (canonical chain)
|
|
130
|
+
#toggleSegmented = null; // <segmented-ui> inside the field
|
|
131
|
+
#toggleDivider = null; // <divider-ui data-toggle-divider> after the toggle
|
|
132
|
+
#plansHost = null; // <grid-ui data-plans role=presentation>
|
|
121
133
|
#skeletonHost = null; // <div data-skeleton>
|
|
122
134
|
#emptyHost = null; // <empty-state-ui data-empty>
|
|
123
135
|
#cardsById = new Map(); // id → <option-card-ui>
|
|
@@ -285,10 +297,11 @@ export class PlanPicker extends UIFormElement {
|
|
|
285
297
|
this.removeAttribute('empty');
|
|
286
298
|
}
|
|
287
299
|
|
|
288
|
-
// Toggle visibility / contents.
|
|
300
|
+
// Toggle visibility / contents (divider tracks the toggle).
|
|
289
301
|
if (this.#toggleHost) {
|
|
290
302
|
const show = this.cycleToggle && plans.length > 0;
|
|
291
303
|
this.#toggleHost.hidden = !show;
|
|
304
|
+
if (this.#toggleDivider) this.#toggleDivider.hidden = !show;
|
|
292
305
|
if (show) this.#renderToggle();
|
|
293
306
|
}
|
|
294
307
|
|
|
@@ -321,12 +334,24 @@ export class PlanPicker extends UIFormElement {
|
|
|
321
334
|
this.appendChild(toggle);
|
|
322
335
|
this.#toggleHost = toggle;
|
|
323
336
|
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
//
|
|
328
|
-
const
|
|
337
|
+
// Divider between the interval toggle and the plan list — the
|
|
338
|
+
// canonical change-plan grammar separates the two groups with a
|
|
339
|
+
// <divider-ui> (billing.contents.html drawer). Visible only when
|
|
340
|
+
// the toggle is.
|
|
341
|
+
const toggleDivider = document.createElement('divider-ui');
|
|
342
|
+
toggleDivider.setAttribute('data-toggle-divider', '');
|
|
343
|
+
toggleDivider.hidden = true;
|
|
344
|
+
this.appendChild(toggleDivider);
|
|
345
|
+
this.#toggleDivider = toggleDivider;
|
|
346
|
+
|
|
347
|
+
// Plans host — a <grid-ui> (the framework grid primitive; the
|
|
348
|
+
// [layout] mode overrides its columns via plan-picker.css) that
|
|
349
|
+
// the option-card-ui kids live in as DIRECT children. We give it
|
|
350
|
+
// role="presentation" because the OUTER host already carries
|
|
351
|
+
// role="radiogroup" and nesting two radiogroups would confuse AT.
|
|
352
|
+
const plansHost = document.createElement('grid-ui');
|
|
329
353
|
plansHost.setAttribute('data-plans', '');
|
|
354
|
+
plansHost.setAttribute('columns', 'auto-fit');
|
|
330
355
|
plansHost.setAttribute('role', 'presentation');
|
|
331
356
|
this.appendChild(plansHost);
|
|
332
357
|
this.#plansHost = plansHost;
|
|
@@ -354,9 +379,16 @@ export class PlanPicker extends UIFormElement {
|
|
|
354
379
|
if (!this.#toggleHost) return;
|
|
355
380
|
let seg = this.#toggleSegmented;
|
|
356
381
|
if (!seg) {
|
|
382
|
+
// Canonical billing-interval chain: <field-ui label="Billing
|
|
383
|
+
// interval"> wrapping the <segmented-ui> (billing.contents.html
|
|
384
|
+
// "Current plan" region).
|
|
385
|
+
const field = document.createElement('field-ui');
|
|
386
|
+
field.setAttribute('label', 'Billing interval');
|
|
357
387
|
seg = document.createElement('segmented-ui');
|
|
358
388
|
seg.setAttribute('aria-label', 'Billing cycle');
|
|
359
|
-
|
|
389
|
+
field.appendChild(seg);
|
|
390
|
+
this.#toggleHost.appendChild(field);
|
|
391
|
+
this.#toggleField = field;
|
|
360
392
|
this.#toggleSegmented = seg;
|
|
361
393
|
// Stamp segments — known cycles in display order.
|
|
362
394
|
for (const cycleKey of ['monthly', 'annual']) {
|
|
@@ -443,8 +475,9 @@ export class PlanPicker extends UIFormElement {
|
|
|
443
475
|
// bodies show always.
|
|
444
476
|
let body = card.querySelector(':scope > [data-plan-body]');
|
|
445
477
|
if (!body) {
|
|
446
|
-
body = document.createElement('
|
|
478
|
+
body = document.createElement('col-ui');
|
|
447
479
|
body.setAttribute('data-plan-body', '');
|
|
480
|
+
body.setAttribute('gap', '3');
|
|
448
481
|
card.appendChild(body);
|
|
449
482
|
}
|
|
450
483
|
this.#decorateBody(body, plan);
|
|
@@ -478,9 +511,11 @@ export class PlanPicker extends UIFormElement {
|
|
|
478
511
|
// Wipe + restamp body (small DOM; cycle / feature-list / cta).
|
|
479
512
|
body.replaceChildren();
|
|
480
513
|
|
|
481
|
-
// Price row.
|
|
482
|
-
const priceRow = document.createElement('
|
|
514
|
+
// Price row — <row-ui> per the canonical inline-cluster grammar.
|
|
515
|
+
const priceRow = document.createElement('row-ui');
|
|
483
516
|
priceRow.setAttribute('data-price-row', '');
|
|
517
|
+
priceRow.setAttribute('gap', '1');
|
|
518
|
+
priceRow.setAttribute('align', 'baseline');
|
|
484
519
|
const cycle = KNOWN_CYCLES.has(this.cycle) ? this.cycle : 'monthly';
|
|
485
520
|
const prices = plan.prices || {};
|
|
486
521
|
const priceRec = prices[cycle] || prices.monthly || null;
|
|
@@ -513,20 +548,33 @@ export class PlanPicker extends UIFormElement {
|
|
|
513
548
|
body.appendChild(note);
|
|
514
549
|
}
|
|
515
550
|
|
|
516
|
-
// Feature list
|
|
551
|
+
// Feature list — the canonical feature-line grammar:
|
|
552
|
+
// <col-ui gap="1"> of <row-ui gap="2"><icon-ui/><span/></row-ui>
|
|
553
|
+
// (billing.contents.html trial-banner / what's-included blocks),
|
|
554
|
+
// separated from the price block by a <divider-ui>.
|
|
517
555
|
if (Array.isArray(plan.features) && plan.features.length) {
|
|
518
|
-
const
|
|
556
|
+
const divider = document.createElement('divider-ui');
|
|
557
|
+
divider.setAttribute('data-body-divider', '');
|
|
558
|
+
body.appendChild(divider);
|
|
559
|
+
|
|
560
|
+
const list = document.createElement('col-ui');
|
|
519
561
|
list.setAttribute('data-features', '');
|
|
562
|
+
list.setAttribute('gap', '1');
|
|
563
|
+
list.setAttribute('role', 'list');
|
|
520
564
|
for (const feature of plan.features) {
|
|
521
|
-
const
|
|
565
|
+
const line = document.createElement('row-ui');
|
|
566
|
+
line.setAttribute('data-feature', '');
|
|
567
|
+
line.setAttribute('gap', '2');
|
|
568
|
+
line.setAttribute('align', 'start');
|
|
569
|
+
line.setAttribute('role', 'listitem');
|
|
522
570
|
const icon = document.createElement('icon-ui');
|
|
523
571
|
icon.setAttribute('name', 'check');
|
|
524
572
|
icon.setAttribute('aria-hidden', 'true');
|
|
525
|
-
|
|
573
|
+
line.appendChild(icon);
|
|
526
574
|
const label = document.createElement('span');
|
|
527
575
|
label.textContent = String(feature);
|
|
528
|
-
|
|
529
|
-
list.appendChild(
|
|
576
|
+
line.appendChild(label);
|
|
577
|
+
list.appendChild(line);
|
|
530
578
|
}
|
|
531
579
|
body.appendChild(list);
|
|
532
580
|
}
|
|
@@ -53,7 +53,8 @@ plan-picker-ui {
|
|
|
53
53
|
background: var(--plan-picker-bg);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
/* ── Toggle row
|
|
56
|
+
/* ── Toggle row — <field-ui label="Billing interval"> wrapping the
|
|
57
|
+
<segmented-ui> (canonical billing-interval chain). ── */
|
|
57
58
|
:scope > [data-toggle] {
|
|
58
59
|
display: flex;
|
|
59
60
|
justify-content: var(--plan-picker-toggle-justify);
|
|
@@ -61,19 +62,21 @@ plan-picker-ui {
|
|
|
61
62
|
:scope > [data-toggle][hidden] {
|
|
62
63
|
display: none;
|
|
63
64
|
}
|
|
65
|
+
:scope > [data-toggle-divider][hidden] {
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
64
68
|
|
|
65
|
-
/* ── Plans grid
|
|
69
|
+
/* ── Plans grid — a <grid-ui columns="auto-fit"> primitive; we only
|
|
70
|
+
forward this composite's min/gap tokens into grid-ui's own
|
|
71
|
+
contract (--grid-min-col / --grid-gap). ── */
|
|
66
72
|
:scope > [data-plans] {
|
|
67
|
-
|
|
68
|
-
grid-
|
|
69
|
-
auto-fit,
|
|
70
|
-
minmax(var(--plan-picker-grid-min), 1fr)
|
|
71
|
-
);
|
|
72
|
-
gap: var(--plan-picker-grid-gap);
|
|
73
|
+
--grid-min-col: var(--plan-picker-grid-min);
|
|
74
|
+
--grid-gap: var(--plan-picker-grid-gap);
|
|
73
75
|
align-items: stretch;
|
|
74
76
|
}
|
|
75
77
|
|
|
76
|
-
/* List layout — single-column rows for in-app settings
|
|
78
|
+
/* List layout — single-column rows for in-app settings (mode
|
|
79
|
+
attribute; overrides grid-ui's auto-fit template). */
|
|
77
80
|
:scope[layout="list"] > [data-plans] {
|
|
78
81
|
grid-template-columns: 1fr;
|
|
79
82
|
}
|
|
@@ -131,12 +134,8 @@ plan-picker-ui {
|
|
|
131
134
|
display: none;
|
|
132
135
|
}
|
|
133
136
|
|
|
134
|
-
/* ── Price row
|
|
135
|
-
|
|
136
|
-
display: flex;
|
|
137
|
-
align-items: baseline;
|
|
138
|
-
gap: var(--a-space-1);
|
|
139
|
-
}
|
|
137
|
+
/* ── Price row — a <row-ui gap="1" align="baseline">; the primitive
|
|
138
|
+
owns the flex geometry, we style only the text chrome. ── */
|
|
140
139
|
:scope [data-price] {
|
|
141
140
|
font-size: var(--plan-picker-price-size);
|
|
142
141
|
color: var(--plan-picker-price-fg);
|
|
@@ -152,39 +151,23 @@ plan-picker-ui {
|
|
|
152
151
|
color: var(--plan-picker-cycle-fg);
|
|
153
152
|
}
|
|
154
153
|
|
|
155
|
-
/* ── Features list
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
display: flex;
|
|
161
|
-
flex-direction: column;
|
|
162
|
-
gap: var(--plan-picker-features-gap);
|
|
154
|
+
/* ── Features list — <col-ui data-features> of <row-ui data-feature>
|
|
155
|
+
lines (canonical feature-line grammar); the layout primitives own
|
|
156
|
+
the stack/row geometry, we forward gap + text/icon chrome. ── */
|
|
157
|
+
:scope [data-features] {
|
|
158
|
+
--col-gap: var(--plan-picker-features-gap);
|
|
163
159
|
}
|
|
164
|
-
:scope
|
|
165
|
-
display: flex;
|
|
166
|
-
align-items: flex-start;
|
|
167
|
-
gap: var(--a-space-2);
|
|
168
|
-
/* Override the docs feature-list indent (site.css adds
|
|
169
|
-
`padding-left: 24px` + a ::before checkmark to ul[data-features] li);
|
|
170
|
-
the slotted <icon-ui> IS our bullet, so the row aligns flush-left. */
|
|
171
|
-
padding-inline-start: 0;
|
|
160
|
+
:scope [data-features] > [data-feature] {
|
|
172
161
|
color: var(--md-sys-color-neutral-on-surface);
|
|
173
162
|
font-size: var(--a-text-sm, 0.875rem);
|
|
174
163
|
line-height: 1.4;
|
|
175
164
|
}
|
|
176
|
-
:scope
|
|
165
|
+
:scope [data-features] > [data-feature] > icon-ui {
|
|
177
166
|
flex-shrink: 0;
|
|
178
167
|
color: var(--plan-picker-feature-icon-fg);
|
|
179
168
|
--a-icon-size: 1rem;
|
|
180
169
|
margin-block-start: 0.125rem;
|
|
181
170
|
}
|
|
182
|
-
/* The feature check is the slotted <icon-ui>. Suppress any inherited
|
|
183
|
-
::before checkmark (the docs admin-page feature-list style adds a green
|
|
184
|
-
"✓" to every ul[data-features] li) so the bullet doesn't double up. */
|
|
185
|
-
:scope ul[data-features] > li::before {
|
|
186
|
-
content: none;
|
|
187
|
-
}
|
|
188
171
|
|
|
189
172
|
/* ── CTA button — full-width, anchored to the body's bottom edge so a
|
|
190
173
|
row of cards keeps their CTAs aligned regardless of feature count. ── */
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
],
|
|
23
23
|
"unevaluatedProperties": false,
|
|
24
24
|
"x-adiaui": {
|
|
25
|
+
"allowedParents": [
|
|
26
|
+
"ChatThread"
|
|
27
|
+
],
|
|
25
28
|
"anti_patterns": [],
|
|
26
29
|
"category": "feedback",
|
|
27
30
|
"composes": [],
|
|
@@ -34,6 +37,7 @@
|
|
|
34
37
|
"no-messages"
|
|
35
38
|
],
|
|
36
39
|
"name": "ChatEmpty",
|
|
40
|
+
"parts": {},
|
|
37
41
|
"related": [
|
|
38
42
|
"ChatShell",
|
|
39
43
|
"ChatThread",
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
],
|
|
23
23
|
"unevaluatedProperties": false,
|
|
24
24
|
"x-adiaui": {
|
|
25
|
+
"allowedParents": [
|
|
26
|
+
"ChatShell",
|
|
27
|
+
"ChatSidebar"
|
|
28
|
+
],
|
|
25
29
|
"anti_patterns": [],
|
|
26
30
|
"category": "layout",
|
|
27
31
|
"composes": [],
|
|
@@ -34,6 +38,7 @@
|
|
|
34
38
|
"app-header"
|
|
35
39
|
],
|
|
36
40
|
"name": "ChatHeader",
|
|
41
|
+
"parts": {},
|
|
37
42
|
"related": [
|
|
38
43
|
"ChatShell",
|
|
39
44
|
"ChatStatus",
|
|
@@ -52,6 +52,9 @@
|
|
|
52
52
|
],
|
|
53
53
|
"unevaluatedProperties": false,
|
|
54
54
|
"x-adiaui": {
|
|
55
|
+
"allowedParents": [
|
|
56
|
+
"Surface"
|
|
57
|
+
],
|
|
55
58
|
"anti_patterns": [],
|
|
56
59
|
"category": "container",
|
|
57
60
|
"composes": [
|
|
@@ -118,6 +121,7 @@
|
|
|
118
121
|
"assistant"
|
|
119
122
|
],
|
|
120
123
|
"name": "ChatShell",
|
|
124
|
+
"parts": {},
|
|
121
125
|
"related": [
|
|
122
126
|
"ChatThread",
|
|
123
127
|
"ChatComposer",
|
|
@@ -52,6 +52,9 @@
|
|
|
52
52
|
],
|
|
53
53
|
"unevaluatedProperties": false,
|
|
54
54
|
"x-adiaui": {
|
|
55
|
+
"allowedParents": [
|
|
56
|
+
"ChatShell"
|
|
57
|
+
],
|
|
55
58
|
"anti_patterns": [],
|
|
56
59
|
"category": "layout",
|
|
57
60
|
"composes": [],
|
|
@@ -83,6 +86,7 @@
|
|
|
83
86
|
"inspector"
|
|
84
87
|
],
|
|
85
88
|
"name": "ChatSidebar",
|
|
89
|
+
"parts": {},
|
|
86
90
|
"related": [
|
|
87
91
|
"ChatShell",
|
|
88
92
|
"ChatComposer",
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
],
|
|
23
23
|
"unevaluatedProperties": false,
|
|
24
24
|
"x-adiaui": {
|
|
25
|
+
"allowedParents": [
|
|
26
|
+
"ChatHeader"
|
|
27
|
+
],
|
|
25
28
|
"anti_patterns": [],
|
|
26
29
|
"category": "feedback",
|
|
27
30
|
"composes": [],
|
|
@@ -34,6 +37,7 @@
|
|
|
34
37
|
"streaming-indicator"
|
|
35
38
|
],
|
|
36
39
|
"name": "ChatStatus",
|
|
40
|
+
"parts": {},
|
|
37
41
|
"related": [
|
|
38
42
|
"ChatShell",
|
|
39
43
|
"ChatHeader",
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
],
|
|
33
33
|
"unevaluatedProperties": false,
|
|
34
34
|
"x-adiaui": {
|
|
35
|
+
"allowedParents": [
|
|
36
|
+
"ChatShell"
|
|
37
|
+
],
|
|
35
38
|
"anti_patterns": [],
|
|
36
39
|
"category": "container",
|
|
37
40
|
"composes": [],
|
|
@@ -45,6 +48,7 @@
|
|
|
45
48
|
"scroll-surface"
|
|
46
49
|
],
|
|
47
50
|
"name": "ChatThread",
|
|
51
|
+
"parts": {},
|
|
48
52
|
"related": [
|
|
49
53
|
"ChatShell",
|
|
50
54
|
"ChatEmpty",
|
|
@@ -58,6 +58,8 @@ states:
|
|
|
58
58
|
description: Zero message children — empty state visible.
|
|
59
59
|
traits: []
|
|
60
60
|
a2ui:
|
|
61
|
+
allowedParents:
|
|
62
|
+
- ChatShell
|
|
61
63
|
rules:
|
|
62
64
|
- chat-thread is the bespoke replacement for legacy <section data-chat-messages> inside <chat-shell>. Use it for the message
|
|
63
65
|
scroll surface; the host appends dynamic message divs as children.
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"properties": {
|
|
16
|
+
"bandGap": {
|
|
17
|
+
"description": "Override band-to-band vertical gap. Empty string = the\ndensity-modulated default. Numeric `1`..`6` selects the\ncorresponding --a-space-N step. Renamed from `[gap]` (gh#1335) —\nthis attribute set the component-local `--dashboard-layout-gap`\ntoken directly, never composing with the ambient\n`[size]`→`--a-gap` cascade the global Scale-grammar `[gap]`\nattribute uses, and covers a narrower numeric range (1-6 vs. the\nglobal 0-16) — a genuinely distinct, band-scoped concept kept\nunder its own namespaced name rather than converged.\n",
|
|
18
|
+
"type": "string",
|
|
19
|
+
"default": ""
|
|
20
|
+
},
|
|
16
21
|
"chart-split": {
|
|
17
22
|
"description": "Chart-band column split. Empty string = single full-width chart;\n`2` = two equal columns; `2:1` / `3:2` / `3:1` = asymmetric\nratios. Collapses to single column at narrow widths (≤48em).\n",
|
|
18
23
|
"type": "string",
|
|
@@ -29,21 +34,15 @@
|
|
|
29
34
|
"const": "DashboardLayout"
|
|
30
35
|
},
|
|
31
36
|
"density": {
|
|
32
|
-
"description": "Spacing scale — propagates --a-density to descendant primitives\nvia CSS custom-property cascade. Empty string inherits whatever\ndensity is in effect on an ancestor (the default — respects an\napp-level density theme). `compact` / `comfortable` / `spacious`\
|
|
37
|
+
"description": "Spacing scale — propagates --a-density to descendant primitives\nvia CSS custom-property cascade. Empty string inherits whatever\ndensity is in effect on an ancestor (the default — respects an\napp-level density theme). `compact` / `spacious` explicitly\noverride. `comfortable` retired (gh#1335) — verified dead code:\nit set `--a-density: 1` with no gap-token override, functionally\nidentical to the \"\" (unset/ambient) state, not to `spacious`\n(`--a-density: 1.15` + wider gap tokens) — so it converges onto\n\"\" (the closest matching real behavior) rather than a\n`comfortable`→`spacious` rename, which would have silently\nchanged behavior for any existing consumer.\n",
|
|
33
38
|
"type": "string",
|
|
34
39
|
"enum": [
|
|
35
40
|
"",
|
|
36
|
-
"comfortable",
|
|
37
41
|
"compact",
|
|
38
42
|
"spacious"
|
|
39
43
|
],
|
|
40
44
|
"default": ""
|
|
41
45
|
},
|
|
42
|
-
"gap": {
|
|
43
|
-
"description": "Override band-to-band vertical gap. Empty string = the\ndensity-modulated default (--a-space-4 at comfortable). Numeric\n`1`..`6` selects the corresponding --a-space-N step.\n",
|
|
44
|
-
"type": "string",
|
|
45
|
-
"default": ""
|
|
46
|
-
},
|
|
47
46
|
"kpi-columns": {
|
|
48
47
|
"description": "Target column count for the KPI band at desktop width. Range 2-6;\nout-of-range values fall back to 4. Container-query collapse\nreduces this at narrower widths (≤48em → 2; ≤32em → 1).\n",
|
|
49
48
|
"type": "string",
|
|
@@ -101,7 +100,7 @@
|
|
|
101
100
|
"description": "Fired when [density] changes (programmatic or via setDensity()).\nBubbles; detail.density carries the new value.\n",
|
|
102
101
|
"detail": {
|
|
103
102
|
"density": {
|
|
104
|
-
"description": "The new density value (
|
|
103
|
+
"description": "The new density value (\"\" / compact / spacious).",
|
|
105
104
|
"type": "string"
|
|
106
105
|
}
|
|
107
106
|
}
|
|
@@ -146,6 +145,7 @@
|
|
|
146
145
|
"layout-container"
|
|
147
146
|
],
|
|
148
147
|
"name": "UIDashboardLayout",
|
|
148
|
+
"parts": {},
|
|
149
149
|
"related": [
|
|
150
150
|
"AdminPageBody",
|
|
151
151
|
"AdminPage",
|
|
@@ -119,10 +119,10 @@ dashboard-layout-ui {
|
|
|
119
119
|
|
|
120
120
|
/* ── Density variants — override TOKEN values only ──
|
|
121
121
|
Per the contract: variants change tokens; modes change layout.
|
|
122
|
-
Density is a token-override, not a layout-shape change.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
Density is a token-override, not a layout-shape change.
|
|
123
|
+
`comfortable` retired (gh#1335) — verified dead code: it set only
|
|
124
|
+
--a-density:1 with no gap-token override, functionally identical
|
|
125
|
+
to the unset/"" state below (no selector needed), not to `spacious`. */
|
|
126
126
|
:scope[density="compact"] {
|
|
127
127
|
--dashboard-layout-gap: var(--dashboard-layout-gap-compact);
|
|
128
128
|
--dashboard-layout-kpi-gap: var(--dashboard-layout-kpi-gap-compact);
|
|
@@ -30,7 +30,7 @@ import { untracked } from '@adia-ai/web-components/core/signals';
|
|
|
30
30
|
|
|
31
31
|
// ── Validation tables ────────────────────────────────────────────
|
|
32
32
|
|
|
33
|
-
const VALID_DENSITIES = new Set(['', '
|
|
33
|
+
const VALID_DENSITIES = new Set(['', 'compact', 'spacious']);
|
|
34
34
|
const VALID_KPI_COLUMNS = new Set(['2', '3', '4', '5', '6']);
|
|
35
35
|
const VALID_CHART_SPLIT = new Set(['', '2', '2:1', '3:2', '3:1']);
|
|
36
36
|
const REGION_SLOTS = ['toolbar', 'kpis', 'charts', 'table', 'aside'];
|
|
@@ -44,7 +44,7 @@ export class UIDashboardLayout extends UIElement {
|
|
|
44
44
|
'kpi-columns': { type: String, default: '4', reflect: true, attribute: 'kpi-columns' },
|
|
45
45
|
'chart-split': { type: String, default: '', reflect: true, attribute: 'chart-split' },
|
|
46
46
|
loading: { type: Boolean, default: false, reflect: true },
|
|
47
|
-
|
|
47
|
+
bandGap: { type: String, default: '', reflect: true, attribute: 'band-gap' },
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -76,7 +76,7 @@ export class UIDashboardLayout extends UIElement {
|
|
|
76
76
|
* Programmatic equivalent of setting the [density] attribute.
|
|
77
77
|
* Fires `density-change` once with the new value.
|
|
78
78
|
*
|
|
79
|
-
* @param {string} value — '' | '
|
|
79
|
+
* @param {string} value — '' | 'compact' | 'spacious'
|
|
80
80
|
*/
|
|
81
81
|
setDensity(value) {
|
|
82
82
|
const next = VALID_DENSITIES.has(value) ? value : '';
|
|
@@ -118,7 +118,7 @@ export class UIDashboardLayout extends UIElement {
|
|
|
118
118
|
// changes flow through attributeChangedCallback below.
|
|
119
119
|
this.#syncAriaBusy();
|
|
120
120
|
|
|
121
|
-
// Apply the [gap] override → public token if set.
|
|
121
|
+
// Apply the [band-gap] override → public token if set.
|
|
122
122
|
this.#applyGapAttr();
|
|
123
123
|
|
|
124
124
|
// Watch for region-empty transitions. Children are arbitrary
|
|
@@ -195,7 +195,7 @@ export class UIDashboardLayout extends UIElement {
|
|
|
195
195
|
return;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
if (name === 'gap' && oldVal !== newVal) {
|
|
198
|
+
if (name === 'band-gap' && oldVal !== newVal) {
|
|
199
199
|
this.#applyGapAttr();
|
|
200
200
|
return;
|
|
201
201
|
}
|
|
@@ -237,12 +237,13 @@ export class UIDashboardLayout extends UIElement {
|
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
/**
|
|
240
|
-
* Map the [gap="N"] attribute to the
|
|
241
|
-
* custom property. The CSS reads
|
|
242
|
-
* so empty / unset falls back to the
|
|
240
|
+
* Map the [band-gap="N"] attribute (renamed from [gap], gh#1335) to the
|
|
241
|
+
* public --dashboard-layout-gap custom property. The CSS reads
|
|
242
|
+
* `var(--dashboard-layout-gap, …)` so empty / unset falls back to the
|
|
243
|
+
* density-modulated default.
|
|
243
244
|
*/
|
|
244
245
|
#applyGapAttr() {
|
|
245
|
-
const g = (this.
|
|
246
|
+
const g = (this.bandGap || '').trim();
|
|
246
247
|
if (g === '') {
|
|
247
248
|
this.style.removeProperty('--dashboard-layout-gap');
|
|
248
249
|
return;
|
|
@@ -40,13 +40,18 @@ props:
|
|
|
40
40
|
Spacing scale — propagates --a-density to descendant primitives
|
|
41
41
|
via CSS custom-property cascade. Empty string inherits whatever
|
|
42
42
|
density is in effect on an ancestor (the default — respects an
|
|
43
|
-
app-level density theme). `compact` / `
|
|
44
|
-
|
|
43
|
+
app-level density theme). `compact` / `spacious` explicitly
|
|
44
|
+
override. `comfortable` retired (gh#1335) — verified dead code:
|
|
45
|
+
it set `--a-density: 1` with no gap-token override, functionally
|
|
46
|
+
identical to the "" (unset/ambient) state, not to `spacious`
|
|
47
|
+
(`--a-density: 1.15` + wider gap tokens) — so it converges onto
|
|
48
|
+
"" (the closest matching real behavior) rather than a
|
|
49
|
+
`comfortable`→`spacious` rename, which would have silently
|
|
50
|
+
changed behavior for any existing consumer.
|
|
45
51
|
type: string
|
|
46
52
|
default: ""
|
|
47
53
|
enum:
|
|
48
54
|
- ""
|
|
49
|
-
- comfortable
|
|
50
55
|
- compact
|
|
51
56
|
- spacious
|
|
52
57
|
reflect: true
|
|
@@ -91,13 +96,20 @@ props:
|
|
|
91
96
|
default: false
|
|
92
97
|
reflect: true
|
|
93
98
|
|
|
94
|
-
|
|
99
|
+
bandGap:
|
|
95
100
|
description: |
|
|
96
101
|
Override band-to-band vertical gap. Empty string = the
|
|
97
|
-
density-modulated default
|
|
98
|
-
|
|
102
|
+
density-modulated default. Numeric `1`..`6` selects the
|
|
103
|
+
corresponding --a-space-N step. Renamed from `[gap]` (gh#1335) —
|
|
104
|
+
this attribute set the component-local `--dashboard-layout-gap`
|
|
105
|
+
token directly, never composing with the ambient
|
|
106
|
+
`[size]`→`--a-gap` cascade the global Scale-grammar `[gap]`
|
|
107
|
+
attribute uses, and covers a narrower numeric range (1-6 vs. the
|
|
108
|
+
global 0-16) — a genuinely distinct, band-scoped concept kept
|
|
109
|
+
under its own namespaced name rather than converged.
|
|
99
110
|
type: string
|
|
100
111
|
default: ""
|
|
112
|
+
attribute: band-gap
|
|
101
113
|
reflect: true
|
|
102
114
|
|
|
103
115
|
events:
|
|
@@ -108,7 +120,7 @@ events:
|
|
|
108
120
|
detail:
|
|
109
121
|
density:
|
|
110
122
|
type: string
|
|
111
|
-
description: The new density value (
|
|
123
|
+
description: The new density value ("" / compact / spacious).
|
|
112
124
|
|
|
113
125
|
region-empty:
|
|
114
126
|
description: |
|