@adia-ai/web-modules 0.3.3 → 0.3.5
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 +60 -0
- package/chat/chat-composer/chat-composer.a2ui.json +94 -0
- package/chat/chat-composer/chat-composer.examples.html +28 -0
- package/chat/chat-composer/chat-composer.html +43 -0
- package/chat/chat-composer/chat-composer.js +107 -0
- package/chat/chat-composer/chat-composer.test.js +112 -0
- package/chat/chat-composer/chat-composer.yaml +91 -0
- package/chat/chat-empty/chat-empty.a2ui.json +68 -0
- package/chat/chat-empty/chat-empty.examples.html +34 -0
- package/chat/chat-empty/chat-empty.html +42 -0
- package/chat/chat-empty/chat-empty.yaml +58 -0
- package/chat/chat-header/chat-header.a2ui.json +77 -0
- package/chat/chat-header/chat-header.examples.html +30 -0
- package/chat/chat-header/chat-header.html +42 -0
- package/chat/chat-header/chat-header.yaml +68 -0
- package/chat/chat-shell/chat-shell.css +1 -0
- package/chat/chat-shell/chat-shell.examples.html +126 -0
- package/chat/chat-shell/chat-shell.html +42 -0
- package/chat/chat-shell/chat-shell.js +35 -7
- package/chat/chat-shell/css/chat-shell.bespoke.css +196 -0
- package/chat/chat-sidebar/chat-sidebar.a2ui.json +136 -0
- package/chat/chat-sidebar/chat-sidebar.examples.html +36 -0
- package/chat/chat-sidebar/chat-sidebar.html +43 -0
- package/chat/chat-sidebar/chat-sidebar.js +227 -0
- package/chat/chat-sidebar/chat-sidebar.test.js +110 -0
- package/chat/chat-sidebar/chat-sidebar.yaml +140 -0
- package/chat/chat-status/chat-status.a2ui.json +63 -0
- package/chat/chat-status/chat-status.examples.html +29 -0
- package/chat/chat-status/chat-status.html +42 -0
- package/chat/chat-status/chat-status.yaml +52 -0
- package/chat/chat-thread/chat-thread.a2ui.json +91 -0
- package/chat/chat-thread/chat-thread.examples.html +36 -0
- package/chat/chat-thread/chat-thread.html +43 -0
- package/chat/chat-thread/chat-thread.js +106 -0
- package/chat/chat-thread/chat-thread.test.js +82 -0
- package/chat/chat-thread/chat-thread.yaml +89 -0
- package/chat/index.js +3 -0
- package/editor/editor-shell/editor-shell.examples.html +71 -0
- package/editor/editor-shell/editor-shell.html +42 -0
- package/package.json +1 -1
- package/shell/admin-command/admin-command.a2ui.json +102 -0
- package/shell/admin-command/admin-command.examples.html +83 -0
- package/shell/admin-command/admin-command.html +42 -0
- package/shell/admin-command/admin-command.js +161 -0
- package/shell/admin-command/admin-command.test.js +115 -0
- package/shell/admin-command/admin-command.yaml +102 -0
- package/shell/admin-content/admin-content.a2ui.json +73 -0
- package/shell/admin-content/admin-content.examples.html +33 -0
- package/shell/admin-content/admin-content.html +42 -0
- package/shell/admin-content/admin-content.yaml +63 -0
- package/shell/admin-page/admin-page.a2ui.json +74 -0
- package/shell/admin-page/admin-page.examples.html +37 -0
- package/shell/admin-page/admin-page.html +42 -0
- package/shell/admin-page/admin-page.yaml +61 -0
- package/shell/admin-page-body/admin-page-body.a2ui.json +62 -0
- package/shell/admin-page-body/admin-page-body.examples.html +34 -0
- package/shell/admin-page-body/admin-page-body.html +42 -0
- package/shell/admin-page-body/admin-page-body.yaml +49 -0
- package/shell/admin-page-header/admin-page-header.a2ui.json +62 -0
- package/shell/admin-page-header/admin-page-header.examples.html +34 -0
- package/shell/admin-page-header/admin-page-header.html +42 -0
- package/shell/admin-page-header/admin-page-header.yaml +47 -0
- package/shell/admin-scroll/admin-scroll.a2ui.json +62 -0
- package/shell/admin-scroll/admin-scroll.examples.html +31 -0
- package/shell/admin-scroll/admin-scroll.html +42 -0
- package/shell/admin-scroll/admin-scroll.yaml +51 -0
- package/shell/admin-shell/admin-shell.a2ui.json +0 -10
- package/shell/admin-shell/admin-shell.css +1 -0
- package/shell/admin-shell/admin-shell.examples.html +61 -5
- package/shell/admin-shell/admin-shell.js +165 -121
- package/shell/admin-shell/admin-shell.yaml +6 -6
- package/shell/admin-shell/css/admin-shell.bespoke.css +198 -0
- package/shell/admin-shell/css/admin-shell.tokens.css +10 -0
- package/shell/admin-sidebar/admin-sidebar.a2ui.json +138 -0
- package/shell/admin-sidebar/admin-sidebar.examples.html +76 -0
- package/shell/admin-sidebar/admin-sidebar.html +47 -0
- package/shell/admin-sidebar/admin-sidebar.js +227 -0
- package/shell/admin-sidebar/admin-sidebar.test.js +123 -0
- package/shell/admin-sidebar/admin-sidebar.yaml +140 -0
- package/shell/admin-statusbar/admin-statusbar.a2ui.json +81 -0
- package/shell/admin-statusbar/admin-statusbar.examples.html +29 -0
- package/shell/admin-statusbar/admin-statusbar.html +42 -0
- package/shell/admin-statusbar/admin-statusbar.yaml +68 -0
- package/shell/admin-topbar/admin-topbar.a2ui.json +83 -0
- package/shell/admin-topbar/admin-topbar.examples.html +31 -0
- package/shell/admin-topbar/admin-topbar.html +42 -0
- package/shell/admin-topbar/admin-topbar.yaml +75 -0
- package/shell/index.js +2 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <admin-command shortcut="cmd+k|ctrl+k|both">
|
|
3
|
+
* <command-ui placeholder="Search…"></command-ui>
|
|
4
|
+
* </admin-command>
|
|
5
|
+
*
|
|
6
|
+
* Module-tier command palette — wraps a native <dialog> and the inner
|
|
7
|
+
* <command-ui>. Owns the keyboard shortcut listener, focus management,
|
|
8
|
+
* and dismiss handlers. Reflects [open].
|
|
9
|
+
*
|
|
10
|
+
* Reflected attributes:
|
|
11
|
+
* [open] — set while the dialog is showing
|
|
12
|
+
*
|
|
13
|
+
* Author-supplied attributes:
|
|
14
|
+
* [shortcut="cmd+k"|"ctrl+k"|"both"]
|
|
15
|
+
* — keyboard shortcut. Default "both"
|
|
16
|
+
* (responds to Cmd+K on Mac and Ctrl+K
|
|
17
|
+
* on other platforms).
|
|
18
|
+
* [no-shortcut] — opts out of the keyboard listener
|
|
19
|
+
* entirely. Use when the host wires
|
|
20
|
+
* its own shortcut handling.
|
|
21
|
+
*
|
|
22
|
+
* Public methods:
|
|
23
|
+
* .show() — open the palette (via showModal)
|
|
24
|
+
* .hide() — close
|
|
25
|
+
* .toggle() — flip open state
|
|
26
|
+
*
|
|
27
|
+
* Events forwarded from inner <command-ui>:
|
|
28
|
+
* command-select — bubbles. detail: { value, ... }
|
|
29
|
+
*
|
|
30
|
+
* Authors composing into <admin-shell> just drop this in as a child;
|
|
31
|
+
* the host does NOT reach inside. <admin-shell> wires
|
|
32
|
+
* [data-command-trigger] elements to this.show() via a lookup.
|
|
33
|
+
*
|
|
34
|
+
* Backwards compat: <admin-shell> still recognizes the legacy
|
|
35
|
+
* <dialog data-command> shape and wires the same shortcut. New code
|
|
36
|
+
* should prefer <admin-command>.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import { UIElement } from '../../../web-components/core/element.js';
|
|
40
|
+
|
|
41
|
+
class AdminCommand extends UIElement {
|
|
42
|
+
static properties = {
|
|
43
|
+
open: { type: Boolean, default: false, reflect: true },
|
|
44
|
+
shortcut: { type: String, default: 'both', reflect: true },
|
|
45
|
+
noShortcut: { type: Boolean, default: false, reflect: true, attribute: 'no-shortcut' },
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
static template = () => null;
|
|
49
|
+
|
|
50
|
+
#keyHandler = null;
|
|
51
|
+
#cmdEl = null;
|
|
52
|
+
#dialog = null;
|
|
53
|
+
|
|
54
|
+
connected() {
|
|
55
|
+
// Find or construct the dialog. If author supplies <dialog>, use it.
|
|
56
|
+
// Otherwise, wrap the slotted content in a fresh <dialog>.
|
|
57
|
+
this.#dialog = this.querySelector(':scope > dialog');
|
|
58
|
+
if (!this.#dialog) {
|
|
59
|
+
this.#dialog = document.createElement('dialog');
|
|
60
|
+
// Move all children into the dialog
|
|
61
|
+
while (this.firstChild) this.#dialog.appendChild(this.firstChild);
|
|
62
|
+
this.appendChild(this.#dialog);
|
|
63
|
+
}
|
|
64
|
+
this.#cmdEl = this.querySelector('command-ui');
|
|
65
|
+
|
|
66
|
+
this.#wireDialog();
|
|
67
|
+
this.#wireCommand();
|
|
68
|
+
if (!this.noShortcut) this.#wireShortcut();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
disconnected() {
|
|
72
|
+
if (this.#keyHandler) {
|
|
73
|
+
document.removeEventListener('keydown', this.#keyHandler);
|
|
74
|
+
this.#keyHandler = null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ── Public API ──
|
|
79
|
+
|
|
80
|
+
show() {
|
|
81
|
+
if (!this.#dialog) return;
|
|
82
|
+
if (this.#dialog.open) return;
|
|
83
|
+
this.#dialog.showModal();
|
|
84
|
+
if (this.#cmdEl) {
|
|
85
|
+
this.#cmdEl.open = true;
|
|
86
|
+
this.#cmdEl.value = '';
|
|
87
|
+
this.#cmdEl.focus();
|
|
88
|
+
}
|
|
89
|
+
this.open = true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
hide() {
|
|
93
|
+
if (!this.#dialog) return;
|
|
94
|
+
if (!this.#dialog.open) return;
|
|
95
|
+
this.#dialog.close();
|
|
96
|
+
if (this.#cmdEl) this.#cmdEl.open = false;
|
|
97
|
+
this.open = false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
toggle() {
|
|
101
|
+
if (this.open) {
|
|
102
|
+
this.hide();
|
|
103
|
+
} else {
|
|
104
|
+
this.show();
|
|
105
|
+
}
|
|
106
|
+
return this.open;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ── Wiring ──
|
|
110
|
+
|
|
111
|
+
#wireDialog() {
|
|
112
|
+
if (!this.#dialog) return;
|
|
113
|
+
|
|
114
|
+
// Backdrop click closes
|
|
115
|
+
this.#dialog.addEventListener('click', (e) => {
|
|
116
|
+
if (e.target === this.#dialog) this.hide();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Native dialog close (esc key, etc.) syncs [open]
|
|
120
|
+
this.#dialog.addEventListener('close', () => {
|
|
121
|
+
if (this.#cmdEl) this.#cmdEl.open = false;
|
|
122
|
+
this.open = false;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
#wireCommand() {
|
|
127
|
+
if (!this.#cmdEl) return;
|
|
128
|
+
|
|
129
|
+
this.#cmdEl.addEventListener('dismiss', () => this.hide());
|
|
130
|
+
this.#cmdEl.addEventListener('select', (e) => {
|
|
131
|
+
// Forward as command-select; let consumers decide what to do
|
|
132
|
+
this.dispatchEvent(new CustomEvent('command-select', {
|
|
133
|
+
bubbles: true,
|
|
134
|
+
detail: e.detail,
|
|
135
|
+
}));
|
|
136
|
+
this.hide();
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#wireShortcut() {
|
|
141
|
+
const matches = (e) => {
|
|
142
|
+
const isMac = e.metaKey;
|
|
143
|
+
const isCtrl = e.ctrlKey;
|
|
144
|
+
if (e.key !== 'k') return false;
|
|
145
|
+
if (this.shortcut === 'cmd+k') return isMac;
|
|
146
|
+
if (this.shortcut === 'ctrl+k') return isCtrl;
|
|
147
|
+
// 'both' (default)
|
|
148
|
+
return isMac || isCtrl;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
this.#keyHandler = (e) => {
|
|
152
|
+
if (!matches(e)) return;
|
|
153
|
+
e.preventDefault();
|
|
154
|
+
this.toggle();
|
|
155
|
+
};
|
|
156
|
+
document.addEventListener('keydown', this.#keyHandler);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
customElements.define('admin-command', AdminCommand);
|
|
161
|
+
export { AdminCommand };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
+
import '../../../web-components/core/element.js';
|
|
3
|
+
import './admin-command.js';
|
|
4
|
+
|
|
5
|
+
const tick = () => new Promise((r) => queueMicrotask(r));
|
|
6
|
+
|
|
7
|
+
function mount(html) {
|
|
8
|
+
const wrap = document.createElement('div');
|
|
9
|
+
wrap.innerHTML = html;
|
|
10
|
+
document.body.appendChild(wrap);
|
|
11
|
+
return wrap.firstElementChild;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// happy-dom's <dialog> support is partial — showModal/close need to be
|
|
15
|
+
// patched into noops that toggle the .open getter via a flag. The real
|
|
16
|
+
// browser does this natively.
|
|
17
|
+
function patchDialogPolyfill(dialog) {
|
|
18
|
+
let isOpen = false;
|
|
19
|
+
Object.defineProperty(dialog, 'open', {
|
|
20
|
+
get: () => isOpen,
|
|
21
|
+
set: (v) => { isOpen = !!v; },
|
|
22
|
+
configurable: true,
|
|
23
|
+
});
|
|
24
|
+
dialog.showModal = function () {
|
|
25
|
+
isOpen = true;
|
|
26
|
+
this.dispatchEvent(new Event('toggle'));
|
|
27
|
+
};
|
|
28
|
+
dialog.close = function () {
|
|
29
|
+
isOpen = false;
|
|
30
|
+
this.dispatchEvent(new Event('close'));
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
document.body.innerHTML = '';
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('admin-command', () => {
|
|
39
|
+
it('registers admin-command as a custom element', () => {
|
|
40
|
+
expect(customElements.get('admin-command')).toBeDefined();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('defaults to open=false, shortcut="both"', () => {
|
|
44
|
+
const cmd = mount('<admin-command></admin-command>');
|
|
45
|
+
expect(cmd.open).toBe(false);
|
|
46
|
+
expect(cmd.shortcut).toBe('both');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('exposes .show() / .hide() / .toggle() public methods', () => {
|
|
50
|
+
const cmd = mount('<admin-command></admin-command>');
|
|
51
|
+
expect(typeof cmd.show).toBe('function');
|
|
52
|
+
expect(typeof cmd.hide).toBe('function');
|
|
53
|
+
expect(typeof cmd.toggle).toBe('function');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('reflects [open] when .show() is called', async () => {
|
|
57
|
+
const cmd = mount('<admin-command></admin-command>');
|
|
58
|
+
const dialog = cmd.shadowRoot?.querySelector('dialog') ?? cmd.querySelector('dialog');
|
|
59
|
+
if (dialog) patchDialogPolyfill(dialog);
|
|
60
|
+
cmd.show();
|
|
61
|
+
await tick();
|
|
62
|
+
expect(cmd.open).toBe(true);
|
|
63
|
+
expect(cmd.hasAttribute('open')).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('clears [open] when .hide() is called', async () => {
|
|
67
|
+
const cmd = mount('<admin-command></admin-command>');
|
|
68
|
+
const dialog = cmd.shadowRoot?.querySelector('dialog') ?? cmd.querySelector('dialog');
|
|
69
|
+
if (dialog) patchDialogPolyfill(dialog);
|
|
70
|
+
cmd.show();
|
|
71
|
+
await tick();
|
|
72
|
+
cmd.hide();
|
|
73
|
+
await tick();
|
|
74
|
+
expect(cmd.open).toBe(false);
|
|
75
|
+
expect(cmd.hasAttribute('open')).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('toggle() flips open state and returns the new value', async () => {
|
|
79
|
+
const cmd = mount('<admin-command></admin-command>');
|
|
80
|
+
const dialog = cmd.shadowRoot?.querySelector('dialog') ?? cmd.querySelector('dialog');
|
|
81
|
+
if (dialog) patchDialogPolyfill(dialog);
|
|
82
|
+
const after1 = cmd.toggle();
|
|
83
|
+
await tick();
|
|
84
|
+
expect(after1).toBe(true);
|
|
85
|
+
const after2 = cmd.toggle();
|
|
86
|
+
await tick();
|
|
87
|
+
expect(after2).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('removes Cmd+K listener on disconnect', () => {
|
|
91
|
+
const cmd = mount('<admin-command></admin-command>');
|
|
92
|
+
const removeSpy = vi.spyOn(document, 'removeEventListener');
|
|
93
|
+
cmd.remove();
|
|
94
|
+
const removedTypes = removeSpy.mock.calls.map((args) => args[0]);
|
|
95
|
+
expect(removedTypes).toContain('keydown');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('honors [no-shortcut] — does not toggle on Cmd+K', async () => {
|
|
99
|
+
// Verify behavior, not listener registration (happy-dom timing makes
|
|
100
|
+
// spy-based tests unreliable for synchronous custom-element lifecycle).
|
|
101
|
+
const cmd = mount('<admin-command no-shortcut></admin-command>');
|
|
102
|
+
const dialog = cmd.querySelector(':scope > dialog');
|
|
103
|
+
if (dialog) patchDialogPolyfill(dialog);
|
|
104
|
+
const event = new KeyboardEvent('keydown', { key: 'k', metaKey: true });
|
|
105
|
+
document.dispatchEvent(event);
|
|
106
|
+
await tick();
|
|
107
|
+
expect(cmd.open).toBe(false);
|
|
108
|
+
cmd.remove();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('accepts shortcut="cmd+k"', () => {
|
|
112
|
+
const cmd = mount('<admin-command shortcut="cmd+k"></admin-command>');
|
|
113
|
+
expect(cmd.shortcut).toBe('cmd+k');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Edit this file; run `npm run build:components` to regenerate a2ui.json.
|
|
2
|
+
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
3
|
+
name: AdminCommand
|
|
4
|
+
tag: admin-command
|
|
5
|
+
component: AdminCommand
|
|
6
|
+
category: interaction
|
|
7
|
+
version: 1
|
|
8
|
+
description: |
|
|
9
|
+
Module-tier command palette wrapper — wraps a native <dialog> and the
|
|
10
|
+
inner <command-ui>. Owns the keyboard shortcut listener, focus
|
|
11
|
+
management, and dismiss handlers. Reflects [open].
|
|
12
|
+
|
|
13
|
+
Sits inside <admin-shell> as a direct child. The host wires
|
|
14
|
+
[data-command-trigger] elements to <admin-command>.show() via lookup.
|
|
15
|
+
|
|
16
|
+
This is the bespoke web-component replacement for the legacy
|
|
17
|
+
<dialog data-command> shape. <admin-shell> still recognizes the
|
|
18
|
+
legacy shape via :is() selector. New code should prefer <admin-command>.
|
|
19
|
+
|
|
20
|
+
props:
|
|
21
|
+
open:
|
|
22
|
+
description: |
|
|
23
|
+
Reflected — set while the dialog is showing. Synced with both
|
|
24
|
+
programmatic .show()/.hide() and native dialog close events
|
|
25
|
+
(esc key, backdrop click).
|
|
26
|
+
type: boolean
|
|
27
|
+
default: false
|
|
28
|
+
reflect: true
|
|
29
|
+
|
|
30
|
+
shortcut:
|
|
31
|
+
description: |
|
|
32
|
+
Keyboard shortcut binding. "cmd+k" responds only on Mac
|
|
33
|
+
(metaKey); "ctrl+k" responds only when ctrlKey; "both" (default)
|
|
34
|
+
responds to either, which is the canonical AdiaUI behavior for
|
|
35
|
+
cross-platform Cmd+K affordance.
|
|
36
|
+
type: string
|
|
37
|
+
default: both
|
|
38
|
+
enum:
|
|
39
|
+
- both
|
|
40
|
+
- cmd+k
|
|
41
|
+
- ctrl+k
|
|
42
|
+
reflect: true
|
|
43
|
+
|
|
44
|
+
no-shortcut:
|
|
45
|
+
description: |
|
|
46
|
+
Opts out of the keyboard listener entirely. Use when the host
|
|
47
|
+
wires its own shortcut handling, or when the palette should be
|
|
48
|
+
mouse-only.
|
|
49
|
+
type: boolean
|
|
50
|
+
default: false
|
|
51
|
+
reflect: true
|
|
52
|
+
|
|
53
|
+
events:
|
|
54
|
+
command-select:
|
|
55
|
+
description: Forwarded from the inner <command-ui> when an option
|
|
56
|
+
is chosen. Detail mirrors the inner event's detail.
|
|
57
|
+
detail:
|
|
58
|
+
value: string
|
|
59
|
+
|
|
60
|
+
slots:
|
|
61
|
+
default:
|
|
62
|
+
description: >-
|
|
63
|
+
Default slot — the inner <command-ui> (and any other content
|
|
64
|
+
inside the dialog). Authors typically place exactly one
|
|
65
|
+
<command-ui placeholder="…">.
|
|
66
|
+
|
|
67
|
+
states:
|
|
68
|
+
- name: idle
|
|
69
|
+
description: Default, palette closed.
|
|
70
|
+
- name: open
|
|
71
|
+
attribute: open
|
|
72
|
+
description: Dialog is showing; first input has focus.
|
|
73
|
+
|
|
74
|
+
traits: []
|
|
75
|
+
|
|
76
|
+
a2ui:
|
|
77
|
+
rules:
|
|
78
|
+
- >-
|
|
79
|
+
admin-command wraps a native <dialog>; the inner <command-ui>
|
|
80
|
+
is the actual palette. Keyboard shortcut defaults to both
|
|
81
|
+
Cmd+K (mac) and Ctrl+K (other) — the AdiaUI convention.
|
|
82
|
+
- >-
|
|
83
|
+
Place admin-command as a direct child of admin-shell, NOT inside
|
|
84
|
+
a sidebar or main column. The host coordinates triggers
|
|
85
|
+
([data-command-trigger]) by reaching across siblings.
|
|
86
|
+
|
|
87
|
+
keywords:
|
|
88
|
+
- admin-command
|
|
89
|
+
- command-palette
|
|
90
|
+
- palette
|
|
91
|
+
- cmd-k
|
|
92
|
+
- keyboard-shortcut
|
|
93
|
+
- quickaction
|
|
94
|
+
|
|
95
|
+
synonyms:
|
|
96
|
+
command-palette: [palette, quick-action, omnibox]
|
|
97
|
+
cmd-k: [ctrl-k, command-shortcut]
|
|
98
|
+
|
|
99
|
+
related:
|
|
100
|
+
- AdminShell
|
|
101
|
+
- AdminSidebar
|
|
102
|
+
- Command
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://adiaui.dev/a2ui/v0_9/components/AdminContent.json",
|
|
4
|
+
"title": "AdminContent",
|
|
5
|
+
"description": "Module-tier shell main-column container. CSS-only — no behavior, no\nJS. Sits inside <admin-shell> as the center column between leading\nand trailing sidebars. Authors compose chrome bars + scroll surface\nvia slot vocabulary.\n\nThis is the bespoke replacement for the legacy raw <main> element\ninside admin-shell. Both shapes still render correctly per ADR-0023\nPhase 1 backwards-compat; new code should prefer <admin-content>.\n",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"allOf": [
|
|
8
|
+
{
|
|
9
|
+
"$ref": "common_types.json#/$defs/ComponentCommon"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"$ref": "common_types.json#/$defs/CatalogComponentCommon"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"component": {
|
|
17
|
+
"const": "AdminContent"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"required": [
|
|
21
|
+
"component"
|
|
22
|
+
],
|
|
23
|
+
"unevaluatedProperties": false,
|
|
24
|
+
"x-adiaui": {
|
|
25
|
+
"anti_patterns": [],
|
|
26
|
+
"category": "layout",
|
|
27
|
+
"events": {},
|
|
28
|
+
"examples": [],
|
|
29
|
+
"keywords": [
|
|
30
|
+
"admin-content",
|
|
31
|
+
"main",
|
|
32
|
+
"center-column",
|
|
33
|
+
"workspace"
|
|
34
|
+
],
|
|
35
|
+
"name": "AdminContent",
|
|
36
|
+
"related": [
|
|
37
|
+
"AdminShell",
|
|
38
|
+
"AdminSidebar",
|
|
39
|
+
"AdminTopbar",
|
|
40
|
+
"AdminStatusbar",
|
|
41
|
+
"AdminScroll",
|
|
42
|
+
"AdminPage"
|
|
43
|
+
],
|
|
44
|
+
"slots": {
|
|
45
|
+
"default": {
|
|
46
|
+
"description": "Default content — typically <admin-topbar slot=\"header\">, an <admin-scroll> wrapping content, and an optional <admin-statusbar slot=\"footer\">."
|
|
47
|
+
},
|
|
48
|
+
"footer": {
|
|
49
|
+
"description": "Bottom chrome bar — typically <admin-statusbar>."
|
|
50
|
+
},
|
|
51
|
+
"header": {
|
|
52
|
+
"description": "Top chrome bar — typically <admin-topbar>."
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"states": [
|
|
56
|
+
{
|
|
57
|
+
"description": "Default, the only state.",
|
|
58
|
+
"name": "idle"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"synonyms": {
|
|
62
|
+
"main": [
|
|
63
|
+
"content",
|
|
64
|
+
"center",
|
|
65
|
+
"workspace"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"tag": "admin-content",
|
|
69
|
+
"tokens": {},
|
|
70
|
+
"traits": [],
|
|
71
|
+
"version": 1
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<div>
|
|
3
|
+
<h1>Admin Content</h1>
|
|
4
|
+
<div data-actions>
|
|
5
|
+
<tag-ui size="sm">admin-content</tag-ui>
|
|
6
|
+
<tag-ui size="sm" variant="ghost">CSS-only</tag-ui>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
<p>Module-tier shell main-column container. CSS-only. Sits inside <admin-shell> as the center column between leading and trailing sidebars.</p>
|
|
10
|
+
</header>
|
|
11
|
+
|
|
12
|
+
<section data-section>
|
|
13
|
+
<h2 variant="section">Role</h2>
|
|
14
|
+
<p>This is a CSS-only structural stub — no JavaScript, no behavior. The shell host (<code><admin-shell></code>) styles it via tag-presence. Authors compose it with sibling bespoke children to express semantic shell-tier structure.</p>
|
|
15
|
+
</section>
|
|
16
|
+
|
|
17
|
+
<section data-section>
|
|
18
|
+
<h2 variant="section">Composition</h2>
|
|
19
|
+
<p>Typical placement inside <code><admin-shell></code>:</p>
|
|
20
|
+
<code-ui language="html"><admin-shell>
|
|
21
|
+
<admin-sidebar slot="leading">…</admin-sidebar>
|
|
22
|
+
<admin-content>
|
|
23
|
+
<admin-topbar slot="header">…</admin-topbar>
|
|
24
|
+
<admin-scroll>…</admin-scroll>
|
|
25
|
+
<admin-statusbar slot="footer">…</admin-statusbar>
|
|
26
|
+
</admin-content>
|
|
27
|
+
</admin-shell></code-ui>
|
|
28
|
+
</section>
|
|
29
|
+
|
|
30
|
+
<section data-section>
|
|
31
|
+
<h2 variant="section">Slot vocabulary</h2>
|
|
32
|
+
<p>See the <a href="../admin-shell/admin-shell.html"><code>admin-shell</code></a> demo for the full composition pattern. CSS-only stubs declare slot intent; the parent shell handles layout.</p>
|
|
33
|
+
</section>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="auto">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Admin Content — AdiaUI</title>
|
|
7
|
+
|
|
8
|
+
<link rel="stylesheet" href="../../../web-components/styles/resets.css">
|
|
9
|
+
<link rel="stylesheet" href="../../../web-components/styles/tokens.css">
|
|
10
|
+
<link rel="stylesheet" href="../admin-shell/admin-shell.css">
|
|
11
|
+
<link rel="stylesheet" href="../../../web-components/components/code/code.css">
|
|
12
|
+
<link rel="stylesheet" href="../../../web-components/components/tag/tag.css">
|
|
13
|
+
|
|
14
|
+
<script type="module" src="../admin-shell/admin-shell.js"></script>
|
|
15
|
+
<script type="module" src="../../../web-components/components/code/code.js"></script>
|
|
16
|
+
<script type="module" src="../../../web-components/components/tag/tag.js"></script>
|
|
17
|
+
|
|
18
|
+
<style>
|
|
19
|
+
:where(html, body) { margin: 0; min-height: 100vh; background: var(--a-bg); color: var(--a-fg); font-family: var(--a-font); }
|
|
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('./admin-content.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 admin-content.examples.html — ${err.message}</p>`;
|
|
37
|
+
console.error('[admin-content.html]', err);
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Edit this file; run `npm run build:components` to regenerate a2ui.json.
|
|
2
|
+
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
3
|
+
name: AdminContent
|
|
4
|
+
tag: admin-content
|
|
5
|
+
component: AdminContent
|
|
6
|
+
category: layout
|
|
7
|
+
version: 1
|
|
8
|
+
description: |
|
|
9
|
+
Module-tier shell main-column container. CSS-only — no behavior, no
|
|
10
|
+
JS. Sits inside <admin-shell> as the center column between leading
|
|
11
|
+
and trailing sidebars. Authors compose chrome bars + scroll surface
|
|
12
|
+
via slot vocabulary.
|
|
13
|
+
|
|
14
|
+
This is the bespoke replacement for the legacy raw <main> element
|
|
15
|
+
inside admin-shell. Both shapes still render correctly per ADR-0023
|
|
16
|
+
Phase 1 backwards-compat; new code should prefer <admin-content>.
|
|
17
|
+
|
|
18
|
+
props: {}
|
|
19
|
+
|
|
20
|
+
events: {}
|
|
21
|
+
|
|
22
|
+
slots:
|
|
23
|
+
default:
|
|
24
|
+
description: >-
|
|
25
|
+
Default content — typically <admin-topbar slot="header">, an
|
|
26
|
+
<admin-scroll> wrapping content, and an optional
|
|
27
|
+
<admin-statusbar slot="footer">.
|
|
28
|
+
header:
|
|
29
|
+
description: >-
|
|
30
|
+
Top chrome bar — typically <admin-topbar>.
|
|
31
|
+
footer:
|
|
32
|
+
description: >-
|
|
33
|
+
Bottom chrome bar — typically <admin-statusbar>.
|
|
34
|
+
|
|
35
|
+
states:
|
|
36
|
+
- name: idle
|
|
37
|
+
description: Default, the only state.
|
|
38
|
+
|
|
39
|
+
traits: []
|
|
40
|
+
|
|
41
|
+
a2ui:
|
|
42
|
+
rules:
|
|
43
|
+
- >-
|
|
44
|
+
admin-content is the bespoke replacement for raw <main> inside
|
|
45
|
+
admin-shell. CSS-only; the shell's css/main.css selectors target
|
|
46
|
+
both shapes via :is(main, admin-content).
|
|
47
|
+
|
|
48
|
+
keywords:
|
|
49
|
+
- admin-content
|
|
50
|
+
- main
|
|
51
|
+
- center-column
|
|
52
|
+
- workspace
|
|
53
|
+
|
|
54
|
+
synonyms:
|
|
55
|
+
main: [content, center, workspace]
|
|
56
|
+
|
|
57
|
+
related:
|
|
58
|
+
- AdminShell
|
|
59
|
+
- AdminSidebar
|
|
60
|
+
- AdminTopbar
|
|
61
|
+
- AdminStatusbar
|
|
62
|
+
- AdminScroll
|
|
63
|
+
- AdminPage
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://adiaui.dev/a2ui/v0_9/components/AdminPage.json",
|
|
4
|
+
"title": "AdminPage",
|
|
5
|
+
"description": "Module-tier page wrapper. CSS-only — no behavior, no JS. Provides\nthe page-content-root container query (named `page-content`) so\ndescendants can adapt to available content width (sidebars expanded\nvs collapsed) instead of viewport width. Stamps the sticky-band\nlayout: <admin-page-header> + <admin-page-body> + optional footer.\n\nReplaces the legacy <article data-content-root> shape per ADR-0023.\n",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"allOf": [
|
|
8
|
+
{
|
|
9
|
+
"$ref": "common_types.json#/$defs/ComponentCommon"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"$ref": "common_types.json#/$defs/CatalogComponentCommon"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"component": {
|
|
17
|
+
"const": "AdminPage"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"required": [
|
|
21
|
+
"component"
|
|
22
|
+
],
|
|
23
|
+
"unevaluatedProperties": false,
|
|
24
|
+
"x-adiaui": {
|
|
25
|
+
"anti_patterns": [],
|
|
26
|
+
"category": "layout",
|
|
27
|
+
"events": {},
|
|
28
|
+
"examples": [],
|
|
29
|
+
"keywords": [
|
|
30
|
+
"admin-page",
|
|
31
|
+
"page-content",
|
|
32
|
+
"container-query-host"
|
|
33
|
+
],
|
|
34
|
+
"name": "AdminPage",
|
|
35
|
+
"related": [
|
|
36
|
+
"AdminShell",
|
|
37
|
+
"AdminContent",
|
|
38
|
+
"AdminScroll",
|
|
39
|
+
"AdminPageHeader",
|
|
40
|
+
"AdminPageBody"
|
|
41
|
+
],
|
|
42
|
+
"slots": {
|
|
43
|
+
"default": {
|
|
44
|
+
"description": "Default — typically <admin-page-header> + <admin-page-body>."
|
|
45
|
+
},
|
|
46
|
+
"body": {
|
|
47
|
+
"description": "Centered reading column (alternate slot for the body band)."
|
|
48
|
+
},
|
|
49
|
+
"footer": {
|
|
50
|
+
"description": "Sticky bottom band."
|
|
51
|
+
},
|
|
52
|
+
"header": {
|
|
53
|
+
"description": "Sticky top band (alternate slot for the header band)."
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"states": [
|
|
57
|
+
{
|
|
58
|
+
"description": "Default, the only state.",
|
|
59
|
+
"name": "idle"
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"synonyms": {
|
|
63
|
+
"page-content": [
|
|
64
|
+
"content-area",
|
|
65
|
+
"content-root",
|
|
66
|
+
"document-region"
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
"tag": "admin-page",
|
|
70
|
+
"tokens": {},
|
|
71
|
+
"traits": [],
|
|
72
|
+
"version": 1
|
|
73
|
+
}
|
|
74
|
+
}
|