@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.
Files changed (89) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +3 -3
  3. package/agent-admin/admin-roster/admin-roster.js +1 -1
  4. package/agent-admin/admin-settings/admin-settings.js +1 -1
  5. package/agent-admin/agent-admin/agent-admin.js +1 -1
  6. package/billing/billing-overview/billing-overview.a2ui.json +281 -0
  7. package/billing/billing-overview/billing-overview.class.js +838 -0
  8. package/billing/billing-overview/billing-overview.css +223 -0
  9. package/billing/billing-overview/billing-overview.js +16 -0
  10. package/billing/billing-overview/billing-overview.yaml +441 -0
  11. package/billing/index.js +21 -0
  12. package/billing/invoice-detail/invoice-detail.a2ui.json +276 -0
  13. package/billing/invoice-detail/invoice-detail.class.js +711 -0
  14. package/billing/invoice-detail/invoice-detail.css +305 -0
  15. package/billing/invoice-detail/invoice-detail.js +16 -0
  16. package/billing/invoice-detail/invoice-detail.yaml +411 -0
  17. package/billing/invoice-history/invoice-history.a2ui.json +315 -0
  18. package/billing/invoice-history/invoice-history.class.js +672 -0
  19. package/billing/invoice-history/invoice-history.css +130 -0
  20. package/billing/invoice-history/invoice-history.js +16 -0
  21. package/billing/invoice-history/invoice-history.yaml +398 -0
  22. package/billing/payment-method-form/payment-method-form.a2ui.json +310 -0
  23. package/billing/payment-method-form/payment-method-form.class.js +886 -0
  24. package/billing/payment-method-form/payment-method-form.css +149 -0
  25. package/billing/payment-method-form/payment-method-form.js +16 -0
  26. package/billing/payment-method-form/payment-method-form.yaml +430 -0
  27. package/billing/payment-method-list/payment-method-list.a2ui.json +283 -0
  28. package/billing/payment-method-list/payment-method-list.class.js +705 -0
  29. package/billing/payment-method-list/payment-method-list.css +128 -0
  30. package/billing/payment-method-list/payment-method-list.js +16 -0
  31. package/billing/payment-method-list/payment-method-list.yaml +355 -0
  32. package/billing/plan-picker/plan-picker.a2ui.json +349 -0
  33. package/billing/plan-picker/plan-picker.class.js +635 -0
  34. package/billing/plan-picker/plan-picker.css +227 -0
  35. package/billing/plan-picker/plan-picker.js +16 -0
  36. package/billing/plan-picker/plan-picker.yaml +453 -0
  37. package/chat/README.md +1 -1
  38. package/chat/chat-composer/chat-composer.js +2 -2
  39. package/chat/chat-empty/chat-empty.js +2 -2
  40. package/chat/chat-shell/chat-shell.js +4 -4
  41. package/chat/chat-sidebar/chat-sidebar.js +2 -2
  42. package/chat/chat-surfaces/chat-surfaces.js +2 -2
  43. package/chat/chat-thread/chat-thread.js +2 -2
  44. package/dashboard/dashboard-layout/dashboard-layout.a2ui.json +254 -0
  45. package/dashboard/dashboard-layout/dashboard-layout.css +190 -0
  46. package/dashboard/dashboard-layout/dashboard-layout.js +289 -0
  47. package/dashboard/dashboard-layout/dashboard-layout.yaml +374 -0
  48. package/dashboard/date-range-selector/date-range-selector.a2ui.json +236 -0
  49. package/dashboard/date-range-selector/date-range-selector.css +84 -0
  50. package/dashboard/date-range-selector/date-range-selector.js +686 -0
  51. package/dashboard/date-range-selector/date-range-selector.yaml +358 -0
  52. package/dashboard/index.js +14 -0
  53. package/dist/everything.min.js +1 -1
  54. package/editor/editor-canvas/editor-canvas.js +2 -2
  55. package/editor/editor-shell/editor-shell.js +2 -2
  56. package/editor/editor-sidebar/editor-sidebar.js +2 -2
  57. package/editor/editor-toolbar/editor-toolbar.js +2 -2
  58. package/feedback/confirm-dialog/confirm-dialog.a2ui.json +206 -0
  59. package/feedback/confirm-dialog/confirm-dialog.css +157 -0
  60. package/feedback/confirm-dialog/confirm-dialog.js +383 -0
  61. package/feedback/confirm-dialog/confirm-dialog.yaml +297 -0
  62. package/feedback/index.js +10 -0
  63. package/form/form-popover/form-popover.js +1 -1
  64. package/generative/index.d.ts +1 -1
  65. package/generative/index.js +2 -2
  66. package/onboarding/index.js +1 -0
  67. package/onboarding/onboarding-checklist/onboarding-checklist.a2ui.json +263 -0
  68. package/onboarding/onboarding-checklist/onboarding-checklist.css +157 -0
  69. package/onboarding/onboarding-checklist/onboarding-checklist.js +428 -0
  70. package/onboarding/onboarding-checklist/onboarding-checklist.yaml +236 -0
  71. package/package.json +99 -6
  72. package/runtime/a2ui-root/a2ui-root.js +3 -3
  73. package/runtime/gen-root/gen-root.js +5 -5
  74. package/settings/index.js +12 -0
  75. package/settings/integrations-page/integrations-page.a2ui.json +274 -0
  76. package/settings/integrations-page/integrations-page.css +177 -0
  77. package/settings/integrations-page/integrations-page.d.ts +77 -0
  78. package/settings/integrations-page/integrations-page.js +413 -0
  79. package/settings/integrations-page/integrations-page.yaml +317 -0
  80. package/settings/notification-preferences/notification-preferences.a2ui.json +245 -0
  81. package/settings/notification-preferences/notification-preferences.css +204 -0
  82. package/settings/notification-preferences/notification-preferences.js +622 -0
  83. package/settings/notification-preferences/notification-preferences.yaml +358 -0
  84. package/shell/admin-command/admin-command.js +2 -2
  85. package/shell/admin-shell/admin-shell.js +2 -2
  86. package/shell/admin-sidebar/admin-sidebar.js +2 -2
  87. package/shell/embed-shell/embed-shell.js +3 -3
  88. package/simple/simple-shell/simple-shell.js +1 -1
  89. 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
@@ -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';