@adia-ai/web-modules 0.8.35 → 0.8.37
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 +22 -0
- package/README.md +3 -3
- package/agent-admin/admin-roster/admin-roster.js +1 -1
- package/agent-admin/admin-settings/admin-settings.js +1 -1
- package/agent-admin/agent-admin/agent-admin.js +1 -1
- package/billing/billing-overview/billing-overview.a2ui.json +281 -0
- package/billing/billing-overview/billing-overview.class.js +838 -0
- package/billing/billing-overview/billing-overview.css +223 -0
- package/billing/billing-overview/billing-overview.js +16 -0
- package/billing/billing-overview/billing-overview.yaml +441 -0
- package/billing/index.js +21 -0
- package/billing/invoice-detail/invoice-detail.a2ui.json +276 -0
- package/billing/invoice-detail/invoice-detail.class.js +711 -0
- package/billing/invoice-detail/invoice-detail.css +305 -0
- package/billing/invoice-detail/invoice-detail.js +16 -0
- package/billing/invoice-detail/invoice-detail.yaml +411 -0
- package/billing/invoice-history/invoice-history.a2ui.json +315 -0
- package/billing/invoice-history/invoice-history.class.js +672 -0
- package/billing/invoice-history/invoice-history.css +130 -0
- package/billing/invoice-history/invoice-history.js +16 -0
- package/billing/invoice-history/invoice-history.yaml +398 -0
- package/billing/payment-method-form/payment-method-form.a2ui.json +310 -0
- package/billing/payment-method-form/payment-method-form.class.js +886 -0
- package/billing/payment-method-form/payment-method-form.css +149 -0
- package/billing/payment-method-form/payment-method-form.js +16 -0
- package/billing/payment-method-form/payment-method-form.yaml +430 -0
- package/billing/payment-method-list/payment-method-list.a2ui.json +283 -0
- package/billing/payment-method-list/payment-method-list.class.js +705 -0
- package/billing/payment-method-list/payment-method-list.css +128 -0
- package/billing/payment-method-list/payment-method-list.js +16 -0
- package/billing/payment-method-list/payment-method-list.yaml +355 -0
- package/billing/plan-picker/plan-picker.a2ui.json +349 -0
- package/billing/plan-picker/plan-picker.class.js +635 -0
- package/billing/plan-picker/plan-picker.css +227 -0
- package/billing/plan-picker/plan-picker.js +16 -0
- package/billing/plan-picker/plan-picker.yaml +453 -0
- package/chat/README.md +1 -1
- package/chat/chat-composer/chat-composer.js +2 -2
- package/chat/chat-empty/chat-empty.js +2 -2
- package/chat/chat-shell/chat-shell.js +4 -4
- package/chat/chat-sidebar/chat-sidebar.js +2 -2
- package/chat/chat-surfaces/chat-surfaces.js +2 -2
- package/chat/chat-thread/chat-thread.js +2 -2
- package/dashboard/dashboard-layout/dashboard-layout.a2ui.json +254 -0
- package/dashboard/dashboard-layout/dashboard-layout.css +190 -0
- package/dashboard/dashboard-layout/dashboard-layout.js +289 -0
- package/dashboard/dashboard-layout/dashboard-layout.yaml +374 -0
- package/dashboard/date-range-selector/date-range-selector.a2ui.json +236 -0
- package/dashboard/date-range-selector/date-range-selector.css +84 -0
- package/dashboard/date-range-selector/date-range-selector.js +686 -0
- package/dashboard/date-range-selector/date-range-selector.yaml +358 -0
- package/dashboard/index.js +14 -0
- package/dist/everything.min.js +1 -1
- package/editor/editor-canvas/editor-canvas.js +2 -2
- package/editor/editor-shell/editor-shell.js +2 -2
- package/editor/editor-sidebar/editor-sidebar.js +2 -2
- package/editor/editor-toolbar/editor-toolbar.js +2 -2
- package/feedback/confirm-dialog/confirm-dialog.a2ui.json +206 -0
- package/feedback/confirm-dialog/confirm-dialog.css +157 -0
- package/feedback/confirm-dialog/confirm-dialog.js +383 -0
- package/feedback/confirm-dialog/confirm-dialog.yaml +297 -0
- package/feedback/index.js +10 -0
- package/form/form-popover/form-popover.js +1 -1
- package/generative/index.d.ts +1 -1
- package/generative/index.js +2 -2
- package/onboarding/index.js +1 -0
- package/onboarding/onboarding-checklist/onboarding-checklist.a2ui.json +263 -0
- package/onboarding/onboarding-checklist/onboarding-checklist.css +157 -0
- package/onboarding/onboarding-checklist/onboarding-checklist.js +428 -0
- package/onboarding/onboarding-checklist/onboarding-checklist.yaml +236 -0
- package/package.json +99 -6
- package/runtime/a2ui-root/a2ui-root.js +3 -3
- package/runtime/gen-root/gen-root.js +5 -5
- package/settings/index.js +12 -0
- package/settings/integrations-page/integrations-page.a2ui.json +274 -0
- package/settings/integrations-page/integrations-page.css +177 -0
- package/settings/integrations-page/integrations-page.d.ts +77 -0
- package/settings/integrations-page/integrations-page.js +413 -0
- package/settings/integrations-page/integrations-page.yaml +317 -0
- package/settings/notification-preferences/notification-preferences.a2ui.json +245 -0
- package/settings/notification-preferences/notification-preferences.css +204 -0
- package/settings/notification-preferences/notification-preferences.js +622 -0
- package/settings/notification-preferences/notification-preferences.yaml +358 -0
- package/shell/admin-command/admin-command.js +2 -2
- package/shell/admin-shell/admin-shell.js +2 -2
- package/shell/admin-sidebar/admin-sidebar.js +2 -2
- package/shell/embed-shell/embed-shell.js +3 -3
- package/simple/simple-shell/simple-shell.js +1 -1
- package/theme/theme-panel/theme-panel.js +2 -2
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
2
|
+
<billing-overview-ui> — Module-tier billing dashboard composite.
|
|
3
|
+
|
|
4
|
+
Stamps a stacked column of dashboard regions:
|
|
5
|
+
[data-header] plan title + status badge + actions
|
|
6
|
+
[data-kpis] 3-stat KPI strip (spend · seats · next)
|
|
7
|
+
[data-dunning] alert-ui[pattern=dunning], conditional
|
|
8
|
+
[data-plan-picker] plan-picker-ui section
|
|
9
|
+
[data-payment-methods] payment-method-list-ui section
|
|
10
|
+
[data-invoice-history] invoice-history-ui section
|
|
11
|
+
[data-empty] default empty-state branch
|
|
12
|
+
|
|
13
|
+
SPEC: docs/specs/implementation-ready/SPEC-004-billing-overview.md
|
|
14
|
+
Two-block @scope pattern per docs/specs/component-token-contract.md.
|
|
15
|
+
Zero raw color values (repo hard rule); rem for sizes ≥ 3px.
|
|
16
|
+
═══════════════════════════════════════════════════════════════ */
|
|
17
|
+
|
|
18
|
+
/* ── Block 1: TOKEN DECLARATIONS ───────────────────────────────── */
|
|
19
|
+
|
|
20
|
+
billing-overview-ui {
|
|
21
|
+
--billing-overview-bg: transparent;
|
|
22
|
+
--billing-overview-gap: var(--a-space-5);
|
|
23
|
+
--billing-overview-px: var(--a-space-5);
|
|
24
|
+
--billing-overview-py: var(--a-space-5);
|
|
25
|
+
--billing-overview-section-radius: var(--a-radius-lg);
|
|
26
|
+
|
|
27
|
+
--billing-overview-header-gap: var(--a-space-3);
|
|
28
|
+
|
|
29
|
+
--billing-overview-kpi-columns: repeat(3, minmax(0, 1fr));
|
|
30
|
+
--billing-overview-kpi-gap: var(--a-space-3);
|
|
31
|
+
|
|
32
|
+
--billing-overview-section-heading-fg: var(--md-sys-color-neutral-on-surface);
|
|
33
|
+
--billing-overview-section-heading-size: var(--a-text-base, 1rem);
|
|
34
|
+
--billing-overview-section-heading-weight: var(--a-weight-semibold, 600);
|
|
35
|
+
|
|
36
|
+
--billing-overview-title-size: var(--a-text-2xl, 1.5rem);
|
|
37
|
+
--billing-overview-title-weight: var(--a-weight-bold, 700);
|
|
38
|
+
|
|
39
|
+
--billing-overview-meta-fg: var(--a-fg-muted);
|
|
40
|
+
--billing-overview-meta-size: var(--a-text-sm, 0.875rem);
|
|
41
|
+
|
|
42
|
+
--billing-overview-empty-fg: var(--a-fg-muted);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ── Block 2: SCOPED LAYOUT ────────────────────────────────────── */
|
|
46
|
+
|
|
47
|
+
@scope (billing-overview-ui) {
|
|
48
|
+
|
|
49
|
+
/* Host — stack regions in a column, container for inner CQ. */
|
|
50
|
+
:scope {
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
gap: var(--billing-overview-gap);
|
|
54
|
+
background: var(--billing-overview-bg);
|
|
55
|
+
padding-block: var(--billing-overview-py);
|
|
56
|
+
padding-inline: var(--billing-overview-px);
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
container-type: inline-size;
|
|
59
|
+
container-name: billing-overview;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* ── Header region ── card-ui owns layout; we just style inline content.
|
|
63
|
+
Per v1.7.1 wireframe re-author (2026-05-24): header is now <card-ui> with
|
|
64
|
+
<header> slot composition (icon | heading | description | action).
|
|
65
|
+
card-ui's @scope provides the layout; we only style descendants. */
|
|
66
|
+
|
|
67
|
+
:scope > [data-header] [data-billing-plan-name] {
|
|
68
|
+
margin: 0;
|
|
69
|
+
font-size: var(--billing-overview-title-size);
|
|
70
|
+
font-weight: var(--billing-overview-title-weight);
|
|
71
|
+
color: var(--md-sys-color-neutral-on-surface);
|
|
72
|
+
line-height: 1.2;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
:scope > [data-header] [data-billing-plan-meta] {
|
|
76
|
+
display: flex;
|
|
77
|
+
flex-wrap: wrap;
|
|
78
|
+
gap: var(--a-space-3);
|
|
79
|
+
font-size: var(--billing-overview-meta-size);
|
|
80
|
+
color: var(--billing-overview-meta-fg);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
:scope > [data-header] [data-billing-plan-meta]:empty {
|
|
84
|
+
display: none;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:scope > [data-header] [data-billing-status] {
|
|
88
|
+
margin-inline-start: var(--a-space-2);
|
|
89
|
+
vertical-align: baseline;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
:scope > [data-header] [data-billing-status][hidden] {
|
|
93
|
+
display: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
:scope > [data-header] [data-header-actions] {
|
|
97
|
+
display: flex;
|
|
98
|
+
gap: var(--a-space-2);
|
|
99
|
+
justify-content: flex-end;
|
|
100
|
+
flex-wrap: wrap;
|
|
101
|
+
align-items: center;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
:scope > [data-header] [data-header-actions]:empty {
|
|
105
|
+
display: none;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* ── KPI strip ── card-ui × 3 wrapping stat-ui per canonical pattern.
|
|
109
|
+
Per v1.7.1 wireframe re-author: each KPI is now <card-ui><section><stat-ui>
|
|
110
|
+
instead of CSS-faked card chrome on raw stat-ui. */
|
|
111
|
+
:scope > [data-kpis] {
|
|
112
|
+
display: grid;
|
|
113
|
+
grid-template-columns: var(--billing-overview-kpi-columns);
|
|
114
|
+
gap: var(--billing-overview-kpi-gap);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* card-ui chrome is provided by card-ui's own @scope; no fake card chrome here. */
|
|
118
|
+
|
|
119
|
+
/* ── Dunning banner ── */
|
|
120
|
+
:scope > [data-dunning] {
|
|
121
|
+
display: block;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
:scope > [data-dunning][hidden] {
|
|
125
|
+
display: none;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* ── Section host shape ── plan-picker, payment-methods, invoice-history */
|
|
129
|
+
:scope > [data-plan-picker],
|
|
130
|
+
:scope > [data-payment-methods],
|
|
131
|
+
:scope > [data-invoice-history] {
|
|
132
|
+
display: flex;
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
gap: var(--a-space-3);
|
|
135
|
+
background: var(--md-sys-color-neutral-background);
|
|
136
|
+
border: 1px solid var(--md-sys-color-neutral-outline-variant);
|
|
137
|
+
border-radius: var(--billing-overview-section-radius);
|
|
138
|
+
padding: var(--a-space-4);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
:scope > [data-plan-picker][hidden],
|
|
142
|
+
:scope > [data-payment-methods][hidden],
|
|
143
|
+
:scope > [data-invoice-history][hidden] {
|
|
144
|
+
display: none;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
:scope [data-section-heading] {
|
|
148
|
+
margin: 0;
|
|
149
|
+
font-size: var(--billing-overview-section-heading-size);
|
|
150
|
+
font-weight: var(--billing-overview-section-heading-weight);
|
|
151
|
+
color: var(--billing-overview-section-heading-fg);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* ── Variant cascade ── */
|
|
155
|
+
/* compact + enterprise hide the plan-picker section (also gated in JS). */
|
|
156
|
+
:scope[variant="compact"] > [data-plan-picker],
|
|
157
|
+
:scope[variant="enterprise"] > [data-plan-picker] {
|
|
158
|
+
display: none;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* ── Slot anchors ── */
|
|
162
|
+
:scope [data-before-plan-picker]:empty,
|
|
163
|
+
:scope [data-after-invoice-history]:empty {
|
|
164
|
+
display: none;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* ── Empty + loading states ── */
|
|
168
|
+
:scope > [data-empty] {
|
|
169
|
+
display: none;
|
|
170
|
+
color: var(--billing-overview-empty-fg);
|
|
171
|
+
text-align: center;
|
|
172
|
+
padding-block: var(--a-space-6);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
:scope[empty] > [data-empty] {
|
|
176
|
+
display: block;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
:scope[empty] > [data-header],
|
|
180
|
+
:scope[empty] > [data-kpis],
|
|
181
|
+
:scope[empty] > [data-dunning],
|
|
182
|
+
:scope[empty] > [data-plan-picker],
|
|
183
|
+
:scope[empty] > [data-payment-methods],
|
|
184
|
+
:scope[empty] > [data-invoice-history] {
|
|
185
|
+
display: none;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
:scope [data-empty-heading] {
|
|
189
|
+
margin: 0 0 var(--a-space-2) 0;
|
|
190
|
+
font-size: var(--a-text-base, 1rem);
|
|
191
|
+
font-weight: var(--a-weight-semibold, 600);
|
|
192
|
+
color: var(--md-sys-color-neutral-on-surface);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
:scope [data-empty-description] {
|
|
196
|
+
margin: 0;
|
|
197
|
+
font-size: var(--a-text-sm, 0.875rem);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
:scope[loading] {
|
|
201
|
+
opacity: 0.85;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* ── Past-due emphasis ── */
|
|
205
|
+
/* The dunning banner already carries danger chrome; tint the header
|
|
206
|
+
status zone subtly. */
|
|
207
|
+
:scope[past-due] > [data-header] [data-billing-plan-meta] {
|
|
208
|
+
color: var(--a-danger-strong, var(--a-danger, var(--a-fg-muted)));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* ── Container query — collapse KPI strip below ~640px ── */
|
|
212
|
+
@container billing-overview (max-width: 40rem) {
|
|
213
|
+
:scope > [data-kpis] {
|
|
214
|
+
grid-template-columns: 1fr;
|
|
215
|
+
}
|
|
216
|
+
:scope > [data-header] {
|
|
217
|
+
grid-template-columns: 1fr;
|
|
218
|
+
}
|
|
219
|
+
:scope > [data-header] [data-header-actions] {
|
|
220
|
+
justify-content: flex-start;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<billing-overview-ui>` — auto-registers the tag on import.
|
|
3
|
+
*
|
|
4
|
+
* For a non-side-effect class import (test isolation, tag override),
|
|
5
|
+
* use the class export from `./billing-overview.class.js`:
|
|
6
|
+
*
|
|
7
|
+
* import { UIBillingOverview } from '@adia-ai/web-modules/billing/billing-overview/class';
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { UIBillingOverview } from './billing-overview.class.js';
|
|
11
|
+
|
|
12
|
+
if (!customElements.get('billing-overview-ui')) {
|
|
13
|
+
customElements.define('billing-overview-ui', UIBillingOverview);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { UIBillingOverview };
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
# Edit this file; run `npm run build:components` to regenerate a2ui.json.
|
|
2
|
+
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
3
|
+
name: UIBillingOverview
|
|
4
|
+
tag: billing-overview-ui
|
|
5
|
+
status: experimental
|
|
6
|
+
component: BillingOverview
|
|
7
|
+
category: container
|
|
8
|
+
version: 1
|
|
9
|
+
description: |
|
|
10
|
+
Module-tier billing dashboard that stitches the seven Wave A+B
|
|
11
|
+
billing primitives into the canonical "all-billing-on-one-page"
|
|
12
|
+
surface — current plan + status header, a KPI strip (monthly
|
|
13
|
+
spend · seats · next invoice), an optional dunning banner when the
|
|
14
|
+
account is past-due, a plan-picker section for in-app plan changes,
|
|
15
|
+
a payment-method-list section, and an invoice-history section.
|
|
16
|
+
|
|
17
|
+
Data-driven via the `account` property — an aggregate snapshot of
|
|
18
|
+
the customer's billing state ({plan, status, billingCycle,
|
|
19
|
+
currentSpend, seats, nextInvoiceDate, paymentMethods[],
|
|
20
|
+
invoices[], dunning?}). The composite stamps a fixed five-region
|
|
21
|
+
skeleton once on first connect — header · kpis · dunning ·
|
|
22
|
+
plan-picker · payment-methods · invoice-history — then mutates
|
|
23
|
+
per-region nodes via id-keyed in-place diff on every property
|
|
24
|
+
change. Children primitives (plan-picker, payment-method-list,
|
|
25
|
+
invoice-history, alert-ui) are stamped as composed tags; this
|
|
26
|
+
composite owns the orchestration, not the row chrome.
|
|
27
|
+
|
|
28
|
+
Higher-level account-action event surfaces consumer-actionable
|
|
29
|
+
intents from descendant primitives. Children carrying
|
|
30
|
+
[data-account-action="X"] or descendant events
|
|
31
|
+
(`plan-action`, `payment-action`, `invoice-action`, `dunning-action`)
|
|
32
|
+
are normalised into a single `account-action` event with
|
|
33
|
+
`detail.action` ∈ {change-plan, add-payment-method, pay-now,
|
|
34
|
+
download-invoice, update-card, retry, custom}. The composite
|
|
35
|
+
does NOT mutate the data source; consumers wire `account-action`
|
|
36
|
+
against their billing backend.
|
|
37
|
+
|
|
38
|
+
Display surface. Extends UIElement, not UIFormElement — child
|
|
39
|
+
primitives are individually form-bearing (plan-picker,
|
|
40
|
+
payment-method-list) while the host is not.
|
|
41
|
+
|
|
42
|
+
Spec: .claude/docs/specs/implementation-ready/SPEC-004-billing-overview.md.
|
|
43
|
+
|
|
44
|
+
# Per ADR-0027 — composites do NOT auto-import the primitives they
|
|
45
|
+
# stamp in connected()/render(). The consumer (or this primitive's
|
|
46
|
+
# .html demo shell) must explicitly side-effect-import each one.
|
|
47
|
+
composes:
|
|
48
|
+
- card-ui
|
|
49
|
+
- stat-ui
|
|
50
|
+
- tag-ui
|
|
51
|
+
- text-ui
|
|
52
|
+
- alert-ui
|
|
53
|
+
- plan-picker-ui
|
|
54
|
+
- payment-method-list-ui
|
|
55
|
+
- invoice-history-ui
|
|
56
|
+
- button-ui
|
|
57
|
+
- icon-ui
|
|
58
|
+
|
|
59
|
+
props:
|
|
60
|
+
account:
|
|
61
|
+
description: |
|
|
62
|
+
Aggregate billing snapshot — source of truth for the whole
|
|
63
|
+
dashboard. Shape:
|
|
64
|
+
{plan: {id, name, price, cycle, currency, status},
|
|
65
|
+
status: "active" | "trialing" | "past_due" | "canceled" | "paused",
|
|
66
|
+
billingCycle: "month" | "year",
|
|
67
|
+
currentSpend: number,
|
|
68
|
+
seats: {used: number, total: number},
|
|
69
|
+
nextInvoiceDate: ISO 8601 date string,
|
|
70
|
+
paymentMethods: [...], // forwarded to payment-method-list
|
|
71
|
+
invoices: [...], // forwarded to invoice-history
|
|
72
|
+
plans?: [...], // forwarded to plan-picker; omitted when planSection is "hidden"
|
|
73
|
+
dunning?: {amount, currency, dueAt, cardLast4?, reason?}}
|
|
74
|
+
Null + no `data-stream-src` renders the empty state.
|
|
75
|
+
type: object
|
|
76
|
+
default: null
|
|
77
|
+
dynamic: true
|
|
78
|
+
required: true
|
|
79
|
+
|
|
80
|
+
variant:
|
|
81
|
+
description: |
|
|
82
|
+
Layout variant. `full` shows every section. `compact` collapses
|
|
83
|
+
the plan-picker section and renders only the KPI strip + payment
|
|
84
|
+
methods + invoice history (the canonical "settings billing"
|
|
85
|
+
shape). `enterprise` hides plan-picker entirely (no self-serve
|
|
86
|
+
plan changes) and keeps the rest.
|
|
87
|
+
type: string
|
|
88
|
+
default: "full"
|
|
89
|
+
enum:
|
|
90
|
+
- full
|
|
91
|
+
- compact
|
|
92
|
+
- enterprise
|
|
93
|
+
reflect: true
|
|
94
|
+
|
|
95
|
+
currency:
|
|
96
|
+
description: |
|
|
97
|
+
Default ISO 4217 currency for all amount formatting. Overridable
|
|
98
|
+
per-record (plan.currency, invoice.currency, etc.).
|
|
99
|
+
type: string
|
|
100
|
+
default: "USD"
|
|
101
|
+
reflect: true
|
|
102
|
+
|
|
103
|
+
locale:
|
|
104
|
+
description: |
|
|
105
|
+
Locale for Intl.NumberFormat (currency) and Intl.DateTimeFormat
|
|
106
|
+
(dates). Defaults to document.documentElement.lang (or "en-US"
|
|
107
|
+
when absent).
|
|
108
|
+
type: string
|
|
109
|
+
default: ""
|
|
110
|
+
|
|
111
|
+
loading:
|
|
112
|
+
description: |
|
|
113
|
+
Renders skeleton placeholders in the header + KPI strip while
|
|
114
|
+
data is fetching. Sets aria-busy on the host. Forwarded to
|
|
115
|
+
child composites that accept [loading] (plan-picker,
|
|
116
|
+
payment-method-list, invoice-history).
|
|
117
|
+
type: boolean
|
|
118
|
+
default: false
|
|
119
|
+
reflect: true
|
|
120
|
+
dynamic: true
|
|
121
|
+
|
|
122
|
+
data-stream-src:
|
|
123
|
+
description: |
|
|
124
|
+
Optional endpoint returning the full account snapshot. On
|
|
125
|
+
successful load, `account` is replaced and a `load` event fires;
|
|
126
|
+
on failure an `error` event fires.
|
|
127
|
+
type: string
|
|
128
|
+
default: ""
|
|
129
|
+
attribute: data-stream-src
|
|
130
|
+
|
|
131
|
+
events:
|
|
132
|
+
account-action:
|
|
133
|
+
description: |
|
|
134
|
+
Unified account-action event — normalises every actionable
|
|
135
|
+
intent from descendant primitives into a single bubbling event.
|
|
136
|
+
Handler can act on `detail.action` without subscribing to four
|
|
137
|
+
different child event names. Bubbles.
|
|
138
|
+
detail:
|
|
139
|
+
action:
|
|
140
|
+
type: string
|
|
141
|
+
description: |
|
|
142
|
+
One of "change-plan" | "add-payment-method" | "pay-now" |
|
|
143
|
+
"download-invoice" | "update-card" | "retry" | "select-plan"
|
|
144
|
+
| "remove-payment-method" | "set-default-payment-method" |
|
|
145
|
+
or any consumer-defined value carried on a descendant
|
|
146
|
+
[data-account-action] attribute.
|
|
147
|
+
source:
|
|
148
|
+
type: string
|
|
149
|
+
description: |
|
|
150
|
+
The originating primitive — "plan-picker" | "payment-method-list"
|
|
151
|
+
| "invoice-history" | "alert-dunning" | "header" | "custom".
|
|
152
|
+
payload:
|
|
153
|
+
type: object
|
|
154
|
+
description: |
|
|
155
|
+
Forwarded detail from the originating event (e.g. the
|
|
156
|
+
invoice record, the plan id, the dunning amount). Shape
|
|
157
|
+
varies by source.
|
|
158
|
+
|
|
159
|
+
load:
|
|
160
|
+
description: |
|
|
161
|
+
Fired when `data-stream-src` finishes a successful fetch and
|
|
162
|
+
`account` is populated. Bubbles.
|
|
163
|
+
detail:
|
|
164
|
+
account:
|
|
165
|
+
type: object
|
|
166
|
+
description: The loaded account snapshot.
|
|
167
|
+
|
|
168
|
+
error:
|
|
169
|
+
description: |
|
|
170
|
+
Fired when a `data-stream-src` fetch fails. Bubbles.
|
|
171
|
+
detail:
|
|
172
|
+
reason:
|
|
173
|
+
type: string
|
|
174
|
+
description: One of `fetch-failed`.
|
|
175
|
+
|
|
176
|
+
slots:
|
|
177
|
+
header-actions:
|
|
178
|
+
description: |
|
|
179
|
+
Optional action row in the dashboard header (top-right). Used
|
|
180
|
+
for consumer-authored "Contact sales", "Cancel subscription",
|
|
181
|
+
etc. The composite NEVER stamps a default toolbar.
|
|
182
|
+
before-plan-picker:
|
|
183
|
+
description: |
|
|
184
|
+
Optional content slotted above the plan-picker section (e.g. a
|
|
185
|
+
promo banner, an annual-savings callout).
|
|
186
|
+
after-invoice-history:
|
|
187
|
+
description: |
|
|
188
|
+
Optional content slotted below the invoice-history section
|
|
189
|
+
(e.g. tax-document download row, billing-contact form).
|
|
190
|
+
empty:
|
|
191
|
+
description: |
|
|
192
|
+
Custom empty-state content when there's no account snapshot
|
|
193
|
+
AND no data-stream-src. Falls back to a default empty-state
|
|
194
|
+
message.
|
|
195
|
+
|
|
196
|
+
states:
|
|
197
|
+
- name: idle
|
|
198
|
+
description: Default — account rendered, ready for interaction.
|
|
199
|
+
- name: loading
|
|
200
|
+
description: A `data-stream-src` fetch is in flight or [loading] is set.
|
|
201
|
+
attribute: loading
|
|
202
|
+
- name: empty
|
|
203
|
+
description: No account snapshot + no data-stream-src.
|
|
204
|
+
attribute: empty
|
|
205
|
+
- name: past-due
|
|
206
|
+
description: |
|
|
207
|
+
Account is past-due (computed from `account.status === "past_due"`).
|
|
208
|
+
Stamps the dunning banner if `account.dunning` is present.
|
|
209
|
+
attribute: past-due
|
|
210
|
+
- name: trial
|
|
211
|
+
description: |
|
|
212
|
+
Account is trialing (computed from `account.status === "trialing"`).
|
|
213
|
+
attribute: trial
|
|
214
|
+
- name: error
|
|
215
|
+
description: Last `data-stream-src` fetch failed.
|
|
216
|
+
attribute: error
|
|
217
|
+
|
|
218
|
+
traits: []
|
|
219
|
+
|
|
220
|
+
tokens:
|
|
221
|
+
--billing-overview-bg:
|
|
222
|
+
description: Host page background. Defaults to transparent.
|
|
223
|
+
default: transparent
|
|
224
|
+
--billing-overview-gap:
|
|
225
|
+
description: Vertical gap between dashboard sections.
|
|
226
|
+
default: var(--a-space-5)
|
|
227
|
+
--billing-overview-px:
|
|
228
|
+
description: Horizontal padding around dashboard content.
|
|
229
|
+
default: var(--a-space-5)
|
|
230
|
+
--billing-overview-py:
|
|
231
|
+
description: Vertical padding around dashboard content.
|
|
232
|
+
default: var(--a-space-5)
|
|
233
|
+
--billing-overview-section-radius:
|
|
234
|
+
description: Section card corner radius.
|
|
235
|
+
default: var(--a-radius-lg)
|
|
236
|
+
--billing-overview-header-gap:
|
|
237
|
+
description: Gap between the plan title block and the status badge cluster.
|
|
238
|
+
default: var(--a-space-3)
|
|
239
|
+
--billing-overview-kpi-columns:
|
|
240
|
+
description: |
|
|
241
|
+
Grid column template for the KPI strip. Falls back to a 3-column
|
|
242
|
+
auto-fit when narrowed below 40rem (container query).
|
|
243
|
+
default: repeat(3, minmax(0, 1fr))
|
|
244
|
+
--billing-overview-kpi-gap:
|
|
245
|
+
description: Gap between KPI stat cards.
|
|
246
|
+
default: var(--a-space-3)
|
|
247
|
+
--billing-overview-section-heading-fg:
|
|
248
|
+
description: Foreground color for section heading labels.
|
|
249
|
+
default: var(--a-fg)
|
|
250
|
+
--billing-overview-section-heading-size:
|
|
251
|
+
description: Font size for section heading labels.
|
|
252
|
+
default: var(--a-text-base, 1rem)
|
|
253
|
+
--billing-overview-section-heading-weight:
|
|
254
|
+
description: Font weight for section heading labels.
|
|
255
|
+
default: var(--a-weight-semibold, 600)
|
|
256
|
+
--billing-overview-meta-fg:
|
|
257
|
+
description: Foreground color for secondary metadata in the header.
|
|
258
|
+
default: var(--a-fg-muted)
|
|
259
|
+
|
|
260
|
+
requiredIcons:
|
|
261
|
+
- credit-card
|
|
262
|
+
- calendar
|
|
263
|
+
- users-three
|
|
264
|
+
|
|
265
|
+
a2ui:
|
|
266
|
+
rules:
|
|
267
|
+
- >-
|
|
268
|
+
BillingOverview.account is REQUIRED. The composite is meaningless
|
|
269
|
+
without an account snapshot; emitting BillingOverview with null
|
|
270
|
+
account and no data-stream-src renders the empty state.
|
|
271
|
+
- >-
|
|
272
|
+
account.status MUST be one of `active` | `trialing` | `past_due`
|
|
273
|
+
| `canceled` | `paused`. Unknown values render neutral chrome.
|
|
274
|
+
- >-
|
|
275
|
+
account.dunning is REQUIRED when account.status is `past_due`
|
|
276
|
+
(otherwise the dunning banner cannot render). Shape:
|
|
277
|
+
`{amount, currency, dueAt, cardLast4?, reason?}`. The composite
|
|
278
|
+
stamps `<alert-ui pattern="dunning">` per SPEC-006.
|
|
279
|
+
- >-
|
|
280
|
+
account.plans is REQUIRED when [variant] is `full` (otherwise
|
|
281
|
+
the plan-picker section has nothing to render). Omit `plans`
|
|
282
|
+
when [variant] is `compact` or `enterprise` to skip the
|
|
283
|
+
plan-picker section.
|
|
284
|
+
- >-
|
|
285
|
+
account.paymentMethods is forwarded verbatim to
|
|
286
|
+
<payment-method-list-ui>; account.invoices is forwarded
|
|
287
|
+
verbatim to <invoice-history-ui>. Their shapes are owned by
|
|
288
|
+
SPEC-010 and SPEC-008 respectively.
|
|
289
|
+
- >-
|
|
290
|
+
BillingOverview MUST NOT be nested inside Modal or Drawer. The
|
|
291
|
+
dashboard is a route, not a modal — Modal traps focus + clips
|
|
292
|
+
on long content; this surface is designed for full-page layout.
|
|
293
|
+
- >-
|
|
294
|
+
Wire one listener to `account-action` instead of subscribing to
|
|
295
|
+
every child primitive's event. The composite normalises
|
|
296
|
+
plan-action / payment-action / invoice-action / dunning-action
|
|
297
|
+
into the single bubbling event.
|
|
298
|
+
|
|
299
|
+
anti_patterns:
|
|
300
|
+
- wrong: |
|
|
301
|
+
{"component": "BillingOverview"}
|
|
302
|
+
why: |
|
|
303
|
+
Missing the required `account` prop. The composite renders the
|
|
304
|
+
empty state. A dashboard without data has nothing to show.
|
|
305
|
+
fix: |
|
|
306
|
+
{"component": "BillingOverview", "account":
|
|
307
|
+
{"plan": {"id":"p_pro","name":"Pro","price":48,"cycle":"month","currency":"USD","status":"active"},
|
|
308
|
+
"status": "active",
|
|
309
|
+
"billingCycle": "month",
|
|
310
|
+
"currentSpend": 48,
|
|
311
|
+
"seats": {"used": 4, "total": 10},
|
|
312
|
+
"nextInvoiceDate": "2026-06-01",
|
|
313
|
+
"paymentMethods": [...],
|
|
314
|
+
"invoices": [...]}}
|
|
315
|
+
- wrong: |
|
|
316
|
+
{"component": "Modal", "children":
|
|
317
|
+
[{"component": "BillingOverview", "account": {...}}]}
|
|
318
|
+
why: |
|
|
319
|
+
The dashboard is a route, not a modal. Modal traps focus + clips
|
|
320
|
+
content; the composite is designed for the full /billing page.
|
|
321
|
+
fix: |
|
|
322
|
+
Render the BillingOverview composite on its own route
|
|
323
|
+
(typically `/settings/billing` or `/billing`).
|
|
324
|
+
- wrong: |
|
|
325
|
+
<billing-overview-ui account='{"status":"past_due"}'></billing-overview-ui>
|
|
326
|
+
why: |
|
|
327
|
+
Past-due status without an `account.dunning` payload. The
|
|
328
|
+
composite cannot render the dunning banner (it needs amount +
|
|
329
|
+
due-at + currency to format the alert message).
|
|
330
|
+
fix: |
|
|
331
|
+
Provide a dunning object alongside the past_due status:
|
|
332
|
+
<billing-overview-ui account='{"status":"past_due","dunning":{"amount":48,"currency":"USD","dueAt":"2026-05-20"}}'></billing-overview-ui>
|
|
333
|
+
- wrong: |
|
|
334
|
+
<billing-overview-ui variant="full" account='{"plan":{...},"status":"active"}'></billing-overview-ui>
|
|
335
|
+
why: |
|
|
336
|
+
`variant=full` requires `account.plans` so the plan-picker
|
|
337
|
+
section has rows to render. Without plans, the section renders
|
|
338
|
+
its own empty-state and looks broken.
|
|
339
|
+
fix: |
|
|
340
|
+
Either pass `account.plans` OR set `variant="compact"` to hide
|
|
341
|
+
the plan-picker section entirely.
|
|
342
|
+
|
|
343
|
+
examples:
|
|
344
|
+
- name: active-pro-account
|
|
345
|
+
description: Active Pro plan with 4 saved cards + 3 invoices.
|
|
346
|
+
a2ui: |
|
|
347
|
+
[
|
|
348
|
+
{
|
|
349
|
+
"id": "bo-pro",
|
|
350
|
+
"component": "BillingOverview",
|
|
351
|
+
"variant": "full",
|
|
352
|
+
"currency": "USD",
|
|
353
|
+
"account": {
|
|
354
|
+
"plan": {
|
|
355
|
+
"id": "p_pro",
|
|
356
|
+
"name": "Pro",
|
|
357
|
+
"price": 48,
|
|
358
|
+
"cycle": "month",
|
|
359
|
+
"currency": "USD",
|
|
360
|
+
"status": "active"
|
|
361
|
+
},
|
|
362
|
+
"status": "active",
|
|
363
|
+
"billingCycle": "month",
|
|
364
|
+
"currentSpend": 48,
|
|
365
|
+
"seats": {"used": 4, "total": 10},
|
|
366
|
+
"nextInvoiceDate": "2026-06-01",
|
|
367
|
+
"plans": [],
|
|
368
|
+
"paymentMethods": [],
|
|
369
|
+
"invoices": []
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
]
|
|
373
|
+
- name: past-due-account
|
|
374
|
+
description: Past-due account with dunning banner above plan section.
|
|
375
|
+
a2ui: |
|
|
376
|
+
[
|
|
377
|
+
{
|
|
378
|
+
"id": "bo-past-due",
|
|
379
|
+
"component": "BillingOverview",
|
|
380
|
+
"variant": "full",
|
|
381
|
+
"currency": "USD",
|
|
382
|
+
"account": {
|
|
383
|
+
"plan": {
|
|
384
|
+
"id": "p_pro",
|
|
385
|
+
"name": "Pro",
|
|
386
|
+
"price": 48,
|
|
387
|
+
"cycle": "month",
|
|
388
|
+
"currency": "USD",
|
|
389
|
+
"status": "past_due"
|
|
390
|
+
},
|
|
391
|
+
"status": "past_due",
|
|
392
|
+
"billingCycle": "month",
|
|
393
|
+
"currentSpend": 48,
|
|
394
|
+
"seats": {"used": 4, "total": 10},
|
|
395
|
+
"nextInvoiceDate": "2026-05-20",
|
|
396
|
+
"dunning": {
|
|
397
|
+
"amount": 48,
|
|
398
|
+
"currency": "USD",
|
|
399
|
+
"dueAt": "2026-05-20",
|
|
400
|
+
"cardLast4": "4242",
|
|
401
|
+
"reason": "declined"
|
|
402
|
+
},
|
|
403
|
+
"plans": [],
|
|
404
|
+
"paymentMethods": [],
|
|
405
|
+
"invoices": []
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
]
|
|
409
|
+
|
|
410
|
+
keywords:
|
|
411
|
+
- billing
|
|
412
|
+
- overview
|
|
413
|
+
- dashboard
|
|
414
|
+
- account
|
|
415
|
+
- subscription
|
|
416
|
+
- plan
|
|
417
|
+
- invoice
|
|
418
|
+
- payment-method
|
|
419
|
+
- usage
|
|
420
|
+
- dunning
|
|
421
|
+
- past-due
|
|
422
|
+
|
|
423
|
+
synonyms:
|
|
424
|
+
billing:
|
|
425
|
+
- subscription
|
|
426
|
+
- account-billing
|
|
427
|
+
overview:
|
|
428
|
+
- dashboard
|
|
429
|
+
- summary
|
|
430
|
+
account:
|
|
431
|
+
- subscription
|
|
432
|
+
- membership
|
|
433
|
+
|
|
434
|
+
related:
|
|
435
|
+
- PlanPicker
|
|
436
|
+
- PaymentMethodList
|
|
437
|
+
- InvoiceHistory
|
|
438
|
+
- InvoiceDetail
|
|
439
|
+
- PaymentMethodForm
|
|
440
|
+
- Alert
|
|
441
|
+
- Stat
|
package/billing/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @adia-ai/web-modules/billing — cluster barrel.
|
|
3
|
+
*
|
|
4
|
+
* Composite billing-surface primitives that compose substrate
|
|
5
|
+
* primitives and pre-stamp the canonical shape for plan choice,
|
|
6
|
+
* pricing display, invoice list/detail, saved-payment-method flows,
|
|
7
|
+
* and card-capture forms.
|
|
8
|
+
*
|
|
9
|
+
* SPEC-004 — billing-overview-ui (module-tier billing dashboard).
|
|
10
|
+
* SPEC-007 — invoice-detail-ui (full-page invoice composite).
|
|
11
|
+
* SPEC-008 — invoice-history-ui (canonical billing-list composite).
|
|
12
|
+
* SPEC-009 — payment-method-form-ui (card capture + structured validation).
|
|
13
|
+
* SPEC-010 — payment-method-list-ui (saved payment methods with default radio).
|
|
14
|
+
* SPEC-011 — plan-picker-ui (one-of-N plan chooser, in-app + marketing).
|
|
15
|
+
*/
|
|
16
|
+
export { UIBillingOverview } from './billing-overview/billing-overview.js';
|
|
17
|
+
export { InvoiceHistory } from './invoice-history/invoice-history.js';
|
|
18
|
+
export { UIInvoiceDetail } from './invoice-detail/invoice-detail.js';
|
|
19
|
+
export { UIPaymentMethodForm } from './payment-method-form/payment-method-form.js';
|
|
20
|
+
export { PaymentMethodList } from './payment-method-list/payment-method-list.js';
|
|
21
|
+
export { PlanPicker } from './plan-picker/plan-picker.js';
|