dockview-core 3.1.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/cjs/api/component.api.d.ts +0 -2
  2. package/dist/cjs/api/component.api.js +0 -10
  3. package/dist/cjs/dnd/abstractDragHandler.js +4 -2
  4. package/dist/cjs/dnd/dropTargetAnchorContainer.d.ts +16 -0
  5. package/dist/cjs/dnd/dropTargetAnchorContainer.js +105 -0
  6. package/dist/cjs/dnd/droptarget.d.ts +16 -0
  7. package/dist/cjs/dnd/droptarget.js +138 -14
  8. package/dist/cjs/dnd/ghost.d.ts +4 -1
  9. package/dist/cjs/dnd/ghost.js +3 -2
  10. package/dist/cjs/dnd/groupDragHandler.js +3 -1
  11. package/dist/cjs/dockview/components/panel/content.js +10 -13
  12. package/dist/cjs/dockview/components/popupService.d.ts +13 -0
  13. package/dist/cjs/dockview/components/popupService.js +76 -0
  14. package/dist/cjs/dockview/components/tab/tab.js +17 -7
  15. package/dist/cjs/dockview/components/titlebar/tabOverflowControl.d.ts +8 -0
  16. package/dist/cjs/dockview/components/titlebar/tabOverflowControl.js +20 -0
  17. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +45 -0
  18. package/dist/cjs/dockview/components/titlebar/tabs.js +288 -0
  19. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +8 -9
  20. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +108 -152
  21. package/dist/cjs/dockview/components/titlebar/voidContainer.js +2 -9
  22. package/dist/cjs/dockview/dockviewComponent.d.ts +10 -3
  23. package/dist/cjs/dockview/dockviewComponent.js +71 -30
  24. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +4 -0
  25. package/dist/cjs/dockview/dockviewGroupPanelModel.js +31 -0
  26. package/dist/cjs/dockview/dockviewPanelModel.d.ts +5 -3
  27. package/dist/cjs/dockview/dockviewPanelModel.js +25 -4
  28. package/dist/cjs/dockview/framework.d.ts +4 -1
  29. package/dist/cjs/dockview/options.d.ts +8 -5
  30. package/dist/cjs/dockview/options.js +3 -1
  31. package/dist/cjs/dockview/theme.d.ts +31 -0
  32. package/dist/cjs/dockview/theme.js +42 -0
  33. package/dist/cjs/dockview/types.d.ts +5 -1
  34. package/dist/cjs/dom.d.ts +1 -0
  35. package/dist/cjs/dom.js +15 -1
  36. package/dist/cjs/gridview/baseComponentGridview.d.ts +3 -0
  37. package/dist/cjs/index.d.ts +1 -0
  38. package/dist/cjs/index.js +1 -0
  39. package/dist/cjs/paneview/paneviewComponent.js +1 -0
  40. package/dist/cjs/scrollbar.d.ts +12 -0
  41. package/dist/cjs/scrollbar.js +106 -0
  42. package/dist/cjs/splitview/splitview.js +1 -0
  43. package/dist/cjs/splitview/splitviewComponent.js +1 -0
  44. package/dist/dockview-core.amd.js +930 -293
  45. package/dist/dockview-core.amd.js.map +1 -1
  46. package/dist/dockview-core.amd.min.js +2 -2
  47. package/dist/dockview-core.amd.min.js.map +1 -1
  48. package/dist/dockview-core.amd.min.noStyle.js +2 -2
  49. package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
  50. package/dist/dockview-core.amd.noStyle.js +929 -292
  51. package/dist/dockview-core.amd.noStyle.js.map +1 -1
  52. package/dist/dockview-core.cjs.js +930 -293
  53. package/dist/dockview-core.cjs.js.map +1 -1
  54. package/dist/dockview-core.esm.js +923 -294
  55. package/dist/dockview-core.esm.js.map +1 -1
  56. package/dist/dockview-core.esm.min.js +2 -2
  57. package/dist/dockview-core.esm.min.js.map +1 -1
  58. package/dist/dockview-core.js +930 -293
  59. package/dist/dockview-core.js.map +1 -1
  60. package/dist/dockview-core.min.js +2 -2
  61. package/dist/dockview-core.min.js.map +1 -1
  62. package/dist/dockview-core.min.noStyle.js +2 -2
  63. package/dist/dockview-core.min.noStyle.js.map +1 -1
  64. package/dist/dockview-core.noStyle.js +929 -292
  65. package/dist/dockview-core.noStyle.js.map +1 -1
  66. package/dist/esm/api/component.api.d.ts +0 -2
  67. package/dist/esm/api/component.api.js +0 -6
  68. package/dist/esm/dnd/abstractDragHandler.js +4 -2
  69. package/dist/esm/dnd/dropTargetAnchorContainer.d.ts +16 -0
  70. package/dist/esm/dnd/dropTargetAnchorContainer.js +74 -0
  71. package/dist/esm/dnd/droptarget.d.ts +16 -0
  72. package/dist/esm/dnd/droptarget.js +134 -14
  73. package/dist/esm/dnd/ghost.d.ts +4 -1
  74. package/dist/esm/dnd/ghost.js +3 -2
  75. package/dist/esm/dnd/groupDragHandler.js +3 -1
  76. package/dist/esm/dockview/components/panel/content.js +10 -13
  77. package/dist/esm/dockview/components/popupService.d.ts +13 -0
  78. package/dist/esm/dockview/components/popupService.js +53 -0
  79. package/dist/esm/dockview/components/tab/tab.js +15 -7
  80. package/dist/esm/dockview/components/titlebar/tabOverflowControl.d.ts +8 -0
  81. package/dist/esm/dockview/components/titlebar/tabOverflowControl.js +16 -0
  82. package/dist/esm/dockview/components/titlebar/tabs.d.ts +45 -0
  83. package/dist/esm/dockview/components/titlebar/tabs.js +183 -0
  84. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +8 -9
  85. package/dist/esm/dockview/components/titlebar/tabsContainer.js +133 -162
  86. package/dist/esm/dockview/components/titlebar/voidContainer.js +2 -9
  87. package/dist/esm/dockview/dockviewComponent.d.ts +10 -3
  88. package/dist/esm/dockview/dockviewComponent.js +69 -24
  89. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +4 -0
  90. package/dist/esm/dockview/dockviewGroupPanelModel.js +27 -0
  91. package/dist/esm/dockview/dockviewPanelModel.d.ts +5 -3
  92. package/dist/esm/dockview/dockviewPanelModel.js +14 -4
  93. package/dist/esm/dockview/framework.d.ts +4 -1
  94. package/dist/esm/dockview/options.d.ts +8 -5
  95. package/dist/esm/dockview/options.js +3 -1
  96. package/dist/esm/dockview/theme.d.ts +31 -0
  97. package/dist/esm/dockview/theme.js +39 -0
  98. package/dist/esm/dockview/types.d.ts +5 -1
  99. package/dist/esm/dom.d.ts +1 -0
  100. package/dist/esm/dom.js +13 -0
  101. package/dist/esm/gridview/baseComponentGridview.d.ts +3 -0
  102. package/dist/esm/index.d.ts +1 -0
  103. package/dist/esm/index.js +1 -0
  104. package/dist/esm/paneview/paneviewComponent.js +1 -0
  105. package/dist/esm/scrollbar.d.ts +12 -0
  106. package/dist/esm/scrollbar.js +80 -0
  107. package/dist/esm/splitview/splitview.js +1 -0
  108. package/dist/esm/splitview/splitviewComponent.js +1 -0
  109. package/dist/styles/dockview.css +444 -76
  110. package/package.json +1 -1
@@ -0,0 +1,45 @@
1
+ import { Event } from '../../../events';
2
+ import { CompositeDisposable } from '../../../lifecycle';
3
+ import { DockviewComponent } from '../../dockviewComponent';
4
+ import { DockviewGroupPanel } from '../../dockviewGroupPanel';
5
+ import { WillShowOverlayLocationEvent } from '../../dockviewGroupPanelModel';
6
+ import { IDockviewPanel } from '../../dockviewPanel';
7
+ import { Tab } from '../tab/tab';
8
+ import { TabDragEvent, TabDropIndexEvent } from './tabsContainer';
9
+ export declare class Tabs extends CompositeDisposable {
10
+ private readonly group;
11
+ private readonly accessor;
12
+ private readonly _element;
13
+ private readonly _tabsList;
14
+ private readonly _observerDisposable;
15
+ private _tabs;
16
+ private selectedIndex;
17
+ private _showTabsOverflowControl;
18
+ private readonly _onTabDragStart;
19
+ readonly onTabDragStart: Event<TabDragEvent>;
20
+ private readonly _onDrop;
21
+ readonly onDrop: Event<TabDropIndexEvent>;
22
+ private readonly _onWillShowOverlay;
23
+ readonly onWillShowOverlay: Event<WillShowOverlayLocationEvent>;
24
+ private readonly _onOverflowTabsChange;
25
+ readonly onOverflowTabsChange: Event<{
26
+ tabs: string[];
27
+ reset: boolean;
28
+ }>;
29
+ get showTabsOverflowControl(): boolean;
30
+ set showTabsOverflowControl(value: boolean);
31
+ get element(): HTMLElement;
32
+ get panels(): string[];
33
+ get size(): number;
34
+ get tabs(): Tab[];
35
+ constructor(group: DockviewGroupPanel, accessor: DockviewComponent, options: {
36
+ showTabsOverflowControl: boolean;
37
+ });
38
+ indexOf(id: string): number;
39
+ isActive(tab: Tab): boolean;
40
+ setActivePanel(panel: IDockviewPanel): void;
41
+ openPanel(panel: IDockviewPanel, index?: number): void;
42
+ delete(id: string): void;
43
+ private addTab;
44
+ private toggleDropdown;
45
+ }
@@ -0,0 +1,183 @@
1
+ import { getPanelData } from '../../../dnd/dataTransfer';
2
+ import { isChildEntirelyVisibleWithinParent, OverflowObserver, } from '../../../dom';
3
+ import { addDisposableListener, Emitter } from '../../../events';
4
+ import { CompositeDisposable, Disposable, MutableDisposable, } from '../../../lifecycle';
5
+ import { Scrollbar } from '../../../scrollbar';
6
+ import { WillShowOverlayLocationEvent } from '../../dockviewGroupPanelModel';
7
+ import { Tab } from '../tab/tab';
8
+ export class Tabs extends CompositeDisposable {
9
+ get showTabsOverflowControl() {
10
+ return this._showTabsOverflowControl;
11
+ }
12
+ set showTabsOverflowControl(value) {
13
+ if (this._showTabsOverflowControl == value) {
14
+ return;
15
+ }
16
+ this._showTabsOverflowControl = value;
17
+ if (value) {
18
+ const observer = new OverflowObserver(this._tabsList);
19
+ this._observerDisposable.value = new CompositeDisposable(observer, observer.onDidChange((event) => {
20
+ const hasOverflow = event.hasScrollX || event.hasScrollY;
21
+ this.toggleDropdown({ reset: !hasOverflow });
22
+ }), addDisposableListener(this._tabsList, 'scroll', () => {
23
+ this.toggleDropdown({ reset: false });
24
+ }));
25
+ }
26
+ }
27
+ get element() {
28
+ return this._element;
29
+ }
30
+ get panels() {
31
+ return this._tabs.map((_) => _.value.panel.id);
32
+ }
33
+ get size() {
34
+ return this._tabs.length;
35
+ }
36
+ get tabs() {
37
+ return this._tabs.map((_) => _.value);
38
+ }
39
+ constructor(group, accessor, options) {
40
+ super();
41
+ this.group = group;
42
+ this.accessor = accessor;
43
+ this._observerDisposable = new MutableDisposable();
44
+ this._tabs = [];
45
+ this.selectedIndex = -1;
46
+ this._showTabsOverflowControl = false;
47
+ this._onTabDragStart = new Emitter();
48
+ this.onTabDragStart = this._onTabDragStart.event;
49
+ this._onDrop = new Emitter();
50
+ this.onDrop = this._onDrop.event;
51
+ this._onWillShowOverlay = new Emitter();
52
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
53
+ this._onOverflowTabsChange = new Emitter();
54
+ this.onOverflowTabsChange = this._onOverflowTabsChange.event;
55
+ this._tabsList = document.createElement('div');
56
+ this._tabsList.className = 'dv-tabs-container dv-horizontal';
57
+ this.showTabsOverflowControl = options.showTabsOverflowControl;
58
+ const scrollbar = new Scrollbar(this._tabsList);
59
+ this._element = scrollbar.element;
60
+ this.addDisposables(this._onOverflowTabsChange, this._observerDisposable, scrollbar, this._onWillShowOverlay, this._onDrop, this._onTabDragStart, addDisposableListener(this.element, 'pointerdown', (event) => {
61
+ if (event.defaultPrevented) {
62
+ return;
63
+ }
64
+ const isLeftClick = event.button === 0;
65
+ if (isLeftClick) {
66
+ this.accessor.doSetGroupActive(this.group);
67
+ }
68
+ }), Disposable.from(() => {
69
+ for (const { value, disposable } of this._tabs) {
70
+ disposable.dispose();
71
+ value.dispose();
72
+ }
73
+ this._tabs = [];
74
+ }));
75
+ }
76
+ indexOf(id) {
77
+ return this._tabs.findIndex((tab) => tab.value.panel.id === id);
78
+ }
79
+ isActive(tab) {
80
+ return (this.selectedIndex > -1 &&
81
+ this._tabs[this.selectedIndex].value === tab);
82
+ }
83
+ setActivePanel(panel) {
84
+ let runningWidth = 0;
85
+ for (const tab of this._tabs) {
86
+ const isActivePanel = panel.id === tab.value.panel.id;
87
+ tab.value.setActive(isActivePanel);
88
+ if (isActivePanel) {
89
+ const element = tab.value.element;
90
+ const parentElement = element.parentElement;
91
+ if (runningWidth < parentElement.scrollLeft ||
92
+ runningWidth + element.clientWidth >
93
+ parentElement.scrollLeft + parentElement.clientWidth) {
94
+ parentElement.scrollLeft = runningWidth;
95
+ }
96
+ }
97
+ runningWidth += tab.value.element.clientWidth;
98
+ }
99
+ }
100
+ openPanel(panel, index = this._tabs.length) {
101
+ if (this._tabs.find((tab) => tab.value.panel.id === panel.id)) {
102
+ return;
103
+ }
104
+ const tab = new Tab(panel, this.accessor, this.group);
105
+ tab.setContent(panel.view.tab);
106
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
107
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
108
+ }), tab.onPointerDown((event) => {
109
+ if (event.defaultPrevented) {
110
+ return;
111
+ }
112
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
113
+ const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
114
+ this.size === 1;
115
+ if (isFloatingGroupsEnabled &&
116
+ !isFloatingWithOnePanel &&
117
+ event.shiftKey) {
118
+ event.preventDefault();
119
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
120
+ const { top, left } = tab.element.getBoundingClientRect();
121
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
122
+ this.accessor.addFloatingGroup(panel, {
123
+ x: left - rootLeft,
124
+ y: top - rootTop,
125
+ inDragMode: true,
126
+ });
127
+ return;
128
+ }
129
+ switch (event.button) {
130
+ case 0: // left click or touch
131
+ if (this.group.activePanel !== panel) {
132
+ this.group.model.openPanel(panel);
133
+ }
134
+ break;
135
+ }
136
+ }), tab.onDrop((event) => {
137
+ this._onDrop.fire({
138
+ event: event.nativeEvent,
139
+ index: this._tabs.findIndex((x) => x.value === tab),
140
+ });
141
+ }), tab.onWillShowOverlay((event) => {
142
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
143
+ kind: 'tab',
144
+ panel: this.group.activePanel,
145
+ api: this.accessor.api,
146
+ group: this.group,
147
+ getData: getPanelData,
148
+ }));
149
+ }));
150
+ const value = { value: tab, disposable };
151
+ this.addTab(value, index);
152
+ }
153
+ delete(id) {
154
+ const index = this.indexOf(id);
155
+ const tabToRemove = this._tabs.splice(index, 1)[0];
156
+ const { value, disposable } = tabToRemove;
157
+ disposable.dispose();
158
+ value.dispose();
159
+ value.element.remove();
160
+ }
161
+ addTab(tab, index = this._tabs.length) {
162
+ if (index < 0 || index > this._tabs.length) {
163
+ throw new Error('invalid location');
164
+ }
165
+ this._tabsList.insertBefore(tab.value.element, this._tabsList.children[index]);
166
+ this._tabs = [
167
+ ...this._tabs.slice(0, index),
168
+ tab,
169
+ ...this._tabs.slice(index),
170
+ ];
171
+ if (this.selectedIndex < 0) {
172
+ this.selectedIndex = index;
173
+ }
174
+ }
175
+ toggleDropdown(options) {
176
+ const tabs = options.reset
177
+ ? []
178
+ : this._tabs
179
+ .filter((tab) => !isChildEntirelyVisibleWithinParent(tab.value.element, this._tabsList))
180
+ .map((x) => x.value.panel.id);
181
+ this._onOverflowTabsChange.fire({ tabs, reset: options.reset });
182
+ }
183
+ }
@@ -43,21 +43,21 @@ export declare class TabsContainer extends CompositeDisposable implements ITabsC
43
43
  private readonly accessor;
44
44
  private readonly group;
45
45
  private readonly _element;
46
- private readonly tabContainer;
46
+ private readonly tabs;
47
47
  private readonly rightActionsContainer;
48
48
  private readonly leftActionsContainer;
49
49
  private readonly preActionsContainer;
50
50
  private readonly voidContainer;
51
- private tabs;
52
- private selectedIndex;
53
51
  private rightActions;
54
52
  private leftActions;
55
53
  private preActions;
56
54
  private _hidden;
55
+ private dropdownPart;
56
+ private _overflowTabs;
57
+ private readonly _dropdownDisposable;
57
58
  private readonly _onDrop;
58
59
  readonly onDrop: Event<TabDropIndexEvent>;
59
- private readonly _onTabDragStart;
60
- readonly onTabDragStart: Event<TabDragEvent>;
60
+ get onTabDragStart(): Event<TabDragEvent>;
61
61
  private readonly _onGroupDragStart;
62
62
  readonly onGroupDragStart: Event<GroupDragEvent>;
63
63
  private readonly _onWillShowOverlay;
@@ -66,21 +66,20 @@ export declare class TabsContainer extends CompositeDisposable implements ITabsC
66
66
  get size(): number;
67
67
  get hidden(): boolean;
68
68
  set hidden(value: boolean);
69
+ get element(): HTMLElement;
70
+ constructor(accessor: DockviewComponent, group: DockviewGroupPanel);
69
71
  show(): void;
70
72
  hide(): void;
71
73
  setRightActionsElement(element: HTMLElement | undefined): void;
72
74
  setLeftActionsElement(element: HTMLElement | undefined): void;
73
75
  setPrefixActionsElement(element: HTMLElement | undefined): void;
74
- get element(): HTMLElement;
75
76
  isActive(tab: Tab): boolean;
76
77
  indexOf(id: string): number;
77
- constructor(accessor: DockviewComponent, group: DockviewGroupPanel);
78
78
  setActive(_isGroupActive: boolean): void;
79
79
  delete(id: string): void;
80
80
  setActivePanel(panel: IDockviewPanel): void;
81
81
  openPanel(panel: IDockviewPanel, index?: number): void;
82
82
  closePanel(panel: IDockviewPanel): void;
83
- dispose(): void;
84
- private addTab;
85
83
  private updateClassnames;
84
+ private toggleDropdown;
86
85
  }
@@ -1,16 +1,20 @@
1
- import { CompositeDisposable, } from '../../../lifecycle';
1
+ import { CompositeDisposable, Disposable, MutableDisposable, } from '../../../lifecycle';
2
2
  import { addDisposableListener, Emitter } from '../../../events';
3
- import { Tab } from '../tab/tab';
4
3
  import { VoidContainer } from './voidContainer';
5
4
  import { toggleClass } from '../../../dom';
6
5
  import { WillShowOverlayLocationEvent } from '../../dockviewGroupPanelModel';
7
6
  import { getPanelData } from '../../../dnd/dataTransfer';
7
+ import { Tabs } from './tabs';
8
+ import { createDropdownElementHandle, } from './tabOverflowControl';
8
9
  export class TabsContainer extends CompositeDisposable {
10
+ get onTabDragStart() {
11
+ return this.tabs.onTabDragStart;
12
+ }
9
13
  get panels() {
10
- return this.tabs.map((_) => _.value.panel.id);
14
+ return this.tabs.panels;
11
15
  }
12
16
  get size() {
13
- return this.tabs.length;
17
+ return this.tabs.size;
14
18
  }
15
19
  get hidden() {
16
20
  return this._hidden;
@@ -19,74 +23,19 @@ export class TabsContainer extends CompositeDisposable {
19
23
  this._hidden = value;
20
24
  this.element.style.display = value ? 'none' : '';
21
25
  }
22
- show() {
23
- if (!this.hidden) {
24
- this.element.style.display = '';
25
- }
26
- }
27
- hide() {
28
- this._element.style.display = 'none';
29
- }
30
- setRightActionsElement(element) {
31
- if (this.rightActions === element) {
32
- return;
33
- }
34
- if (this.rightActions) {
35
- this.rightActions.remove();
36
- this.rightActions = undefined;
37
- }
38
- if (element) {
39
- this.rightActionsContainer.appendChild(element);
40
- this.rightActions = element;
41
- }
42
- }
43
- setLeftActionsElement(element) {
44
- if (this.leftActions === element) {
45
- return;
46
- }
47
- if (this.leftActions) {
48
- this.leftActions.remove();
49
- this.leftActions = undefined;
50
- }
51
- if (element) {
52
- this.leftActionsContainer.appendChild(element);
53
- this.leftActions = element;
54
- }
55
- }
56
- setPrefixActionsElement(element) {
57
- if (this.preActions === element) {
58
- return;
59
- }
60
- if (this.preActions) {
61
- this.preActions.remove();
62
- this.preActions = undefined;
63
- }
64
- if (element) {
65
- this.preActionsContainer.appendChild(element);
66
- this.preActions = element;
67
- }
68
- }
69
26
  get element() {
70
27
  return this._element;
71
28
  }
72
- isActive(tab) {
73
- return (this.selectedIndex > -1 &&
74
- this.tabs[this.selectedIndex].value === tab);
75
- }
76
- indexOf(id) {
77
- return this.tabs.findIndex((tab) => tab.value.panel.id === id);
78
- }
79
29
  constructor(accessor, group) {
80
30
  super();
81
31
  this.accessor = accessor;
82
32
  this.group = group;
83
- this.tabs = [];
84
- this.selectedIndex = -1;
85
33
  this._hidden = false;
34
+ this.dropdownPart = null;
35
+ this._overflowTabs = [];
36
+ this._dropdownDisposable = new MutableDisposable();
86
37
  this._onDrop = new Emitter();
87
38
  this.onDrop = this._onDrop.event;
88
- this._onTabDragStart = new Emitter();
89
- this.onTabDragStart = this._onTabDragStart.event;
90
39
  this._onGroupDragStart = new Emitter();
91
40
  this.onGroupDragStart = this._onGroupDragStart.event;
92
41
  this._onWillShowOverlay = new Emitter();
@@ -100,15 +49,21 @@ export class TabsContainer extends CompositeDisposable {
100
49
  this.leftActionsContainer.className = 'dv-left-actions-container';
101
50
  this.preActionsContainer = document.createElement('div');
102
51
  this.preActionsContainer.className = 'dv-pre-actions-container';
103
- this.tabContainer = document.createElement('div');
104
- this.tabContainer.className = 'dv-tabs-container';
52
+ this.tabs = new Tabs(group, accessor, {
53
+ showTabsOverflowControl: !accessor.options.disableTabsOverflowList,
54
+ });
105
55
  this.voidContainer = new VoidContainer(this.accessor, this.group);
106
56
  this._element.appendChild(this.preActionsContainer);
107
- this._element.appendChild(this.tabContainer);
57
+ this._element.appendChild(this.tabs.element);
108
58
  this._element.appendChild(this.leftActionsContainer);
109
59
  this._element.appendChild(this.voidContainer.element);
110
60
  this._element.appendChild(this.rightActionsContainer);
111
- this.addDisposables(this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
61
+ this.addDisposables(accessor.onDidOptionsChange(() => {
62
+ this.tabs.showTabsOverflowControl =
63
+ !accessor.options.disableTabsOverflowList;
64
+ }), this.tabs.onOverflowTabsChange((event) => {
65
+ this.toggleDropdown(event);
66
+ }), this.tabs, this._onWillShowOverlay, this._onDrop, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
112
67
  this._onGroupDragStart.fire({
113
68
  nativeEvent: event,
114
69
  group: this.group,
@@ -116,7 +71,7 @@ export class TabsContainer extends CompositeDisposable {
116
71
  }), this.voidContainer.onDrop((event) => {
117
72
  this._onDrop.fire({
118
73
  event: event.nativeEvent,
119
- index: this.tabs.length,
74
+ index: this.tabs.size,
120
75
  });
121
76
  }), this.voidContainer.onWillShowOverlay((event) => {
122
77
  this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
@@ -127,6 +82,9 @@ export class TabsContainer extends CompositeDisposable {
127
82
  getData: getPanelData,
128
83
  }));
129
84
  }), addDisposableListener(this.voidContainer.element, 'pointerdown', (event) => {
85
+ if (event.defaultPrevented) {
86
+ return;
87
+ }
130
88
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
131
89
  if (isFloatingGroupsEnabled &&
132
90
  event.shiftKey &&
@@ -140,117 +98,130 @@ export class TabsContainer extends CompositeDisposable {
140
98
  inDragMode: true,
141
99
  });
142
100
  }
143
- }), addDisposableListener(this.tabContainer, 'pointerdown', (event) => {
144
- if (event.defaultPrevented) {
145
- return;
146
- }
147
- const isLeftClick = event.button === 0;
148
- if (isLeftClick) {
149
- this.accessor.doSetGroupActive(this.group);
150
- }
151
101
  }));
152
102
  }
103
+ show() {
104
+ if (!this.hidden) {
105
+ this.element.style.display = '';
106
+ }
107
+ }
108
+ hide() {
109
+ this._element.style.display = 'none';
110
+ }
111
+ setRightActionsElement(element) {
112
+ if (this.rightActions === element) {
113
+ return;
114
+ }
115
+ if (this.rightActions) {
116
+ this.rightActions.remove();
117
+ this.rightActions = undefined;
118
+ }
119
+ if (element) {
120
+ this.rightActionsContainer.appendChild(element);
121
+ this.rightActions = element;
122
+ }
123
+ }
124
+ setLeftActionsElement(element) {
125
+ if (this.leftActions === element) {
126
+ return;
127
+ }
128
+ if (this.leftActions) {
129
+ this.leftActions.remove();
130
+ this.leftActions = undefined;
131
+ }
132
+ if (element) {
133
+ this.leftActionsContainer.appendChild(element);
134
+ this.leftActions = element;
135
+ }
136
+ }
137
+ setPrefixActionsElement(element) {
138
+ if (this.preActions === element) {
139
+ return;
140
+ }
141
+ if (this.preActions) {
142
+ this.preActions.remove();
143
+ this.preActions = undefined;
144
+ }
145
+ if (element) {
146
+ this.preActionsContainer.appendChild(element);
147
+ this.preActions = element;
148
+ }
149
+ }
150
+ isActive(tab) {
151
+ return this.tabs.isActive(tab);
152
+ }
153
+ indexOf(id) {
154
+ return this.tabs.indexOf(id);
155
+ }
153
156
  setActive(_isGroupActive) {
154
157
  // noop
155
158
  }
156
159
  delete(id) {
157
- const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
158
- const tabToRemove = this.tabs.splice(index, 1)[0];
159
- if (!tabToRemove) {
160
- throw new Error(`dockview: Tab not found`);
161
- }
162
- const { value, disposable } = tabToRemove;
163
- disposable.dispose();
164
- value.dispose();
165
- value.element.remove();
160
+ this.tabs.delete(id);
166
161
  this.updateClassnames();
167
162
  }
168
163
  setActivePanel(panel) {
169
- this.tabs.forEach((tab) => {
170
- const isActivePanel = panel.id === tab.value.panel.id;
171
- tab.value.setActive(isActivePanel);
172
- });
164
+ this.tabs.setActivePanel(panel);
173
165
  }
174
- openPanel(panel, index = this.tabs.length) {
175
- if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
176
- return;
177
- }
178
- const tab = new Tab(panel, this.accessor, this.group);
179
- tab.setContent(panel.view.tab);
180
- const disposable = new CompositeDisposable(tab.onDragStart((event) => {
181
- this._onTabDragStart.fire({ nativeEvent: event, panel });
182
- }), tab.onPointerDown((event) => {
183
- if (event.defaultPrevented) {
184
- return;
185
- }
186
- const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
187
- const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
188
- this.size === 1;
189
- if (isFloatingGroupsEnabled &&
190
- !isFloatingWithOnePanel &&
191
- event.shiftKey) {
192
- event.preventDefault();
193
- const panel = this.accessor.getGroupPanel(tab.panel.id);
194
- const { top, left } = tab.element.getBoundingClientRect();
195
- const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
196
- this.accessor.addFloatingGroup(panel, {
197
- x: left - rootLeft,
198
- y: top - rootTop,
199
- inDragMode: true,
200
- });
201
- return;
202
- }
203
- switch (event.button) {
204
- case 0: // left click or touch
205
- if (this.group.activePanel !== panel) {
206
- this.group.model.openPanel(panel);
207
- }
208
- break;
209
- }
210
- }), tab.onDrop((event) => {
211
- this._onDrop.fire({
212
- event: event.nativeEvent,
213
- index: this.tabs.findIndex((x) => x.value === tab),
214
- });
215
- }), tab.onWillShowOverlay((event) => {
216
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
217
- kind: 'tab',
218
- panel: this.group.activePanel,
219
- api: this.accessor.api,
220
- group: this.group,
221
- getData: getPanelData,
222
- }));
223
- }));
224
- const value = { value: tab, disposable };
225
- this.addTab(value, index);
166
+ openPanel(panel, index = this.tabs.size) {
167
+ this.tabs.openPanel(panel, index);
168
+ this.updateClassnames();
226
169
  }
227
170
  closePanel(panel) {
228
171
  this.delete(panel.id);
229
172
  }
230
- dispose() {
231
- super.dispose();
232
- for (const { value, disposable } of this.tabs) {
233
- disposable.dispose();
234
- value.dispose();
235
- }
236
- this.tabs = [];
173
+ updateClassnames() {
174
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
237
175
  }
238
- addTab(tab, index = this.tabs.length) {
239
- if (index < 0 || index > this.tabs.length) {
240
- throw new Error('invalid location');
176
+ toggleDropdown(options) {
177
+ const tabs = options.reset ? [] : options.tabs;
178
+ this._overflowTabs = tabs;
179
+ if (this._overflowTabs.length > 0 && this.dropdownPart) {
180
+ this.dropdownPart.update({ tabs: tabs.length });
181
+ return;
241
182
  }
242
- this.tabContainer.insertBefore(tab.value.element, this.tabContainer.children[index]);
243
- this.tabs = [
244
- ...this.tabs.slice(0, index),
245
- tab,
246
- ...this.tabs.slice(index),
247
- ];
248
- if (this.selectedIndex < 0) {
249
- this.selectedIndex = index;
183
+ if (this._overflowTabs.length === 0) {
184
+ this._dropdownDisposable.dispose();
185
+ return;
250
186
  }
251
- this.updateClassnames();
252
- }
253
- updateClassnames() {
254
- toggleClass(this._element, 'dv-single-tab', this.size === 1);
187
+ const root = document.createElement('div');
188
+ root.className = 'dv-tabs-overflow-dropdown-root';
189
+ const part = createDropdownElementHandle();
190
+ part.update({ tabs: tabs.length });
191
+ this.dropdownPart = part;
192
+ root.appendChild(part.element);
193
+ this.rightActionsContainer.prepend(root);
194
+ this._dropdownDisposable.value = new CompositeDisposable(Disposable.from(() => {
195
+ var _a, _b;
196
+ root.remove();
197
+ (_b = (_a = this.dropdownPart) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
198
+ this.dropdownPart = null;
199
+ }), addDisposableListener(root, 'pointerdown', (event) => {
200
+ event.preventDefault();
201
+ }, { capture: true }), addDisposableListener(root, 'click', (event) => {
202
+ const el = document.createElement('div');
203
+ el.style.overflow = 'auto';
204
+ el.className = 'dv-tabs-overflow-container';
205
+ for (const tab of this.tabs.tabs.filter((tab) => this._overflowTabs.includes(tab.panel.id))) {
206
+ const panelObject = this.group.panels.find((panel) => panel === tab.panel);
207
+ const tabComponent = panelObject.view.createTabRenderer('headerOverflow');
208
+ const child = tabComponent.element;
209
+ const wrapper = document.createElement('div');
210
+ toggleClass(wrapper, 'dv-tab', true);
211
+ toggleClass(wrapper, 'dv-active-tab', panelObject.api.isActive);
212
+ toggleClass(wrapper, 'dv-inactive-tab', !panelObject.api.isActive);
213
+ wrapper.addEventListener('mousedown', () => {
214
+ this.accessor.popupService.close();
215
+ tab.element.scrollIntoView();
216
+ tab.panel.api.setActive();
217
+ });
218
+ wrapper.appendChild(child);
219
+ el.appendChild(wrapper);
220
+ }
221
+ this.accessor.popupService.openPopover(el, {
222
+ x: event.clientX,
223
+ y: event.clientY,
224
+ });
225
+ }));
255
226
  }
256
227
  }
@@ -1,4 +1,3 @@
1
- import { last } from '../../../array';
2
1
  import { getPanelData } from '../../../dnd/dataTransfer';
3
2
  import { Droptarget, } from '../../../dnd/droptarget';
4
3
  import { GroupDragHandler } from '../../../dnd/groupDragHandler';
@@ -26,19 +25,13 @@ export class VoidContainer extends CompositeDisposable {
26
25
  this.dropTraget = new Droptarget(this._element, {
27
26
  acceptedTargetZones: ['center'],
28
27
  canDisplayOverlay: (event, position) => {
29
- var _a;
30
28
  const data = getPanelData();
31
29
  if (data && this.accessor.id === data.viewId) {
32
- if (data.panelId === null &&
33
- data.groupId === this.group.id) {
34
- // don't allow group move to drop on self
35
- return false;
36
- }
37
- // don't show the overlay if the tab being dragged is the last panel of this group
38
- return ((_a = last(this.group.panels)) === null || _a === void 0 ? void 0 : _a.id) !== data.panelId;
30
+ return true;
39
31
  }
40
32
  return group.model.canDisplayOverlay(event, position, 'header_space');
41
33
  },
34
+ getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
42
35
  });
43
36
  this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
44
37
  this.addDisposables(handler, handler.onDragStart((event) => {