@adia-ai/adia-ui-factory 0.2.2 → 0.2.3
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/.claude-plugin/plugin.json +12 -3
- package/CHANGELOG.md +8 -0
- package/README.md +24 -1
- package/bin/adia-scaffold +93 -13
- package/package.json +2 -2
- package/references/shell-embed.md +10 -0
- package/references/spa-architecture.md +7 -0
- package/skills/adia-ui-kit/CHANGELOG.md +41 -0
- package/skills/adia-ui-kit/SKILL.md +442 -0
- package/skills/adia-ui-kit/assets/figma-make/guidelines/Guidelines.md +87 -0
- package/skills/adia-ui-kit/assets/figma-make/guidelines/components.md +142 -0
- package/skills/adia-ui-kit/assets/figma-make/guidelines/styles.md +118 -0
- package/skills/adia-ui-kit/assets/figma-make/guidelines/tokens.md +120 -0
- package/skills/adia-ui-kit/assets/team-scaffold/archive-README.md +30 -0
- package/skills/adia-ui-kit/assets/team-scaffold/drafts-README.md +57 -0
- package/skills/adia-ui-kit/assets/team-scaffold/inbox-README.md +76 -0
- package/skills/adia-ui-kit/assets/team-scaffold/outbox-README.md +46 -0
- package/skills/adia-ui-kit/assets/team-scaffold/team-root.README.md +51 -0
- package/skills/adia-ui-kit/assets/team-scaffold/tickets-README.md +208 -0
- package/skills/adia-ui-kit/assets/team-scaffold/tickets-REGISTRY.md +81 -0
- package/skills/adia-ui-kit/assets/templates/AGENTS.template.md +128 -0
- package/skills/adia-ui-kit/assets/templates/CLAUDE.template.md +1 -0
- package/skills/adia-ui-kit/assets/templates/FEEDBACK-OMISSIONS-DEFENSE.template.md +150 -0
- package/skills/adia-ui-kit/assets/templates/FEEDBACK.template.md +213 -0
- package/skills/adia-ui-kit/assets/templates/RESPONSE.template.md +114 -0
- package/skills/adia-ui-kit/assets/templates/figma-make-guidelines.md +90 -0
- package/skills/adia-ui-kit/evals/adversarial-content-trust.json +83 -0
- package/skills/adia-ui-kit/evals/evals.json +55 -0
- package/skills/adia-ui-kit/evals/routing-corpus.json +121 -0
- package/skills/adia-ui-kit/evals/teach-routing-cases.json +92 -0
- package/skills/adia-ui-kit/references/capabilities.md +245 -0
- package/skills/adia-ui-kit/references/catalog-lookup.md +186 -0
- package/skills/adia-ui-kit/references/changelog-archive/CHANGELOG-v1.md +8 -0
- package/skills/adia-ui-kit/references/changelog-archive/CHANGELOG-v2.md +3585 -0
- package/skills/adia-ui-kit/references/changelog-archive/CHANGELOG-v3.md +1899 -0
- package/skills/adia-ui-kit/references/common-gotchas-consumer.md +522 -0
- package/skills/adia-ui-kit/references/component-literacy.md +291 -0
- package/skills/adia-ui-kit/references/composition.md +245 -0
- package/skills/adia-ui-kit/references/correction-loop.md +462 -0
- package/skills/adia-ui-kit/references/css-policy.md +343 -0
- package/skills/adia-ui-kit/references/decision-model.md +158 -0
- package/skills/adia-ui-kit/references/diagnostic-output.md +57 -0
- package/skills/adia-ui-kit/references/docs-catalog.md +239 -0
- package/skills/adia-ui-kit/references/exclusions.md +225 -0
- package/skills/adia-ui-kit/references/feedback-authoring.md +466 -0
- package/skills/adia-ui-kit/references/figma-make.md +244 -0
- package/skills/adia-ui-kit/references/flows-auth.md +307 -0
- package/skills/adia-ui-kit/references/flows-content.md +206 -0
- package/skills/adia-ui-kit/references/flows-data.md +348 -0
- package/skills/adia-ui-kit/references/flows-interaction.md +181 -0
- package/skills/adia-ui-kit/references/flows-shells.md +336 -0
- package/skills/adia-ui-kit/references/gap-detection.md +266 -0
- package/skills/adia-ui-kit/references/harness.md +284 -0
- package/skills/adia-ui-kit/references/loading-protocol.md +406 -0
- package/skills/adia-ui-kit/references/local-link.md +198 -0
- package/skills/adia-ui-kit/references/mcp.md +401 -0
- package/skills/adia-ui-kit/references/migration.md +116 -0
- package/skills/adia-ui-kit/references/mission.md +194 -0
- package/skills/adia-ui-kit/references/mode-routing.md +298 -0
- package/skills/adia-ui-kit/references/patterns-agent.md +223 -0
- package/skills/adia-ui-kit/references/patterns-data.md +1066 -0
- package/skills/adia-ui-kit/references/patterns-forms.md +223 -0
- package/skills/adia-ui-kit/references/patterns-layout.md +326 -0
- package/skills/adia-ui-kit/references/patterns-recipes.md +1416 -0
- package/skills/adia-ui-kit/references/patterns-shells.md +1097 -0
- package/skills/adia-ui-kit/references/patterns-traits.md +259 -0
- package/skills/adia-ui-kit/references/patterns-wiring.md +339 -0
- package/skills/adia-ui-kit/references/pev-rationale.md +137 -0
- package/skills/adia-ui-kit/references/reasoning-gate.md +146 -0
- package/skills/adia-ui-kit/references/reasoning-methodologies.md +112 -0
- package/skills/adia-ui-kit/references/recon.md +192 -0
- package/skills/adia-ui-kit/references/rendering-model.md +431 -0
- package/skills/adia-ui-kit/references/response-authoring.md +398 -0
- package/skills/adia-ui-kit/references/session-log-schema.md +203 -0
- package/skills/adia-ui-kit/references/session-log-template.md +118 -0
- package/skills/adia-ui-kit/references/setup.md +652 -0
- package/skills/adia-ui-kit/references/skill-hygiene.md +135 -0
- package/skills/adia-ui-kit/references/spec-to-ui-reasoning.md +394 -0
- package/skills/adia-ui-kit/references/state.md +229 -0
- package/skills/adia-ui-kit/references/teach-protocol.md +421 -0
- package/skills/adia-ui-kit/references/theme.md +142 -0
- package/skills/adia-ui-kit/references/version-check.md +69 -0
- package/skills/adia-ui-kit/scripts/audit-decision-trace.mjs +198 -0
- package/skills/adia-ui-kit/scripts/audit-kit-roster.mjs +366 -0
- package/skills/adia-ui-kit/scripts/changelog-archive.mjs +126 -0
- package/skills/adia-ui-kit/scripts/check-adia-versions.py +404 -0
- package/skills/adia-ui-kit/scripts/run-skill-evals.mjs +358 -0
- package/skills/adia-ui-kit/scripts/validate-session-log.mjs +242 -0
- package/skills/adia-ui-kit/skill.json +102 -0
- package/skills/adia-ui-migration/CHANGELOG.md +47 -0
- package/skills/adia-ui-migration/SKILL.md +381 -0
- package/skills/adia-ui-migration/skill.json +29 -0
- package/skills/adia-ui-spa/SKILL.md +1 -1
- package/skills/adia-ui-verify/SKILL.md +2 -2
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# §Flows — Error pages, kanban boards, agent surfaces
|
|
2
|
+
|
|
3
|
+
> **Loading note.** Reference bundle extracted from `SKILL.md` per the
|
|
4
|
+
> §LoadingProtocol inversion contract (v2.20.3+). Load via
|
|
5
|
+
> `skill_view(name='adia-ui-kit', file_path='references/flows-content.md')`
|
|
6
|
+
> When wiring content-tier surfaces — 404/500 error pages, kanban with drag-friendly columns, agent reasoning + activity + chat panes. Skip if your task doesn't involve these surfaces — the
|
|
7
|
+
> seed has a stub naming each flow + the load invocation.
|
|
8
|
+
|
|
9
|
+
### Error pages (404, 500, maintenance)
|
|
10
|
+
|
|
11
|
+
All three share the same shape: centered hero, brand mark, heading,
|
|
12
|
+
explanatory text, optional alert with diagnostic info, primary action.
|
|
13
|
+
The canonical wrapper is `<simple-shell centered>` + `<simple-hero>` —
|
|
14
|
+
substrate ships this exactly for error / 404 / 500 / maintenance / thank-you
|
|
15
|
+
flows. Do **not** hand-roll `<main style="display: grid; place-items: center">`
|
|
16
|
+
+ `<card-ui>` for these surfaces — that re-implements `[centered]` and
|
|
17
|
+
bypasses the canonical slot vocabulary.
|
|
18
|
+
|
|
19
|
+
**404 — page not found:**
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<simple-shell centered>
|
|
23
|
+
<simple-hero>
|
|
24
|
+
<img slot="heading" src="/logo.svg" alt="" style="height: 4rem" />
|
|
25
|
+
<h1 slot="heading">404 — Page not found</h1>
|
|
26
|
+
<p slot="lede">We couldn't find that page. It may have moved or never existed.</p>
|
|
27
|
+
<div slot="actions">
|
|
28
|
+
<button-ui text="Go to home" variant="primary" icon="house"
|
|
29
|
+
onclick="location.href = '/'"></button-ui>
|
|
30
|
+
<button-ui text="Go back" variant="outline" icon="arrow-left"
|
|
31
|
+
onclick="history.back()"></button-ui>
|
|
32
|
+
</div>
|
|
33
|
+
<alert-ui variant="info" icon="map-trifold">
|
|
34
|
+
<span slot="content">Path: <code>/that/route/that/wasnt/found</code></span>
|
|
35
|
+
</alert-ui>
|
|
36
|
+
</simple-hero>
|
|
37
|
+
</simple-shell>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**500 — server error** (substitutions: `<alert-ui variant="warning" icon="warning">`,
|
|
41
|
+
heading "Something went wrong", trace ID + "Try again" / "Status page" actions).
|
|
42
|
+
|
|
43
|
+
**Maintenance** (substitutions: `<alert-ui variant="info" icon="wrench">`, heading
|
|
44
|
+
"We'll be right back", window/affected services + "Status page" action).
|
|
45
|
+
|
|
46
|
+
> **Pitfall:** error pages render before `installIconLoadersForRegistered`
|
|
47
|
+
> if the JS fails to load. Inline an SVG fallback for the logo, and prefer
|
|
48
|
+
> `text` over `icon=` for critical alerts on the 500 path.
|
|
49
|
+
|
|
50
|
+
> **CSS-import note:** when using the bundler path, import the simple-shell
|
|
51
|
+
> stylesheet alongside the primitives bundle:
|
|
52
|
+
> `import '@adia-ai/web-modules/simple/simple-shell.css';`
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Kanban board (3-column drag-friendly)
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<grid-ui columns="3" gap="4">
|
|
61
|
+
<card-ui raw>
|
|
62
|
+
<header>
|
|
63
|
+
<row-ui gap="2" align="center">
|
|
64
|
+
<text-ui weight="semibold">To Do</text-ui>
|
|
65
|
+
<badge-ui text="3" variant="muted" size="sm"></badge-ui>
|
|
66
|
+
</row-ui>
|
|
67
|
+
</header>
|
|
68
|
+
<section>
|
|
69
|
+
<col-ui gap="2">
|
|
70
|
+
<card-ui size="sm" draggable><section><text-ui>Design system tokens</text-ui></section></card-ui>
|
|
71
|
+
<card-ui size="sm" draggable><section><text-ui>Component audit</text-ui></section></card-ui>
|
|
72
|
+
<card-ui size="sm" draggable><section><text-ui>Accessibility review</text-ui></section></card-ui>
|
|
73
|
+
</col-ui>
|
|
74
|
+
</section>
|
|
75
|
+
</card-ui>
|
|
76
|
+
<card-ui raw>
|
|
77
|
+
<header>
|
|
78
|
+
<row-ui gap="2" align="center">
|
|
79
|
+
<text-ui weight="semibold">In Progress</text-ui>
|
|
80
|
+
<badge-ui text="2" variant="accent" size="sm"></badge-ui>
|
|
81
|
+
</row-ui>
|
|
82
|
+
</header>
|
|
83
|
+
<section>
|
|
84
|
+
<col-ui gap="2">
|
|
85
|
+
<card-ui size="sm" draggable><section><text-ui>Dark mode palette</text-ui></section></card-ui>
|
|
86
|
+
<card-ui size="sm" draggable><section><text-ui>Button variants</text-ui></section></card-ui>
|
|
87
|
+
</col-ui>
|
|
88
|
+
</section>
|
|
89
|
+
</card-ui>
|
|
90
|
+
<card-ui raw>
|
|
91
|
+
<header>
|
|
92
|
+
<row-ui gap="2" align="center">
|
|
93
|
+
<text-ui weight="semibold">Done</text-ui>
|
|
94
|
+
<badge-ui text="5" variant="success" size="sm"></badge-ui>
|
|
95
|
+
</row-ui>
|
|
96
|
+
</header>
|
|
97
|
+
<section><!-- done cards --></section>
|
|
98
|
+
</card-ui>
|
|
99
|
+
</grid-ui>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The `draggable` trait wires native HTML5 drag-and-drop on each card.
|
|
103
|
+
Listen for `dragstart` / `dragover` / `drop` on the column `<section>` to
|
|
104
|
+
move cards between columns.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
### Agent surface (reasoning + activity + chat)
|
|
110
|
+
|
|
111
|
+
The full AI/agent UI: reasoning trace, streaming chat, activity feed,
|
|
112
|
+
artifact previews.
|
|
113
|
+
|
|
114
|
+
**Chat streaming surface:**
|
|
115
|
+
|
|
116
|
+
```html
|
|
117
|
+
<card-ui raw style="height: 100%">
|
|
118
|
+
<section style="overflow: auto; flex: 1">
|
|
119
|
+
<chat-thread-ui id="thread" streaming>
|
|
120
|
+
<div role="user">What's the status?</div>
|
|
121
|
+
<div role="assistant">Processing your request...</div>
|
|
122
|
+
</chat-thread-ui>
|
|
123
|
+
</section>
|
|
124
|
+
<footer>
|
|
125
|
+
<row-ui gap="2" align="center">
|
|
126
|
+
<chat-input-ui id="prompt" placeholder="Ask follow-up..." style="flex:1"></chat-input-ui>
|
|
127
|
+
<button-ui id="send-btn" icon="paper-plane-right" variant="primary" size="sm"></button-ui>
|
|
128
|
+
</row-ui>
|
|
129
|
+
</footer>
|
|
130
|
+
</card-ui>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Live reasoning trace** (paired alongside the chat):
|
|
134
|
+
|
|
135
|
+
```html
|
|
136
|
+
<card-ui>
|
|
137
|
+
<header>
|
|
138
|
+
<h3>Agent Activity</h3>
|
|
139
|
+
<text-ui slot="description" color="subtle">Live reasoning trace</text-ui>
|
|
140
|
+
</header>
|
|
141
|
+
<section>
|
|
142
|
+
<col-ui gap="3">
|
|
143
|
+
<agent-trace-ui></agent-trace-ui>
|
|
144
|
+
<agent-reasoning-ui></agent-reasoning-ui>
|
|
145
|
+
<agent-artifact-ui></agent-artifact-ui>
|
|
146
|
+
</col-ui>
|
|
147
|
+
</section>
|
|
148
|
+
</card-ui>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Imports needed** (none are in the barrel for the agent cluster):
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
import '@adia-ai/web-components/components/chat-thread/chat-thread.js';
|
|
155
|
+
import '@adia-ai/web-components/components/chat-thread/chat-input.js';
|
|
156
|
+
import '@adia-ai/web-components/components/agent-reasoning/agent-reasoning.js';
|
|
157
|
+
import '@adia-ai/web-components/components/agent-trace/agent-trace.js';
|
|
158
|
+
import '@adia-ai/web-components/components/agent-artifact/agent-artifact.js';
|
|
159
|
+
import '@adia-ai/web-components/components/agent-feedback-bar/agent-feedback-bar.js';
|
|
160
|
+
import '@adia-ai/web-components/components/agent-suggestions/agent-suggestions.js';
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Sending a message + handling streaming:**
|
|
164
|
+
|
|
165
|
+
```js
|
|
166
|
+
const thread = document.getElementById('thread');
|
|
167
|
+
const prompt = document.getElementById('prompt');
|
|
168
|
+
const send = document.getElementById('send-btn');
|
|
169
|
+
|
|
170
|
+
send.addEventListener('press', async () => {
|
|
171
|
+
const text = prompt.value.trim();
|
|
172
|
+
if (!text) return;
|
|
173
|
+
prompt.value = '';
|
|
174
|
+
|
|
175
|
+
// Add user bubble
|
|
176
|
+
thread.appendMessage({ role: 'user', content: text });
|
|
177
|
+
// Add empty assistant bubble that will fill via streaming
|
|
178
|
+
const asstId = thread.appendMessage({ role: 'assistant', content: '', streaming: true });
|
|
179
|
+
|
|
180
|
+
// Stream from /api/chat (or your LLM endpoint)
|
|
181
|
+
const res = await fetch('/api/chat', {
|
|
182
|
+
method: 'POST',
|
|
183
|
+
headers: { 'Content-Type': 'application/json' },
|
|
184
|
+
body: JSON.stringify({ messages: [{ role: 'user', content: text }] }),
|
|
185
|
+
});
|
|
186
|
+
const reader = res.body.getReader();
|
|
187
|
+
const decoder = new TextDecoder();
|
|
188
|
+
let buffer = '';
|
|
189
|
+
while (true) {
|
|
190
|
+
const { done, value } = await reader.read();
|
|
191
|
+
if (done) break;
|
|
192
|
+
buffer += decoder.decode(value, { stream: true });
|
|
193
|
+
// Parse SSE-style data: lines
|
|
194
|
+
for (const line of buffer.split('\n')) {
|
|
195
|
+
if (line.startsWith('data: ')) {
|
|
196
|
+
const chunk = JSON.parse(line.slice(6));
|
|
197
|
+
thread.appendToMessage(asstId, chunk.text);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
thread.finalizeMessage(asstId);
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# §Flows — Settings, tables, dashboards, charts
|
|
2
|
+
|
|
3
|
+
> **Loading note.** Reference bundle extracted from `SKILL.md` per the
|
|
4
|
+
> §LoadingProtocol inversion contract (v2.20.3+). Load via
|
|
5
|
+
> `skill_view(name='adia-ui-kit', file_path='references/flows-data.md')`
|
|
6
|
+
> When wiring data-display surfaces — preference panes, sortable tables, KPI strips, chart-card pairings. Skip if your task doesn't involve these surfaces — the
|
|
7
|
+
> seed has a stub naming each flow + the load invocation.
|
|
8
|
+
|
|
9
|
+
### Settings page
|
|
10
|
+
|
|
11
|
+
`aside | data-col` two-column layout. Each group is a `<section>`
|
|
12
|
+
separated by `<divider-ui>`. Danger actions open `<drawer-ui>`.
|
|
13
|
+
|
|
14
|
+
```html
|
|
15
|
+
<admin-page-body>
|
|
16
|
+
<section-ui>
|
|
17
|
+
<article>
|
|
18
|
+
|
|
19
|
+
<section>
|
|
20
|
+
<h2>Workspace</h2>
|
|
21
|
+
<div data-section>
|
|
22
|
+
<aside><h3>Details</h3><p>Name and identify your workspace.</p></aside>
|
|
23
|
+
<col-ui gap="4">
|
|
24
|
+
<field-ui label="Workspace name">
|
|
25
|
+
<input-ui name="name" value="Acme Inc."></input-ui>
|
|
26
|
+
</field-ui>
|
|
27
|
+
<field-ui label="Slug">
|
|
28
|
+
<input-ui name="slug" prefix="/" value="acme"></input-ui>
|
|
29
|
+
</field-ui>
|
|
30
|
+
<field-ui label="Description">
|
|
31
|
+
<textarea-ui name="description" rows="3"></textarea-ui>
|
|
32
|
+
</field-ui>
|
|
33
|
+
<row-ui justify="flex-end">
|
|
34
|
+
<button-ui text="Save changes" variant="primary"></button-ui>
|
|
35
|
+
</row-ui>
|
|
36
|
+
</col-ui>
|
|
37
|
+
</div>
|
|
38
|
+
</section>
|
|
39
|
+
|
|
40
|
+
<divider-ui></divider-ui>
|
|
41
|
+
|
|
42
|
+
<section>
|
|
43
|
+
<h2>Appearance</h2>
|
|
44
|
+
<div data-section>
|
|
45
|
+
<aside><h3>Theme</h3><p>Light, dark, or system.</p></aside>
|
|
46
|
+
<col-ui>
|
|
47
|
+
<field-ui label="Color scheme" inline>
|
|
48
|
+
<segmented-ui value="auto">
|
|
49
|
+
<segment-ui value="light" text="Light"></segment-ui>
|
|
50
|
+
<segment-ui value="dark" text="Dark"></segment-ui>
|
|
51
|
+
<segment-ui value="auto" text="System"></segment-ui>
|
|
52
|
+
</segmented-ui>
|
|
53
|
+
</field-ui>
|
|
54
|
+
</col-ui>
|
|
55
|
+
</div>
|
|
56
|
+
</section>
|
|
57
|
+
|
|
58
|
+
<divider-ui></divider-ui>
|
|
59
|
+
|
|
60
|
+
<section>
|
|
61
|
+
<h2>Notifications</h2>
|
|
62
|
+
<div data-section>
|
|
63
|
+
<aside><h3>Preferences</h3><p>What to be notified about.</p></aside>
|
|
64
|
+
<col-ui gap="3">
|
|
65
|
+
<switch-ui name="email-digest" label="Weekly email digest" checked></switch-ui>
|
|
66
|
+
<switch-ui name="push-mentions" label="Push on @mention" checked></switch-ui>
|
|
67
|
+
<switch-ui name="push-assigns" label="Push on assignment"></switch-ui>
|
|
68
|
+
</col-ui>
|
|
69
|
+
</div>
|
|
70
|
+
</section>
|
|
71
|
+
|
|
72
|
+
<divider-ui></divider-ui>
|
|
73
|
+
|
|
74
|
+
<section>
|
|
75
|
+
<h2>Danger zone</h2>
|
|
76
|
+
<div data-section>
|
|
77
|
+
<aside><h3>Delete workspace</h3><p>Permanent and irreversible.</p></aside>
|
|
78
|
+
<col-ui>
|
|
79
|
+
<button-ui text="Delete workspace" variant="danger"
|
|
80
|
+
onclick="document.getElementById('drawer-delete').open = true">
|
|
81
|
+
</button-ui>
|
|
82
|
+
</col-ui>
|
|
83
|
+
</div>
|
|
84
|
+
</section>
|
|
85
|
+
|
|
86
|
+
</article>
|
|
87
|
+
</section-ui>
|
|
88
|
+
|
|
89
|
+
<drawer-ui id="drawer-delete" side="right">
|
|
90
|
+
<card-ui>
|
|
91
|
+
<header slot="header"><span slot="heading">Delete workspace?</span></header>
|
|
92
|
+
<section>
|
|
93
|
+
<col-ui gap="4">
|
|
94
|
+
<alert-ui variant="danger" icon="warning">
|
|
95
|
+
<span slot="content">This cannot be undone.</span>
|
|
96
|
+
</alert-ui>
|
|
97
|
+
<field-ui label="Type workspace name to confirm">
|
|
98
|
+
<input-ui name="confirm" placeholder="Acme Inc."></input-ui>
|
|
99
|
+
</field-ui>
|
|
100
|
+
</col-ui>
|
|
101
|
+
</section>
|
|
102
|
+
<footer slot="footer">
|
|
103
|
+
<row-ui gap="2" justify="flex-end">
|
|
104
|
+
<button-ui text="Cancel" variant="ghost"
|
|
105
|
+
onclick="this.closest('drawer-ui').open = false"></button-ui>
|
|
106
|
+
<button-ui text="Delete" variant="danger"></button-ui>
|
|
107
|
+
</row-ui>
|
|
108
|
+
</footer>
|
|
109
|
+
</card-ui>
|
|
110
|
+
</drawer-ui>
|
|
111
|
+
</admin-page-body>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
### Tables
|
|
118
|
+
|
|
119
|
+
**Always pair `<table-ui>` with `<table-toolbar-ui>`.**
|
|
120
|
+
Columns and data are set via JavaScript — never via HTML attributes.
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<card-ui>
|
|
124
|
+
<header><span slot="heading">Users</span></header>
|
|
125
|
+
<section style="padding: 0;">
|
|
126
|
+
<table-toolbar-ui id="users-toolbar"></table-toolbar-ui>
|
|
127
|
+
<table-ui id="users-table" sortable selectable striped></table-ui>
|
|
128
|
+
</section>
|
|
129
|
+
</card-ui>
|
|
130
|
+
|
|
131
|
+
<script type="module">
|
|
132
|
+
const table = document.getElementById('users-table');
|
|
133
|
+
const toolbar = document.getElementById('users-toolbar');
|
|
134
|
+
toolbar.table = table; // links search/sort/export to the table
|
|
135
|
+
|
|
136
|
+
table.columns = [
|
|
137
|
+
{ key: 'name', label: 'Name', type: 'avatar' },
|
|
138
|
+
{ key: 'email', label: 'Email', type: 'link' },
|
|
139
|
+
{ key: 'status', label: 'Status', type: 'badge',
|
|
140
|
+
meta: { variants: { Active: 'success', Pending: 'warning', Inactive: 'danger' } } },
|
|
141
|
+
{ key: 'role', label: 'Role' },
|
|
142
|
+
{ key: 'joined', label: 'Joined', type: 'date' },
|
|
143
|
+
{ key: 'id', label: '', type: 'actions', width: 80,
|
|
144
|
+
meta: { actions: [
|
|
145
|
+
{ icon: 'pencil-simple', label: 'Edit', event: 'edit-row' },
|
|
146
|
+
{ icon: 'trash', label: 'Delete', event: 'delete-row' },
|
|
147
|
+
] } },
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
// Static data or fetch from endpoint
|
|
151
|
+
table.data = [
|
|
152
|
+
{ id: 1, name: 'Alice Johnson', email: 'alice@acme.com', role: 'Engineer',
|
|
153
|
+
status: 'Active', joined: '2024-03-15' },
|
|
154
|
+
{ id: 2, name: 'Bob Smith', email: 'bob@acme.com', role: 'Designer',
|
|
155
|
+
status: 'Pending', joined: '2024-05-22' },
|
|
156
|
+
];
|
|
157
|
+
// fetch('/api/users').then(r => r.json()).then(d => { table.data = d.items; });
|
|
158
|
+
|
|
159
|
+
table.addEventListener('edit-row', e => console.log('edit', e.detail.row));
|
|
160
|
+
table.addEventListener('delete-row', e => console.log('delete', e.detail.row));
|
|
161
|
+
</script>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Cell type reference:**
|
|
165
|
+
|
|
166
|
+
| `type` | Renders | `meta` shape |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| (default) | Plain string | — |
|
|
169
|
+
| `avatar` | Avatar + name | — |
|
|
170
|
+
| `link` | Anchor `<a>` | `{ href: row => '/users/' + row.id }` |
|
|
171
|
+
| `badge` | `<badge-ui>` | `{ variants: { Active: 'success' } }` |
|
|
172
|
+
| `progress` | Progress bar | — |
|
|
173
|
+
| `date` | Formatted date | `{ format: 'relative' }` |
|
|
174
|
+
| `actions` | Icon buttons | `{ actions: [{icon, label, event}] }` |
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
### Dashboard + KPI
|
|
180
|
+
|
|
181
|
+
```html
|
|
182
|
+
<admin-page-body>
|
|
183
|
+
<section-ui data-full-bleed>
|
|
184
|
+
<col-ui gap="6">
|
|
185
|
+
|
|
186
|
+
<!-- 4-column KPI strip -->
|
|
187
|
+
<grid-ui columns="4" gap="4">
|
|
188
|
+
<card-ui size="sm"><section>
|
|
189
|
+
<stat-ui label="Revenue" value="$45,231" change="+20.1%" trend="up" icon="currency-dollar">
|
|
190
|
+
</stat-ui>
|
|
191
|
+
</section></card-ui>
|
|
192
|
+
<card-ui size="sm"><section>
|
|
193
|
+
<stat-ui label="Subscriptions" value="+2,350" change="+180%" trend="up" icon="users">
|
|
194
|
+
</stat-ui>
|
|
195
|
+
</section></card-ui>
|
|
196
|
+
<card-ui size="sm"><section>
|
|
197
|
+
<stat-ui label="Sales" value="+12,234" change="+19%" trend="up" icon="credit-card">
|
|
198
|
+
</stat-ui>
|
|
199
|
+
</section></card-ui>
|
|
200
|
+
<card-ui size="sm"><section>
|
|
201
|
+
<stat-ui label="Active Now" value="+573" change="+201" trend="up" icon="chart-bar">
|
|
202
|
+
</stat-ui>
|
|
203
|
+
</section></card-ui>
|
|
204
|
+
</grid-ui>
|
|
205
|
+
|
|
206
|
+
<!-- Chart (3 cols) + activity feed (2 cols) -->
|
|
207
|
+
<grid-ui columns="5" gap="4">
|
|
208
|
+
<card-ui style="grid-column: span 3">
|
|
209
|
+
<header><span slot="heading">Revenue over time</span></header>
|
|
210
|
+
<section>
|
|
211
|
+
<chart-ui id="revenue-chart" type="area" x="month" y="revenue"></chart-ui>
|
|
212
|
+
</section>
|
|
213
|
+
</card-ui>
|
|
214
|
+
<card-ui style="grid-column: span 2">
|
|
215
|
+
<header><span slot="heading">Recent activity</span></header>
|
|
216
|
+
<section><!-- activity list --></section>
|
|
217
|
+
</card-ui>
|
|
218
|
+
</grid-ui>
|
|
219
|
+
|
|
220
|
+
<!-- Transactions table -->
|
|
221
|
+
<card-ui>
|
|
222
|
+
<header><span slot="heading">Recent transactions</span></header>
|
|
223
|
+
<section style="padding: 0;">
|
|
224
|
+
<table-toolbar-ui id="txn-toolbar"></table-toolbar-ui>
|
|
225
|
+
<table-ui id="txn-table" sortable striped></table-ui>
|
|
226
|
+
</section>
|
|
227
|
+
</card-ui>
|
|
228
|
+
|
|
229
|
+
</col-ui>
|
|
230
|
+
</section-ui>
|
|
231
|
+
<!--
|
|
232
|
+
Note on <section-ui data-full-bleed>: admin-page-body wraps an inner
|
|
233
|
+
<section-ui> by default for centered reading-column rhythm (per
|
|
234
|
+
admin-page-body.yaml a2ui rules). Dashboards with tables/charts/
|
|
235
|
+
grids want full content width — opt into that with [data-full-bleed]
|
|
236
|
+
on the wrapping <section-ui>. For text-heavy pages (settings forms,
|
|
237
|
+
documentation), use <section-ui> without [data-full-bleed] to get
|
|
238
|
+
the centered reading column.
|
|
239
|
+
-->
|
|
240
|
+
</admin-page-body>
|
|
241
|
+
|
|
242
|
+
<script type="module">
|
|
243
|
+
// Charts: data MUST be set via JS — not HTML attributes
|
|
244
|
+
document.getElementById('revenue-chart').data = [
|
|
245
|
+
{ month: 'Jan', revenue: 40 }, { month: 'Feb', revenue: 55 },
|
|
246
|
+
{ month: 'Mar', revenue: 48 }, { month: 'Apr', revenue: 62 },
|
|
247
|
+
{ month: 'May', revenue: 70 }, { month: 'Jun', revenue: 65 },
|
|
248
|
+
];
|
|
249
|
+
|
|
250
|
+
const txn = document.getElementById('txn-table');
|
|
251
|
+
document.getElementById('txn-toolbar').table = txn;
|
|
252
|
+
txn.columns = [
|
|
253
|
+
{ key: 'customer', label: 'Customer', type: 'avatar' },
|
|
254
|
+
{ key: 'amount', label: 'Amount' },
|
|
255
|
+
{ key: 'status', label: 'Status', type: 'badge',
|
|
256
|
+
meta: { variants: { Paid: 'success', Pending: 'warning', Failed: 'danger' } } },
|
|
257
|
+
{ key: 'date', label: 'Date', type: 'date' },
|
|
258
|
+
];
|
|
259
|
+
// txn.data = await fetch('/api/transactions').then(r => r.json()).then(d => d.items);
|
|
260
|
+
</script>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
### Charts
|
|
267
|
+
|
|
268
|
+
`<chart-ui>` **requires `.data` set via JS** — HTML only declares `type`, `x`, `y`.
|
|
269
|
+
|
|
270
|
+
**18 types across 5 families:**
|
|
271
|
+
|
|
272
|
+
| Family | Types |
|
|
273
|
+
|---|---|
|
|
274
|
+
| Axis | `bar`, `line`, `area`, `scatter`, `sparkline` |
|
|
275
|
+
| Categorical | `pie`, `donut`, `segments` |
|
|
276
|
+
| Radial | `radar`, `radial-bar`, `gauge` |
|
|
277
|
+
| Multi-series | `stacked-bar`, `grouped-bar`, `multi-line`, `composed` |
|
|
278
|
+
| Flow/hierarchy | `funnel`, `treemap`, `sankey` |
|
|
279
|
+
|
|
280
|
+
**Wiring template:**
|
|
281
|
+
|
|
282
|
+
```html
|
|
283
|
+
<chart-ui id="my-chart" type="bar" x="month" y="value"></chart-ui>
|
|
284
|
+
<chart-legend-ui for="my-chart"></chart-legend-ui>
|
|
285
|
+
<tooltip-ui follows="pointer"></tooltip-ui>
|
|
286
|
+
|
|
287
|
+
<script type="module">
|
|
288
|
+
// Single-series (bar, line, area, scatter, sparkline)
|
|
289
|
+
document.getElementById('my-chart').data = [
|
|
290
|
+
{ month: 'Jan', value: 30 }, { month: 'Feb', value: 45 },
|
|
291
|
+
{ month: 'Mar', value: 28 }, { month: 'Apr', value: 62 },
|
|
292
|
+
];
|
|
293
|
+
|
|
294
|
+
// Multi-series — extra keys beyond y become additional series
|
|
295
|
+
// el.data = [{ quarter: 'Q1', desktop: 40, mobile: 25 }, ...];
|
|
296
|
+
|
|
297
|
+
// Gauge — needs max field
|
|
298
|
+
// el.data = [{ label: 'Capacity', value: 72, max: 100 }];
|
|
299
|
+
</script>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**KPI + sparkline card:**
|
|
303
|
+
|
|
304
|
+
```html
|
|
305
|
+
<card-ui size="sm">
|
|
306
|
+
<section>
|
|
307
|
+
<row-ui justify="space-between" align="flex-start">
|
|
308
|
+
<col-ui gap="1">
|
|
309
|
+
<text-ui variant="label" color="subtle">Monthly Revenue</text-ui>
|
|
310
|
+
<text-ui variant="heading-lg">$42,350</text-ui>
|
|
311
|
+
<badge-ui text="+12.5%" variant="success" icon="trend-up"></badge-ui>
|
|
312
|
+
</col-ui>
|
|
313
|
+
<chart-ui id="spark" type="sparkline" x="month" y="value"
|
|
314
|
+
style="width: 80px; height: 40px"></chart-ui>
|
|
315
|
+
</row-ui>
|
|
316
|
+
</section>
|
|
317
|
+
</card-ui>
|
|
318
|
+
<script type="module">
|
|
319
|
+
document.getElementById('spark').data = [
|
|
320
|
+
{ month: 'Jan', value: 30 }, { month: 'Feb', value: 38 },
|
|
321
|
+
{ month: 'Mar', value: 35 }, { month: 'Apr', value: 42 },
|
|
322
|
+
];
|
|
323
|
+
</script>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Heatmap:**
|
|
327
|
+
|
|
328
|
+
```html
|
|
329
|
+
<!-- Day-grid (GitHub contributions) -->
|
|
330
|
+
<heatmap-ui id="activity" type="day-grid" rows="7" cols="52"
|
|
331
|
+
start-date="2025-01-01" color-scheme="data-ramp"
|
|
332
|
+
aria-label="Activity grid"></heatmap-ui>
|
|
333
|
+
|
|
334
|
+
<!-- Matrix with live data-stream -->
|
|
335
|
+
<heatmap-ui type="matrix" rows="7" cols="12" color-scheme="accent"
|
|
336
|
+
data-stream-src="/api/activity"
|
|
337
|
+
data-stream-path="cells"></heatmap-ui>
|
|
338
|
+
|
|
339
|
+
<script type="module">
|
|
340
|
+
// Static: flat array of {r, c, v}
|
|
341
|
+
document.getElementById('activity').data = [
|
|
342
|
+
{ r: 0, c: 0, v: 3 }, { r: 0, c: 1, v: 7 }, { r: 1, c: 0, v: 1 },
|
|
343
|
+
];
|
|
344
|
+
</script>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|