dockview-core 3.2.0 → 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.
- package/dist/cjs/api/component.api.d.ts +0 -2
- package/dist/cjs/api/component.api.js +0 -10
- package/dist/cjs/dnd/abstractDragHandler.js +4 -2
- package/dist/cjs/dnd/dropTargetAnchorContainer.d.ts +16 -0
- package/dist/cjs/dnd/dropTargetAnchorContainer.js +105 -0
- package/dist/cjs/dnd/droptarget.d.ts +16 -0
- package/dist/cjs/dnd/droptarget.js +138 -14
- package/dist/cjs/dnd/ghost.d.ts +4 -1
- package/dist/cjs/dnd/ghost.js +3 -2
- package/dist/cjs/dnd/groupDragHandler.js +3 -1
- package/dist/cjs/dockview/components/panel/content.js +10 -13
- package/dist/cjs/dockview/components/popupService.d.ts +13 -0
- package/dist/cjs/dockview/components/popupService.js +76 -0
- package/dist/cjs/dockview/components/tab/tab.js +17 -7
- package/dist/cjs/dockview/components/titlebar/tabOverflowControl.d.ts +8 -0
- package/dist/cjs/dockview/components/titlebar/tabOverflowControl.js +20 -0
- package/dist/cjs/dockview/components/titlebar/tabs.d.ts +45 -0
- package/dist/cjs/dockview/components/titlebar/tabs.js +288 -0
- package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +8 -9
- package/dist/cjs/dockview/components/titlebar/tabsContainer.js +108 -152
- package/dist/cjs/dockview/components/titlebar/voidContainer.js +2 -9
- package/dist/cjs/dockview/dockviewComponent.d.ts +10 -3
- package/dist/cjs/dockview/dockviewComponent.js +71 -30
- package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +4 -0
- package/dist/cjs/dockview/dockviewGroupPanelModel.js +31 -0
- package/dist/cjs/dockview/dockviewPanelModel.d.ts +5 -3
- package/dist/cjs/dockview/dockviewPanelModel.js +25 -4
- package/dist/cjs/dockview/framework.d.ts +4 -1
- package/dist/cjs/dockview/options.d.ts +8 -5
- package/dist/cjs/dockview/options.js +3 -1
- package/dist/cjs/dockview/theme.d.ts +31 -0
- package/dist/cjs/dockview/theme.js +42 -0
- package/dist/cjs/dockview/types.d.ts +5 -1
- package/dist/cjs/dom.d.ts +1 -0
- package/dist/cjs/dom.js +15 -1
- package/dist/cjs/gridview/baseComponentGridview.d.ts +3 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/paneview/paneviewComponent.js +1 -0
- package/dist/cjs/scrollbar.d.ts +12 -0
- package/dist/cjs/scrollbar.js +106 -0
- package/dist/cjs/splitview/splitview.js +1 -0
- package/dist/cjs/splitview/splitviewComponent.js +1 -0
- package/dist/dockview-core.amd.js +930 -293
- package/dist/dockview-core.amd.js.map +1 -1
- package/dist/dockview-core.amd.min.js +2 -2
- package/dist/dockview-core.amd.min.js.map +1 -1
- package/dist/dockview-core.amd.min.noStyle.js +2 -2
- package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
- package/dist/dockview-core.amd.noStyle.js +929 -292
- package/dist/dockview-core.amd.noStyle.js.map +1 -1
- package/dist/dockview-core.cjs.js +930 -293
- package/dist/dockview-core.cjs.js.map +1 -1
- package/dist/dockview-core.esm.js +923 -294
- package/dist/dockview-core.esm.js.map +1 -1
- package/dist/dockview-core.esm.min.js +2 -2
- package/dist/dockview-core.esm.min.js.map +1 -1
- package/dist/dockview-core.js +930 -293
- package/dist/dockview-core.js.map +1 -1
- package/dist/dockview-core.min.js +2 -2
- package/dist/dockview-core.min.js.map +1 -1
- package/dist/dockview-core.min.noStyle.js +2 -2
- package/dist/dockview-core.min.noStyle.js.map +1 -1
- package/dist/dockview-core.noStyle.js +929 -292
- package/dist/dockview-core.noStyle.js.map +1 -1
- package/dist/esm/api/component.api.d.ts +0 -2
- package/dist/esm/api/component.api.js +0 -6
- package/dist/esm/dnd/abstractDragHandler.js +4 -2
- package/dist/esm/dnd/dropTargetAnchorContainer.d.ts +16 -0
- package/dist/esm/dnd/dropTargetAnchorContainer.js +74 -0
- package/dist/esm/dnd/droptarget.d.ts +16 -0
- package/dist/esm/dnd/droptarget.js +134 -14
- package/dist/esm/dnd/ghost.d.ts +4 -1
- package/dist/esm/dnd/ghost.js +3 -2
- package/dist/esm/dnd/groupDragHandler.js +3 -1
- package/dist/esm/dockview/components/panel/content.js +10 -13
- package/dist/esm/dockview/components/popupService.d.ts +13 -0
- package/dist/esm/dockview/components/popupService.js +53 -0
- package/dist/esm/dockview/components/tab/tab.js +15 -7
- package/dist/esm/dockview/components/titlebar/tabOverflowControl.d.ts +8 -0
- package/dist/esm/dockview/components/titlebar/tabOverflowControl.js +16 -0
- package/dist/esm/dockview/components/titlebar/tabs.d.ts +45 -0
- package/dist/esm/dockview/components/titlebar/tabs.js +183 -0
- package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +8 -9
- package/dist/esm/dockview/components/titlebar/tabsContainer.js +133 -162
- package/dist/esm/dockview/components/titlebar/voidContainer.js +2 -9
- package/dist/esm/dockview/dockviewComponent.d.ts +10 -3
- package/dist/esm/dockview/dockviewComponent.js +69 -24
- package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +4 -0
- package/dist/esm/dockview/dockviewGroupPanelModel.js +27 -0
- package/dist/esm/dockview/dockviewPanelModel.d.ts +5 -3
- package/dist/esm/dockview/dockviewPanelModel.js +14 -4
- package/dist/esm/dockview/framework.d.ts +4 -1
- package/dist/esm/dockview/options.d.ts +8 -5
- package/dist/esm/dockview/options.js +3 -1
- package/dist/esm/dockview/theme.d.ts +31 -0
- package/dist/esm/dockview/theme.js +39 -0
- package/dist/esm/dockview/types.d.ts +5 -1
- package/dist/esm/dom.d.ts +1 -0
- package/dist/esm/dom.js +13 -0
- package/dist/esm/gridview/baseComponentGridview.d.ts +3 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/paneview/paneviewComponent.js +1 -0
- package/dist/esm/scrollbar.d.ts +12 -0
- package/dist/esm/scrollbar.js +80 -0
- package/dist/esm/splitview/splitview.js +1 -0
- package/dist/esm/splitview/splitviewComponent.js +1 -0
- package/dist/styles/dockview.css +427 -69
- 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
|
|
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
|
-
|
|
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.
|
|
14
|
+
return this.tabs.panels;
|
|
11
15
|
}
|
|
12
16
|
get size() {
|
|
13
|
-
return this.tabs.
|
|
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.
|
|
104
|
-
|
|
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.
|
|
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(
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
231
|
-
|
|
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
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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.
|
|
243
|
-
|
|
244
|
-
|
|
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
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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
|
-
|
|
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) => {
|