dockview-svelte 0.0.1

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.
Files changed (36) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +480 -0
  3. package/dist/components/DefaultTab.svelte +55 -0
  4. package/dist/components/DefaultTab.svelte.d.ts +7 -0
  5. package/dist/components/Dockview.svelte +517 -0
  6. package/dist/components/Dockview.svelte.d.ts +113 -0
  7. package/dist/components/DvWidget.svelte +120 -0
  8. package/dist/components/DvWidget.svelte.d.ts +41 -0
  9. package/dist/components/Gridview.svelte +341 -0
  10. package/dist/components/Gridview.svelte.d.ts +73 -0
  11. package/dist/components/Paneview.svelte +307 -0
  12. package/dist/components/Paneview.svelte.d.ts +64 -0
  13. package/dist/components/Splitview.svelte +332 -0
  14. package/dist/components/Splitview.svelte.d.ts +70 -0
  15. package/dist/core/context.d.ts +62 -0
  16. package/dist/core/context.js +1 -0
  17. package/dist/core/effect-helpers.d.ts +7 -0
  18. package/dist/core/effect-helpers.js +23 -0
  19. package/dist/core/factory.svelte.d.ts +16 -0
  20. package/dist/core/factory.svelte.js +248 -0
  21. package/dist/core/gridview.svelte.d.ts +31 -0
  22. package/dist/core/gridview.svelte.js +177 -0
  23. package/dist/core/paneview-test-helpers.js +28 -0
  24. package/dist/core/paneview.svelte.d.ts +29 -0
  25. package/dist/core/paneview.svelte.js +186 -0
  26. package/dist/core/registry.d.ts +88 -0
  27. package/dist/core/registry.js +143 -0
  28. package/dist/core/splitview.svelte.d.ts +32 -0
  29. package/dist/core/splitview.svelte.js +179 -0
  30. package/dist/core/types.d.ts +424 -0
  31. package/dist/core/types.js +1 -0
  32. package/dist/core/utils.d.ts +12 -0
  33. package/dist/core/utils.js +59 -0
  34. package/dist/index.d.ts +9 -0
  35. package/dist/index.js +11 -0
  36. package/package.json +66 -0
@@ -0,0 +1,120 @@
1
+ <script lang="ts">
2
+ import { DEV } from 'esm-env'
3
+ import type { Snippet } from 'svelte'
4
+ import { getContext } from 'svelte'
5
+ import { DOCKVIEW_CONTEXT_KEY } from '../core/context.js'
6
+
7
+ /**
8
+ * Props for `<DvWidget>`.
9
+ *
10
+ * The `children` snippet receives the panel's shared `state` object — the same
11
+ * object a `widgets`-registry component receives as its `state` prop — and its
12
+ * output is rendered into the panel body (and tab/header, when given).
13
+ * `tab` / `header` snippets receive the same `state`.
14
+ *
15
+ * > **Type note:** the snippet parameter defaults to `never` on purpose — it
16
+ * > cannot be inferred per-widget, so annotate it with your panel's state type
17
+ * > (e.g. `{#snippet children(state: PanelState<{ id: number }>)}`). The
18
+ * > annotation is what gives you typed `state.params`.
19
+ *
20
+ * Usage:
21
+ *
22
+ * ```svelte
23
+ * <Dockview>
24
+ * <DvWidget name="chat" title="Chat">
25
+ * {#snippet children(state)}
26
+ * <ChatWidget {state} />
27
+ * {/snippet}
28
+ * </DvWidget>
29
+ * </Dockview>
30
+ * ```
31
+ */
32
+ interface Props {
33
+ /** Widget key this instance registers under. */
34
+ name: string
35
+ /** Body content, called with the shared `state`. */
36
+ children: Snippet<[state: never]>
37
+ /** Dockview tab override, called with the shared `PanelState` (Dockview only). */
38
+ tab?: Snippet<[state: never]>
39
+ /** Paneview header override, called with the shared `PaneviewState` (Paneview only). */
40
+ header?: Snippet<[state: never]>
41
+ /** Default title for this widget (tier 2 in the resolution chain). */
42
+ title?: string
43
+ }
44
+
45
+ let { name, children, tab, header, title }: Props = $props()
46
+
47
+ const ctx = getContext<{
48
+ kind: 'dockview' | 'splitview' | 'gridview' | 'paneview'
49
+ registerWidget: (key: string, def: Record<string, unknown>) => void
50
+ unregisterWidget: (key: string) => void
51
+ } | null>(DOCKVIEW_CONTEXT_KEY)
52
+ if (!ctx) {
53
+ throw new Error(
54
+ 'dockview-svelte: <DvWidget> must be a child of Dockview/Splitview/Gridview/Paneview'
55
+ )
56
+ }
57
+
58
+ // Snippets only apply to specific layouts; warn on inapplicable ones instead
59
+ // of silently dropping them (the per-layout registry ignores unknown keys).
60
+ $effect(() => {
61
+ if (!DEV) return
62
+ if (tab && ctx.kind !== 'dockview') {
63
+ console.warn(
64
+ `dockview-svelte: <DvWidget tab> is only supported by <Dockview>; ignored inside <${ctx.kind}>`
65
+ )
66
+ }
67
+ if (header && ctx.kind !== 'paneview') {
68
+ console.warn(
69
+ `dockview-svelte: <DvWidget header> is only supported by <Paneview>; ignored inside <${ctx.kind}>`
70
+ )
71
+ }
72
+ if (title !== undefined && ctx.kind !== 'dockview' && ctx.kind !== 'paneview') {
73
+ console.warn(
74
+ `dockview-svelte: <DvWidget title> is only supported by <Dockview>/<Paneview>; ignored inside <${ctx.kind}>`
75
+ )
76
+ }
77
+ })
78
+
79
+ /**
80
+ * Build a plain-function component around a snippet. The factories call
81
+ * `mount(component, { target, props: { state } })`, so the wrapper only needs
82
+ * to accept `{ state }` and invoke the snippet with the dockview-owned anchor.
83
+ * A plain function works because Svelte 5 `mount` invokes
84
+ * `Component(anchor, props)` directly (see `_mount` in `svelte/internal/client`).
85
+ *
86
+ * Compiled snippets are `(anchor, ...args)` functions where each arg is a
87
+ * getter thunk (see `svelte/compiler` output: `children($$anchor, () =>
88
+ * myState)`). Passing a thunk over the live `state` keeps reactive reads
89
+ * tracked.
90
+ */
91
+ function snippetComponent(snippet: Snippet<[state: never]>) {
92
+ return (anchor: Node, props: { state: never }) => {
93
+ ;(snippet as unknown as (node: Node, getState: () => never) => void)(anchor, () => props.state)
94
+ }
95
+ }
96
+
97
+ const component = $derived(snippetComponent(children as Snippet<[state: never]>))
98
+ const tabComponent = $derived(tab ? snippetComponent(tab as Snippet<[state: never]>) : undefined)
99
+ const headerComponent = $derived(
100
+ header ? snippetComponent(header as Snippet<[state: never]>) : undefined
101
+ )
102
+
103
+ // Register on mount and on every prop change; the cleanup unregisters the
104
+ // current key first, so a changed `name` never leaves a stale entry behind.
105
+ // `widgets`-prop entries with the same key win on re-seed — declarative
106
+ // children are the override path, not the base.
107
+ // Only include snippets that apply to the parent layout (`tab` → Dockview,
108
+ // `header` → Paneview, `title` → Dockview/Paneview) so the dev warning above is
109
+ // accurate and the inapplicable keys never reach the registry.
110
+ $effect(() => {
111
+ const def: Record<string, unknown> = { component }
112
+ if (tabComponent && ctx.kind === 'dockview') def.tab = tabComponent
113
+ if (headerComponent && ctx.kind === 'paneview') def.header = headerComponent
114
+ if (title !== undefined && (ctx.kind === 'dockview' || ctx.kind === 'paneview')) {
115
+ def.title = title
116
+ }
117
+ ctx.registerWidget(name, def)
118
+ return () => ctx.unregisterWidget(name)
119
+ })
120
+ </script>
@@ -0,0 +1,41 @@
1
+ import type { Snippet } from 'svelte';
2
+ /**
3
+ * Props for `<DvWidget>`.
4
+ *
5
+ * The `children` snippet receives the panel's shared `state` object — the same
6
+ * object a `widgets`-registry component receives as its `state` prop — and its
7
+ * output is rendered into the panel body (and tab/header, when given).
8
+ * `tab` / `header` snippets receive the same `state`.
9
+ *
10
+ * > **Type note:** the snippet parameter defaults to `never` on purpose — it
11
+ * > cannot be inferred per-widget, so annotate it with your panel's state type
12
+ * > (e.g. `{#snippet children(state: PanelState<{ id: number }>)}`). The
13
+ * > annotation is what gives you typed `state.params`.
14
+ *
15
+ * Usage:
16
+ *
17
+ * ```svelte
18
+ * <Dockview>
19
+ * <DvWidget name="chat" title="Chat">
20
+ * {#snippet children(state)}
21
+ * <ChatWidget {state} />
22
+ * {/snippet}
23
+ * </DvWidget>
24
+ * </Dockview>
25
+ * ```
26
+ */
27
+ interface Props {
28
+ /** Widget key this instance registers under. */
29
+ name: string;
30
+ /** Body content, called with the shared `state`. */
31
+ children: Snippet<[state: never]>;
32
+ /** Dockview tab override, called with the shared `PanelState` (Dockview only). */
33
+ tab?: Snippet<[state: never]>;
34
+ /** Paneview header override, called with the shared `PaneviewState` (Paneview only). */
35
+ header?: Snippet<[state: never]>;
36
+ /** Default title for this widget (tier 2 in the resolution chain). */
37
+ title?: string;
38
+ }
39
+ declare const DvWidget: import("svelte").Component<Props, {}, "">;
40
+ type DvWidget = ReturnType<typeof DvWidget>;
41
+ export default DvWidget;
@@ -0,0 +1,341 @@
1
+ <script lang="ts" generics="const W extends GridviewWidgets">
2
+ import type {
3
+ GridviewApi,
4
+ GridviewComponentOptions,
5
+ IGridviewPanel,
6
+ SerializedGridviewComponent,
7
+ } from 'dockview'
8
+ import { createGridview, Orientation } from 'dockview'
9
+ import { onMount, type Snippet, setContext } from 'svelte'
10
+ import { DOCKVIEW_CONTEXT_KEY, type GridviewContext } from '../core/context.js'
11
+ import { createGridviewFactory } from '../core/gridview.svelte.js'
12
+ import { GridviewWidgetRegistry } from '../core/registry.js'
13
+ import type {
14
+ GridviewHandle,
15
+ GridviewMoveOptions,
16
+ GridviewOpenPanelOptions,
17
+ GridviewPanelHandle,
18
+ GridviewParamsOf,
19
+ GridviewWidgetDefinition,
20
+ GridviewWidgets,
21
+ } from '../core/types.js'
22
+ import { deepEqual } from '../core/utils.js'
23
+
24
+ interface Props<W extends GridviewWidgets> {
25
+ /** Widget registry: `{ [key]: { component } }` — no tabs or titles, grid cells have no headers. */
26
+ widgets?: W
27
+ /**
28
+ * `GridviewComponentOptions` passthrough (proportionalLayout, …).
29
+ * `orientation` defaults to `HORIZONTAL` (required by dockview).
30
+ *
31
+ * `createComponent` is owned by the library (Svelte `mount` factory
32
+ * backed by the `widgets` registry) and cannot be overridden.
33
+ */
34
+ options?: Omit<GridviewComponentOptions, 'createComponent'> & { orientation?: Orientation }
35
+ /** `bind:layout` — gridview JSON (`toJSON`/`fromJSON` shape). */
36
+ layout?: SerializedGridviewComponent
37
+ /** `bind:handle` — `{ api, openPanel, registerWidget, removePanel, movePanel, setVisible, setActive }`. */
38
+ handle?: GridviewHandle<W>
39
+ /**
40
+ * `bind:panels` — reactive list of current cells (`api.panels` snapshot).
41
+ * Refreshed on layout/add/remove/FromJSON, so `panels.length` is the
42
+ * sveltish cell count — no manual `onDidAddPanel` counting needed.
43
+ */
44
+ panels?: IGridviewPanel[]
45
+ /**
46
+ * `bind:activePanel` — the currently active cell. Derived from the
47
+ * per-panel `api.onDidActiveChange` (via the factory) plus explicit sync
48
+ * on the open/remove paths — `GridviewApi.onDidActivePanelChange` only
49
+ * fires on focus-driven activation, never on programmatic adds.
50
+ */
51
+ activePanel?: IGridviewPanel | undefined
52
+ /** Extra classes for the root container. */
53
+ class?: string
54
+ /** Declarative widgets (`<DvWidget>` children) — alternative to the `widgets` prop. */
55
+ children?: Snippet
56
+ /** Fired once the component is mounted and `api` is ready. */
57
+ onReady?: (event: { api: GridviewApi; handle: GridviewHandle<W> }) => void
58
+ onDidLayoutChange?: () => void
59
+ onDidLayoutFromJSON?: () => void
60
+ onDidAddPanel?: (panel: IGridviewPanel) => void
61
+ onDidRemovePanel?: (panel: IGridviewPanel) => void
62
+ onDidActivePanelChange?: (panel: IGridviewPanel | undefined) => void
63
+ }
64
+
65
+ let {
66
+ widgets = {} as W,
67
+ options = {} as Omit<GridviewComponentOptions, 'createComponent'> & {
68
+ orientation?: Orientation
69
+ },
70
+ layout = $bindable(),
71
+ handle = $bindable(),
72
+ panels = $bindable([]),
73
+ activePanel = $bindable(undefined),
74
+ class: className = '',
75
+ children,
76
+ onReady,
77
+ onDidLayoutChange,
78
+ onDidLayoutFromJSON,
79
+ onDidAddPanel,
80
+ onDidRemovePanel,
81
+ onDidActivePanelChange,
82
+ }: Props<W> = $props()
83
+
84
+ let container: HTMLElement
85
+ let api = $state<GridviewApi | undefined>(undefined)
86
+
87
+ const registry = new GridviewWidgetRegistry()
88
+ const counters = new Map<string, number>()
89
+
90
+ // Stable `registerWidget`, shared by context and handle.
91
+ function registerWidget(key: string, def: GridviewWidgetDefinition): void {
92
+ registry.register(key, def)
93
+ }
94
+
95
+ function unregisterWidget(key: string): void {
96
+ registry.unregister(key)
97
+ }
98
+
99
+ // Context for descendant widgets (api is populated after mount).
100
+ const context = $state<GridviewContext>({
101
+ api: undefined,
102
+ registerWidget,
103
+ unregisterWidget,
104
+ kind: 'gridview',
105
+ })
106
+ setContext(DOCKVIEW_CONTEXT_KEY, context)
107
+
108
+ // Seed the registry from the `widgets` prop (additive).
109
+ $effect(() => {
110
+ registry.seed(widgets)
111
+ })
112
+
113
+ function nextId(key: string): string {
114
+ const n = (counters.get(key) ?? 0) + 1
115
+ counters.set(key, n)
116
+ return `${key}-${n}`
117
+ }
118
+
119
+ /** `bind:layout` loop-break: the JSON we last emitted to the parent. */
120
+ let lastEmitted: SerializedGridviewComponent | undefined
121
+
122
+ /** Serialize the current layout and push it to the bound `layout`. */
123
+ function emitLayout(): void {
124
+ if (!api) return
125
+ const json = api.toJSON()
126
+ lastEmitted = json
127
+ layout = json
128
+ refreshPanels()
129
+ }
130
+
131
+ /** Refresh `bind:panels` from the live cells. */
132
+ function refreshPanels(): void {
133
+ if (!api) return
134
+ panels = [...api.panels]
135
+ }
136
+
137
+ /**
138
+ * Set `bind:activePanel` + fire `onDidActivePanelChange`, deduped on panel
139
+ * id. Per-panel `onDidActiveChange` fires on both the deactivated and the
140
+ * activated cell, so the guard keeps a single update per activation.
141
+ */
142
+ function setActivePanel(panel: IGridviewPanel | undefined): void {
143
+ if (activePanel?.id === panel?.id) return
144
+ activePanel = panel
145
+ onDidActivePanelChange?.(panel)
146
+ }
147
+
148
+ function getPanelOrThrow(id: string): import('dockview').GridviewPanel {
149
+ const panel = api!.getPanel(id)
150
+ if (!panel) {
151
+ throw new Error(`dockview-svelte: unknown panel "${id}"`)
152
+ }
153
+ return panel as import('dockview').GridviewPanel
154
+ }
155
+
156
+ function openPanel<K extends keyof W & string>(
157
+ key: K,
158
+ opts?: GridviewOpenPanelOptions<GridviewParamsOf<W[K]['component']>>
159
+ ): GridviewPanelHandle<GridviewParamsOf<W[K]['component']>> {
160
+ if (!api) {
161
+ throw new Error('dockview-svelte: Gridview is not mounted yet')
162
+ }
163
+ const def = registry.get(key)
164
+ if (!def) {
165
+ throw new Error(`dockview-svelte: unknown widget "${key}"`)
166
+ }
167
+
168
+ const id = opts?.id ?? nextId(key)
169
+ const panel = api.addPanel({
170
+ ...(opts ?? {}),
171
+ id,
172
+ component: key,
173
+ params: opts?.params ?? {},
174
+ })
175
+ // `addPanel` fires no event the component observes for the open path
176
+ // itself (events cover external mutations) — refresh the bound
177
+ // panels/layout directly so `bind:panels` reflects the new cell.
178
+ // `doSetGroupActive` inside `addPanel` fires per-panel
179
+ // `onDidActiveChange`, which the factory mirrors to `state.active`
180
+ // but the component does not observe — so sync `bind:activePanel`
181
+ // explicitly.
182
+ emitLayout()
183
+ setActivePanel(panel)
184
+
185
+ const state = factory?.getState(id)
186
+ // `state` is `GridviewState<Record<string, unknown>>` at the factory
187
+ // boundary; `GridviewState<P>` is invariant in `P` (params is read/write),
188
+ // so the runtime-known `P` requires an `unknown` bridge.
189
+ return { id, panel, api: panel.api, state: state! } as unknown as GridviewPanelHandle<
190
+ GridviewParamsOf<W[K]['component']>
191
+ >
192
+ }
193
+
194
+ /** Remove a cell by panel id. */
195
+ function removePanel(id: string): void {
196
+ if (!api) {
197
+ throw new Error('dockview-svelte: Gridview is not mounted yet')
198
+ }
199
+ const removed = getPanelOrThrow(id)
200
+ const wasActive = activePanel?.id === removed.id
201
+ api.removePanel(removed)
202
+ // Removal fires no active event either — fall back to the last
203
+ // remaining cell when the active one was removed.
204
+ if (wasActive) setActivePanel(api.panels.at(-1))
205
+ }
206
+
207
+ /** Move a cell relative to a reference panel. */
208
+ function movePanel(id: string, move: GridviewMoveOptions): void {
209
+ if (!api) {
210
+ throw new Error('dockview-svelte: Gridview is not mounted yet')
211
+ }
212
+ api.movePanel(getPanelOrThrow(id), {
213
+ direction: move.direction,
214
+ reference: move.reference,
215
+ size: move.size,
216
+ })
217
+ }
218
+
219
+ /** Show or hide a cell by id (via the panel api — `panel.setVisible` only fires `onDidVisibilityChange` without touching the layout). */
220
+ function setVisible(id: string, visible: boolean): void {
221
+ if (!api) {
222
+ throw new Error('dockview-svelte: Gridview is not mounted yet')
223
+ }
224
+ getPanelOrThrow(id).api.setVisible(visible)
225
+ }
226
+
227
+ /** Activate a cell by id (via the panel api — `panel.setActive` only fires `onDidActiveChange`). */
228
+ function setActive(id: string): void {
229
+ if (!api) {
230
+ throw new Error('dockview-svelte: Gridview is not mounted yet')
231
+ }
232
+ getPanelOrThrow(id).api.setActive()
233
+ }
234
+
235
+ let factory: ReturnType<typeof createGridviewFactory> | undefined
236
+
237
+ // External `layout` changes → apply via `fromJSON` (loop-break via `lastEmitted`).
238
+ $effect(() => {
239
+ const current = api
240
+ if (!current || !layout) return
241
+ if (deepEqual(lastEmitted, layout)) return
242
+ current.fromJSON(layout)
243
+ })
244
+
245
+ // Live `options` changes (orientation, etc.) → apply via `updateOptions`.
246
+ // NOTE: `opts` must be read before the `api` guard — otherwise the
247
+ // initial run returns early without tracking `options`, and later changes
248
+ // never re-trigger the effect.
249
+ $effect(() => {
250
+ const opts = options
251
+ if (!api) return
252
+ api.updateOptions(opts)
253
+ })
254
+
255
+ onMount(() => {
256
+ factory = createGridviewFactory(registry, context, {
257
+ onDidActivePanelChange: (panel) => setActivePanel(panel as unknown as IGridviewPanel),
258
+ })
259
+ const createdApi = createGridview(container, {
260
+ ...options,
261
+ orientation: options.orientation ?? Orientation.HORIZONTAL,
262
+ createComponent: factory.createComponent,
263
+ })
264
+ // Apply a pre-existing `bind:layout` before exposing the api.
265
+ if (layout) {
266
+ createdApi.fromJSON(layout)
267
+ lastEmitted = createdApi.toJSON()
268
+ layout = lastEmitted
269
+ }
270
+ api = createdApi
271
+ context.api = createdApi
272
+
273
+ const createdHandle: GridviewHandle<W> = {
274
+ api: createdApi,
275
+ openPanel,
276
+ registerWidget,
277
+ removePanel,
278
+ movePanel,
279
+ setVisible,
280
+ setActive,
281
+ }
282
+ handle = createdHandle
283
+
284
+ // Bridge gridview events to callbacks, disposing on teardown.
285
+ const subscriptions = [
286
+ createdApi.onDidLayoutChange(() => {
287
+ emitLayout()
288
+ onDidLayoutChange?.()
289
+ }),
290
+ createdApi.onDidLayoutFromJSON(() => {
291
+ refreshPanels()
292
+ onDidLayoutFromJSON?.()
293
+ }),
294
+ createdApi.onDidAddPanel((panel: IGridviewPanel) => {
295
+ refreshPanels()
296
+ // External adds (e.g. `api.addPanel` escape hatch) activate the
297
+ // new cell without a component-level event — same sync as the
298
+ // `openPanel` path.
299
+ setActivePanel(panel)
300
+ onDidAddPanel?.(panel)
301
+ }),
302
+ createdApi.onDidRemovePanel((panel: IGridviewPanel) => {
303
+ refreshPanels()
304
+ if (activePanel?.id === panel.id) setActivePanel(createdApi.panels.at(-1))
305
+ onDidRemovePanel?.(panel)
306
+ }),
307
+ createdApi.onDidActivePanelChange((panel: IGridviewPanel | undefined) => {
308
+ // Focus-driven activation path (`registerPanel` wires
309
+ // `onDidFocusChange` → `doSetGroupActive`). Programmatic
310
+ // activation (`api.setActive`, `addPanel`) only fires the
311
+ // per-panel event, handled via the factory hook below.
312
+ setActivePanel(panel)
313
+ }),
314
+ ]
315
+ // Seed the initial panels before exposing the handle.
316
+ refreshPanels()
317
+ onReady?.({ api: createdApi, handle: createdHandle })
318
+
319
+ return () => {
320
+ for (const disposable of subscriptions) disposable.dispose()
321
+ createdApi.dispose()
322
+ api = undefined
323
+ factory = undefined
324
+ lastEmitted = undefined
325
+ }
326
+ })
327
+ </script>
328
+
329
+ <div class="dv-svelte-gridview-root {className}" bind:this={container}>
330
+ {#if children}
331
+ {@render children()}
332
+ {/if}
333
+ </div>
334
+
335
+ <style>
336
+ .dv-svelte-gridview-root {
337
+ width: 100%;
338
+ height: 100%;
339
+ position: relative;
340
+ }
341
+ </style>
@@ -0,0 +1,73 @@
1
+ import type { GridviewApi, GridviewComponentOptions, IGridviewPanel, SerializedGridviewComponent } from 'dockview';
2
+ import { Orientation } from 'dockview';
3
+ import { type Snippet } from 'svelte';
4
+ import type { GridviewHandle, GridviewWidgets } from '../core/types.js';
5
+ interface Props<W extends GridviewWidgets> {
6
+ /** Widget registry: `{ [key]: { component } }` — no tabs or titles, grid cells have no headers. */
7
+ widgets?: W;
8
+ /**
9
+ * `GridviewComponentOptions` passthrough (proportionalLayout, …).
10
+ * `orientation` defaults to `HORIZONTAL` (required by dockview).
11
+ *
12
+ * `createComponent` is owned by the library (Svelte `mount` factory
13
+ * backed by the `widgets` registry) and cannot be overridden.
14
+ */
15
+ options?: Omit<GridviewComponentOptions, 'createComponent'> & {
16
+ orientation?: Orientation;
17
+ };
18
+ /** `bind:layout` — gridview JSON (`toJSON`/`fromJSON` shape). */
19
+ layout?: SerializedGridviewComponent;
20
+ /** `bind:handle` — `{ api, openPanel, registerWidget, removePanel, movePanel, setVisible, setActive }`. */
21
+ handle?: GridviewHandle<W>;
22
+ /**
23
+ * `bind:panels` — reactive list of current cells (`api.panels` snapshot).
24
+ * Refreshed on layout/add/remove/FromJSON, so `panels.length` is the
25
+ * sveltish cell count — no manual `onDidAddPanel` counting needed.
26
+ */
27
+ panels?: IGridviewPanel[];
28
+ /**
29
+ * `bind:activePanel` — the currently active cell. Derived from the
30
+ * per-panel `api.onDidActiveChange` (via the factory) plus explicit sync
31
+ * on the open/remove paths — `GridviewApi.onDidActivePanelChange` only
32
+ * fires on focus-driven activation, never on programmatic adds.
33
+ */
34
+ activePanel?: IGridviewPanel | undefined;
35
+ /** Extra classes for the root container. */
36
+ class?: string;
37
+ /** Declarative widgets (`<DvWidget>` children) — alternative to the `widgets` prop. */
38
+ children?: Snippet;
39
+ /** Fired once the component is mounted and `api` is ready. */
40
+ onReady?: (event: {
41
+ api: GridviewApi;
42
+ handle: GridviewHandle<W>;
43
+ }) => void;
44
+ onDidLayoutChange?: () => void;
45
+ onDidLayoutFromJSON?: () => void;
46
+ onDidAddPanel?: (panel: IGridviewPanel) => void;
47
+ onDidRemovePanel?: (panel: IGridviewPanel) => void;
48
+ onDidActivePanelChange?: (panel: IGridviewPanel | undefined) => void;
49
+ }
50
+ declare function $$render<const W extends GridviewWidgets>(): {
51
+ props: Props<W>;
52
+ exports: {};
53
+ bindings: "layout" | "handle" | "panels" | "activePanel";
54
+ slots: {};
55
+ events: {};
56
+ };
57
+ declare class __sveltets_Render<const W extends GridviewWidgets> {
58
+ props(): ReturnType<typeof $$render<W>>['props'];
59
+ events(): ReturnType<typeof $$render<W>>['events'];
60
+ slots(): ReturnType<typeof $$render<W>>['slots'];
61
+ bindings(): "layout" | "handle" | "panels" | "activePanel";
62
+ exports(): {};
63
+ }
64
+ interface $$IsomorphicComponent {
65
+ new <const W extends GridviewWidgets>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<W>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<W>['props']>, ReturnType<__sveltets_Render<W>['events']>, ReturnType<__sveltets_Render<W>['slots']>> & {
66
+ $$bindings?: ReturnType<__sveltets_Render<W>['bindings']>;
67
+ } & ReturnType<__sveltets_Render<W>['exports']>;
68
+ <const W extends GridviewWidgets>(internal: unknown, props: ReturnType<__sveltets_Render<W>['props']> & {}): ReturnType<__sveltets_Render<W>['exports']>;
69
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
70
+ }
71
+ declare const Gridview: $$IsomorphicComponent;
72
+ type Gridview<const W extends GridviewWidgets> = InstanceType<typeof Gridview<W>>;
73
+ export default Gridview;