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,424 @@
1
+ import type { AddGridviewComponentOptions, AddPanelOptions, AddPaneviewComponentOptions, AddSplitviewComponentOptions, Direction, DockviewApi, DockviewGroupLocation, DockviewGroupPanel, DockviewPanelApi, DockviewPopoutGroupOptions, FloatingGroupOptions, GridviewApi, GridviewPanelApi, IDockviewPanel, IGridviewPanel, IPaneviewPanel, ISplitviewPanel, PaneviewApi, PaneviewPanelApi, SplitviewApi, SplitviewPanelApi } from 'dockview';
2
+ import type { Component, ComponentProps } from 'svelte';
3
+ /**
4
+ * The reactive state shared between a panel's tab header and its content.
5
+ *
6
+ * One instance exists per panel id. It is created as a `$state` object and
7
+ * passed to both the tab and content widgets by reference, so both sides
8
+ * observe and mutate the same reactive fields.
9
+ *
10
+ * Two visibility notions are exposed, deliberately named after their source:
11
+ * - `shown`: the renderer's `onShow`/`onHide` — whether this panel's content
12
+ * DOM is currently mounted (it's the active tab of its group).
13
+ * - `visible`: dockview's `api.isVisible` — the gridview-level visibility
14
+ * (false when the whole group is hidden/collapsed).
15
+ */
16
+ export interface PanelState<P = Record<string, unknown>> {
17
+ /** Double-bound with dockview: mutations propagate to `api.updateParameters` and back. */
18
+ params: P;
19
+ /** Written by the renderer's `layout()` hook, rAF-throttled (only while `shown`). */
20
+ size: {
21
+ width: number;
22
+ height: number;
23
+ };
24
+ /** Renderer `onShow`/`onHide` — content mounted as the active tab. */
25
+ shown: boolean;
26
+ /** dockview `api.isVisible` — gridview-level visibility. */
27
+ visible: boolean;
28
+ /** dockview `api.isActive` — write `true` to activate (writing `false` is ignored). */
29
+ active: boolean;
30
+ /** dockview `api.isFocused` — read-only mirror. */
31
+ focused: boolean;
32
+ /** dockview `api.isPinned` — two-way (`setPinned`). */
33
+ pinned: boolean;
34
+ /** dockview `api.isGroupActive` — read-only mirror. */
35
+ groupActive: boolean;
36
+ /** The per-panel dockview api. */
37
+ api: DockviewPanelApi;
38
+ /** Read-only mirror of dockview's title (rename via `api.setTitle`). */
39
+ title: string;
40
+ /** App channel for arbitrary tab↔content data, e.g. `custom.unread = 3`. */
41
+ custom: Record<string, unknown>;
42
+ }
43
+ /**
44
+ * The currently active panel + group, bound via `bind:active` on `<Dockview>`.
45
+ * Reacts to `onDidActivePanelChange` / `onDidActiveGroupChange`.
46
+ */
47
+ export interface ActiveState {
48
+ panel: IDockviewPanel | undefined;
49
+ group: DockviewGroupPanel | undefined;
50
+ }
51
+ /**
52
+ * Reactive floating-window state, bound via `bind:floating` on `<Dockview>`.
53
+ * Mirrors `api.groups` where `location.type === 'floating'` — refreshed on
54
+ * layout/add/remove/move, so dragging, floating, or docking back all update it.
55
+ */
56
+ export interface FloatingState {
57
+ /** Number of floating windows currently open. */
58
+ count: number;
59
+ /** True when at least one floating window is open. */
60
+ hasFloating: boolean;
61
+ }
62
+ /**
63
+ * Reactive popout-window state, bound via `bind:popout` on `<Dockview>`.
64
+ * Mirrors `api.getPopouts()` — refreshed on popout add/remove and layout changes.
65
+ */
66
+ export interface PopoutState {
67
+ /** Number of popout windows currently open. */
68
+ count: number;
69
+ /** True when at least one popout window is open. */
70
+ hasPopout: boolean;
71
+ }
72
+ /**
73
+ * Reactive group state, passed to a Svelte group-header action component via
74
+ * `HeaderActionProps.state`. Mirrors the group api's collapsed/peek/location
75
+ * (and their `onDid*` events) — the same idiom as {@link PanelState}.
76
+ */
77
+ export interface GroupState {
78
+ /** True while the group is collapsed to its header. */
79
+ isCollapsed: boolean;
80
+ /** True while the group is peeking (edge/tool window). */
81
+ isPeeking: boolean;
82
+ /** The group's current location: `'grid'`, `'floating'`, `'popout'`, or `'edge'`. */
83
+ location: DockviewGroupLocation;
84
+ }
85
+ /** A widget receives its whole {@link PanelState} as a single `state` prop. */
86
+ export type WidgetComponent<P = Record<string, unknown>> = Component<{
87
+ state: PanelState<P>;
88
+ }>;
89
+ /**
90
+ * Props passed to the Svelte `watermark` overlay component.
91
+ * Rendered as a plain Svelte child when the dock is empty, so it reads the
92
+ * parent `DockviewContext` (`api`, `registerWidget`) via `getContext` —
93
+ * no dockview `IWatermarkRenderer` factory involved.
94
+ */
95
+ export interface WatermarkProps<W extends Widgets = Widgets> {
96
+ /** Open a panel by widget key — same as `handle.openPanel`. */
97
+ openPanel: OpenPanelFn<W>;
98
+ }
99
+ /**
100
+ * A Svelte component rendered as the empty-state overlay.
101
+ * `any` props: Svelte component variance can't express "accepts my W" —
102
+ * the overlay always passes this dock's typed `openPanel` at runtime.
103
+ */
104
+ export type WatermarkComponent = Component<any>;
105
+ /**
106
+ * Props passed to a Svelte group-header action component
107
+ * (`leftHeaderActions` / `rightHeaderActions` / `prefixHeaderActions`).
108
+ * Mirrors dockview's `IGroupHeaderProps`, plus a reactive {@link GroupState}.
109
+ */
110
+ export interface HeaderActionProps {
111
+ /** The parent {@link DockviewApi} (`addFloatingGroup`, `addPopoutGroup`, …). */
112
+ containerApi: DockviewApi;
113
+ /** The concrete group these actions render for (`.api`, `.id`, `.panels`, …). */
114
+ group: DockviewGroupPanel;
115
+ /** Reactive mirror of the group's collapsed/peek/location state. */
116
+ state: GroupState;
117
+ }
118
+ /**
119
+ * A Svelte component rendered into a group header slot.
120
+ * `any` props for the same variance reason as {@link WatermarkComponent}.
121
+ */
122
+ export type HeaderActionComponent = Component<any>;
123
+ /**
124
+ * Extracts the params type of a widget component from its `state` prop.
125
+ * Components that do not declare a `state: PanelState<...>` prop fall back to
126
+ * an open record.
127
+ */
128
+ export type ParamsOf<C extends Component<any>> = 'state' extends keyof ComponentProps<C> ? ComponentProps<C>['state'] extends PanelState<infer P> ? P : Record<string, unknown> : Record<string, unknown>;
129
+ /**
130
+ * A single registry entry: one panel *type*, keyed by its widget key
131
+ * (e.g. `'chat'`). The header (`tab`) and default `title` live on the same
132
+ * definition as the content so they can never drift.
133
+ */
134
+ export interface WidgetDefinition<C extends WidgetComponent<any> = WidgetComponent> {
135
+ /** Content component rendered inside the panel body. */
136
+ component: C;
137
+ /** Header component for this widget. Omit to use the built-in default tab. */
138
+ tab?: WidgetComponent;
139
+ /** Default title for this widget (tier 2 in the resolution chain). */
140
+ title?: string;
141
+ }
142
+ /** The widget registry: a map of widget key → definition. */
143
+ export type Widgets = Record<string, WidgetDefinition>;
144
+ /** A handle returned by `openPanel`, bundling the panel and its shared state. */
145
+ export interface PanelHandle<P = Record<string, unknown>> {
146
+ id: string;
147
+ /** Raw dockview panel for full escape-hatch access. */
148
+ panel: IDockviewPanel;
149
+ /** Convenience alias of `panel.api`. */
150
+ api: DockviewPanelApi;
151
+ /** Reactive state shared by tab + content. */
152
+ state: PanelState<P>;
153
+ }
154
+ /** Options accepted by `openPanel`. Owns `id`/`title`/`params`, passes the rest through. */
155
+ export type OpenPanelOptions<P> = {
156
+ id?: string;
157
+ title?: string;
158
+ params?: P;
159
+ } & Omit<AddPanelOptions, 'id' | 'title' | 'component' | 'tabComponent' | 'params'>;
160
+ export type OpenPanelFn<W extends Widgets> = <K extends keyof W & string>(key: K, options?: OpenPanelOptions<ParamsOf<W[K]['component']>>) => PanelHandle<ParamsOf<W[K]['component']>>;
161
+ /** Bound via `bind:handle`; bundles raw api access with the typed ergonomic surface. */
162
+ export interface DockviewHandle<W extends Widgets = Widgets> {
163
+ /** The raw dockview api — full escape hatch for anything `openPanel` can't do. */
164
+ api: DockviewApi;
165
+ /** Open a panel by widget key with an optional title/params/position. */
166
+ openPanel: OpenPanelFn<W>;
167
+ /** Register (or override) a widget type at runtime. */
168
+ registerWidget: (key: string, def: WidgetDefinition) => void;
169
+ /**
170
+ * Float an existing panel or group into its own window.
171
+ * Accepts an `IDockviewPanel`, a `DockviewGroupPanel`, or a panel id string.
172
+ */
173
+ float: (target: IDockviewPanel | DockviewGroupPanel | string, options?: FloatingGroupOptions) => void;
174
+ /**
175
+ * Pop an existing panel or group out into its own browser window.
176
+ * Accepts an `IDockviewPanel`, a `DockviewGroupPanel`, or a panel id string.
177
+ * Resolves `true` on success, `false` if the popout window failed to open.
178
+ */
179
+ popout: (target: IDockviewPanel | DockviewGroupPanel | string, options?: DockviewPopoutGroupOptions) => Promise<boolean>;
180
+ /** Dock every floating window back into the main grid. */
181
+ dockAll: () => void;
182
+ }
183
+ /**
184
+ * The reactive state shared by a splitview panel. Same shape as
185
+ * {@link PanelState} minus the tab-only fields (`title`, `shown`, `pinned`,
186
+ * `groupActive`) — splitview panes have no headers or tabs.
187
+ */
188
+ export interface SplitviewState<P = Record<string, unknown>> {
189
+ /** Double-bound with dockview: mutations propagate to `api.updateParameters` and back. */
190
+ params: P;
191
+ /** Written by the renderer's `layout()` hook via `api.onDidDimensionsChange`. */
192
+ size: {
193
+ width: number;
194
+ height: number;
195
+ };
196
+ /** dockview `api.isVisible` — two-way (`setVisible`). */
197
+ visible: boolean;
198
+ /** dockview `api.isActive` — write `true` to activate (writing `false` is ignored). */
199
+ active: boolean;
200
+ /** dockview `api.isFocused` — read-only mirror. */
201
+ focused: boolean;
202
+ /** The per-panel dockview api. */
203
+ api: SplitviewPanelApi;
204
+ /** App channel for arbitrary widget data, e.g. `custom.unread = 3`. */
205
+ custom: Record<string, unknown>;
206
+ }
207
+ /** A splitview widget receives its whole {@link SplitviewState} as a `state` prop. */
208
+ export type SplitviewWidgetComponent<P = Record<string, unknown>> = Component<{
209
+ state: SplitviewState<P>;
210
+ }>;
211
+ /** Extracts the params type of a splitview widget from its `state` prop. */
212
+ export type SplitviewParamsOf<C extends Component<any>> = 'state' extends keyof ComponentProps<C> ? ComponentProps<C>['state'] extends SplitviewState<infer P> ? P : Record<string, unknown> : Record<string, unknown>;
213
+ /**
214
+ * A single splitview registry entry. No `tab`/`title` — splitview panes have
215
+ * no headers.
216
+ */
217
+ export interface SplitviewWidgetDefinition<C extends SplitviewWidgetComponent<any> = SplitviewWidgetComponent> {
218
+ /** Content component rendered inside the split pane. */
219
+ component: C;
220
+ }
221
+ /** The splitview widget registry: a map of widget key → definition. */
222
+ export type SplitviewWidgets = Record<string, SplitviewWidgetDefinition>;
223
+ /** A handle returned by a splitview `openPanel`, bundling the pane and its state. */
224
+ export interface SplitviewPanelHandle<P = Record<string, unknown>> {
225
+ id: string;
226
+ /** Raw dockview splitview panel. */
227
+ panel: ISplitviewPanel;
228
+ /** Convenience alias of `panel.api`. */
229
+ api: SplitviewPanelApi;
230
+ /** Reactive state. */
231
+ state: SplitviewState<P>;
232
+ }
233
+ /** Options accepted by a splitview `openPanel`. Owns `id`/`params`, passes the rest through. */
234
+ export type SplitviewOpenPanelOptions<P> = {
235
+ id?: string;
236
+ params?: P;
237
+ } & Omit<AddSplitviewComponentOptions, 'id' | 'component' | 'params'>;
238
+ export type SplitviewOpenPanelFn<W extends SplitviewWidgets> = <K extends keyof W & string>(key: K, options?: SplitviewOpenPanelOptions<SplitviewParamsOf<W[K]['component']>>) => SplitviewPanelHandle<SplitviewParamsOf<W[K]['component']>>;
239
+ /** Bound via `bind:handle`; bundles raw api access with the typed ergonomic surface. */
240
+ export interface SplitviewHandle<W extends SplitviewWidgets = SplitviewWidgets> {
241
+ /** The raw splitview api. */
242
+ api: SplitviewApi;
243
+ /** Open a split pane by widget key with an optional params/position. */
244
+ openPanel: SplitviewOpenPanelFn<W>;
245
+ /** Register (or override) a widget type at runtime. */
246
+ registerWidget: (key: string, def: SplitviewWidgetDefinition) => void;
247
+ /** Remove a split pane by id. */
248
+ removePanel: (id: string) => void;
249
+ /** Move a split pane from one index to another. */
250
+ movePanel: (from: number, to: number) => void;
251
+ /** Show or hide a split pane by id. */
252
+ setVisible: (id: string, visible: boolean) => void;
253
+ /** Activate a split pane by id. */
254
+ setActive: (id: string) => void;
255
+ }
256
+ /**
257
+ * The reactive state shared by a gridview panel. Same shape as
258
+ * {@link SplitviewState} — grid cells have no headers or tabs.
259
+ */
260
+ export interface GridviewState<P = Record<string, unknown>> {
261
+ /** Double-bound with dockview: mutations propagate to `api.updateParameters` and back. */
262
+ params: P;
263
+ /** Written by the renderer's `layout()` hook, rAF-throttled. */
264
+ size: {
265
+ width: number;
266
+ height: number;
267
+ };
268
+ /** dockview `api.isVisible` — two-way (`setVisible`). */
269
+ visible: boolean;
270
+ /** dockview `api.isActive` — write `true` to activate (writing `false` is ignored). */
271
+ active: boolean;
272
+ /** dockview `api.isFocused` — read-only mirror. */
273
+ focused: boolean;
274
+ /** The per-panel dockview api. */
275
+ api: GridviewPanelApi;
276
+ /** App channel for arbitrary widget data, e.g. `custom.unread = 3`. */
277
+ custom: Record<string, unknown>;
278
+ }
279
+ /** A gridview widget receives its whole {@link GridviewState} as a `state` prop. */
280
+ export type GridviewWidgetComponent<P = Record<string, unknown>> = Component<{
281
+ state: GridviewState<P>;
282
+ }>;
283
+ /** Extracts the params type of a gridview widget from its `state` prop. */
284
+ export type GridviewParamsOf<C extends Component<any>> = 'state' extends keyof ComponentProps<C> ? ComponentProps<C>['state'] extends GridviewState<infer P> ? P : Record<string, unknown> : Record<string, unknown>;
285
+ /**
286
+ * A single gridview registry entry. No `tab`/`title` — grid cells have
287
+ * no headers.
288
+ */
289
+ export interface GridviewWidgetDefinition<C extends GridviewWidgetComponent<any> = GridviewWidgetComponent> {
290
+ /** Content component rendered inside the grid cell. */
291
+ component: C;
292
+ }
293
+ /** The gridview widget registry: a map of widget key → definition. */
294
+ export type GridviewWidgets = Record<string, GridviewWidgetDefinition>;
295
+ /** A handle returned by a gridview `openPanel`, bundling the cell and its state. */
296
+ export interface GridviewPanelHandle<P = Record<string, unknown>> {
297
+ id: string;
298
+ /** Raw dockview gridview panel. */
299
+ panel: IGridviewPanel;
300
+ /** Convenience alias of `panel.api`. */
301
+ api: GridviewPanelApi;
302
+ /** Reactive state. */
303
+ state: GridviewState<P>;
304
+ }
305
+ /** Options accepted by a gridview `openPanel`. Owns `id`/`params`, passes the rest through. */
306
+ export type GridviewOpenPanelOptions<P> = {
307
+ id?: string;
308
+ params?: P;
309
+ } & Omit<AddGridviewComponentOptions, 'id' | 'component' | 'params'>;
310
+ export type GridviewOpenPanelFn<W extends GridviewWidgets> = <K extends keyof W & string>(key: K, options?: GridviewOpenPanelOptions<GridviewParamsOf<W[K]['component']>>) => GridviewPanelHandle<GridviewParamsOf<W[K]['component']>>;
311
+ /** Options for `handle.movePanel`: a direction relative to a reference panel id. */
312
+ export interface GridviewMoveOptions {
313
+ /** `'left' | 'right' | 'above' | 'below' | 'within'` — relative to `reference`. */
314
+ direction: Direction;
315
+ /** Id of the panel to position relative to. */
316
+ reference: string;
317
+ /** Optional size of the moved panel. */
318
+ size?: number;
319
+ }
320
+ /** Bound via `bind:handle`; bundles raw api access with the typed ergonomic surface. */
321
+ export interface GridviewHandle<W extends GridviewWidgets = GridviewWidgets> {
322
+ /** The raw gridview api. */
323
+ api: GridviewApi;
324
+ /** Open a grid cell by widget key with an optional params/position. */
325
+ openPanel: GridviewOpenPanelFn<W>;
326
+ /** Register (or override) a widget type at runtime. */
327
+ registerWidget: (key: string, def: GridviewWidgetDefinition) => void;
328
+ /** Remove a grid cell by id. */
329
+ removePanel: (id: string) => void;
330
+ /** Move a grid cell relative to a reference panel. */
331
+ movePanel: (id: string, options: GridviewMoveOptions) => void;
332
+ /** Show or hide a grid cell by id. */
333
+ setVisible: (id: string, visible: boolean) => void;
334
+ /** Activate a grid cell by id. */
335
+ setActive: (id: string) => void;
336
+ }
337
+ /**
338
+ * The reactive state shared by a paneview pane's body and header. Same shape
339
+ * as {@link SplitviewState} plus the pane-specific `title` (owned by dockview
340
+ * at open time, mirrored read-only) and `expanded` (two-way via
341
+ * `api.setExpanded`).
342
+ */
343
+ export interface PaneviewState<P = Record<string, unknown>> {
344
+ /** Double-bound with dockview: mutations propagate to `api.updateParameters` and back. */
345
+ params: P;
346
+ /** Written by the renderer's `layout()` hook, rAF-throttled. */
347
+ size: {
348
+ width: number;
349
+ height: number;
350
+ };
351
+ /** dockview `api.isVisible` — two-way (`setVisible`). */
352
+ visible: boolean;
353
+ /** dockview `api.isActive` — write `true` to activate (writing `false` is ignored). */
354
+ active: boolean;
355
+ /** dockview `api.isFocused` — read-only mirror. */
356
+ focused: boolean;
357
+ /** dockview `api.isExpanded` — two-way (`setExpanded`). */
358
+ expanded: boolean;
359
+ /** The per-pane dockview api. */
360
+ api: PaneviewPanelApi;
361
+ /** Read-only mirror of dockview's title (fixed at open time). */
362
+ title: string;
363
+ /** App channel for arbitrary widget data, e.g. `custom.unread = 3`. */
364
+ custom: Record<string, unknown>;
365
+ }
366
+ /** A paneview body widget receives its whole {@link PaneviewState} as a `state` prop. */
367
+ export type PaneviewWidgetComponent<P = Record<string, unknown>> = Component<{
368
+ state: PaneviewState<P>;
369
+ }>;
370
+ /** A paneview header widget receives the same {@link PaneviewState} as the body. */
371
+ export type PaneviewHeaderComponent = Component<{
372
+ state: PaneviewState<any>;
373
+ }>;
374
+ /** Extracts the params type of a paneview widget from its `state` prop. */
375
+ export type PaneviewParamsOf<C extends Component<any>> = 'state' extends keyof ComponentProps<C> ? ComponentProps<C>['state'] extends PaneviewState<infer P> ? P : Record<string, unknown> : Record<string, unknown>;
376
+ /**
377
+ * A single paneview registry entry: one pane *type*, keyed by its widget key.
378
+ * The header lives on the same definition as the body so they can never drift.
379
+ * Omit `header` to use dockview's built-in default header (plain title text).
380
+ */
381
+ export interface PaneviewWidgetDefinition<C extends PaneviewWidgetComponent<any> = PaneviewWidgetComponent> {
382
+ /** Body component rendered inside the pane. */
383
+ component: C;
384
+ /** Header component for this pane. Omit to use dockview's default header. */
385
+ header?: PaneviewHeaderComponent;
386
+ /** Default title for this pane (tier 2 in the resolution chain). */
387
+ title?: string;
388
+ }
389
+ /** The paneview widget registry: a map of widget key → definition. */
390
+ export type PaneviewWidgets = Record<string, PaneviewWidgetDefinition>;
391
+ /** A handle returned by a paneview `openPanel`, bundling the pane and its state. */
392
+ export interface PaneviewPanelHandle<P = Record<string, unknown>> {
393
+ id: string;
394
+ /** Raw dockview paneview panel. */
395
+ panel: IPaneviewPanel;
396
+ /** Convenience alias of `panel.api`. */
397
+ api: PaneviewPanelApi;
398
+ /** Reactive state shared by header + body. */
399
+ state: PaneviewState<P>;
400
+ }
401
+ /** Options accepted by a paneview `openPanel`. Owns `id`/`title`/`params`, passes the rest through. */
402
+ export type PaneviewOpenPanelOptions<P> = {
403
+ id?: string;
404
+ title?: string;
405
+ params?: P;
406
+ } & Omit<AddPaneviewComponentOptions, 'id' | 'component' | 'headerComponent' | 'title' | 'params'>;
407
+ export type PaneviewOpenPanelFn<W extends PaneviewWidgets> = <K extends keyof W & string>(key: K, options?: PaneviewOpenPanelOptions<PaneviewParamsOf<W[K]['component']>>) => PaneviewPanelHandle<PaneviewParamsOf<W[K]['component']>>;
408
+ /** Bound via `bind:handle`; bundles raw api access with the typed ergonomic surface. */
409
+ export interface PaneviewHandle<W extends PaneviewWidgets = PaneviewWidgets> {
410
+ /** The raw paneview api. */
411
+ api: PaneviewApi;
412
+ /** Open a pane by widget key with an optional title/params/position. */
413
+ openPanel: PaneviewOpenPanelFn<W>;
414
+ /** Register (or override) a widget type at runtime. */
415
+ registerWidget: (key: string, def: PaneviewWidgetDefinition) => void;
416
+ /** Remove a pane by id. */
417
+ removePanel: (id: string) => void;
418
+ /** Move a pane from one index to another. */
419
+ movePanel: (from: number, to: number) => void;
420
+ /** Show or hide a pane by id. */
421
+ setVisible: (id: string, visible: boolean) => void;
422
+ /** Expand or collapse a pane by id. */
423
+ setExpanded: (id: string, expanded: boolean) => void;
424
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ /** True for plain objects (not arrays, not null, not class instances). */
2
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
3
+ /** Structural deep equality for JSON-like data (plain objects, arrays, primitives). */
4
+ export declare function deepEqual(a: unknown, b: unknown): boolean;
5
+ /**
6
+ * Deep-merge `partial` into `target` in place.
7
+ *
8
+ * Nested plain objects are recursed into (preserving object identity so that
9
+ * existing reactive subscriptions survive); leaf values are assigned only when
10
+ * they actually differ, so a no-op merge triggers no reactivity.
11
+ */
12
+ export declare function mergeInto(target: Record<string, unknown>, partial: Record<string, unknown>): void;
@@ -0,0 +1,59 @@
1
+ /** True for plain objects (not arrays, not null, not class instances). */
2
+ export function isPlainObject(value) {
3
+ if (typeof value !== 'object' || value === null)
4
+ return false;
5
+ const proto = Object.getPrototypeOf(value);
6
+ return proto === Object.prototype || proto === null;
7
+ }
8
+ /** Structural deep equality for JSON-like data (plain objects, arrays, primitives). */
9
+ export function deepEqual(a, b) {
10
+ if (Object.is(a, b))
11
+ return true;
12
+ if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) {
13
+ return false;
14
+ }
15
+ const aIsArray = Array.isArray(a);
16
+ const bIsArray = Array.isArray(b);
17
+ if (aIsArray !== bIsArray)
18
+ return false;
19
+ if (aIsArray && bIsArray) {
20
+ if (a.length !== b.length)
21
+ return false;
22
+ for (let i = 0; i < a.length; i++) {
23
+ if (!deepEqual(a[i], b[i]))
24
+ return false;
25
+ }
26
+ return true;
27
+ }
28
+ const aKeys = Object.keys(a);
29
+ const bKeys = Object.keys(b);
30
+ if (aKeys.length !== bKeys.length)
31
+ return false;
32
+ for (const key of aKeys) {
33
+ if (!Object.hasOwn(b, key))
34
+ return false;
35
+ if (!deepEqual(a[key], b[key])) {
36
+ return false;
37
+ }
38
+ }
39
+ return true;
40
+ }
41
+ /**
42
+ * Deep-merge `partial` into `target` in place.
43
+ *
44
+ * Nested plain objects are recursed into (preserving object identity so that
45
+ * existing reactive subscriptions survive); leaf values are assigned only when
46
+ * they actually differ, so a no-op merge triggers no reactivity.
47
+ */
48
+ export function mergeInto(target, partial) {
49
+ for (const key of Object.keys(partial)) {
50
+ const value = partial[key];
51
+ const current = target[key];
52
+ if (isPlainObject(value) && isPlainObject(current)) {
53
+ mergeInto(current, value);
54
+ }
55
+ else if (!deepEqual(value, current)) {
56
+ target[key] = value;
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,9 @@
1
+ export { default as DefaultTab } from './components/DefaultTab.svelte';
2
+ export { default as Dockview } from './components/Dockview.svelte';
3
+ export { default as DvWidget } from './components/DvWidget.svelte';
4
+ export { default as Gridview } from './components/Gridview.svelte';
5
+ export { default as Paneview } from './components/Paneview.svelte';
6
+ export { default as Splitview } from './components/Splitview.svelte';
7
+ export { DOCKVIEW_CONTEXT_KEY, type DockviewContext, type GridviewContext, type PaneviewContext, type SplitviewContext, } from './core/context.js';
8
+ export { defineGridviewWidgets, definePaneviewWidgets, defineSplitviewWidgets, defineWidgets, GridviewWidgetRegistry, PaneviewWidgetRegistry, SplitviewWidgetRegistry, WidgetRegistry, } from './core/registry.js';
9
+ export type { ActiveState, DockviewHandle, FloatingState, GridviewHandle, GridviewMoveOptions, GridviewOpenPanelFn, GridviewOpenPanelOptions, GridviewPanelHandle, GridviewParamsOf, GridviewState, GridviewWidgetComponent, GridviewWidgetDefinition, GridviewWidgets, GroupState, HeaderActionComponent, HeaderActionProps, OpenPanelFn, OpenPanelOptions, PanelHandle, PanelState, PaneviewHandle, PaneviewHeaderComponent, PaneviewOpenPanelFn, PaneviewOpenPanelOptions, PaneviewPanelHandle, PaneviewParamsOf, PaneviewState, PaneviewWidgetComponent, PaneviewWidgetDefinition, PaneviewWidgets, ParamsOf, PopoutState, SplitviewHandle, SplitviewOpenPanelFn, SplitviewOpenPanelOptions, SplitviewPanelHandle, SplitviewParamsOf, SplitviewState, SplitviewWidgetComponent, SplitviewWidgetDefinition, SplitviewWidgets, WatermarkComponent, WatermarkProps, WidgetComponent, WidgetDefinition, Widgets, } from './core/types.js';
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ // Components
2
+ export { default as DefaultTab } from './components/DefaultTab.svelte';
3
+ export { default as Dockview } from './components/Dockview.svelte';
4
+ export { default as DvWidget } from './components/DvWidget.svelte';
5
+ export { default as Gridview } from './components/Gridview.svelte';
6
+ export { default as Paneview } from './components/Paneview.svelte';
7
+ export { default as Splitview } from './components/Splitview.svelte';
8
+ // Context
9
+ export { DOCKVIEW_CONTEXT_KEY, } from './core/context.js';
10
+ // Registry
11
+ export { defineGridviewWidgets, definePaneviewWidgets, defineSplitviewWidgets, defineWidgets, GridviewWidgetRegistry, PaneviewWidgetRegistry, SplitviewWidgetRegistry, WidgetRegistry, } from './core/registry.js';
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "dockview-svelte",
3
+ "version": "0.0.1",
4
+ "scripts": {
5
+ "dev": "vite dev",
6
+ "build": "vite build && npm run prepack",
7
+ "preview": "vite preview",
8
+ "prepare": "svelte-kit sync || echo ''",
9
+ "prepack": "svelte-kit sync && svelte-package && publint",
10
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
11
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
12
+ "test:unit": "vitest run --config vitest.config.ts",
13
+ "test:e2e": "playwright test",
14
+ "test:install": "rm -f tests/install/dockview-svelte-*.tgz && npm pack --pack-destination tests/install && mv tests/install/dockview-svelte-*.tgz tests/install/dockview-svelte-local.tgz && npm --prefix tests/install install && npm --prefix tests/install test",
15
+ "biome": "biome check .",
16
+ "biome:fix": "biome check --write .",
17
+ "biome:unsafe": "biome check --write --unsafe ."
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "!dist/**/*.test.*",
22
+ "!dist/**/*.spec.*"
23
+ ],
24
+ "sideEffects": [
25
+ "**/*.css"
26
+ ],
27
+ "svelte": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "type": "module",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "svelte": "./dist/index.js"
34
+ }
35
+ },
36
+ "peerDependencies": {
37
+ "svelte": "^5.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@biomejs/biome": "2.5.12",
41
+ "@playwright/test": "^1.62.1",
42
+ "@sveltejs/adapter-auto": "^7.0.1",
43
+ "@sveltejs/kit": "^2.63.0",
44
+ "@sveltejs/package": "^2.5.8",
45
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
46
+ "@testing-library/svelte": "^5.4.2",
47
+ "@vitest/browser": "^5.0.0",
48
+ "jsdom": "^30.0.1",
49
+ "playwright": "^1.62.1",
50
+ "publint": "^0.3.21",
51
+ "shiki": "^4.4.3",
52
+ "svelte": "^5.56.1",
53
+ "svelte-check": "^4.6.0",
54
+ "typescript": "^6.0.3",
55
+ "vite": "^8.0.16",
56
+ "vitest": "^5.0.0",
57
+ "vitest-browser-svelte": "^3.1.0"
58
+ },
59
+ "keywords": [
60
+ "svelte"
61
+ ],
62
+ "license": "AGPL-3.0-only",
63
+ "dependencies": {
64
+ "dockview": "^8.2.0"
65
+ }
66
+ }