@ismail-elkorchi/ui-shell 0.1.1 → 0.2.0
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 +117 -30
- package/dist/custom-elements.json +487 -120
- package/dist/index.d.ts +10 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/register.d.ts +5 -5
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +5 -5
- package/dist/register.js.map +1 -1
- package/dist/src/internal/command-center.d.ts +32 -0
- package/dist/src/internal/command-center.d.ts.map +1 -0
- package/dist/src/internal/command-center.js +169 -0
- package/dist/src/internal/command-center.js.map +1 -0
- package/dist/src/internal/light-dom-slot-controller.d.ts.map +1 -1
- package/dist/src/internal/light-dom-slot-controller.js +14 -13
- package/dist/src/internal/light-dom-slot-controller.js.map +1 -1
- package/dist/src/internal/router.d.ts +9 -0
- package/dist/src/internal/router.d.ts.map +1 -1
- package/dist/src/internal/router.js +14 -4
- package/dist/src/internal/router.js.map +1 -1
- package/dist/src/structures/uik-shell-activity-bar-contract.d.ts +1 -1
- package/dist/src/structures/uik-shell-activity-bar-contract.d.ts.map +1 -1
- package/dist/src/structures/uik-shell-activity-bar.d.ts +25 -15
- package/dist/src/structures/uik-shell-activity-bar.d.ts.map +1 -1
- package/dist/src/structures/uik-shell-activity-bar.js +89 -213
- package/dist/src/structures/uik-shell-activity-bar.js.map +1 -1
- package/dist/src/structures/uik-shell-layout.d.ts +21 -2
- package/dist/src/structures/uik-shell-layout.d.ts.map +1 -1
- package/dist/src/structures/uik-shell-layout.js +144 -54
- package/dist/src/structures/uik-shell-layout.js.map +1 -1
- package/dist/src/structures/uik-shell-secondary-sidebar.d.ts +34 -4
- package/dist/src/structures/uik-shell-secondary-sidebar.d.ts.map +1 -1
- package/dist/src/structures/uik-shell-secondary-sidebar.js +207 -70
- package/dist/src/structures/uik-shell-secondary-sidebar.js.map +1 -1
- package/dist/src/structures/uik-shell-sidebar.d.ts +27 -4
- package/dist/src/structures/uik-shell-sidebar.d.ts.map +1 -1
- package/dist/src/structures/uik-shell-sidebar.js +161 -84
- package/dist/src/structures/uik-shell-sidebar.js.map +1 -1
- package/dist/src/structures/uik-shell-status-bar.d.ts +23 -4
- package/dist/src/structures/uik-shell-status-bar.d.ts.map +1 -1
- package/dist/src/structures/uik-shell-status-bar.js +105 -56
- package/dist/src/structures/uik-shell-status-bar.js.map +1 -1
- package/package.json +17 -4
package/README.md
CHANGED
|
@@ -9,21 +9,43 @@ Token-driven shell components (activity bar, sidebars, status bar, and an option
|
|
|
9
9
|
- Shell components expose only UI surface/state; business logic should live in the host app.
|
|
10
10
|
- **Contract**: Shell components use `ui-primitives` strictly via their public API (attributes/props). Visual styling comes from `--uik-*` custom properties (no framework utility classes).
|
|
11
11
|
|
|
12
|
+
## Landmarks & labels (Accessibility contract)
|
|
13
|
+
|
|
14
|
+
- `uik-shell-layout` renders a `role="region"` container; override its label via `aria-label` or `aria-labelledby` on the host.
|
|
15
|
+
- `uik-shell-activity-bar` renders an `<aside>` landmark and forwards `aria-label`/`aria-labelledby` to the internal nav rail; default label is "Activity bar".
|
|
16
|
+
- `uik-shell-sidebar` and `uik-shell-secondary-sidebar` render `<aside>` landmarks; default labels come from the `heading` or fall back to "Sidebar"/"Secondary sidebar".
|
|
17
|
+
- `uik-shell-status-bar` uses `role="status"` with `aria-live="polite"` for status messages.
|
|
18
|
+
- Provide a semantic `<main>` element in the `main-content` slot and label additional landmarks as needed in host markup.
|
|
19
|
+
|
|
20
|
+
## Focus + roving focus
|
|
21
|
+
|
|
22
|
+
- Shell navigation surfaces delegate roving focus to primitives (`uik-nav-rail`, `uik-tree-view`) and do not add competing keyboard handlers.
|
|
23
|
+
- Follow the Focus + Roving Focus contract in `@ismail-elkorchi/ui-primitives` when composing activity bars or navigation trees.
|
|
24
|
+
|
|
25
|
+
## Overlay close semantics
|
|
26
|
+
|
|
27
|
+
- Overlay-like shells emit close events with `detail.reason` aligned to primitives: `escape | outside | programmatic | toggle`.
|
|
28
|
+
- `uik-shell-secondary-sidebar` captures the previously focused element on open and restores focus on close (unless a `focus-return-target` is provided).
|
|
29
|
+
|
|
12
30
|
## Using the components
|
|
13
31
|
|
|
14
32
|
```ts
|
|
15
|
-
import {html} from
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import type {UikShellActivityBarItem} from
|
|
33
|
+
import { html } from "lit";
|
|
34
|
+
import "@ismail-elkorchi/ui-primitives/register";
|
|
35
|
+
import "@ismail-elkorchi/ui-shell/register";
|
|
36
|
+
import type { UikShellActivityBarItem } from "@ismail-elkorchi/ui-shell/activity-bar";
|
|
19
37
|
|
|
20
38
|
const activityItems: UikShellActivityBarItem[] = [
|
|
21
39
|
{
|
|
22
|
-
id:
|
|
23
|
-
label:
|
|
24
|
-
icon:
|
|
40
|
+
id: "explorer",
|
|
41
|
+
label: "Explorer",
|
|
42
|
+
icon: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "search",
|
|
46
|
+
label: "Search",
|
|
47
|
+
icon: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z",
|
|
25
48
|
},
|
|
26
|
-
{id: 'search', label: 'Search', icon: 'M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z'}
|
|
27
49
|
];
|
|
28
50
|
|
|
29
51
|
html`
|
|
@@ -31,8 +53,10 @@ html`
|
|
|
31
53
|
<uik-shell-activity-bar
|
|
32
54
|
slot="activity-bar"
|
|
33
55
|
.items=${activityItems}
|
|
34
|
-
.activeId=${
|
|
35
|
-
@activity-bar-select=${(e: CustomEvent<{id: string}>) =>
|
|
56
|
+
.activeId=${"explorer"}
|
|
57
|
+
@activity-bar-select=${(e: CustomEvent<{ id: string }>) =>
|
|
58
|
+
console.log(e.detail.id)}
|
|
59
|
+
>
|
|
36
60
|
</uik-shell-activity-bar>
|
|
37
61
|
<uik-shell-sidebar slot="primary-sidebar" heading="Explorer">
|
|
38
62
|
<uik-button slot="actions" variant="ghost" size="icon">…</uik-button>
|
|
@@ -40,23 +64,33 @@ html`
|
|
|
40
64
|
<!-- put your tree view or navigation here -->
|
|
41
65
|
</div>
|
|
42
66
|
</uik-shell-sidebar>
|
|
43
|
-
<main
|
|
67
|
+
<main
|
|
68
|
+
slot="main-content"
|
|
69
|
+
style="flex: 1 1 auto; min-height: var(--uik-space-0);"
|
|
70
|
+
>
|
|
44
71
|
Your editor or subviews
|
|
45
72
|
</main>
|
|
46
73
|
<uik-shell-secondary-sidebar
|
|
47
74
|
slot="secondary-sidebar"
|
|
48
75
|
.isOpen=${true}
|
|
49
76
|
heading="AI Assistant"
|
|
50
|
-
@secondary-sidebar-close=${() => console.log(
|
|
77
|
+
@secondary-sidebar-close=${() => console.log("close secondary")}
|
|
78
|
+
>
|
|
51
79
|
<p
|
|
52
80
|
style="
|
|
53
81
|
font-size: var(--uik-typography-font-size-2);
|
|
54
82
|
color: oklch(var(--uik-text-muted));
|
|
55
|
-
"
|
|
83
|
+
"
|
|
84
|
+
>
|
|
56
85
|
Auxiliary tools live here.
|
|
57
86
|
</p>
|
|
58
87
|
</uik-shell-secondary-sidebar>
|
|
59
|
-
<uik-shell-status-bar
|
|
88
|
+
<uik-shell-status-bar
|
|
89
|
+
slot="status-bar"
|
|
90
|
+
message="Ready"
|
|
91
|
+
tone="info"
|
|
92
|
+
meta="3 files selected"
|
|
93
|
+
></uik-shell-status-bar>
|
|
60
94
|
</uik-shell-layout>
|
|
61
95
|
`;
|
|
62
96
|
```
|
|
@@ -64,15 +98,15 @@ html`
|
|
|
64
98
|
### Component notes
|
|
65
99
|
|
|
66
100
|
- `uik-shell-layout`: named slots `activity-bar`, `primary-sidebar`, `main-content`, `secondary-sidebar`, `status-bar`.
|
|
67
|
-
- `uik-shell-activity-bar`: accepts `.items` (id/label/icon/path) and emits `activity-bar-select`; optional `footer` slot; roving focus
|
|
101
|
+
- `uik-shell-activity-bar`: accepts `.items` (id/label/icon/path) and emits `activity-bar-select`; optional `footer` slot; delegates roving focus to `uik-nav-rail` (set `aria-label` if you need a custom name).
|
|
68
102
|
- `uik-shell-sidebar`: `slot="actions"` for header actions, default slot for body, optional `slot="footer"`; `isBodyPadded`/`isBodyScrollable` toggle spacing + scroll.
|
|
69
|
-
- `uik-shell-secondary-sidebar`: controlled via `.isOpen`;
|
|
103
|
+
- `uik-shell-secondary-sidebar`: controlled via `.isOpen`; optional `focus-return-target` (selector or element) to restore focus on close; Escape and the close button emit `secondary-sidebar-close` (`detail.reason` is `escape | toggle`).
|
|
70
104
|
- `uik-shell-status-bar`: `.message` + `.tone` colorize the left side; `meta` string (outline badge) or `slot="meta"` for custom content; optional `slot="actions"`.
|
|
71
105
|
- Use `@ismail-elkorchi/ui-primitives/uik-nav` or `@ismail-elkorchi/ui-primitives/uik-tree-view` for sidebar navigation content.
|
|
72
106
|
|
|
73
107
|
### Custom properties
|
|
74
108
|
|
|
75
|
-
- Activity bar: `--uik-component-shell-activity-bar-bg`, `--uik-component-shell-activity-bar-fg`, `--uik-component-shell-activity-bar-width`.
|
|
109
|
+
- Activity bar: `--uik-component-shell-activity-bar-bg`, `--uik-component-shell-activity-bar-fg`, `--uik-component-shell-activity-bar-width`, `--uik-component-shell-activity-bar-item-size`, `--uik-component-shell-activity-bar-item-icon-size`, `--uik-component-shell-activity-bar-item-indicator-bg`, `--uik-component-shell-activity-bar-item-indicator-radius`, `--uik-component-shell-activity-bar-item-indicator-width`.
|
|
76
110
|
- Sidebar: `--uik-component-shell-sidebar-bg`, `--uik-component-shell-sidebar-fg`, `--uik-component-shell-sidebar-width`.
|
|
77
111
|
- Secondary sidebar: `--uik-component-shell-secondary-sidebar-bg`, `--uik-component-shell-secondary-sidebar-width`.
|
|
78
112
|
- Status bar: `--uik-component-shell-status-bar-bg`, `--uik-component-shell-status-bar-fg`, `--uik-component-shell-status-bar-height`.
|
|
@@ -83,7 +117,7 @@ html`
|
|
|
83
117
|
Load tokens once and set theme/density attributes on a shared container (often `:root`):
|
|
84
118
|
|
|
85
119
|
```css
|
|
86
|
-
@import
|
|
120
|
+
@import "@ismail-elkorchi/ui-tokens/index.css";
|
|
87
121
|
```
|
|
88
122
|
|
|
89
123
|
```html
|
|
@@ -92,38 +126,91 @@ Load tokens once and set theme/density attributes on a shared container (often `
|
|
|
92
126
|
</html>
|
|
93
127
|
```
|
|
94
128
|
|
|
129
|
+
## Command center
|
|
130
|
+
|
|
131
|
+
Wire a global command palette to app commands with `createUikCommandCenter`. It handles Ctrl/Cmd+K by default, manages open/close state, and keeps trigger ARIA attributes in sync.
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import type { UikCommandPalette } from "@ismail-elkorchi/ui-primitives";
|
|
135
|
+
import {
|
|
136
|
+
createUikCommandCenter,
|
|
137
|
+
type UikCommandCenterCommand,
|
|
138
|
+
} from "@ismail-elkorchi/ui-shell/command-center";
|
|
139
|
+
|
|
140
|
+
const palette = document.querySelector(
|
|
141
|
+
"uik-command-palette",
|
|
142
|
+
) as UikCommandPalette;
|
|
143
|
+
|
|
144
|
+
const commands: UikCommandCenterCommand[] = [
|
|
145
|
+
{
|
|
146
|
+
id: "docs-tokens",
|
|
147
|
+
label: "Tokens reference",
|
|
148
|
+
description: "Jump to the tokens docs.",
|
|
149
|
+
value: "docs/tokens",
|
|
150
|
+
},
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
const commandCenter = createUikCommandCenter({
|
|
154
|
+
palette,
|
|
155
|
+
commands,
|
|
156
|
+
onSelect: (command) => {
|
|
157
|
+
if (!command.value) return;
|
|
158
|
+
const [view, subview] = command.value.split("/");
|
|
159
|
+
console.log("Navigate", view, subview);
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
commandCenter.setOpenButton(document.querySelector("[data-command-trigger]"));
|
|
164
|
+
```
|
|
165
|
+
|
|
95
166
|
## Routing store
|
|
96
167
|
|
|
97
168
|
A tiny EventTarget-based router lives in `@ismail-elkorchi/ui-shell/router`. It is framework-light, keeps state in memory (no history), and is meant for desktop flows that only need named views and optional subviews.
|
|
98
169
|
|
|
99
170
|
```ts
|
|
100
|
-
import {
|
|
171
|
+
import {
|
|
172
|
+
createUikShellRouter,
|
|
173
|
+
UIK_SHELL_NAVIGATION_EVENT,
|
|
174
|
+
type UikShellNavigationDetail,
|
|
175
|
+
} from "@ismail-elkorchi/ui-shell/router";
|
|
101
176
|
|
|
102
177
|
const routes = [
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
|
|
178
|
+
{
|
|
179
|
+
id: "explorer",
|
|
180
|
+
label: "Explorer",
|
|
181
|
+
subviews: ["code", "prompt", "apply"],
|
|
182
|
+
defaultSubview: "code",
|
|
183
|
+
},
|
|
184
|
+
{ id: "search", label: "Search" },
|
|
185
|
+
{ id: "settings", label: "Settings" },
|
|
106
186
|
] as const;
|
|
107
187
|
|
|
108
|
-
export const shellRouter = createUikShellRouter({
|
|
188
|
+
export const shellRouter = createUikShellRouter({
|
|
189
|
+
routes,
|
|
190
|
+
initialView: "explorer",
|
|
191
|
+
initialSubview: "code",
|
|
192
|
+
});
|
|
109
193
|
|
|
110
194
|
// React to navigation anywhere in the app
|
|
111
|
-
const unsubscribe = shellRouter.subscribe(({view, subview}) => {
|
|
112
|
-
console.log(
|
|
195
|
+
const unsubscribe = shellRouter.subscribe(({ view, subview }) => {
|
|
196
|
+
console.log("Current location", view, subview);
|
|
113
197
|
});
|
|
114
198
|
|
|
115
199
|
// Wire Lit components through events
|
|
116
200
|
html`
|
|
117
201
|
<uik-shell-activity-bar
|
|
118
|
-
.items=${routes.map(r => ({id: r.id, label: r.label ?? r.id}))}
|
|
202
|
+
.items=${routes.map((r) => ({ id: r.id, label: r.label ?? r.id }))}
|
|
119
203
|
.activeId=${shellRouter.current.view}
|
|
120
|
-
@activity-bar-select=${(e: CustomEvent<{id: string}>) =>
|
|
204
|
+
@activity-bar-select=${(e: CustomEvent<{ id: string }>) =>
|
|
205
|
+
shellRouter.navigate(e.detail.id)}
|
|
206
|
+
>
|
|
121
207
|
</uik-shell-activity-bar>
|
|
122
208
|
|
|
123
209
|
<editor-area
|
|
124
|
-
.activeSubview=${shellRouter.current.subview ??
|
|
125
|
-
@subview-change=${(e: CustomEvent<{subview: string}>) =>
|
|
126
|
-
shellRouter.navigate(shellRouter.current.view, e.detail.subview)}
|
|
210
|
+
.activeSubview=${shellRouter.current.subview ?? "code"}
|
|
211
|
+
@subview-change=${(e: CustomEvent<{ subview: string }>) =>
|
|
212
|
+
shellRouter.navigate(shellRouter.current.view, e.detail.subview)}
|
|
213
|
+
>
|
|
127
214
|
</editor-area>
|
|
128
215
|
`;
|
|
129
216
|
|