@sentropic/design-system-svelte 0.34.48 → 0.34.50
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/dist/AppShell.svelte +284 -28
- package/dist/AppShell.svelte.d.ts +23 -3
- package/dist/AppShell.svelte.d.ts.map +1 -1
- package/dist/ContextPanel.svelte +86 -0
- package/dist/ContextPanel.svelte.d.ts +14 -0
- package/dist/ContextPanel.svelte.d.ts.map +1 -0
- package/dist/NavDrawer.svelte +46 -0
- package/dist/NavDrawer.svelte.d.ts +17 -0
- package/dist/NavDrawer.svelte.d.ts.map +1 -0
- package/dist/NavItem.svelte +266 -0
- package/dist/NavItem.svelte.d.ts +49 -0
- package/dist/NavItem.svelte.d.ts.map +1 -0
- package/dist/NavRail.svelte +147 -0
- package/dist/NavRail.svelte.d.ts +23 -0
- package/dist/NavRail.svelte.d.ts.map +1 -0
- package/dist/NavSection.svelte +152 -0
- package/dist/NavSection.svelte.d.ts +29 -0
- package/dist/NavSection.svelte.d.ts.map +1 -0
- package/dist/NavShell.svelte +218 -0
- package/dist/NavShell.svelte.d.ts +38 -0
- package/dist/NavShell.svelte.d.ts.map +1 -0
- package/dist/SelectableRow.svelte +16 -5
- package/dist/SelectableRow.svelte.d.ts +2 -0
- package/dist/SelectableRow.svelte.d.ts.map +1 -1
- package/dist/UtilityPanel.svelte +89 -0
- package/dist/UtilityPanel.svelte.d.ts +18 -0
- package/dist/UtilityPanel.svelte.d.ts.map +1 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/site-config.d.ts +3 -3
- package/dist/site-config.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/AppShell.svelte
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { SiteConfig } from "./site-config";
|
|
4
|
+
|
|
5
|
+
export type AppShellVariant = "site" | "workspace";
|
|
6
|
+
export type AppShellUtilityMode = "reserve" | "overlay" | "floating";
|
|
7
|
+
export type AppShellUtilitySide = "left" | "right" | "bottom";
|
|
8
|
+
|
|
9
|
+
export type AppShellProps = {
|
|
10
|
+
variant?: AppShellVariant;
|
|
11
|
+
config?: SiteConfig;
|
|
12
|
+
topChrome?: Snippet;
|
|
13
|
+
primaryRail?: Snippet;
|
|
14
|
+
navigationPanel?: Snippet;
|
|
15
|
+
main?: Snippet;
|
|
16
|
+
contextPanel?: Snippet;
|
|
17
|
+
utilityPanel?: Snippet;
|
|
18
|
+
bottomPanel?: Snippet;
|
|
19
|
+
children?: Snippet;
|
|
20
|
+
mainId?: string;
|
|
21
|
+
navigationLabel?: string;
|
|
22
|
+
contextLabel?: string;
|
|
23
|
+
utilityLabel?: string;
|
|
24
|
+
utilityMode?: AppShellUtilityMode;
|
|
25
|
+
utilitySide?: AppShellUtilitySide;
|
|
26
|
+
class?: string;
|
|
27
|
+
};
|
|
28
|
+
</script>
|
|
29
|
+
|
|
1
30
|
<script lang="ts">
|
|
2
31
|
// App-shell SVELTE : COMPOSE les vrais composants du design system — zéro contrôle
|
|
3
32
|
// bricolé. Triggers = DS Button / IconButton ; menus = DS MenuPopover + Menu ;
|
|
@@ -11,24 +40,45 @@
|
|
|
11
40
|
import Menu from "./Menu.svelte";
|
|
12
41
|
import { Boxes, ChevronDown, Globe, Moon, Palette, Search as SearchIcon, Sun } from "@lucide/svelte";
|
|
13
42
|
import IdentityButton from "./IdentityButton.svelte";
|
|
14
|
-
import type { SiteConfig } from "./site-config";
|
|
15
43
|
|
|
16
|
-
let {
|
|
44
|
+
let {
|
|
45
|
+
variant,
|
|
46
|
+
config,
|
|
47
|
+
topChrome,
|
|
48
|
+
primaryRail,
|
|
49
|
+
navigationPanel,
|
|
50
|
+
main,
|
|
51
|
+
contextPanel,
|
|
52
|
+
utilityPanel,
|
|
53
|
+
bottomPanel,
|
|
54
|
+
children,
|
|
55
|
+
mainId = "main",
|
|
56
|
+
navigationLabel = "Workspace navigation",
|
|
57
|
+
contextLabel = "Context panel",
|
|
58
|
+
utilityLabel = "Utility panel",
|
|
59
|
+
utilityMode = "reserve",
|
|
60
|
+
utilitySide = "right",
|
|
61
|
+
class: className
|
|
62
|
+
}: AppShellProps = $props();
|
|
17
63
|
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
64
|
+
const mode = $derived(variant ?? (config ? "site" : "workspace"));
|
|
65
|
+
const siteConfig = $derived(config ?? ({ brand: { name: "Sentropic" }, nav: [], theming: { themes: [], theme: "" } } as SiteConfig));
|
|
66
|
+
const brand = $derived(siteConfig.brand ?? { name: "Sentropic" });
|
|
67
|
+
const nav = $derived(Array.isArray(siteConfig.nav) ? siteConfig.nav : []);
|
|
68
|
+
const t = $derived(siteConfig.theming ?? { themes: [], theme: "" });
|
|
69
|
+
const siteClasses = $derived(["st-shell", className].filter(Boolean).join(" "));
|
|
70
|
+
const workspaceClasses = $derived(["st-appShell", "st-appShell--workspace", className].filter(Boolean).join(" "));
|
|
21
71
|
|
|
22
72
|
const isActive = (item: { href: string; active?: boolean }) =>
|
|
23
73
|
item.active != null
|
|
24
74
|
? item.active
|
|
25
|
-
:
|
|
26
|
-
(item.href ===
|
|
75
|
+
: siteConfig.activePath != null &&
|
|
76
|
+
(item.href === siteConfig.activePath || (item.href !== "/" && (siteConfig.activePath ?? "").startsWith(item.href)));
|
|
27
77
|
|
|
28
78
|
const themeItems = $derived((t.themes ?? []).map((o) => ({ label: o.label, value: o.id })));
|
|
29
|
-
const fwItems = $derived((
|
|
30
|
-
const localeItems = $derived((
|
|
31
|
-
const fwLabel = $derived((
|
|
79
|
+
const fwItems = $derived((siteConfig.frameworkSwitcher?.available ?? []).map((o) => ({ label: o.label, value: o.id })));
|
|
80
|
+
const localeItems = $derived((siteConfig.locale?.available ?? []).map((o) => ({ label: o.label, value: o.code })));
|
|
81
|
+
const fwLabel = $derived((siteConfig.frameworkSwitcher?.available ?? []).find((o) => o.id === siteConfig.frameworkSwitcher?.current)?.label ?? "");
|
|
32
82
|
const themeLabel = $derived((t.themes ?? []).find((o) => o.id === t.theme)?.label ?? "");
|
|
33
83
|
|
|
34
84
|
// Ancrage des menus (MenuPopover veut un HTMLElement) : on bind un span tight.
|
|
@@ -56,7 +106,7 @@
|
|
|
56
106
|
{/snippet}
|
|
57
107
|
|
|
58
108
|
{#snippet navigation()}
|
|
59
|
-
<nav class="st-shell__nav" aria-label={
|
|
109
|
+
<nav class="st-shell__nav" aria-label={siteConfig.navLabel ?? "Navigation"}>
|
|
60
110
|
{#each nav as item (item.href)}
|
|
61
111
|
<a class="st-shell__navLink" href={item.href} aria-current={isActive(item) ? "page" : undefined}>{item.label}</a>
|
|
62
112
|
{/each}
|
|
@@ -65,22 +115,22 @@
|
|
|
65
115
|
|
|
66
116
|
{#snippet actions()}
|
|
67
117
|
<div class="st-shell__actions">
|
|
68
|
-
{#if
|
|
69
|
-
<Button variant="secondary" size="sm" class="st-shell__search" onclick={() =>
|
|
118
|
+
{#if siteConfig.search?.enabled}
|
|
119
|
+
<Button variant="secondary" size="sm" class="st-shell__search" onclick={() => siteConfig.search?.onSearch?.("")}>
|
|
70
120
|
<SearchIcon size={16} strokeWidth={2.1} aria-hidden="true" />
|
|
71
|
-
<span>{
|
|
121
|
+
<span>{siteConfig.search.placeholder ?? "Rechercher…"}</span>
|
|
72
122
|
<kbd class="st-shell__kbd">/</kbd>
|
|
73
123
|
</Button>
|
|
74
124
|
{/if}
|
|
75
125
|
|
|
76
|
-
{#if
|
|
126
|
+
{#if siteConfig.frameworkSwitcher?.enabled}
|
|
77
127
|
<span class="st-shell__menuWrap" bind:this={fwEl}>
|
|
78
128
|
<Button variant="secondary" size="sm" class="st-shell__switch" onclick={() => (fwOpen = !fwOpen)} aria-haspopup="menu" aria-expanded={fwOpen}>
|
|
79
129
|
<Boxes size={14} aria-hidden="true" /><span>{fwLabel}</span><ChevronDown size={14} aria-hidden="true" />
|
|
80
130
|
</Button>
|
|
81
131
|
</span>
|
|
82
132
|
<MenuPopover bind:open={fwOpen} trigger={fwEl} placement="bottom-end" label="Framework">
|
|
83
|
-
<Menu label="Framework" items={fwItems} onselect={(v) => {
|
|
133
|
+
<Menu label="Framework" items={fwItems} onselect={(v) => { siteConfig.frameworkSwitcher?.onChange?.(v); fwOpen = false; }} />
|
|
84
134
|
</MenuPopover>
|
|
85
135
|
{/if}
|
|
86
136
|
|
|
@@ -101,32 +151,81 @@
|
|
|
101
151
|
</IconButton>
|
|
102
152
|
{/if}
|
|
103
153
|
|
|
104
|
-
{#if
|
|
154
|
+
{#if siteConfig.locale}
|
|
105
155
|
<span class="st-shell__menuWrap" bind:this={localeEl}>
|
|
106
156
|
<Button variant="secondary" size="sm" class="st-shell__switch" onclick={() => (localeOpen = !localeOpen)} aria-haspopup="menu" aria-expanded={localeOpen}>
|
|
107
|
-
<Globe size={14} aria-hidden="true" /><span>{(
|
|
157
|
+
<Globe size={14} aria-hidden="true" /><span>{(siteConfig.locale.current ?? "").toUpperCase()}</span><ChevronDown size={14} aria-hidden="true" />
|
|
108
158
|
</Button>
|
|
109
159
|
</span>
|
|
110
|
-
<MenuPopover bind:open={localeOpen} trigger={localeEl} placement="bottom-end" label={
|
|
111
|
-
<Menu label={
|
|
160
|
+
<MenuPopover bind:open={localeOpen} trigger={localeEl} placement="bottom-end" label={siteConfig.locale.label ?? "Langue"}>
|
|
161
|
+
<Menu label={siteConfig.locale.label ?? "Langue"} items={localeItems} onselect={(v) => { siteConfig.locale?.onChange?.(v); localeOpen = false; }} />
|
|
112
162
|
</MenuPopover>
|
|
113
163
|
{/if}
|
|
114
164
|
|
|
115
|
-
{#if
|
|
165
|
+
{#if siteConfig.identity}
|
|
116
166
|
<IdentityButton
|
|
117
167
|
mode="icon"
|
|
118
|
-
authState={
|
|
119
|
-
user={
|
|
120
|
-
signInLabel={
|
|
121
|
-
onSignIn={() =>
|
|
122
|
-
onSignOut={() =>
|
|
123
|
-
menu={
|
|
168
|
+
authState={siteConfig.identity.state}
|
|
169
|
+
user={siteConfig.identity.user ?? null}
|
|
170
|
+
signInLabel={siteConfig.identity.label ?? "Se connecter"}
|
|
171
|
+
onSignIn={() => siteConfig.identity?.onSignIn?.()}
|
|
172
|
+
onSignOut={() => siteConfig.identity?.onSignOut?.()}
|
|
173
|
+
menu={siteConfig.identity.menu ?? []}
|
|
124
174
|
/>
|
|
125
175
|
{/if}
|
|
126
176
|
</div>
|
|
127
177
|
{/snippet}
|
|
128
178
|
|
|
129
|
-
|
|
179
|
+
{#if mode === "workspace"}
|
|
180
|
+
<div
|
|
181
|
+
class={workspaceClasses}
|
|
182
|
+
data-st-app-shell-variant="workspace"
|
|
183
|
+
data-utility-mode={utilityMode}
|
|
184
|
+
data-utility-side={utilitySide}
|
|
185
|
+
>
|
|
186
|
+
{#if topChrome}
|
|
187
|
+
<div class="st-appShell__topChrome">
|
|
188
|
+
{@render topChrome()}
|
|
189
|
+
</div>
|
|
190
|
+
{/if}
|
|
191
|
+
<div class="st-appShell__body">
|
|
192
|
+
{#if primaryRail}
|
|
193
|
+
<aside class="st-appShell__primaryRail" aria-label="Primary rail">
|
|
194
|
+
{@render primaryRail()}
|
|
195
|
+
</aside>
|
|
196
|
+
{/if}
|
|
197
|
+
{#if navigationPanel}
|
|
198
|
+
<aside class="st-appShell__navigationPanel" aria-label={navigationLabel}>
|
|
199
|
+
{@render navigationPanel()}
|
|
200
|
+
</aside>
|
|
201
|
+
{/if}
|
|
202
|
+
<main class="st-appShell__main" id={mainId}>
|
|
203
|
+
{#if main}
|
|
204
|
+
{@render main()}
|
|
205
|
+
{:else if children}
|
|
206
|
+
{@render children()}
|
|
207
|
+
{/if}
|
|
208
|
+
</main>
|
|
209
|
+
{#if contextPanel}
|
|
210
|
+
<aside class="st-appShell__contextPanel" aria-label={contextLabel}>
|
|
211
|
+
{@render contextPanel()}
|
|
212
|
+
</aside>
|
|
213
|
+
{/if}
|
|
214
|
+
{#if utilityPanel}
|
|
215
|
+
<aside class="st-appShell__utilityPanel" aria-label={utilityLabel}>
|
|
216
|
+
{@render utilityPanel()}
|
|
217
|
+
</aside>
|
|
218
|
+
{/if}
|
|
219
|
+
</div>
|
|
220
|
+
{#if bottomPanel}
|
|
221
|
+
<section class="st-appShell__bottomPanel" aria-label="Workspace tools">
|
|
222
|
+
{@render bottomPanel()}
|
|
223
|
+
</section>
|
|
224
|
+
{/if}
|
|
225
|
+
</div>
|
|
226
|
+
{:else}
|
|
227
|
+
<Header class={siteClasses} label={siteConfig.brand?.label ?? "Navigation"} logo={logo} navigation={navigation} actions={actions} />
|
|
228
|
+
{/if}
|
|
130
229
|
|
|
131
230
|
<style>
|
|
132
231
|
/* Hauteur de barre alignée sur la référence docs (80px) : le Header DS lit
|
|
@@ -164,4 +263,161 @@
|
|
|
164
263
|
.st-shell__actions { display: flex; align-items: center; gap: var(--st-spacing-2, 0.5rem); }
|
|
165
264
|
.st-shell__menuWrap { display: inline-flex; }
|
|
166
265
|
.st-shell__kbd { border: 1px solid var(--st-semantic-border-subtle); border-radius: 0.25rem; font-size: 0.6875rem; padding: 0 0.3rem; color: var(--st-semantic-text-secondary); }
|
|
266
|
+
|
|
267
|
+
.st-appShell {
|
|
268
|
+
--st-appShell-rail-width: var(--st-component-appShell-railWidth, 4.5rem);
|
|
269
|
+
--st-appShell-navigation-width: var(--st-component-appShell-navigationWidth, 20rem);
|
|
270
|
+
--st-appShell-context-width: var(--st-component-appShell-contextWidth, 22rem);
|
|
271
|
+
--st-appShell-utility-width: var(--st-component-appShell-utilityWidth, 24rem);
|
|
272
|
+
background: var(--st-component-appShell-background, var(--st-semantic-surface-default));
|
|
273
|
+
color: var(--st-semantic-text-primary);
|
|
274
|
+
display: grid;
|
|
275
|
+
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
276
|
+
min-block-size: 100%;
|
|
277
|
+
position: relative;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.st-appShell__topChrome {
|
|
281
|
+
border-block-end: 1px solid var(--st-component-appShell-border, var(--st-semantic-border-subtle));
|
|
282
|
+
min-inline-size: 0;
|
|
283
|
+
z-index: var(--st-component-appShell-top-zIndex, 30);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.st-appShell__body {
|
|
287
|
+
display: grid;
|
|
288
|
+
grid-template-columns:
|
|
289
|
+
minmax(0, auto)
|
|
290
|
+
minmax(0, auto)
|
|
291
|
+
minmax(0, 1fr)
|
|
292
|
+
minmax(0, auto)
|
|
293
|
+
minmax(0, auto);
|
|
294
|
+
min-block-size: 0;
|
|
295
|
+
min-inline-size: 0;
|
|
296
|
+
position: relative;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.st-appShell__primaryRail {
|
|
300
|
+
inline-size: var(--st-appShell-rail-width);
|
|
301
|
+
order: 10;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.st-appShell__navigationPanel {
|
|
305
|
+
inline-size: var(--st-appShell-navigation-width);
|
|
306
|
+
order: 20;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.st-appShell__contextPanel {
|
|
310
|
+
inline-size: var(--st-appShell-context-width);
|
|
311
|
+
order: 40;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.st-appShell__utilityPanel {
|
|
315
|
+
inline-size: var(--st-appShell-utility-width);
|
|
316
|
+
order: 50;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.st-appShell__main {
|
|
320
|
+
order: 30;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.st-appShell__primaryRail,
|
|
324
|
+
.st-appShell__navigationPanel,
|
|
325
|
+
.st-appShell__contextPanel,
|
|
326
|
+
.st-appShell__utilityPanel {
|
|
327
|
+
background: var(--st-component-appShell-panelSurface, var(--st-semantic-surface-raised));
|
|
328
|
+
border-color: var(--st-component-appShell-border, var(--st-semantic-border-subtle));
|
|
329
|
+
min-block-size: 0;
|
|
330
|
+
min-inline-size: 0;
|
|
331
|
+
overflow: hidden;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.st-appShell__primaryRail,
|
|
335
|
+
.st-appShell__navigationPanel {
|
|
336
|
+
border-inline-end-style: solid;
|
|
337
|
+
border-inline-end-width: 1px;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.st-appShell__contextPanel,
|
|
341
|
+
.st-appShell__utilityPanel {
|
|
342
|
+
border-inline-start-style: solid;
|
|
343
|
+
border-inline-start-width: 1px;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.st-appShell[data-utility-side="left"] .st-appShell__utilityPanel {
|
|
347
|
+
border-inline-end-style: solid;
|
|
348
|
+
border-inline-end-width: 1px;
|
|
349
|
+
border-inline-start-width: 0;
|
|
350
|
+
order: 25;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.st-appShell[data-utility-side="bottom"] .st-appShell__utilityPanel {
|
|
354
|
+
border-block-start: 1px solid var(--st-component-appShell-border, var(--st-semantic-border-subtle));
|
|
355
|
+
border-inline-start-width: 0;
|
|
356
|
+
grid-column: 1 / -1;
|
|
357
|
+
inline-size: auto;
|
|
358
|
+
order: 60;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.st-appShell__main {
|
|
362
|
+
min-block-size: 0;
|
|
363
|
+
min-inline-size: 0;
|
|
364
|
+
overflow: auto;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.st-appShell__bottomPanel {
|
|
368
|
+
background: var(--st-component-appShell-panelSurface, var(--st-semantic-surface-raised));
|
|
369
|
+
border-block-start: 1px solid var(--st-component-appShell-border, var(--st-semantic-border-subtle));
|
|
370
|
+
min-block-size: 0;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.st-appShell[data-utility-mode="overlay"] .st-appShell__utilityPanel,
|
|
374
|
+
.st-appShell[data-utility-mode="floating"] .st-appShell__utilityPanel {
|
|
375
|
+
box-shadow: var(--st-component-appShell-utilityShadow, 0 18px 45px rgb(15 23 42 / 0.18));
|
|
376
|
+
max-block-size: 100%;
|
|
377
|
+
position: absolute;
|
|
378
|
+
z-index: var(--st-component-appShell-utility-zIndex, 40);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.st-appShell[data-utility-mode="overlay"][data-utility-side="right"] .st-appShell__utilityPanel,
|
|
382
|
+
.st-appShell[data-utility-mode="floating"][data-utility-side="right"] .st-appShell__utilityPanel {
|
|
383
|
+
inset-block: 0;
|
|
384
|
+
inset-inline-end: 0;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.st-appShell[data-utility-mode="overlay"][data-utility-side="left"] .st-appShell__utilityPanel,
|
|
388
|
+
.st-appShell[data-utility-mode="floating"][data-utility-side="left"] .st-appShell__utilityPanel {
|
|
389
|
+
inset-block: 0;
|
|
390
|
+
inset-inline-start: 0;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.st-appShell[data-utility-mode="overlay"][data-utility-side="bottom"] .st-appShell__utilityPanel,
|
|
394
|
+
.st-appShell[data-utility-mode="floating"][data-utility-side="bottom"] .st-appShell__utilityPanel {
|
|
395
|
+
block-size: var(--st-component-appShell-utilityBottomHeight, min(40%, 20rem));
|
|
396
|
+
inline-size: auto;
|
|
397
|
+
inset-block-end: 0;
|
|
398
|
+
inset-inline: 0;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.st-appShell[data-utility-mode="floating"] .st-appShell__utilityPanel {
|
|
402
|
+
border: 1px solid var(--st-component-appShell-border, var(--st-semantic-border-subtle));
|
|
403
|
+
border-radius: var(--st-radius-lg, 0.75rem);
|
|
404
|
+
margin: var(--st-spacing-4, 1rem);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
@media (max-width: 48rem) {
|
|
408
|
+
.st-appShell__body {
|
|
409
|
+
display: flex;
|
|
410
|
+
flex-direction: column;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.st-appShell__primaryRail,
|
|
414
|
+
.st-appShell__navigationPanel,
|
|
415
|
+
.st-appShell__contextPanel,
|
|
416
|
+
.st-appShell__utilityPanel {
|
|
417
|
+
border-inline: 0;
|
|
418
|
+
border-block-end: 1px solid var(--st-component-appShell-border, var(--st-semantic-border-subtle));
|
|
419
|
+
inline-size: auto;
|
|
420
|
+
max-block-size: min(60vh, 28rem);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
167
423
|
</style>
|
|
@@ -1,8 +1,28 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
1
2
|
import type { SiteConfig } from "./site-config";
|
|
2
|
-
type
|
|
3
|
-
|
|
3
|
+
export type AppShellVariant = "site" | "workspace";
|
|
4
|
+
export type AppShellUtilityMode = "reserve" | "overlay" | "floating";
|
|
5
|
+
export type AppShellUtilitySide = "left" | "right" | "bottom";
|
|
6
|
+
export type AppShellProps = {
|
|
7
|
+
variant?: AppShellVariant;
|
|
8
|
+
config?: SiteConfig;
|
|
9
|
+
topChrome?: Snippet;
|
|
10
|
+
primaryRail?: Snippet;
|
|
11
|
+
navigationPanel?: Snippet;
|
|
12
|
+
main?: Snippet;
|
|
13
|
+
contextPanel?: Snippet;
|
|
14
|
+
utilityPanel?: Snippet;
|
|
15
|
+
bottomPanel?: Snippet;
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
mainId?: string;
|
|
18
|
+
navigationLabel?: string;
|
|
19
|
+
contextLabel?: string;
|
|
20
|
+
utilityLabel?: string;
|
|
21
|
+
utilityMode?: AppShellUtilityMode;
|
|
22
|
+
utilitySide?: AppShellUtilitySide;
|
|
23
|
+
class?: string;
|
|
4
24
|
};
|
|
5
|
-
declare const AppShell: import("svelte").Component
|
|
25
|
+
declare const AppShell: import("svelte").Component<AppShellProps, {}, "">;
|
|
6
26
|
type AppShell = ReturnType<typeof AppShell>;
|
|
7
27
|
export default AppShell;
|
|
8
28
|
//# sourceMappingURL=AppShell.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.svelte.d.ts","sourceRoot":"","sources":["../src/lib/AppShell.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AppShell.svelte.d.ts","sourceRoot":"","sources":["../src/lib/AppShell.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,WAAW,CAAC;AACnD,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AACrE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9D,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAiNJ,QAAA,MAAM,QAAQ,mDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
|
|
4
|
+
export interface ContextPanelProps {
|
|
5
|
+
title?: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
actions?: Snippet;
|
|
9
|
+
footer?: Snippet;
|
|
10
|
+
children?: Snippet;
|
|
11
|
+
class?: string;
|
|
12
|
+
}
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<script lang="ts">
|
|
16
|
+
let { title, subtitle, label, actions, footer, children, class: className }: ContextPanelProps = $props();
|
|
17
|
+
const classes = $derived(["st-contextPanel", className].filter(Boolean).join(" "));
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<aside class={classes} aria-label={label ?? title ?? "Context panel"}>
|
|
21
|
+
{#if title || subtitle || actions}
|
|
22
|
+
<header class="st-contextPanel__header">
|
|
23
|
+
<div class="st-contextPanel__heading">
|
|
24
|
+
{#if title}<h2 class="st-contextPanel__title">{title}</h2>{/if}
|
|
25
|
+
{#if subtitle}<p class="st-contextPanel__subtitle">{subtitle}</p>{/if}
|
|
26
|
+
</div>
|
|
27
|
+
{#if actions}<div class="st-contextPanel__actions">{@render actions()}</div>{/if}
|
|
28
|
+
</header>
|
|
29
|
+
{/if}
|
|
30
|
+
<div class="st-contextPanel__body">{@render children?.()}</div>
|
|
31
|
+
{#if footer}<footer class="st-contextPanel__footer">{@render footer()}</footer>{/if}
|
|
32
|
+
</aside>
|
|
33
|
+
|
|
34
|
+
<style>
|
|
35
|
+
.st-contextPanel {
|
|
36
|
+
background: var(--st-component-contextPanel-surface, var(--st-semantic-surface-raised));
|
|
37
|
+
color: var(--st-semantic-text-primary);
|
|
38
|
+
display: grid;
|
|
39
|
+
grid-template-rows: auto 1fr auto;
|
|
40
|
+
block-size: 100%;
|
|
41
|
+
min-block-size: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.st-contextPanel__header,
|
|
45
|
+
.st-contextPanel__footer {
|
|
46
|
+
border-color: var(--st-component-contextPanel-border, var(--st-semantic-border-subtle));
|
|
47
|
+
padding: var(--st-spacing-4, 1rem);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.st-contextPanel__header {
|
|
51
|
+
align-items: start;
|
|
52
|
+
border-block-end-style: solid;
|
|
53
|
+
border-block-end-width: 1px;
|
|
54
|
+
display: flex;
|
|
55
|
+
gap: var(--st-spacing-3, 0.75rem);
|
|
56
|
+
justify-content: space-between;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.st-contextPanel__footer {
|
|
60
|
+
border-block-start-style: solid;
|
|
61
|
+
border-block-start-width: 1px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.st-contextPanel__title,
|
|
65
|
+
.st-contextPanel__subtitle {
|
|
66
|
+
margin: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.st-contextPanel__title {
|
|
70
|
+
font-size: 1rem;
|
|
71
|
+
line-height: 1.3;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.st-contextPanel__subtitle {
|
|
75
|
+
color: var(--st-semantic-text-secondary);
|
|
76
|
+
font-size: 0.8125rem;
|
|
77
|
+
line-height: 1.4;
|
|
78
|
+
margin-block-start: var(--st-spacing-1, 0.25rem);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.st-contextPanel__body {
|
|
82
|
+
min-block-size: 0;
|
|
83
|
+
overflow: auto;
|
|
84
|
+
padding: var(--st-spacing-4, 1rem);
|
|
85
|
+
}
|
|
86
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
export interface ContextPanelProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
subtitle?: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
actions?: Snippet;
|
|
7
|
+
footer?: Snippet;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const ContextPanel: import("svelte").Component<ContextPanelProps, {}, "">;
|
|
12
|
+
type ContextPanel = ReturnType<typeof ContextPanel>;
|
|
13
|
+
export default ContextPanel;
|
|
14
|
+
//# sourceMappingURL=ContextPanel.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextPanel.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ContextPanel.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2BH,QAAA,MAAM,YAAY,uDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { NavShellSide } from "./NavShell.svelte";
|
|
4
|
+
|
|
5
|
+
export interface NavDrawerProps {
|
|
6
|
+
title?: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
search?: Snippet;
|
|
10
|
+
footer?: Snippet;
|
|
11
|
+
children: Snippet;
|
|
12
|
+
open?: boolean;
|
|
13
|
+
side?: NavShellSide;
|
|
14
|
+
class?: string;
|
|
15
|
+
}
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<script lang="ts">
|
|
19
|
+
import NavShell from "./NavShell.svelte";
|
|
20
|
+
|
|
21
|
+
let {
|
|
22
|
+
title,
|
|
23
|
+
subtitle,
|
|
24
|
+
label,
|
|
25
|
+
search,
|
|
26
|
+
footer,
|
|
27
|
+
children,
|
|
28
|
+
open = $bindable(false),
|
|
29
|
+
side = "left",
|
|
30
|
+
class: className
|
|
31
|
+
}: NavDrawerProps = $props();
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<NavShell
|
|
35
|
+
bind:open
|
|
36
|
+
variant="drawer"
|
|
37
|
+
{title}
|
|
38
|
+
{subtitle}
|
|
39
|
+
{label}
|
|
40
|
+
{search}
|
|
41
|
+
{footer}
|
|
42
|
+
{side}
|
|
43
|
+
class={["st-navDrawer", className].filter(Boolean).join(" ")}
|
|
44
|
+
>
|
|
45
|
+
{@render children()}
|
|
46
|
+
</NavShell>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { NavShellSide } from "./NavShell.svelte";
|
|
3
|
+
export interface NavDrawerProps {
|
|
4
|
+
title?: string;
|
|
5
|
+
subtitle?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
search?: Snippet;
|
|
8
|
+
footer?: Snippet;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
open?: boolean;
|
|
11
|
+
side?: NavShellSide;
|
|
12
|
+
class?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const NavDrawer: import("svelte").Component<NavDrawerProps, {}, "open">;
|
|
15
|
+
type NavDrawer = ReturnType<typeof NavDrawer>;
|
|
16
|
+
export default NavDrawer;
|
|
17
|
+
//# sourceMappingURL=NavDrawer.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavDrawer.svelte.d.ts","sourceRoot":"","sources":["../src/lib/NavDrawer.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA6BH,QAAA,MAAM,SAAS,wDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|