@adia-ai/web-components 0.0.25 → 0.0.26

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.
@@ -24,7 +24,6 @@ export { AdiaSegmented } from './segmented/segmented.js';
24
24
  export { AdiaRange } from './range/range.js';
25
25
  export { AdiaTree, AdiaTreeItem } from './tree/tree.js';
26
26
  export { AdiaPane } from './pane/pane.js';
27
- export { AdiaAppShell } from './app-shell/app-shell.js';
28
27
  export { AdiaPage } from './page/page.js';
29
28
  export { AdiaChatInput } from './chat/chat-input.js';
30
29
  export { AdiaChat } from './chat/chat.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-components",
3
- "version": "0.0.25",
3
+ "version": "0.0.26",
4
4
  "description": "AdiaUI web components — vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-utils.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,18 +1,6 @@
1
1
  /* ═══════════════════════════════════════════════════════════════
2
2
  App Shell — <app-shell-ui> pattern component CSS
3
3
 
4
- ⚠ DEPRECATED PATH (2026-04-29): preserved as an alias for one
5
- release while consumers migrate. The CSS now lives behind the
6
- <app-shell-ui> custom element at
7
- packages/web-components/components/app-shell/ and ships via
8
- packages/web-components/styles/components.css.
9
-
10
- Migration: drop the explicit <link rel="stylesheet"> to this file —
11
- styles/components.css now bundles the same content via the new
12
- component.
13
-
14
- Companion ADR: ../../../../.brain/adrs/0009-promote-app-shell-and-page-to-components.md.
15
-
16
4
  Split into constituent parts for maintainability.
17
5
  Import order matters: tokens first, then structure, then overrides.
18
6
  ═══════════════════════════════════════════════════════════════ */
@@ -26,7 +26,6 @@
26
26
  @import "../components/range/range.css";
27
27
  @import "../components/tree/tree.css";
28
28
  @import "../components/pane/pane.css";
29
- @import "../components/app-shell/app-shell.css";
30
29
  @import "../components/page/page.css";
31
30
  @import "../components/chat/chat-input.css";
32
31
  @import "../components/chat/chat.css";
@@ -1,136 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://adiaui.dev/a2ui/v0_9/components/AppShell.json",
4
- "title": "AppShell",
5
- "description": "Application shell layout. Holds a leading nav rail, a main column\n(topbar + scroll area + statusbar), an optional trailing inspector,\nand an optional command-palette `<dialog>`. The component wires\nsidebar toggle, sidebar resize, and Cmd+K shortcut on top of the\nlong-lived CSS pattern that already targets `app-shell-ui` as a tag.\nChildren use native HTML semantic elements (`<aside data-sidebar>`,\n`<main>`, `<header>`, `<section>`, `<footer>`); the existing\nCSS scopes by tag.\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
- "cmdK": {
17
- "description": "Installs a global Cmd+K / Ctrl+K listener that opens the inner\n`<dialog data-command>` via `showModal()`. No-op when no such\ndialog is present.\n",
18
- "type": "boolean",
19
- "default": false
20
- },
21
- "component": {
22
- "const": "AppShell"
23
- },
24
- "leadingCollapsed": {
25
- "description": "Reflects to the leading aside's `[data-collapsed]`. Toggled\nprogrammatically (`shell.toggleLeading()`) or via a click on any\nelement with `[data-sidebar-toggle=\"leading\"]` inside the shell.\n",
26
- "type": "boolean",
27
- "default": false
28
- },
29
- "leadingMaxWidth": {
30
- "description": "Maximum leading-aside width (px) when resizing.",
31
- "type": "number",
32
- "default": 480
33
- },
34
- "leadingMinWidth": {
35
- "description": "Minimum leading-aside width (px) when resizing.",
36
- "type": "number",
37
- "default": 48
38
- },
39
- "mode": {
40
- "description": "Space-separated list of layout modes. `rounded` adds border-radius\nto the scroll section; `borderless` removes chrome borders (content\nborders persist). Pass both for a soft, edgeless shell.\n",
41
- "type": "string",
42
- "default": ""
43
- },
44
- "trailingCollapsed": {
45
- "description": "Reflects to the trailing aside's `[data-collapsed]`. Toggled via\n`shell.toggleTrailing()` or `[data-sidebar-toggle=\"trailing\"]`.\n",
46
- "type": "boolean",
47
- "default": false
48
- },
49
- "trailingMaxWidth": {
50
- "description": "Maximum trailing-aside width (px) when resizing.",
51
- "type": "number",
52
- "default": 480
53
- },
54
- "trailingMinWidth": {
55
- "description": "Minimum trailing-aside width (px) when resizing.",
56
- "type": "number",
57
- "default": 48
58
- }
59
- },
60
- "required": [
61
- "component"
62
- ],
63
- "unevaluatedProperties": false,
64
- "x-adiaui": {
65
- "anti_patterns": [],
66
- "category": "container",
67
- "events": {
68
- "command-close": {
69
- "description": "Fired after the command-palette `<dialog>` closes."
70
- },
71
- "command-open": {
72
- "description": "Fired after the command-palette `<dialog>` opens."
73
- },
74
- "sidebar-toggle": {
75
- "description": "Fired after a sidebar's collapsed state flips. Detail:\n`{ side: 'leading'|'trailing', collapsed: boolean }`.\n"
76
- }
77
- },
78
- "examples": [
79
- {
80
- "description": "Documentation shell — leading nav, topbar with breadcrumb, scroll content, statusbar.",
81
- "a2ui": "[\n {\n \"id\": \"root\",\n \"component\": \"AppShell\",\n \"mode\": \"rounded\",\n \"cmdK\": true,\n \"children\": [\"leading\", \"main\", \"cmd\"]\n },\n {\n \"id\": \"leading\",\n \"component\": \"Aside\",\n \"data-sidebar\": \"leading\",\n \"children\": [\"nav-hdr\", \"nav-list\", \"nav-ftr\"]\n },\n {\n \"id\": \"nav-hdr\",\n \"component\": \"Header\",\n \"children\": []\n },\n {\n \"id\": \"nav-list\",\n \"component\": \"Section\",\n \"children\": []\n },\n {\n \"id\": \"nav-ftr\",\n \"component\": \"Footer\",\n \"children\": []\n },\n {\n \"id\": \"main\",\n \"component\": \"Column\",\n \"children\": [\"topbar\", \"scroll\", \"statusbar\"]\n },\n {\n \"id\": \"topbar\",\n \"component\": \"Header\",\n \"children\": []\n },\n {\n \"id\": \"scroll\",\n \"component\": \"Section\",\n \"scroll\": true,\n \"children\": []\n },\n {\n \"id\": \"statusbar\",\n \"component\": \"Footer\",\n \"children\": []\n },\n {\n \"id\": \"cmd\",\n \"component\": \"Modal\",\n \"data-command\": true,\n \"children\": []\n }\n]",
82
- "name": "docs-shell"
83
- }
84
- ],
85
- "keywords": [
86
- "app-shell",
87
- "shell",
88
- "layout",
89
- "sidebar",
90
- "topbar",
91
- "command-palette",
92
- "cmdK",
93
- "dashboard-shell"
94
- ],
95
- "name": "AdiaAppShell",
96
- "related": [
97
- "aside",
98
- "header",
99
- "footer",
100
- "section",
101
- "drawer",
102
- "modal",
103
- "command",
104
- "app-nav",
105
- "section-nav"
106
- ],
107
- "slots": {
108
- "default": {
109
- "description": "Composes from native HTML children: `<aside data-sidebar=\"leading\">`,\n`<main>` (with `<header>`, `<section>`, `<footer>` inside),\noptional `<aside data-sidebar=\"trailing\">`, optional\n`<dialog data-command>`. The existing pattern CSS scopes each\nchild by tag + attribute; no `slot=` attributes needed.\n"
110
- }
111
- },
112
- "states": [
113
- {
114
- "description": "Default, ready for interaction.",
115
- "name": "idle"
116
- },
117
- {
118
- "description": "Leading aside collapsed via attribute / API.",
119
- "name": "leading-collapsed"
120
- },
121
- {
122
- "description": "Trailing aside collapsed via attribute / API.",
123
- "name": "trailing-collapsed"
124
- },
125
- {
126
- "description": "Command-palette dialog is showing.",
127
- "name": "command-open"
128
- }
129
- ],
130
- "synonyms": {},
131
- "tag": "app-shell-ui",
132
- "tokens": {},
133
- "traits": [],
134
- "version": 1
135
- }
136
- }
@@ -1,16 +0,0 @@
1
- /* ═══════════════════════════════════════════════════════════════
2
- <app-shell-ui> component CSS
3
-
4
- The substantive CSS lives in `patterns/app-shell/css/*.css` —
5
- that surface predates this component and already targets
6
- `app-shell-ui` as a tag. We re-import it here so consumers
7
- importing this component's CSS get the full styling without
8
- duplication. A future cleanup may invert the relationship
9
- (move the CSS into this folder and have the pattern import
10
- from here, or retire the pattern folder entirely once all
11
- consumers have migrated to the component).
12
-
13
- Companion ADR: .brain/adrs/0009-promote-app-shell-and-page-to-components.md
14
- ═══════════════════════════════════════════════════════════════ */
15
-
16
- @import "../../patterns/app-shell/app-shell.css";
@@ -1,202 +0,0 @@
1
- /**
2
- * <app-shell-ui> — Application shell layout component.
3
- *
4
- * Promotes the long-lived `patterns/app-shell/` CSS pattern (which already
5
- * targeted `app-shell-ui` as a tag) to a real custom element. CSS continues
6
- * to live in `patterns/app-shell/app-shell.css` (re-imported from this
7
- * component's CSS); the JS layer adds:
8
- *
9
- * - sidebar toggle (delegated [data-sidebar-toggle="leading|trailing"])
10
- * - sidebar resize (pointer drag on [data-resize])
11
- * - command-palette wiring (delegated [data-command-trigger] +
12
- * optional Cmd+K global shortcut when [cmd-k])
13
- *
14
- * Authoring shape (consumer markup, unchanged from the pre-existing pattern):
15
- *
16
- * <app-shell-ui mode="rounded borderless" cmd-k>
17
- * <aside data-sidebar="leading"> <-- nav rail
18
- * <header>...</header>
19
- * <section>...</section>
20
- * <footer>...</footer>
21
- * <div data-resize></div>
22
- * </aside>
23
- * <main>
24
- * <header>...</header> <-- topbar
25
- * <section>...</section> <-- scroll area
26
- * <footer>...</footer> <-- statusbar
27
- * </main>
28
- * <aside data-sidebar="trailing">...</aside> <!-- optional inspector -->
29
- * <dialog data-command> <!-- optional cmd palette -->
30
- * <command-ui>...</command-ui>
31
- * </dialog>
32
- * </app-shell-ui>
33
- *
34
- * Attributes:
35
- * mode — space-separated list: "rounded" | "borderless" | both.
36
- * leading-collapsed — boolean, reflects to leading aside's [data-collapsed].
37
- * trailing-collapsed — boolean, reflects to trailing aside's [data-collapsed].
38
- * cmd-k — boolean, installs Cmd+K / Ctrl+K global listener
39
- * that opens the inner <dialog data-command> via
40
- * showModal(). No-op when no such dialog is present.
41
- * leading-min-width — minimum width when resizing leading sidebar (px).
42
- * leading-max-width — maximum width (px).
43
- * trailing-min-width / trailing-max-width — same for trailing.
44
- *
45
- * API:
46
- * shell.toggleLeading() shell.toggleTrailing()
47
- * shell.openCommand() shell.closeCommand()
48
- *
49
- * Events (bubbling):
50
- * sidebar-toggle { detail: { side: 'leading'|'trailing', collapsed: boolean } }
51
- * command-open no detail
52
- * command-close no detail
53
- *
54
- * Spec: docs/specs/genui-multiturn-architecture.md (orthogonal — gen-UI uses
55
- * this layer). ADR: .brain/adrs/0009-promote-app-shell-and-page-to-components.md.
56
- */
57
-
58
- import { AdiaElement } from '../../core/element.js';
59
-
60
- const DEFAULT_MIN_WIDTH = 48;
61
- const DEFAULT_MAX_WIDTH = 480;
62
-
63
- class AdiaAppShell extends AdiaElement {
64
- static properties = {
65
- mode: { type: String, default: '', reflect: true },
66
- leadingCollapsed: { type: Boolean, default: false, attribute: 'leading-collapsed', reflect: true },
67
- trailingCollapsed: { type: Boolean, default: false, attribute: 'trailing-collapsed', reflect: true },
68
- cmdK: { type: Boolean, default: false, attribute: 'cmd-k', reflect: true },
69
- leadingMinWidth: { type: Number, default: DEFAULT_MIN_WIDTH, attribute: 'leading-min-width' },
70
- leadingMaxWidth: { type: Number, default: DEFAULT_MAX_WIDTH, attribute: 'leading-max-width' },
71
- trailingMinWidth: { type: Number, default: DEFAULT_MIN_WIDTH, attribute: 'trailing-min-width' },
72
- trailingMaxWidth: { type: Number, default: DEFAULT_MAX_WIDTH, attribute: 'trailing-max-width' },
73
- };
74
-
75
- static template = () => null;
76
-
77
- #bound = false;
78
- #drag = null; // { aside, startX, startW, side }
79
-
80
- connected() {
81
- if (!this.#bound) {
82
- this.#bound = true;
83
- this.addEventListener('click', this.#onClick);
84
- this.addEventListener('pointerdown', this.#onPointerDown);
85
- }
86
- document.addEventListener('keydown', this.#onKeydown);
87
- }
88
-
89
- disconnected() {
90
- document.removeEventListener('keydown', this.#onKeydown);
91
- document.removeEventListener('pointermove', this.#onResizeMove);
92
- document.removeEventListener('pointerup', this.#onResizeUp);
93
- this.#drag = null;
94
- }
95
-
96
- render() {
97
- const leading = this.querySelector(':scope > aside[data-sidebar="leading"]');
98
- if (leading) leading.toggleAttribute('data-collapsed', !!this.leadingCollapsed);
99
- const trailing = this.querySelector(':scope > aside[data-sidebar="trailing"]');
100
- if (trailing) trailing.toggleAttribute('data-collapsed', !!this.trailingCollapsed);
101
- }
102
-
103
- // ── API ─────────────────────────────────────────────────────────
104
-
105
- toggleLeading() {
106
- this.leadingCollapsed = !this.leadingCollapsed;
107
- this.dispatchEvent(new CustomEvent('sidebar-toggle', {
108
- bubbles: true,
109
- detail: { side: 'leading', collapsed: this.leadingCollapsed },
110
- }));
111
- }
112
-
113
- toggleTrailing() {
114
- this.trailingCollapsed = !this.trailingCollapsed;
115
- this.dispatchEvent(new CustomEvent('sidebar-toggle', {
116
- bubbles: true,
117
- detail: { side: 'trailing', collapsed: this.trailingCollapsed },
118
- }));
119
- }
120
-
121
- openCommand() {
122
- const dialog = this.querySelector(':scope > dialog[data-command]');
123
- if (!dialog || dialog.open) return;
124
- dialog.showModal();
125
- this.dispatchEvent(new CustomEvent('command-open', { bubbles: true }));
126
- }
127
-
128
- closeCommand() {
129
- const dialog = this.querySelector(':scope > dialog[data-command]');
130
- if (!dialog || !dialog.open) return;
131
- dialog.close();
132
- this.dispatchEvent(new CustomEvent('command-close', { bubbles: true }));
133
- }
134
-
135
- // ── Delegated click ─────────────────────────────────────────────
136
-
137
- #onClick = (e) => {
138
- const toggle = e.target.closest('[data-sidebar-toggle]');
139
- if (toggle && this.contains(toggle)) {
140
- const side = toggle.getAttribute('data-sidebar-toggle');
141
- if (side === 'leading') { this.toggleLeading(); return; }
142
- if (side === 'trailing') { this.toggleTrailing(); return; }
143
- }
144
- const trigger = e.target.closest('[data-command-trigger]');
145
- if (trigger && this.contains(trigger)) {
146
- this.openCommand();
147
- }
148
- };
149
-
150
- // ── Cmd+K / Ctrl+K ──────────────────────────────────────────────
151
-
152
- #onKeydown = (e) => {
153
- if (!this.cmdK) return;
154
- if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
155
- e.preventDefault();
156
- this.openCommand();
157
- }
158
- };
159
-
160
- // ── Resize handle ───────────────────────────────────────────────
161
- // Pointerdown on a [data-resize] inside one of the asides starts a drag.
162
- // Leading aside grows when dragged right; trailing aside grows when
163
- // dragged left (mirrors `<pane-ui>[side]` semantics).
164
-
165
- #onPointerDown = (e) => {
166
- const handle = e.target.closest('[data-resize]');
167
- if (!handle) return;
168
- const aside = handle.closest(':scope > aside[data-sidebar]');
169
- if (!aside || aside.parentElement !== this) return;
170
-
171
- const side = aside.getAttribute('data-sidebar'); // 'leading' | 'trailing'
172
- this.#drag = {
173
- aside,
174
- side,
175
- startX: e.clientX,
176
- startW: aside.getBoundingClientRect().width,
177
- };
178
- handle.setPointerCapture?.(e.pointerId);
179
- document.addEventListener('pointermove', this.#onResizeMove);
180
- document.addEventListener('pointerup', this.#onResizeUp, { once: true });
181
- e.preventDefault();
182
- };
183
-
184
- #onResizeMove = (e) => {
185
- if (!this.#drag) return;
186
- const { aside, side, startX, startW } = this.#drag;
187
- const dx = e.clientX - startX;
188
- const min = side === 'leading' ? this.leadingMinWidth : this.trailingMinWidth;
189
- const max = side === 'leading' ? this.leadingMaxWidth : this.trailingMaxWidth;
190
- const next = Math.max(min, Math.min(max, startW + (side === 'leading' ? dx : -dx)));
191
- aside.style.width = `${next}px`;
192
- };
193
-
194
- #onResizeUp = () => {
195
- this.#drag = null;
196
- document.removeEventListener('pointermove', this.#onResizeMove);
197
- };
198
- }
199
-
200
- customElements.define('app-shell-ui', AdiaAppShell);
201
-
202
- export { AdiaAppShell };
@@ -1,183 +0,0 @@
1
- # Edit this file; run `npm run build:components` to regenerate a2ui.json.
2
- $schema: ../../../../scripts/schemas/component.yaml.schema.json
3
- name: AdiaAppShell
4
- tag: app-shell-ui
5
- component: AppShell
6
- category: container
7
- version: 1
8
- description: |
9
- Application shell layout. Holds a leading nav rail, a main column
10
- (topbar + scroll area + statusbar), an optional trailing inspector,
11
- and an optional command-palette `<dialog>`. The component wires
12
- sidebar toggle, sidebar resize, and Cmd+K shortcut on top of the
13
- long-lived CSS pattern that already targets `app-shell-ui` as a tag.
14
- Children use native HTML semantic elements (`<aside data-sidebar>`,
15
- `<main>`, `<header>`, `<section>`, `<footer>`); the existing
16
- CSS scopes by tag.
17
- props:
18
- mode:
19
- description: |
20
- Space-separated list of layout modes. `rounded` adds border-radius
21
- to the scroll section; `borderless` removes chrome borders (content
22
- borders persist). Pass both for a soft, edgeless shell.
23
- type: string
24
- default: ""
25
- reflect: true
26
- leadingCollapsed:
27
- description: |
28
- Reflects to the leading aside's `[data-collapsed]`. Toggled
29
- programmatically (`shell.toggleLeading()`) or via a click on any
30
- element with `[data-sidebar-toggle="leading"]` inside the shell.
31
- type: boolean
32
- default: false
33
- attribute: leading-collapsed
34
- reflect: true
35
- trailingCollapsed:
36
- description: |
37
- Reflects to the trailing aside's `[data-collapsed]`. Toggled via
38
- `shell.toggleTrailing()` or `[data-sidebar-toggle="trailing"]`.
39
- type: boolean
40
- default: false
41
- attribute: trailing-collapsed
42
- reflect: true
43
- cmdK:
44
- description: |
45
- Installs a global Cmd+K / Ctrl+K listener that opens the inner
46
- `<dialog data-command>` via `showModal()`. No-op when no such
47
- dialog is present.
48
- type: boolean
49
- default: false
50
- attribute: cmd-k
51
- reflect: true
52
- leadingMinWidth:
53
- description: Minimum leading-aside width (px) when resizing.
54
- type: number
55
- default: 48
56
- attribute: leading-min-width
57
- leadingMaxWidth:
58
- description: Maximum leading-aside width (px) when resizing.
59
- type: number
60
- default: 480
61
- attribute: leading-max-width
62
- trailingMinWidth:
63
- description: Minimum trailing-aside width (px) when resizing.
64
- type: number
65
- default: 48
66
- attribute: trailing-min-width
67
- trailingMaxWidth:
68
- description: Maximum trailing-aside width (px) when resizing.
69
- type: number
70
- default: 480
71
- attribute: trailing-max-width
72
- events:
73
- sidebar-toggle:
74
- description: |
75
- Fired after a sidebar's collapsed state flips. Detail:
76
- `{ side: 'leading'|'trailing', collapsed: boolean }`.
77
- command-open:
78
- description: Fired after the command-palette `<dialog>` opens.
79
- command-close:
80
- description: Fired after the command-palette `<dialog>` closes.
81
- slots:
82
- default:
83
- description: |
84
- Composes from native HTML children: `<aside data-sidebar="leading">`,
85
- `<main>` (with `<header>`, `<section>`, `<footer>` inside),
86
- optional `<aside data-sidebar="trailing">`, optional
87
- `<dialog data-command>`. The existing pattern CSS scopes each
88
- child by tag + attribute; no `slot=` attributes needed.
89
- states:
90
- - name: idle
91
- description: Default, ready for interaction.
92
- - name: leading-collapsed
93
- description: Leading aside collapsed via attribute / API.
94
- - name: trailing-collapsed
95
- description: Trailing aside collapsed via attribute / API.
96
- - name: command-open
97
- description: Command-palette dialog is showing.
98
- traits: []
99
- tokens: {}
100
- a2ui:
101
- rules: []
102
- anti_patterns: []
103
- examples:
104
- - name: docs-shell
105
- description: Documentation shell — leading nav, topbar with breadcrumb, scroll content, statusbar.
106
- a2ui: >-
107
- [
108
- {
109
- "id": "root",
110
- "component": "AppShell",
111
- "mode": "rounded",
112
- "cmdK": true,
113
- "children": ["leading", "main", "cmd"]
114
- },
115
- {
116
- "id": "leading",
117
- "component": "Aside",
118
- "data-sidebar": "leading",
119
- "children": ["nav-hdr", "nav-list", "nav-ftr"]
120
- },
121
- {
122
- "id": "nav-hdr",
123
- "component": "Header",
124
- "children": []
125
- },
126
- {
127
- "id": "nav-list",
128
- "component": "Section",
129
- "children": []
130
- },
131
- {
132
- "id": "nav-ftr",
133
- "component": "Footer",
134
- "children": []
135
- },
136
- {
137
- "id": "main",
138
- "component": "Column",
139
- "children": ["topbar", "scroll", "statusbar"]
140
- },
141
- {
142
- "id": "topbar",
143
- "component": "Header",
144
- "children": []
145
- },
146
- {
147
- "id": "scroll",
148
- "component": "Section",
149
- "scroll": true,
150
- "children": []
151
- },
152
- {
153
- "id": "statusbar",
154
- "component": "Footer",
155
- "children": []
156
- },
157
- {
158
- "id": "cmd",
159
- "component": "Modal",
160
- "data-command": true,
161
- "children": []
162
- }
163
- ]
164
- keywords:
165
- - app-shell
166
- - shell
167
- - layout
168
- - sidebar
169
- - topbar
170
- - command-palette
171
- - cmdK
172
- - dashboard-shell
173
- synonyms: {}
174
- related:
175
- - aside
176
- - header
177
- - footer
178
- - section
179
- - drawer
180
- - modal
181
- - command
182
- - app-nav
183
- - section-nav