dockview-core 8.3.1 → 8.4.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 (31) hide show
  1. package/dist/cjs/api/component.api.d.ts +26 -1
  2. package/dist/cjs/dismissableLayer.d.ts +19 -7
  3. package/dist/cjs/dnd/ghost.d.ts +3 -0
  4. package/dist/cjs/dnd/pointer/pointerDragController.d.ts +1 -0
  5. package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +1 -0
  6. package/dist/cjs/dnd/pointer/pointerGhost.d.ts +6 -2
  7. package/dist/cjs/dockview/components/popupService.d.ts +2 -0
  8. package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +3 -1
  9. package/dist/cjs/dockview/components/titlebar/tabReorderController.d.ts +52 -21
  10. package/dist/cjs/dockview/dndCapabilities.d.ts +3 -4
  11. package/dist/cjs/dockview/dockviewComponent.d.ts +34 -16
  12. package/dist/cjs/dockview/dockviewShell.d.ts +12 -0
  13. package/dist/cjs/dockview/moduleContracts.d.ts +2 -0
  14. package/dist/cjs/dockview/options.d.ts +13 -0
  15. package/dist/cjs/dockview/popoutWindowService.d.ts +8 -2
  16. package/dist/cjs/dom.d.ts +61 -1
  17. package/dist/cjs/gridview/branchNode.d.ts +2 -1
  18. package/dist/cjs/gridview/gridview.d.ts +2 -1
  19. package/dist/cjs/index.d.ts +5 -1
  20. package/dist/cjs/popoutWindow.d.ts +57 -12
  21. package/dist/cjs/resizable.d.ts +12 -0
  22. package/dist/cjs/splitview/splitview.d.ts +3 -1
  23. package/dist/dockview-core.js +979 -469
  24. package/dist/dockview-core.min.js +11 -4
  25. package/dist/dockview-core.min.noStyle.js +2 -2
  26. package/dist/dockview-core.noStyle.js +978 -468
  27. package/dist/package/main.cjs.js +978 -468
  28. package/dist/package/main.cjs.min.js +2 -2
  29. package/dist/package/main.esm.min.mjs +2 -2
  30. package/dist/package/main.esm.mjs +977 -469
  31. package/package.json +1 -1
@@ -1,4 +1,6 @@
1
1
  import { DockviewActivePanelChangeEvent, DockviewPanelPinnedChangeEvent, DockviewLayoutMutationEvent, DockviewMaximizedGroupChangeEvent, DockviewPopoutGroupOptions, FloatingGroupOptions, GroupNavigationDirection, IDockviewComponent, MovePanelEvent, PopoutGroup, PopoutGroupChangePositionEvent, PopoutGroupChangeSizeEvent, SerializedDockview } from '../dockview/dockviewComponent';
2
+ import { PopoutWindowEvent, PopoutWindowFailure } from '../popoutWindow';
3
+ import { DndCapabilities } from '../dockview/dndCapabilities';
2
4
  import { AddGroupOptions, AddPanelOptions, DockviewComponentOptions, DockviewDndOverlayEvent, MovementOptions, SmartGuidesOptions } from '../dockview/options';
3
5
  import { DockviewMessages } from '../dockview/accessibilityMessages';
4
6
  import { Parameters } from '../panel/types';
@@ -449,6 +451,13 @@ export declare class DockviewApi implements CommonApi<SerializedDockview> {
449
451
  */
450
452
  get onWillDragPanel(): Event<TabDragEvent>;
451
453
  get onUnhandledDragOver(): Event<DockviewDndOverlayEvent>;
454
+ /**
455
+ * The drag-and-drop backends currently live: `dndStrategy` resolved against
456
+ * this device, which `'auto'` reads from the primary input device. Only an
457
+ * HTML5 drag can leave the window it started in, so check `html5` before
458
+ * relying on a drag between a popout window and the main window.
459
+ */
460
+ get dndCapabilities(): DndCapabilities;
452
461
  get onDidPopoutGroupSizeChange(): Event<PopoutGroupChangeSizeEvent>;
453
462
  get onDidPopoutGroupPositionChange(): Event<PopoutGroupChangePositionEvent>;
454
463
  /**
@@ -463,7 +472,23 @@ export declare class DockviewApi implements CommonApi<SerializedDockview> {
463
472
  * {@link onDidAddPopoutGroup}; not fired during component disposal.
464
473
  */
465
474
  get onDidRemovePopoutGroup(): Event<PopoutGroup>;
466
- get onDidOpenPopoutWindowFail(): Event<void>;
475
+ /**
476
+ * Fires when a popout window could not be used, carrying which way it
477
+ * failed: the URL was refused, the browser blocked the window, the host
478
+ * returned a window whose document the opener cannot reach, or it closed
479
+ * before loading. The group stays in (or returns to) the main grid.
480
+ */
481
+ get onDidOpenPopoutWindowFail(): Event<PopoutWindowFailure>;
482
+ /**
483
+ * Fires as dockview lets go of a popout window, while that window is still
484
+ * open, carrying its live `Window` handle. Covers every popout the component
485
+ * opened and every reason for closing one, disposal included;
486
+ * {@link onDidAddPopoutGroup} is the opening half.
487
+ *
488
+ * For hosts that own their windows: in a desktop webview the page's own
489
+ * `close()` can be a no-op, so the shell has to be told.
490
+ */
491
+ get onWillClosePopoutWindow(): Event<PopoutWindowEvent>;
467
492
  /** Enumerate the popout groups currently open in their own windows. */
468
493
  getPopouts(): PopoutGroup[];
469
494
  /**
@@ -8,13 +8,20 @@ export interface DismissableLayerOptions {
8
8
  /** A pointerdown landed *inside* the layer (not a dismissal). Use it to
9
9
  * mark interaction (e.g. make a transient layer sticky). */
10
10
  readonly onInsidePointerDown?: (event: PointerEvent) => void;
11
- /** Whether a pointer event is inside the layer. Defaults to a DOM
12
- * `contains` check against {@link DismissableLayerOptions.elements}.
11
+ /** Whether a pointer event is inside the layer. Defaults to checking the
12
+ * event's composed path against {@link DismissableLayerOptions.elements}.
13
13
  * Provide this for geometry-based hit testing (e.g. when the visible
14
14
  * content is a sibling overlay stacked on top of the layer). */
15
15
  readonly isInside?: (event: PointerEvent) => boolean;
16
16
  /** Elements treated as "inside" by the default contains check. */
17
17
  readonly elements?: () => HTMLElement[];
18
+ /** An element the layer is anchored to, used only to locate the shadow
19
+ * roots it lives in for {@link focusOut}. `elements` already provides
20
+ * that, so pass this when the layer has none — a layer that decides
21
+ * inside/outside purely by geometry ({@link isInside} /
22
+ * {@link isFocusInside}) would otherwise never see a focus move *within*
23
+ * a shadow root, since such a move never reaches the window. */
24
+ readonly anchor?: () => Node | null | undefined;
18
25
  /** Dismiss on `Escape` (default `true`). */
19
26
  readonly escape?: boolean;
20
27
  /** Extra keys that also dismiss (e.g. `'Enter'`). */
@@ -32,9 +39,14 @@ export interface DismissableLayerOptions {
32
39
  * `false`): the "slide back on focus loss" behaviour. */
33
40
  readonly focusOut?: boolean;
34
41
  /** Whether a newly-focused element is inside the layer (for
35
- * {@link focusOut}). Defaults to a `contains` check against
36
- * {@link elements}. Provide this for geometry-based testing when the
37
- * content is a sibling overlay stacked on top of the layer. */
42
+ * {@link focusOut}). Receives the target as seen from the layer's own
43
+ * tree — the one holding {@link anchor}, else the first of
44
+ * {@link elements} — so a predicate can always be written against the
45
+ * elements it was given: focus inside a *nested* web component arrives as
46
+ * that component's host, while focus in the layer's own shadow root
47
+ * arrives as the real element. Defaults to checking the event's composed
48
+ * path against {@link elements}. Provide this for geometry-based testing
49
+ * when the content is a sibling overlay stacked on top of the layer. */
38
50
  readonly isFocusInside?: (focused: Element) => boolean;
39
51
  /** Listen in the capture phase (default `false`). Use capture when the
40
52
  * layer must see the event before content handlers stop its propagation. */
@@ -47,8 +59,8 @@ export interface DismissableLayerOptions {
47
59
  * peeks): while it lives it watches a configurable set of dismiss signals
48
60
  * (Escape / extra keys, outside-pointerdown with an optional grace window,
49
61
  * window resize, focus moving outside) and calls `onDismiss`. Inside/outside is
50
- * decided by an `isInside` predicate (geometry) or a `contains` check against
51
- * `elements`. Dispose to detach every listener.
62
+ * decided by an `isInside` predicate (geometry) or by checking the event's
63
+ * composed path against `elements`. Dispose to detach every listener.
52
64
  *
53
65
  * It owns only the *signals*, not the surface element, its position, or any
54
66
  * hover/keep-open policy, so callers keep their own element lifecycle and
@@ -2,4 +2,7 @@ export declare function addGhostImage(dataTransfer: DataTransfer, ghostElement:
2
2
  x?: number;
3
3
  y?: number;
4
4
  ownerDocument?: Document;
5
+ /** The drag source. When it is inside a shadow root the ghost is
6
+ * appended there, so the styles scoped to that root apply. */
7
+ owner?: Node;
5
8
  }): void;
@@ -36,6 +36,7 @@ export declare class PointerDragController extends CompositeDisposable {
36
36
  private _upListener;
37
37
  private _cancelListener;
38
38
  private _iframeShield;
39
+ private _selectionShield;
39
40
  private _onDragMoveCallback?;
40
41
  private _onDragEndCallback?;
41
42
  private readonly _onDragStart;
@@ -40,6 +40,7 @@ export declare class PointerDragSource extends CompositeDisposable {
40
40
  private _pendingUpListener;
41
41
  private _pendingCancelListener;
42
42
  private _armTimer;
43
+ private _selectionShield;
43
44
  private _armed;
44
45
  private _startX;
45
46
  private _startY;
@@ -9,8 +9,9 @@ export interface PointerGhostOptions {
9
9
  /** Default 0.8. */
10
10
  opacity?: number;
11
11
  /**
12
- * Source element whose `ownerDocument.body` hosts the ghost. Pass it for
13
- * popout-window drags so the ghost renders in the popout's document.
12
+ * Source element whose document body (or shadow root, when it lives in
13
+ * one) hosts the ghost. Pass it for popout-window drags so the ghost
14
+ * renders in the popout's document.
14
15
  */
15
16
  owner?: Element;
16
17
  }
@@ -21,6 +22,9 @@ export interface PointerGhostOptions {
21
22
  */
22
23
  export declare class PointerGhost implements IDisposable {
23
24
  private readonly element;
25
+ /** What is positioned and attached: `element`, or a top-layer wrapper
26
+ * around it when the ghost lives in a shadow root. */
27
+ private readonly container;
24
28
  private readonly offsetX;
25
29
  private readonly offsetY;
26
30
  private _disposed;
@@ -16,6 +16,8 @@ export declare class PopupService extends CompositeDisposable {
16
16
  x: number;
17
17
  y: number;
18
18
  zIndex?: string;
19
+ }, options?: {
20
+ onClose?: () => void;
19
21
  }): void;
20
22
  close(): void;
21
23
  }
@@ -73,7 +73,9 @@ export declare class TabGroupManager {
73
73
  * target under the cursor never sees the drop that would clear its own.
74
74
  */
75
75
  clearChipDropOverlays(): void;
76
- snapshotChipWidths(): Map<string, number>;
76
+ /** Each chip's extent along the strip's main axis: width for a horizontal
77
+ * header, height for a vertical one. */
78
+ snapshotChipSizes(): Map<string, number>;
77
79
  positionUnderlines(): void;
78
80
  trackUnderlines(): void;
79
81
  setGroupDragImage(event: DragEvent, tabGroup: ITabGroup, chipEl: HTMLElement): void;
@@ -9,23 +9,43 @@ export interface TabAnimationState {
9
9
  sourceTabId: string;
10
10
  sourceIndex: number;
11
11
  tabPositions: Map<string, DOMRect>;
12
- /** Group-chip widths keyed by group ID, captured before collapse */
13
- chipPositions: Map<string, number>;
12
+ /** Group-chip main-axis sizes keyed by group ID, captured before collapse */
13
+ chipSizes: Map<string, number>;
14
14
  currentInsertionIndex: number | null;
15
15
  targetTabGroupId: string | null;
16
16
  /** When set, the drag source is a group chip (entire group drag) */
17
17
  sourceTabGroupId: string | null;
18
18
  /** Cached panel IDs of the source group (avoids repeated lookups during drag) */
19
19
  sourceGroupPanelIds: Set<string> | null;
20
- /** Width of the group chip, captured before collapse */
21
- sourceChipWidth: number;
22
- /** Distance from cursor to the left edge of the drag image */
23
- cursorOffsetFromDragLeft: number;
24
- /** Total width of the dragged content (chip + tabs for groups, tab width for singles) */
25
- sourceGapWidth: number;
26
- /** Left edge of the tabs container at drag start */
27
- containerLeft: number;
20
+ /** Main-axis size of the group chip, captured before collapse */
21
+ sourceChipSize: number;
22
+ /** Distance from the cursor to the leading edge of the drag image */
23
+ cursorOffsetFromDragStart: number;
24
+ /** Total main-axis size of the dragged content (chip + tabs for groups,
25
+ * the tab's own size for singles) */
26
+ sourceGapSize: number;
27
+ /** Leading edge of the tabs container at drag start */
28
+ containerStart: number;
28
29
  }
30
+ /**
31
+ * Main-axis extent of a rect. Tabs flow along x in a horizontal header
32
+ * (top/bottom) and along y in a vertical one (the left/right edge groups),
33
+ * so the reorder math reads every size through this.
34
+ */
35
+ export declare function mainAxisSize(rect: {
36
+ width: number;
37
+ height: number;
38
+ }, direction: DockviewHeaderDirection): number;
39
+ /** Leading edge of a rect along the main axis. */
40
+ export declare function mainAxisStart(rect: {
41
+ left: number;
42
+ top: number;
43
+ }, direction: DockviewHeaderDirection): number;
44
+ /** A cursor position projected onto the main axis. */
45
+ export declare function mainAxisCursor(event: {
46
+ clientX: number;
47
+ clientY: number;
48
+ }, direction: DockviewHeaderDirection): number;
29
49
  export interface ITabReorderHost {
30
50
  /** Live tab list (the `_tabs` array of the owning `Tabs`). */
31
51
  readonly tabItems: IValueDisposable<Tab>[];
@@ -88,7 +108,16 @@ export declare class TabReorderController extends CompositeDisposable {
88
108
  */
89
109
  clearExternalAnimState(): void;
90
110
  snapshotTabPositions(): Map<string, DOMRect>;
91
- private getAverageTabWidth;
111
+ /** Main-axis extent of a rect for this header's orientation. */
112
+ private _mainAxisSize;
113
+ /** Main-axis leading edge of a rect for this header's orientation. */
114
+ private _mainAxisStart;
115
+ /** The cursor coordinate along the main axis. */
116
+ private _mainAxisCoord;
117
+ /** The margin that opens the insertion gap. It must run along the main
118
+ * axis, so a vertical header pushes tabs down rather than sideways. */
119
+ private get _gapMarginProperty();
120
+ private getAverageTabSize;
92
121
  /**
93
122
  * Pointer-event entry point. The HTML5 path enters via the per-element
94
123
  * `dragover` listener; this one hit-tests the global pointer-drag
@@ -161,16 +190,18 @@ export declare class TabReorderController extends CompositeDisposable {
161
190
  */
162
191
  private _buildFirstPanelToGroupMap;
163
192
  /**
164
- * Walk the tabs left-to-right by their original widths and return the
165
- * insertion slot for the drag image's left edge (null if no slot fits).
193
+ * Walk the tabs in flow order by their original main-axis sizes and return
194
+ * the insertion slot for the drag image's leading edge (null if no slot
195
+ * fits).
166
196
  */
167
197
  private _computeDragOverInsertionIndex;
168
198
  /**
169
- * Rebuild the accumulated original width up to `insertionIndex`, walking the
170
- * tabs exactly the way the accumulation loop does, so callers know the
171
- * original right edge of the chip (if any) that precedes the insertion slot.
199
+ * Rebuild the accumulated original main-axis size up to `insertionIndex`,
200
+ * walking the tabs exactly the way the accumulation loop does, so callers
201
+ * know the original trailing edge of the chip (if any) that precedes the
202
+ * insertion slot.
172
203
  */
173
- private _accumulatedWidthUpTo;
204
+ private _accumulatedSizeUpTo;
174
205
  /**
175
206
  * Given a raw insertion index, snap it out of / into any tab group it falls
176
207
  * within and resolve the target group (if the drop should merge into one).
@@ -246,9 +277,9 @@ export declare class TabReorderController extends CompositeDisposable {
246
277
  */
247
278
  uncollapseSourceTab(sourceTabId: string): void;
248
279
  applyDragOverTransforms(skipTransition?: boolean): void;
249
- /** Gap width for the current drag: the whole group's span for a group
250
- * drag, otherwise the source tab's own width. */
251
- private _computeGapWidth;
280
+ /** Gap size for the current drag: the whole group's span for a group
281
+ * drag, otherwise the source tab's own main-axis size. */
282
+ private _computeGapSize;
252
283
  /**
253
284
  * When the insertion lands at or before a group's first tab, the chip is
254
285
  * shifted so the gap appears before the entire group. Returns that chip
@@ -270,7 +301,7 @@ export declare class TabReorderController extends CompositeDisposable {
270
301
  private _applyGapMargins;
271
302
  /** Pick the correct shifting class for tabs vs chips. */
272
303
  private _shiftingClass;
273
- /** Apply a margin-left value to an element, optionally bypassing CSS
304
+ /** Apply the main-axis gap margin to an element, optionally bypassing CSS
274
305
  * transitions for instant positioning. */
275
306
  private _setMargin;
276
307
  /** Clear an element's gap margin, animating it back to zero unless
@@ -1,9 +1,8 @@
1
1
  import { DockviewOptions } from './options';
2
2
  /**
3
- * Internal mapping of the user-facing `dndStrategy` option into the
4
- * per-backend capability flags consumed by drag-source / drop-target
5
- * construction sites. Not part of the public API; consumers only see
6
- * the `dndStrategy` option itself.
3
+ * Which drag-and-drop backends are live: the `dndStrategy` option resolved
4
+ * against the device. Read by the drag-source / drop-target construction sites,
5
+ * and exposed to consumers as `api.dndCapabilities`.
7
6
  */
8
7
  export interface DndCapabilities {
9
8
  /** HTML5 drag/drop wiring active (draggable attr, dragstart). */
@@ -1,5 +1,6 @@
1
1
  import { SerializedGridObject, Gridview, SerializedGridview } from '../gridview/gridview';
2
2
  import { DroptargetOverlayModel, Position, PositionResolver } from '../dnd/droptarget';
3
+ import { DndCapabilities } from './dndCapabilities';
3
4
  import { DockviewPanel, IDockviewPanel } from './dockviewPanel';
4
5
  import { IDisposable } from '../lifecycle';
5
6
  import { Event, Emitter } from '../events';
@@ -22,6 +23,7 @@ import { IKeyboardNavigationHost, IAdvancedDnDHost, IAutoHideEdgeGroupHost, ICon
22
23
  import { IHeaderActionsHost } from './headerActionsService';
23
24
  import { AnchoredBox, AnchorPosition, Box } from '../types';
24
25
  import { DockviewPanelRenderer, OverlayRenderContainer } from '../overlay/overlayRenderContainer';
26
+ import { PopoutWindowEvent, PopoutWindowFailure } from '../popoutWindow';
25
27
  import { PopupService } from './components/popupService';
26
28
  import { IRootDropTargetHost } from './rootDropTargetService';
27
29
  import { ILiveRegionHost } from './liveRegionService';
@@ -41,14 +43,16 @@ export interface DockviewPopoutGroupOptions {
41
43
  * Defaults to `/popout.html` if not provided
42
44
  */
43
45
  popoutUrl?: string;
44
- onDidOpen?: (event: {
45
- id: string;
46
- window: Window;
47
- }) => void;
48
- onWillClose?: (event: {
49
- id: string;
50
- window: Window;
51
- }) => void;
46
+ /**
47
+ * Called once this popout's window has opened, before its group is moved in.
48
+ * Scoped to this call; `onDidAddPopoutGroup` covers every popout.
49
+ */
50
+ onDidOpen?: (event: PopoutWindowEvent) => void;
51
+ /**
52
+ * Called while this popout's window is still open, as dockview lets go of
53
+ * it. Scoped to this call; `onWillClosePopoutWindow` covers every popout.
54
+ */
55
+ onWillClose?: (event: PopoutWindowEvent) => void;
52
56
  }
53
57
  interface DockviewPopoutGroupOptionsInternal extends DockviewPopoutGroupOptions {
54
58
  referenceGroup?: DockviewGroupPanel;
@@ -251,7 +255,8 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
251
255
  readonly onDidPopoutGroupPositionChange: Event<PopoutGroupChangePositionEvent>;
252
256
  readonly onDidAddPopoutGroup: Event<PopoutGroup>;
253
257
  readonly onDidRemovePopoutGroup: Event<PopoutGroup>;
254
- readonly onDidOpenPopoutWindowFail: Event<void>;
258
+ readonly onDidOpenPopoutWindowFail: Event<PopoutWindowFailure>;
259
+ readonly onWillClosePopoutWindow: Event<PopoutWindowEvent>;
255
260
  getPopouts(): PopoutGroup[];
256
261
  readonly onDidCreateTabGroup: Event<DockviewTabGroupChangeEvent>;
257
262
  readonly onDidDestroyTabGroup: Event<DockviewTabGroupChangeEvent>;
@@ -260,6 +265,7 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
260
265
  readonly onDidTabGroupChange: Event<DockviewTabGroupChangeEvent>;
261
266
  readonly onDidTabGroupCollapsedChange: Event<DockviewTabGroupCollapsedChangeEvent>;
262
267
  readonly options: DockviewComponentOptions;
268
+ readonly dndCapabilities: DndCapabilities;
263
269
  readonly tabGroupColorPalette: TabGroupColorPalette;
264
270
  updateOptions(options: DockviewOptions): void;
265
271
  moveGroupOrPanel(options: MoveGroupOrPanelOptions): void;
@@ -350,7 +356,9 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
350
356
  private readonly _onWillDrop;
351
357
  readonly onWillDrop: Event<DockviewWillDropEvent>;
352
358
  private _mutationDepth;
359
+ private _syncMutationDepth;
353
360
  private readonly _pendingLocationChanges;
361
+ private readonly _openingPopoutWindows;
354
362
  private _origin;
355
363
  private _originDepth;
356
364
  private readonly _onWillMutateLayout;
@@ -379,7 +387,11 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
379
387
  * state (e.g. a live region in each popout). */
380
388
  readonly onDidChangePopouts: Event<void>;
381
389
  private readonly _onDidOpenPopoutWindowFail;
382
- readonly onDidOpenPopoutWindowFail: Event<void>;
390
+ readonly onDidOpenPopoutWindowFail: Event<PopoutWindowFailure>;
391
+ private readonly _onWillClosePopoutWindow;
392
+ /** Fires for every popout window this component opened, however it was
393
+ * opened, while that window is still there. See `DockviewApi`. */
394
+ readonly onWillClosePopoutWindow: Event<PopoutWindowEvent>;
383
395
  private readonly _onDidStartFloatingGroupDrag;
384
396
  /** Fires with the dragged group when a floating group move-drag first moves.
385
397
  * Consumed by the Smart Guides service (`ISmartGuidesHost`) to start each
@@ -434,6 +446,8 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
434
446
  get orientation(): Orientation;
435
447
  get totalPanels(): number;
436
448
  get panels(): IDockviewPanel[];
449
+ /** `dndStrategy` resolved against this device; see `DockviewApi`. */
450
+ get dndCapabilities(): DndCapabilities;
437
451
  get options(): DockviewComponentOptions;
438
452
  get tabGroupColorPalette(): TabGroupColorPalette;
439
453
  get activePanel(): IDockviewPanel | undefined;
@@ -647,10 +661,11 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
647
661
  getPopoutWindows(): Window[];
648
662
  private _doAddPopoutGroup;
649
663
  /**
650
- * The popout window was blocked (e.g. by the browser's popup blocker,
651
- * common when restoring popouts on load). Fall back gracefully so the
652
- * group(s) end up valid and visible in the main grid rather than as
653
- * orphans that later crash clear()/remove().
664
+ * The popout window never opened - blocked by the browser's popup blocker
665
+ * (common when restoring popouts on load), or refused outright because its
666
+ * URL failed the same-origin guard. Fall back gracefully so the group(s)
667
+ * end up valid and visible in the main grid rather than as orphans that
668
+ * render nothing and later crash clear()/remove().
654
669
  */
655
670
  private handleBlockedPopout;
656
671
  /**
@@ -673,8 +688,9 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
673
688
  private _doAddFloatingGroup;
674
689
  private removeGroupIfEmpty;
675
690
  /**
676
- * Build an empty gridview configured to match the main grid's styling, for
677
- * hosting a nested layout inside a floating or popout window.
691
+ * Build an empty gridview configured to match the main grid's styling and
692
+ * resize behaviour, for hosting a nested layout inside a floating or popout
693
+ * window.
678
694
  */
679
695
  private createNestedGridview;
680
696
  /**
@@ -887,6 +903,8 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
887
903
  * therefore report as one, tagged with the kind of the last to finish.
888
904
  */
889
905
  private openMutation;
906
+ /** Covers removals with `skipActive` that disposed the active group. */
907
+ private releaseDisposedActiveGroup;
890
908
  /**
891
909
  * Coalesce a panel's `onDidLocationChange` to the end of the enclosing
892
910
  * transaction, or fire it immediately when no transaction is in flight.
@@ -152,6 +152,18 @@ export declare class ShellManager implements IDisposable {
152
152
  * Throws if a group at this position is already registered.
153
153
  */
154
154
  addEdgeView(position: EdgeGroupPosition, options: EdgeGroupOptions, group: IEdgeGroupHost): EdgeGroupView;
155
+ /**
156
+ * Lay out from the shell's current size.
157
+ *
158
+ * The ResizeObserver above only reports asynchronously, so between
159
+ * construction and its first callback the shell believes it has no size -
160
+ * and any layout built in that window (panels added straight after
161
+ * `createDockview`, say) resolves its sizes against zero and collapses to
162
+ * minimums, permanently. Seeding the size synchronously gives that work
163
+ * the real dimensions. Same guards as the observer: a detached or hidden
164
+ * shell has no size worth propagating.
165
+ */
166
+ layoutFromElement(): void;
155
167
  layout(width: number, height: number): void;
156
168
  /**
157
169
  * Called when the active theme changes. Updates splitview margins and
@@ -523,6 +523,8 @@ export interface IOverflowRow {
523
523
  * the keyboard controller (Enter).
524
524
  */
525
525
  activate(): void;
526
+ /** Disposes the row's tab renderer. */
527
+ dispose(): void;
526
528
  }
527
529
  /**
528
530
  * Core-provided builders handed to {@link IAdvancedOverflowService.renderOverflow}
@@ -293,6 +293,19 @@ export interface DockviewOptions {
293
293
  * Call `.layout(width, height)` to manually resize the container.
294
294
  */
295
295
  disableAutoResizing?: boolean;
296
+ /**
297
+ * Distribute the available space proportionally between groups when the
298
+ * container is resized, preserving each group's share of the layout.
299
+ *
300
+ * When `false` the extra (or missing) space is absorbed by the last group
301
+ * in each row/column instead, leaving the other splitters where they are -
302
+ * the behaviour found in VS Code. If the last group reaches its minimum or
303
+ * maximum size, the remainder moves on to the group before it.
304
+ *
305
+ * Applies to floating and popout windows too, and can be changed at runtime
306
+ * with `updateOptions`; `undefined` restores the default. Default: `true`.
307
+ */
308
+ proportionalLayout?: boolean;
296
309
  hideBorders?: boolean;
297
310
  singleTabMode?: 'fullwidth' | 'default';
298
311
  disableFloatingGroups?: boolean;
@@ -55,7 +55,7 @@ export interface IPopoutWindowService extends IDisposable {
55
55
  findReferenceGroupId(group: DockviewGroupPanel): string | undefined;
56
56
  observeGridviewSize(popoutWindow: PopoutWindow, gridview: Gridview, overlayRenderContainer: OverlayRenderContainer): IDisposable | undefined;
57
57
  readonly restorationPromise: Promise<void>;
58
- scheduleRestoration(delayMs: number, work: () => void, onCancel?: () => void): Promise<void>;
58
+ scheduleRestoration(delayMs: number, work: () => void | Promise<unknown>, onCancel?: () => void): Promise<void>;
59
59
  finishRestoration(promises: Promise<void>[]): void;
60
60
  cancelPendingRestorations(): void;
61
61
  serialize(): SerializedPopoutGroup[];
@@ -90,7 +90,13 @@ export declare class PopoutWindowService implements IPopoutWindowService {
90
90
  * the popout realm has no ResizeObserver (e.g. jsdom).
91
91
  */
92
92
  observeGridviewSize(popoutWindow: PopoutWindow, gridview: Gridview, overlayRenderContainer: OverlayRenderContainer): IDisposable | undefined;
93
- scheduleRestoration(delayMs: number, work: () => void, onCancel?: () => void): Promise<void>;
93
+ /**
94
+ * Runs `work` after `delayMs`, resolving once it has finished. Work that
95
+ * returns a promise is awaited, so a caller holding
96
+ * `restorationPromise` waits for the popout window itself rather than
97
+ * only for the timer that starts it.
98
+ */
99
+ scheduleRestoration(delayMs: number, work: () => void | Promise<unknown>, onCancel?: () => void): Promise<void>;
94
100
  finishRestoration(promises: Promise<void>[]): void;
95
101
  cancelPendingRestorations(): void;
96
102
  serialize(): SerializedPopoutGroup[];
package/dist/cjs/dom.d.ts CHANGED
@@ -24,11 +24,31 @@ export interface IFocusTracker extends IDisposable {
24
24
  export declare function trackFocus(element: HTMLElement): IFocusTracker;
25
25
  export declare function quasiPreventDefault(event: Event): void;
26
26
  export declare function quasiDefaultPrevented(event: Event): boolean;
27
+ /** Whether the event originated within any of `elements`. Checks the
28
+ * composed path, so it also holds for elements inside a shadow root, which a
29
+ * window or document listener sees retargeted to the shadow host. */
30
+ export declare function isEventWithin(event: Event, elements: readonly Element[]): boolean;
31
+ /** Every shadow root between `element` and its document, innermost first. An
32
+ * element in a component nested inside another component sits in more than
33
+ * one, and an event is cut at each boundary. */
34
+ export declare function shadowRootsOf(node: Node): ShadowRoot[];
35
+ /**
36
+ * `element` as a listener rooted in `scope`'s tree sees it. A node in a shadow
37
+ * root *below* that tree is retargeted to its host there, repeatedly for
38
+ * nested roots; a node already in the same tree is returned unchanged. Omit
39
+ * `scope` (or pass a node in the document) for the document-level view, which
40
+ * is what a window listener gets.
41
+ *
42
+ * The scope matters: a layer living inside a shadow root must be able to tell
43
+ * its own elements apart, and retargeting everything out to the document would
44
+ * collapse them all onto the one host.
45
+ */
46
+ export declare function retargetInto(element: Element, scope?: Node | null): Element;
27
47
  export type CspNonceProvider = string | ((targetDocument: Document) => string | undefined);
28
48
  export interface AddStylesOptions {
29
49
  nonce?: CspNonceProvider;
30
50
  }
31
- export declare function addStyles(document: Document, styleSheetList: StyleSheetList, options?: AddStylesOptions): void;
51
+ export declare function addStyles(document: Document, styleSheetList: StyleSheetList | readonly CSSStyleSheet[], options?: AddStylesOptions): void;
32
52
  export declare function getDomNodePagePosition(domNode: Element): {
33
53
  left: number;
34
54
  top: number;
@@ -40,10 +60,40 @@ export declare function getDomNodePagePosition(domNode: Element): {
40
60
  * @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/
41
61
  */
42
62
  export declare function isInDocument(element: Element): boolean;
63
+ /** Duck-typed so it holds for a shadow root from another window's realm. */
64
+ export declare function isShadowRoot(node: Node | null | undefined): node is ShadowRoot;
65
+ /**
66
+ * The document or shadow root to hit-test (`elementFromPoint` /
67
+ * `elementsFromPoint`) against for `node`. Hit-testing on the document stops
68
+ * at a shadow host, so when dockview is mounted in a shadow root it has to go
69
+ * through that root to reach its own elements. Falls back to the owning
70
+ * document (which may be a popout's) for a detached node.
71
+ */
72
+ export declare function getHitTestRoot(node: Node): DocumentOrShadowRoot;
43
73
  export declare function addTestId(element: HTMLElement, id: string): void;
44
74
  export declare function disableIframePointEvents(rootNode?: ParentNode): {
45
75
  release: () => void;
46
76
  };
77
+ /**
78
+ * Suppress text selection for the duration of a pointer drag.
79
+ *
80
+ * A pointer drag is just a held button as far as the browser is concerned, so
81
+ * it selects text under the cursor as it travels. HTML5 drag-and-drop is
82
+ * exempt - the browser owns the gesture - which is why this is only needed on
83
+ * the pointer backend.
84
+ *
85
+ * `user-select: none` alone is not enough on WebKit: it starts the selection
86
+ * gesture from a mousedown on a `user-select: none` element unless that
87
+ * element is also natively draggable, then extends it into whatever the
88
+ * pointer crosses. Cancelling `selectstart` refuses that first extension,
89
+ * which ends the gesture for the rest of the drag.
90
+ *
91
+ * An existing selection is left alone: a mousedown on a `user-select: none`
92
+ * element does not clear one natively, and a pointer drag should not either.
93
+ */
94
+ export declare function disableTextSelection(rootNode?: ParentNode): {
95
+ release: () => void;
96
+ };
47
97
  export declare function getDockviewTheme(element: HTMLElement): string | undefined;
48
98
  export declare class Classnames {
49
99
  private readonly element;
@@ -66,3 +116,13 @@ export declare function prefersReducedMotion(doc?: Document): boolean;
66
116
  * surface a non-see-through backdrop derived from the live DOM. Returns `''`
67
117
  * when nothing opaque is found (let the stylesheet decide). */
68
118
  export declare function resolveOpaqueBackground(element: HTMLElement): string;
119
+ /** The focused element as seen from `node`'s own tree. Unlike
120
+ * `document.activeElement`, which is the shadow host when focus is inside a
121
+ * shadow root, this reaches into the root `node` lives in (and a popout's
122
+ * own document), while a web component nested inside that tree still
123
+ * resolves to its host there. */
124
+ export declare function getActiveElement(node: Node): Element | null;
125
+ /** Where to append a floating element (e.g. a drag ghost) for `node`: its
126
+ * shadow root when it lives in one, so styles scoped there still apply,
127
+ * otherwise the body of its own document (which may be a popout's). */
128
+ export declare function getOverlayParent(node: Node): ParentNode;
@@ -5,7 +5,6 @@ import { Node } from './types';
5
5
  import { CompositeDisposable } from '../lifecycle';
6
6
  export declare class BranchNode extends CompositeDisposable implements IView {
7
7
  readonly orientation: Orientation;
8
- readonly proportionalLayout: boolean;
9
8
  readonly styles: ISplitviewStyles | undefined;
10
9
  readonly element: HTMLElement;
11
10
  private readonly splitview;
@@ -55,6 +54,8 @@ export declare class BranchNode extends CompositeDisposable implements IView {
55
54
  set disabled(value: boolean);
56
55
  get margin(): number;
57
56
  set margin(value: number);
57
+ get proportionalLayout(): boolean;
58
+ set proportionalLayout(value: boolean);
58
59
  constructor(orientation: Orientation, proportionalLayout: boolean, styles: ISplitviewStyles | undefined, size: number, orthogonalSize: number, disabled: boolean, margin: number | undefined, childDescriptors?: INodeDescriptor[]);
59
60
  setVisible(_visible: boolean): void;
60
61
  isChildVisible(index: number): boolean;
@@ -94,7 +94,6 @@ export interface MaximizedViewChanged {
94
94
  isMaximized: boolean;
95
95
  }
96
96
  export declare class Gridview implements IDisposable {
97
- readonly proportionalLayout: boolean;
98
97
  readonly styles: ISplitviewStyles | undefined;
99
98
  readonly element: HTMLElement;
100
99
  private _root;
@@ -148,6 +147,8 @@ export declare class Gridview implements IDisposable {
148
147
  getView(location?: number[]): GridNode<IGridView>;
149
148
  private _getViews;
150
149
  private progmaticSelect;
150
+ get proportionalLayout(): boolean;
151
+ set proportionalLayout(value: boolean);
151
152
  constructor(proportionalLayout: boolean, styles: ISplitviewStyles | undefined, orientation: Orientation, locked?: boolean, margin?: number);
152
153
  isViewVisible(location: number[]): boolean;
153
154
  setViewVisible(location: number[], visible: boolean): void;