@happyvertical/smrt-svelte 0.55.16 → 0.55.17
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 +145 -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 +274 -9
- 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 +27 -1
- 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 +4 -1
- package/dist/components/workspace/admin-shell/AdminShell.svelte +502 -72
- 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 +21 -8
- 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 +4 -1
- 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 +4 -1
- package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte +4 -1
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte +13 -7
- 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 +4 -1
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte +4 -1
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte +15 -10
- 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 +81 -36
- 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 +305 -53
- 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
|
@@ -49,7 +49,7 @@ async function handleToggle() {
|
|
|
49
49
|
}
|
|
50
50
|
</script>
|
|
51
51
|
|
|
52
|
-
<div class="voice-input" class:sm={size === 'sm'} class:lg={size === 'lg'}>
|
|
52
|
+
<div class="voice-input" class:sm={size === 'sm'} class:lg={size === 'lg'} data-smrt-component="VoiceInput">
|
|
53
53
|
{#if stt.isInitializing}
|
|
54
54
|
<DownloadProgress
|
|
55
55
|
progress={stt.downloadProgress ? {
|
|
@@ -84,11 +84,13 @@ async function handleToggle() {
|
|
|
84
84
|
</div>
|
|
85
85
|
|
|
86
86
|
<style>
|
|
87
|
+
@layer smrt.reset, smrt.structure, smrt.theme;
|
|
88
|
+
@layer smrt.theme {
|
|
87
89
|
.voice-input {
|
|
88
90
|
display: flex;
|
|
89
91
|
flex-direction: column;
|
|
90
92
|
align-items: center;
|
|
91
|
-
gap: var(--smrt-spacing-sm
|
|
93
|
+
gap: var(--smrt-spacing-sm);
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
.mic-button {
|
|
@@ -96,8 +98,8 @@ async function handleToggle() {
|
|
|
96
98
|
height: 3rem;
|
|
97
99
|
border-radius: var(--smrt-radius-full, 50%);
|
|
98
100
|
border: none;
|
|
99
|
-
background: var(--smrt-color-primary
|
|
100
|
-
color: var(--smrt-color-on-primary
|
|
101
|
+
background: var(--smrt-color-primary);
|
|
102
|
+
color: var(--smrt-color-on-primary);
|
|
101
103
|
cursor: pointer;
|
|
102
104
|
display: flex;
|
|
103
105
|
align-items: center;
|
|
@@ -107,7 +109,7 @@ async function handleToggle() {
|
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
.mic-button:hover:not(:disabled) {
|
|
110
|
-
background: var(--smrt-color-primary-container
|
|
112
|
+
background: var(--smrt-color-primary-container);
|
|
111
113
|
opacity: 0.9;
|
|
112
114
|
transform: scale(1.05);
|
|
113
115
|
}
|
|
@@ -118,7 +120,7 @@ async function handleToggle() {
|
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
.mic-button.listening {
|
|
121
|
-
background: var(--smrt-color-error
|
|
123
|
+
background: var(--smrt-color-error);
|
|
122
124
|
animation: pulse 1.5s ease-in-out infinite;
|
|
123
125
|
}
|
|
124
126
|
|
|
@@ -163,12 +165,12 @@ async function handleToggle() {
|
|
|
163
165
|
.error {
|
|
164
166
|
display: flex;
|
|
165
167
|
align-items: center;
|
|
166
|
-
gap: var(--smrt-spacing-sm
|
|
167
|
-
padding: var(--smrt-spacing-md
|
|
168
|
-
background: var(--smrt-color-error-container
|
|
169
|
-
border: 1px solid var(--smrt-color-error
|
|
170
|
-
border-radius: var(--smrt-radius-medium
|
|
171
|
-
color: var(--smrt-color-on-error-container
|
|
168
|
+
gap: var(--smrt-spacing-sm);
|
|
169
|
+
padding: var(--smrt-spacing-md) var(--smrt-spacing-md);
|
|
170
|
+
background: var(--smrt-color-error-container);
|
|
171
|
+
border: 1px solid var(--smrt-color-error);
|
|
172
|
+
border-radius: var(--smrt-radius-medium);
|
|
173
|
+
color: var(--smrt-color-on-error-container);
|
|
172
174
|
font: var(--smrt-typography-body-medium-font, 0.875rem / 1.25 sans-serif);
|
|
173
175
|
}
|
|
174
176
|
|
|
@@ -178,8 +180,8 @@ async function handleToggle() {
|
|
|
178
180
|
justify-content: center;
|
|
179
181
|
width: 20px;
|
|
180
182
|
height: 20px;
|
|
181
|
-
background: var(--smrt-color-error
|
|
182
|
-
color: var(--smrt-color-on-error
|
|
183
|
+
background: var(--smrt-color-error);
|
|
184
|
+
color: var(--smrt-color-on-error);
|
|
183
185
|
border-radius: var(--smrt-radius-full, 50%);
|
|
184
186
|
font-weight: var(--smrt-typography-weight-bold, 700);
|
|
185
187
|
font: var(--smrt-typography-label-small-font, 0.75rem / 1 sans-serif);
|
|
@@ -198,4 +200,5 @@ async function handleToggle() {
|
|
|
198
200
|
animation: none;
|
|
199
201
|
}
|
|
200
202
|
}
|
|
203
|
+
}
|
|
201
204
|
</style>
|
|
@@ -32,4 +32,4 @@ $effect(() => {
|
|
|
32
32
|
};
|
|
33
33
|
});
|
|
34
34
|
</script>
|
|
35
|
-
{#if shell}<WorkspaceActivityList filter={{ kind: prefix }} {emptyLabel} />{:else}<p>{emptyLabel}</p>{/if}
|
|
35
|
+
{#if shell}<WorkspaceActivityList filter={{ kind: prefix }} {emptyLabel} />{:else}<p data-smrt-component="ActivityList">{emptyLabel}</p>{/if}
|
|
@@ -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,10 +1038,13 @@ 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
|
}
|
|
@@ -797,13 +1052,23 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
797
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-radius: var(--smrt-radius-full); background: var(--smrt-color-surface-container-high); box-shadow: var(--smrt-elevation-2); }
|
|
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: 1px solid var(--smrt-color-outline-variant); border-radius: var(--smrt-radius-full); background: var(--smrt-color-surface); 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
1062
|
.smrt-edit-item { display: inline-flex; align-items: center; min-inline-size: 0; border: 1px solid var(--smrt-color-outline-variant); border-radius: var(--smrt-radius-medium); background: var(--smrt-color-surface); }
|
|
803
1063
|
.smrt-edit-item--dragging { opacity: 0.55; }
|
|
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
1070
|
.smrt-edit-item__grip:hover { background: var(--smrt-color-surface-container-high); }
|
|
807
1071
|
.smrt-edit-item__grip:focus-visible { outline: 2px solid var(--smrt-color-primary); outline-offset: 2px; }
|
|
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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"}
|