@adia-ai/web-components 0.8.6 → 0.8.8

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 (108) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +3 -3
  3. package/dist/host.min.css +1 -1
  4. package/dist/host.sheet.js +1 -1
  5. package/dist/theme-provider.min.js +2 -2
  6. package/dist/web-components.min.css +1 -1
  7. package/dist/web-components.min.js +1 -1
  8. package/dist/web-components.sheet.js +1 -1
  9. package/package.json +2 -1
  10. package/patterns/access-requests/access-requests.examples.html +132 -0
  11. package/patterns/access-requests/access-requests.html +60 -0
  12. package/patterns/admin-keys-and-export/admin-keys-and-export.examples.html +236 -0
  13. package/patterns/admin-keys-and-export/admin-keys-and-export.html +64 -0
  14. package/patterns/admin-shell/admin-shell.examples.html +327 -0
  15. package/patterns/admin-shell/admin-shell.html +44 -0
  16. package/patterns/agent-cost/agent-cost.examples.html +111 -0
  17. package/patterns/agent-cost/agent-cost.html +62 -0
  18. package/patterns/agent-memory/agent-memory.examples.html +155 -0
  19. package/patterns/agent-memory/agent-memory.html +64 -0
  20. package/patterns/agent-prompt-library/agent-prompt-library.examples.html +181 -0
  21. package/patterns/agent-prompt-library/agent-prompt-library.html +64 -0
  22. package/patterns/agent-tool-call/agent-tool-call.examples.html +123 -0
  23. package/patterns/agent-tool-call/agent-tool-call.html +60 -0
  24. package/patterns/alert-dialog/alert-dialog.examples.html +105 -0
  25. package/patterns/alert-dialog/alert-dialog.html +57 -0
  26. package/patterns/app-nav/app-nav.examples.html +421 -0
  27. package/patterns/app-nav/app-nav.html +50 -0
  28. package/patterns/approvals/approvals.examples.html +131 -0
  29. package/patterns/approvals/approvals.html +58 -0
  30. package/patterns/audit-log/audit-log.examples.html +74 -0
  31. package/patterns/audit-log/audit-log.examples.js +60 -0
  32. package/patterns/audit-log/audit-log.html +63 -0
  33. package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.html +89 -0
  34. package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.js +69 -0
  35. package/patterns/bulk-action-toolbar/bulk-action-toolbar.html +62 -0
  36. package/patterns/changelog-feed/changelog-feed.examples.html +151 -0
  37. package/patterns/changelog-feed/changelog-feed.html +57 -0
  38. package/patterns/chart-in-card/chart-in-card.examples.html +193 -0
  39. package/patterns/chart-in-card/chart-in-card.examples.js +46 -0
  40. package/patterns/chart-in-card/chart-in-card.html +66 -0
  41. package/patterns/chat-shell/chat-shell.examples.html +129 -0
  42. package/patterns/chat-shell/chat-shell.html +46 -0
  43. package/patterns/comments-and-collaboration/comments-and-collaboration.examples.html +241 -0
  44. package/patterns/comments-and-collaboration/comments-and-collaboration.html +66 -0
  45. package/patterns/component-tokens/component-tokens.examples.html +483 -0
  46. package/patterns/component-tokens/component-tokens.html +42 -0
  47. package/patterns/conversion-funnel/conversion-funnel.examples.html +158 -0
  48. package/patterns/conversion-funnel/conversion-funnel.examples.js +4 -0
  49. package/patterns/conversion-funnel/conversion-funnel.html +64 -0
  50. package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.examples.html +196 -0
  51. package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.html +58 -0
  52. package/patterns/diff-review/diff-review.examples.html +147 -0
  53. package/patterns/diff-review/diff-review.html +56 -0
  54. package/patterns/editor-shell/editor-shell.examples.html +139 -0
  55. package/patterns/editor-shell/editor-shell.html +62 -0
  56. package/patterns/export-flow/export-flow.examples.html +152 -0
  57. package/patterns/export-flow/export-flow.examples.js +37 -0
  58. package/patterns/export-flow/export-flow.html +65 -0
  59. package/patterns/filter-bar/filter-bar.examples.html +116 -0
  60. package/patterns/filter-bar/filter-bar.examples.js +23 -0
  61. package/patterns/filter-bar/filter-bar.html +70 -0
  62. package/patterns/form-drawer/form-drawer.examples.html +210 -0
  63. package/patterns/form-drawer/form-drawer.html +64 -0
  64. package/patterns/form-system/form-system.examples.html +383 -0
  65. package/patterns/form-system/form-system.html +48 -0
  66. package/patterns/forms-conditional-and-autocomplete/forms-conditional-and-autocomplete.examples.html +189 -0
  67. package/patterns/forms-conditional-and-autocomplete/forms-conditional-and-autocomplete.html +64 -0
  68. package/patterns/inline-dialog/inline-dialog.examples.html +143 -0
  69. package/patterns/inline-dialog/inline-dialog.html +59 -0
  70. package/patterns/kanban-board/kanban-board.examples.html +224 -0
  71. package/patterns/kanban-board/kanban-board.html +58 -0
  72. package/patterns/layout/layout.examples.html +365 -0
  73. package/patterns/layout/layout.html +54 -0
  74. package/patterns/marketing-engagement/marketing-engagement.examples.html +280 -0
  75. package/patterns/marketing-engagement/marketing-engagement.html +64 -0
  76. package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.examples.html +213 -0
  77. package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.html +58 -0
  78. package/patterns/overview/overview.examples.html +119 -0
  79. package/patterns/overview/overview.html +42 -0
  80. package/patterns/permissions-matrix/permissions-matrix.examples.html +91 -0
  81. package/patterns/permissions-matrix/permissions-matrix.examples.js +28 -0
  82. package/patterns/permissions-matrix/permissions-matrix.html +56 -0
  83. package/patterns/permissions-role-picker/permissions-role-picker.examples.html +81 -0
  84. package/patterns/permissions-role-picker/permissions-role-picker.html +56 -0
  85. package/patterns/permissions-sharing/permissions-sharing.examples.html +175 -0
  86. package/patterns/permissions-sharing/permissions-sharing.html +66 -0
  87. package/patterns/profile-public-and-verification/profile-public-and-verification.examples.html +227 -0
  88. package/patterns/profile-public-and-verification/profile-public-and-verification.html +70 -0
  89. package/patterns/record-detail-drawer/record-detail-drawer.examples.html +164 -0
  90. package/patterns/record-detail-drawer/record-detail-drawer.html +64 -0
  91. package/patterns/responsive-shell-sidebar/README.md +37 -0
  92. package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.css +39 -0
  93. package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.examples.html +208 -0
  94. package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.html +47 -0
  95. package/patterns/retention-cohort/retention-cohort.examples.html +149 -0
  96. package/patterns/retention-cohort/retention-cohort.examples.js +37 -0
  97. package/patterns/retention-cohort/retention-cohort.html +62 -0
  98. package/patterns/search-discovery/search-discovery.examples.html +263 -0
  99. package/patterns/search-discovery/search-discovery.html +58 -0
  100. package/patterns/system-banners/system-banners.examples.html +150 -0
  101. package/patterns/system-banners/system-banners.html +52 -0
  102. package/patterns/timezone-selector/timezone-selector.examples.html +82 -0
  103. package/patterns/timezone-selector/timezone-selector.examples.js +72 -0
  104. package/patterns/timezone-selector/timezone-selector.html +57 -0
  105. package/patterns/wizard-drawer/wizard-drawer.examples.html +144 -0
  106. package/patterns/wizard-drawer/wizard-drawer.examples.js +33 -0
  107. package/patterns/wizard-drawer/wizard-drawer.html +72 -0
  108. package/styles/type/roles.css +8 -8
@@ -0,0 +1,56 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" theme="auto">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Diff &amp; Review (pattern) — AdiaUI</title>
7
+
8
+ <!-- Token base -->
9
+ <link rel="stylesheet" href="../../styles/resets.css">
10
+ <link rel="stylesheet" href="../../styles/tokens.css">
11
+
12
+ <!-- Component CSS — primitives this pattern composes -->
13
+ <link rel="stylesheet" href="../../components/button/button.css">
14
+ <link rel="stylesheet" href="../../components/card/card.css">
15
+ <link rel="stylesheet" href="../../components/code/code.css">
16
+ <link rel="stylesheet" href="../../components/description-list/description-list.css">
17
+ <link rel="stylesheet" href="../../components/grid/grid.css">
18
+ <link rel="stylesheet" href="../../components/row/row.css">
19
+ <link rel="stylesheet" href="../../components/tag/tag.css">
20
+ <link rel="stylesheet" href="../../components/text/text.css">
21
+
22
+ <!-- Component JS -->
23
+ <script type="module" src="../../components/button/button.js"></script>
24
+ <script type="module" src="../../components/card/card.js"></script>
25
+ <script type="module" src="../../components/code/code.js"></script>
26
+ <script type="module" src="../../components/description-list/description-list.js"></script>
27
+ <script type="module" src="../../components/grid/grid.js"></script>
28
+ <script type="module" src="../../components/row/row.js"></script>
29
+ <script type="module" src="../../components/tag/tag.js"></script>
30
+ <script type="module" src="../../components/text/text.js"></script>
31
+
32
+ <style>
33
+ :where(html, body) { margin: 0; min-height: 100vh; background: var(--md-sys-color-neutral-background); color: var(--md-sys-color-neutral-on-surface); font-family: var(--a-font-family); }
34
+ main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
35
+ </style>
36
+ </head>
37
+ <body>
38
+
39
+ <main id="demo-root">
40
+ <p>Loading examples…</p>
41
+ </main>
42
+
43
+ <script type="module">
44
+ const root = document.getElementById('demo-root');
45
+ try {
46
+ const res = await fetch('./diff-review.examples.html');
47
+ if (!res.ok) throw new Error(`fetch failed (${res.status})`);
48
+ root.innerHTML = await res.text();
49
+ } catch (err) {
50
+ root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load diff-review.examples.html — ${err.message}</p>`;
51
+ console.error('[diff-review.html]', err);
52
+ }
53
+ </script>
54
+
55
+ </body>
56
+ </html>
@@ -0,0 +1,139 @@
1
+ <header>
2
+ <div>
3
+ <h1>Editor Shell — Composition Pattern</h1>
4
+ <div data-actions>
5
+ <tag-ui size="sm">editor-shell</tag-ui>
6
+ <tag-ui size="sm" variant="ghost">cluster-namespaced</tag-ui>
7
+ </div>
8
+ </div>
9
+ <p>
10
+ The canonical composition pattern for design-tool / code-editor /
11
+ canvas surfaces — a toolbar, a leading navigator pane, a center
12
+ canvas, an optional trailing inspector pane, and a statusbar. Built
13
+ from cluster-namespaced bespoke children. The legacy raw-HTML form
14
+ (raw <code>&lt;header&gt;</code> + <code>&lt;div data-editor-body&gt;</code>
15
+ + <code>&lt;pane-ui data-left|data-right&gt;</code> +
16
+ <code>&lt;div data-canvas&gt;</code> + raw <code>&lt;footer&gt;</code>)
17
+ was retired in v0.4.0 per
18
+ <a href="../../../../.brain/adrs/0024-legacy-shell-shapes-retired.md">ADR-0024</a>;
19
+ new code uses the bespoke shape exclusively per
20
+ <a href="../../../../.brain/adrs/0023-bespoke-shell-tier-children.md">ADR-0023</a>.
21
+ </p>
22
+ </header>
23
+
24
+ <section data-section data-property="canonical-hierarchy">
25
+ <h2 variant="section">Canonical hierarchy</h2>
26
+ <p data-note>
27
+ For the full live demo + state-as-attribute documentation, see
28
+ <a href="/site/components/editor-shell">/site/components/editor-shell</a>.
29
+ This page is the pattern hub.
30
+ </p>
31
+ <code-ui language="html">&lt;editor-shell&gt;
32
+
33
+ &lt;!-- Top toolbar — icon + heading + description + actions --&gt;
34
+ &lt;editor-toolbar&gt;
35
+ &lt;span slot="icon"&gt;&lt;icon-ui name="layers"&gt;&lt;/icon-ui&gt;&lt;/span&gt;
36
+ &lt;span slot="heading"&gt;Untitled.fig&lt;/span&gt;
37
+ &lt;span slot="description"&gt;1920 × 1080&lt;/span&gt;
38
+ &lt;span slot="action"&gt;
39
+ &lt;button-ui text="Share" variant="ghost"&gt;&lt;/button-ui&gt;
40
+ &lt;button-ui text="Run" variant="primary"&gt;&lt;/button-ui&gt;
41
+ &lt;/span&gt;
42
+ &lt;/editor-toolbar&gt;
43
+
44
+ &lt;!-- Leading sidebar — layer tree / outline / file browser --&gt;
45
+ &lt;editor-sidebar slot="leading" collapsible persist="structure"&gt;
46
+ &lt;pane-ui side="leading" resizable size="sm"&gt;
47
+ &lt;header&gt;Layers&lt;/header&gt;
48
+ &lt;section&gt;
49
+ &lt;tree-ui&gt;...&lt;/tree-ui&gt;
50
+ &lt;/section&gt;
51
+ &lt;/pane-ui&gt;
52
+ &lt;/editor-sidebar&gt;
53
+
54
+ &lt;!-- Center canvas — the editing surface --&gt;
55
+ &lt;editor-canvas&gt;
56
+ &lt;editor-canvas-toolbar&gt;
57
+ &lt;tabs-ui value="preview" variant="underline"&gt;
58
+ &lt;tab-ui value="preview" text="Preview"&gt;&lt;/tab-ui&gt;
59
+ &lt;tab-ui value="schema" text="Schema"&gt;&lt;/tab-ui&gt;
60
+ &lt;/tabs-ui&gt;
61
+ &lt;/editor-canvas-toolbar&gt;
62
+ &lt;editor-canvas-empty&gt;
63
+ &lt;empty-state-ui icon="cursor"
64
+ heading="Open a file to begin"&gt;&lt;/empty-state-ui&gt;
65
+ &lt;/editor-canvas-empty&gt;
66
+ &lt;!-- canvas children: code editor, preview iframe, design surface, etc. --&gt;
67
+ &lt;/editor-canvas&gt;
68
+
69
+ &lt;!-- Trailing sidebar (optional) — inspector / properties panel --&gt;
70
+ &lt;editor-sidebar slot="trailing" collapsible persist="inspector"&gt;
71
+ &lt;pane-ui side="trailing" resizable size="sm"&gt;
72
+ &lt;header&gt;Inspector&lt;/header&gt;
73
+ &lt;section&gt;
74
+ &lt;field-ui label="Width"&gt;&lt;input-ui type="number"&gt;&lt;/input-ui&gt;&lt;/field-ui&gt;
75
+ &lt;field-ui label="Height"&gt;&lt;input-ui type="number"&gt;&lt;/input-ui&gt;&lt;/field-ui&gt;
76
+ &lt;/section&gt;
77
+ &lt;/pane-ui&gt;
78
+ &lt;/editor-sidebar&gt;
79
+
80
+ &lt;!-- Bottom statusbar — connection / sync / cursor position --&gt;
81
+ &lt;editor-statusbar&gt;
82
+ &lt;span&gt;Ready&lt;/span&gt;
83
+ &lt;span data-spacer&gt;&lt;/span&gt;
84
+ &lt;span&gt;Ln 42, Col 8&lt;/span&gt;
85
+ &lt;/editor-statusbar&gt;
86
+
87
+ &lt;/editor-shell&gt;</code-ui>
88
+ </section>
89
+
90
+ <section data-section data-property="part-by-part-reference">
91
+ <h2 variant="section">Part-by-part reference</h2>
92
+ <table>
93
+ <thead>
94
+ <tr><th>Part</th><th>Role</th></tr>
95
+ </thead>
96
+ <tbody>
97
+ <tr>
98
+ <td><a href="/site/components/editor-shell"><code>&lt;editor-shell&gt;</code></a></td>
99
+ <td>Behavior-only host. Coordinates the family and propagates <code>[focus-mode]</code> to children's <code>[full-screen]</code> / <code>[focused]</code>.</td>
100
+ </tr>
101
+ <tr>
102
+ <td><a href="/site/components/editor-toolbar"><code>&lt;editor-toolbar&gt;</code></a></td>
103
+ <td>Top band — slots: <code>icon</code>, <code>heading</code>, <code>description</code>, <code>action</code>.</td>
104
+ </tr>
105
+ <tr>
106
+ <td><a href="/site/components/editor-sidebar"><code>&lt;editor-sidebar&gt;</code></a></td>
107
+ <td>Leading (navigator) or trailing (inspector) pane. Holds <code>&lt;pane-ui&gt;</code>. Reflects <code>[collapsed]</code>; <code>persist=</code> wires localStorage.</td>
108
+ </tr>
109
+ <tr>
110
+ <td><a href="/site/components/editor-canvas"><code>&lt;editor-canvas&gt;</code></a></td>
111
+ <td>Center surface. Holds optional <code>&lt;editor-canvas-toolbar&gt;</code> + <code>&lt;editor-canvas-empty&gt;</code> + canvas children. Reflects <code>[empty]</code>.</td>
112
+ </tr>
113
+ <tr>
114
+ <td><a href="/site/components/editor-statusbar"><code>&lt;editor-statusbar&gt;</code></a></td>
115
+ <td>Bottom band — same slot vocabulary as toolbar; conventionally read-only.</td>
116
+ </tr>
117
+ </tbody>
118
+ </table>
119
+ </section>
120
+
121
+ <section data-section data-property="authoring-rules">
122
+ <h2 variant="section">Authoring rules</h2>
123
+ <ul>
124
+ <li><strong>Cluster-namespaced children only.</strong> Inside <code>&lt;editor-shell&gt;</code>: <code>&lt;editor-toolbar&gt;</code>, <code>&lt;editor-sidebar&gt;</code>, <code>&lt;editor-canvas&gt;</code>, <code>&lt;editor-statusbar&gt;</code>. Don't author raw <code>&lt;header&gt;</code>, <code>&lt;footer&gt;</code>, <code>&lt;div data-editor-body&gt;</code>, <code>&lt;div data-canvas&gt;</code> — retired in v0.4.0.</li>
125
+ <li><strong>Each sidebar wraps a <code>&lt;pane-ui&gt;</code>.</strong> The pane owns resize; the sidebar owns slot positioning + collapse + persist. <code>&lt;pane-ui side="leading|trailing"&gt;</code> is required so the resize handle lands on the correct edge.</li>
126
+ <li><strong>Canvas reflects <code>[empty]</code>.</strong> Use <code>:has(editor-canvas[empty])</code> to style the shell differently when nothing's open.</li>
127
+ <li><strong>Focus mode is one attribute.</strong> Setting <code>focus-mode</code> on the shell propagates to <code>[full-screen]</code> on the canvas and <code>[focused]</code> on the active sidebar — no JS coordination needed.</li>
128
+ </ul>
129
+ </section>
130
+
131
+ <section data-section data-property="where-to-next">
132
+ <h2 variant="section">Where to next</h2>
133
+ <ul>
134
+ <li><a href="/site/components/editor-shell">editor-shell component reference</a> — full anatomy + live demo</li>
135
+ <li><a href="/site/components/pane">pane-ui</a> · <a href="/site/components/tree">tree-ui</a> · <a href="/site/components/tabs">tabs-ui</a></li>
136
+ <li><a href="/site/patterns/shells">Macro-shells overview</a></li>
137
+ <li><a href="/site/patterns/admin-shell">admin-shell pattern</a> · <a href="/site/patterns/chat-shell">chat-shell pattern</a></li>
138
+ </ul>
139
+ </section>
@@ -0,0 +1,62 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" theme="auto">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Editor Shell (pattern) — AdiaUI</title>
7
+
8
+ <!-- Token base -->
9
+ <link rel="stylesheet" href="../../styles/resets.css">
10
+ <link rel="stylesheet" href="../../styles/tokens.css">
11
+
12
+ <!-- Component CSS — primitives this pattern composes -->
13
+ <link rel="stylesheet" href="../../components/button/button.css">
14
+ <link rel="stylesheet" href="../../components/code/code.css">
15
+ <link rel="stylesheet" href="../../components/field/field.css">
16
+ <link rel="stylesheet" href="../../components/input/input.css">
17
+ <link rel="stylesheet" href="../../components/pane/pane.css">
18
+ <link rel="stylesheet" href="../../components/range/range.css">
19
+ <link rel="stylesheet" href="../../components/segment/segment.css">
20
+ <link rel="stylesheet" href="../../components/segmented/segmented.css">
21
+ <link rel="stylesheet" href="../../components/select/select.css">
22
+ <link rel="stylesheet" href="../../components/tag/tag.css">
23
+ <link rel="stylesheet" href="../../components/tree/tree.css">
24
+
25
+ <!-- Component JS -->
26
+ <script type="module" src="../../components/button/button.js"></script>
27
+ <script type="module" src="../../components/code/code.js"></script>
28
+ <script type="module" src="../../components/field/field.js"></script>
29
+ <script type="module" src="../../components/input/input.js"></script>
30
+ <script type="module" src="../../components/pane/pane.js"></script>
31
+ <script type="module" src="../../components/range/range.js"></script>
32
+ <script type="module" src="../../components/segment/segment.js"></script>
33
+ <script type="module" src="../../components/segmented/segmented.js"></script>
34
+ <script type="module" src="../../components/select/select.js"></script>
35
+ <script type="module" src="../../components/tag/tag.js"></script>
36
+ <script type="module" src="../../components/tree/tree.js"></script>
37
+
38
+ <style>
39
+ :where(html, body) { margin: 0; min-height: 100vh; background: var(--md-sys-color-neutral-background); color: var(--md-sys-color-neutral-on-surface); font-family: var(--a-font-family); }
40
+ main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
41
+ </style>
42
+ </head>
43
+ <body>
44
+
45
+ <main id="demo-root">
46
+ <p>Loading examples…</p>
47
+ </main>
48
+
49
+ <script type="module">
50
+ const root = document.getElementById('demo-root');
51
+ try {
52
+ const res = await fetch('./editor-shell.examples.html');
53
+ if (!res.ok) throw new Error(`fetch failed (${res.status})`);
54
+ root.innerHTML = await res.text();
55
+ } catch (err) {
56
+ root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load editor-shell.examples.html — ${err.message}</p>`;
57
+ console.error('[editor-shell.html]', err);
58
+ }
59
+ </script>
60
+
61
+ </body>
62
+ </html>
@@ -0,0 +1,152 @@
1
+ <header>
2
+ <div>
3
+ <h1>Export flow</h1>
4
+ <div data-actions>
5
+ <tag-ui size="sm">card-ui</tag-ui> <tag-ui size="sm">field-ui</tag-ui> <tag-ui size="sm">select-ui</tag-ui> <tag-ui size="sm">radio-ui</tag-ui> <tag-ui size="sm">check-ui</tag-ui> <tag-ui size="sm">button-ui</tag-ui> <tag-ui size="sm">alert-ui</tag-ui>
6
+ </div>
7
+ </div>
8
+ <p>Generic export-request form. User picks scope, format, and delivery (download or email), then submits. Distilled from the data-export-request flow in <a href="/site/patterns/admin-keys-and-export">admin-keys-and-export</a> — use this when an export form lives standalone (settings panel, admin shell, in-context "Export…" affordance).</p>
9
+ </header>
10
+
11
+ <section data-section data-property="when-to-use">
12
+ <h2 variant="section">When to use</h2>
13
+ <p data-note>Standalone export forms: dataset → file → delivery. Sync (download now) or async (email when ready). Distinct from <a href="/site/patterns/admin-keys-and-export">admin-keys-and-export</a> (compliance + workspace migration; always async) and from a single "Download CSV" button (no choices to make).</p>
14
+ </section>
15
+
16
+ <section data-section data-property="sync-download">
17
+ <h2 variant="section">Sync — download now</h2>
18
+ <p data-note>Small datasets (&lt; 10 k rows). User picks format, browser downloads on click. Submit button copy = the verb ("Download CSV"); format-picker change updates the button label.</p>
19
+ <div data-artifact-container>
20
+ <div data-artifact-item data-artifact-label="download now">
21
+ <card-ui data-chunk="export-flow-sync" style="max-width: 480px;">
22
+ <header>
23
+ <span slot="heading" variant="section">Export users</span>
24
+ <text-ui slot="description" color="subtle">428 rows · current filter applied</text-ui>
25
+ </header>
26
+ <section>
27
+ <col-ui gap="3">
28
+ <field-ui label="Format">
29
+ <select-ui id="export-sync-format" name="format">
30
+ <option value="csv" selected>CSV (Excel-compatible)</option>
31
+ <option value="json">JSON</option>
32
+ <option value="xlsx">XLSX (Excel native)</option>
33
+ </select-ui>
34
+ </field-ui>
35
+ <field-ui label="Columns">
36
+ <col-ui gap="1">
37
+ <radio-ui name="cols" value="all" label="All columns" checked></radio-ui>
38
+ <radio-ui name="cols" value="visible" label="Only visible columns (8)"></radio-ui>
39
+ </col-ui>
40
+ </field-ui>
41
+ </col-ui>
42
+ </section>
43
+ <footer divider>
44
+ <button-ui slot="action" text="Cancel" variant="ghost"></button-ui>
45
+ <button-ui id="export-sync-submit" slot="action" text="Download CSV" variant="primary" icon-leading="download-simple"></button-ui>
46
+ </footer>
47
+ </card-ui>
48
+ </div>
49
+ </div>
50
+ </section>
51
+
52
+ <section data-section data-property="async-email">
53
+ <h2 variant="section">Async — email when ready</h2>
54
+ <p data-note>Large datasets (≥ 10 k rows / known-slow exports). Submit queues a job; the user gets an email with a download link when the archive is ready. The form acknowledges the latency up front in an info alert + uses the verb "Request" instead of "Download".</p>
55
+ <div data-artifact-container>
56
+ <div data-artifact-item data-artifact-label="request email export">
57
+ <card-ui data-chunk="export-flow-async" style="max-width: 480px;">
58
+ <header>
59
+ <span slot="heading" variant="section">Export analytics</span>
60
+ <text-ui slot="description" color="subtle">~1.4M events · last 90 days</text-ui>
61
+ </header>
62
+ <section>
63
+ <col-ui gap="3">
64
+ <field-ui label="Date range">
65
+ <select-ui name="range">
66
+ <option value="7d">Last 7 days</option>
67
+ <option value="30d">Last 30 days</option>
68
+ <option value="90d" selected>Last 90 days</option>
69
+ <option value="custom">Custom range…</option>
70
+ </select-ui>
71
+ </field-ui>
72
+ <field-ui label="Format">
73
+ <select-ui id="export-async-format" name="format">
74
+ <option value="ndjson" selected>NDJSON (line-delimited)</option>
75
+ <option value="parquet">Parquet</option>
76
+ <option value="csv">CSV per day</option>
77
+ </select-ui>
78
+ </field-ui>
79
+ <field-ui label="Deliver to" required>
80
+ <input-ui name="email" type="email" value="kim@example.com"></input-ui>
81
+ </field-ui>
82
+ <alert-ui variant="info" icon="clock">
83
+ <col-ui slot="content" gap="0-5">
84
+ <text-ui strong>Exports complete within 1 hour.</text-ui>
85
+ <text-ui>You'll receive an email with a download link valid for 7 days.</text-ui>
86
+ </col-ui>
87
+ </alert-ui>
88
+ </col-ui>
89
+ </section>
90
+ <footer divider>
91
+ <button-ui slot="action" text="Cancel" variant="ghost"></button-ui>
92
+ <button-ui slot="action" text="Request export" variant="primary"></button-ui>
93
+ </footer>
94
+ </card-ui>
95
+ </div>
96
+ </div>
97
+ </section>
98
+
99
+ <section data-section data-property="delivery-choice">
100
+ <h2 variant="section">Choice — download vs email</h2>
101
+ <p data-note>When both make sense (medium datasets, user preference matters). Radio choice up top toggles which submit verb fires; email field hides when "download" is selected.</p>
102
+ <div data-artifact-container>
103
+ <div data-artifact-item data-artifact-label="delivery picker">
104
+ <card-ui data-chunk="export-flow-delivery" style="max-width: 480px;">
105
+ <header>
106
+ <span slot="heading" variant="section">Export invoices</span>
107
+ <text-ui slot="description" color="subtle">2024 fiscal year · 1,247 invoices</text-ui>
108
+ </header>
109
+ <section>
110
+ <col-ui gap="3">
111
+ <field-ui label="Format">
112
+ <select-ui id="export-delivery-format" name="format">
113
+ <option value="pdf" selected>PDF bundle</option>
114
+ <option value="zip-pdf">ZIP of individual PDFs</option>
115
+ <option value="csv">CSV summary only</option>
116
+ </select-ui>
117
+ </field-ui>
118
+ <field-ui label="Delivery" required>
119
+ <col-ui gap="1">
120
+ <radio-ui id="export-delivery-radio-download" name="delivery" value="download" label="Download now" checked></radio-ui>
121
+ <radio-ui name="delivery" value="email" label="Email when ready (recommended for large bundles)"></radio-ui>
122
+ </col-ui>
123
+ </field-ui>
124
+ </col-ui>
125
+ </section>
126
+ <footer divider>
127
+ <button-ui slot="action" text="Cancel" variant="ghost"></button-ui>
128
+ <button-ui id="export-delivery-submit" slot="action" text="Download PDF" variant="primary" icon-leading="download-simple"></button-ui>
129
+ </footer>
130
+ </card-ui>
131
+ </div>
132
+ </div>
133
+ </section>
134
+
135
+ <section data-section data-property="composition">
136
+ <h2 variant="section">Composition rules</h2>
137
+ <ul>
138
+ <li><strong>Submit-button verb mirrors delivery</strong> — "Download CSV" for sync, "Request export" for async. Never "Submit" — the verb tells the user what happens next.</li>
139
+ <li><strong>Format picker drives submit label</strong> — change the format from CSV to JSON, the button copy updates to "Download JSON". Removes ambiguity ("what am I getting?").</li>
140
+ <li><strong>Async exports announce the latency</strong> — info alert with the expected wait + delivery channel. "Up to 24 hours" is fine; silent spinners are not.</li>
141
+ <li><strong>Show the dataset size up front</strong> — the description slot carries row count / data range / filter context so the user knows scope before submitting.</li>
142
+ <li><strong>Compose with</strong> — wrap in <code>&lt;modal-ui&gt;</code> for in-context "Export…" affordances, OR render inline in a settings panel. The form composes; the surface choice is yours.</li>
143
+ </ul>
144
+ </section>
145
+
146
+ <section data-section data-property="cross-references">
147
+ <h2 variant="section">Cross-references</h2>
148
+ <ul>
149
+ <li><a href="/site/patterns/admin-keys-and-export">admin-keys-and-export</a> — compliance / workspace-migration export (always async, GDPR / SOC-2 framing).</li>
150
+ <li><a href="/site/components/select">select-ui</a> · <a href="/site/components/radio">radio-ui</a> · <a href="/site/components/field">field-ui</a> — primitives composed here.</li>
151
+ </ul>
152
+ </section>
@@ -0,0 +1,37 @@
1
+ /** Export-flow demo — wire the format select to the submit button label.
2
+ *
3
+ * The pattern's composition rule says the submit-button verb mirrors the
4
+ * format choice ("Download CSV" / "Download JSON" / "Download PDF"). The
5
+ * demo backs that rule by rebinding the button text on format change. */
6
+
7
+ const FORMAT_LABELS = {
8
+ csv: 'CSV',
9
+ json: 'JSON',
10
+ xlsx: 'XLSX',
11
+ pdf: 'PDF',
12
+ 'zip-pdf':'PDF (zip)',
13
+ ndjson: 'NDJSON',
14
+ parquet: 'Parquet',
15
+ };
16
+
17
+ function wire(root, { selectId, submitId, verb = 'Download' }) {
18
+ const select = root.querySelector('#' + selectId);
19
+ const submit = root.querySelector('#' + submitId);
20
+ if (!select || !submit) return;
21
+ const update = () => {
22
+ const fmt = (select.value || '').toLowerCase();
23
+ const label = FORMAT_LABELS[fmt] || fmt.toUpperCase();
24
+ submit.setAttribute('text', `${verb} ${label}`);
25
+ };
26
+ update();
27
+ select.addEventListener('change', update);
28
+ }
29
+
30
+ export default function setup(router) {
31
+ const root = router || document;
32
+ wire(root, { selectId: 'export-sync-format', submitId: 'export-sync-submit' });
33
+ wire(root, { selectId: 'export-delivery-format', submitId: 'export-delivery-submit' });
34
+ // Async variant uses "Request export" — no format suffix per the rule
35
+ // ("Request" verb signals the async job; the user gets a download link
36
+ // by email, not an immediate file).
37
+ }
@@ -0,0 +1,65 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" theme="auto">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Export flow (pattern) — AdiaUI</title>
7
+
8
+ <link rel="stylesheet" href="../../styles/resets.css">
9
+ <link rel="stylesheet" href="../../styles/tokens.css">
10
+
11
+ <link rel="stylesheet" href="../../components/alert/alert.css">
12
+ <link rel="stylesheet" href="../../components/button/button.css">
13
+ <link rel="stylesheet" href="../../components/card/card.css">
14
+ <link rel="stylesheet" href="../../components/check/check.css">
15
+ <link rel="stylesheet" href="../../components/col/col.css">
16
+ <link rel="stylesheet" href="../../components/field/field.css">
17
+ <link rel="stylesheet" href="../../components/icon/icon.css">
18
+ <link rel="stylesheet" href="../../components/input/input.css">
19
+ <link rel="stylesheet" href="../../components/list/list.css">
20
+ <link rel="stylesheet" href="../../components/radio/radio.css">
21
+ <link rel="stylesheet" href="../../components/row/row.css">
22
+ <link rel="stylesheet" href="../../components/select/select.css">
23
+ <link rel="stylesheet" href="../../components/tag/tag.css">
24
+ <link rel="stylesheet" href="../../components/text/text.css">
25
+
26
+ <script type="module" src="../../components/alert/alert.js"></script>
27
+ <script type="module" src="../../components/button/button.js"></script>
28
+ <script type="module" src="../../components/card/card.js"></script>
29
+ <script type="module" src="../../components/check/check.js"></script>
30
+ <script type="module" src="../../components/col/col.js"></script>
31
+ <script type="module" src="../../components/field/field.js"></script>
32
+ <script type="module" src="../../components/icon/icon.js"></script>
33
+ <script type="module" src="../../components/input/input.js"></script>
34
+ <script type="module" src="../../components/list/list.js"></script>
35
+ <script type="module" src="../../components/radio/radio.js"></script>
36
+ <script type="module" src="../../components/row/row.js"></script>
37
+ <script type="module" src="../../components/select/select.js"></script>
38
+ <script type="module" src="../../components/tag/tag.js"></script>
39
+ <script type="module" src="../../components/text/text.js"></script>
40
+
41
+ <style>
42
+ :where(html, body) { margin: 0; min-height: 100vh; background: var(--md-sys-color-neutral-background); color: var(--md-sys-color-neutral-on-surface); font-family: var(--a-font-family); }
43
+ main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
44
+ </style>
45
+ </head>
46
+ <body>
47
+
48
+ <main id="demo-root">
49
+ <p>Loading examples…</p>
50
+ </main>
51
+
52
+ <script type="module">
53
+ const root = document.getElementById('demo-root');
54
+ try {
55
+ const res = await fetch('./export-flow.examples.html');
56
+ if (!res.ok) throw new Error(`fetch failed (${res.status})`);
57
+ root.innerHTML = await res.text();
58
+ } catch (err) {
59
+ root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load export-flow.examples.html — ${err.message}</p>`;
60
+ console.error('[export-flow.html]', err);
61
+ }
62
+ </script>
63
+
64
+ </body>
65
+ </html>
@@ -0,0 +1,116 @@
1
+ <header>
2
+ <div>
3
+ <h1>Filter Bar</h1>
4
+ <div data-actions>
5
+ <tag-ui size="sm">tag-ui</tag-ui> <tag-ui size="sm">popover-ui</tag-ui> <tag-ui size="sm">action-list-ui</tag-ui>
6
+ </div>
7
+ </div>
8
+ <p>Row of active filters above a table or list. Each filter is a removable chip; a trailing "Add filter" button opens a popover of available facets. Distinct from full-text search, which stays in the toolbar.</p>
9
+ </header>
10
+
11
+ <section data-section data-property="when-to-use">
12
+ <h2 variant="section">When to use</h2>
13
+ <p data-note>
14
+ Use a filter bar when users apply multiple faceted filters to the same view
15
+ — status + owner + date range is the typical shape. A single dropdown is enough
16
+ for one facet; a drawer is better for 5+ complex facets. The bar is the
17
+ middle ground.
18
+ </p>
19
+ </section>
20
+
21
+ <section data-section data-property="active-filters" data-chunk="filter-bar-active-filters">
22
+ <h2 variant="section">Active filters + Add filter</h2>
23
+ <p data-note>Chips show each active filter. The trailing button opens a popover of available facets.</p>
24
+ <card-ui>
25
+ <section>
26
+ <row-ui gap="2" align="center" wrap>
27
+ <text-ui color="subtle" weight="semibold">Filters:</text-ui>
28
+ <tag-ui text="Status: Active" removable></tag-ui>
29
+ <tag-ui text="Owner: Alex Chen" removable></tag-ui>
30
+ <tag-ui text="Updated: last 7 days" removable></tag-ui>
31
+ <button-ui text="+ Add filter" variant="ghost" size="sm" popovertarget="pat-filter-menu"></button-ui>
32
+ <span data-spacer></span>
33
+ <button-ui text="Clear all" variant="ghost" size="sm"></button-ui>
34
+ </row-ui>
35
+ <popover-ui id="pat-filter-menu" anchor="previous">
36
+ <action-list-ui>
37
+ <action-item-ui icon="flag" text="Status" value="status"></action-item-ui>
38
+ <action-item-ui icon="user" text="Owner" value="owner"></action-item-ui>
39
+ <action-item-ui icon="tag" text="Label" value="label"></action-item-ui>
40
+ <action-item-ui icon="calendar" text="Date range" value="date"></action-item-ui>
41
+ <action-item-ui icon="folder" text="Project" value="project"></action-item-ui>
42
+ </action-list-ui>
43
+ </popover-ui>
44
+ </section>
45
+ </card-ui>
46
+ </section>
47
+
48
+ <section data-section data-property="filter-bar-with-table" data-chunk="filter-bar-filter-bar-with-table">
49
+ <h2 variant="section">Filter bar + table</h2>
50
+ <p data-note>The common composition: filters sit above the table inside one card surface so they read as modifying the same data.</p>
51
+ <card-ui>
52
+ <section bleed>
53
+ <toolbar-ui overflow="none" style="padding: var(--a-space-2) var(--a-space-3); border-block-end: 1px solid var(--md-sys-color-neutral-outline-variant); border-radius: 0;">
54
+ <row-ui gap="2" align="center" grow>
55
+ <tag-ui text="Status: Active" removable></tag-ui>
56
+ <tag-ui text="Owner: Alex" removable></tag-ui>
57
+ <button-ui text="+ Add filter" variant="ghost" size="sm"></button-ui>
58
+ </row-ui>
59
+ <search-ui placeholder="Search…" size="sm"></search-ui>
60
+ </toolbar-ui>
61
+ <table-ui id="pat-filter-table" sortable striped></table-ui>
62
+ </section>
63
+ </card-ui>
64
+ </section>
65
+
66
+ <section data-section data-property="saved-views" data-chunk="filter-bar-saved-views">
67
+ <h2 variant="section">Saved views</h2>
68
+ <p data-note>Named combinations of filters. Segmented control replaces the active-filter chips while a view is applied.</p>
69
+ <card-ui>
70
+ <section>
71
+ <row-ui align="center" gap="3" wrap>
72
+ <segmented-ui value="my-open">
73
+ <segment-ui value="all" text="All"></segment-ui>
74
+ <segment-ui value="my-open" text="My open"></segment-ui>
75
+ <segment-ui value="team" text="Team"></segment-ui>
76
+ <segment-ui value="archived" text="Archived"></segment-ui>
77
+ </segmented-ui>
78
+ <span data-spacer></span>
79
+ <button-ui text="Save view" icon="bookmark" variant="ghost"></button-ui>
80
+ </row-ui>
81
+ </section>
82
+ </card-ui>
83
+ </section>
84
+
85
+ <section data-section data-property="anatomy">
86
+ <h2 variant="section">Anatomy</h2>
87
+ <code-ui language="html">&lt;row-ui gap="2" align="center" wrap&gt;
88
+ &lt;text-ui color="subtle" weight="semibold"&gt;Filters:&lt;/text-ui&gt;
89
+
90
+ &lt;!-- one removable chip per active filter --&gt;
91
+ &lt;tag-ui text="Status: Active" removable&gt;&lt;/tag-ui&gt;
92
+ &lt;tag-ui text="Owner: Alex Chen" removable&gt;&lt;/tag-ui&gt;
93
+
94
+ &lt;!-- popover-anchored menu of facets --&gt;
95
+ &lt;button-ui text="+ Add filter" variant="ghost"
96
+ popovertarget="filter-menu"&gt;&lt;/button-ui&gt;
97
+
98
+ &lt;span data-spacer&gt;&lt;/span&gt;
99
+ &lt;button-ui text="Clear all" variant="ghost"&gt;&lt;/button-ui&gt;
100
+ &lt;/row-ui&gt;
101
+
102
+ &lt;popover-ui id="filter-menu" anchor="previous"&gt;
103
+ &lt;action-list-ui&gt;...facets...&lt;/action-list-ui&gt;
104
+ &lt;/popover-ui&gt;</code-ui>
105
+ </section>
106
+
107
+ <section data-section data-property="rules">
108
+ <h2 variant="section">Rules</h2>
109
+ <ul>
110
+ <li>One chip per active filter. If a filter has multiple values (e.g., Status in [Active, Draft]), collapse to <code>"Status: 2"</code> with the chip showing the count.</li>
111
+ <li>Filters modify the dataset. Search modifies the <em>match within</em> the dataset. Keep them visually distinct — filters left, search right.</li>
112
+ <li>Clear-all only appears when ≥1 filter is active.</li>
113
+ <li>Saved views and free-form chip filters are mutually exclusive. Pick one per surface — mixing both confuses "what state am I in?".</li>
114
+ <li>When filters come from a drawer instead (5+ facets, complex forms), use a <code>button-ui icon="funnel"</code> that opens a filter drawer. The chip bar below still shows what's active.</li>
115
+ </ul>
116
+ </section>