@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,158 @@
1
+ <header>
2
+ <div>
3
+ <h1>Conversion Funnel</h1>
4
+ <div data-actions>
5
+ <tag-ui size="sm">card-ui</tag-ui> <tag-ui size="sm">progress-row-ui</tag-ui> <tag-ui size="sm">row-ui</tag-ui> <tag-ui size="sm">col-ui</tag-ui>
6
+ </div>
7
+ </div>
8
+ <p>Composition pattern: render a multi-step drop-off funnel without a dedicated funnel component. Uses <code>progress-row-ui</code> for each step so the bar, label, and meta text stay aligned to the card-ui content rhythm.</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
+ Funnel charts ship with a lot of visual baggage (trapezoidal segments, angled
15
+ labels) that don't compose well inside a card. A stack of labeled progress rows
16
+ reads clearer, hits the same "big → small" shape, and stays accessible:
17
+ every step is a real DOM element with a percentage. Use this whenever a user
18
+ needs to see sequential drop-off — onboarding, checkout, activation, paywall.
19
+ </p>
20
+ </section>
21
+
22
+ <section data-section data-property="4-step-funnel">
23
+ <h2 variant="section">Four-step funnel</h2>
24
+ <p data-note>Top step is an explicit 100% baseline (no progress bar — it's the anchor). Subsequent steps use <code>progress-row-ui</code> with the count + percentage in the meta slot.</p>
25
+ <div data-artifact-container>
26
+ <div data-artifact-item data-artifact-label="conversion funnel">
27
+ <card-ui data-chunk="conversion-funnel-4-step-funnel" style="max-width: 560px;">
28
+ <header>
29
+ <h3>Conversion funnel</h3>
30
+ <text-ui slot="description" color="subtle">Visit → Sign up → Activate → Convert</text-ui>
31
+ </header>
32
+ <section>
33
+ <col-ui gap="3">
34
+ <row-ui align="center" gap="3">
35
+ <col-ui gap="0" grow>
36
+ <text-ui strong>Visited landing page</text-ui>
37
+ <text-ui color="subtle">28,432 visitors</text-ui>
38
+ </col-ui>
39
+ <text-ui strong>100%</text-ui>
40
+ </row-ui>
41
+ <progress-row-ui label="Signed up" value="42" meta="11,942 · 42%"></progress-row-ui>
42
+ <progress-row-ui label="Activated" value="28" meta="7,961 · 28%"></progress-row-ui>
43
+ <progress-row-ui label="Converted to paid" value="8" meta="2,274 · 8.0%"></progress-row-ui>
44
+ </col-ui>
45
+ </section>
46
+ </card-ui>
47
+ </div>
48
+ </div>
49
+ </section>
50
+
51
+ <section data-section data-property="with-segment-compare">
52
+ <h2 variant="section">With segment comparison</h2>
53
+ <p data-note>Pair the funnel card with a segmented control in <code>slot="action"</code> so users can switch between cohorts (e.g. new-vs-returning, mobile-vs-desktop). Swap the <code>value</code> + <code>meta</code> attributes in setup.js on segment change.</p>
54
+ <div data-artifact-container>
55
+ <div data-artifact-item data-artifact-label="funnel with cohort toggle">
56
+ <card-ui data-chunk="conversion-funnel-with-segment-compare" style="max-width: 560px;">
57
+ <header>
58
+ <h3>Checkout funnel</h3>
59
+ <text-ui slot="description" color="subtle">Last 30 days · by first-time vs returning</text-ui>
60
+ <span slot="action">
61
+ <segmented-ui value="new" size="sm">
62
+ <segment-ui value="new" text="New"></segment-ui>
63
+ <segment-ui value="returning" text="Returning"></segment-ui>
64
+ </segmented-ui>
65
+ </span>
66
+ </header>
67
+ <section>
68
+ <col-ui gap="3">
69
+ <row-ui align="center" gap="3">
70
+ <col-ui gap="0" grow>
71
+ <text-ui strong>Cart viewed</text-ui>
72
+ <text-ui color="subtle">42,180 sessions</text-ui>
73
+ </col-ui>
74
+ <text-ui strong>100%</text-ui>
75
+ </row-ui>
76
+ <progress-row-ui label="Added to cart" value="58" meta="24,464 · 58%"></progress-row-ui>
77
+ <progress-row-ui label="Reached payment" value="34" meta="14,341 · 34%"></progress-row-ui>
78
+ <progress-row-ui label="Completed purchase" value="19" meta="8,014 · 19%"></progress-row-ui>
79
+ </col-ui>
80
+ </section>
81
+ <footer divider>
82
+ <small slot="description">Funnel window: 30 days · ends at first purchase or abandonment.</small>
83
+ <span slot="action">
84
+ <button-ui text="View in analytics" variant="ghost" size="sm" icon="arrow-square-out"></button-ui>
85
+ </span>
86
+ </footer>
87
+ </card-ui>
88
+ </div>
89
+ </div>
90
+ </section>
91
+
92
+ <section data-section data-property="wide-summary">
93
+ <h2 variant="section">Wide summary with step-over-step delta</h2>
94
+ <p data-note>For board reporting, combine the funnel with a step-over-step delta column so stakeholders can see exactly where the biggest drop-off happens. Delta is a <code>badge-ui</code> colored by severity.</p>
95
+ <div data-artifact-container>
96
+ <div data-artifact-item data-artifact-label="funnel with step-over-step">
97
+ <card-ui data-chunk="conversion-funnel-wide-summary" style="max-width: 640px;">
98
+ <header>
99
+ <h3>Signup funnel</h3>
100
+ <text-ui slot="description" color="subtle">Step-over-step conversion, last 7 days</text-ui>
101
+ </header>
102
+ <section>
103
+ <col-ui gap="3">
104
+ <row-ui align="center" gap="3">
105
+ <col-ui gap="0" grow>
106
+ <text-ui strong>Signup form viewed</text-ui>
107
+ <text-ui color="subtle">8,420 visitors</text-ui>
108
+ </col-ui>
109
+ <text-ui strong>100%</text-ui>
110
+ </row-ui>
111
+ <row-ui align="center" gap="3">
112
+ <progress-row-ui label="Email verified" value="68" meta="5,726 · 68%" grow></progress-row-ui>
113
+ <badge-ui text="−32%" variant="warning"></badge-ui>
114
+ </row-ui>
115
+ <row-ui align="center" gap="3">
116
+ <progress-row-ui label="Workspace created" value="54" meta="4,547 · 54%" grow></progress-row-ui>
117
+ <badge-ui text="−21%" variant="muted"></badge-ui>
118
+ </row-ui>
119
+ <row-ui align="center" gap="3">
120
+ <progress-row-ui label="Invited a teammate" value="22" meta="1,852 · 22%" grow></progress-row-ui>
121
+ <badge-ui text="−59%" variant="danger"></badge-ui>
122
+ </row-ui>
123
+ </col-ui>
124
+ </section>
125
+ </card-ui>
126
+ </div>
127
+ </div>
128
+ </section>
129
+
130
+ <section data-section data-property="variants-and-knobs">
131
+ <h2 variant="section">Variants &amp; knobs</h2>
132
+ <ul data-note>
133
+ <li><strong>Step count.</strong> Keep to 3–6 steps. Beyond 6 the drop-off numbers lose impact; split into nested funnels.</li>
134
+ <li><strong>Top-row value.</strong> Always show the absolute count next to a 100% label — it anchors every subsequent percentage.</li>
135
+ <li><strong>Meta format.</strong> <code>meta="count · percent"</code> is the canonical order. Count first reads as data, percent second reads as insight.</li>
136
+ <li><strong>Color coding.</strong> Don't tint the progress bars by drop-off severity — it implies "bad" for inherently-lossy funnels. Use a neutral progress color and let the numbers speak.</li>
137
+ <li><strong>Delta column (optional).</strong> When step-over-step matters more than overall conversion, add a <code>badge-ui</code> in a sibling column: <code>warning</code> for 20–40% drop, <code>danger</code> above 40%.</li>
138
+ </ul>
139
+ </section>
140
+
141
+ <section data-section data-property="anti-patterns">
142
+ <h2 variant="section">Anti-patterns</h2>
143
+ <ul data-note>
144
+ <li><strong>Don't use a trapezoidal funnel SVG.</strong> The angled geometry burns horizontal space, makes labels hard to align, and provides no precision benefit over a stacked progress pattern.</li>
145
+ <li><strong>Don't fill the bar for step 1.</strong> 100% is the anchor, not data. Render it as a plain row so step 2 becomes the first visible drop.</li>
146
+ <li><strong>Don't encode drop-off in bar color alone.</strong> CVD users can't distinguish severities by hue — always pair with a numeric badge or explicit text.</li>
147
+ </ul>
148
+ </section>
149
+
150
+ <section data-section data-property="rules">
151
+ <h2 variant="section">Authoring rules</h2>
152
+ <ul>
153
+ <li><strong>Steps must be ordered by drop-off severity</strong> — widest bar at top (entry), narrowest at bottom (conversion). Do not reorder steps for aesthetic reasons.</li>
154
+ <li><strong>Label every step with the action, not the state.</strong> "Started checkout" not "Checkout". The label describes what the user did to enter this stage.</li>
155
+ <li><strong>Always show the percentage alongside the absolute count</strong> — absolute numbers without percentages hide relative drop-off; percentages without absolutes hide scale.</li>
156
+ <li><strong>Use <code>chart-in-card</code> pattern for standalone KPI surfaces</strong>, not <code>conversion-funnel</code>. Funnels require at least 3 sequential stages and a meaningful conversion event.</li>
157
+ </ul>
158
+ </section>
@@ -0,0 +1,4 @@
1
+ /** Conversion Funnel pattern — no dynamic wiring; static demo content. */
2
+ export default function setup(_router) {
3
+ // Pattern is pure HTML. Kept a setup hook for parity with other patterns.
4
+ }
@@ -0,0 +1,64 @@
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>Conversion Funnel (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/badge/badge.css">
14
+ <link rel="stylesheet" href="../../components/button/button.css">
15
+ <link rel="stylesheet" href="../../components/card/card.css">
16
+ <link rel="stylesheet" href="../../components/col/col.css">
17
+ <link rel="stylesheet" href="../../components/progress-row/progress-row.css">
18
+ <link rel="stylesheet" href="../../components/row/row.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/tag/tag.css">
22
+ <link rel="stylesheet" href="../../components/text/text.css">
23
+
24
+ <!-- Component JS -->
25
+ <script type="module" src="../../components/badge/badge.js"></script>
26
+ <script type="module" src="../../components/button/button.js"></script>
27
+ <script type="module" src="../../components/card/card.js"></script>
28
+ <script type="module" src="../../components/col/col.js"></script>
29
+ <script type="module" src="../../components/progress-row/progress-row.js"></script>
30
+ <script type="module" src="../../components/row/row.js"></script>
31
+ <script type="module" src="../../components/segment/segment.js"></script>
32
+ <script type="module" src="../../components/segmented/segmented.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('./conversion-funnel.examples.html');
51
+ if (!res.ok) throw new Error(`fetch failed (${res.status})`);
52
+ root.innerHTML = await res.text();
53
+ try {
54
+ const mod = await import(/* @vite-ignore */ './conversion-funnel.examples.js');
55
+ mod.default?.(root);
56
+ } catch (e) { console.error('[conversion-funnel.html] setup failed:', e); }
57
+ } catch (err) {
58
+ root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load conversion-funnel.examples.html — ${err.message}</p>`;
59
+ console.error('[conversion-funnel.html]', err);
60
+ }
61
+ </script>
62
+
63
+ </body>
64
+ </html>
@@ -0,0 +1,196 @@
1
+ <header>
2
+ <div>
3
+ <h1>Inline-edit grids &amp; tree tables</h1>
4
+ <div data-actions>
5
+ <tag-ui size="sm">table-ui</tag-ui> <tag-ui size="sm">tree-ui</tag-ui> <tag-ui size="sm">input-ui</tag-ui> <tag-ui size="sm">field-ui</tag-ui> <tag-ui size="sm">tag-ui</tag-ui>
6
+ </div>
7
+ </div>
8
+ <p>Two adjacent advanced data-table patterns: spreadsheet-style cells the user can edit inline (06i) and hierarchical rows with expand/collapse (06j). Both compose existing primitives — `&lt;table-ui&gt;` for the grid, `&lt;tree-ui&gt;` for the hierarchy.</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
+ Inline-edit grids: when the user spends most of their time
15
+ correcting/refining row data — pricing matrices, inventory
16
+ counts, bulk metadata editing. Distinct from a detail drawer
17
+ (12b) which is for one-row-at-a-time depth. Tree tables: when
18
+ rows are recursively nested and the hierarchy is the data —
19
+ org charts, file trees, accounting categories. Distinct from
20
+ a flat table with a parent-id column.
21
+ </p>
22
+ </section>
23
+
24
+ <section data-section data-property="inline-edit-row">
25
+ <h2 variant="section">Inline-edit — single editing row</h2>
26
+ <p data-note>The most common shape: a normal table where one row at a time enters edit mode (double-click or pencil button). Cells become `&lt;input-ui&gt;` / `&lt;select-ui&gt;` / etc.; Save / Cancel actions appear in the row's trailing column.</p>
27
+ <div data-artifact-container>
28
+ <div data-artifact-item data-artifact-label="single editing row">
29
+ <card-ui data-chunk="table-inline-edit-row">
30
+ <header>
31
+ <span slot="heading" variant="section">Pricing matrix</span>
32
+ <text-ui slot="description" color="subtle">12 rows · 1 unsaved</text-ui>
33
+ <button-ui slot="action" text="Add row" variant="ghost" size="sm" icon-leading="plus"></button-ui>
34
+ </header>
35
+ <section bleed>
36
+ <!-- A real <table> in <table-ui raw> (consumer-owns-body mode) gives
37
+ true column alignment; the editing row (Pro) swaps its Price/Limits
38
+ cells for <input-ui> and its action cell for Save/Cancel. -->
39
+ <table-ui raw>
40
+ <table>
41
+ <thead>
42
+ <tr><th>Plan</th><th>Price</th><th>Limits</th><th></th></tr>
43
+ </thead>
44
+ <tbody>
45
+ <tr>
46
+ <td><text-ui strong>Starter</text-ui></td>
47
+ <td><text-ui color="subtle">$0 / month</text-ui></td>
48
+ <td><text-ui color="subtle">5 seats · 1k requests</text-ui></td>
49
+ <td><button-ui icon="pencil-simple" variant="ghost" size="sm" aria-label="Edit"></button-ui></td>
50
+ </tr>
51
+ <tr style="background: var(--a-bg-subtle);">
52
+ <td><text-ui strong>Pro</text-ui></td>
53
+ <td><input-ui name="pro_price" value="$29" size="sm"></input-ui></td>
54
+ <td><input-ui name="pro_features" value="50 seats · 100k requests" size="sm"></input-ui></td>
55
+ <td>
56
+ <row-ui gap="2" align="center">
57
+ <button-ui text="Save" variant="primary" size="sm"></button-ui>
58
+ <button-ui text="Cancel" variant="ghost" size="sm"></button-ui>
59
+ </row-ui>
60
+ </td>
61
+ </tr>
62
+ <tr>
63
+ <td><text-ui strong>Enterprise</text-ui></td>
64
+ <td><text-ui color="subtle">Custom</text-ui></td>
65
+ <td><text-ui color="subtle">Unlimited · SSO · SLA</text-ui></td>
66
+ <td><button-ui icon="pencil-simple" variant="ghost" size="sm" aria-label="Edit"></button-ui></td>
67
+ </tr>
68
+ </tbody>
69
+ </table>
70
+ </table-ui>
71
+ </section>
72
+ </card-ui>
73
+ </div>
74
+ </div>
75
+ </section>
76
+
77
+ <section data-section data-property="spreadsheet-cells">
78
+ <h2 variant="section">Spreadsheet — every cell editable</h2>
79
+ <p data-note>The full Excel-style shape: every cell renders an `&lt;input-ui&gt;` (or typed equivalent — number, select, date). Tab moves to the next cell, Enter commits + moves down. Saves are auto-debounced; the dirty state surfaces as a per-row tag.</p>
80
+ <div data-artifact-container>
81
+ <div data-artifact-item data-artifact-label="spreadsheet cells">
82
+ <card-ui data-chunk="table-spreadsheet-cells">
83
+ <header>
84
+ <span slot="heading" variant="section">Inventory — Q4 forecast</span>
85
+ <text-ui slot="description" color="subtle">Auto-saving · 3 cells dirty</text-ui>
86
+ <row-ui slot="action" gap="2">
87
+ <button-ui text="Undo" variant="ghost" size="sm" icon-leading="arrow-counter-clockwise"></button-ui>
88
+ <button-ui text="Save now" variant="primary" size="sm"></button-ui>
89
+ </row-ui>
90
+ </header>
91
+ <section bleed>
92
+ <!-- Every cell is an <input-ui>; a real <table> gives the Excel-style
93
+ column alignment the list-item flex layout couldn't. The per-row
94
+ dirty/clean state sits in its own Status column. -->
95
+ <table-ui raw>
96
+ <table>
97
+ <thead>
98
+ <tr><th>Item</th><th>Oct</th><th>Nov</th><th>Dec</th><th>Status</th></tr>
99
+ </thead>
100
+ <tbody>
101
+ <tr>
102
+ <td><text-ui strong>Widget A</text-ui></td>
103
+ <td><input-ui type="number" value="124" size="sm"></input-ui></td>
104
+ <td><input-ui type="number" value="98" size="sm"></input-ui></td>
105
+ <td><input-ui type="number" value="156" size="sm"></input-ui></td>
106
+ <td><tag-ui size="sm" variant="muted">clean</tag-ui></td>
107
+ </tr>
108
+ <tr>
109
+ <td><text-ui strong>Widget B</text-ui></td>
110
+ <td><input-ui type="number" value="42" size="sm"></input-ui></td>
111
+ <td><input-ui type="number" value="51" size="sm"></input-ui></td>
112
+ <td><input-ui type="number" value="78" size="sm"></input-ui></td>
113
+ <td><tag-ui size="sm" variant="warning">dirty</tag-ui></td>
114
+ </tr>
115
+ <tr>
116
+ <td><text-ui strong>Widget C</text-ui></td>
117
+ <td><input-ui type="number" value="0" size="sm"></input-ui></td>
118
+ <td><input-ui type="number" value="0" size="sm"></input-ui></td>
119
+ <td><input-ui type="number" value="320" size="sm"></input-ui></td>
120
+ <td><tag-ui size="sm" variant="warning">dirty</tag-ui></td>
121
+ </tr>
122
+ <tr>
123
+ <td><text-ui strong>Widget D</text-ui></td>
124
+ <td><input-ui type="number" value="200" size="sm"></input-ui></td>
125
+ <td><input-ui type="number" value="245" size="sm"></input-ui></td>
126
+ <td><input-ui type="number" value="280" size="sm"></input-ui></td>
127
+ <td><tag-ui size="sm" variant="muted">clean</tag-ui></td>
128
+ </tr>
129
+ </tbody>
130
+ </table>
131
+ </table-ui>
132
+ </section>
133
+ </card-ui>
134
+ </div>
135
+ </div>
136
+ </section>
137
+
138
+ <section data-section data-property="tree-table-basic">
139
+ <h2 variant="section">Tree table — hierarchical rows</h2>
140
+ <p data-note>Use <code>&lt;tree-ui&gt;</code> for the recursion. Each <code>&lt;tree-item-ui&gt;</code> renders the chevron + indent automatically; nested items go inside the parent's default slot. Common in budgets, org charts, file browsers.</p>
141
+ <div data-artifact-container>
142
+ <div data-artifact-item data-artifact-label="tree table">
143
+ <card-ui data-chunk="tree-table-basic">
144
+ <header>
145
+ <span slot="heading" variant="section">Q4 budget — by department</span>
146
+ <text-ui slot="description" color="subtle">Total: $1.24M · 4 departments · 12 categories</text-ui>
147
+ </header>
148
+ <section bleed>
149
+ <tree-ui style="padding: var(--a-space-2);">
150
+ <tree-item-ui text="Engineering — $620k" icon="cpu">
151
+ <tree-item-ui text="Salaries — $480k"></tree-item-ui>
152
+ <tree-item-ui text="Tooling — $80k"></tree-item-ui>
153
+ <tree-item-ui text="Travel — $60k"></tree-item-ui>
154
+ </tree-item-ui>
155
+ <tree-item-ui text="Design — $180k" icon="palette">
156
+ <tree-item-ui text="Salaries — $140k"></tree-item-ui>
157
+ <tree-item-ui text="Software — $20k"></tree-item-ui>
158
+ <tree-item-ui text="Conferences — $20k"></tree-item-ui>
159
+ </tree-item-ui>
160
+ <tree-item-ui text="Sales &amp; marketing — $320k" icon="megaphone-simple">
161
+ <tree-item-ui text="Salaries — $200k"></tree-item-ui>
162
+ <tree-item-ui text="Ad spend — $80k"></tree-item-ui>
163
+ <tree-item-ui text="Events — $40k"></tree-item-ui>
164
+ </tree-item-ui>
165
+ <tree-item-ui text="Operations — $120k" icon="gear"></tree-item-ui>
166
+ </tree-ui>
167
+ </section>
168
+ </card-ui>
169
+ </div>
170
+ </div>
171
+ </section>
172
+
173
+ <section data-section data-property="composition">
174
+ <h2 variant="section">Composition rules</h2>
175
+ <ul>
176
+ <li><strong>One editing row at a time is the default</strong> — a single editable row preserves the table's scan-readability for unaffected rows. Reach for full spreadsheet only when the user's job <em>is</em> to edit most cells.</li>
177
+ <li><strong>Highlight the editing row</strong> — a subtle <code>--a-bg-subtle</code> background makes the active row obvious. Without it, users lose track of which row they're editing after scrolling.</li>
178
+ <li><strong>Save / Cancel are inline, not modal</strong> — the actions appear at the trailing edge of the row. Modal save dialogs break the table flow.</li>
179
+ <li><strong>Dirty state surfaces per row, not just per cell</strong> — a <code>tag-ui variant="warning">dirty</tag-ui></code> trailing tag tells the user which rows have unsaved changes. Per-cell highlighting is too noisy.</li>
180
+ <li><strong>Auto-save is the right default for spreadsheets</strong> — debounced 800ms after last keystroke. The "Save now" button is for users who want to force a flush before navigating away.</li>
181
+ <li><strong>Tree depth caps at 4</strong> — beyond that, indentation eats the column width and the structure stops reading. Use a search/filter (06g) or breadcrumbs to navigate deep trees.</li>
182
+ <li><strong>Tree rows render the same shape at every depth</strong> — an icon + text + optional metadata. Don't make the root row look different from leaves; the chevron + indent already encode hierarchy.</li>
183
+ <li><strong>Aggregates roll up</strong> — "Engineering — $620k" includes the children's $480 + $80 + $60. Show the total at the parent so users don't have to expand to verify.</li>
184
+ </ul>
185
+ </section>
186
+
187
+ <section data-section data-property="cross-references">
188
+ <h2 variant="section">See also</h2>
189
+ <ul>
190
+ <li><a href="/site/components/table">table-ui</a> — the canonical grid primitive (used for the spreadsheet body).</li>
191
+ <li><a href="/site/components/tree">tree-ui</a> · <a href="/site/components/tree-item">tree-item-ui</a> — hierarchy primitive.</li>
192
+ <li><a href="/site/components/input">input-ui</a> · <a href="/site/components/field">field-ui</a> — cell editor primitives.</li>
193
+ <li><a href="/site/patterns/filter-bar">filter-bar</a> — adjacent (filter the rows before drilling in).</li>
194
+ <li><a href="/site/patterns/bulk-action-toolbar">bulk-action-toolbar</a> — adjacent (apply edits to selected rows).</li>
195
+ </ul>
196
+ </section>
@@ -0,0 +1,58 @@
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>Inline-edit grids &amp; tree tables (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/field/field.css">
16
+ <link rel="stylesheet" href="../../components/input/input.css">
17
+ <link rel="stylesheet" href="../../components/list/list.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
+ <link rel="stylesheet" href="../../components/tree/tree.css">
22
+
23
+ <!-- Component JS -->
24
+ <script type="module" src="../../components/button/button.js"></script>
25
+ <script type="module" src="../../components/card/card.js"></script>
26
+ <script type="module" src="../../components/field/field.js"></script>
27
+ <script type="module" src="../../components/input/input.js"></script>
28
+ <script type="module" src="../../components/list/list.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
+ <script type="module" src="../../components/tree/tree.js"></script>
33
+
34
+ <style>
35
+ :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); }
36
+ main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
37
+ </style>
38
+ </head>
39
+ <body>
40
+
41
+ <main id="demo-root">
42
+ <p>Loading examples…</p>
43
+ </main>
44
+
45
+ <script type="module">
46
+ const root = document.getElementById('demo-root');
47
+ try {
48
+ const res = await fetch('./data-tables-inline-edit-and-tree.examples.html');
49
+ if (!res.ok) throw new Error(`fetch failed (${res.status})`);
50
+ root.innerHTML = await res.text();
51
+ } catch (err) {
52
+ root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load data-tables-inline-edit-and-tree.examples.html — ${err.message}</p>`;
53
+ console.error('[data-tables-inline-edit-and-tree.html]', err);
54
+ }
55
+ </script>
56
+
57
+ </body>
58
+ </html>
@@ -0,0 +1,147 @@
1
+ <header>
2
+ <div>
3
+ <h1>Diff &amp; Review</h1>
4
+ <div data-actions>
5
+ <tag-ui size="sm">code-ui</tag-ui> <tag-ui size="sm">card-ui</tag-ui> <tag-ui size="sm">text-ui</tag-ui> <tag-ui size="sm">tag-ui</tag-ui>
6
+ </div>
7
+ </div>
8
+ <p>The before/after viewer that surfaces every change. Three shapes: code diff (side-by-side or inline), prose diff (rendered text with markup), and structured diff (field-level deltas on a record).</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
+ Anywhere the user needs to see what changed before approving,
15
+ merging, or rolling back. Code review surfaces, content
16
+ publishing flows, settings change-history, audit detail views.
17
+ The right shape depends on the data: line-oriented text →
18
+ code diff; paragraph-flow prose → prose diff; tabular fields →
19
+ structured diff.
20
+ </p>
21
+ </section>
22
+
23
+ <section data-section data-property="side-by-side">
24
+ <h2 variant="section">Code diff — side by side</h2>
25
+ <p data-note>Two-column view with the old version on the left and the new on the right. Removed lines tinted danger; added lines tinted success. Compose two <code>code-ui line-numbers</code> blocks side-by-side; per-line tint comes from a <code>data-line-states</code> CSV (one entry per line: <code>unchanged</code>, <code>added</code>, or <code>removed</code>).</p>
26
+ <div data-artifact-container>
27
+ <div data-artifact-item data-artifact-label="side-by-side diff">
28
+ <card-ui data-chunk="diff-side-by-side">
29
+ <header>
30
+ <span slot="heading" variant="section">tokens.css</span>
31
+ <text-ui slot="description" color="subtle">+3 −2 · 5 lines changed</text-ui>
32
+ <row-ui slot="action" gap="2">
33
+ <button-ui text="Inline" variant="ghost" size="sm"></button-ui>
34
+ <button-ui text="Side-by-side" variant="primary" size="sm"></button-ui>
35
+ </row-ui>
36
+ </header>
37
+ <section bleed>
38
+ <grid-ui columns="2" gap="0" style="grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); border-block-start: 1px solid var(--md-sys-color-neutral-outline-variant);">
39
+ <code-ui language="css" line-numbers bare data-line-states="unchanged,removed,unchanged,removed,unchanged" style="min-width: 0; border-inline-end: 1px solid var(--md-sys-color-neutral-outline-variant);">
40
+ :root {
41
+ --a-primary-bg: oklch(64% 0.15 245);
42
+ --a-primary-fg: oklch(98% 0.01 245);
43
+ --a-primary-border: oklch(60% 0.12 245);
44
+ }
45
+ </code-ui>
46
+ <code-ui language="css" line-numbers bare data-line-states="unchanged,added,unchanged,added,added,unchanged" style="min-width: 0;">
47
+ :root {
48
+ --a-primary-bg: oklch(64% 0.18 245);
49
+ --a-primary-fg: oklch(98% 0.01 245);
50
+ --a-primary-border: oklch(60% 0.15 245);
51
+ --a-primary-hover: oklch(58% 0.18 245);
52
+ }
53
+ </code-ui>
54
+ </grid-ui>
55
+ </section>
56
+ </card-ui>
57
+ </div>
58
+ </div>
59
+ </section>
60
+
61
+ <section data-section data-property="inline">
62
+ <h2 variant="section">Code diff — inline (unified)</h2>
63
+ <p data-note>Single-column view with `+` and `−` line markers. Better for narrow columns and quick scan-reading. Compose <code>code-ui language="diff" line-numbers</code>; the `+`/`−`/space prefix on each line auto-resolves to <code>added</code> / <code>removed</code> / <code>unchanged</code> tint.</p>
64
+ <div data-artifact-container>
65
+ <div data-artifact-item data-artifact-label="inline unified diff">
66
+ <card-ui data-chunk="diff-inline" style="max-width: 640px;">
67
+ <header>
68
+ <span slot="heading" variant="section">tokens.css — inline diff</span>
69
+ <text-ui slot="description" color="subtle">+3 −2</text-ui>
70
+ </header>
71
+ <section bleed>
72
+ <code-ui language="diff" line-numbers bare>
73
+ :root {
74
+ - --a-primary-bg: oklch(64% 0.15 245);
75
+ + --a-primary-bg: oklch(64% 0.18 245);
76
+ --a-primary-fg: oklch(98% 0.01 245);
77
+ - --a-primary-border: oklch(60% 0.12 245);
78
+ + --a-primary-border: oklch(60% 0.15 245);
79
+ + --a-primary-hover: oklch(58% 0.18 245);
80
+ }
81
+ </code-ui>
82
+ </section>
83
+ </card-ui>
84
+ </div>
85
+ </div>
86
+ </section>
87
+
88
+ <section data-section data-property="structured">
89
+ <h2 variant="section">Structured diff — field-level</h2>
90
+ <p data-note>For settings or records where the underlying shape is a key-value object, not lines of text. Each row shows the field name + old → new value pair. <code>description-list-ui</code> for layout; <code>tag-ui</code> with diff variants for the value pair.</p>
91
+ <div data-artifact-container>
92
+ <div data-artifact-item data-artifact-label="structured field diff">
93
+ <card-ui data-chunk="diff-structured" style="max-width: 640px;">
94
+ <header>
95
+ <span slot="heading" variant="section">Workspace settings — change preview</span>
96
+ <text-ui slot="description" color="subtle">3 fields changed</text-ui>
97
+ </header>
98
+ <section>
99
+ <description-list-ui>
100
+ <description-term-ui>Workspace name</description-term-ui>
101
+ <description-detail-ui>
102
+ <row-ui gap="2" align="center">
103
+ <tag-ui size="sm" variant="danger" icon-leading="minus">Adia</tag-ui>
104
+ <tag-ui size="sm" variant="success" icon-leading="plus">Adia AI</tag-ui>
105
+ </row-ui>
106
+ </description-detail-ui>
107
+ <description-term-ui>Default theme</description-term-ui>
108
+ <description-detail-ui>
109
+ <row-ui gap="2" align="center">
110
+ <tag-ui size="sm" variant="danger" icon-leading="minus">light</tag-ui>
111
+ <tag-ui size="sm" variant="success" icon-leading="plus">auto</tag-ui>
112
+ </row-ui>
113
+ </description-detail-ui>
114
+ <description-term-ui>Member invites</description-term-ui>
115
+ <description-detail-ui>
116
+ <row-ui gap="2" align="center">
117
+ <tag-ui size="sm" variant="danger" icon-leading="minus">Admin only</tag-ui>
118
+ <tag-ui size="sm" variant="success" icon-leading="plus">Anyone with link</tag-ui>
119
+ </row-ui>
120
+ </description-detail-ui>
121
+ </description-list-ui>
122
+ </section>
123
+ </card-ui>
124
+ </div>
125
+ </div>
126
+ </section>
127
+
128
+ <section data-section data-property="composition">
129
+ <h2 variant="section">Composition rules</h2>
130
+ <ul>
131
+ <li><strong>Color is the primary signal, not the only one</strong> — green/red tints carry the diff but icons and the `+`/`−` markers must work without color too. Color-blind users still need to read the diff.</li>
132
+ <li><strong>Side-by-side for review, inline for scan</strong> — side-by-side maps to "I'm comparing two versions", inline to "I'm reading the change". Offer both as a header toggle on review surfaces.</li>
133
+ <li><strong>Show context lines, not just the changes</strong> — a 5-line hunk with 3 changes is unreviewable without context; show ±3 unchanged lines around each change.</li>
134
+ <li><strong>Structured diff is for shaped data, not for code</strong> — if the field has a long string body, fall back to the line diff for that field. Don't tag-render multi-paragraph values.</li>
135
+ <li><strong>Counts in the header</strong> — "+3 −2" or "3 fields changed" lets the user calibrate before they start reading. Bare diffs feel arbitrarily long.</li>
136
+ </ul>
137
+ </section>
138
+
139
+ <section data-section data-property="cross-references">
140
+ <h2 variant="section">See also</h2>
141
+ <ul>
142
+ <li><a href="/site/components/code">code-ui</a> — line-number gutter + language hint primitive.</li>
143
+ <li><a href="/site/components/description-list">description-list-ui</a> — structured diff layout.</li>
144
+ <li><a href="/site/patterns/approvals">approvals</a> — host pattern (review surfaces use diff for the body).</li>
145
+ <li><a href="/site/components/richtext">richtext-ui</a> — for prose-diff (body of a Notion/Google-Docs-style edit).</li>
146
+ </ul>
147
+ </section>