sh3-core 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Sh3.svelte +107 -39
- package/dist/__screenshots__/handheld.browser.test.ts/handheld-viewport-flip-e2e-viewport-override-flips-chrome-and-body-branches-1.png +0 -0
- package/dist/actions/CommandPalette.svelte +1 -2
- package/dist/actions/listActionsFromEntries.test.js +29 -0
- package/dist/actions/listActive.js +2 -0
- package/dist/actions/listeners.js +16 -1
- package/dist/actions/programmatic-dispatch.svelte.test.js +9 -2
- package/dist/actions/types.d.ts +8 -0
- package/dist/api.d.ts +8 -1
- package/dist/app/store/storeShard.svelte.js +1 -21
- package/dist/app/store/version.d.ts +11 -0
- package/dist/app/store/version.js +39 -0
- package/dist/app/store/version.test.d.ts +1 -0
- package/dist/app/store/version.test.js +44 -0
- package/dist/apps/lifecycle.d.ts +6 -0
- package/dist/apps/lifecycle.js +5 -2
- package/dist/apps/lifecycle.test.js +30 -0
- package/dist/apps/types.d.ts +12 -0
- package/dist/assets/iconIds.generated.d.ts +1 -1
- package/dist/assets/iconIds.generated.js +5 -0
- package/dist/assets/icons.svg +31 -0
- package/dist/auth/auth.svelte.js +18 -8
- package/dist/auth/types.d.ts +6 -0
- package/dist/chrome/CompactChrome.svelte +130 -0
- package/dist/chrome/CompactChrome.svelte.d.ts +3 -0
- package/dist/chrome/CompactChrome.svelte.test.d.ts +1 -0
- package/dist/chrome/CompactChrome.svelte.test.js +174 -0
- package/dist/chrome/MenuSheet.svelte +224 -0
- package/dist/chrome/MenuSheet.svelte.d.ts +7 -0
- package/dist/chrome/MenuSheet.svelte.test.d.ts +1 -0
- package/dist/chrome/MenuSheet.svelte.test.js +46 -0
- package/dist/createShell.d.ts +9 -0
- package/dist/createShell.js +20 -7
- package/dist/createShell.remoteAuth.test.d.ts +1 -0
- package/dist/createShell.remoteAuth.test.js +71 -0
- package/dist/documents/http-backend.js +12 -11
- package/dist/env/client.js +11 -5
- package/dist/files/types.d.ts +106 -0
- package/dist/files/types.js +1 -0
- package/dist/gestures/gestureRegistry.d.ts +6 -0
- package/dist/gestures/gestureRegistry.js +190 -0
- package/dist/gestures/gestureRegistry.test.d.ts +1 -0
- package/dist/gestures/gestureRegistry.test.js +119 -0
- package/dist/gestures/index.d.ts +6 -0
- package/dist/gestures/index.js +12 -0
- package/dist/gestures/pointerClaim.d.ts +7 -0
- package/dist/gestures/pointerClaim.js +36 -0
- package/dist/gestures/pointerClaim.test.d.ts +1 -0
- package/dist/gestures/pointerClaim.test.js +64 -0
- package/dist/gestures/types.d.ts +83 -0
- package/dist/gestures/types.js +1 -0
- package/dist/handheld.browser.test.d.ts +1 -0
- package/dist/handheld.browser.test.js +90 -0
- package/dist/host-entry.d.ts +1 -0
- package/dist/host-entry.js +1 -0
- package/dist/layout/LayoutRenderer.browser.test.js +15 -3
- package/dist/layout/LayoutRenderer.svelte +27 -3
- package/dist/layout/LayoutRenderer.svelte.d.ts +4 -1
- package/dist/layout/__screenshots__/LayoutRenderer.browser.test.ts/LayoutRenderer-browser---E-3-splitter-drag-updates-split-sizes-when-the-splitter-handle-is-dragged-1.png +0 -0
- package/dist/layout/__screenshots__/LayoutRenderer.browser.test.ts/LayoutRenderer-browser---E-5-splitter-collapse-toggle-toggles-collapsed-i--on-double-click-1.png +0 -0
- package/dist/layout/__screenshots__/LayoutRenderer.browser.test.ts/LayoutRenderer-browser---E-6-fixed-slots-hides-the-collapse-widget-on-a-fixed-pane-but-keeps-it-on-panes-with-a-non-fixed-neighbor-1.png +0 -0
- package/dist/layout/compact/CarouselTabs.svelte +361 -0
- package/dist/layout/compact/CarouselTabs.svelte.d.ts +10 -0
- package/dist/layout/compact/CarouselTabs.svelte.test.d.ts +1 -0
- package/dist/layout/compact/CarouselTabs.svelte.test.js +300 -0
- package/dist/layout/compact/CompactRenderer.svelte +53 -0
- package/dist/layout/compact/CompactRenderer.svelte.d.ts +3 -0
- package/dist/layout/compact/CompactRenderer.svelte.test.d.ts +1 -0
- package/dist/layout/compact/CompactRenderer.svelte.test.js +125 -0
- package/dist/layout/compact/derive.d.ts +3 -0
- package/dist/layout/compact/derive.js +157 -0
- package/dist/layout/compact/derive.test.d.ts +1 -0
- package/dist/layout/compact/derive.test.js +197 -0
- package/dist/layout/compact/drawerStore.svelte.d.ts +21 -0
- package/dist/layout/compact/drawerStore.svelte.js +75 -0
- package/dist/layout/compact/drawerStore.svelte.test.d.ts +1 -0
- package/dist/layout/compact/drawerStore.svelte.test.js +43 -0
- package/dist/layout/compact/enrichCarousels.d.ts +8 -0
- package/dist/layout/compact/enrichCarousels.js +44 -0
- package/dist/layout/compact/enrichCarousels.test.d.ts +1 -0
- package/dist/layout/compact/enrichCarousels.test.js +88 -0
- package/dist/layout/compact/resolveRole.d.ts +6 -0
- package/dist/layout/compact/resolveRole.js +13 -0
- package/dist/layout/compact/resolveRole.test.d.ts +1 -0
- package/dist/layout/compact/resolveRole.test.js +18 -0
- package/dist/layout/compact/types.d.ts +30 -0
- package/dist/layout/compact/types.js +15 -0
- package/dist/layout/drag.svelte.js +13 -0
- package/dist/layout/presets.compactVariant.test.d.ts +1 -0
- package/dist/layout/presets.compactVariant.test.js +27 -0
- package/dist/layout/presets.d.ts +12 -0
- package/dist/layout/presets.js +16 -0
- package/dist/layout/store.drawers.svelte.test.d.ts +1 -0
- package/dist/layout/store.drawers.svelte.test.js +49 -0
- package/dist/layout/store.schemaVersion.test.d.ts +1 -0
- package/dist/layout/store.schemaVersion.test.js +35 -0
- package/dist/layout/store.svelte.js +52 -2
- package/dist/layout/types.d.ts +51 -1
- package/dist/layout/types.js +1 -1
- package/dist/layout/types.test.d.ts +1 -0
- package/dist/layout/types.test.js +26 -0
- package/dist/overlays/DrawerSurface.svelte +141 -0
- package/dist/overlays/DrawerSurface.svelte.d.ts +12 -0
- package/dist/overlays/DrawerSurface.svelte.test.d.ts +1 -0
- package/dist/overlays/DrawerSurface.svelte.test.js +67 -0
- package/dist/overlays/ModalFrame.svelte +3 -1
- package/dist/overlays/ModalFrame.svelte.d.ts +1 -0
- package/dist/overlays/OverlayRoots.svelte +12 -9
- package/dist/overlays/floatDismiss.js +5 -0
- package/dist/overlays/focusTrap.d.ts +11 -1
- package/dist/overlays/focusTrap.js +11 -9
- package/dist/overlays/modal.js +1 -0
- package/dist/overlays/popup.js +4 -0
- package/dist/overlays/types.d.ts +10 -1
- package/dist/primitives/Button.svelte +18 -0
- package/dist/primitives/Button.svelte.d.ts +6 -0
- package/dist/primitives/ResizableSplitter.svelte +71 -11
- package/dist/primitives/ResizableSplitter.svelte.d.ts +8 -0
- package/dist/primitives/ResizableSplitter.svelte.test.d.ts +1 -0
- package/dist/primitives/ResizableSplitter.svelte.test.js +74 -0
- package/dist/server-shard/types.d.ts +2 -1
- package/dist/sh3Api/headless.js +9 -1
- package/dist/sh3Api/headless.svelte.test.js +45 -1
- package/dist/sh3Runtime.svelte.d.ts +36 -0
- package/dist/sh3Runtime.svelte.js +33 -0
- package/dist/shards/activate.svelte.js +10 -0
- package/dist/shards/ctx-fetch.test.d.ts +1 -0
- package/dist/shards/ctx-fetch.test.js +66 -0
- package/dist/shards/types.d.ts +22 -1
- package/dist/tokens.css +3 -2
- package/dist/transport/apiFetch.d.ts +1 -0
- package/dist/transport/apiFetch.js +65 -0
- package/dist/transport/apiFetch.test.d.ts +1 -0
- package/dist/transport/apiFetch.test.js +37 -0
- package/dist/transport/authToken.d.ts +2 -0
- package/dist/transport/authToken.js +53 -0
- package/dist/transport/authToken.test.d.ts +1 -0
- package/dist/transport/authToken.test.js +33 -0
- package/dist/verbs/types.d.ts +5 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/viewport/classify.d.ts +8 -0
- package/dist/viewport/classify.js +20 -0
- package/dist/viewport/classify.test.d.ts +1 -0
- package/dist/viewport/classify.test.js +32 -0
- package/dist/viewport/store.browser.test.d.ts +1 -0
- package/dist/viewport/store.browser.test.js +33 -0
- package/dist/viewport/store.svelte.d.ts +9 -0
- package/dist/viewport/store.svelte.js +71 -0
- package/dist/viewport/store.svelte.test.d.ts +1 -0
- package/dist/viewport/store.svelte.test.js +54 -0
- package/dist/viewport/types.d.ts +9 -0
- package/dist/viewport/types.js +6 -0
- package/package.json +1 -1
package/dist/Sh3.svelte
CHANGED
|
@@ -26,6 +26,12 @@
|
|
|
26
26
|
import { startServerSideStream } from './keys/revocation-bus.svelte';
|
|
27
27
|
import BrandSlot from './BrandSlot.svelte';
|
|
28
28
|
import MenuBar from './actions/MenuBar.svelte';
|
|
29
|
+
import CompactChrome from './chrome/CompactChrome.svelte';
|
|
30
|
+
import CompactRenderer from './layout/compact/CompactRenderer.svelte';
|
|
31
|
+
import { sh3 } from './sh3Runtime.svelte';
|
|
32
|
+
import { claim, revoke } from './gestures/pointerClaim';
|
|
33
|
+
|
|
34
|
+
let contentEl: HTMLElement | undefined = $state();
|
|
29
35
|
|
|
30
36
|
const authenticated = $derived(isAuthenticated());
|
|
31
37
|
const user = $derived(getUser());
|
|
@@ -34,6 +40,8 @@
|
|
|
34
40
|
// getActiveApp() here: returnToHome() keeps the app warm (activeApp.id
|
|
35
41
|
// stays set) and only flips the layout store's activeRoot back to 'home'.
|
|
36
42
|
const onHome = $derived(getActiveRoot() === 'home');
|
|
43
|
+
// Reactive viewport class — drives the compact-vs-desktop chrome/body fork.
|
|
44
|
+
const viewportClass = $derived(sh3.viewport.current.class);
|
|
37
45
|
|
|
38
46
|
// Keep the actions dispatcher's `mountedViewIds` set in sync with the
|
|
39
47
|
// live layout tree, so `view:<viewId>` scope checks (context menu,
|
|
@@ -58,52 +66,99 @@
|
|
|
58
66
|
const stop = startServerSideStream();
|
|
59
67
|
return stop;
|
|
60
68
|
});
|
|
69
|
+
|
|
70
|
+
// Register left/right edge zones as priority:'edge' pointer claims so that
|
|
71
|
+
// any shard with a priority:'normal' claim automatically beats the shell's
|
|
72
|
+
// edge-swipe gesture (carousel navigation, future side-panel reveals).
|
|
73
|
+
const EDGE_PX = 24;
|
|
74
|
+
$effect(() => {
|
|
75
|
+
const el = contentEl;
|
|
76
|
+
if (!el) return;
|
|
77
|
+
|
|
78
|
+
const edgePointers = new Set<number>();
|
|
79
|
+
|
|
80
|
+
function onPointerDown(e: PointerEvent): void {
|
|
81
|
+
const rect = el.getBoundingClientRect();
|
|
82
|
+
const local = e.clientX - rect.left;
|
|
83
|
+
if (local >= EDGE_PX && local <= rect.width - EDGE_PX) return;
|
|
84
|
+
const granted = claim(e.pointerId, { ownerId: 'sh3:edge', axis: 'x', priority: 'edge', depth: 0 });
|
|
85
|
+
if (granted) edgePointers.add(e.pointerId);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function onPointerEnd(e: PointerEvent): void {
|
|
89
|
+
if (!edgePointers.has(e.pointerId)) return;
|
|
90
|
+
revoke(e.pointerId, 'sh3:edge');
|
|
91
|
+
edgePointers.delete(e.pointerId);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
el.addEventListener('pointerdown', onPointerDown);
|
|
95
|
+
el.addEventListener('pointerup', onPointerEnd);
|
|
96
|
+
el.addEventListener('pointercancel', onPointerEnd);
|
|
97
|
+
|
|
98
|
+
return () => {
|
|
99
|
+
el.removeEventListener('pointerdown', onPointerDown);
|
|
100
|
+
el.removeEventListener('pointerup', onPointerEnd);
|
|
101
|
+
el.removeEventListener('pointercancel', onPointerEnd);
|
|
102
|
+
for (const id of edgePointers) revoke(id, 'sh3:edge');
|
|
103
|
+
edgePointers.clear();
|
|
104
|
+
};
|
|
105
|
+
});
|
|
61
106
|
</script>
|
|
62
107
|
|
|
63
|
-
<div class="sh3">
|
|
64
|
-
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
<div class="sh3" data-sh3-viewport={viewportClass}>
|
|
109
|
+
{#if viewportClass === 'desktop'}
|
|
110
|
+
<header class="sh3-tabbar" data-sh3-region="tabbar">
|
|
111
|
+
<button
|
|
112
|
+
type="button"
|
|
113
|
+
class="sh3-tabbar-home-button"
|
|
114
|
+
onclick={() => returnToHome()}
|
|
115
|
+
disabled={onHome}
|
|
116
|
+
title="Home"
|
|
117
|
+
>
|
|
118
|
+
<svg class="sh3-tabbar-home-icon" aria-hidden="true">
|
|
119
|
+
<use href="{iconsUrl}#house" />
|
|
120
|
+
</svg>
|
|
121
|
+
</button>
|
|
122
|
+
<BrandSlot />
|
|
123
|
+
<MenuBar />
|
|
124
|
+
{#if authenticated && user}
|
|
125
|
+
<div class="sh3-tabbar-user">
|
|
126
|
+
<span class="sh3-tabbar-user-name">{user.displayName}</span>
|
|
127
|
+
<span class="sh3-tabbar-tag">{elevated ? 'admin' : 'user'}</span>
|
|
128
|
+
{#if !isLocalOwner()}
|
|
129
|
+
<button
|
|
130
|
+
type="button"
|
|
131
|
+
class="sh3-tabbar-signout"
|
|
132
|
+
onclick={() => logout()}
|
|
133
|
+
title="Sign out"
|
|
134
|
+
>
|
|
135
|
+
<svg class="sh3-tabbar-signout-icon" aria-hidden="true">
|
|
136
|
+
<use href="{iconsUrl}#log-out" />
|
|
137
|
+
</svg>
|
|
138
|
+
</button>
|
|
139
|
+
{/if}
|
|
140
|
+
</div>
|
|
141
|
+
{/if}
|
|
142
|
+
</header>
|
|
143
|
+
{:else}
|
|
144
|
+
<CompactChrome />
|
|
145
|
+
{/if}
|
|
97
146
|
|
|
98
147
|
<GuestBanner />
|
|
99
148
|
|
|
100
|
-
<main class="sh3-content" data-sh3-region="content" data-sh3-layer="0">
|
|
101
|
-
|
|
149
|
+
<main class="sh3-content" data-sh3-region="content" data-sh3-layer="0" bind:this={contentEl}>
|
|
150
|
+
{#if viewportClass === 'desktop'}
|
|
151
|
+
<LayoutRenderer />
|
|
152
|
+
{:else}
|
|
153
|
+
<CompactRenderer />
|
|
154
|
+
{/if}
|
|
102
155
|
</main>
|
|
103
156
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
157
|
+
{#if viewportClass === 'desktop'}
|
|
158
|
+
<footer class="sh3-statusbar" data-sh3-region="statusbar">
|
|
159
|
+
<!-- alpha tag moved to Sh3Home title row -->
|
|
160
|
+
</footer>
|
|
161
|
+
{/if}
|
|
107
162
|
|
|
108
163
|
<OverlayRoots />
|
|
109
164
|
|
|
@@ -125,6 +180,19 @@
|
|
|
125
180
|
position: relative;
|
|
126
181
|
background: var(--sh3-grad-bg, var(--sh3-bg));
|
|
127
182
|
color: var(--sh3-fg);
|
|
183
|
+
/* Edge-to-edge platforms (Tauri Android in particular) draw the
|
|
184
|
+
* webview under the system status / navigation bars. env() resolves
|
|
185
|
+
* to 0 elsewhere, so this is a no-op on desktop browsers and
|
|
186
|
+
* windowed Tauri builds. box-sizing on body/html is `content-box`
|
|
187
|
+
* by default, so padding here shrinks the grid area accordingly. */
|
|
188
|
+
box-sizing: border-box;
|
|
189
|
+
padding-top: env(safe-area-inset-top);
|
|
190
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
191
|
+
padding-left: env(safe-area-inset-left);
|
|
192
|
+
padding-right: env(safe-area-inset-right);
|
|
193
|
+
}
|
|
194
|
+
.sh3[data-sh3-viewport='compact'] {
|
|
195
|
+
grid-template-rows: var(--sh3-tabbar-height) auto 1fr;
|
|
128
196
|
}
|
|
129
197
|
|
|
130
198
|
.sh3-tabbar {
|
|
Binary file
|
|
@@ -35,9 +35,8 @@
|
|
|
35
35
|
}
|
|
36
36
|
</script>
|
|
37
37
|
|
|
38
|
-
<!-- svelte-ignore a11y_autofocus -->
|
|
39
38
|
<div class="sh3-palette" role="dialog" aria-label="Command palette" aria-modal="true" tabindex="-1" onkeydown={onKeydown}>
|
|
40
|
-
<input class="sh3-palette-input hell-base-input" bind:value={query}
|
|
39
|
+
<input class="sh3-palette-input hell-base-input" bind:value={query} placeholder="Command…" />
|
|
41
40
|
<div class="sh3-palette-list" role="listbox">
|
|
42
41
|
{#each ranked as item, i (item.id)}
|
|
43
42
|
<button
|
|
@@ -75,4 +75,33 @@ describe('listActionsFromEntries', () => {
|
|
|
75
75
|
expect(out).toHaveLength(1);
|
|
76
76
|
expect(out[0].ownerShardId).toBe('shard.a');
|
|
77
77
|
});
|
|
78
|
+
it('passes through submenu=true on a parent descriptor', () => {
|
|
79
|
+
const entries = [{
|
|
80
|
+
ownerShardId: 'shard.x',
|
|
81
|
+
action: { id: 'p', label: 'P', scope: 'home', submenu: true },
|
|
82
|
+
}];
|
|
83
|
+
const out = listActionsFromEntries(entries, mkState());
|
|
84
|
+
expect(out[0].submenu).toBe(true);
|
|
85
|
+
expect(out[0].submenuOf).toBeUndefined();
|
|
86
|
+
});
|
|
87
|
+
it('passes through submenuOf on a child descriptor', () => {
|
|
88
|
+
const entries = [
|
|
89
|
+
{
|
|
90
|
+
ownerShardId: 'shard.x',
|
|
91
|
+
action: {
|
|
92
|
+
id: 'p:dark', label: 'Dark', scope: 'home',
|
|
93
|
+
submenuOf: 'p', run: () => { },
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
const out = listActionsFromEntries(entries, mkState());
|
|
98
|
+
expect(out[0].submenuOf).toBe('p');
|
|
99
|
+
expect(out[0].submenu).toBeUndefined();
|
|
100
|
+
});
|
|
101
|
+
it('omits submenu and submenuOf on plain actions', () => {
|
|
102
|
+
const entries = [mkEntry({ id: 'plain', scope: 'home' })];
|
|
103
|
+
const out = listActionsFromEntries(entries, mkState());
|
|
104
|
+
expect(out[0].submenu).toBeUndefined();
|
|
105
|
+
expect(out[0].submenuOf).toBeUndefined();
|
|
106
|
+
});
|
|
78
107
|
});
|
|
@@ -50,6 +50,8 @@ export function listActionsFromEntries(entries, state) {
|
|
|
50
50
|
ownerShardId: entry.ownerShardId,
|
|
51
51
|
paletteItem: entry.action.paletteItem !== false,
|
|
52
52
|
contextItem: entry.action.contextItem !== false,
|
|
53
|
+
submenu: entry.action.submenu,
|
|
54
|
+
submenuOf: entry.action.submenuOf,
|
|
53
55
|
active,
|
|
54
56
|
};
|
|
55
57
|
if (active) {
|
|
@@ -94,6 +94,10 @@ export function dispatchActionProgrammatic(actionId, _opts) {
|
|
|
94
94
|
const state = getLiveDispatcherState();
|
|
95
95
|
const desc = listActionsFromEntries(entries, state).find((d) => d.id === actionId);
|
|
96
96
|
if (!desc || !desc.active) {
|
|
97
|
+
if (entry.action.submenu === true &&
|
|
98
|
+
typeof entry.action.run !== 'function') {
|
|
99
|
+
return Promise.reject(new Error(`action "${actionId}" is a submenu parent — list children with listActions({ submenuOf: "${actionId}" })`));
|
|
100
|
+
}
|
|
97
101
|
return Promise.reject(new Error(`action "${actionId}" is not active in current scope`));
|
|
98
102
|
}
|
|
99
103
|
// run is guaranteed non-null by `desc.active === true`.
|
|
@@ -345,7 +349,18 @@ export function openPalette(opts) {
|
|
|
345
349
|
}
|
|
346
350
|
},
|
|
347
351
|
onClose: () => handle.close(),
|
|
348
|
-
}, {
|
|
352
|
+
}, {
|
|
353
|
+
dismissOnBackdrop: true,
|
|
354
|
+
// On touch-only devices, autofocusing the palette input pops the
|
|
355
|
+
// on-screen keyboard before the user has expressed intent to type
|
|
356
|
+
// — the toolbar-button entry path expects to tap a result, not
|
|
357
|
+
// type. Discriminant: a touch-only device (no hover, coarse
|
|
358
|
+
// pointer) — desktop browsers and laptops with touchscreens
|
|
359
|
+
// still report `(any-hover: hover)`.
|
|
360
|
+
initialFocus: !(typeof window !== 'undefined'
|
|
361
|
+
&& typeof window.matchMedia === 'function'
|
|
362
|
+
&& window.matchMedia('(hover: none) and (pointer: coarse)').matches),
|
|
363
|
+
});
|
|
349
364
|
if (previousFocus) {
|
|
350
365
|
const innerClose = handle.close;
|
|
351
366
|
handle.close = () => {
|
|
@@ -34,11 +34,18 @@ describe('dispatchActionProgrammatic', () => {
|
|
|
34
34
|
await expect(dispatchActionProgrammatic('d')).rejects.toThrow(/action "d" is not active/);
|
|
35
35
|
expect(run).not.toHaveBeenCalled();
|
|
36
36
|
});
|
|
37
|
-
it('rejects on a submenu parent
|
|
37
|
+
it('rejects on a submenu parent with the parent-specific message', async () => {
|
|
38
38
|
registerAction({
|
|
39
39
|
id: 's', label: 'S', scope: 'home', submenu: true,
|
|
40
40
|
}, 'shard.x');
|
|
41
|
-
await expect(dispatchActionProgrammatic('s')).rejects.toThrow(/action "s" is
|
|
41
|
+
await expect(dispatchActionProgrammatic('s')).rejects.toThrow(/action "s" is a submenu parent — list children with listActions\(\{ submenuOf: "s" \}\)/);
|
|
42
|
+
});
|
|
43
|
+
it('still uses the generic inactive message for non-submenu inactive actions', async () => {
|
|
44
|
+
registerAction({
|
|
45
|
+
id: 'gated2', label: 'G', scope: 'app', run: () => { },
|
|
46
|
+
}, 'shard.x');
|
|
47
|
+
// No active app -> 'app' scope is inactive.
|
|
48
|
+
await expect(dispatchActionProgrammatic('gated2')).rejects.toThrow(/action "gated2" is not active/);
|
|
42
49
|
});
|
|
43
50
|
it('invokes run with invokedVia="programmatic" on happy path', async () => {
|
|
44
51
|
let captured = null;
|
package/dist/actions/types.d.ts
CHANGED
|
@@ -148,6 +148,10 @@ export interface ActiveActionDescriptor {
|
|
|
148
148
|
ownerShardId: string;
|
|
149
149
|
paletteItem: boolean;
|
|
150
150
|
contextItem: boolean;
|
|
151
|
+
/** True when this action is a submenu parent (children opened by drill). */
|
|
152
|
+
submenu?: true;
|
|
153
|
+
/** Parent action id when this action is a submenu child. */
|
|
154
|
+
submenuOf?: string;
|
|
151
155
|
}
|
|
152
156
|
/**
|
|
153
157
|
* Read-only snapshot describing one action in the registry. Produced by
|
|
@@ -183,6 +187,10 @@ export interface ActionDescriptor {
|
|
|
183
187
|
ownerShardId: string;
|
|
184
188
|
paletteItem: boolean;
|
|
185
189
|
contextItem: boolean;
|
|
190
|
+
/** True when this action is a submenu parent (children opened by drill). */
|
|
191
|
+
submenu?: true;
|
|
192
|
+
/** Parent action id when this action is a submenu child. */
|
|
193
|
+
submenuOf?: string;
|
|
186
194
|
/** True when `runAction(id)` would dispatch right now. */
|
|
187
195
|
active: boolean;
|
|
188
196
|
}
|
package/dist/api.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export { sh3 } from './sh3Runtime.svelte';
|
|
2
|
-
export type { Sh3 } from './sh3Runtime.svelte';
|
|
2
|
+
export type { Sh3, Sh3Drawers, Sh3Viewport } from './sh3Runtime.svelte';
|
|
3
|
+
export type { ViewportClass, ViewportInfo } from './viewport/types';
|
|
4
|
+
export type { SlotRole } from './layout/types';
|
|
5
|
+
export type { DrawerAnchor, DrawerSpec, DrawerState, DrawerStateMap, CompactRendering, } from './layout/compact/types';
|
|
3
6
|
export type { Shard, ShardManifest, SourceShard, SourceShardManifest, ShardContext, ViewDeclaration, ViewFactory, ViewHandle, MountContext, } from './shards/types';
|
|
4
7
|
export type { LayoutNode, SplitNode, TabsNode, SlotNode, TabEntry, SplitDirection, SizeMode, LayoutTree, FloatEntry, LayoutPreset, CanonicalPreset, TreeRootRef as SlotLocation, } from './layout/types';
|
|
5
8
|
export type { ActionDescriptor, ActiveActionDescriptor, BindingSource, AtomicScope, ActionScope, } from './actions/types';
|
|
@@ -16,6 +19,8 @@ export type { EnvState } from './env/types';
|
|
|
16
19
|
export type { App, AppManifest, SourceApp, SourceAppManifest, AppContext, } from './apps/types';
|
|
17
20
|
export { listRegisteredApps, getActiveApp } from './apps/registry.svelte';
|
|
18
21
|
export { launchApp, returnToHome, unregisterApp } from './apps/lifecycle';
|
|
22
|
+
export type { LaunchAppOptions } from './apps/lifecycle';
|
|
23
|
+
export type { FileRef, FileHandlerDescriptor, FileHandlerMatch, FileHandlerHeader, FileHandlerPattern, FileHandlerOpen, } from './files/types';
|
|
19
24
|
export { pushNavEntry } from './navigation';
|
|
20
25
|
export type { NavEntry, NavEntryHandle } from './navigation';
|
|
21
26
|
export { spawnSatellite } from './sh3Api/window';
|
|
@@ -58,6 +63,8 @@ export type { RunVerbOpts, RunVerbResult } from './runtime';
|
|
|
58
63
|
export { registerShellMode } from './shell-shard/registerShellMode';
|
|
59
64
|
export type { ShellModeDescriptor, ShellModeOutput, ShellModeDispatchHandler, ShellModeDispatchInput, ShellModeRunsOn, RichEntryHandle, StreamHandle, } from './shell-shard/contract';
|
|
60
65
|
export { SHELL_MODE_CONTRIBUTION_POINT } from './shell-shard/contract';
|
|
66
|
+
export type { GestureRegistry, GestureHandle } from './gestures';
|
|
67
|
+
export type { GestureType, Axis, ClaimPriority, ClaimEntry, PanEvent, ScrollEvent, ButtonEvent, PanOptions, DragOptions, ButtonOptions, ScrollOptions, } from './gestures/types';
|
|
61
68
|
export { VERSION } from './version';
|
|
62
69
|
export declare const FRAMEWORK_SHARD_IDS: readonly string[];
|
|
63
70
|
export { setTokenOverrides, clearTokenOverrides, getTokenOverrides, } from './theme';
|
|
@@ -26,27 +26,7 @@ import { extractBundlePermissions } from '../../registry/permission-descriptions
|
|
|
26
26
|
import { serverInstallPackage, fetchServerPackages, serverUninstallPackage } from '../../env/client';
|
|
27
27
|
import { VERSION } from '../../version';
|
|
28
28
|
import { installVerb, uninstallVerb, appinfoVerb, updateVerb } from './verbs';
|
|
29
|
-
|
|
30
|
-
* Compare two semver-like version strings.
|
|
31
|
-
* Returns true only if `available` is strictly greater than `installed`.
|
|
32
|
-
* Compares major.minor.patch left-to-right as integers.
|
|
33
|
-
* Non-numeric segments are treated as 0.
|
|
34
|
-
*/
|
|
35
|
-
function isNewerVersion(available, installed) {
|
|
36
|
-
var _a, _b;
|
|
37
|
-
const a = available.split('.').map((s) => parseInt(s, 10) || 0);
|
|
38
|
-
const b = installed.split('.').map((s) => parseInt(s, 10) || 0);
|
|
39
|
-
const len = Math.max(a.length, b.length);
|
|
40
|
-
for (let i = 0; i < len; i++) {
|
|
41
|
-
const av = (_a = a[i]) !== null && _a !== void 0 ? _a : 0;
|
|
42
|
-
const bv = (_b = b[i]) !== null && _b !== void 0 ? _b : 0;
|
|
43
|
-
if (av > bv)
|
|
44
|
-
return true;
|
|
45
|
-
if (av < bv)
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
29
|
+
import { isNewerVersion } from './version';
|
|
50
30
|
/**
|
|
51
31
|
* Pick a version entry from a resolved package. When `requested` is
|
|
52
32
|
* undefined returns `latest`; when set, finds the matching entry by
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare two artifact version strings for the app store update check.
|
|
3
|
+
*
|
|
4
|
+
* Handles semver build-metadata suffixes (`+N`): per ADR-013 the build suffix
|
|
5
|
+
* represents artifact iterations of the same release, so `1.0.0+1 > 1.0.0`
|
|
6
|
+
* and `1.0.0+2 > 1.0.0+1`. A canonical release (no suffix) is not considered
|
|
7
|
+
* newer than a suffixed one.
|
|
8
|
+
*
|
|
9
|
+
* Returns true only when `available` is strictly greater than `installed`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isNewerVersion(available: string, installed: string): boolean;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare two artifact version strings for the app store update check.
|
|
3
|
+
*
|
|
4
|
+
* Handles semver build-metadata suffixes (`+N`): per ADR-013 the build suffix
|
|
5
|
+
* represents artifact iterations of the same release, so `1.0.0+1 > 1.0.0`
|
|
6
|
+
* and `1.0.0+2 > 1.0.0+1`. A canonical release (no suffix) is not considered
|
|
7
|
+
* newer than a suffixed one.
|
|
8
|
+
*
|
|
9
|
+
* Returns true only when `available` is strictly greater than `installed`.
|
|
10
|
+
*/
|
|
11
|
+
export function isNewerVersion(available, installed) {
|
|
12
|
+
var _a, _b;
|
|
13
|
+
const [aRelease = '', aBuild = ''] = available.split('+');
|
|
14
|
+
const [bRelease = '', bBuild = ''] = installed.split('+');
|
|
15
|
+
const a = aRelease.split('.').map((s) => parseInt(s, 10) || 0);
|
|
16
|
+
const b = bRelease.split('.').map((s) => parseInt(s, 10) || 0);
|
|
17
|
+
const len = Math.max(a.length, b.length);
|
|
18
|
+
for (let i = 0; i < len; i++) {
|
|
19
|
+
const av = (_a = a[i]) !== null && _a !== void 0 ? _a : 0;
|
|
20
|
+
const bv = (_b = b[i]) !== null && _b !== void 0 ? _b : 0;
|
|
21
|
+
if (av > bv)
|
|
22
|
+
return true;
|
|
23
|
+
if (av < bv)
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
// Release versions are equal — compare build metadata.
|
|
27
|
+
// absent (canonical) < any suffix; numeric suffix compared numerically.
|
|
28
|
+
if (aBuild === bBuild)
|
|
29
|
+
return false;
|
|
30
|
+
if (aBuild === '')
|
|
31
|
+
return false; // canonical is not newer than suffixed
|
|
32
|
+
if (bBuild === '')
|
|
33
|
+
return true; // suffixed is newer than canonical
|
|
34
|
+
const an = parseInt(aBuild, 10);
|
|
35
|
+
const bn = parseInt(bBuild, 10);
|
|
36
|
+
if (!isNaN(an) && !isNaN(bn))
|
|
37
|
+
return an > bn;
|
|
38
|
+
return aBuild > bBuild; // lexicographic fallback for non-numeric suffixes
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { isNewerVersion } from './version';
|
|
3
|
+
describe('isNewerVersion', () => {
|
|
4
|
+
describe('standard semver (no build metadata)', () => {
|
|
5
|
+
it('returns true when available has higher major', () => {
|
|
6
|
+
expect(isNewerVersion('2.0.0', '1.9.9')).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
it('returns true when available has higher minor', () => {
|
|
9
|
+
expect(isNewerVersion('0.2.0', '0.1.9')).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
it('returns true when available has higher patch', () => {
|
|
12
|
+
expect(isNewerVersion('0.1.1', '0.1.0')).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
it('returns false when available is lower', () => {
|
|
15
|
+
expect(isNewerVersion('0.1.0', '1.0.0')).toBe(false);
|
|
16
|
+
});
|
|
17
|
+
it('returns false when versions are equal', () => {
|
|
18
|
+
expect(isNewerVersion('0.1.0', '0.1.0')).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('build metadata suffix (+N)', () => {
|
|
22
|
+
it('returns true when available has suffix and installed does not', () => {
|
|
23
|
+
expect(isNewerVersion('0.1.0+1', '0.1.0')).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
it('returns false when available has no suffix and installed does', () => {
|
|
26
|
+
expect(isNewerVersion('0.1.0', '0.1.0+1')).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
it('returns true when available has higher numeric suffix', () => {
|
|
29
|
+
expect(isNewerVersion('0.1.0+2', '0.1.0+1')).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
it('returns false when available has lower numeric suffix', () => {
|
|
32
|
+
expect(isNewerVersion('0.1.0+1', '0.1.0+2')).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
it('returns false when suffixes are equal', () => {
|
|
35
|
+
expect(isNewerVersion('0.1.0+1', '0.1.0+1')).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
it('higher build suffix does not beat higher release version', () => {
|
|
38
|
+
expect(isNewerVersion('0.1.0+99', '0.2.0')).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
it('higher release version beats any build suffix', () => {
|
|
41
|
+
expect(isNewerVersion('0.2.0', '0.1.0+99')).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
package/dist/apps/lifecycle.d.ts
CHANGED
|
@@ -25,6 +25,12 @@ export interface LaunchAppOptions {
|
|
|
25
25
|
* "home" view to return to first.
|
|
26
26
|
*/
|
|
27
27
|
skipSwitchToHome?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Arbitrary data passed to the app at launch time. Available as
|
|
30
|
+
* `ctx.args` in `App.activate` and `App.onAppReady`.
|
|
31
|
+
* Ignored on re-entry (resume) — the app's existing context is reused.
|
|
32
|
+
*/
|
|
33
|
+
args?: Record<string, unknown>;
|
|
28
34
|
}
|
|
29
35
|
/**
|
|
30
36
|
* Launch an app by id. Activates all required shards (idempotent for
|
package/dist/apps/lifecycle.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* return-to-home (null). Boot reads it to decide whether to auto-launch.
|
|
13
13
|
*/
|
|
14
14
|
import { createStateZones } from '../state/zones.svelte';
|
|
15
|
+
import { createGestureRegistry } from '../gestures';
|
|
15
16
|
import { activateShard, deactivateShard, getShardContext, registeredShards, } from '../shards/activate.svelte';
|
|
16
17
|
import { attachApp, acquireAppSlotHolds, detachApp, switchToApp, switchToHome, } from '../layout/store.svelte';
|
|
17
18
|
import { activeApp, breadcrumbApp, getRegisteredApp, registeredApps } from './registry.svelte';
|
|
@@ -60,7 +61,7 @@ function resolveLaunchScope() {
|
|
|
60
61
|
var _a;
|
|
61
62
|
return (_a = sessionState.activeProjectId) !== null && _a !== void 0 ? _a : getActiveScopeId();
|
|
62
63
|
}
|
|
63
|
-
function getOrCreateAppContext(appId, scopeId) {
|
|
64
|
+
function getOrCreateAppContext(appId, scopeId, args) {
|
|
64
65
|
var _a;
|
|
65
66
|
let ctx = appContexts.get(appId);
|
|
66
67
|
if (!ctx) {
|
|
@@ -68,10 +69,12 @@ function getOrCreateAppContext(appId, scopeId) {
|
|
|
68
69
|
const scope = scopeId !== null && scopeId !== void 0 ? scopeId : resolveLaunchScope();
|
|
69
70
|
ctx = {
|
|
70
71
|
scopeId: scope,
|
|
72
|
+
args: args !== null && args !== void 0 ? args : {},
|
|
71
73
|
state: (schema) => createStateZones(`__app__:${appId}:scope:${scope}`, schema),
|
|
72
74
|
zones: ((_a = app === null || app === void 0 ? void 0 : app.manifest.permissions) === null || _a === void 0 ? void 0 : _a.includes(PERMISSION_STATE_MANAGE))
|
|
73
75
|
? createZoneManager()
|
|
74
76
|
: undefined,
|
|
77
|
+
gestures: createGestureRegistry(typeof document !== 'undefined' ? document.body : null),
|
|
75
78
|
};
|
|
76
79
|
appContexts.set(appId, ctx);
|
|
77
80
|
}
|
|
@@ -156,7 +159,7 @@ export async function launchApp(id, opts = {}) {
|
|
|
156
159
|
// refcount holds on the app's slots now (pool's factory lookup
|
|
157
160
|
// happens in a microtask from this call).
|
|
158
161
|
acquireAppSlotHolds();
|
|
159
|
-
void ((_f = app.activate) === null || _f === void 0 ? void 0 : _f.call(app, getOrCreateAppContext(id)));
|
|
162
|
+
void ((_f = app.activate) === null || _f === void 0 ? void 0 : _f.call(app, getOrCreateAppContext(id, undefined, opts.args)));
|
|
160
163
|
activeApp.id = id;
|
|
161
164
|
setActiveApp(id, new Set((_g = app.manifest.requiredShards) !== null && _g !== void 0 ? _g : []));
|
|
162
165
|
void loadUserBindings(id).then(setUserBindings);
|
|
@@ -630,3 +630,33 @@ describe('launchApp — scenario D.1 skipLastApp option', () => {
|
|
|
630
630
|
expect(readLastApp()).toBe('app-default-last');
|
|
631
631
|
});
|
|
632
632
|
});
|
|
633
|
+
// ---------------------------------------------------------------------------
|
|
634
|
+
// Launch args — ctx.args
|
|
635
|
+
// ---------------------------------------------------------------------------
|
|
636
|
+
describe('launchApp — ctx.args', () => {
|
|
637
|
+
beforeEach(resetFramework);
|
|
638
|
+
it('passes args to activate via ctx.args', async () => {
|
|
639
|
+
let receivedArgs;
|
|
640
|
+
const shard = makeShard({ manifest: makeShardManifest({ id: 'shard-args' }) });
|
|
641
|
+
registerShard(shard);
|
|
642
|
+
const app = makeApp({
|
|
643
|
+
manifest: makeAppManifest({ id: 'app-args', requiredShards: ['shard-args'] }),
|
|
644
|
+
activate: (ctx) => { receivedArgs = ctx.args; },
|
|
645
|
+
});
|
|
646
|
+
registerApp(app);
|
|
647
|
+
await launchApp('app-args', { args: { file: { path: '/doc.svg', tenantId: 'alice', binary: false } } });
|
|
648
|
+
expect(receivedArgs).toEqual({ file: { path: '/doc.svg', tenantId: 'alice', binary: false } });
|
|
649
|
+
});
|
|
650
|
+
it('defaults ctx.args to empty object when no args passed', async () => {
|
|
651
|
+
let receivedArgs;
|
|
652
|
+
const shard = makeShard({ manifest: makeShardManifest({ id: 'shard-noargs' }) });
|
|
653
|
+
registerShard(shard);
|
|
654
|
+
const app = makeApp({
|
|
655
|
+
manifest: makeAppManifest({ id: 'app-noargs', requiredShards: ['shard-noargs'] }),
|
|
656
|
+
activate: (ctx) => { receivedArgs = ctx.args; },
|
|
657
|
+
});
|
|
658
|
+
registerApp(app);
|
|
659
|
+
await launchApp('app-noargs');
|
|
660
|
+
expect(receivedArgs).toEqual({});
|
|
661
|
+
});
|
|
662
|
+
});
|
package/dist/apps/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { LayoutNode, LayoutTree, LayoutPreset } from '../layout/types';
|
|
2
2
|
import type { ZoneSchema, ZoneManager } from '../state/types';
|
|
3
3
|
import type { StateZones } from '../state/zones.svelte';
|
|
4
|
+
import type { GestureRegistry } from '../gestures';
|
|
4
5
|
/**
|
|
5
6
|
* One menu bar container ("File", "Edit", etc.). Apps declare these in
|
|
6
7
|
* `AppManifest.menus`; when omitted, sh3-core uses DEFAULT_MENU_CONTAINERS.
|
|
@@ -95,6 +96,12 @@ export interface AppContext {
|
|
|
95
96
|
* scope and cannot reach across scopes — exiting a scope unloads the app.
|
|
96
97
|
*/
|
|
97
98
|
scopeId: string;
|
|
99
|
+
/**
|
|
100
|
+
* Arguments supplied by the caller at launch time via `LaunchAppOptions.args`.
|
|
101
|
+
* Defaults to `{}` when the app is launched without explicit args.
|
|
102
|
+
* Read-only — apps observe but do not mutate this object.
|
|
103
|
+
*/
|
|
104
|
+
readonly args: Record<string, unknown>;
|
|
98
105
|
/**
|
|
99
106
|
* App-scoped state zones. The shardId underneath is the app id plus the
|
|
100
107
|
* scope, so `state({ workspace: { x: 0 } }).workspace.x = 1` persists to
|
|
@@ -108,6 +115,11 @@ export interface AppContext {
|
|
|
108
115
|
* `if (ctx.zones)` before use.
|
|
109
116
|
*/
|
|
110
117
|
zones?: ZoneManager;
|
|
118
|
+
/**
|
|
119
|
+
* Per-app gesture binding API. Register Pan, Drag, Button, and Scroll
|
|
120
|
+
* handlers that participate in the shell's pointer arbitration protocol.
|
|
121
|
+
*/
|
|
122
|
+
gestures: GestureRegistry;
|
|
111
123
|
}
|
|
112
124
|
/**
|
|
113
125
|
* An app module. An app is a composition document — it declares required
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const ICON_IDS: readonly ["activity", "align-horizontal-justify-center", "align-horizontal-justify-end", "align-horizontal-justify-start", "app-window", "archive", "archive-restore", "axis-3d", "box", "brick-wall", "bug", "building-2", "cable", "calendar", "camera", "check", "chevron-down", "chevron-right", "circle-check", "circle-dot", "circle-minus", "circle-x", "clipboard", "clipboard-paste", "clock", "compass", "component", "copy", "cpu", "crop", "crosshair", "crown", "dollar-sign", "download", "droplet", "eraser", "euro", "external-link", "eye", "eye-off", "file", "file-archive", "file-diff", "file-plus", "file-text", "flame", "flip-horizontal-2", "flip-vertical-2", "folder", "folder-open", "folder-plus", "folder-tree", "gallery-vertical-end", "gamepad-2", "gauge", "gem", "git-branch", "git-commit-horizontal", "git-merge", "globe", "grid-2x2", "grid-3x3", "group", "hard-drive", "heart", "history", "house", "image", "info", "joystick", "key", "layers", "layout-dashboard", "layout-grid", "layout-list", "layout-panel-left", "layout-panel-top", "layout-template", "lightbulb", "link", "list-ordered", "list-tree", "lock", "log-out", "magnet", "mail", "map", "maximize", "minimize", "moon", "mouse-pointer", "move", "move-3d", "music", "navigation", "network", "notebook-pen", "palette", "pause", "pencil", "pipette", "play", "plus", "pointer", "pound-sterling", "receipt", "redo-2", "refresh-cw", "rocket", "rotate-3d", "rotate-ccw", "rotate-cw", "ruler", "save", "scissors", "scroll-text", "search", "send", "server", "settings", "shield", "skull", "sliders-horizontal", "snowflake", "sparkles", "square", "square-terminal", "star", "sun", "sword", "table-properties", "target", "texture", "timer", "trash-2", "triangle-alert", "type", "undo-2", "ungroup", "unity", "upload", "user", "users", "video", "volume-2", "wand-sparkles", "wind", "x", "zap", "zoom-in", "zoom-out"];
|
|
1
|
+
export declare const ICON_IDS: readonly ["activity", "align-horizontal-justify-center", "align-horizontal-justify-end", "align-horizontal-justify-start", "app-window", "archive", "archive-restore", "axis-3d", "box", "brick-wall", "bug", "building-2", "cable", "calendar", "camera", "check", "chevron-down", "chevron-right", "circle-check", "circle-dot", "circle-minus", "circle-x", "clipboard", "clipboard-paste", "clock", "command", "compass", "component", "copy", "cpu", "crop", "crosshair", "crown", "dollar-sign", "download", "droplet", "ellipsis-vertical", "eraser", "euro", "external-link", "eye", "eye-off", "file", "file-archive", "file-diff", "file-plus", "file-text", "flame", "flip-horizontal-2", "flip-vertical-2", "folder", "folder-open", "folder-plus", "folder-tree", "gallery-vertical-end", "gamepad-2", "gauge", "gem", "git-branch", "git-commit-horizontal", "git-merge", "globe", "grid-2x2", "grid-3x3", "group", "hard-drive", "heart", "history", "house", "image", "info", "joystick", "key", "layers", "layout-dashboard", "layout-grid", "layout-list", "layout-panel-left", "layout-panel-top", "layout-template", "lightbulb", "link", "list-ordered", "list-tree", "lock", "log-out", "magnet", "mail", "map", "maximize", "menu", "minimize", "moon", "mouse-pointer", "move", "move-3d", "music", "navigation", "network", "notebook-pen", "palette", "panel-right", "panel-top", "pause", "pencil", "pipette", "play", "plus", "pointer", "pound-sterling", "receipt", "redo-2", "refresh-cw", "rocket", "rotate-3d", "rotate-ccw", "rotate-cw", "ruler", "save", "scissors", "scroll-text", "search", "send", "server", "settings", "shield", "skull", "sliders-horizontal", "snowflake", "sparkles", "square", "square-terminal", "star", "sun", "sword", "table-properties", "target", "texture", "timer", "trash-2", "triangle-alert", "type", "undo-2", "ungroup", "unity", "upload", "user", "users", "video", "volume-2", "wand-sparkles", "wind", "x", "zap", "zoom-in", "zoom-out"];
|
|
2
2
|
export type IconId = (typeof ICON_IDS)[number];
|
|
@@ -25,6 +25,7 @@ export const ICON_IDS = [
|
|
|
25
25
|
'clipboard',
|
|
26
26
|
'clipboard-paste',
|
|
27
27
|
'clock',
|
|
28
|
+
'command',
|
|
28
29
|
'compass',
|
|
29
30
|
'component',
|
|
30
31
|
'copy',
|
|
@@ -35,6 +36,7 @@ export const ICON_IDS = [
|
|
|
35
36
|
'dollar-sign',
|
|
36
37
|
'download',
|
|
37
38
|
'droplet',
|
|
39
|
+
'ellipsis-vertical',
|
|
38
40
|
'eraser',
|
|
39
41
|
'euro',
|
|
40
42
|
'external-link',
|
|
@@ -88,6 +90,7 @@ export const ICON_IDS = [
|
|
|
88
90
|
'mail',
|
|
89
91
|
'map',
|
|
90
92
|
'maximize',
|
|
93
|
+
'menu',
|
|
91
94
|
'minimize',
|
|
92
95
|
'moon',
|
|
93
96
|
'mouse-pointer',
|
|
@@ -98,6 +101,8 @@ export const ICON_IDS = [
|
|
|
98
101
|
'network',
|
|
99
102
|
'notebook-pen',
|
|
100
103
|
'palette',
|
|
104
|
+
'panel-right',
|
|
105
|
+
'panel-top',
|
|
101
106
|
'pause',
|
|
102
107
|
'pencil',
|
|
103
108
|
'pipette',
|