@adia-ai/web-components 0.8.6 → 0.8.7

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 (102) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/theme-provider.min.js +1 -1
  3. package/dist/web-components.min.js +1 -1
  4. package/package.json +2 -1
  5. package/patterns/access-requests/access-requests.examples.html +132 -0
  6. package/patterns/access-requests/access-requests.html +60 -0
  7. package/patterns/admin-keys-and-export/admin-keys-and-export.examples.html +236 -0
  8. package/patterns/admin-keys-and-export/admin-keys-and-export.html +64 -0
  9. package/patterns/admin-shell/admin-shell.examples.html +327 -0
  10. package/patterns/admin-shell/admin-shell.html +44 -0
  11. package/patterns/agent-cost/agent-cost.examples.html +111 -0
  12. package/patterns/agent-cost/agent-cost.html +62 -0
  13. package/patterns/agent-memory/agent-memory.examples.html +155 -0
  14. package/patterns/agent-memory/agent-memory.html +64 -0
  15. package/patterns/agent-prompt-library/agent-prompt-library.examples.html +181 -0
  16. package/patterns/agent-prompt-library/agent-prompt-library.html +64 -0
  17. package/patterns/agent-tool-call/agent-tool-call.examples.html +123 -0
  18. package/patterns/agent-tool-call/agent-tool-call.html +60 -0
  19. package/patterns/alert-dialog/alert-dialog.examples.html +105 -0
  20. package/patterns/alert-dialog/alert-dialog.html +57 -0
  21. package/patterns/app-nav/app-nav.examples.html +421 -0
  22. package/patterns/app-nav/app-nav.html +50 -0
  23. package/patterns/approvals/approvals.examples.html +131 -0
  24. package/patterns/approvals/approvals.html +58 -0
  25. package/patterns/audit-log/audit-log.examples.html +74 -0
  26. package/patterns/audit-log/audit-log.examples.js +60 -0
  27. package/patterns/audit-log/audit-log.html +63 -0
  28. package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.html +89 -0
  29. package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.js +69 -0
  30. package/patterns/bulk-action-toolbar/bulk-action-toolbar.html +62 -0
  31. package/patterns/changelog-feed/changelog-feed.examples.html +151 -0
  32. package/patterns/changelog-feed/changelog-feed.html +57 -0
  33. package/patterns/chart-in-card/chart-in-card.examples.html +193 -0
  34. package/patterns/chart-in-card/chart-in-card.examples.js +46 -0
  35. package/patterns/chart-in-card/chart-in-card.html +66 -0
  36. package/patterns/chat-shell/chat-shell.examples.html +129 -0
  37. package/patterns/chat-shell/chat-shell.html +46 -0
  38. package/patterns/comments-and-collaboration/comments-and-collaboration.examples.html +241 -0
  39. package/patterns/comments-and-collaboration/comments-and-collaboration.html +66 -0
  40. package/patterns/component-tokens/component-tokens.examples.html +483 -0
  41. package/patterns/component-tokens/component-tokens.html +42 -0
  42. package/patterns/conversion-funnel/conversion-funnel.examples.html +158 -0
  43. package/patterns/conversion-funnel/conversion-funnel.examples.js +4 -0
  44. package/patterns/conversion-funnel/conversion-funnel.html +64 -0
  45. package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.examples.html +196 -0
  46. package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.html +58 -0
  47. package/patterns/diff-review/diff-review.examples.html +147 -0
  48. package/patterns/diff-review/diff-review.html +56 -0
  49. package/patterns/editor-shell/editor-shell.examples.html +139 -0
  50. package/patterns/editor-shell/editor-shell.html +62 -0
  51. package/patterns/export-flow/export-flow.examples.html +152 -0
  52. package/patterns/export-flow/export-flow.examples.js +37 -0
  53. package/patterns/export-flow/export-flow.html +65 -0
  54. package/patterns/filter-bar/filter-bar.examples.html +116 -0
  55. package/patterns/filter-bar/filter-bar.examples.js +23 -0
  56. package/patterns/filter-bar/filter-bar.html +70 -0
  57. package/patterns/form-drawer/form-drawer.examples.html +210 -0
  58. package/patterns/form-drawer/form-drawer.html +64 -0
  59. package/patterns/form-system/form-system.examples.html +383 -0
  60. package/patterns/form-system/form-system.html +48 -0
  61. package/patterns/forms-conditional-and-autocomplete/forms-conditional-and-autocomplete.examples.html +189 -0
  62. package/patterns/forms-conditional-and-autocomplete/forms-conditional-and-autocomplete.html +64 -0
  63. package/patterns/inline-dialog/inline-dialog.examples.html +143 -0
  64. package/patterns/inline-dialog/inline-dialog.html +59 -0
  65. package/patterns/kanban-board/kanban-board.examples.html +224 -0
  66. package/patterns/kanban-board/kanban-board.html +58 -0
  67. package/patterns/layout/layout.examples.html +365 -0
  68. package/patterns/layout/layout.html +54 -0
  69. package/patterns/marketing-engagement/marketing-engagement.examples.html +280 -0
  70. package/patterns/marketing-engagement/marketing-engagement.html +64 -0
  71. package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.examples.html +213 -0
  72. package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.html +58 -0
  73. package/patterns/overview/overview.examples.html +119 -0
  74. package/patterns/overview/overview.html +42 -0
  75. package/patterns/permissions-matrix/permissions-matrix.examples.html +91 -0
  76. package/patterns/permissions-matrix/permissions-matrix.examples.js +28 -0
  77. package/patterns/permissions-matrix/permissions-matrix.html +56 -0
  78. package/patterns/permissions-role-picker/permissions-role-picker.examples.html +81 -0
  79. package/patterns/permissions-role-picker/permissions-role-picker.html +56 -0
  80. package/patterns/permissions-sharing/permissions-sharing.examples.html +175 -0
  81. package/patterns/permissions-sharing/permissions-sharing.html +66 -0
  82. package/patterns/profile-public-and-verification/profile-public-and-verification.examples.html +227 -0
  83. package/patterns/profile-public-and-verification/profile-public-and-verification.html +70 -0
  84. package/patterns/record-detail-drawer/record-detail-drawer.examples.html +164 -0
  85. package/patterns/record-detail-drawer/record-detail-drawer.html +64 -0
  86. package/patterns/responsive-shell-sidebar/README.md +37 -0
  87. package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.css +39 -0
  88. package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.examples.html +208 -0
  89. package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.html +47 -0
  90. package/patterns/retention-cohort/retention-cohort.examples.html +149 -0
  91. package/patterns/retention-cohort/retention-cohort.examples.js +37 -0
  92. package/patterns/retention-cohort/retention-cohort.html +62 -0
  93. package/patterns/search-discovery/search-discovery.examples.html +263 -0
  94. package/patterns/search-discovery/search-discovery.html +58 -0
  95. package/patterns/system-banners/system-banners.examples.html +150 -0
  96. package/patterns/system-banners/system-banners.html +52 -0
  97. package/patterns/timezone-selector/timezone-selector.examples.html +82 -0
  98. package/patterns/timezone-selector/timezone-selector.examples.js +72 -0
  99. package/patterns/timezone-selector/timezone-selector.html +57 -0
  100. package/patterns/wizard-drawer/wizard-drawer.examples.html +144 -0
  101. package/patterns/wizard-drawer/wizard-drawer.examples.js +33 -0
  102. package/patterns/wizard-drawer/wizard-drawer.html +72 -0
@@ -0,0 +1,60 @@
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>Agent Tool Call (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/agent-artifact/agent-artifact.css">
14
+ <link rel="stylesheet" href="../../components/alert/alert.css">
15
+ <link rel="stylesheet" href="../../components/button/button.css">
16
+ <link rel="stylesheet" href="../../components/code/code.css">
17
+ <link rel="stylesheet" href="../../components/col/col.css">
18
+ <link rel="stylesheet" href="../../components/description-list/description-list.css">
19
+ <link rel="stylesheet" href="../../components/progress/progress.css">
20
+ <link rel="stylesheet" href="../../components/row/row.css">
21
+ <link rel="stylesheet" href="../../components/tag/tag.css">
22
+ <link rel="stylesheet" href="../../components/text/text.css">
23
+
24
+ <!-- Component JS -->
25
+ <script type="module" src="../../components/agent-artifact/agent-artifact.js"></script>
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/code/code.js"></script>
29
+ <script type="module" src="../../components/col/col.js"></script>
30
+ <script type="module" src="../../components/description-list/description-list.js"></script>
31
+ <script type="module" src="../../components/progress/progress.js"></script>
32
+ <script type="module" src="../../components/row/row.js"></script>
33
+ <script type="module" src="../../components/tag/tag.js"></script>
34
+ <script type="module" src="../../components/text/text.js"></script>
35
+
36
+ <style>
37
+ :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); }
38
+ main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
39
+ </style>
40
+ </head>
41
+ <body>
42
+
43
+ <main id="demo-root">
44
+ <p>Loading examples…</p>
45
+ </main>
46
+
47
+ <script type="module">
48
+ const root = document.getElementById('demo-root');
49
+ try {
50
+ const res = await fetch('./agent-tool-call.examples.html');
51
+ if (!res.ok) throw new Error(`fetch failed (${res.status})`);
52
+ root.innerHTML = await res.text();
53
+ } catch (err) {
54
+ root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load agent-tool-call.examples.html — ${err.message}</p>`;
55
+ console.error('[agent-tool-call.html]', err);
56
+ }
57
+ </script>
58
+
59
+ </body>
60
+ </html>
@@ -0,0 +1,105 @@
1
+ <header>
2
+ <div>
3
+ <h1>Alert dialog</h1>
4
+ <div data-actions>
5
+ <tag-ui size="sm">modal-ui</tag-ui> <tag-ui size="sm">field-ui</tag-ui> <tag-ui size="sm">button-ui</tag-ui>
6
+ </div>
7
+ </div>
8
+ <p>Demands acknowledgement before continuing (WAI-APG <a href="https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/">alertdialog</a>). modal-ui composed with destructive-confirm semantics: clear consequence prose, danger-colored primary action, Cancel as the safe default. Distinct from <code>&lt;modal-ui&gt;</code> bare (informational / form modal — role=dialog) and from <a href="/site/components/toast">toast-ui</a> with action (which is non-blocking).</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>Action is irreversible, affects others (workspace-wide delete, billing change), or violates a strong invariant (data loss). The interruption is the point — modal blocks the page; the user must explicitly confirm or cancel. Distinct from <a href="/site/patterns/inline-dialog">inline-dialog</a> (reversible micro-decisions) and from confirm-toast (reversible with timed undo).</p>
14
+ </section>
15
+
16
+ <section data-section data-property="simple-confirm">
17
+ <h2 variant="section">Simple — one-click confirm</h2>
18
+ <p data-note>For ordinary destructive actions where the consequence is bounded (delete a single item). Title carries the question; body carries the consequence; Cancel + Delete actions. modal-ui's <code>[text]</code> attribute is the title — don't author a separate <code>&lt;header&gt;</code>.</p>
19
+ <div data-artifact-container>
20
+ <div data-artifact-item data-artifact-label="delete item — simple confirm">
21
+ <button-ui data-chunk="alert-dialog-simple-trigger" text="Delete item" variant="outline"
22
+ onclick="document.getElementById('alert-dialog-simple').open = true"></button-ui>
23
+ <modal-ui id="alert-dialog-simple" data-chunk="alert-dialog-simple" text="Delete this item?" role="alertdialog">
24
+ <p>This action cannot be undone. The item will be permanently removed from your workspace.</p>
25
+ <div slot="footer" style="display:flex; gap:var(--a-space-2); justify-content:flex-end;">
26
+ <button-ui text="Cancel" variant="ghost"
27
+ onclick="this.closest('modal-ui').open=false"></button-ui>
28
+ <button-ui text="Delete" color="danger"
29
+ onclick="this.closest('modal-ui').open=false"></button-ui>
30
+ </div>
31
+ </modal-ui>
32
+ </div>
33
+ </div>
34
+ </section>
35
+
36
+ <section data-section data-property="type-to-confirm">
37
+ <h2 variant="section">Type-to-confirm — high-consequence gate</h2>
38
+ <p data-note>For workspace-wide / billing / account-level destructives. User must type the resource name (or a fixed string like "DELETE") into the input — the danger button stays disabled until the typed string matches verbatim. Friction is the point: prevents muscle-memory mistakes.</p>
39
+ <div data-artifact-container>
40
+ <div data-artifact-item data-artifact-label="delete workspace — typed gate">
41
+ <button-ui data-chunk="alert-dialog-typed-trigger" text="Delete workspace" variant="outline"
42
+ onclick="document.getElementById('alert-dialog-typed').open = true"></button-ui>
43
+ <modal-ui id="alert-dialog-typed" data-chunk="alert-dialog-typed" text='Delete workspace "acme-prod"?' role="alertdialog">
44
+ <col-ui gap="3">
45
+ <p>This will permanently delete the workspace, all members, all data, and all integrations. <strong>This cannot be undone.</strong></p>
46
+ <field-ui label='Type "acme-prod" to confirm' required>
47
+ <input-ui id="alert-dialog-typed-input" name="confirm" placeholder="acme-prod"
48
+ oninput="document.getElementById('alert-dialog-typed-submit').disabled = this.value !== 'acme-prod'"></input-ui>
49
+ </field-ui>
50
+ </col-ui>
51
+ <div slot="footer" style="display:flex; gap:var(--a-space-2); justify-content:flex-end;">
52
+ <button-ui text="Cancel" variant="ghost"
53
+ onclick="this.closest('modal-ui').open=false; document.getElementById('alert-dialog-typed-input').value='';"></button-ui>
54
+ <button-ui id="alert-dialog-typed-submit" text="Delete workspace" color="danger" disabled
55
+ onclick="this.closest('modal-ui').open=false"></button-ui>
56
+ </div>
57
+ </modal-ui>
58
+ </div>
59
+ </div>
60
+ </section>
61
+
62
+ <section data-section data-property="warning-unsaved">
63
+ <h2 variant="section">Warning — unsaved changes</h2>
64
+ <p data-note>Non-destructive but interrupts to surface a consequence ("leaving this page will lose your edits"). Same alertdialog role; primary action is the SAFE path (Save & close) with the risky path (Discard) as an outline button.</p>
65
+ <div data-artifact-container>
66
+ <div data-artifact-item data-artifact-label="unsaved changes — discard or save">
67
+ <button-ui data-chunk="alert-dialog-unsaved-trigger" text="Close editor" variant="outline"
68
+ onclick="document.getElementById('alert-dialog-unsaved').open = true"></button-ui>
69
+ <modal-ui id="alert-dialog-unsaved" data-chunk="alert-dialog-unsaved" text="Discard unsaved changes?" role="alertdialog">
70
+ <p>You have unsaved changes to this document. Leaving will lose them.</p>
71
+ <div slot="footer" style="display:flex; gap:var(--a-space-2); justify-content:flex-end;">
72
+ <button-ui text="Cancel" variant="ghost"
73
+ onclick="this.closest('modal-ui').open=false"></button-ui>
74
+ <button-ui text="Discard" variant="outline" color="danger"
75
+ onclick="this.closest('modal-ui').open=false"></button-ui>
76
+ <button-ui text="Save & close" variant="primary"
77
+ onclick="this.closest('modal-ui').open=false"></button-ui>
78
+ </div>
79
+ </modal-ui>
80
+ </div>
81
+ </div>
82
+ </section>
83
+
84
+ <section data-section data-property="composition">
85
+ <h2 variant="section">Composition rules</h2>
86
+ <ul>
87
+ <li><strong>role="alertdialog" (not "dialog")</strong> — WAI-APG calls out alertdialog for "demands acknowledgement before continuing". Screen readers announce more assertively + don't allow tab-out to background content.</li>
88
+ <li><strong>Use modal-ui's <code>[text]</code> attribute for the title</strong> — NOT a child <code>&lt;header&gt;</code>. modal-ui auto-stamps the title bar from the attr; authoring your own header collides with the default slot (and the title ends up rendered as body content). See the modal-ui docs for its canonical slot vocabulary.</li>
89
+ <li><strong>Default size is md</strong> — don't downsize to <code>sm</code> "to look tighter". md gives the action buttons proper breathing room. Use <code>lg</code> only when the body has a multi-section form.</li>
90
+ <li><strong>Cancel is safe + first</strong> — render Cancel as <code>variant="ghost"</code> on the left; render the destructive action as <code>color="danger"</code> on the right. Pressing Enter on whatever has focus is the muscle-memory danger — keep Cancel-shaped affordances obvious.</li>
91
+ <li><strong>Type-to-confirm for high-consequence</strong> — disable the danger button until the user types the resource name verbatim. The inline <code>oninput</code> handler toggles <code>[disabled]</code>. Friction is the feature.</li>
92
+ <li><strong>Prose names the consequence + the scope</strong> — "all members, all data, all integrations" beats "this workspace and its contents". Specific scope reduces re-read time.</li>
93
+ <li><strong>Three buttons max</strong> — Cancel + 1 or 2 actions. Anything more is a settings surface, not an alert.</li>
94
+ </ul>
95
+ </section>
96
+
97
+ <section data-section data-property="cross-references">
98
+ <h2 variant="section">Cross-references</h2>
99
+ <ul>
100
+ <li><a href="/site/components/modal">modal-ui</a> — the surface primitive ([text] attribute for title; slot="footer" for actions; role override via <code>role="alertdialog"</code>).</li>
101
+ <li><a href="/site/patterns/inline-dialog">inline-dialog</a> — reversible micro-decision alternative (anchored, non-modal).</li>
102
+ <li><a href="/site/components/toast">toast-ui</a> — undo-able confirmation alternative (non-blocking, timed).</li>
103
+ <li><a href="https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/">WAI-APG alertdialog</a> — pattern source.</li>
104
+ </ul>
105
+ </section>
@@ -0,0 +1,57 @@
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>Alert dialog (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/avatar/avatar.css">
12
+ <link rel="stylesheet" href="../../components/button/button.css">
13
+ <link rel="stylesheet" href="../../components/col/col.css">
14
+ <link rel="stylesheet" href="../../components/field/field.css">
15
+ <link rel="stylesheet" href="../../components/icon/icon.css">
16
+ <link rel="stylesheet" href="../../components/input/input.css">
17
+ <link rel="stylesheet" href="../../components/modal/modal.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
+ <script type="module" src="../../components/avatar/avatar.js"></script>
23
+ <script type="module" src="../../components/button/button.js"></script>
24
+ <script type="module" src="../../components/col/col.js"></script>
25
+ <script type="module" src="../../components/field/field.js"></script>
26
+ <script type="module" src="../../components/icon/icon.js"></script>
27
+ <script type="module" src="../../components/input/input.js"></script>
28
+ <script type="module" src="../../components/modal/modal.js"></script>
29
+ <script type="module" src="../../components/row/row.js"></script>
30
+ <script type="module" src="../../components/tag/tag.js"></script>
31
+ <script type="module" src="../../components/text/text.js"></script>
32
+
33
+ <style>
34
+ :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); }
35
+ main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
36
+ </style>
37
+ </head>
38
+ <body>
39
+
40
+ <main id="demo-root">
41
+ <p>Loading examples…</p>
42
+ </main>
43
+
44
+ <script type="module">
45
+ const root = document.getElementById('demo-root');
46
+ try {
47
+ const res = await fetch('./alert-dialog.examples.html');
48
+ if (!res.ok) throw new Error(`fetch failed (${res.status})`);
49
+ root.innerHTML = await res.text();
50
+ } catch (err) {
51
+ root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load alert-dialog.examples.html — ${err.message}</p>`;
52
+ console.error('[alert-dialog.html]', err);
53
+ }
54
+ </script>
55
+
56
+ </body>
57
+ </html>
@@ -0,0 +1,421 @@
1
+ <style>
2
+ /* Page-local demo helpers — keep inline styles off individual demo
3
+ elements so the markup reads cleanly. ────────────────────────── */
4
+
5
+ /* Bounded-height frame for nav patterns that need real vertical
6
+ space (Spacer, Full Example). Frame is a flex column so the
7
+ nested nav-ui can take remaining height; `min-height: 0`
8
+ lets it shrink + scroll instead of overflowing the rounded box. */
9
+ [data-nav-frame] {
10
+ border: 1px solid var(--md-sys-color-neutral-outline);
11
+ border-radius: var(--a-radius-lg);
12
+ display: flex;
13
+ flex-direction: column;
14
+ }
15
+ [data-nav-frame="md"] { height: 300px; }
16
+ [data-nav-frame="lg"] { height: 480px; }
17
+ [data-nav-frame] > nav-ui {
18
+ flex: 1;
19
+ min-height: 0;
20
+ }
21
+
22
+ /* Side-by-side expanded vs collapsed comparison demo. */
23
+ [data-nav-compare] {
24
+ display: flex;
25
+ gap: var(--a-space-4);
26
+ }
27
+ [data-nav-compare] > [data-col="expanded"] { max-width: 280px; flex: 1; }
28
+ [data-nav-compare] > [data-col="collapsed"] { max-width: 60px; flex: 0 0 auto; }
29
+ [data-nav-compare] [data-col-label] {
30
+ margin-bottom: var(--a-space-2);
31
+ color: var(--a-fg-muted);
32
+ }
33
+
34
+ /* Bordered, content-sized nav for the comparison demo (no fixed
35
+ height — sizes to its own content). */
36
+ [data-nav-bordered] {
37
+ border: 1px solid var(--md-sys-color-neutral-outline);
38
+ border-radius: var(--a-radius-lg);
39
+ padding: var(--a-space-2);
40
+ }
41
+ </style>
42
+
43
+ <header>
44
+ <div>
45
+ <h1>App Nav</h1>
46
+ <div data-actions>
47
+ <tag-ui size="sm">nav-ui</tag-ui>
48
+ </div>
49
+ </div>
50
+ <p>Sidebar navigation pattern with groups, items, dividers, spacers, badges, and collapsed popover flyouts.</p>
51
+ </header>
52
+
53
+ <section data-section data-property="overview">
54
+ <h2 variant="section">Overview</h2>
55
+ <p>
56
+ The <code>nav-ui</code> pattern provides a complete sidebar navigation tree.
57
+ Items can be grouped with collapsible headers, separated with dividers,
58
+ and labeled with section headings. When the nav is collapsed (narrow width),
59
+ groups show their children in popover flyouts instead of inline.
60
+ </p>
61
+
62
+ </section>
63
+
64
+ <section data-section data-property="structure">
65
+ <h2 variant="section">Structure</h2>
66
+ <code-ui language="html">
67
+ <template>
68
+ <nav-ui>
69
+ <!-- Top-level item with icon -->
70
+ <nav-item-ui icon="magnifying-glass" text="Search" value="search">
71
+ <kbd slot="trailing">&#8984;K</kbd>
72
+ </nav-item-ui>
73
+
74
+ <!-- Divider + label -->
75
+ <hr data-nav-divider />
76
+ <span data-nav-label>Platform</span>
77
+
78
+ <!-- Collapsible group -->
79
+ <nav-group-ui icon="gear" text="Settings" open>
80
+ <nav-item-ui text="General" value="general" selected></nav-item-ui>
81
+ <nav-item-ui text="Security" value="security"></nav-item-ui>
82
+ <nav-item-ui text="Billing" value="billing" badge="Pro"></nav-item-ui>
83
+ </nav-group-ui>
84
+
85
+ <!-- Spacer pushes remaining items to the bottom -->
86
+ <span data-nav-spacer></span>
87
+
88
+ <!-- Bottom items -->
89
+ <nav-item-ui icon="question" text="Help" value="help"></nav-item-ui>
90
+ </nav-ui>
91
+ </template>
92
+ </code-ui>
93
+
94
+ </section>
95
+
96
+ <section data-section data-property="groups">
97
+ <h2 variant="section">Groups</h2>
98
+ <p>
99
+ Groups are collapsible sections with a header row. They display an icon,
100
+ label, optional badge, and a caret indicator. Click the header to toggle.
101
+ </p>
102
+ <div data-artifact-container>
103
+ <div data-demo data-artifact-item data-artifact-label="groups">
104
+ <nav-ui data-chunk="app-nav-groups">
105
+ <nav-group-ui icon="gear" text="Settings" open>
106
+ <nav-item-ui text="General" value="general" selected></nav-item-ui>
107
+ <nav-item-ui text="Security" value="security"></nav-item-ui>
108
+ <nav-item-ui text="Notifications" value="notifications"></nav-item-ui>
109
+ </nav-group-ui>
110
+ <nav-group-ui icon="user" text="Team" badge="5">
111
+ <nav-item-ui text="Members" value="members"></nav-item-ui>
112
+ <nav-item-ui text="Roles" value="roles"></nav-item-ui>
113
+ <nav-item-ui text="Invites" value="invites" badge="2"></nav-item-ui>
114
+ </nav-group-ui>
115
+ </nav-ui>
116
+ </div>
117
+ </div>
118
+
119
+ </section>
120
+
121
+ <section data-section data-property="items">
122
+ <h2 variant="section">Items</h2>
123
+ <p>
124
+ Standalone items live outside groups. They can have icons, text, badges,
125
+ and trailing slots (such as keyboard shortcuts).
126
+ </p>
127
+ <div data-artifact-container>
128
+ <div data-demo data-artifact-item data-artifact-label="items">
129
+ <nav-ui data-chunk="app-nav-items">
130
+ <nav-item-ui icon="house" text="Dashboard" value="dashboard" selected></nav-item-ui>
131
+ <nav-item-ui icon="chart-bar" text="Analytics" value="analytics"></nav-item-ui>
132
+ <nav-item-ui icon="book-open" text="Documentation" value="docs"></nav-item-ui>
133
+ <nav-item-ui icon="chat-circle" text="Support" value="support" badge="3"></nav-item-ui>
134
+ </nav-ui>
135
+ </div>
136
+ </div>
137
+
138
+ </section>
139
+
140
+ <section data-section data-property="badges">
141
+ <h2 variant="section">Badges</h2>
142
+ <p>
143
+ Items and groups both accept a <code>badge</code> attribute that
144
+ renders a small trailing chip. The badge takes any string —
145
+ numeric counts, "New" / "Beta" callouts, plan tiers, status
146
+ labels — single visual style, content does the differentiating.
147
+ </p>
148
+
149
+ <h3>Counts</h3>
150
+ <p data-note>
151
+ Inbox / notifications / pending items. Use literal numbers up to
152
+ a threshold then "<code>99+</code>" or similar to keep the chip
153
+ width bounded.
154
+ </p>
155
+ <div data-artifact-container>
156
+ <div data-demo data-artifact-item data-artifact-label="counts">
157
+ <nav-ui data-chunk="app-nav-badges-counts">
158
+ <nav-item-ui icon="tray" text="Inbox" value="inbox" badge="12" selected></nav-item-ui>
159
+ <nav-item-ui icon="bell" text="Notifications" value="notifications" badge="3"></nav-item-ui>
160
+ <nav-item-ui icon="envelope-open" text="Mentions" value="mentions" badge="1"></nav-item-ui>
161
+ <nav-item-ui icon="warning-circle" text="Alerts" value="alerts" badge="99+"></nav-item-ui>
162
+ </nav-ui>
163
+ </div>
164
+ </div>
165
+
166
+ <h3>Status callouts</h3>
167
+ <p data-note>
168
+ "New" / "Beta" / "Soon" — flag a feature lifecycle stage so users
169
+ know what's just shipped, what's in preview, and what's coming.
170
+ </p>
171
+ <div data-artifact-container>
172
+ <div data-demo data-artifact-item data-artifact-label="status callouts">
173
+ <nav-ui data-chunk="app-nav-badges-status-callouts">
174
+ <nav-item-ui icon="sparkle" text="AI Assistant" value="assistant" badge="New"></nav-item-ui>
175
+ <nav-item-ui icon="flask" text="Experiments" value="experiments" badge="Beta"></nav-item-ui>
176
+ <nav-item-ui icon="hourglass" text="Real-time sync" value="rtsync" badge="Soon"></nav-item-ui>
177
+ <nav-item-ui icon="archive" text="Archive" value="archive"></nav-item-ui>
178
+ </nav-ui>
179
+ </div>
180
+ </div>
181
+
182
+ <h3>Plan tiers</h3>
183
+ <p data-note>
184
+ Surface paywalled / tier-locked items so users see what their plan
185
+ unlocks. Pair with a click-handler that opens a billing dialog
186
+ when a non-eligible plan tries to enter.
187
+ </p>
188
+ <div data-artifact-container>
189
+ <div data-demo data-artifact-item data-artifact-label="plan tiers">
190
+ <nav-ui data-chunk="app-nav-badges-plan-tiers">
191
+ <nav-item-ui icon="house" text="Dashboard" value="dashboard"></nav-item-ui>
192
+ <nav-item-ui icon="chart-line" text="Forecasting" value="forecasting" badge="Pro"></nav-item-ui>
193
+ <nav-item-ui icon="users-three" text="Audit log" value="audit" badge="Team"></nav-item-ui>
194
+ <nav-item-ui icon="key" text="SSO" value="sso" badge="Enterprise"></nav-item-ui>
195
+ </nav-ui>
196
+ </div>
197
+ </div>
198
+
199
+ <h3>Groups with rollup badges</h3>
200
+ <p data-note>
201
+ Group headers carry a badge that summarizes child state — total
202
+ open count, oldest unread, "needs attention" indicator. The group
203
+ badge sits on the collapsed header so users see the rollup
204
+ without expanding.
205
+ </p>
206
+ <div data-artifact-container>
207
+ <div data-demo data-artifact-item data-artifact-label="group rollup badges">
208
+ <nav-ui data-chunk="app-nav-badges-group-rollup-badges">
209
+ <nav-group-ui icon="tray" text="Inbox" badge="14" open>
210
+ <nav-item-ui text="Unread" value="unread" badge="12" selected></nav-item-ui>
211
+ <nav-item-ui text="Mentions" value="mentions" badge="2"></nav-item-ui>
212
+ <nav-item-ui text="All messages" value="all"></nav-item-ui>
213
+ </nav-group-ui>
214
+ <nav-group-ui icon="users" text="Team" badge="3 invites">
215
+ <nav-item-ui text="Members" value="members"></nav-item-ui>
216
+ <nav-item-ui text="Pending invites" value="invites" badge="3"></nav-item-ui>
217
+ </nav-group-ui>
218
+ </nav-ui>
219
+ </div>
220
+ </div>
221
+
222
+ <h3>Mixed</h3>
223
+ <p data-note>
224
+ Real navs combine the above — counts on activity-driven items,
225
+ status callouts on new features, plan badges on paywalled
226
+ surfaces, group rollups summarizing child state. The badge slot
227
+ is one of the cheapest ways to surface "what changed since I
228
+ last looked" inside a sidebar.
229
+ </p>
230
+ <div data-artifact-container>
231
+ <div data-demo data-artifact-item data-artifact-label="mixed">
232
+ <nav-ui data-chunk="app-nav-badges-mixed">
233
+ <nav-item-ui icon="house" text="Home" value="home" selected></nav-item-ui>
234
+ <nav-item-ui icon="tray" text="Inbox" value="inbox" badge="7"></nav-item-ui>
235
+ <hr data-nav-divider />
236
+ <span data-nav-label>Workspace</span>
237
+ <nav-group-ui icon="folder" text="Projects" badge="2 stale">
238
+ <nav-item-ui text="Active" value="active"></nav-item-ui>
239
+ <nav-item-ui text="Stale" value="stale" badge="2"></nav-item-ui>
240
+ <nav-item-ui text="Archived" value="archived"></nav-item-ui>
241
+ </nav-group-ui>
242
+ <nav-item-ui icon="sparkle" text="AI Assistant" value="assistant" badge="New"></nav-item-ui>
243
+ <nav-item-ui icon="chart-line" text="Forecasting" value="forecasting" badge="Pro"></nav-item-ui>
244
+ </nav-ui>
245
+ </div>
246
+ </div>
247
+
248
+ <p data-note>
249
+ Badges hide automatically when <code>nav-ui[collapsed]</code>
250
+ is set — see the <a href="#collapsed-mode">Collapsed Mode</a>
251
+ section. If a badge needs to remain visible in the collapsed rail
252
+ (e.g., a "9+" attention dot on Inbox), use a custom indicator in
253
+ the <code>trailing</code> slot of the icon-only item instead.
254
+ </p>
255
+ </section>
256
+
257
+ <section data-section data-property="labels-and-dividers">
258
+ <h2 variant="section">Labels and Dividers</h2>
259
+ <p>
260
+ Use <code>data-nav-label</code> for section headings and
261
+ <code>data-nav-divider</code> for visual separation.
262
+ </p>
263
+ <div data-artifact-container>
264
+ <div data-demo data-artifact-item data-artifact-label="labels and dividers">
265
+ <nav-ui data-chunk="app-nav-labels-and-dividers">
266
+ <span data-nav-label>Platform</span>
267
+ <nav-item-ui icon="gear" text="Settings" value="settings"></nav-item-ui>
268
+ <nav-item-ui icon="user" text="Profile" value="profile"></nav-item-ui>
269
+ <hr data-nav-divider />
270
+ <span data-nav-label>Resources</span>
271
+ <nav-item-ui icon="book-open" text="Docs" value="docs"></nav-item-ui>
272
+ <nav-item-ui icon="chat-circle" text="Support" value="support"></nav-item-ui>
273
+ </nav-ui>
274
+ </div>
275
+ </div>
276
+
277
+ </section>
278
+
279
+ <section data-section data-property="spacer">
280
+ <h2 variant="section">Spacer</h2>
281
+ <p>
282
+ The <code>data-nav-spacer</code> element acts as a flex spacer, pushing
283
+ subsequent items to the bottom of the sidebar.
284
+ </p>
285
+ <div data-artifact-container>
286
+ <div data-demo data-artifact-item data-artifact-label="spacer" data-nav-frame="md">
287
+ <nav-ui data-chunk="app-nav-spacer">
288
+ <nav-item-ui icon="house" text="Home" value="home" selected></nav-item-ui>
289
+ <nav-item-ui icon="gear" text="Settings" value="settings"></nav-item-ui>
290
+ <span data-nav-spacer></span>
291
+ <hr data-nav-divider />
292
+ <nav-item-ui icon="question" text="Help & Feedback" value="help"></nav-item-ui>
293
+ </nav-ui>
294
+ </div>
295
+ </div>
296
+
297
+ </section>
298
+
299
+ <section data-section data-property="collapsed-mode">
300
+ <h2 variant="section">Collapsed Mode</h2>
301
+ <p>
302
+ When <code>collapsed</code> is set on the nav, labels and badges hide.
303
+ Only icons remain visible. Clicking a group header opens a popover flyout
304
+ with its children instead of toggling inline.
305
+ </p>
306
+ <div data-demo data-nav-compare>
307
+ <div data-col="expanded">
308
+ <p data-col-label>Expanded</p>
309
+ <nav-ui data-nav-bordered>
310
+ <nav-group-ui icon="gear" text="Settings" open>
311
+ <nav-item-ui text="General" value="general" selected></nav-item-ui>
312
+ <nav-item-ui text="Security" value="security"></nav-item-ui>
313
+ </nav-group-ui>
314
+ <nav-item-ui icon="book-open" text="Docs" value="docs"></nav-item-ui>
315
+ </nav-ui>
316
+ </div>
317
+ <div data-col="collapsed">
318
+ <p data-col-label>Collapsed</p>
319
+ <nav-ui collapsed data-nav-bordered>
320
+ <nav-group-ui icon="gear" text="Settings">
321
+ <nav-item-ui text="General" value="general2"></nav-item-ui>
322
+ <nav-item-ui text="Security" value="security2"></nav-item-ui>
323
+ </nav-group-ui>
324
+ <nav-item-ui icon="book-open" text="Docs" value="docs2"></nav-item-ui>
325
+ </nav-ui>
326
+ </div>
327
+ </div>
328
+
329
+ </section>
330
+
331
+ <section data-section data-property="full-example">
332
+ <h2 variant="section">Full Example</h2>
333
+ <p>A complete navigation sidebar as used in the admin pattern:</p>
334
+ <div data-artifact-container>
335
+ <div data-demo data-artifact-item data-artifact-label="full example" data-nav-frame="lg">
336
+ <nav-ui data-chunk="app-nav-full-example">
337
+ <nav-item-ui icon="magnifying-glass" text="Search" value="search">
338
+ <kbd slot="trailing">&#8984;K</kbd>
339
+ </nav-item-ui>
340
+ <hr data-nav-divider />
341
+ <span data-nav-label>Platform</span>
342
+ <nav-group-ui icon="gear" text="Settings" open>
343
+ <nav-item-ui text="General" value="general" selected></nav-item-ui>
344
+ <nav-item-ui text="Security" value="security"></nav-item-ui>
345
+ <nav-item-ui text="Notifications" value="notifications"></nav-item-ui>
346
+ <nav-item-ui text="Billing" value="billing" badge="Pro"></nav-item-ui>
347
+ </nav-group-ui>
348
+ <nav-group-ui icon="user" text="Team" badge="5">
349
+ <nav-item-ui text="Members" value="members"></nav-item-ui>
350
+ <nav-item-ui text="Roles" value="roles"></nav-item-ui>
351
+ </nav-group-ui>
352
+ <hr data-nav-divider />
353
+ <span data-nav-label>Observe</span>
354
+ <nav-group-ui icon="chart-bar" text="Analytics">
355
+ <nav-item-ui text="Dashboard" value="dashboard"></nav-item-ui>
356
+ <nav-item-ui text="Reports" value="reports"></nav-item-ui>
357
+ </nav-group-ui>
358
+ <span data-nav-spacer></span>
359
+ <hr data-nav-divider />
360
+ <nav-item-ui icon="question" text="Help & Feedback" value="help"></nav-item-ui>
361
+ </nav-ui>
362
+ </div>
363
+ </div>
364
+
365
+ </section>
366
+
367
+ <section data-section data-property="api">
368
+ <h2 variant="section">API</h2>
369
+ <table>
370
+ <thead>
371
+ <tr>
372
+ <th>Element</th>
373
+ <th>Attribute</th>
374
+ <th>Type</th>
375
+ <th>Description</th>
376
+ </tr>
377
+ </thead>
378
+ <tbody>
379
+ <tr><td><code>nav-ui</code></td><td><code>collapsed</code></td><td>boolean</td><td>Show icons only, groups use popover flyouts</td></tr>
380
+ <tr><td><code>nav-group-ui</code></td><td><code>icon</code></td><td>string</td><td>Phosphor icon name for the group header</td></tr>
381
+ <tr><td><code>nav-group-ui</code></td><td><code>text</code></td><td>string</td><td>Group label text</td></tr>
382
+ <tr><td><code>nav-group-ui</code></td><td><code>badge</code></td><td>string</td><td>Badge text on the group header</td></tr>
383
+ <tr><td><code>nav-group-ui</code></td><td><code>open</code></td><td>boolean</td><td>Expand this group on load</td></tr>
384
+ <tr><td><code>nav-item-ui</code></td><td><code>icon</code></td><td>string</td><td>Phosphor icon name</td></tr>
385
+ <tr><td><code>nav-item-ui</code></td><td><code>text</code></td><td>string</td><td>Item label</td></tr>
386
+ <tr><td><code>nav-item-ui</code></td><td><code>value</code></td><td>string</td><td>Value emitted in nav-select event</td></tr>
387
+ <tr><td><code>nav-item-ui</code></td><td><code>badge</code></td><td>string</td><td>Badge text</td></tr>
388
+ <tr><td><code>nav-item-ui</code></td><td><code>selected</code></td><td>boolean</td><td>Marks this item as the current selection</td></tr>
389
+ </tbody>
390
+ </table>
391
+
392
+ </section>
393
+
394
+ <section data-section data-property="events">
395
+ <h2 variant="section">Events</h2>
396
+ <table>
397
+ <thead>
398
+ <tr>
399
+ <th>Event</th>
400
+ <th>Target</th>
401
+ <th>Detail</th>
402
+ </tr>
403
+ </thead>
404
+ <tbody>
405
+ <tr><td><code>nav-select</code></td><td><code>nav-ui</code></td><td><code>{ item, text, value }</code></td></tr>
406
+ </tbody>
407
+ </table>
408
+ </section>
409
+
410
+ <section data-section data-property="rules">
411
+ <h2 variant="section">Authoring rules</h2>
412
+ <ul>
413
+ <li><strong>Always use <code>nav-ui</code> + <code>nav-item-ui</code></strong> for sidebar and in-page navigation. Never use <code>menu-ui</code> in a nav context — <code>menu-ui</code> is for popover dropdown menus, not navigation rails.</li>
414
+ <li><strong>Every <code>nav-item-ui</code> must have <code>icon=</code>.</strong> When the sidebar collapses to icon-only mode, items without an icon become invisible. Provide a meaningful Phosphor icon name on every row.</li>
415
+ <li><strong>Use <code>nav-group-ui</code> for collapsible sub-navs</strong>, never nested <code>nav-ui</code>. <code>nav-group-ui</code> owns the chevron toggle, open/closed state, and keyboard navigation for the group.</li>
416
+ <li><strong>Use <code>&lt;hr data-nav-divider /&gt;</code> for visual separators</strong>, not bare <code>&lt;hr&gt;</code>. The plain <code>&lt;hr&gt;</code> renders as a content divider with different spacing; <code>data-nav-divider</code> renders as a subtle nav-rail separator.</li>
417
+ <li><strong>The workspace switcher belongs in <code>&lt;admin-topbar slot="header"&gt;</code></strong>, not inside <code>nav-ui</code>. The topbar header is the canonical location for workspace context and brand.</li>
418
+ <li><strong>The user switcher belongs in <code>&lt;admin-statusbar slot="footer"&gt;</code></strong>. Placing it inside the nav scroll area causes it to scroll out of view on long nav lists.</li>
419
+ <li><strong>Do not put interactive elements (<code>button-ui</code>, <code>switch-ui</code>) directly inside <code>nav-ui</code></strong> — they break the roving tab index and keyboard navigation model. Use <code>nav-item-ui</code> with event delegation, or place the control outside the nav rail.</li>
420
+ </ul>
421
+ </section>