@adia-ai/web-components 0.0.28 → 0.0.33
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/README.md +4 -8
- package/a2ui/index.js +1 -1
- package/components/accordion/accordion.a2ui.json +1 -1
- package/components/accordion/accordion.js +6 -6
- package/components/accordion/accordion.yaml +1 -1
- package/components/action-list/action-list.a2ui.json +1 -1
- package/components/action-list/action-list.js +6 -6
- package/components/action-list/action-list.yaml +1 -1
- package/components/agent-artifact/agent-artifact.a2ui.json +1 -1
- package/components/agent-artifact/agent-artifact.js +4 -4
- package/components/agent-artifact/agent-artifact.yaml +1 -1
- package/components/agent-feedback-bar/agent-feedback-bar.a2ui.json +1 -1
- package/components/agent-feedback-bar/agent-feedback-bar.js +4 -4
- package/components/agent-feedback-bar/agent-feedback-bar.yaml +1 -1
- package/components/agent-questions/agent-questions.a2ui.json +1 -1
- package/components/agent-questions/agent-questions.js +4 -4
- package/components/agent-questions/agent-questions.yaml +1 -1
- package/components/agent-reasoning/agent-reasoning.a2ui.json +3 -3
- package/components/agent-reasoning/agent-reasoning.js +4 -4
- package/components/agent-reasoning/agent-reasoning.yaml +3 -3
- package/components/agent-suggestions/agent-suggestions.a2ui.json +1 -1
- package/components/agent-suggestions/agent-suggestions.js +4 -4
- package/components/agent-suggestions/agent-suggestions.yaml +1 -1
- package/components/agent-trace/agent-trace.a2ui.json +1 -1
- package/components/agent-trace/agent-trace.js +4 -4
- package/components/agent-trace/agent-trace.yaml +1 -1
- package/components/alert/alert.a2ui.json +1 -1
- package/components/alert/alert.js +4 -4
- package/components/alert/alert.yaml +1 -1
- package/components/aside/aside.a2ui.json +1 -1
- package/components/aside/aside.yaml +1 -1
- package/components/avatar/avatar.a2ui.json +1 -1
- package/components/avatar/avatar.js +8 -8
- package/components/avatar/avatar.yaml +1 -1
- package/components/badge/badge.a2ui.json +1 -1
- package/components/badge/badge.js +4 -4
- package/components/badge/badge.yaml +1 -1
- package/components/block/block.a2ui.json +1 -1
- package/components/block/block.js +4 -4
- package/components/block/block.yaml +1 -1
- package/components/breadcrumb/breadcrumb.a2ui.json +1 -1
- package/components/breadcrumb/breadcrumb.js +4 -4
- package/components/breadcrumb/breadcrumb.yaml +1 -1
- package/components/button/button.a2ui.json +1 -1
- package/components/button/button.js +4 -4
- package/components/button/button.yaml +1 -1
- package/components/calendar-picker/calendar-picker.a2ui.json +1 -1
- package/components/calendar-picker/calendar-picker.js +6 -6
- package/components/calendar-picker/calendar-picker.yaml +1 -1
- package/components/canvas/canvas.a2ui.json +1 -1
- package/components/canvas/canvas.js +5 -5
- package/components/canvas/canvas.yaml +1 -1
- package/components/card/card.a2ui.json +1 -1
- package/components/card/card.js +4 -4
- package/components/card/card.yaml +1 -1
- package/components/chart/chart.a2ui.json +1 -1
- package/components/chart/chart.js +5 -5
- package/components/chart/chart.yaml +1 -1
- package/components/chart-legend/chart-legend.a2ui.json +1 -1
- package/components/chart-legend/chart-legend.js +7 -7
- package/components/chart-legend/chart-legend.yaml +1 -1
- package/components/{chat → chat-thread}/chat-input.js +5 -5
- package/components/{chat/chat.a2ui.json → chat-thread/chat-thread.a2ui.json} +6 -6
- package/components/{chat/chat.css → chat-thread/chat-thread.css} +2 -2
- package/components/{chat/chat.js → chat-thread/chat-thread.js} +7 -7
- package/components/{chat/chat.yaml → chat-thread/chat-thread.yaml} +4 -4
- package/components/check/check.a2ui.json +1 -1
- package/components/check/check.js +5 -5
- package/components/check/check.yaml +1 -1
- package/components/code/code.a2ui.json +1 -1
- package/components/code/code.js +4 -4
- package/components/code/code.yaml +1 -1
- package/components/col/col.a2ui.json +1 -1
- package/components/col/col.js +4 -4
- package/components/col/col.yaml +1 -1
- package/components/color-picker/color-picker.a2ui.json +1 -1
- package/components/color-picker/color-picker.js +6 -6
- package/components/color-picker/color-picker.yaml +1 -1
- package/components/command/command.a2ui.json +1 -1
- package/components/command/command.js +5 -5
- package/components/command/command.yaml +1 -1
- package/components/description-list/description-list.a2ui.json +1 -1
- package/components/description-list/description-list.js +4 -4
- package/components/description-list/description-list.yaml +1 -1
- package/components/divider/divider.a2ui.json +1 -1
- package/components/divider/divider.js +4 -4
- package/components/divider/divider.yaml +1 -1
- package/components/drawer/drawer.a2ui.json +1 -1
- package/components/drawer/drawer.js +4 -4
- package/components/drawer/drawer.yaml +1 -1
- package/components/embed/embed.a2ui.json +1 -1
- package/components/embed/embed.js +4 -4
- package/components/embed/embed.yaml +1 -1
- package/components/empty-state/empty-state.a2ui.json +1 -1
- package/components/empty-state/empty-state.js +4 -4
- package/components/empty-state/empty-state.yaml +1 -1
- package/components/feed/feed-item.yaml +2 -2
- package/components/feed/feed.a2ui.json +2 -2
- package/components/feed/feed.css +21 -3
- package/components/feed/feed.js +140 -31
- package/components/feed/feed.yaml +2 -2
- package/components/field/field.a2ui.json +1 -1
- package/components/field/field.js +10 -10
- package/components/field/field.yaml +2 -2
- package/components/footer/footer.a2ui.json +1 -1
- package/components/footer/footer.yaml +1 -1
- package/components/grid/grid.a2ui.json +1 -1
- package/components/grid/grid.js +4 -4
- package/components/grid/grid.yaml +1 -1
- package/components/header/header.a2ui.json +1 -1
- package/components/header/header.yaml +1 -1
- package/components/heatmap/heatmap.a2ui.json +1 -1
- package/components/heatmap/heatmap.js +4 -4
- package/components/heatmap/heatmap.yaml +1 -1
- package/components/icon/icon.a2ui.json +1 -1
- package/components/icon/icon.js +4 -4
- package/components/icon/icon.yaml +1 -1
- package/components/image/image.a2ui.json +1 -1
- package/components/image/image.js +4 -4
- package/components/image/image.yaml +1 -1
- package/components/index.js +88 -85
- package/components/input/input.a2ui.json +1 -1
- package/components/input/input.js +7 -7
- package/components/input/input.yaml +1 -1
- package/components/inspector/inspector.a2ui.json +1 -1
- package/components/inspector/inspector.js +4 -4
- package/components/inspector/inspector.yaml +1 -1
- package/components/kbd/kbd.a2ui.json +1 -1
- package/components/kbd/kbd.js +4 -4
- package/components/kbd/kbd.yaml +1 -1
- package/components/list/list.a2ui.json +1 -1
- package/components/list/list.js +6 -6
- package/components/list/list.yaml +1 -1
- package/components/menu/menu.a2ui.json +1 -1
- package/components/menu/menu.js +8 -8
- package/components/menu/menu.yaml +1 -1
- package/components/modal/modal.a2ui.json +1 -1
- package/components/modal/modal.js +4 -4
- package/components/modal/modal.yaml +1 -1
- package/components/nav/nav.a2ui.json +98 -0
- package/components/nav/nav.css +133 -0
- package/components/nav/nav.js +140 -0
- package/components/nav/nav.test.js +428 -0
- package/components/nav/nav.yaml +114 -0
- package/components/nav-group/nav-group.a2ui.json +100 -0
- package/{patterns/app-nav-group/app-nav-group.css → components/nav-group/nav-group.css} +71 -18
- package/{patterns/app-nav-group/app-nav-group.js → components/nav-group/nav-group.js} +51 -25
- package/components/nav-group/nav-group.yaml +69 -0
- package/components/nav-item/nav-item.a2ui.json +106 -0
- package/{patterns/app-nav-item/app-nav-item.css → components/nav-item/nav-item.css} +42 -10
- package/components/nav-item/nav-item.js +76 -0
- package/components/nav-item/nav-item.yaml +73 -0
- package/components/noodles/noodles.a2ui.json +1 -1
- package/components/noodles/noodles.js +4 -4
- package/components/noodles/noodles.yaml +1 -1
- package/components/option-card/option-card.a2ui.json +1 -1
- package/components/option-card/option-card.js +6 -6
- package/components/option-card/option-card.yaml +1 -1
- package/components/otp-input/otp-input.a2ui.json +1 -1
- package/components/otp-input/otp-input.js +5 -5
- package/components/otp-input/otp-input.yaml +1 -1
- package/components/page/page.a2ui.json +3 -3
- package/components/page/page.js +4 -4
- package/components/page/page.yaml +3 -3
- package/components/pagination/pagination.a2ui.json +1 -1
- package/components/pagination/pagination.js +4 -4
- package/components/pagination/pagination.yaml +1 -1
- package/components/pane/pane.a2ui.json +1 -1
- package/components/pane/pane.js +4 -4
- package/components/pane/pane.yaml +1 -1
- package/components/pipeline-status/pipeline-status.a2ui.json +1 -1
- package/components/pipeline-status/pipeline-status.js +4 -4
- package/components/pipeline-status/pipeline-status.yaml +1 -1
- package/components/popover/popover.a2ui.json +1 -1
- package/components/popover/popover.js +4 -4
- package/components/popover/popover.yaml +1 -1
- package/components/progress/progress.a2ui.json +1 -1
- package/components/progress/progress.js +4 -4
- package/components/progress/progress.yaml +1 -1
- package/components/progress-row/progress-row.a2ui.json +1 -1
- package/components/progress-row/progress-row.js +4 -4
- package/components/progress-row/progress-row.yaml +1 -1
- package/components/radio/radio.a2ui.json +1 -1
- package/components/radio/radio.js +5 -5
- package/components/radio/radio.yaml +1 -1
- package/components/range/range.a2ui.json +1 -1
- package/components/range/range.js +7 -7
- package/components/range/range.yaml +1 -1
- package/components/rating/rating.a2ui.json +1 -1
- package/components/rating/rating.js +6 -6
- package/components/rating/rating.yaml +1 -1
- package/components/richtext/richtext.a2ui.json +1 -1
- package/components/richtext/richtext.js +4 -4
- package/components/richtext/richtext.yaml +1 -1
- package/components/row/row.a2ui.json +1 -1
- package/components/row/row.js +4 -4
- package/components/row/row.yaml +1 -1
- package/components/search/search.a2ui.json +1 -1
- package/components/search/search.js +5 -5
- package/components/search/search.yaml +1 -1
- package/components/section/section.a2ui.json +1 -1
- package/components/section/section.yaml +1 -1
- package/components/segment/segment.a2ui.json +1 -1
- package/components/segment/segment.js +4 -4
- package/components/segment/segment.yaml +1 -1
- package/components/segmented/segmented.a2ui.json +1 -1
- package/components/segmented/segmented.css +6 -0
- package/components/segmented/segmented.js +7 -7
- package/components/segmented/segmented.yaml +1 -1
- package/components/select/select.a2ui.json +1 -1
- package/components/select/select.js +5 -5
- package/components/select/select.yaml +1 -1
- package/components/skeleton/skeleton.a2ui.json +1 -1
- package/components/skeleton/skeleton.js +4 -4
- package/components/skeleton/skeleton.yaml +1 -1
- package/components/slider/slider.a2ui.json +1 -1
- package/components/slider/slider.js +7 -7
- package/components/slider/slider.yaml +1 -1
- package/components/stack/stack.a2ui.json +1 -1
- package/components/stack/stack.js +4 -4
- package/components/stack/stack.yaml +1 -1
- package/components/stat/stat.a2ui.json +1 -1
- package/components/stat/stat.js +4 -4
- package/components/stat/stat.yaml +1 -1
- package/components/stepper/stepper.a2ui.json +1 -1
- package/components/stepper/stepper.js +6 -6
- package/components/stepper/stepper.yaml +1 -1
- package/components/stream/stream.a2ui.json +1 -1
- package/components/stream/stream.js +4 -4
- package/components/stream/stream.yaml +1 -1
- package/components/swatch/swatch.a2ui.json +1 -1
- package/components/swatch/swatch.js +4 -4
- package/components/swatch/swatch.yaml +1 -1
- package/components/swiper/swiper.a2ui.json +1 -1
- package/components/swiper/swiper.js +4 -4
- package/components/swiper/swiper.yaml +1 -1
- package/components/switch/switch.a2ui.json +1 -1
- package/components/switch/switch.js +5 -5
- package/components/switch/switch.yaml +1 -1
- package/components/table/table.a2ui.json +1 -1
- package/components/table/table.js +4 -4
- package/components/table/table.yaml +1 -1
- package/components/table-toolbar/table-toolbar.a2ui.json +1 -1
- package/components/table-toolbar/table-toolbar.js +4 -4
- package/components/table-toolbar/table-toolbar.yaml +1 -1
- package/components/tabs/tab.js +4 -4
- package/components/tabs/tabs.a2ui.json +1 -1
- package/components/tabs/tabs.js +5 -5
- package/components/tabs/tabs.yaml +1 -1
- package/components/tag/tag.a2ui.json +1 -1
- package/components/tag/tag.js +4 -4
- package/components/tag/tag.yaml +1 -1
- package/components/text/text.a2ui.json +1 -1
- package/components/text/text.js +4 -4
- package/components/text/text.yaml +1 -1
- package/components/textarea/textarea.a2ui.json +1 -1
- package/components/textarea/textarea.js +5 -5
- package/components/textarea/textarea.yaml +1 -1
- package/components/timeline/timeline.a2ui.json +1 -1
- package/components/timeline/timeline.js +6 -6
- package/components/timeline/timeline.yaml +1 -1
- package/components/toast/toast.a2ui.json +1 -1
- package/components/toast/toast.js +54 -184
- package/components/toast/toast.yaml +1 -1
- package/components/toggle-group/toggle-group.a2ui.json +1 -1
- package/components/toggle-group/toggle-group.js +6 -6
- package/components/toggle-group/toggle-group.yaml +1 -1
- package/components/toolbar/toolbar.a2ui.json +1 -1
- package/components/toolbar/toolbar.js +6 -6
- package/components/toolbar/toolbar.yaml +1 -1
- package/components/tooltip/tooltip.a2ui.json +1 -1
- package/components/tooltip/tooltip.js +7 -7
- package/components/tooltip/tooltip.yaml +1 -1
- package/components/tree/tree.a2ui.json +1 -1
- package/components/tree/tree.js +6 -6
- package/components/tree/tree.yaml +1 -1
- package/components/upload/upload.a2ui.json +1 -1
- package/components/upload/upload.js +6 -6
- package/components/upload/upload.yaml +1 -1
- package/core/element.js +4 -4
- package/core/element.test.js +18 -18
- package/core/form.js +9 -9
- package/core/index.js +2 -2
- package/core/provider.js +7 -7
- package/core/template.js +1 -1
- package/index.css +3 -2
- package/index.js +17 -7
- package/package.json +1 -5
- package/styles/components.css +10 -6
- package/styles/resets.css +1 -1
- package/traits/define.js +2 -2
- package/patterns/a2ui-root/a2ui-root.a2ui.json +0 -125
- package/patterns/a2ui-root/a2ui-root.js +0 -191
- package/patterns/a2ui-root/a2ui-root.yaml +0 -87
- package/patterns/adia-chat/adia-chat.a2ui.json +0 -149
- package/patterns/adia-chat/adia-chat.css +0 -10
- package/patterns/adia-chat/adia-chat.js +0 -297
- package/patterns/adia-chat/adia-chat.yaml +0 -118
- package/patterns/adia-chat/css/adia-chat.empty.css +0 -12
- package/patterns/adia-chat/css/adia-chat.layout.css +0 -60
- package/patterns/adia-chat/css/adia-chat.markdown.css +0 -74
- package/patterns/adia-chat/css/adia-chat.messages.css +0 -87
- package/patterns/adia-chat/css/adia-chat.streaming.css +0 -30
- package/patterns/adia-chat/css/adia-chat.tokens.css +0 -95
- package/patterns/adia-editor/adia-editor.a2ui.json +0 -73
- package/patterns/adia-editor/adia-editor.css +0 -6
- package/patterns/adia-editor/adia-editor.js +0 -56
- package/patterns/adia-editor/adia-editor.yaml +0 -59
- package/patterns/adia-editor/css/adia-editor.layout.css +0 -171
- package/patterns/adia-editor/css/adia-editor.tokens.css +0 -28
- package/patterns/app-nav/app-nav.a2ui.json +0 -89
- package/patterns/app-nav/app-nav.css +0 -92
- package/patterns/app-nav/app-nav.js +0 -112
- package/patterns/app-nav/app-nav.yaml +0 -54
- package/patterns/app-nav-group/app-nav-group.a2ui.json +0 -82
- package/patterns/app-nav-group/app-nav-group.yaml +0 -59
- package/patterns/app-nav-item/app-nav-item.a2ui.json +0 -83
- package/patterns/app-nav-item/app-nav-item.js +0 -42
- package/patterns/app-nav-item/app-nav-item.yaml +0 -62
- package/patterns/app-shell/app-shell.a2ui.json +0 -129
- package/patterns/app-shell/app-shell.css +0 -14
- package/patterns/app-shell/app-shell.js +0 -251
- package/patterns/app-shell/app-shell.yaml +0 -89
- package/patterns/app-shell/css/app-shell.collapsed.css +0 -86
- package/patterns/app-shell/css/app-shell.helpers.css +0 -42
- package/patterns/app-shell/css/app-shell.main.css +0 -172
- package/patterns/app-shell/css/app-shell.shell.css +0 -44
- package/patterns/app-shell/css/app-shell.sidebar.css +0 -161
- package/patterns/app-shell/css/app-shell.templates.css +0 -214
- package/patterns/app-shell/css/app-shell.tokens.css +0 -119
- package/patterns/gen-ui/gen-ui.a2ui.json +0 -72
- package/patterns/gen-ui/gen-ui.css +0 -83
- package/patterns/gen-ui/gen-ui.js +0 -136
- package/patterns/gen-ui/gen-ui.yaml +0 -43
- package/patterns/index.js +0 -11
- package/patterns/section-nav/section-nav.a2ui.json +0 -91
- package/patterns/section-nav/section-nav.css +0 -60
- package/patterns/section-nav/section-nav.js +0 -42
- package/patterns/section-nav/section-nav.yaml +0 -58
- package/patterns/section-nav-group/section-nav-group.a2ui.json +0 -95
- package/patterns/section-nav-group/section-nav-group.css +0 -74
- package/patterns/section-nav-group/section-nav-group.js +0 -84
- package/patterns/section-nav-group/section-nav-group.yaml +0 -66
- package/patterns/section-nav-item/section-nav-item.a2ui.json +0 -97
- package/patterns/section-nav-item/section-nav-item.css +0 -106
- package/patterns/section-nav-item/section-nav-item.js +0 -66
- package/patterns/section-nav-item/section-nav-item.yaml +0 -70
- package/styles/layouts/admin.css +0 -7
- /package/components/{chat → chat-thread}/chat-input.css +0 -0
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* <app-shell-ui mode="rounded borderless">
|
|
3
|
-
* <aside data-sidebar="leading">...</aside>
|
|
4
|
-
* <main>...</main>
|
|
5
|
-
* <aside data-sidebar="trailing">...</aside>
|
|
6
|
-
* <dialog data-command>...</dialog>
|
|
7
|
-
* </app-shell-ui>
|
|
8
|
-
*
|
|
9
|
-
* Behavior-only app shell. Stamps no HTML — the page author writes the
|
|
10
|
-
* structure using semantic elements + data attributes. The component
|
|
11
|
-
* auto-wires four JS behaviors that CSS can't handle:
|
|
12
|
-
*
|
|
13
|
-
* 1. Sidebar resize (drag handle with snap thresholds)
|
|
14
|
-
* 2. Sidebar toggle (collapse/restore width)
|
|
15
|
-
* 3. Command palette (Cmd+K keyboard shortcut)
|
|
16
|
-
* 4. ResizeObserver (select placement in narrow sidebars)
|
|
17
|
-
*
|
|
18
|
-
* CSS handles everything else: layout, collapse, container queries,
|
|
19
|
-
* sticky headers, scroll containment, mode composition.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { AdiaElement } from '../../core/element.js';
|
|
23
|
-
|
|
24
|
-
const SNAP_THRESHOLD = 96;
|
|
25
|
-
const SNAP_MIN_USABLE = 160;
|
|
26
|
-
|
|
27
|
-
class AdiaAppShell extends AdiaElement {
|
|
28
|
-
static properties = {
|
|
29
|
-
mode: { type: String, default: '', reflect: true },
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
static template = () => null;
|
|
33
|
-
|
|
34
|
-
#sidebarWidths = new Map();
|
|
35
|
-
#resizeCleanups = [];
|
|
36
|
-
#sidebarRO = null;
|
|
37
|
-
#cmdKeyHandler = null;
|
|
38
|
-
|
|
39
|
-
connected() {
|
|
40
|
-
this.#setupToggles();
|
|
41
|
-
this.#setupResizeHandles();
|
|
42
|
-
this.#setupCommandPalette();
|
|
43
|
-
this.#setupResizeObserver();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
disconnected() {
|
|
47
|
-
// Clean up resize handles
|
|
48
|
-
for (const cleanup of this.#resizeCleanups) cleanup();
|
|
49
|
-
this.#resizeCleanups = [];
|
|
50
|
-
|
|
51
|
-
// Clean up ResizeObserver
|
|
52
|
-
this.#sidebarRO?.disconnect();
|
|
53
|
-
this.#sidebarRO = null;
|
|
54
|
-
|
|
55
|
-
// Clean up Cmd+K
|
|
56
|
-
if (this.#cmdKeyHandler) {
|
|
57
|
-
document.removeEventListener('keydown', this.#cmdKeyHandler);
|
|
58
|
-
this.#cmdKeyHandler = null;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// ── Sidebar persistence ────────────────────────────────────
|
|
63
|
-
|
|
64
|
-
#persistSidebar(sidebarName, width) {
|
|
65
|
-
try { localStorage.setItem(`adia-sidebar-${sidebarName}`, width); } catch {}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
#restoreSidebars() {
|
|
69
|
-
for (const sidebar of this.querySelectorAll('[data-sidebar]')) {
|
|
70
|
-
const name = sidebar.getAttribute('data-sidebar');
|
|
71
|
-
try {
|
|
72
|
-
const saved = localStorage.getItem(`adia-sidebar-${name}`);
|
|
73
|
-
if (saved) {
|
|
74
|
-
sidebar.style.width = saved;
|
|
75
|
-
// Only store as the "previous expanded width" if it's actually expanded.
|
|
76
|
-
// If collapsed, keep the default expanded width so toggle can restore it.
|
|
77
|
-
const w = parseFloat(saved);
|
|
78
|
-
if (isNaN(w) || w > SNAP_THRESHOLD) {
|
|
79
|
-
this.#sidebarWidths.set(name, saved);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
} catch {}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// ── 1. Sidebar toggle ──────────────────────────────────────
|
|
87
|
-
|
|
88
|
-
#setupToggles() {
|
|
89
|
-
this.#restoreSidebars();
|
|
90
|
-
|
|
91
|
-
for (const btn of this.querySelectorAll('[data-sidebar-toggle]')) {
|
|
92
|
-
const sidebarName = btn.getAttribute('data-sidebar-toggle');
|
|
93
|
-
btn.addEventListener('click', () => {
|
|
94
|
-
const sidebar = this.querySelector(`[data-sidebar="${sidebarName}"]`);
|
|
95
|
-
if (!sidebar) return;
|
|
96
|
-
|
|
97
|
-
const isCollapsed = sidebar.getBoundingClientRect().width <= SNAP_THRESHOLD;
|
|
98
|
-
|
|
99
|
-
if (isCollapsed) {
|
|
100
|
-
// Expand: restore previous width
|
|
101
|
-
const prev = this.#sidebarWidths.get(sidebarName);
|
|
102
|
-
sidebar.style.width = prev || '';
|
|
103
|
-
this.#persistSidebar(sidebarName, prev || '');
|
|
104
|
-
} else {
|
|
105
|
-
// Collapse: save current width, set to min
|
|
106
|
-
this.#sidebarWidths.set(sidebarName, sidebar.style.width || getComputedStyle(sidebar).width);
|
|
107
|
-
const minW = getComputedStyle(sidebar).minWidth;
|
|
108
|
-
sidebar.style.width = minW;
|
|
109
|
-
this.#persistSidebar(sidebarName, minW);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
this.dispatchEvent(new CustomEvent('sidebar-toggle', {
|
|
113
|
-
bubbles: true,
|
|
114
|
-
detail: { sidebar: sidebarName, expanded: !isCollapsed },
|
|
115
|
-
}));
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ── 2. Sidebar resize handles ──────────────────────────────
|
|
121
|
-
|
|
122
|
-
#setupResizeHandles() {
|
|
123
|
-
for (const handle of this.querySelectorAll('[data-sidebar] > [data-resize]')) {
|
|
124
|
-
const sidebar = handle.parentElement;
|
|
125
|
-
const sidebarName = sidebar.getAttribute('data-sidebar');
|
|
126
|
-
const isLeading = sidebarName === 'leading';
|
|
127
|
-
|
|
128
|
-
const onPointerDown = (e) => {
|
|
129
|
-
e.preventDefault();
|
|
130
|
-
handle.setPointerCapture(e.pointerId);
|
|
131
|
-
const startX = e.clientX;
|
|
132
|
-
const startW = sidebar.getBoundingClientRect().width;
|
|
133
|
-
sidebar.setAttribute('data-resizing', '');
|
|
134
|
-
document.documentElement.style.cursor = 'col-resize';
|
|
135
|
-
|
|
136
|
-
const onMove = (e) => {
|
|
137
|
-
const dx = e.clientX - startX;
|
|
138
|
-
const max = parseInt(getComputedStyle(sidebar).getPropertyValue('max-width')) || 480;
|
|
139
|
-
const w = Math.max(48, Math.min(max, startW + (isLeading ? dx : -dx)));
|
|
140
|
-
sidebar.style.width = `${w}px`;
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const onUp = () => {
|
|
144
|
-
sidebar.removeAttribute('data-resizing');
|
|
145
|
-
document.documentElement.style.cursor = '';
|
|
146
|
-
handle.removeEventListener('pointermove', onMove);
|
|
147
|
-
handle.removeEventListener('pointerup', onUp);
|
|
148
|
-
|
|
149
|
-
// Snap logic
|
|
150
|
-
const w = sidebar.getBoundingClientRect().width;
|
|
151
|
-
if (w <= SNAP_THRESHOLD) {
|
|
152
|
-
sidebar.style.width = getComputedStyle(sidebar).minWidth;
|
|
153
|
-
} else if (w < SNAP_MIN_USABLE) {
|
|
154
|
-
sidebar.style.width = `${SNAP_MIN_USABLE}px`;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
this.#persistSidebar(sidebarName, sidebar.style.width);
|
|
158
|
-
this.dispatchEvent(new CustomEvent('sidebar-resize', {
|
|
159
|
-
bubbles: true,
|
|
160
|
-
detail: { sidebar: sidebarName, width: sidebar.getBoundingClientRect().width },
|
|
161
|
-
}));
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
handle.addEventListener('pointermove', onMove);
|
|
165
|
-
handle.addEventListener('pointerup', onUp);
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
handle.addEventListener('pointerdown', onPointerDown);
|
|
169
|
-
this.#resizeCleanups.push(() => handle.removeEventListener('pointerdown', onPointerDown));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// ── 3. Command palette ─────────────────────────────────────
|
|
174
|
-
|
|
175
|
-
#setupCommandPalette() {
|
|
176
|
-
const dialog = this.querySelector('dialog[data-command]');
|
|
177
|
-
if (!dialog) return;
|
|
178
|
-
|
|
179
|
-
const cmdEl = dialog.querySelector('command-ui');
|
|
180
|
-
const nav = this.querySelector('app-nav-ui');
|
|
181
|
-
|
|
182
|
-
const openCmd = () => {
|
|
183
|
-
dialog.showModal();
|
|
184
|
-
if (cmdEl) { cmdEl.open = true; cmdEl.value = ''; cmdEl.focus(); }
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
const closeCmd = () => {
|
|
188
|
-
dialog.close();
|
|
189
|
-
if (cmdEl) cmdEl.open = false;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
// Trigger elements
|
|
193
|
-
for (const trigger of this.querySelectorAll('[data-command-trigger]')) {
|
|
194
|
-
trigger.addEventListener('click', (e) => {
|
|
195
|
-
e.stopPropagation();
|
|
196
|
-
openCmd();
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Backdrop click closes
|
|
201
|
-
dialog.addEventListener('click', (e) => {
|
|
202
|
-
if (e.target === dialog) closeCmd();
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
// Command-n events
|
|
206
|
-
if (cmdEl) {
|
|
207
|
-
cmdEl.addEventListener('dismiss', closeCmd);
|
|
208
|
-
cmdEl.addEventListener('select', (e) => {
|
|
209
|
-
closeCmd();
|
|
210
|
-
if (nav) {
|
|
211
|
-
const item = nav.querySelector(`app-nav-item-ui[value="${e.detail.value}"]`);
|
|
212
|
-
if (item) nav.select(item);
|
|
213
|
-
}
|
|
214
|
-
this.dispatchEvent(new CustomEvent('command-select', {
|
|
215
|
-
bubbles: true,
|
|
216
|
-
detail: e.detail,
|
|
217
|
-
}));
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Cmd+K / Ctrl+K
|
|
222
|
-
this.#cmdKeyHandler = (e) => {
|
|
223
|
-
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
|
224
|
-
e.preventDefault();
|
|
225
|
-
dialog.open ? closeCmd() : openCmd();
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
document.addEventListener('keydown', this.#cmdKeyHandler);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// ── 4. ResizeObserver for select placement ─────────────────
|
|
232
|
-
|
|
233
|
-
#setupResizeObserver() {
|
|
234
|
-
this.#sidebarRO = new ResizeObserver((entries) => {
|
|
235
|
-
for (const entry of entries) {
|
|
236
|
-
const sidebar = entry.target;
|
|
237
|
-
const narrow = entry.contentBoxSize[0].inlineSize <= SNAP_THRESHOLD;
|
|
238
|
-
for (const sel of sidebar.querySelectorAll('select-ui')) {
|
|
239
|
-
sel.setAttribute('placement', narrow ? 'right' : 'bottom-start');
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
for (const sb of this.querySelectorAll('[data-sidebar]')) {
|
|
245
|
-
this.#sidebarRO.observe(sb);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
customElements.define('app-shell-ui', AdiaAppShell);
|
|
251
|
-
export { AdiaAppShell };
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
2
|
-
name: AdiaAppShell
|
|
3
|
-
tag: app-shell-ui
|
|
4
|
-
component: AppShell
|
|
5
|
-
category: layout
|
|
6
|
-
version: 1
|
|
7
|
-
description: |
|
|
8
|
-
Behavior-only application shell. Wires sidebar toggles, resize handles,
|
|
9
|
-
a Cmd+K command palette, and a ResizeObserver that drives responsive
|
|
10
|
-
sidebar collapse. Author supplies the DOM (aside[data-sidebar], main,
|
|
11
|
-
dialog[data-command]); app-shell-ui binds the interactions.
|
|
12
|
-
|
|
13
|
-
props:
|
|
14
|
-
mode:
|
|
15
|
-
type: string
|
|
16
|
-
default: ""
|
|
17
|
-
enum: ["", rounded, borderless]
|
|
18
|
-
reflect: true
|
|
19
|
-
description: Layout variant — default is bordered surface; rounded softens edges; borderless removes the outer chrome.
|
|
20
|
-
|
|
21
|
-
events:
|
|
22
|
-
sidebar-toggle:
|
|
23
|
-
description: Fired when a sidebar is collapsed or expanded.
|
|
24
|
-
detail:
|
|
25
|
-
sidebar: string
|
|
26
|
-
expanded: boolean
|
|
27
|
-
sidebar-resize:
|
|
28
|
-
description: Fired as a sidebar is dragged; debounced on the trailing edge.
|
|
29
|
-
detail:
|
|
30
|
-
sidebar: string
|
|
31
|
-
width: number
|
|
32
|
-
command-select:
|
|
33
|
-
description: Forwarded from the command palette when an option is chosen.
|
|
34
|
-
detail:
|
|
35
|
-
value: string
|
|
36
|
-
|
|
37
|
-
slots:
|
|
38
|
-
default:
|
|
39
|
-
description: >-
|
|
40
|
-
Author-supplied page DOM. Expected structure — aside[data-sidebar] for
|
|
41
|
-
navigation, main for content, optional dialog[data-command] for Cmd+K.
|
|
42
|
-
icon:
|
|
43
|
-
description: >-
|
|
44
|
-
Leading glyph inside any chrome bar — > main > header / footer and
|
|
45
|
-
[data-sidebar] > header / footer. Muted color, flex-align.
|
|
46
|
-
heading:
|
|
47
|
-
description: >-
|
|
48
|
-
Primary label inside any chrome bar. Medium-weight + strong fg.
|
|
49
|
-
description:
|
|
50
|
-
description: >-
|
|
51
|
-
Secondary metadata inside any chrome bar. Muted + --a-ui-sm size.
|
|
52
|
-
action:
|
|
53
|
-
description: >-
|
|
54
|
-
Trailing control cluster inside any chrome bar. The first
|
|
55
|
-
[slot="action"] child pushes itself (and siblings) to the end;
|
|
56
|
-
subsequent siblings flow with gap. Coexists with legacy
|
|
57
|
-
<span data-spacer> / <div data-actions> hooks for one release —
|
|
58
|
-
new code should prefer slots.
|
|
59
|
-
action-leading:
|
|
60
|
-
description: >-
|
|
61
|
-
Leading (inline-start) control cluster inside any chrome bar.
|
|
62
|
-
Pairs with [slot="action"] for dual-cluster chrome (e.g. back
|
|
63
|
-
button + breadcrumb on the left, primary actions on the right).
|
|
64
|
-
Replaces the legacy <span data-spacer> hack.
|
|
65
|
-
|
|
66
|
-
states:
|
|
67
|
-
- name: idle
|
|
68
|
-
description: Default, interactive shell.
|
|
69
|
-
- name: collapsed-leading
|
|
70
|
-
attribute: data-sidebar-leading-collapsed
|
|
71
|
-
description: Leading sidebar is collapsed; content expands.
|
|
72
|
-
- name: collapsed-trailing
|
|
73
|
-
attribute: data-sidebar-trailing-collapsed
|
|
74
|
-
description: Trailing sidebar (inspector) is collapsed.
|
|
75
|
-
|
|
76
|
-
traits: []
|
|
77
|
-
|
|
78
|
-
a2ui:
|
|
79
|
-
rules:
|
|
80
|
-
- >-
|
|
81
|
-
app-shell-ui is a behavior wrapper; its children are native HTML landmarks
|
|
82
|
-
(aside, main, header). Don't wrap them in col-ui/row-ui — app-shell.css
|
|
83
|
-
handles grid layout based on [data-sidebar] attributes.
|
|
84
|
-
|
|
85
|
-
keywords: [app-shell, shell, layout, admin, dashboard, sidebar, nav]
|
|
86
|
-
synonyms:
|
|
87
|
-
admin: [dashboard, shell, app-shell]
|
|
88
|
-
dashboard: [admin, shell, app-shell]
|
|
89
|
-
related: [AppNav, AppNavGroup, AppNavItem, Command]
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/* ═══════════════════════════════════════════════════════════════
|
|
2
|
-
App Shell — Sidebar collapsed state
|
|
3
|
-
|
|
4
|
-
@container sidebar (max-width: 96px)
|
|
5
|
-
|
|
6
|
-
All collapse behavior is CSS-driven via container queries.
|
|
7
|
-
JS only handles:
|
|
8
|
-
- Resize drag with snap (≤96px → 48px, 97-159px → 160px)
|
|
9
|
-
- Toggle button (sets width to min/restore)
|
|
10
|
-
- Select placement attribute (bottom-start → right)
|
|
11
|
-
- Nav-group popover-vs-toggle (checks width at click time)
|
|
12
|
-
═══════════════════════════════════════════════════════════════ */
|
|
13
|
-
|
|
14
|
-
@container sidebar (max-width: 96px) {
|
|
15
|
-
/* Center header/footer content */
|
|
16
|
-
header, footer {
|
|
17
|
-
justify-content: center;
|
|
18
|
-
padding: var(--page-sidebar-px);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/* Center section content */
|
|
22
|
-
section {
|
|
23
|
-
display: flex;
|
|
24
|
-
flex-direction: column;
|
|
25
|
-
align-items: center;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/* Select: hide text + caret, keep leading icon/avatar */
|
|
29
|
-
select-ui [slot="display"],
|
|
30
|
-
select-ui [slot="caret"] {
|
|
31
|
-
display: none;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
select-ui [slot="trigger"] {
|
|
35
|
-
justify-content: center;
|
|
36
|
-
padding: 0;
|
|
37
|
-
min-height: var(--page-header-height);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/* Select leading: bump icon/avatar size for collapsed state */
|
|
41
|
-
select-ui [slot="leading"] {
|
|
42
|
-
--a-icon-size: var(--page-sidebar-collapsed-icon);
|
|
43
|
-
font-size: var(--page-sidebar-collapsed-icon);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
select-ui img[slot="leading"] {
|
|
47
|
-
width: var(--page-sidebar-collapsed-avatar);
|
|
48
|
-
height: var(--page-sidebar-collapsed-avatar);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/* Nav: hide all text/meta, show only icons */
|
|
52
|
-
app-nav-ui [slot="text"],
|
|
53
|
-
app-nav-ui [slot="badge"],
|
|
54
|
-
app-nav-ui [slot="caret"],
|
|
55
|
-
app-nav-ui [slot="trailing"],
|
|
56
|
-
app-nav-ui [data-nav-label],
|
|
57
|
-
app-nav-ui [data-nav-divider] {
|
|
58
|
-
display: none !important;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/* Nav items/group headers: center icon, ensure square hit area */
|
|
62
|
-
app-nav-group-ui [slot="header"] {
|
|
63
|
-
justify-content: center;
|
|
64
|
-
padding: 0;
|
|
65
|
-
min-height: var(--nav-group-row-height);
|
|
66
|
-
min-width: var(--nav-group-row-height);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
app-nav-item-ui {
|
|
70
|
-
justify-content: center;
|
|
71
|
-
padding: 0;
|
|
72
|
-
min-height: var(--nav-item-row-height);
|
|
73
|
-
min-width: var(--nav-item-row-height);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/* Button: icon-only mode */
|
|
77
|
-
button-ui {
|
|
78
|
-
--button-px: 0;
|
|
79
|
-
width: auto !important;
|
|
80
|
-
justify-content: center;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
button-ui [slot="trailing"] {
|
|
84
|
-
display: none;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/* ═══════════════════════════════════════════════════════════════
|
|
2
|
-
App Shell — Layout helpers
|
|
3
|
-
|
|
4
|
-
Generic layout utilities used across admin pages.
|
|
5
|
-
═══════════════════════════════════════════════════════════════ */
|
|
6
|
-
|
|
7
|
-
/* Flex spacer — pushes siblings to opposite ends */
|
|
8
|
-
[data-spacer] { flex: 1; }
|
|
9
|
-
|
|
10
|
-
/* Inline action group (buttons, icons) */
|
|
11
|
-
[data-actions] {
|
|
12
|
-
display: flex;
|
|
13
|
-
align-items: center;
|
|
14
|
-
gap: var(--page-actions-gap);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/* ── Form layout helpers ── */
|
|
18
|
-
|
|
19
|
-
/* 2-column grid (default), 3-column with data-grid="3" */
|
|
20
|
-
[data-grid] {
|
|
21
|
-
display: grid;
|
|
22
|
-
grid-template-columns: 1fr 1fr;
|
|
23
|
-
gap: var(--page-grid-gap);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
[data-grid="3"] {
|
|
27
|
-
grid-template-columns: 1fr 1fr 1fr;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/* Vertical stack */
|
|
31
|
-
[data-col] {
|
|
32
|
-
display: flex;
|
|
33
|
-
flex-direction: column;
|
|
34
|
-
gap: var(--page-grid-gap);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* Horizontal row */
|
|
38
|
-
[data-row] {
|
|
39
|
-
display: flex;
|
|
40
|
-
align-items: center;
|
|
41
|
-
gap: var(--page-grid-gap);
|
|
42
|
-
}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/* ═══════════════════════════════════════════════════════════════
|
|
2
|
-
App Shell — Main column (topbar + scroll + footer)
|
|
3
|
-
═══════════════════════════════════════════════════════════════ */
|
|
4
|
-
|
|
5
|
-
/* ── Main column ── */
|
|
6
|
-
app-shell-ui > main {
|
|
7
|
-
display: flex;
|
|
8
|
-
flex-direction: column;
|
|
9
|
-
flex: 1;
|
|
10
|
-
min-width: 0;
|
|
11
|
-
min-height: 0;
|
|
12
|
-
border-inline: var(--page-main-border);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/* ── Edge breathing room when adjacent chrome is absent ──
|
|
16
|
-
When the shell has no visible chrome on a given edge of the content
|
|
17
|
-
surface, `> main > section` owns a small inset against that edge so
|
|
18
|
-
the rounded/elevated surface doesn't sit flush with the viewport.
|
|
19
|
-
The `:has(... :not([hidden]))` probe catches both "element missing
|
|
20
|
-
from the DOM" AND "element present but [hidden]" — toggling
|
|
21
|
-
[hidden] flips the inset live with no JS coordination. Scope is the
|
|
22
|
-
section, not main, so the topbar/statusbar inside main keep
|
|
23
|
-
spanning full-width even when the section gets its inset.
|
|
24
|
-
|
|
25
|
-
Block-edge probes accept either an app-level chrome bar
|
|
26
|
-
(`app-shell-ui > header / > footer`) OR a main-level chrome bar
|
|
27
|
-
(`> main > header / > main > footer`). Either qualifies as
|
|
28
|
-
"chrome present" and suppresses the corresponding margin. */
|
|
29
|
-
app-shell-ui:not(:has(> aside[data-sidebar="trailing"]:not([hidden]))) > main > section {
|
|
30
|
-
margin-inline-end: var(--a-space-2);
|
|
31
|
-
}
|
|
32
|
-
app-shell-ui:not(:has(> header:not([hidden]), > main > header:not([hidden]))) > main > section {
|
|
33
|
-
margin-block-start: var(--a-space-2);
|
|
34
|
-
}
|
|
35
|
-
app-shell-ui:not(:has(> footer:not([hidden]), > main > footer:not([hidden]))) > main > section {
|
|
36
|
-
margin-block-end: var(--a-space-2);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/* ── Main > header (topbar) ──
|
|
40
|
-
Contains: sidebar toggle, breadcrumb, spacer, action buttons.
|
|
41
|
-
|
|
42
|
-
Slot contract (shared with > main > footer and [data-sidebar] >
|
|
43
|
-
header/footer) — identical to card-ui / drawer-ui / adia-editor-ui:
|
|
44
|
-
[slot="icon"] leading glyph
|
|
45
|
-
[slot="heading"] primary label; strong weight + strong fg
|
|
46
|
-
[slot="description"] secondary metadata; muted fg + --a-ui-sm
|
|
47
|
-
[slot="action"] trailing cluster; first pushes to end
|
|
48
|
-
The legacy data-sidebar-toggle / breadcrumb-ui / <span data-spacer>
|
|
49
|
-
/ <div data-actions> hooks (see app-shell.helpers.css) remain
|
|
50
|
-
fully supported — slots are additive, not a replacement. Use slots
|
|
51
|
-
for simpler chrome surfaces; keep breadcrumb + data-actions for
|
|
52
|
-
docs-style shells where those conventions carry semantic weight. */
|
|
53
|
-
app-shell-ui > main > header {
|
|
54
|
-
display: flex;
|
|
55
|
-
align-items: center;
|
|
56
|
-
gap: var(--page-header-gap);
|
|
57
|
-
min-height: var(--page-header-height);
|
|
58
|
-
padding: 0 var(--page-header-px);
|
|
59
|
-
border-bottom: var(--page-border);
|
|
60
|
-
font-size: var(--page-header-font);
|
|
61
|
-
flex-shrink: 0;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
app-shell-ui > main > header > [slot="icon"] {
|
|
65
|
-
display: flex;
|
|
66
|
-
align-items: center;
|
|
67
|
-
flex-shrink: 0;
|
|
68
|
-
color: var(--page-header-fg-muted);
|
|
69
|
-
}
|
|
70
|
-
app-shell-ui > main > header > [slot="heading"] {
|
|
71
|
-
font-weight: var(--a-weight-medium);
|
|
72
|
-
color: var(--a-fg);
|
|
73
|
-
}
|
|
74
|
-
app-shell-ui > main > header > [slot="description"] {
|
|
75
|
-
color: var(--page-header-fg-muted);
|
|
76
|
-
font-size: var(--a-ui-sm);
|
|
77
|
-
}
|
|
78
|
-
app-shell-ui > main > header > [slot="action"] {
|
|
79
|
-
display: flex;
|
|
80
|
-
align-items: center;
|
|
81
|
-
gap: var(--page-actions-gap);
|
|
82
|
-
flex-shrink: 0;
|
|
83
|
-
margin-inline-start: auto;
|
|
84
|
-
}
|
|
85
|
-
app-shell-ui > main > header > [slot="action"] ~ [slot="action"] {
|
|
86
|
-
margin-inline-start: 0;
|
|
87
|
-
}
|
|
88
|
-
/* Dual-cluster: leading group on inline-start, trailing cluster on inline-end. */
|
|
89
|
-
app-shell-ui > main > header > [slot="action-leading"] {
|
|
90
|
-
display: flex;
|
|
91
|
-
align-items: center;
|
|
92
|
-
gap: var(--page-actions-gap);
|
|
93
|
-
flex-shrink: 0;
|
|
94
|
-
margin-inline-end: auto;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/* ── Main > section (scroll container) ──
|
|
98
|
-
Wraps [data-content-root]. Scrolls vertically, hides scrollbar.
|
|
99
|
-
Soft elevation via --page-content-shadow (defaults to --a-shadow-md)
|
|
100
|
-
so the content surface lifts off the chrome canvas regardless of
|
|
101
|
-
mode — pairs with --page-content-radius under "rounded" and stays
|
|
102
|
-
visible under "borderless". */
|
|
103
|
-
app-shell-ui > main > section {
|
|
104
|
-
flex: 1;
|
|
105
|
-
min-height: 0;
|
|
106
|
-
overflow-y: auto;
|
|
107
|
-
overscroll-behavior: contain;
|
|
108
|
-
scrollbar-width: none;
|
|
109
|
-
background: var(--page-content-bg);
|
|
110
|
-
box-shadow: var(--page-content-shadow);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
app-shell-ui > main > section::-webkit-scrollbar { display: none; }
|
|
114
|
-
|
|
115
|
-
/* ── Main > footer (status bar) ──
|
|
116
|
-
Legacy pattern: last-child auto-pushed to trailing edge via
|
|
117
|
-
margin-inline-start: auto (works when authors use a simple
|
|
118
|
-
<span>…</span><span>version</span> shape).
|
|
119
|
-
Slot pattern: same icon / heading / description / action vocabulary
|
|
120
|
-
as > main > header (see comment block above). */
|
|
121
|
-
app-shell-ui > main > footer {
|
|
122
|
-
flex-shrink: 0;
|
|
123
|
-
display: flex;
|
|
124
|
-
align-items: center;
|
|
125
|
-
margin-top: auto;
|
|
126
|
-
gap: var(--page-header-gap);
|
|
127
|
-
min-height: var(--page-header-height);
|
|
128
|
-
padding: 0 var(--page-header-px);
|
|
129
|
-
border-top: var(--page-border);
|
|
130
|
-
font-size: var(--page-header-font);
|
|
131
|
-
color: var(--page-header-fg-muted);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* Legacy: bare <span>…</span><span>version</span> shapes. Only kicks
|
|
135
|
-
in when NO slot="action" is present, so it doesn't fight the slot
|
|
136
|
-
rule below. */
|
|
137
|
-
app-shell-ui > main > footer:not(:has(> [slot="action"])) > :last-child {
|
|
138
|
-
margin-inline-start: auto;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
app-shell-ui > main > footer > [slot="icon"] {
|
|
142
|
-
display: flex;
|
|
143
|
-
align-items: center;
|
|
144
|
-
flex-shrink: 0;
|
|
145
|
-
color: var(--page-header-fg-muted);
|
|
146
|
-
}
|
|
147
|
-
app-shell-ui > main > footer > [slot="heading"] {
|
|
148
|
-
font-weight: var(--a-weight-medium);
|
|
149
|
-
color: var(--a-fg);
|
|
150
|
-
}
|
|
151
|
-
app-shell-ui > main > footer > [slot="description"] {
|
|
152
|
-
color: var(--page-header-fg-muted);
|
|
153
|
-
font-size: var(--a-ui-sm);
|
|
154
|
-
}
|
|
155
|
-
app-shell-ui > main > footer > [slot="action"] {
|
|
156
|
-
display: flex;
|
|
157
|
-
align-items: center;
|
|
158
|
-
gap: var(--page-actions-gap);
|
|
159
|
-
flex-shrink: 0;
|
|
160
|
-
margin-inline-start: auto;
|
|
161
|
-
}
|
|
162
|
-
app-shell-ui > main > footer > [slot="action"] ~ [slot="action"] {
|
|
163
|
-
margin-inline-start: 0;
|
|
164
|
-
}
|
|
165
|
-
/* Dual-cluster: leading group on inline-start, trailing cluster on inline-end. */
|
|
166
|
-
app-shell-ui > main > footer > [slot="action-leading"] {
|
|
167
|
-
display: flex;
|
|
168
|
-
align-items: center;
|
|
169
|
-
gap: var(--page-actions-gap);
|
|
170
|
-
flex-shrink: 0;
|
|
171
|
-
margin-inline-end: auto;
|
|
172
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/* ═══════════════════════════════════════════════════════════════
|
|
2
|
-
App Shell — Root layout + modes
|
|
3
|
-
|
|
4
|
-
Structure:
|
|
5
|
-
app-shell-ui — root shell (flex row, fixed viewport)
|
|
6
|
-
aside[data-sidebar="leading"] — nav sidebar (resizable, collapsible)
|
|
7
|
-
main — center column (topbar + scroll + footer)
|
|
8
|
-
header — topbar
|
|
9
|
-
section — scroll container
|
|
10
|
-
article[data-content-root] — page wrapper (sticky bands + centered body)
|
|
11
|
-
div[data-content-header] > header — sticky page title + tabs
|
|
12
|
-
div[data-content-body] > section — centered reading column (tab/form content)
|
|
13
|
-
footer — status bar
|
|
14
|
-
aside[data-sidebar="trailing"] — inspector sidebar
|
|
15
|
-
dialog[data-command] — command palette
|
|
16
|
-
|
|
17
|
-
Modes (space-separated on mode attribute):
|
|
18
|
-
"rounded" — border-radius on scroll section
|
|
19
|
-
"borderless" — removes chrome borders (content borders persist)
|
|
20
|
-
═══════════════════════════════════════════════════════════════ */
|
|
21
|
-
|
|
22
|
-
/* ── Page modes ── */
|
|
23
|
-
app-shell-ui[mode~="rounded"] > main > section {
|
|
24
|
-
border-radius: var(--page-content-radius);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
app-shell-ui[mode~="borderless"] {
|
|
28
|
-
--page-main-border: none;
|
|
29
|
-
--page-border: none;
|
|
30
|
-
/* Note: --page-content-border is NOT reset — content dividers persist */
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/* ── Page shell ── */
|
|
34
|
-
app-shell-ui {
|
|
35
|
-
display: flex;
|
|
36
|
-
height: 100dvh;
|
|
37
|
-
overflow: hidden;
|
|
38
|
-
background: var(--page-bg);
|
|
39
|
-
position: fixed;
|
|
40
|
-
inset: 0;
|
|
41
|
-
overscroll-behavior: none;
|
|
42
|
-
font-family: var(--page-font-family);
|
|
43
|
-
font-size: var(--page-body-size);
|
|
44
|
-
}
|