@happyvertical/smrt-svelte 0.55.6 → 0.55.7
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/AGENTS.md +17 -2
- package/README.md +83 -4
- package/agents/workspace.md +202 -5
- package/dist/browser-ai/adapters/stt/dictation-source.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/dictation-source.js +8 -2
- package/dist/browser-ai/adapters/stt/factory.d.ts +6 -3
- package/dist/browser-ai/adapters/stt/factory.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/factory.js +19 -9
- package/dist/browser-ai/adapters/stt/index.d.ts +3 -1
- package/dist/browser-ai/adapters/stt/index.d.ts.map +1 -1
- package/dist/browser-ai/adapters/stt/index.js +3 -1
- package/dist/browser-ai/adapters/stt/local-speech-model.d.ts +111 -0
- package/dist/browser-ai/adapters/stt/local-speech-model.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech-model.js +377 -0
- package/dist/browser-ai/adapters/stt/local-speech.d.ts +82 -0
- package/dist/browser-ai/adapters/stt/local-speech.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech.js +317 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.d.ts +2 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/local-speech.worker.js +32 -0
- package/dist/browser-ai/adapters/stt/transformers-env.d.ts +8 -0
- package/dist/browser-ai/adapters/stt/transformers-env.d.ts.map +1 -0
- package/dist/browser-ai/adapters/stt/transformers-env.js +17 -0
- package/dist/browser-ai/adapters/stt/types.d.ts +54 -9
- package/dist/browser-ai/adapters/stt/types.d.ts.map +1 -1
- package/dist/browser-ai/capabilities/speech-probe.d.ts +29 -0
- package/dist/browser-ai/capabilities/speech-probe.d.ts.map +1 -0
- package/dist/browser-ai/capabilities/speech-probe.js +19 -0
- package/dist/browser-ai/core/errors.d.ts +9 -0
- package/dist/browser-ai/core/errors.d.ts.map +1 -1
- package/dist/browser-ai/core/errors.js +12 -0
- package/dist/browser-ai/index.d.ts +1 -0
- package/dist/browser-ai/index.d.ts.map +1 -1
- package/dist/browser-ai/index.js +1 -0
- package/dist/components/app/AppShell.svelte +587 -33
- package/dist/components/app/AppShell.svelte.d.ts +75 -4
- package/dist/components/app/AppShell.svelte.d.ts.map +1 -1
- package/dist/components/app/DockToggles.svelte +0 -1
- package/dist/components/app/dock-toggle.d.ts +7 -1
- 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/slot-item.d.ts +21 -0
- package/dist/components/app/slot-item.d.ts.map +1 -0
- package/dist/components/app/slot-item.js +1 -0
- package/dist/components/forms/AddressInput.svelte +2 -15
- package/dist/components/forms/AddressInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/DateRangeInput.svelte +2 -15
- package/dist/components/forms/DateRangeInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/DateTimeInput.svelte +8 -15
- package/dist/components/forms/DateTimeInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/MeasurementInput.svelte +2 -15
- package/dist/components/forms/MeasurementInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/MoneyInput.svelte +8 -25
- package/dist/components/forms/MoneyInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/NumberInput.svelte +7 -15
- package/dist/components/forms/NumberInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/PhoneInput.svelte +7 -15
- package/dist/components/forms/PhoneInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/SelectInput.svelte +34 -40
- package/dist/components/forms/SelectInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/TextInput.svelte +20 -37
- package/dist/components/forms/TextInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/TextareaInput.svelte +19 -35
- package/dist/components/forms/TextareaInput.svelte.d.ts.map +1 -1
- package/dist/components/sortable/Sortable.svelte +6 -33
- package/dist/components/sortable/Sortable.svelte.d.ts.map +1 -1
- package/dist/components/sortable/announce.d.ts +5 -0
- package/dist/components/sortable/announce.d.ts.map +1 -0
- package/dist/components/sortable/announce.js +33 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte +424 -58
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts +27 -2
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellBrand.svelte +86 -0
- package/dist/components/workspace/admin-shell/ShellBrand.svelte.d.ts +18 -0
- package/dist/components/workspace/admin-shell/ShellBrand.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte +77 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte.d.ts +26 -0
- package/dist/components/workspace/admin-shell/ShellIconButton.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte +88 -16
- package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte +531 -0
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts +26 -0
- package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte +57 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte.d.ts +22 -0
- package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte +290 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts +32 -0
- package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte +67 -2
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts +8 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout-controller.svelte.d.ts +67 -0
- package/dist/components/workspace/admin-shell/layout-controller.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout-controller.svelte.js +129 -1
- package/dist/components/workspace/admin-shell/layout.d.ts +122 -0
- package/dist/components/workspace/admin-shell/layout.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/layout.js +410 -10
- package/dist/components/workspace/admin-shell/settings.js +4 -4
- package/dist/components/workspace/admin-shell/shell-icons.d.ts +45 -0
- package/dist/components/workspace/admin-shell/shell-icons.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/shell-icons.js +66 -0
- package/dist/components/workspace/admin-shell/slot-labels.d.ts +33 -0
- package/dist/components/workspace/admin-shell/slot-labels.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/slot-labels.js +33 -0
- package/dist/components/workspace/admin-shell/slots.d.ts +50 -0
- package/dist/components/workspace/admin-shell/slots.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/slots.js +77 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts +35 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/state.svelte.js +111 -0
- package/dist/components/workspace/admin-shell/types.d.ts +101 -1
- package/dist/components/workspace/admin-shell/types.d.ts.map +1 -1
- package/dist/components/workspace/index.d.ts +9 -2
- package/dist/components/workspace/index.d.ts.map +1 -1
- package/dist/components/workspace/index.js +6 -0
- package/dist/i18n/strings.workspace.d.ts +49 -0
- package/dist/i18n/strings.workspace.d.ts.map +1 -1
- package/dist/i18n/strings.workspace.js +49 -0
- package/package.json +30 -19
- package/dist/browser-ai/adapters/stt/whisper-wasm.d.ts +0 -51
- package/dist/browser-ai/adapters/stt/whisper-wasm.d.ts.map +0 -1
- package/dist/browser-ai/adapters/stt/whisper-wasm.js +0 -380
|
@@ -1,8 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-customizable shell layout: a small, versioned, JSON-serializable delta
|
|
3
|
+
* applied over the navigation and panel defaults the host generates.
|
|
4
|
+
*
|
|
5
|
+
* This module is pure (no Svelte, no DOM) so a host can validate, store,
|
|
6
|
+
* export, or apply a layout anywhere, including on the server. It is also
|
|
7
|
+
* published as `@happyvertical/smrt-svelte/workspace/layout`.
|
|
8
|
+
*
|
|
9
|
+
* Ids: sections are identified by `ShellNavGroup.id ?? heading`, items by
|
|
10
|
+
* `ShellNavItem.id ?? href`. Sections and items share one id namespace (the
|
|
11
|
+
* `hidden` list holds both), so keep them unique; later duplicates get a
|
|
12
|
+
* `#2`, `#3`, ... suffix. The flat `nav` items form an implicit first
|
|
13
|
+
* section, {@link SHELL_NAV_ROOT_SECTION_ID}, which always renders first and
|
|
14
|
+
* cannot be reordered or hidden as a whole.
|
|
15
|
+
*/
|
|
16
|
+
import { isShellSlot, resolveSlot, SHELL_SLOTS, } from './slots.js';
|
|
1
17
|
/** The only layout format version this package reads and writes. */
|
|
2
18
|
export const SHELL_LAYOUT_VERSION = 1;
|
|
3
19
|
/** Section id of the flat `nav` items rendered above all groups. */
|
|
4
20
|
export const SHELL_NAV_ROOT_SECTION_ID = '@root';
|
|
5
21
|
const EDGES = ['top', 'left', 'right', 'bottom'];
|
|
22
|
+
/** Prefix of the ids of user-created sections. */
|
|
23
|
+
export const SHELL_CUSTOM_SECTION_PREFIX = 'custom:';
|
|
6
24
|
export function createShellLayout() {
|
|
7
25
|
return { version: SHELL_LAYOUT_VERSION };
|
|
8
26
|
}
|
|
@@ -14,7 +32,11 @@ export function isShellLayoutEmpty(layout) {
|
|
|
14
32
|
!hasKeys(layout.itemOrder) &&
|
|
15
33
|
!layout.hidden?.length &&
|
|
16
34
|
!hasKeys(layout.moved) &&
|
|
17
|
-
!hasKeys(layout.
|
|
35
|
+
!hasKeys(layout.sections) &&
|
|
36
|
+
!hasKeys(layout.items) &&
|
|
37
|
+
!layout.customSections?.length &&
|
|
38
|
+
!hasKeys(layout.panels) &&
|
|
39
|
+
!hasKeys(layout.placements));
|
|
18
40
|
}
|
|
19
41
|
function hasKeys(value) {
|
|
20
42
|
return (typeof value === 'object' && value !== null && Object.keys(value).length > 0);
|
|
@@ -32,6 +54,67 @@ function stringList(value) {
|
|
|
32
54
|
}
|
|
33
55
|
return seen.size > 0 ? [...seen] : undefined;
|
|
34
56
|
}
|
|
57
|
+
function cleanLabel(value) {
|
|
58
|
+
if (typeof value !== 'string')
|
|
59
|
+
return undefined;
|
|
60
|
+
const label = value.trim();
|
|
61
|
+
return label === '' ? undefined : label;
|
|
62
|
+
}
|
|
63
|
+
function readSection(raw) {
|
|
64
|
+
if (!isRecord(raw))
|
|
65
|
+
return undefined;
|
|
66
|
+
const section = {};
|
|
67
|
+
const label = cleanLabel(raw.label);
|
|
68
|
+
if (label)
|
|
69
|
+
section.label = label;
|
|
70
|
+
if (typeof raw.showTitle === 'boolean')
|
|
71
|
+
section.showTitle = raw.showTitle;
|
|
72
|
+
const icon = cleanLabel(raw.icon);
|
|
73
|
+
if (icon)
|
|
74
|
+
section.icon = icon;
|
|
75
|
+
return hasKeys(section) ? section : undefined;
|
|
76
|
+
}
|
|
77
|
+
function readItem(raw) {
|
|
78
|
+
if (!isRecord(raw))
|
|
79
|
+
return undefined;
|
|
80
|
+
const item = {};
|
|
81
|
+
const label = cleanLabel(raw.label);
|
|
82
|
+
if (label)
|
|
83
|
+
item.label = label;
|
|
84
|
+
const description = cleanLabel(raw.description);
|
|
85
|
+
if (description)
|
|
86
|
+
item.description = description;
|
|
87
|
+
return hasKeys(item) ? item : undefined;
|
|
88
|
+
}
|
|
89
|
+
function readItems(value) {
|
|
90
|
+
if (!isRecord(value))
|
|
91
|
+
return undefined;
|
|
92
|
+
const items = {};
|
|
93
|
+
for (const [id, raw] of Object.entries(value)) {
|
|
94
|
+
const item = id === '' ? undefined : readItem(raw);
|
|
95
|
+
if (item)
|
|
96
|
+
items[id] = item;
|
|
97
|
+
}
|
|
98
|
+
return hasKeys(items) ? items : undefined;
|
|
99
|
+
}
|
|
100
|
+
function readCustomSections(value) {
|
|
101
|
+
if (!Array.isArray(value))
|
|
102
|
+
return [];
|
|
103
|
+
const seen = new Set();
|
|
104
|
+
const out = [];
|
|
105
|
+
for (const raw of value) {
|
|
106
|
+
if (!isRecord(raw) || typeof raw.id !== 'string')
|
|
107
|
+
continue;
|
|
108
|
+
const label = cleanLabel(raw.label);
|
|
109
|
+
if (!raw.id.startsWith(SHELL_CUSTOM_SECTION_PREFIX) || !label)
|
|
110
|
+
continue;
|
|
111
|
+
if (seen.has(raw.id))
|
|
112
|
+
continue;
|
|
113
|
+
seen.add(raw.id);
|
|
114
|
+
out.push({ id: raw.id, label });
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
35
118
|
/**
|
|
36
119
|
* Read an untrusted value (stored JSON, an imported blueprint) as a layout.
|
|
37
120
|
* Never throws: anything unreadable, including a version this package does not
|
|
@@ -66,6 +149,22 @@ export function normalizeShellLayout(input) {
|
|
|
66
149
|
if (hasKeys(moved))
|
|
67
150
|
layout.moved = moved;
|
|
68
151
|
}
|
|
152
|
+
if (isRecord(input.sections)) {
|
|
153
|
+
const sections = {};
|
|
154
|
+
for (const [id, raw] of Object.entries(input.sections)) {
|
|
155
|
+
const section = readSection(raw);
|
|
156
|
+
if (section)
|
|
157
|
+
sections[id] = section;
|
|
158
|
+
}
|
|
159
|
+
if (hasKeys(sections))
|
|
160
|
+
layout.sections = sections;
|
|
161
|
+
}
|
|
162
|
+
const itemOverrides = readItems(input.items);
|
|
163
|
+
if (itemOverrides)
|
|
164
|
+
layout.items = itemOverrides;
|
|
165
|
+
const customSections = readCustomSections(input.customSections);
|
|
166
|
+
if (customSections.length > 0)
|
|
167
|
+
layout.customSections = customSections;
|
|
69
168
|
if (isRecord(input.panels)) {
|
|
70
169
|
const panels = {};
|
|
71
170
|
for (const edge of EDGES) {
|
|
@@ -84,6 +183,9 @@ export function normalizeShellLayout(input) {
|
|
|
84
183
|
if (hasKeys(panels))
|
|
85
184
|
layout.panels = panels;
|
|
86
185
|
}
|
|
186
|
+
const placements = readPlacements(input.placements);
|
|
187
|
+
if (placements)
|
|
188
|
+
layout.placements = placements;
|
|
87
189
|
return layout;
|
|
88
190
|
}
|
|
89
191
|
export function shellNavGroupId(group) {
|
|
@@ -146,6 +248,20 @@ export function resolveShellNavModel(nav = [], groups = [], layout) {
|
|
|
146
248
|
})),
|
|
147
249
|
});
|
|
148
250
|
}
|
|
251
|
+
// User-created sections follow the host's, in creation order.
|
|
252
|
+
for (const custom of readCustomSections(layout?.customSections)) {
|
|
253
|
+
if (used.has(custom.id))
|
|
254
|
+
continue;
|
|
255
|
+
used.add(custom.id);
|
|
256
|
+
natives.push({
|
|
257
|
+
id: custom.id,
|
|
258
|
+
group: { id: custom.id, heading: custom.label, items: [] },
|
|
259
|
+
items: [],
|
|
260
|
+
custom: true,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
const overrides = isRecord(layout?.sections) ? layout.sections : {};
|
|
264
|
+
const itemOverrides = readItems(layout?.items) ?? {};
|
|
149
265
|
const hidden = new Set(stringList(layout?.hidden) ?? []);
|
|
150
266
|
const moved = isRecord(layout?.moved)
|
|
151
267
|
? layout?.moved
|
|
@@ -177,10 +293,17 @@ export function resolveShellNavModel(nav = [], groups = [], layout) {
|
|
|
177
293
|
continue;
|
|
178
294
|
defaults.push({
|
|
179
295
|
id: entry.id,
|
|
180
|
-
item: entry.
|
|
296
|
+
item: itemOverrides[entry.id]?.description
|
|
297
|
+
? {
|
|
298
|
+
...entry.item,
|
|
299
|
+
description: itemOverrides[entry.id]?.description,
|
|
300
|
+
}
|
|
301
|
+
: entry.item,
|
|
181
302
|
nativeSectionId: native.id,
|
|
182
303
|
sectionId: section.id,
|
|
183
304
|
hidden: hidden.has(entry.id),
|
|
305
|
+
label: itemOverrides[entry.id]?.label ?? entry.item.label,
|
|
306
|
+
defaultLabel: entry.item.label,
|
|
184
307
|
});
|
|
185
308
|
}
|
|
186
309
|
}
|
|
@@ -189,10 +312,25 @@ export function resolveShellNavModel(nav = [], groups = [], layout) {
|
|
|
189
312
|
Number(b.nativeSectionId !== section.id));
|
|
190
313
|
const byItem = new Map(defaults.map((entry) => [entry.id, entry]));
|
|
191
314
|
const order = mergeOrder(defaults.map((entry) => entry.id), stringList(itemOrder[section.id]));
|
|
315
|
+
const override = section.group
|
|
316
|
+
? readSection(overrides[section.id])
|
|
317
|
+
: undefined;
|
|
318
|
+
const custom = section.custom === true;
|
|
192
319
|
return {
|
|
193
320
|
id: section.id,
|
|
194
321
|
group: section.group,
|
|
195
|
-
heading: section.group
|
|
322
|
+
heading: section.group
|
|
323
|
+
? ((custom ? undefined : override?.label) ?? section.group.heading)
|
|
324
|
+
: null,
|
|
325
|
+
defaultHeading: section.group && !custom ? section.group.heading : null,
|
|
326
|
+
custom,
|
|
327
|
+
titleVisible: section.group
|
|
328
|
+
? (override?.showTitle ?? section.group.showTitle !== false)
|
|
329
|
+
: false,
|
|
330
|
+
icon: section.group
|
|
331
|
+
? (override?.icon ?? section.group.icon ?? null)
|
|
332
|
+
: null,
|
|
333
|
+
defaultIcon: section.group?.icon ?? null,
|
|
196
334
|
hidden: section.group ? hidden.has(section.id) : false,
|
|
197
335
|
items: order.map((id) => byItem.get(id)),
|
|
198
336
|
};
|
|
@@ -229,16 +367,32 @@ export function applyShellLayout(nav, groups, panels, layout) {
|
|
|
229
367
|
const model = resolveShellNavModel(nav, groups, layout);
|
|
230
368
|
const visible = (section) => section.hidden
|
|
231
369
|
? []
|
|
232
|
-
: section.items
|
|
370
|
+
: section.items
|
|
371
|
+
.filter((entry) => !entry.hidden)
|
|
372
|
+
.map((e) => e.label === e.defaultLabel
|
|
373
|
+
? e.item
|
|
374
|
+
: { ...e.item, label: e.label, defaultLabel: e.defaultLabel });
|
|
233
375
|
const [root, ...sections] = model;
|
|
234
376
|
const nextGroups = [];
|
|
235
377
|
for (const section of sections) {
|
|
236
378
|
const items = visible(section);
|
|
237
379
|
const group = section.group;
|
|
238
|
-
if (section.hidden ||
|
|
380
|
+
if (section.hidden ||
|
|
381
|
+
(items.length === 0 && (section.custom || group.items.length > 0))) {
|
|
239
382
|
continue;
|
|
240
383
|
}
|
|
241
|
-
|
|
384
|
+
const next = { ...group, items };
|
|
385
|
+
if (section.heading !== group.heading) {
|
|
386
|
+
next.id = shellNavGroupId(group);
|
|
387
|
+
next.heading = section.heading;
|
|
388
|
+
}
|
|
389
|
+
if (section.titleVisible)
|
|
390
|
+
delete next.showTitle;
|
|
391
|
+
else
|
|
392
|
+
next.showTitle = false;
|
|
393
|
+
if (section.icon)
|
|
394
|
+
next.icon = section.icon;
|
|
395
|
+
nextGroups.push(next);
|
|
242
396
|
}
|
|
243
397
|
const nextPanels = { ...basePanels };
|
|
244
398
|
const overrides = isRecord(layout?.panels) ? layout?.panels : undefined;
|
|
@@ -263,8 +417,17 @@ function compact(layout) {
|
|
|
263
417
|
next.hidden = layout.hidden;
|
|
264
418
|
if (hasKeys(layout.moved))
|
|
265
419
|
next.moved = layout.moved;
|
|
420
|
+
if (hasKeys(layout.sections))
|
|
421
|
+
next.sections = layout.sections;
|
|
422
|
+
if (hasKeys(layout.items))
|
|
423
|
+
next.items = layout.items;
|
|
424
|
+
if (layout.customSections?.length) {
|
|
425
|
+
next.customSections = layout.customSections;
|
|
426
|
+
}
|
|
266
427
|
if (hasKeys(layout.panels))
|
|
267
428
|
next.panels = layout.panels;
|
|
429
|
+
if (hasKeys(layout.placements))
|
|
430
|
+
next.placements = layout.placements;
|
|
268
431
|
return next;
|
|
269
432
|
}
|
|
270
433
|
function sameList(a, b) {
|
|
@@ -288,7 +451,10 @@ export function moveShellSection(nav, groups, layout, sectionId, toIndex) {
|
|
|
288
451
|
return current;
|
|
289
452
|
const next = ids.filter((id) => id !== sectionId);
|
|
290
453
|
next.splice(clampIndex(toIndex, next.length), 0, sectionId);
|
|
291
|
-
const defaults = resolveShellNavModel(nav, groups
|
|
454
|
+
const defaults = resolveShellNavModel(nav, groups, {
|
|
455
|
+
version: SHELL_LAYOUT_VERSION,
|
|
456
|
+
customSections: current.customSections,
|
|
457
|
+
})
|
|
292
458
|
.slice(1)
|
|
293
459
|
.map((section) => section.id);
|
|
294
460
|
const sectionOrder = sameList(next, defaults) ? undefined : next;
|
|
@@ -329,6 +495,7 @@ export function moveShellItem(nav, groups, layout, itemId, toSectionId, toIndex)
|
|
|
329
495
|
version: SHELL_LAYOUT_VERSION,
|
|
330
496
|
moved,
|
|
331
497
|
sectionOrder: current.sectionOrder,
|
|
498
|
+
customSections: current.customSections,
|
|
332
499
|
});
|
|
333
500
|
const itemOrder = { ...(current.itemOrder ?? {}) };
|
|
334
501
|
for (const id of new Set([source.id, target.id])) {
|
|
@@ -346,7 +513,7 @@ export function moveShellItem(nav, groups, layout, itemId, toSectionId, toIndex)
|
|
|
346
513
|
/** Hide a section or item. Unknown ids and the root section are ignored. */
|
|
347
514
|
export function hideShellEntry(nav, groups, layout, id) {
|
|
348
515
|
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
349
|
-
if (!isKnownEntry(nav, groups, id) || current.hidden?.includes(id)) {
|
|
516
|
+
if (!isKnownEntry(nav, groups, current, id) || current.hidden?.includes(id)) {
|
|
350
517
|
return current;
|
|
351
518
|
}
|
|
352
519
|
return compact({ ...current, hidden: [...(current.hidden ?? []), id] });
|
|
@@ -361,8 +528,11 @@ export function showShellEntry(layout, id) {
|
|
|
361
528
|
hidden: current.hidden.filter((entry) => entry !== id),
|
|
362
529
|
});
|
|
363
530
|
}
|
|
364
|
-
function isKnownEntry(nav, groups, id) {
|
|
365
|
-
return resolveShellNavModel(nav, groups
|
|
531
|
+
function isKnownEntry(nav, groups, layout, id) {
|
|
532
|
+
return resolveShellNavModel(nav, groups, {
|
|
533
|
+
version: SHELL_LAYOUT_VERSION,
|
|
534
|
+
customSections: layout.customSections,
|
|
535
|
+
}).some((section) => (section.group !== null && section.id === id) ||
|
|
366
536
|
section.items.some((entry) => entry.id === id));
|
|
367
537
|
}
|
|
368
538
|
/**
|
|
@@ -400,3 +570,233 @@ export function setShellLayoutPanel(layout, edge, patch, defaults) {
|
|
|
400
570
|
delete panels[edge];
|
|
401
571
|
return compact({ ...current, panels });
|
|
402
572
|
}
|
|
573
|
+
function setSectionOverride(current, id, patch) {
|
|
574
|
+
const sections = { ...(current.sections ?? {}) };
|
|
575
|
+
const merged = { ...(sections[id] ?? {}), ...patch };
|
|
576
|
+
if (merged.label === undefined)
|
|
577
|
+
delete merged.label;
|
|
578
|
+
if (merged.showTitle === undefined)
|
|
579
|
+
delete merged.showTitle;
|
|
580
|
+
if (merged.icon === undefined)
|
|
581
|
+
delete merged.icon;
|
|
582
|
+
if (hasKeys(merged))
|
|
583
|
+
sections[id] = merged;
|
|
584
|
+
else
|
|
585
|
+
delete sections[id];
|
|
586
|
+
return compact({ ...current, sections });
|
|
587
|
+
}
|
|
588
|
+
function findSection(nav, groups, layout, id) {
|
|
589
|
+
return resolveShellNavModel(nav, groups, layout).find((section) => section.group !== null && section.id === id);
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Rename a section. A blank label, or the host's own heading, removes the
|
|
593
|
+
* override (the section goes back to the suggested name). A custom section's
|
|
594
|
+
* label is replaced outright and a blank label is ignored. Unknown ids and the
|
|
595
|
+
* root section are ignored.
|
|
596
|
+
*/
|
|
597
|
+
export function renameShellSection(nav, groups, layout, sectionId, label) {
|
|
598
|
+
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
599
|
+
const section = findSection(nav, groups, current, sectionId);
|
|
600
|
+
if (!section)
|
|
601
|
+
return current;
|
|
602
|
+
const clean = cleanLabel(label);
|
|
603
|
+
if (section.custom) {
|
|
604
|
+
if (!clean)
|
|
605
|
+
return current;
|
|
606
|
+
return compact({
|
|
607
|
+
...current,
|
|
608
|
+
customSections: current.customSections?.map((entry) => entry.id === sectionId ? { ...entry, label: clean } : entry),
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
const reset = !clean || clean === section.defaultHeading;
|
|
612
|
+
return setSectionOverride(current, sectionId, {
|
|
613
|
+
label: reset ? undefined : clean,
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Rename a navigation item. A blank label (or `null`), or the host's own
|
|
618
|
+
* label, removes the override. Unknown ids are ignored. Items keep their id,
|
|
619
|
+
* so a rename survives reordering and moving between sections.
|
|
620
|
+
*/
|
|
621
|
+
export function renameShellItem(nav, groups, layout, itemId, label) {
|
|
622
|
+
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
623
|
+
const entry = resolveShellNavModel(nav, groups, current)
|
|
624
|
+
.flatMap((section) => section.items)
|
|
625
|
+
.find((candidate) => candidate.id === itemId);
|
|
626
|
+
if (!entry)
|
|
627
|
+
return current;
|
|
628
|
+
const clean = cleanLabel(label);
|
|
629
|
+
const items = { ...(current.items ?? {}) };
|
|
630
|
+
const kept = items[itemId]?.description;
|
|
631
|
+
const next = {
|
|
632
|
+
...(clean && clean !== entry.defaultLabel ? { label: clean } : {}),
|
|
633
|
+
...(kept ? { description: kept } : {}),
|
|
634
|
+
};
|
|
635
|
+
if (hasKeys(next))
|
|
636
|
+
items[itemId] = next;
|
|
637
|
+
else
|
|
638
|
+
delete items[itemId];
|
|
639
|
+
return compact({ ...current, items });
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Show or hide a section's title. Hidden titles render the items flat (the
|
|
643
|
+
* shell keeps an accessible group name). Matching the host's suggestion drops
|
|
644
|
+
* the override.
|
|
645
|
+
*/
|
|
646
|
+
export function setShellSectionTitleVisible(nav, groups, layout, sectionId, visible) {
|
|
647
|
+
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
648
|
+
const section = findSection(nav, groups, current, sectionId);
|
|
649
|
+
if (!section)
|
|
650
|
+
return current;
|
|
651
|
+
const suggested = section.custom ? true : section.group?.showTitle !== false;
|
|
652
|
+
return setSectionOverride(current, sectionId, {
|
|
653
|
+
showTitle: visible === suggested ? undefined : visible,
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Set a section's icon. A blank icon (or `null`), or the host's own icon,
|
|
658
|
+
* removes the override. Works for host and custom sections; unknown ids and
|
|
659
|
+
* the root section are ignored.
|
|
660
|
+
*/
|
|
661
|
+
export function setShellSectionIcon(nav, groups, layout, sectionId, icon) {
|
|
662
|
+
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
663
|
+
const section = findSection(nav, groups, current, sectionId);
|
|
664
|
+
if (!section)
|
|
665
|
+
return current;
|
|
666
|
+
const clean = cleanLabel(icon);
|
|
667
|
+
return setSectionOverride(current, sectionId, {
|
|
668
|
+
icon: !clean || clean === section.defaultIcon ? undefined : clean,
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
function slug(label) {
|
|
672
|
+
const base = label
|
|
673
|
+
.toLowerCase()
|
|
674
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
675
|
+
.replace(/^-+|-+$/g, '');
|
|
676
|
+
return base || 'section';
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Create an empty user section named `label` (blank labels are ignored). It
|
|
680
|
+
* gets a unique `custom:` id and lands after the existing sections; read the
|
|
681
|
+
* new id from the last entry of `customSections`.
|
|
682
|
+
*/
|
|
683
|
+
export function createShellSection(nav, groups, layout, label) {
|
|
684
|
+
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
685
|
+
const clean = cleanLabel(label);
|
|
686
|
+
if (!clean)
|
|
687
|
+
return current;
|
|
688
|
+
const used = new Set(resolveShellNavModel(nav, groups, current).flatMap((section) => [
|
|
689
|
+
section.id,
|
|
690
|
+
...section.items.map((entry) => entry.id),
|
|
691
|
+
]));
|
|
692
|
+
const base = `${SHELL_CUSTOM_SECTION_PREFIX}${slug(clean)}`;
|
|
693
|
+
let id = base;
|
|
694
|
+
for (let n = 2; used.has(id); n += 1)
|
|
695
|
+
id = `${base}-${n}`;
|
|
696
|
+
return compact({
|
|
697
|
+
...current,
|
|
698
|
+
customSections: [...(current.customSections ?? []), { id, label: clean }],
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Delete a user-created section. Its items return to the sections the host
|
|
703
|
+
* suggested; host sections cannot be deleted (hide them instead).
|
|
704
|
+
*/
|
|
705
|
+
export function deleteShellSection(layout, sectionId) {
|
|
706
|
+
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
707
|
+
if (!current.customSections?.some((entry) => entry.id === sectionId)) {
|
|
708
|
+
return current;
|
|
709
|
+
}
|
|
710
|
+
const without = (record) => {
|
|
711
|
+
if (!record)
|
|
712
|
+
return undefined;
|
|
713
|
+
const next = { ...record };
|
|
714
|
+
delete next[sectionId];
|
|
715
|
+
return next;
|
|
716
|
+
};
|
|
717
|
+
const moved = Object.fromEntries(Object.entries(current.moved ?? {}).filter(([, target]) => target !== sectionId));
|
|
718
|
+
return compact({
|
|
719
|
+
...current,
|
|
720
|
+
customSections: current.customSections.filter((entry) => entry.id !== sectionId),
|
|
721
|
+
sectionOrder: current.sectionOrder?.filter((id) => id !== sectionId),
|
|
722
|
+
itemOrder: without(current.itemOrder),
|
|
723
|
+
hidden: current.hidden?.filter((id) => id !== sectionId),
|
|
724
|
+
sections: without(current.sections),
|
|
725
|
+
moved,
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
// Slot placement of shell items (dock toggles, host items).
|
|
729
|
+
function readPlacements(value) {
|
|
730
|
+
if (!isRecord(value))
|
|
731
|
+
return undefined;
|
|
732
|
+
const placements = {};
|
|
733
|
+
for (const [id, slot] of Object.entries(value)) {
|
|
734
|
+
if (id !== '' && isShellSlot(slot))
|
|
735
|
+
placements[id] = slot;
|
|
736
|
+
}
|
|
737
|
+
return hasKeys(placements) ? placements : undefined;
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Where each item lives once the layout's `placements` are applied, before any
|
|
741
|
+
* hidden-region fallback. Items stay in the order given within their default
|
|
742
|
+
* slot; items placed into a slot follow, in placement order. Placements for
|
|
743
|
+
* ids not in `items` are ignored. Every slot is present, possibly empty.
|
|
744
|
+
*/
|
|
745
|
+
export function resolveShellPlacements(items, layout) {
|
|
746
|
+
const out = Object.fromEntries(SHELL_SLOTS.map((slot) => [slot, []]));
|
|
747
|
+
const placements = readPlacements(layout?.placements) ?? {};
|
|
748
|
+
const known = new Set();
|
|
749
|
+
for (const item of items) {
|
|
750
|
+
if (known.has(item.id))
|
|
751
|
+
continue;
|
|
752
|
+
known.add(item.id);
|
|
753
|
+
if (placements[item.id] === undefined)
|
|
754
|
+
out[item.slot]?.push(item.id);
|
|
755
|
+
}
|
|
756
|
+
for (const [id, slot] of Object.entries(placements)) {
|
|
757
|
+
if (known.has(id))
|
|
758
|
+
out[slot].push(id);
|
|
759
|
+
}
|
|
760
|
+
return out;
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* {@link resolveShellPlacements} followed by the hidden-region fallback: an
|
|
764
|
+
* item whose slot's region is not `visible` moves along the slot's fallback
|
|
765
|
+
* chain to the first visible slot (and is dropped only if none is visible).
|
|
766
|
+
*/
|
|
767
|
+
export function resolveShellVisiblePlacements(items, layout, visible) {
|
|
768
|
+
const nominal = resolveShellPlacements(items, layout);
|
|
769
|
+
const out = Object.fromEntries(SHELL_SLOTS.map((slot) => [slot, []]));
|
|
770
|
+
for (const slot of SHELL_SLOTS) {
|
|
771
|
+
for (const id of nominal[slot]) {
|
|
772
|
+
const target = resolveSlot(slot, visible);
|
|
773
|
+
if (target)
|
|
774
|
+
out[target].push(id);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
return out;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Place an item in `slot`. Unknown slots are ignored. When `defaultSlot` (the
|
|
781
|
+
* item's own default) is given and equals `slot`, the override is removed so
|
|
782
|
+
* the layout stays sparse. Re-placing an item puts it last in its slot.
|
|
783
|
+
*/
|
|
784
|
+
export function placeShellItem(layout, itemId, slot, defaultSlot) {
|
|
785
|
+
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
786
|
+
if (itemId === '' || !isShellSlot(slot))
|
|
787
|
+
return current;
|
|
788
|
+
const placements = { ...(current.placements ?? {}) };
|
|
789
|
+
delete placements[itemId];
|
|
790
|
+
if (slot !== defaultSlot)
|
|
791
|
+
placements[itemId] = slot;
|
|
792
|
+
return compact({ ...current, placements });
|
|
793
|
+
}
|
|
794
|
+
/** Remove an item's placement override; it returns to its default slot. */
|
|
795
|
+
export function resetShellItemPlacement(layout, itemId) {
|
|
796
|
+
const current = normalizeShellLayout(layout ?? createShellLayout());
|
|
797
|
+
if (!current.placements || !(itemId in current.placements))
|
|
798
|
+
return current;
|
|
799
|
+
const placements = { ...current.placements };
|
|
800
|
+
delete placements[itemId];
|
|
801
|
+
return compact({ ...current, placements });
|
|
802
|
+
}
|
|
@@ -10,7 +10,7 @@ const DEFAULT_PANEL_CONFIG = {
|
|
|
10
10
|
top: {
|
|
11
11
|
edge: 'top',
|
|
12
12
|
scope: 'app',
|
|
13
|
-
label: '
|
|
13
|
+
label: 'Header',
|
|
14
14
|
initial: 'collapsed',
|
|
15
15
|
presentation: 'overlay',
|
|
16
16
|
hotkey: DEFAULT_SHELL_KEYMAP.top,
|
|
@@ -20,7 +20,7 @@ const DEFAULT_PANEL_CONFIG = {
|
|
|
20
20
|
left: {
|
|
21
21
|
edge: 'left',
|
|
22
22
|
scope: 'tenant',
|
|
23
|
-
label: '
|
|
23
|
+
label: 'Left sidebar',
|
|
24
24
|
initial: 'collapsed',
|
|
25
25
|
presentation: 'push',
|
|
26
26
|
hotkey: DEFAULT_SHELL_KEYMAP.left,
|
|
@@ -30,7 +30,7 @@ const DEFAULT_PANEL_CONFIG = {
|
|
|
30
30
|
right: {
|
|
31
31
|
edge: 'right',
|
|
32
32
|
scope: 'focus',
|
|
33
|
-
label: '
|
|
33
|
+
label: 'Right sidebar',
|
|
34
34
|
initial: 'collapsed',
|
|
35
35
|
presentation: 'push',
|
|
36
36
|
hotkey: DEFAULT_SHELL_KEYMAP.right,
|
|
@@ -40,7 +40,7 @@ const DEFAULT_PANEL_CONFIG = {
|
|
|
40
40
|
bottom: {
|
|
41
41
|
edge: 'bottom',
|
|
42
42
|
scope: 'system',
|
|
43
|
-
label: '
|
|
43
|
+
label: 'Footer',
|
|
44
44
|
initial: 'collapsed',
|
|
45
45
|
presentation: 'overlay',
|
|
46
46
|
hotkey: DEFAULT_SHELL_KEYMAP.bottom,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filled 24x24 icon paths used by the layout-editing chrome (the same
|
|
3
|
+
* convention as `@happyvertical/smrt-ui`'s `Icon`, which fills one path).
|
|
4
|
+
*/
|
|
5
|
+
export declare const SHELL_ICON_PATHS: {
|
|
6
|
+
readonly edit: "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 0 0 0-1.41l-2.34-2.34a1 1 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z";
|
|
7
|
+
readonly undo: "M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z";
|
|
8
|
+
readonly done: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z";
|
|
9
|
+
readonly eye: "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z";
|
|
10
|
+
readonly eyeOff: "M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z";
|
|
11
|
+
readonly heading: "M5 4v3h5.5v12h3V7H19V4z";
|
|
12
|
+
readonly headingOff: "M5 4v3h5.5v12h3V7H19V4zM3.5 2.5L2.1 3.9l18 18 1.4-1.4z";
|
|
13
|
+
readonly trash: "M7 3h10v2h4v2H3V5h4V3zm-2 6h14v12H5V9zm4 2v8h2v-8H9zm4 0v8h2v-8h-2z";
|
|
14
|
+
readonly add: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z";
|
|
15
|
+
readonly more: "M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z";
|
|
16
|
+
readonly settings: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z";
|
|
17
|
+
readonly calendar: "M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z";
|
|
18
|
+
readonly users: "M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z";
|
|
19
|
+
readonly shoppingBag: "M18 6h-2c0-2.21-1.79-4-4-4S8 3.79 8 6H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-8 4c0 .55-.45 1-1 1s-1-.45-1-1V8h2v2zm2-6c1.1 0 2 .9 2 2h-4c0-1.1.9-2 2-2zm4 6c0 .55-.45 1-1 1s-1-.45-1-1V8h2v2z";
|
|
20
|
+
readonly receipt: "M18 17H6v-2h12v2zm0-4H6v-2h12v2zm0-4H6V7h12v2zM3 22l1.5-1.5L6 22l1.5-1.5L9 22l1.5-1.5L12 22l1.5-1.5L15 22l1.5-1.5L18 22l1.5-1.5L21 22V2l-1.5 1.5L18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2 4.5 3.5 3 2v20z";
|
|
21
|
+
readonly book: "M21 5c-1.11-.35-2.33-.5-3.5-.5-1.95 0-4.05.4-5.5 1.5-1.45-1.1-3.55-1.5-5.5-1.5S2.45 4.9 1 6v14.65c0 .25.25.5.5.5.1 0 .15-.05.25-.05C3.1 20.45 5.05 20 6.5 20c1.95 0 4.05.4 5.5 1.5 1.35-.85 3.8-1.5 5.5-1.5 1.65 0 3.35.3 4.75 1.05.1.05.15.05.25.05.25 0 .5-.25.5-.5V6c-.6-.45-1.25-.75-2-1zm0 13.5c-1.1-.35-2.3-.5-3.5-.5-1.7 0-4.15.65-5.5 1.5V8c1.35-.85 3.8-1.5 5.5-1.5 1.2 0 2.4.15 3.5.5v11.5z";
|
|
22
|
+
readonly briefcase: "M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z";
|
|
23
|
+
readonly truck: "M20 8h-3V4H3c-1.1 0-2 .9-2 2v11h2c0 1.66 1.34 3 3 3s3-1.34 3-3h6c0 1.66 1.34 3 3 3s3-1.34 3-3h2v-5l-3-4zM6 18.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm13.5-9l1.96 2.5H17V9.5h2.5zm-1.5 9c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z";
|
|
24
|
+
readonly package: "M20 2H4c-1 0-2 .9-2 2v3.01c0 .72.43 1.34 1 1.69V20c0 1.1 1.1 2 2 2h14c.9 0 2-.9 2-2V8.7c.57-.35 1-.97 1-1.69V4c0-1.1-1-2-2-2zm-5 12H9v-2h6v2zm5-7H4V4h16v3z";
|
|
25
|
+
readonly wrench: "M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z";
|
|
26
|
+
readonly fileText: "M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z";
|
|
27
|
+
readonly layers: "M11.99 18.54l-7.37-5.73L3 14.07l9 7 9-7-1.63-1.27-7.38 5.74zM12 16l7.36-5.73L21 9l-9-7-9 7 1.63 1.27L12 16z";
|
|
28
|
+
readonly folder: "M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z";
|
|
29
|
+
readonly bank: "M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z";
|
|
30
|
+
readonly creditCard: "M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z";
|
|
31
|
+
readonly school: "M5 13.18v4L12 21l7-3.82v-4L12 17l-7-3.82zM12 3L1 9l11 6 9-4.91V17h2V9L12 3z";
|
|
32
|
+
readonly home: "M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z";
|
|
33
|
+
readonly repeat: "M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z";
|
|
34
|
+
readonly tag: "M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58s1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41s-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z";
|
|
35
|
+
readonly archive: "M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z";
|
|
36
|
+
readonly chevronRight: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z";
|
|
37
|
+
};
|
|
38
|
+
export type ShellIconName = keyof typeof SHELL_ICON_PATHS;
|
|
39
|
+
/** Section icon used when neither the host nor the user chose one. */
|
|
40
|
+
export declare const SHELL_DEFAULT_SECTION_ICON: ShellIconName;
|
|
41
|
+
/** Icons the section icon picker offers (a subset of the shell icon set). */
|
|
42
|
+
export declare const SHELL_SECTION_ICONS: readonly ShellIconName[];
|
|
43
|
+
/** True when `name` is one of the shell's built-in icon names. */
|
|
44
|
+
export declare function isShellIconName(name: string): name is ShellIconName;
|
|
45
|
+
//# sourceMappingURL=shell-icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-icons.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/shell-icons.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDnB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,gBAAgB,CAAC;AAE1D,sEAAsE;AACtE,eAAO,MAAM,0BAA0B,EAAE,aAAwB,CAAC;AAElE,6EAA6E;AAC7E,eAAO,MAAM,mBAAmB,EAAE,SAAS,aAAa,EAqBvD,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,aAAa,CAEnE"}
|