@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.
- package/CHANGELOG.md +5 -0
- package/dist/theme-provider.min.js +1 -1
- package/dist/web-components.min.js +1 -1
- package/package.json +2 -1
- package/patterns/access-requests/access-requests.examples.html +132 -0
- package/patterns/access-requests/access-requests.html +60 -0
- package/patterns/admin-keys-and-export/admin-keys-and-export.examples.html +236 -0
- package/patterns/admin-keys-and-export/admin-keys-and-export.html +64 -0
- package/patterns/admin-shell/admin-shell.examples.html +327 -0
- package/patterns/admin-shell/admin-shell.html +44 -0
- package/patterns/agent-cost/agent-cost.examples.html +111 -0
- package/patterns/agent-cost/agent-cost.html +62 -0
- package/patterns/agent-memory/agent-memory.examples.html +155 -0
- package/patterns/agent-memory/agent-memory.html +64 -0
- package/patterns/agent-prompt-library/agent-prompt-library.examples.html +181 -0
- package/patterns/agent-prompt-library/agent-prompt-library.html +64 -0
- package/patterns/agent-tool-call/agent-tool-call.examples.html +123 -0
- package/patterns/agent-tool-call/agent-tool-call.html +60 -0
- package/patterns/alert-dialog/alert-dialog.examples.html +105 -0
- package/patterns/alert-dialog/alert-dialog.html +57 -0
- package/patterns/app-nav/app-nav.examples.html +421 -0
- package/patterns/app-nav/app-nav.html +50 -0
- package/patterns/approvals/approvals.examples.html +131 -0
- package/patterns/approvals/approvals.html +58 -0
- package/patterns/audit-log/audit-log.examples.html +74 -0
- package/patterns/audit-log/audit-log.examples.js +60 -0
- package/patterns/audit-log/audit-log.html +63 -0
- package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.html +89 -0
- package/patterns/bulk-action-toolbar/bulk-action-toolbar.examples.js +69 -0
- package/patterns/bulk-action-toolbar/bulk-action-toolbar.html +62 -0
- package/patterns/changelog-feed/changelog-feed.examples.html +151 -0
- package/patterns/changelog-feed/changelog-feed.html +57 -0
- package/patterns/chart-in-card/chart-in-card.examples.html +193 -0
- package/patterns/chart-in-card/chart-in-card.examples.js +46 -0
- package/patterns/chart-in-card/chart-in-card.html +66 -0
- package/patterns/chat-shell/chat-shell.examples.html +129 -0
- package/patterns/chat-shell/chat-shell.html +46 -0
- package/patterns/comments-and-collaboration/comments-and-collaboration.examples.html +241 -0
- package/patterns/comments-and-collaboration/comments-and-collaboration.html +66 -0
- package/patterns/component-tokens/component-tokens.examples.html +483 -0
- package/patterns/component-tokens/component-tokens.html +42 -0
- package/patterns/conversion-funnel/conversion-funnel.examples.html +158 -0
- package/patterns/conversion-funnel/conversion-funnel.examples.js +4 -0
- package/patterns/conversion-funnel/conversion-funnel.html +64 -0
- package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.examples.html +196 -0
- package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.html +58 -0
- package/patterns/diff-review/diff-review.examples.html +147 -0
- package/patterns/diff-review/diff-review.html +56 -0
- package/patterns/editor-shell/editor-shell.examples.html +139 -0
- package/patterns/editor-shell/editor-shell.html +62 -0
- package/patterns/export-flow/export-flow.examples.html +152 -0
- package/patterns/export-flow/export-flow.examples.js +37 -0
- package/patterns/export-flow/export-flow.html +65 -0
- package/patterns/filter-bar/filter-bar.examples.html +116 -0
- package/patterns/filter-bar/filter-bar.examples.js +23 -0
- package/patterns/filter-bar/filter-bar.html +70 -0
- package/patterns/form-drawer/form-drawer.examples.html +210 -0
- package/patterns/form-drawer/form-drawer.html +64 -0
- package/patterns/form-system/form-system.examples.html +383 -0
- package/patterns/form-system/form-system.html +48 -0
- package/patterns/forms-conditional-and-autocomplete/forms-conditional-and-autocomplete.examples.html +189 -0
- package/patterns/forms-conditional-and-autocomplete/forms-conditional-and-autocomplete.html +64 -0
- package/patterns/inline-dialog/inline-dialog.examples.html +143 -0
- package/patterns/inline-dialog/inline-dialog.html +59 -0
- package/patterns/kanban-board/kanban-board.examples.html +224 -0
- package/patterns/kanban-board/kanban-board.html +58 -0
- package/patterns/layout/layout.examples.html +365 -0
- package/patterns/layout/layout.html +54 -0
- package/patterns/marketing-engagement/marketing-engagement.examples.html +280 -0
- package/patterns/marketing-engagement/marketing-engagement.html +64 -0
- package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.examples.html +213 -0
- package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.html +58 -0
- package/patterns/overview/overview.examples.html +119 -0
- package/patterns/overview/overview.html +42 -0
- package/patterns/permissions-matrix/permissions-matrix.examples.html +91 -0
- package/patterns/permissions-matrix/permissions-matrix.examples.js +28 -0
- package/patterns/permissions-matrix/permissions-matrix.html +56 -0
- package/patterns/permissions-role-picker/permissions-role-picker.examples.html +81 -0
- package/patterns/permissions-role-picker/permissions-role-picker.html +56 -0
- package/patterns/permissions-sharing/permissions-sharing.examples.html +175 -0
- package/patterns/permissions-sharing/permissions-sharing.html +66 -0
- package/patterns/profile-public-and-verification/profile-public-and-verification.examples.html +227 -0
- package/patterns/profile-public-and-verification/profile-public-and-verification.html +70 -0
- package/patterns/record-detail-drawer/record-detail-drawer.examples.html +164 -0
- package/patterns/record-detail-drawer/record-detail-drawer.html +64 -0
- package/patterns/responsive-shell-sidebar/README.md +37 -0
- package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.css +39 -0
- package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.examples.html +208 -0
- package/patterns/responsive-shell-sidebar/responsive-shell-sidebar.html +47 -0
- package/patterns/retention-cohort/retention-cohort.examples.html +149 -0
- package/patterns/retention-cohort/retention-cohort.examples.js +37 -0
- package/patterns/retention-cohort/retention-cohort.html +62 -0
- package/patterns/search-discovery/search-discovery.examples.html +263 -0
- package/patterns/search-discovery/search-discovery.html +58 -0
- package/patterns/system-banners/system-banners.examples.html +150 -0
- package/patterns/system-banners/system-banners.html +52 -0
- package/patterns/timezone-selector/timezone-selector.examples.html +82 -0
- package/patterns/timezone-selector/timezone-selector.examples.js +72 -0
- package/patterns/timezone-selector/timezone-selector.html +57 -0
- package/patterns/wizard-drawer/wizard-drawer.examples.html +144 -0
- package/patterns/wizard-drawer/wizard-drawer.examples.js +33 -0
- package/patterns/wizard-drawer/wizard-drawer.html +72 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<div>
|
|
3
|
+
<h1>Patterns</h1>
|
|
4
|
+
</div>
|
|
5
|
+
<p>Reusable compositions that solve common UI problems — from app shells to data tables, permissions grids, and AI agent surfaces.</p>
|
|
6
|
+
</header>
|
|
7
|
+
|
|
8
|
+
<section data-section data-property="what-are-patterns">
|
|
9
|
+
<h2 variant="section">What are patterns</h2>
|
|
10
|
+
<p data-note>Patterns are two things simultaneously: <strong>shell elements</strong> (web components that coordinate multiple child regions) and <strong>composition recipes</strong> (documented HTML structures that show how to assemble primitives for a specific problem).</p>
|
|
11
|
+
<p>Shell elements (<code>admin-shell</code>, <code>chat-shell</code>, <code>editor-shell</code>) stamp no markup — they orchestrate behaviors CSS alone cannot: resize observers, keyboard routing, panel toggling, state sync. You author the HTML; the pattern wires the JavaScript. Composition recipes are documented in the /site/patterns/ pages and serve as copy-paste starting points.</p>
|
|
12
|
+
</section>
|
|
13
|
+
|
|
14
|
+
<section data-section data-property="decision-matrix">
|
|
15
|
+
<h2 variant="section">Decision matrix</h2>
|
|
16
|
+
<p data-note>Start here. Find your intent, go straight to the pattern.</p>
|
|
17
|
+
<table>
|
|
18
|
+
<thead><tr><th>I need to build…</th><th>Pattern</th></tr></thead>
|
|
19
|
+
<tbody>
|
|
20
|
+
<tr><td colspan="2" style="background:var(--a-canvas-1);font-weight:600;font-size:var(--a-ui-sm);color:var(--a-fg-muted);letter-spacing:.04em;text-transform:uppercase;">App Shells</td></tr>
|
|
21
|
+
<tr><td>A full admin SaaS app (sidebar + topbar + content + statusbar)</td><td><a href="/site/patterns/admin-shell">admin-shell</a></td></tr>
|
|
22
|
+
<tr><td>A chat interface with history, input, and streaming responses</td><td><a href="/site/patterns/chat-shell">chat-shell</a></td></tr>
|
|
23
|
+
<tr><td>A design-tool shell (canvas + navigator + inspector panes)</td><td><a href="/site/patterns/editor-shell">editor-shell</a></td></tr>
|
|
24
|
+
<tr><td>A sidebar that collapses to a drawer at narrow viewports</td><td><a href="/site/patterns/responsive-shell-sidebar">responsive-shell-sidebar</a></td></tr>
|
|
25
|
+
<tr><td>App navigation: sidebar rail, grouped nav, sub-nav, collapsible</td><td><a href="/site/patterns/app-nav">app-nav</a></td></tr>
|
|
26
|
+
|
|
27
|
+
<tr><td colspan="2" style="background:var(--a-canvas-1);font-weight:600;font-size:var(--a-ui-sm);color:var(--a-fg-muted);letter-spacing:.04em;text-transform:uppercase;">Data & Tables</td></tr>
|
|
28
|
+
<tr><td>A data table with inline editing and tree/expand rows</td><td><a href="/site/patterns/data-tables-inline-edit-and-tree">data-tables-inline-edit-and-tree</a></td></tr>
|
|
29
|
+
<tr><td>A kanban board with draggable cards and column swim lanes</td><td><a href="/site/patterns/kanban-board">kanban-board</a></td></tr>
|
|
30
|
+
<tr><td>Bulk actions toolbar for selected rows (delete, export, move)</td><td><a href="/site/patterns/bulk-action-toolbar">bulk-action-toolbar</a></td></tr>
|
|
31
|
+
<tr><td>A filter bar above a list or table (multi-facet, chips, clear-all)</td><td><a href="/site/patterns/filter-bar">filter-bar</a></td></tr>
|
|
32
|
+
<tr><td>Search with result previews, categories, recent, and suggestions</td><td><a href="/site/patterns/search-discovery">search-discovery</a></td></tr>
|
|
33
|
+
<tr><td>A chart embedded inside a card (KPI, sparkline, summary)</td><td><a href="/site/patterns/chart-in-card">chart-in-card</a></td></tr>
|
|
34
|
+
<tr><td>A conversion funnel visualization</td><td><a href="/site/patterns/conversion-funnel">conversion-funnel</a></td></tr>
|
|
35
|
+
<tr><td>A retention / cohort heatmap</td><td><a href="/site/patterns/retention-cohort">retention-cohort</a></td></tr>
|
|
36
|
+
|
|
37
|
+
<tr><td colspan="2" style="background:var(--a-canvas-1);font-weight:600;font-size:var(--a-ui-sm);color:var(--a-fg-muted);letter-spacing:.04em;text-transform:uppercase;">Forms & Wizards</td></tr>
|
|
38
|
+
<tr><td>A form layout (field groups, sections, submit/cancel footer)</td><td><a href="/site/patterns/form-system">form-system</a></td></tr>
|
|
39
|
+
<tr><td>A form inside a drawer (side panel form, quick-edit)</td><td><a href="/site/patterns/form-drawer">form-drawer</a></td></tr>
|
|
40
|
+
<tr><td>Conditional form fields, dependent selects, autocomplete inputs</td><td><a href="/site/patterns/forms-conditional-and-autocomplete">forms-conditional-and-autocomplete</a></td></tr>
|
|
41
|
+
<tr><td>A multi-step wizard or onboarding flow in a drawer</td><td><a href="/site/patterns/wizard-drawer">wizard-drawer</a></td></tr>
|
|
42
|
+
|
|
43
|
+
<tr><td colspan="2" style="background:var(--a-canvas-1);font-weight:600;font-size:var(--a-ui-sm);color:var(--a-fg-muted);letter-spacing:.04em;text-transform:uppercase;">Permissions & Access</td></tr>
|
|
44
|
+
<tr><td>A permissions grid (role × resource matrix)</td><td><a href="/site/patterns/permissions-matrix">permissions-matrix</a></td></tr>
|
|
45
|
+
<tr><td>A role picker (assign roles to users)</td><td><a href="/site/patterns/permissions-role-picker">permissions-role-picker</a></td></tr>
|
|
46
|
+
<tr><td>Sharing / collaborator management (invite, revoke, change level)</td><td><a href="/site/patterns/permissions-sharing">permissions-sharing</a></td></tr>
|
|
47
|
+
<tr><td>Access requests (request → review → approve / deny flow)</td><td><a href="/site/patterns/access-requests">access-requests</a></td></tr>
|
|
48
|
+
<tr><td>API key management + data export controls</td><td><a href="/site/patterns/admin-keys-and-export">admin-keys-and-export</a></td></tr>
|
|
49
|
+
|
|
50
|
+
<tr><td colspan="2" style="background:var(--a-canvas-1);font-weight:600;font-size:var(--a-ui-sm);color:var(--a-fg-muted);letter-spacing:.04em;text-transform:uppercase;">Records & Review</td></tr>
|
|
51
|
+
<tr><td>A record detail view in a side drawer</td><td><a href="/site/patterns/record-detail-drawer">record-detail-drawer</a></td></tr>
|
|
52
|
+
<tr><td>An approval workflow (request → reviewers → decision)</td><td><a href="/site/patterns/approvals">approvals</a></td></tr>
|
|
53
|
+
<tr><td>A diff view (code or content before/after comparison)</td><td><a href="/site/patterns/diff-review">diff-review</a></td></tr>
|
|
54
|
+
<tr><td>Comments, mentions, threaded replies, reactions</td><td><a href="/site/patterns/comments-and-collaboration">comments-and-collaboration</a></td></tr>
|
|
55
|
+
<tr><td>A public profile page with verification badges</td><td><a href="/site/patterns/profile-public-and-verification">profile-public-and-verification</a></td></tr>
|
|
56
|
+
|
|
57
|
+
<tr><td colspan="2" style="background:var(--a-canvas-1);font-weight:600;font-size:var(--a-ui-sm);color:var(--a-fg-muted);letter-spacing:.04em;text-transform:uppercase;">AI & Agent Surfaces</td></tr>
|
|
58
|
+
<tr><td>Display LLM token usage and cost per request</td><td><a href="/site/patterns/agent-cost">agent-cost</a></td></tr>
|
|
59
|
+
<tr><td>Show the agent's memory / context window state</td><td><a href="/site/patterns/agent-memory">agent-memory</a></td></tr>
|
|
60
|
+
<tr><td>A prompt library with save, search, and insert</td><td><a href="/site/patterns/agent-prompt-library">agent-prompt-library</a></td></tr>
|
|
61
|
+
<tr><td>Display tool calls the agent made (name, args, result)</td><td><a href="/site/patterns/agent-tool-call">agent-tool-call</a></td></tr>
|
|
62
|
+
|
|
63
|
+
<tr><td colspan="2" style="background:var(--a-canvas-1);font-weight:600;font-size:var(--a-ui-sm);color:var(--a-fg-muted);letter-spacing:.04em;text-transform:uppercase;">Communication & Notifications</td></tr>
|
|
64
|
+
<tr><td>Notification bell with badge + dropdown digest</td><td><a href="/site/patterns/notifications-bell-and-digest">notifications-bell-and-digest</a></td></tr>
|
|
65
|
+
<tr><td>System-wide banners (announcements, maintenance, warnings)</td><td><a href="/site/patterns/system-banners">system-banners</a></td></tr>
|
|
66
|
+
|
|
67
|
+
<tr><td colspan="2" style="background:var(--a-canvas-1);font-weight:600;font-size:var(--a-ui-sm);color:var(--a-fg-muted);letter-spacing:.04em;text-transform:uppercase;">Marketing & Public</td></tr>
|
|
68
|
+
<tr><td>Marketing sections (hero, pricing, CTA, testimonials)</td><td><a href="/site/patterns/marketing-engagement">marketing-engagement</a></td></tr>
|
|
69
|
+
</tbody>
|
|
70
|
+
</table>
|
|
71
|
+
</section>
|
|
72
|
+
|
|
73
|
+
<section data-section data-property="pattern-vs-component">
|
|
74
|
+
<h2 variant="section">Pattern vs Component</h2>
|
|
75
|
+
<table>
|
|
76
|
+
<thead><tr><th></th><th>Component</th><th>Pattern</th></tr></thead>
|
|
77
|
+
<tbody>
|
|
78
|
+
<tr><td>Renders UI</td><td>Yes — light DOM, <code>@scope</code>-isolated CSS, slots</td><td>Shell elements orchestrate author-supplied HTML; composition recipes are documented starting points</td></tr>
|
|
79
|
+
<tr><td>Scope</td><td>Single element</td><td>Coordinates multiple elements via slots and <code>data-*</code> roles</td></tr>
|
|
80
|
+
<tr><td>Examples</td><td><code>button-ui</code>, <code>card-ui</code>, <code>modal-ui</code></td><td><code>admin-shell</code>, <code>kanban-board</code> recipe, <code>permissions-matrix</code> recipe</td></tr>
|
|
81
|
+
<tr><td>Customization</td><td>Attributes, slots, CSS custom properties</td><td>HTML structure, <code>data-*</code> region markers, slot vocabulary</td></tr>
|
|
82
|
+
</tbody>
|
|
83
|
+
</table>
|
|
84
|
+
</section>
|
|
85
|
+
|
|
86
|
+
<section data-section data-property="usage">
|
|
87
|
+
<h2 variant="section">Using a shell pattern</h2>
|
|
88
|
+
<p data-note>Shell elements stamp no HTML — you author the structure; the element wires the behavior.</p>
|
|
89
|
+
<code-ui language="html"><admin-shell mode="rounded">
|
|
90
|
+
<admin-sidebar slot="leading" resizable collapsible>
|
|
91
|
+
<admin-topbar slot="header">
|
|
92
|
+
<span slot="heading">My App</span>
|
|
93
|
+
</admin-topbar>
|
|
94
|
+
<section-ui>
|
|
95
|
+
<nav-ui>
|
|
96
|
+
<nav-item-ui icon="house" text="Dashboard" selected></nav-item-ui>
|
|
97
|
+
<nav-item-ui icon="gear" text="Settings"></nav-item-ui>
|
|
98
|
+
</nav-ui>
|
|
99
|
+
</section-ui>
|
|
100
|
+
</admin-sidebar>
|
|
101
|
+
|
|
102
|
+
<admin-content>
|
|
103
|
+
<admin-topbar>
|
|
104
|
+
<button-ui data-sidebar-toggle="leading" icon="sidebar" variant="ghost" size="sm"></button-ui>
|
|
105
|
+
<breadcrumb-ui><span>Dashboard</span></breadcrumb-ui>
|
|
106
|
+
</admin-topbar>
|
|
107
|
+
<admin-scroll>
|
|
108
|
+
<admin-page>
|
|
109
|
+
<admin-page-header>
|
|
110
|
+
<header><div><h1>Dashboard</h1></div></header>
|
|
111
|
+
</admin-page-header>
|
|
112
|
+
<admin-page-body>
|
|
113
|
+
<section><!-- page content --></section>
|
|
114
|
+
</admin-page-body>
|
|
115
|
+
</admin-page>
|
|
116
|
+
</admin-scroll>
|
|
117
|
+
</admin-content>
|
|
118
|
+
</admin-shell></code-ui>
|
|
119
|
+
</section>
|
|
@@ -0,0 +1,42 @@
|
|
|
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>Patterns (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/code/code.css">
|
|
14
|
+
|
|
15
|
+
<!-- Component JS -->
|
|
16
|
+
<script type="module" src="../../components/code/code.js"></script>
|
|
17
|
+
|
|
18
|
+
<style>
|
|
19
|
+
: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); }
|
|
20
|
+
main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
|
|
25
|
+
<main id="demo-root">
|
|
26
|
+
<p>Loading examples…</p>
|
|
27
|
+
</main>
|
|
28
|
+
|
|
29
|
+
<script type="module">
|
|
30
|
+
const root = document.getElementById('demo-root');
|
|
31
|
+
try {
|
|
32
|
+
const res = await fetch('./overview.examples.html');
|
|
33
|
+
if (!res.ok) throw new Error(`fetch failed (${res.status})`);
|
|
34
|
+
root.innerHTML = await res.text();
|
|
35
|
+
} catch (err) {
|
|
36
|
+
root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load overview.examples.html — ${err.message}</p>`;
|
|
37
|
+
console.error('[overview.html]', err);
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<div>
|
|
3
|
+
<h1>Permission Matrix</h1>
|
|
4
|
+
<div data-actions>
|
|
5
|
+
<tag-ui size="sm">card-ui</tag-ui> <tag-ui size="sm">table-ui</tag-ui> <tag-ui size="sm">check-ui</tag-ui> <tag-ui size="sm">description-list-ui</tag-ui> <tag-ui size="sm">tag-ui</tag-ui>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
<p>The full RBAC grid — capabilities (rows) × roles (columns), check-mark cells indicating which role grants which capability. Two shapes: an editable grid for custom roles (admin authoring), and a read-only summary card showing one role's permissions in plain language.</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
|
+
Reach for the matrix when the role count exceeds the rich-picker
|
|
15
|
+
sweet spot (~5) or when permissions are configurable. For built-in
|
|
16
|
+
roles only, the summary view is enough — the matrix is the
|
|
17
|
+
authoring surface, the summary is the runtime surface.
|
|
18
|
+
</p>
|
|
19
|
+
</section>
|
|
20
|
+
|
|
21
|
+
<section data-section data-property="grid">
|
|
22
|
+
<h2 variant="section">Editable matrix</h2>
|
|
23
|
+
<p data-note>Capability per row, role per column, <code>check-ui</code> in each cell. Built-in roles (Viewer / Member / Admin / Owner) render <code>disabled</code> — they reflect the role's permissions but can't be edited from this surface. The <em>Custom</em> column is the authoring affordance: cells there toggle freely and save on change.</p>
|
|
24
|
+
<div data-artifact-container>
|
|
25
|
+
<div data-artifact-item data-artifact-label="permission matrix grid">
|
|
26
|
+
<card-ui data-chunk="permissions-matrix-grid" data-perm-card>
|
|
27
|
+
<header>
|
|
28
|
+
<span slot="heading" variant="section">Permissions</span>
|
|
29
|
+
<text-ui slot="description" color="subtle">Changes save automatically</text-ui>
|
|
30
|
+
<button-ui slot="action" text="Add custom role" variant="ghost" size="sm" icon-leading="plus"></button-ui>
|
|
31
|
+
</header>
|
|
32
|
+
<section bleed>
|
|
33
|
+
<table-ui id="pat-perm-matrix"></table-ui>
|
|
34
|
+
</section>
|
|
35
|
+
<footer divider>
|
|
36
|
+
<text-ui slot="description" color="subtle" size="sm">Built-in roles are read-only. The Custom column is editable.</text-ui>
|
|
37
|
+
</footer>
|
|
38
|
+
</card-ui>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</section>
|
|
42
|
+
|
|
43
|
+
<section data-section data-property="summary">
|
|
44
|
+
<h2 variant="section">Read-only role summary</h2>
|
|
45
|
+
<p data-note>One card per role; <code>description-list-ui</code> with capability category as term, list of capabilities as description. Inline tag indicates whether the role is built-in or custom.</p>
|
|
46
|
+
<div data-artifact-container>
|
|
47
|
+
<div data-artifact-item data-artifact-label="role summary card">
|
|
48
|
+
<card-ui data-chunk="permissions-matrix-summary" data-perm-summary>
|
|
49
|
+
<header>
|
|
50
|
+
<span slot="heading" variant="section">Admin</span>
|
|
51
|
+
<text-ui slot="description" color="subtle">Built-in role · 3 members</text-ui>
|
|
52
|
+
<tag-ui slot="action" variant="accent" size="sm">Built-in</tag-ui>
|
|
53
|
+
</header>
|
|
54
|
+
<section>
|
|
55
|
+
<description-list-ui>
|
|
56
|
+
<span slot="term">Content</span>
|
|
57
|
+
<span slot="description">Read · Comment · Edit own</span>
|
|
58
|
+
<span slot="term">Members</span>
|
|
59
|
+
<span slot="description">Manage members (invite, change role, remove)</span>
|
|
60
|
+
<span slot="term">Workspace</span>
|
|
61
|
+
<span slot="description">All settings except deletion (Owner only)</span>
|
|
62
|
+
</description-list-ui>
|
|
63
|
+
</section>
|
|
64
|
+
<footer divider>
|
|
65
|
+
<button-ui slot="action" text="View matrix" variant="ghost" size="sm" icon-trailing="arrow-right"></button-ui>
|
|
66
|
+
</footer>
|
|
67
|
+
</card-ui>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</section>
|
|
71
|
+
|
|
72
|
+
<section data-section data-property="composition">
|
|
73
|
+
<h2 variant="section">Composition rules</h2>
|
|
74
|
+
<ul>
|
|
75
|
+
<li><strong>Group capabilities by resource</strong>, not alphabetically — "Members: invite / remove / change role" reads cleaner than three rows scattered.</li>
|
|
76
|
+
<li><strong>Built-in role columns are <code>disabled</code></strong> — their cells reflect each role's permissions but can't be edited from the matrix. Owner is always fully checked; the others vary.</li>
|
|
77
|
+
<li><strong>The Custom column is the editable surface</strong> — that's where the matrix earns its keep over a role-picker. New custom roles append a column to the right.</li>
|
|
78
|
+
<li><strong>Auto-save, don't queue</strong> — checkboxes are atomic decisions; a "Save" button at the bottom invites batching errors.</li>
|
|
79
|
+
<li><strong>Use the summary view in tooltips</strong> — when a user hovers a role tag in a members table, surface the summary card via popover; don't make them click through to settings.</li>
|
|
80
|
+
</ul>
|
|
81
|
+
</section>
|
|
82
|
+
|
|
83
|
+
<section data-section data-property="cross-references">
|
|
84
|
+
<h2 variant="section">See also</h2>
|
|
85
|
+
<ul>
|
|
86
|
+
<li><a href="/site/components/table">table-ui</a> — grid primitive used for the matrix.</li>
|
|
87
|
+
<li><a href="/site/components/check">check-ui</a> — cell primitive (auto-rendered by <code>type: 'boolean'</code> columns).</li>
|
|
88
|
+
<li><a href="/site/components/description-list">description-list-ui</a> — summary card layout.</li>
|
|
89
|
+
<li><a href="/site/patterns/permissions-role-picker">permissions-role-picker</a> — sibling for role assignment.</li>
|
|
90
|
+
</ul>
|
|
91
|
+
</section>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Permissions Matrix pattern — capability rows × role columns. */
|
|
2
|
+
|
|
3
|
+
const renderEditable = (v) =>
|
|
4
|
+
`<check-ui ${v ? 'checked' : ''}></check-ui>`;
|
|
5
|
+
|
|
6
|
+
const columns = [
|
|
7
|
+
{ key: 'capability', label: 'Capability', width: 220 },
|
|
8
|
+
{ key: 'viewer', label: 'Viewer', type: 'boolean', width: 90 },
|
|
9
|
+
{ key: 'member', label: 'Member', type: 'boolean', width: 90 },
|
|
10
|
+
{ key: 'admin', label: 'Admin', type: 'boolean', width: 90 },
|
|
11
|
+
{ key: 'owner', label: 'Owner', type: 'boolean', width: 90 },
|
|
12
|
+
{ key: 'custom', label: 'Custom', align: 'center', width: 90, render: renderEditable },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const data = [
|
|
16
|
+
{ capability: 'Read content', viewer: true, member: true, admin: true, owner: true, custom: true },
|
|
17
|
+
{ capability: 'Comment on content', viewer: false, member: true, admin: true, owner: true, custom: true },
|
|
18
|
+
{ capability: 'Edit own content', viewer: false, member: true, admin: true, owner: true, custom: false },
|
|
19
|
+
{ capability: 'Manage members', viewer: false, member: false, admin: true, owner: true, custom: false },
|
|
20
|
+
{ capability: 'Delete workspace', viewer: false, member: false, admin: false, owner: true, custom: false },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export default function setup(router) {
|
|
24
|
+
const table = router.querySelector('#pat-perm-matrix');
|
|
25
|
+
if (!table) return;
|
|
26
|
+
table.columns = columns;
|
|
27
|
+
table.data = data;
|
|
28
|
+
}
|
|
@@ -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>Permission Matrix (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/description-list/description-list.css">
|
|
16
|
+
<link rel="stylesheet" href="../../components/table/table.css">
|
|
17
|
+
<link rel="stylesheet" href="../../components/tag/tag.css">
|
|
18
|
+
<link rel="stylesheet" href="../../components/text/text.css">
|
|
19
|
+
|
|
20
|
+
<!-- Component JS -->
|
|
21
|
+
<script type="module" src="../../components/button/button.js"></script>
|
|
22
|
+
<script type="module" src="../../components/card/card.js"></script>
|
|
23
|
+
<script type="module" src="../../components/description-list/description-list.js"></script>
|
|
24
|
+
<script type="module" src="../../components/table/table.js"></script>
|
|
25
|
+
<script type="module" src="../../components/tag/tag.js"></script>
|
|
26
|
+
<script type="module" src="../../components/text/text.js"></script>
|
|
27
|
+
|
|
28
|
+
<style>
|
|
29
|
+
: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); }
|
|
30
|
+
main { max-width: 960px; margin-inline: auto; padding: var(--a-space-6) var(--a-space-5); }
|
|
31
|
+
</style>
|
|
32
|
+
</head>
|
|
33
|
+
<body>
|
|
34
|
+
|
|
35
|
+
<main id="demo-root">
|
|
36
|
+
<p>Loading examples…</p>
|
|
37
|
+
</main>
|
|
38
|
+
|
|
39
|
+
<script type="module">
|
|
40
|
+
const root = document.getElementById('demo-root');
|
|
41
|
+
try {
|
|
42
|
+
const res = await fetch('./permissions-matrix.examples.html');
|
|
43
|
+
if (!res.ok) throw new Error(`fetch failed (${res.status})`);
|
|
44
|
+
root.innerHTML = await res.text();
|
|
45
|
+
try {
|
|
46
|
+
const mod = await import(/* @vite-ignore */ './permissions-matrix.examples.js');
|
|
47
|
+
mod.default?.(root);
|
|
48
|
+
} catch (e) { console.error('[permissions-matrix.html] setup failed:', e); }
|
|
49
|
+
} catch (err) {
|
|
50
|
+
root.innerHTML = `<p style="color:var(--a-danger-strong);">Failed to load permissions-matrix.examples.html — ${err.message}</p>`;
|
|
51
|
+
console.error('[permissions-matrix.html]', err);
|
|
52
|
+
}
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<div>
|
|
3
|
+
<h1>Permissions Role Picker</h1>
|
|
4
|
+
<div data-actions>
|
|
5
|
+
<tag-ui size="sm">option-card-ui</tag-ui> <tag-ui size="sm">radio-ui</tag-ui> <tag-ui size="sm">select-ui</tag-ui> <tag-ui size="sm">field-ui</tag-ui>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
<p>Surface for assigning a role — at invite time, when promoting an existing member, or when editing a row in a members table. Two shapes: a rich radio group with role descriptions (settings-page or invite flow), and a compact select for inline edits inside a member row.</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 the rich radio group when the user is making a deliberate
|
|
15
|
+
role decision — invite, promotion, role change inside a drawer.
|
|
16
|
+
Use the compact select when the role is a column inside a table
|
|
17
|
+
and the user is sweeping through many rows. Both pull from the
|
|
18
|
+
same role list, but the surfaces have different rhythms.
|
|
19
|
+
</p>
|
|
20
|
+
</section>
|
|
21
|
+
|
|
22
|
+
<section data-section data-property="radio">
|
|
23
|
+
<h2 variant="section">Rich radio group</h2>
|
|
24
|
+
<p data-note>Each role gets an <code>option-card-ui</code> with name, one-line description, and (optionally) a "recommended" badge. Default selection lands on the lowest-privilege role — promote-by-decision, not by accident.</p>
|
|
25
|
+
<div data-artifact-container>
|
|
26
|
+
<div data-artifact-item data-artifact-label="rich role picker">
|
|
27
|
+
<field-ui data-chunk="permissions-role-picker-radio" label="Role" hint="Members can be promoted to admin later by any owner.">
|
|
28
|
+
<col-ui gap="2">
|
|
29
|
+
<option-card-ui name="role" value="viewer" heading="Viewer" description="Can read everything; cannot edit, comment, or share."></option-card-ui>
|
|
30
|
+
<option-card-ui name="role" value="member" heading="Member" description="Can edit content they own and comment on anything." checked></option-card-ui>
|
|
31
|
+
<option-card-ui name="role" value="admin" description="Can manage members, billing, and integrations.">
|
|
32
|
+
<span slot="heading">Admin <tag-ui size="sm">Recommended for leads</tag-ui></span>
|
|
33
|
+
</option-card-ui>
|
|
34
|
+
<option-card-ui name="role" value="owner" heading="Owner" description="Admin powers plus the ability to delete the workspace."></option-card-ui>
|
|
35
|
+
</col-ui>
|
|
36
|
+
</field-ui>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</section>
|
|
40
|
+
|
|
41
|
+
<section data-section data-property="select">
|
|
42
|
+
<h2 variant="section">Compact select (table inline)</h2>
|
|
43
|
+
<p data-note>Used inside a members table. The select replaces the static role tag on row-hover, or stays inline when the table is in edit mode. Falls back to a non-interactive <code>tag-ui</code> when the current user can't change roles.</p>
|
|
44
|
+
<div data-artifact-container>
|
|
45
|
+
<div data-artifact-item data-artifact-label="role select inline">
|
|
46
|
+
<row-ui data-chunk="permissions-role-picker-select" gap="3" align="center" padding="2" style="max-width: 480px;">
|
|
47
|
+
<avatar-ui size="sm" text="Kim Granlund"></avatar-ui>
|
|
48
|
+
<col-ui gap="0" grow>
|
|
49
|
+
<text-ui strong>Kim Granlund</text-ui>
|
|
50
|
+
<text-ui color="subtle" size="sm">kim@example.com</text-ui>
|
|
51
|
+
</col-ui>
|
|
52
|
+
<select-ui value="admin" size="sm" style="min-width: 140px;">
|
|
53
|
+
<option value="viewer">Viewer</option>
|
|
54
|
+
<option value="member">Member</option>
|
|
55
|
+
<option value="admin" selected>Admin</option>
|
|
56
|
+
<option value="owner">Owner</option>
|
|
57
|
+
</select-ui>
|
|
58
|
+
</row-ui>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</section>
|
|
62
|
+
|
|
63
|
+
<section data-section data-property="composition">
|
|
64
|
+
<h2 variant="section">Composition rules</h2>
|
|
65
|
+
<ul>
|
|
66
|
+
<li><strong>Default to the lowest privilege</strong> — Viewer (or Member if there's no Viewer in your model). Make promotion an explicit click, not an oversight.</li>
|
|
67
|
+
<li><strong>Description is mandatory</strong> in the rich variant — users hovering between Member and Admin should see exactly what changes.</li>
|
|
68
|
+
<li><strong>Don't mix scope into role names</strong> — "Workspace Admin" vs "Project Admin" are scope distinctions; either pick scope first then role, or use a dedicated permission matrix (36b).</li>
|
|
69
|
+
<li><strong>The role list is short</strong> — 3–5 roles. Beyond that, the user can't hold the mental model and you should reach for custom roles (04d).</li>
|
|
70
|
+
</ul>
|
|
71
|
+
</section>
|
|
72
|
+
|
|
73
|
+
<section data-section data-property="cross-references">
|
|
74
|
+
<h2 variant="section">See also</h2>
|
|
75
|
+
<ul>
|
|
76
|
+
<li><a href="/site/components/option-card">option-card-ui</a> — rich-radio surface.</li>
|
|
77
|
+
<li><a href="/site/components/select">select-ui</a> — compact select.</li>
|
|
78
|
+
<li><a href="/site/components/field">field-ui</a> — wrapper with label / hint / error.</li>
|
|
79
|
+
<li><a href="/site/patterns/form-drawer">form-drawer</a> — host for invite flows.</li>
|
|
80
|
+
</ul>
|
|
81
|
+
</section>
|
|
@@ -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>Permissions Role Picker (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/avatar/avatar.css">
|
|
14
|
+
<link rel="stylesheet" href="../../components/col/col.css">
|
|
15
|
+
<link rel="stylesheet" href="../../components/field/field.css">
|
|
16
|
+
<link rel="stylesheet" href="../../components/option-card/option-card.css">
|
|
17
|
+
<link rel="stylesheet" href="../../components/row/row.css">
|
|
18
|
+
<link rel="stylesheet" href="../../components/select/select.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/avatar/avatar.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/option-card/option-card.js"></script>
|
|
27
|
+
<script type="module" src="../../components/row/row.js"></script>
|
|
28
|
+
<script type="module" src="../../components/select/select.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('./permissions-role-picker.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 permissions-role-picker.examples.html — ${err.message}</p>`;
|
|
51
|
+
console.error('[permissions-role-picker.html]', err);
|
|
52
|
+
}
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|