@happyvertical/smrt-svelte 0.55.16 → 0.55.18
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 +5 -3
- package/agents/cookbook-shell.md +7 -1
- package/agents/overview-surfaces.md +5 -0
- package/agents/workspace.md +155 -11
- package/dist/browser-ai/svelte/components/DownloadProgress.svelte +22 -19
- package/dist/browser-ai/svelte/components/ModelStatusControl.svelte +16 -13
- package/dist/browser-ai/svelte/components/STTTest.svelte +41 -38
- package/dist/browser-ai/svelte/components/VoiceInput.svelte +17 -14
- package/dist/components/activity/ActivityList.svelte +1 -1
- package/dist/components/app/AppShell.svelte +279 -14
- package/dist/components/app/AppShell.svelte.d.ts +63 -2
- package/dist/components/app/AppShell.svelte.d.ts.map +1 -1
- package/dist/components/app/DockToggles.svelte +53 -11
- package/dist/components/app/DockToggles.svelte.d.ts.map +1 -1
- package/dist/components/app/OwnerSetupForm.svelte +98 -34
- package/dist/components/app/OwnerSetupForm.svelte.d.ts +4 -0
- package/dist/components/app/OwnerSetupForm.svelte.d.ts.map +1 -1
- package/dist/components/app/PhoneTabBar.svelte +136 -0
- package/dist/components/app/PhoneTabBar.svelte.d.ts +22 -0
- package/dist/components/app/PhoneTabBar.svelte.d.ts.map +1 -0
- package/dist/components/app/ShellSettingsPage.svelte +17 -2
- package/dist/components/app/ShellSettingsPage.svelte.d.ts +11 -16
- package/dist/components/app/ShellSettingsPage.svelte.d.ts.map +1 -1
- package/dist/components/app/dock-toggle.d.ts +3 -2
- package/dist/components/app/dock-toggle.d.ts.map +1 -1
- package/dist/components/app/index.d.ts +2 -1
- package/dist/components/app/index.d.ts.map +1 -1
- package/dist/components/app/index.js +1 -0
- package/dist/components/app/owner-setup-types.d.ts +5 -0
- package/dist/components/app/owner-setup-types.d.ts.map +1 -1
- package/dist/components/app/phone-tabs.d.ts +41 -0
- package/dist/components/app/phone-tabs.d.ts.map +1 -0
- package/dist/components/app/phone-tabs.js +66 -0
- package/dist/components/app/slot-item.d.ts +16 -0
- package/dist/components/app/slot-item.d.ts.map +1 -1
- package/dist/components/app/view-transition.d.ts +43 -0
- package/dist/components/app/view-transition.d.ts.map +1 -0
- package/dist/components/app/view-transition.js +76 -0
- package/dist/components/audit/AuditList.svelte +4 -1
- package/dist/components/audit/RecordHistory.svelte +4 -1
- package/dist/components/board/Board.svelte +4 -1
- package/dist/components/command-palette/CommandPalette.svelte +4 -1
- package/dist/components/command-palette/CommandPalette.svelte.d.ts +2 -0
- package/dist/components/command-palette/CommandPalette.svelte.d.ts.map +1 -1
- package/dist/components/command-palette/CommandPaletteDialog.svelte +3 -0
- package/dist/components/command-palette/CommandPaletteTrigger.svelte +3 -0
- package/dist/components/cookbook/CookbookApp.svelte +2 -1
- package/dist/components/cookbook/CookbookApp.svelte.d.ts.map +1 -1
- package/dist/components/cookbook/CookbookSectionPage.svelte +4 -1
- package/dist/components/cookbook/brand-theme.d.ts.map +1 -1
- package/dist/components/cookbook/brand-theme.js +21 -2
- package/dist/components/cookbook/build.js +1 -1
- package/dist/components/cookbook/theme.d.ts.map +1 -1
- package/dist/components/cookbook/theme.js +9 -5
- package/dist/components/cookbook/types.d.ts +5 -1
- package/dist/components/cookbook/types.d.ts.map +1 -1
- package/dist/components/forms/AddressInput.svelte +25 -22
- package/dist/components/forms/CheckboxInput.svelte +8 -5
- package/dist/components/forms/DateRangeInput.svelte +41 -38
- package/dist/components/forms/DateTimeInput.svelte +29 -26
- package/dist/components/forms/FileUpload.svelte +24 -21
- package/dist/components/forms/Form.svelte +34 -31
- package/dist/components/forms/FormMicButton.svelte +10 -7
- package/dist/components/forms/FormScope.svelte +4 -1
- package/dist/components/forms/MeasurementInput.svelte +26 -23
- package/dist/components/forms/MoneyInput.svelte +18 -15
- package/dist/components/forms/NumberInput.svelte +17 -14
- package/dist/components/forms/PhoneInput.svelte +37 -34
- package/dist/components/forms/SearchInput.svelte +16 -13
- package/dist/components/forms/SelectInput.svelte +17 -14
- package/dist/components/forms/TextInput.svelte +19 -16
- package/dist/components/forms/TextareaInput.svelte +21 -18
- package/dist/components/import-export/ImportExport.svelte +4 -1
- package/dist/components/module/ModulePanel.svelte +14 -11
- package/dist/components/notifications/NotificationBell.svelte +4 -1
- package/dist/components/overview/OverviewAssistantUndo.svelte +4 -1
- package/dist/components/overview/OverviewGrid.svelte +11 -6
- package/dist/components/overview/OverviewGrid.svelte.d.ts.map +1 -1
- package/dist/components/overview/WidgetOptionsForm.svelte +3 -0
- package/dist/components/overview/widgets/ChartWidget.svelte +7 -4
- package/dist/components/overview/widgets/MetricWidget.svelte +5 -2
- package/dist/components/overview/widgets/NoteWidget.svelte +5 -2
- package/dist/components/overview/widgets/RecordListWidget.svelte +6 -3
- package/dist/components/overview/widgets/ShortcutsWidget.svelte +12 -6
- package/dist/components/overview/widgets/ShortcutsWidget.svelte.d.ts.map +1 -1
- package/dist/components/screens/DetailScreen.svelte +6 -3
- package/dist/components/screens/EditForm.svelte +6 -3
- package/dist/components/screens/ListScreen.svelte +4 -1
- package/dist/components/screens/RecipeScreens.svelte +1 -1
- package/dist/components/settings/SettingsCatalog.svelte +4 -1
- package/dist/components/sortable/Sortable.svelte +11 -5
- package/dist/components/sortable/Sortable.svelte.d.ts.map +1 -1
- package/dist/components/workspace/Breadcrumbs.svelte +4 -1
- package/dist/components/workspace/NavTree.svelte +4 -1
- package/dist/components/workspace/RoleShell.svelte +4 -1
- package/dist/components/workspace/WorkspaceShell.svelte +43 -40
- package/dist/components/workspace/admin-shell/ActivityItem.svelte +4 -1
- package/dist/components/workspace/admin-shell/ActivityList.svelte +5 -2
- package/dist/components/workspace/admin-shell/ActivityTicker.svelte +6 -3
- package/dist/components/workspace/admin-shell/ActivityToasts.svelte +9 -4
- package/dist/components/workspace/admin-shell/AdminShell.svelte +642 -126
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts +7 -1
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/AppScopePanel.svelte +4 -1
- package/dist/components/workspace/admin-shell/HotkeyInput.svelte +4 -1
- package/dist/components/workspace/admin-shell/PhoneBottomBar.svelte +58 -14
- package/dist/components/workspace/admin-shell/PhoneBottomBar.svelte.d.ts +9 -2
- package/dist/components/workspace/admin-shell/PhoneBottomBar.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/PhoneTopBar.svelte +15 -6
- package/dist/components/workspace/admin-shell/ShellBrand.svelte +3 -0
- package/dist/components/workspace/admin-shell/ShellCorner.svelte +4 -1
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte +11 -7
- package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte +6 -3
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte +19 -13
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts +1 -1
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellNavToggle.svelte +8 -5
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte +4 -1
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte +24 -17
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte +236 -48
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte.d.ts +11 -1
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellTitle.svelte +4 -1
- package/dist/components/workspace/admin-shell/ShortcutsOverlay.svelte +4 -1
- package/dist/components/workspace/admin-shell/SystemScopePanel.svelte +4 -1
- package/dist/components/workspace/admin-shell/SystemStatusChips.svelte +5 -2
- package/dist/components/workspace/admin-shell/TenantNav.svelte +112 -43
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts +4 -3
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte +322 -55
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte.d.ts +15 -2
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/motion.d.ts +19 -0
- package/dist/components/workspace/admin-shell/motion.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/motion.js +44 -0
- package/dist/components/workspace/admin-shell/settings.d.ts +1 -0
- package/dist/components/workspace/admin-shell/settings.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/settings.js +1 -1
- package/dist/components/workspace/admin-shell/shell-icons.d.ts +8 -0
- package/dist/components/workspace/admin-shell/shell-icons.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/shell-icons.js +8 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts +6 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/state.svelte.js +15 -0
- package/dist/components/workspace/admin-shell/types.d.ts +13 -3
- package/dist/components/workspace/admin-shell/types.d.ts.map +1 -1
- package/dist/components/workspace/tools-dock/ToolsDock.svelte +41 -38
- package/dist/i18n/strings.workspace.d.ts +37 -0
- package/dist/i18n/strings.workspace.d.ts.map +1 -1
- package/dist/i18n/strings.workspace.js +42 -2
- package/dist/mcp-apps/McpAppsBridge.svelte +4 -1
- package/package.json +14 -14
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import {
|
|
3
3
|
type ColorScheme,
|
|
4
|
+
ColorSchemeToggle,
|
|
4
5
|
type ThemePreset,
|
|
5
6
|
ThemeProvider,
|
|
6
7
|
} from '@happyvertical/smrt-ui/themes';
|
|
@@ -15,6 +16,7 @@ import { M } from '../../i18n/strings.workspace.js';
|
|
|
15
16
|
import Provider from '../../Provider.svelte';
|
|
16
17
|
import type { User } from '../../state/app-state.js';
|
|
17
18
|
import type { WebMcpProviderConfig } from '../../web/webmcp-provider.js';
|
|
19
|
+
import CommandPalette from '../command-palette/CommandPalette.svelte';
|
|
18
20
|
import { formatSortableAnnouncement } from '../sortable/announce.js';
|
|
19
21
|
import { createSortable } from '../sortable/controller.svelte.js';
|
|
20
22
|
import AdminShell from '../workspace/admin-shell/AdminShell.svelte';
|
|
@@ -57,11 +59,23 @@ import {
|
|
|
57
59
|
type ShellPanelDefaults,
|
|
58
60
|
type ShellSectionActionsContext,
|
|
59
61
|
} from '../workspace/admin-shell/types.js';
|
|
62
|
+
import WorkspaceAccountMenu from '../workspace/admin-shell/WorkspaceAccountMenu.svelte';
|
|
60
63
|
import DockSlot from './DockSlot.svelte';
|
|
61
64
|
import DockToggles from './DockToggles.svelte';
|
|
62
65
|
import type { DockToggle } from './dock-toggle.js';
|
|
66
|
+
import PhoneTabBar from './PhoneTabBar.svelte';
|
|
67
|
+
import {
|
|
68
|
+
type PhoneTabBarOptions,
|
|
69
|
+
phoneTabNavEntries,
|
|
70
|
+
resolvePhoneTabBar,
|
|
71
|
+
} from './phone-tabs.js';
|
|
63
72
|
import RuntimeDiagnosticsWebMcp from './RuntimeDiagnosticsWebMcp.svelte';
|
|
64
|
-
import type {
|
|
73
|
+
import type {
|
|
74
|
+
AppShellAccountMenu,
|
|
75
|
+
AppShellCommandPalette,
|
|
76
|
+
ShellSlotItem,
|
|
77
|
+
} from './slot-item.js';
|
|
78
|
+
import { runViewTransition } from './view-transition.js';
|
|
65
79
|
|
|
66
80
|
interface Props {
|
|
67
81
|
/** Application name shown in the shell brand and app panel. */
|
|
@@ -88,6 +102,38 @@ interface Props {
|
|
|
88
102
|
environment?: string;
|
|
89
103
|
/** When set, the app panel links here (e.g. a settings route). */
|
|
90
104
|
settingsHref?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The signed-in user's account menu: the built-in item `item:account`
|
|
107
|
+
* (shown when `user` is set). Default slot `leftSidebar.footer`: the full
|
|
108
|
+
* identity in the expanded sidebar footer, the avatar alone at the bottom of
|
|
109
|
+
* the collapsed rail; on phones the avatar sits at the end of the header
|
|
110
|
+
* band. Menu: name and email, Settings (`settingsHref`) and Sign out
|
|
111
|
+
* (`onSignOut` or `signOutHref`). `false` opts out; `{ slot }` overrides the
|
|
112
|
+
* default slot (users can still move it in the layout editor).
|
|
113
|
+
*/
|
|
114
|
+
accountMenu?: AppShellAccountMenu;
|
|
115
|
+
/** Called when the account menu's Sign out is chosen (wins over `signOutHref`). */
|
|
116
|
+
onSignOut?: () => void;
|
|
117
|
+
/**
|
|
118
|
+
* Where the account menu's Sign out link goes when there is no `onSignOut`.
|
|
119
|
+
* A link is a GET: never point it at the runtime's POST-only `/sign-out`
|
|
120
|
+
* route; pass `onSignOut` for that.
|
|
121
|
+
*/
|
|
122
|
+
signOutHref?: string;
|
|
123
|
+
/**
|
|
124
|
+
* The theme switcher (`ColorSchemeToggle` from `smrt-ui/themes`) as the
|
|
125
|
+
* built-in item `item:color-scheme`, default slot `header.end`. On by
|
|
126
|
+
* default; `false` opts out, `{ slot }` sets the default slot. Icon-only on
|
|
127
|
+
* phones.
|
|
128
|
+
*/
|
|
129
|
+
colorSchemeToggle?: boolean | { slot?: ShellSlot };
|
|
130
|
+
/**
|
|
131
|
+
* The command palette as the built-in item `item:command-palette` (default
|
|
132
|
+
* slot `header.center`): a search-shaped trigger with the shortcut hint, a
|
|
133
|
+
* search icon button on phones. Mounts the existing `CommandPalette`
|
|
134
|
+
* (trigger, dialog and global shortcut). Off unless given.
|
|
135
|
+
*/
|
|
136
|
+
commandPalette?: AppShellCommandPalette;
|
|
91
137
|
/** Options for the Provider's WebMCP integration; passed through unchanged. */
|
|
92
138
|
webmcp?: boolean | WebMcpProviderConfig;
|
|
93
139
|
/** Authenticated user forwarded to the Provider; `null` renders the shell signed out. */
|
|
@@ -177,7 +223,7 @@ interface Props {
|
|
|
177
223
|
* mode the sidebar edits sections (grip, rename, hide, icon); entries are
|
|
178
224
|
* edited on the section page.
|
|
179
225
|
*/
|
|
180
|
-
navMode?: 'items' | 'sections';
|
|
226
|
+
navMode?: 'items' | 'sections' | 'sections-with-items';
|
|
181
227
|
/** Section page for groups without an `href` (e.g. user-created ones). */
|
|
182
228
|
sectionHref?: (sectionId: string) => string | undefined;
|
|
183
229
|
/** Renders host icon names for sections and entries. */
|
|
@@ -190,6 +236,32 @@ interface Props {
|
|
|
190
236
|
edgeToggles?: AdminShellProps['edgeToggles'];
|
|
191
237
|
/** Keyboard shortcuts; default follows `edgeToggles` (see `AdminShell`). */
|
|
192
238
|
hotkeys?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Phone bottom tab bar (default `false`): on phones, the footer region's
|
|
241
|
+
* phone presentation (conceptually the footer's center slot) shows the first
|
|
242
|
+
* N navigation items as icon + label tabs (`aria-current` from
|
|
243
|
+
* `currentHref`), then a tab for the first `dockToggles` entry (or a "Tools"
|
|
244
|
+
* tab when the right edge has tools), then "More" opening the left drawer
|
|
245
|
+
* when navigation overflows. `N` defaults to 4 and counts the dock tab;
|
|
246
|
+
* `{ items }` overrides it. While on, the header "Tools" opener and the
|
|
247
|
+
* header copy of the dock tab's toggle are not rendered on phones. Read once
|
|
248
|
+
* at mount, like `config`.
|
|
249
|
+
*/
|
|
250
|
+
phoneTabBar?: boolean | PhoneTabBarOptions;
|
|
251
|
+
/**
|
|
252
|
+
* How the right edge (dock tools) presents on phones: `'sheet'` rises from
|
|
253
|
+
* the bottom above the tab bar (grabber, swipe down or Escape to close),
|
|
254
|
+
* `'drawer'` slides in from the side. Default `'sheet'` when `phoneTabBar`
|
|
255
|
+
* is on, else `'drawer'`. An explicit value wins over `config.right.phone`.
|
|
256
|
+
* Read once at mount.
|
|
257
|
+
*/
|
|
258
|
+
phoneDock?: 'sheet' | 'drawer';
|
|
259
|
+
/**
|
|
260
|
+
* Render the shell chrome (default). `false` mounts only the Provider and
|
|
261
|
+
* ThemeProvider around `children`: no navigation, sidebars, header, or
|
|
262
|
+
* footer, so a host can show the first-run setup route chrome-free.
|
|
263
|
+
*/
|
|
264
|
+
chrome?: boolean;
|
|
193
265
|
children: Snippet;
|
|
194
266
|
}
|
|
195
267
|
|
|
@@ -206,6 +278,11 @@ let {
|
|
|
206
278
|
tenantLabel = '',
|
|
207
279
|
environment = 'local',
|
|
208
280
|
settingsHref,
|
|
281
|
+
accountMenu = true,
|
|
282
|
+
onSignOut,
|
|
283
|
+
signOutHref,
|
|
284
|
+
colorSchemeToggle = true,
|
|
285
|
+
commandPalette,
|
|
209
286
|
webmcp = false,
|
|
210
287
|
user = null,
|
|
211
288
|
permissions = [],
|
|
@@ -227,10 +304,17 @@ let {
|
|
|
227
304
|
iconComponent,
|
|
228
305
|
edgeToggles = false,
|
|
229
306
|
hotkeys,
|
|
307
|
+
phoneTabBar = false,
|
|
308
|
+
phoneDock,
|
|
309
|
+
chrome = true,
|
|
230
310
|
children,
|
|
231
311
|
}: Props = $props();
|
|
232
312
|
/** Stable id of the built-in brand item (title, subtitle). */
|
|
233
313
|
const SHELL_BRAND_ITEM_ID = 'item:brand';
|
|
314
|
+
/** Stable ids of the built-in header and account items (stored in layouts). */
|
|
315
|
+
const SHELL_ACCOUNT_ITEM_ID = 'item:account';
|
|
316
|
+
const SHELL_COLOR_SCHEME_ITEM_ID = 'item:color-scheme';
|
|
317
|
+
const SHELL_COMMAND_PALETTE_ITEM_ID = 'item:command-palette';
|
|
234
318
|
/** Stable id of the built-in edit-layout toggle item. */
|
|
235
319
|
const layoutFloating = $derived(
|
|
236
320
|
typeof layoutEditing === 'object' && layoutEditing.floating === true,
|
|
@@ -294,14 +378,53 @@ const entries = $derived.by(() => {
|
|
|
294
378
|
fixed: true,
|
|
295
379
|
});
|
|
296
380
|
}
|
|
381
|
+
if (colorSchemeToggle !== false) {
|
|
382
|
+
add({
|
|
383
|
+
id: SHELL_COLOR_SCHEME_ITEM_ID,
|
|
384
|
+
label: t(M['ui.app_shell.color_scheme_item']),
|
|
385
|
+
slot:
|
|
386
|
+
(typeof colorSchemeToggle === 'object'
|
|
387
|
+
? colorSchemeToggle.slot
|
|
388
|
+
: undefined) ?? 'header.end',
|
|
389
|
+
render: colorSchemeItem,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
if (commandPalette) {
|
|
393
|
+
add({
|
|
394
|
+
id: SHELL_COMMAND_PALETTE_ITEM_ID,
|
|
395
|
+
label: t(M['ui.app_shell.command_palette_item']),
|
|
396
|
+
slot: 'header.center',
|
|
397
|
+
render: commandPaletteItem,
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
// Last, so on phones it ends the header band.
|
|
401
|
+
if (user && accountMenu !== false) {
|
|
402
|
+
add({
|
|
403
|
+
id: SHELL_ACCOUNT_ITEM_ID,
|
|
404
|
+
label: t(M['ui.app_shell.account_item']),
|
|
405
|
+
slot:
|
|
406
|
+
(typeof accountMenu === 'object' ? accountMenu.slot : undefined) ??
|
|
407
|
+
(shell.viewport === 'phone' ? 'header.end' : 'leftSidebar.footer'),
|
|
408
|
+
render: accountItem,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
297
411
|
return out;
|
|
298
412
|
});
|
|
413
|
+
/** The right edge's phone presentation from `phoneDock` / `phoneTabBar`. */
|
|
414
|
+
function withPhoneDock(base: ShellPanelDefaults | undefined) {
|
|
415
|
+
const mode =
|
|
416
|
+
phoneDock ?? (resolvePhoneTabBar(phoneTabBar) ? 'sheet' : undefined);
|
|
417
|
+
const right = base?.right;
|
|
418
|
+
if (!mode || right === false) return base;
|
|
419
|
+
if (!phoneDock && right?.phone !== undefined) return base;
|
|
420
|
+
return { ...base, right: { ...right, phone: mode } };
|
|
421
|
+
}
|
|
299
422
|
// The shell state lives here (not inside AdminShell) so the layout can reach
|
|
300
423
|
// it: panel overrides apply to it, and the user's layout is stored in it when
|
|
301
424
|
// the host does not own persistence.
|
|
302
425
|
const shell = untrack(() =>
|
|
303
426
|
createShellState({
|
|
304
|
-
config,
|
|
427
|
+
config: withPhoneDock(config),
|
|
305
428
|
storageKey,
|
|
306
429
|
layoutPanels: normalizeShellLayout(layout).panels,
|
|
307
430
|
}),
|
|
@@ -320,10 +443,22 @@ const applied = $derived(
|
|
|
320
443
|
);
|
|
321
444
|
const hasNav = $derived(applied.nav.length > 0 || applied.groups.length > 0);
|
|
322
445
|
|
|
446
|
+
// Phone tab bar: on only when asked for and there is something to show.
|
|
447
|
+
const tabBarBudget = $derived(resolvePhoneTabBar(phoneTabBar)?.items ?? 0);
|
|
448
|
+
const tabEntries = $derived(
|
|
449
|
+
phoneTabNavEntries(applied.nav, applied.groups, navMode, sectionHref),
|
|
450
|
+
);
|
|
451
|
+
const tabBarOn = $derived(
|
|
452
|
+
tabBarBudget > 0 && (tabEntries.length > 0 || dockToggles.length > 0),
|
|
453
|
+
);
|
|
454
|
+
const tabDockToggle = $derived(tabBarOn ? dockToggles[0] : undefined);
|
|
455
|
+
|
|
323
456
|
const slotIds = $derived(resolveShellPlacements(entries, effectiveLayout));
|
|
324
457
|
const entriesFor = (name: ShellSlot): PlacedEntry[] => {
|
|
325
458
|
const byId = new Map(entries.map((entry) => [entry.id, entry]));
|
|
326
|
-
return slotIds[name].flatMap((id) =>
|
|
459
|
+
return slotIds[name].flatMap((id) =>
|
|
460
|
+
id === SHELL_ACCOUNT_ITEM_ID && accountInRail ? [] : (byId.get(id) ?? []),
|
|
461
|
+
);
|
|
327
462
|
};
|
|
328
463
|
const slotSnippets: Record<ShellSlot, Snippet> = {
|
|
329
464
|
'header.start': slot_0,
|
|
@@ -340,7 +475,7 @@ const slotSnippets: Record<ShellSlot, Snippet> = {
|
|
|
340
475
|
const shellSlots = $derived.by(() => {
|
|
341
476
|
const out: Partial<Record<ShellSlot, Snippet>> = {};
|
|
342
477
|
for (const name of SHELL_SLOTS) {
|
|
343
|
-
if (
|
|
478
|
+
if (entriesFor(name).length > 0) out[name] = slotSnippets[name];
|
|
344
479
|
}
|
|
345
480
|
return out;
|
|
346
481
|
});
|
|
@@ -392,6 +527,55 @@ setShellLayout(layoutApi);
|
|
|
392
527
|
// ---- In-place layout editing -------------------------------------------
|
|
393
528
|
const editing = $derived(layoutApi.editing);
|
|
394
529
|
let shellRoot = $state<HTMLElement | undefined>();
|
|
530
|
+
|
|
531
|
+
// ---- Account menu ------------------------------------------------------
|
|
532
|
+
const accountSlot = $derived(
|
|
533
|
+
SHELL_SLOTS.find((name) => slotIds[name].includes(SHELL_ACCOUNT_ITEM_ID)),
|
|
534
|
+
);
|
|
535
|
+
// The collapsed rail keeps the account at its bottom as the avatar alone,
|
|
536
|
+
// instead of letting the sidebar footer slot fall back to another region.
|
|
537
|
+
const accountInRail = $derived(
|
|
538
|
+
accountSlot === 'leftSidebar.footer' &&
|
|
539
|
+
!editing &&
|
|
540
|
+
shell.viewport !== 'phone' &&
|
|
541
|
+
shell.isEdgeShown('left') &&
|
|
542
|
+
shell.panels.left === 'collapsed',
|
|
543
|
+
);
|
|
544
|
+
// Full identity only inside an expanded sidebar; everywhere else the avatar.
|
|
545
|
+
const accountCompact = $derived.by(() => {
|
|
546
|
+
if (shell.viewport === 'phone' || !accountSlot) return true;
|
|
547
|
+
const region = slotRegion(accountSlot);
|
|
548
|
+
return !(
|
|
549
|
+
(region === 'leftSidebar' || region === 'rightSidebar') &&
|
|
550
|
+
shell.isRegionVisible(region)
|
|
551
|
+
);
|
|
552
|
+
});
|
|
553
|
+
function accountPlacement(
|
|
554
|
+
slot: ShellSlot | undefined,
|
|
555
|
+
rail: boolean,
|
|
556
|
+
): 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'inline-end' {
|
|
557
|
+
if (rail) return 'inline-end';
|
|
558
|
+
if (!slot) return 'bottom-end';
|
|
559
|
+
// Place the menu from the slot the item actually renders in: a hidden
|
|
560
|
+
// region sends it down the fallback chain, and a stored placement may put
|
|
561
|
+
// it in any slot on any viewport. Footers and sidebar footers open upward;
|
|
562
|
+
// everything else opens downward. The menu aligns to the trigger's own
|
|
563
|
+
// edge (start slots and the left sidebar to the start) so it stays inside
|
|
564
|
+
// the viewport on a phone.
|
|
565
|
+
const rendered =
|
|
566
|
+
resolveSlot(slot, (region) => shell.isRegionVisible(region)) ?? slot;
|
|
567
|
+
const region = slotRegion(rendered);
|
|
568
|
+
const opensUp = region === 'footer' || rendered.endsWith('.footer');
|
|
569
|
+
const alignStart = rendered.endsWith('.start') || region === 'leftSidebar';
|
|
570
|
+
if (opensUp) return alignStart ? 'top-start' : 'top-end';
|
|
571
|
+
return alignStart ? 'bottom-start' : 'bottom-end';
|
|
572
|
+
}
|
|
573
|
+
const accountIdentity = $derived.by(() => {
|
|
574
|
+
const record = (user ?? {}) as { name?: unknown; email?: unknown };
|
|
575
|
+
const name = typeof record.name === 'string' ? record.name.trim() : '';
|
|
576
|
+
const email = typeof record.email === 'string' ? record.email.trim() : '';
|
|
577
|
+
return { name, email };
|
|
578
|
+
});
|
|
395
579
|
// The floating toggle sits over the header's end (header visible), the top of
|
|
396
580
|
// the right sidebar (header hidden) or the top of main (neither); reserve that room so it covers no
|
|
397
581
|
// control. AdminShell reads these custom properties.
|
|
@@ -565,8 +749,11 @@ $effect(() => {
|
|
|
565
749
|
});
|
|
566
750
|
|
|
567
751
|
async function toggleEditing(): Promise<void> {
|
|
568
|
-
|
|
569
|
-
await
|
|
752
|
+
// The drop zones morph in/out under a view transition (when supported).
|
|
753
|
+
await runViewTransition(async () => {
|
|
754
|
+
layoutApi.setEditing(!layoutApi.editing);
|
|
755
|
+
await tick();
|
|
756
|
+
});
|
|
570
757
|
}
|
|
571
758
|
const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
572
759
|
header: 'top',
|
|
@@ -579,7 +766,10 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
579
766
|
{#snippet slotBody(name: ShellSlot)}
|
|
580
767
|
{#each entriesFor(name) as entry (entry.id)}
|
|
581
768
|
{#if entry.toggle}
|
|
582
|
-
|
|
769
|
+
<!-- On phones the tab bar carries this toggle. -->
|
|
770
|
+
{#if !(tabDockToggle?.tool === entry.toggle.tool && shell.viewport === 'phone')}
|
|
771
|
+
<DockToggles toggles={[entry.toggle]} />
|
|
772
|
+
{/if}
|
|
583
773
|
{:else if entry.render}
|
|
584
774
|
{@render entry.render()}
|
|
585
775
|
{/if}
|
|
@@ -673,6 +863,52 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
673
863
|
{/each}
|
|
674
864
|
{/snippet}
|
|
675
865
|
|
|
866
|
+
{#snippet accountMenuBody(compact: boolean, rail: boolean)}
|
|
867
|
+
<WorkspaceAccountMenu
|
|
868
|
+
userName={accountIdentity.name || accountIdentity.email}
|
|
869
|
+
email={accountIdentity.email}
|
|
870
|
+
{compact}
|
|
871
|
+
{tenantLabel}
|
|
872
|
+
{onSignOut}
|
|
873
|
+
{signOutHref}
|
|
874
|
+
{settingsHref}
|
|
875
|
+
placement={accountPlacement(accountSlot, rail)}
|
|
876
|
+
/>
|
|
877
|
+
{/snippet}
|
|
878
|
+
|
|
879
|
+
{#snippet accountItem()}
|
|
880
|
+
{@render accountMenuBody(accountCompact, false)}
|
|
881
|
+
{/snippet}
|
|
882
|
+
|
|
883
|
+
{#snippet railAccount()}
|
|
884
|
+
{#if accountInRail}{@render accountMenuBody(true, true)}{/if}
|
|
885
|
+
{/snippet}
|
|
886
|
+
|
|
887
|
+
{#snippet colorSchemeItem()}
|
|
888
|
+
<span class="smrt-app-shell-color-scheme">
|
|
889
|
+
<ColorSchemeToggle
|
|
890
|
+
variant="switch"
|
|
891
|
+
showLabels={shell.viewport !== 'phone'}
|
|
892
|
+
ariaLabel={t(M['ui.app_shell.color_scheme_toggle'])}
|
|
893
|
+
/>
|
|
894
|
+
</span>
|
|
895
|
+
{/snippet}
|
|
896
|
+
|
|
897
|
+
{#snippet commandPaletteItem()}
|
|
898
|
+
{#if commandPalette}
|
|
899
|
+
<span
|
|
900
|
+
class="smrt-app-shell-palette"
|
|
901
|
+
data-search={shell.viewport === 'phone' ? undefined : ''}
|
|
902
|
+
>
|
|
903
|
+
<CommandPalette
|
|
904
|
+
providers={commandPalette.providers}
|
|
905
|
+
placeholder={commandPalette.placeholder}
|
|
906
|
+
compact={shell.viewport === 'phone'}
|
|
907
|
+
/>
|
|
908
|
+
</span>
|
|
909
|
+
{/if}
|
|
910
|
+
{/snippet}
|
|
911
|
+
|
|
676
912
|
{#snippet brandItem()}
|
|
677
913
|
<ShellBrand {title} {subtitle} {logoSrc} {logoAlt} {homeHref} />
|
|
678
914
|
{/snippet}
|
|
@@ -703,9 +939,22 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
703
939
|
/>
|
|
704
940
|
{/snippet}
|
|
705
941
|
|
|
942
|
+
{#snippet phoneTabs()}
|
|
943
|
+
<PhoneTabBar
|
|
944
|
+
entries={tabEntries}
|
|
945
|
+
{currentHref}
|
|
946
|
+
budget={tabBarBudget}
|
|
947
|
+
dockToggle={tabDockToggle}
|
|
948
|
+
{iconComponent}
|
|
949
|
+
/>
|
|
950
|
+
{/snippet}
|
|
951
|
+
|
|
706
952
|
<Provider {webmcp} {user} {permissions}>
|
|
707
953
|
<RuntimeDiagnosticsWebMcp enabled={runtimeDiagnostics} />
|
|
708
954
|
<ThemeProvider {preset} {colorScheme} persist={true}>
|
|
955
|
+
{#if !chrome}
|
|
956
|
+
{@render children()}
|
|
957
|
+
{:else}
|
|
709
958
|
<AdminShell
|
|
710
959
|
{title}
|
|
711
960
|
{subtitle}
|
|
@@ -719,6 +968,9 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
719
968
|
{edgeToggles}
|
|
720
969
|
{hotkeys}
|
|
721
970
|
brandInSlot
|
|
971
|
+
phoneDockOpener={dockToggles.length === 0 && !tabBarOn}
|
|
972
|
+
phoneBottomBar={tabBarOn ? phoneTabs : undefined}
|
|
973
|
+
tenantRailFooter={accountInRail ? railAccount : undefined}
|
|
722
974
|
bind:rootElement={shellRoot}
|
|
723
975
|
{floatingReserve}
|
|
724
976
|
>
|
|
@@ -739,7 +991,7 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
739
991
|
{/snippet}
|
|
740
992
|
|
|
741
993
|
{#snippet tenantRail()}
|
|
742
|
-
{#if
|
|
994
|
+
{#if !editing && hasNav}
|
|
743
995
|
<TenantNav
|
|
744
996
|
collapsed
|
|
745
997
|
items={applied.nav}
|
|
@@ -786,24 +1038,37 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
786
1038
|
{/if}
|
|
787
1039
|
{@render children()}
|
|
788
1040
|
</AdminShell>
|
|
1041
|
+
{/if}
|
|
789
1042
|
</ThemeProvider>
|
|
790
1043
|
</Provider>
|
|
791
1044
|
|
|
792
1045
|
<style>
|
|
1046
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
1047
|
+
@layer smrt.theme {
|
|
793
1048
|
a {
|
|
794
1049
|
color: var(--smrt-color-primary);
|
|
795
1050
|
}
|
|
796
1051
|
.smrt-layout-toggle { display: inline-flex; align-items: center; gap: var(--smrt-spacing-1); }
|
|
797
|
-
.smrt-layout-toggle--floating { position: fixed; z-index: 45; inset-block-start: max(var(--smrt-spacing-3), env(safe-area-inset-top)); inset-inline-end: max(var(--smrt-spacing-3), env(safe-area-inset-right)); border-radius: var(--smrt-radius-full); background: var(--smrt-
|
|
1052
|
+
.smrt-layout-toggle--floating { position: fixed; z-index: 45; inset-block-start: max(var(--smrt-spacing-3), env(safe-area-inset-top)); inset-inline-end: max(var(--smrt-spacing-3), env(safe-area-inset-right)); border: var(--smrt-hairline); border-radius: var(--smrt-radius-full); background: var(--smrt-surface-raised); box-shadow: var(--smrt-elevation-3), var(--smrt-inset-highlight); }
|
|
798
1053
|
.smrt-layout-toggle--floating :global(.smrt-shell-icon-button) { border-radius: var(--smrt-radius-full); }
|
|
799
1054
|
.smrt-layout-toggle :global(.smrt-shell-icon-button[aria-pressed='true']) { background: var(--smrt-color-primary-container); color: var(--smrt-color-on-primary-container); }
|
|
1055
|
+
.smrt-app-shell-color-scheme { display: inline-flex; align-items: center; }
|
|
1056
|
+
.smrt-app-shell-color-scheme :global(.smrt-color-scheme-toggle__switch) { min-block-size: var(--smrt-control-target-min); }
|
|
1057
|
+
.smrt-app-shell-palette { display: inline-flex; min-inline-size: 0; }
|
|
1058
|
+
.smrt-app-shell-palette[data-search] :global(.smrt-command-palette-trigger) { inline-size: min(28rem, 40vw); justify-content: flex-start; border: var(--smrt-hairline-strong); border-radius: var(--smrt-radius-full); background: var(--smrt-surface-control); color: var(--smrt-color-on-surface-variant); }
|
|
1059
|
+
.smrt-app-shell-palette[data-search] :global(.smrt-command-palette-trigger__hint) { margin-inline-start: auto; }
|
|
800
1060
|
.smrt-layout-live { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
|
|
801
1061
|
.smrt-edit-zone__label { flex: 0 0 auto; color: var(--smrt-color-on-surface-variant); font: var(--smrt-typography-label-small-font); white-space: nowrap; }
|
|
802
|
-
.smrt-edit-item { display: inline-flex; align-items: center; min-inline-size: 0; border:
|
|
803
|
-
.smrt-edit-item--dragging { opacity:
|
|
1062
|
+
.smrt-edit-item { display: inline-flex; align-items: center; min-inline-size: 0; border: var(--smrt-hairline); border-radius: var(--smrt-control-radius); background: var(--smrt-surface-raised); }
|
|
1063
|
+
.smrt-edit-item--dragging { opacity: var(--smrt-state-disabled); }
|
|
1064
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
1065
|
+
.smrt-edit-item { animation: smrt-edit-item-in var(--smrt-duration-short2) var(--smrt-easing-standard) backwards; }
|
|
1066
|
+
}
|
|
1067
|
+
@keyframes smrt-edit-item-in { from { opacity: 0; transform: scale(0.96); } }
|
|
804
1068
|
.smrt-edit-item__body { display: inline-flex; align-items: center; min-inline-size: 0; pointer-events: none; }
|
|
805
1069
|
.smrt-edit-item__grip { display: inline-grid; place-items: center; flex: 0 0 auto; inline-size: 1.5rem; block-size: 2rem; padding: 0; border: 0; border-radius: var(--smrt-radius-sm); background: transparent; color: var(--smrt-color-on-surface-variant); cursor: grab; touch-action: none; }
|
|
806
|
-
.smrt-edit-item__grip:hover { background: var(--smrt-
|
|
807
|
-
.smrt-edit-item__grip:focus-visible { outline:
|
|
1070
|
+
.smrt-edit-item__grip:hover { background: color-mix(in srgb, currentColor calc(var(--smrt-state-hover) * 100%), transparent); }
|
|
1071
|
+
.smrt-edit-item__grip:focus-visible { outline: var(--smrt-focus-ring-width) solid var(--smrt-focus-ring-color); outline-offset: var(--smrt-focus-ring-offset); }
|
|
808
1072
|
.smrt-edit-item__grip[aria-pressed='true'] { background: var(--smrt-color-primary-container); color: var(--smrt-color-on-primary-container); }
|
|
1073
|
+
}
|
|
809
1074
|
</style>
|
|
@@ -10,7 +10,8 @@ import { type ShellLayout } from '../workspace/admin-shell/layout.js';
|
|
|
10
10
|
import { type ShellSlot } from '../workspace/admin-shell/slots.js';
|
|
11
11
|
import { type AdminShellProps, type ShellNavGroup, type ShellNavItem, type ShellPanelDefaults, type ShellSectionActionsContext } from '../workspace/admin-shell/types.js';
|
|
12
12
|
import type { DockToggle } from './dock-toggle.js';
|
|
13
|
-
import type
|
|
13
|
+
import { type PhoneTabBarOptions } from './phone-tabs.js';
|
|
14
|
+
import type { AppShellAccountMenu, AppShellCommandPalette, ShellSlotItem } from './slot-item.js';
|
|
14
15
|
interface Props {
|
|
15
16
|
/** Application name shown in the shell brand and app panel. */
|
|
16
17
|
title?: string;
|
|
@@ -36,6 +37,40 @@ interface Props {
|
|
|
36
37
|
environment?: string;
|
|
37
38
|
/** When set, the app panel links here (e.g. a settings route). */
|
|
38
39
|
settingsHref?: string;
|
|
40
|
+
/**
|
|
41
|
+
* The signed-in user's account menu: the built-in item `item:account`
|
|
42
|
+
* (shown when `user` is set). Default slot `leftSidebar.footer`: the full
|
|
43
|
+
* identity in the expanded sidebar footer, the avatar alone at the bottom of
|
|
44
|
+
* the collapsed rail; on phones the avatar sits at the end of the header
|
|
45
|
+
* band. Menu: name and email, Settings (`settingsHref`) and Sign out
|
|
46
|
+
* (`onSignOut` or `signOutHref`). `false` opts out; `{ slot }` overrides the
|
|
47
|
+
* default slot (users can still move it in the layout editor).
|
|
48
|
+
*/
|
|
49
|
+
accountMenu?: AppShellAccountMenu;
|
|
50
|
+
/** Called when the account menu's Sign out is chosen (wins over `signOutHref`). */
|
|
51
|
+
onSignOut?: () => void;
|
|
52
|
+
/**
|
|
53
|
+
* Where the account menu's Sign out link goes when there is no `onSignOut`.
|
|
54
|
+
* A link is a GET: never point it at the runtime's POST-only `/sign-out`
|
|
55
|
+
* route; pass `onSignOut` for that.
|
|
56
|
+
*/
|
|
57
|
+
signOutHref?: string;
|
|
58
|
+
/**
|
|
59
|
+
* The theme switcher (`ColorSchemeToggle` from `smrt-ui/themes`) as the
|
|
60
|
+
* built-in item `item:color-scheme`, default slot `header.end`. On by
|
|
61
|
+
* default; `false` opts out, `{ slot }` sets the default slot. Icon-only on
|
|
62
|
+
* phones.
|
|
63
|
+
*/
|
|
64
|
+
colorSchemeToggle?: boolean | {
|
|
65
|
+
slot?: ShellSlot;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* The command palette as the built-in item `item:command-palette` (default
|
|
69
|
+
* slot `header.center`): a search-shaped trigger with the shortcut hint, a
|
|
70
|
+
* search icon button on phones. Mounts the existing `CommandPalette`
|
|
71
|
+
* (trigger, dialog and global shortcut). Off unless given.
|
|
72
|
+
*/
|
|
73
|
+
commandPalette?: AppShellCommandPalette;
|
|
39
74
|
/** Options for the Provider's WebMCP integration; passed through unchanged. */
|
|
40
75
|
webmcp?: boolean | WebMcpProviderConfig;
|
|
41
76
|
/** Authenticated user forwarded to the Provider; `null` renders the shell signed out. */
|
|
@@ -128,7 +163,7 @@ interface Props {
|
|
|
128
163
|
* mode the sidebar edits sections (grip, rename, hide, icon); entries are
|
|
129
164
|
* edited on the section page.
|
|
130
165
|
*/
|
|
131
|
-
navMode?: 'items' | 'sections';
|
|
166
|
+
navMode?: 'items' | 'sections' | 'sections-with-items';
|
|
132
167
|
/** Section page for groups without an `href` (e.g. user-created ones). */
|
|
133
168
|
sectionHref?: (sectionId: string) => string | undefined;
|
|
134
169
|
/** Renders host icon names for sections and entries. */
|
|
@@ -144,6 +179,32 @@ interface Props {
|
|
|
144
179
|
edgeToggles?: AdminShellProps['edgeToggles'];
|
|
145
180
|
/** Keyboard shortcuts; default follows `edgeToggles` (see `AdminShell`). */
|
|
146
181
|
hotkeys?: boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Phone bottom tab bar (default `false`): on phones, the footer region's
|
|
184
|
+
* phone presentation (conceptually the footer's center slot) shows the first
|
|
185
|
+
* N navigation items as icon + label tabs (`aria-current` from
|
|
186
|
+
* `currentHref`), then a tab for the first `dockToggles` entry (or a "Tools"
|
|
187
|
+
* tab when the right edge has tools), then "More" opening the left drawer
|
|
188
|
+
* when navigation overflows. `N` defaults to 4 and counts the dock tab;
|
|
189
|
+
* `{ items }` overrides it. While on, the header "Tools" opener and the
|
|
190
|
+
* header copy of the dock tab's toggle are not rendered on phones. Read once
|
|
191
|
+
* at mount, like `config`.
|
|
192
|
+
*/
|
|
193
|
+
phoneTabBar?: boolean | PhoneTabBarOptions;
|
|
194
|
+
/**
|
|
195
|
+
* How the right edge (dock tools) presents on phones: `'sheet'` rises from
|
|
196
|
+
* the bottom above the tab bar (grabber, swipe down or Escape to close),
|
|
197
|
+
* `'drawer'` slides in from the side. Default `'sheet'` when `phoneTabBar`
|
|
198
|
+
* is on, else `'drawer'`. An explicit value wins over `config.right.phone`.
|
|
199
|
+
* Read once at mount.
|
|
200
|
+
*/
|
|
201
|
+
phoneDock?: 'sheet' | 'drawer';
|
|
202
|
+
/**
|
|
203
|
+
* Render the shell chrome (default). `false` mounts only the Provider and
|
|
204
|
+
* ThemeProvider around `children`: no navigation, sidebars, header, or
|
|
205
|
+
* footer, so a host can show the first-run setup route chrome-free.
|
|
206
|
+
*/
|
|
207
|
+
chrome?: boolean;
|
|
147
208
|
children: Snippet;
|
|
148
209
|
}
|
|
149
210
|
declare const AppShell: Component<Props, {}, "">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/AppShell.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"AppShell.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/AppShell.svelte.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { useShellDock } from '../workspace/admin-shell/dock.js';
|
|
3
|
+
import {
|
|
4
|
+
isShellIconName,
|
|
5
|
+
SHELL_DEFAULT_TOOL_ICON,
|
|
6
|
+
SHELL_ICON_PATHS,
|
|
7
|
+
} from '../workspace/admin-shell/shell-icons.js';
|
|
3
8
|
import type { DockToggle } from './dock-toggle.js';
|
|
4
9
|
|
|
5
10
|
interface Props {
|
|
@@ -54,14 +59,27 @@ function press(event: MouseEvent, toggle: DockToggle): void {
|
|
|
54
59
|
>
|
|
55
60
|
<path d="M21 11.5a8.5 8.5 0 0 1-12.4 7.5L3 20.5l1.6-5A8.5 8.5 0 1 1 21 11.5z" />
|
|
56
61
|
</svg>
|
|
62
|
+
{:else if icon === undefined || isShellIconName(icon)}
|
|
63
|
+
<svg
|
|
64
|
+
viewBox="0 0 24 24"
|
|
65
|
+
width="20"
|
|
66
|
+
height="20"
|
|
67
|
+
fill="currentColor"
|
|
68
|
+
aria-hidden="true"
|
|
69
|
+
focusable="false"
|
|
70
|
+
>
|
|
71
|
+
<path d={SHELL_ICON_PATHS[icon === undefined ? SHELL_DEFAULT_TOOL_ICON : icon]} />
|
|
72
|
+
</svg>
|
|
57
73
|
{:else}
|
|
58
|
-
<span aria-hidden="true">{icon
|
|
74
|
+
<span aria-hidden="true">{icon}</span>
|
|
59
75
|
{/if}
|
|
60
76
|
</button>
|
|
61
77
|
{/each}
|
|
62
78
|
</div>
|
|
63
79
|
|
|
64
80
|
<style>
|
|
81
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
82
|
+
@layer smrt.theme {
|
|
65
83
|
.smrt-dock-toggles {
|
|
66
84
|
display: flex;
|
|
67
85
|
align-items: center;
|
|
@@ -71,32 +89,56 @@ function press(event: MouseEvent, toggle: DockToggle): void {
|
|
|
71
89
|
.smrt-dock-toggles__button {
|
|
72
90
|
display: inline-grid;
|
|
73
91
|
place-items: center;
|
|
74
|
-
|
|
75
|
-
|
|
92
|
+
position: relative;
|
|
93
|
+
inline-size: var(--smrt-control-height-small);
|
|
94
|
+
block-size: var(--smrt-control-height-small);
|
|
76
95
|
padding: 0;
|
|
77
96
|
border: 1px solid transparent;
|
|
78
|
-
border-radius: var(--smrt-radius
|
|
97
|
+
border-radius: var(--smrt-control-radius);
|
|
79
98
|
background: transparent;
|
|
80
99
|
color: var(--smrt-color-on-surface);
|
|
81
100
|
cursor: pointer;
|
|
82
101
|
}
|
|
83
102
|
|
|
84
|
-
|
|
85
|
-
|
|
103
|
+
@media (max-width: 48rem) {
|
|
104
|
+
.smrt-dock-toggles__button {
|
|
105
|
+
min-inline-size: var(--smrt-touch-target-min);
|
|
106
|
+
min-block-size: var(--smrt-touch-target-min);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* State layer over the button; the active container fill sits under it. */
|
|
111
|
+
.smrt-dock-toggles__button::after {
|
|
112
|
+
content: '';
|
|
113
|
+
position: absolute;
|
|
114
|
+
inset: 0;
|
|
115
|
+
border-radius: inherit;
|
|
116
|
+
background: currentColor;
|
|
117
|
+
opacity: 0;
|
|
118
|
+
pointer-events: none;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.smrt-dock-toggles__button:hover::after {
|
|
122
|
+
opacity: var(--smrt-state-hover);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.smrt-dock-toggles__button:active::after {
|
|
126
|
+
opacity: var(--smrt-state-pressed);
|
|
86
127
|
}
|
|
87
128
|
|
|
88
129
|
.smrt-dock-toggles__button:focus-visible {
|
|
89
|
-
outline:
|
|
90
|
-
outline-offset:
|
|
130
|
+
outline: var(--smrt-focus-ring-width) solid var(--smrt-focus-ring-color);
|
|
131
|
+
outline-offset: var(--smrt-focus-ring-offset);
|
|
91
132
|
}
|
|
92
133
|
|
|
93
134
|
.smrt-dock-toggles__button.active {
|
|
94
|
-
background: var(--smrt-color-primary-container
|
|
95
|
-
color: var(--smrt-color-on-primary-container
|
|
135
|
+
background: var(--smrt-color-primary-container);
|
|
136
|
+
color: var(--smrt-color-on-primary-container);
|
|
96
137
|
}
|
|
97
138
|
|
|
98
139
|
.smrt-dock-toggles__button[aria-disabled='true'] {
|
|
99
|
-
opacity:
|
|
140
|
+
opacity: var(--smrt-state-disabled);
|
|
100
141
|
cursor: default;
|
|
101
142
|
}
|
|
143
|
+
}
|
|
102
144
|
</style>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DockToggles.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/DockToggles.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DockToggles.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/DockToggles.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,UAAU,KAAK;IACb,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAgDD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|