dockview-core 6.3.0 → 6.5.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/README.md +1 -0
- package/dist/cjs/dnd/backend.d.ts +70 -0
- package/dist/cjs/dnd/backend.js +171 -0
- package/dist/cjs/dnd/dropOverlay.d.ts +20 -0
- package/dist/cjs/dnd/dropOverlay.js +197 -0
- package/dist/cjs/dnd/droptarget.d.ts +20 -6
- package/dist/cjs/dnd/droptarget.js +14 -208
- package/dist/cjs/dnd/pointer/index.d.ts +11 -0
- package/dist/cjs/dnd/pointer/index.js +13 -0
- package/dist/cjs/dnd/pointer/longPress.d.ts +32 -0
- package/dist/cjs/dnd/pointer/longPress.js +151 -0
- package/dist/cjs/dnd/pointer/pointerDragController.d.ts +60 -0
- package/dist/cjs/dnd/pointer/pointerDragController.js +241 -0
- package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +61 -0
- package/dist/cjs/dnd/pointer/pointerDragSource.js +195 -0
- package/dist/cjs/dnd/pointer/pointerDropTarget.d.ts +39 -0
- package/dist/cjs/dnd/pointer/pointerDropTarget.js +198 -0
- package/dist/cjs/dnd/pointer/pointerGhost.d.ts +30 -0
- package/dist/cjs/dnd/pointer/pointerGhost.js +44 -0
- package/dist/cjs/dnd/pointer/types.d.ts +16 -0
- package/dist/cjs/dnd/pointer/types.js +2 -0
- package/dist/cjs/dockview/components/panel/content.d.ts +3 -1
- package/dist/cjs/dockview/components/panel/content.js +33 -16
- package/dist/cjs/dockview/components/popupService.js +34 -0
- package/dist/cjs/dockview/components/tab/tab.d.ts +11 -3
- package/dist/cjs/dockview/components/tab/tab.js +151 -117
- package/dist/cjs/dockview/components/titlebar/tabGroupChip.d.ts +9 -2
- package/dist/cjs/dockview/components/titlebar/tabGroupChip.js +15 -6
- package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +33 -5
- package/dist/cjs/dockview/components/titlebar/tabGroups.js +231 -40
- package/dist/cjs/dockview/components/titlebar/tabs.d.ts +38 -1
- package/dist/cjs/dockview/components/titlebar/tabs.js +372 -251
- package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +5 -3
- package/dist/cjs/dockview/components/titlebar/voidContainer.d.ts +6 -2
- package/dist/cjs/dockview/components/titlebar/voidContainer.js +189 -27
- package/dist/cjs/dockview/contextMenu.js +19 -4
- package/dist/cjs/dockview/dndCapabilities.d.ts +19 -0
- package/dist/cjs/dockview/dndCapabilities.js +39 -0
- package/dist/cjs/dockview/dockviewComponent.d.ts +1 -0
- package/dist/cjs/dockview/dockviewComponent.js +54 -33
- package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +9 -5
- package/dist/cjs/dockview/dockviewGroupPanelModel.js +25 -11
- package/dist/cjs/dockview/events.d.ts +2 -1
- package/dist/cjs/dockview/events.js +1 -0
- package/dist/cjs/dockview/options.d.ts +18 -3
- package/dist/cjs/dockview/options.js +1 -0
- package/dist/cjs/dom.js +7 -3
- package/dist/cjs/overlay/overlay.d.ts +12 -0
- package/dist/cjs/overlay/overlay.js +84 -16
- package/dist/cjs/paneview/draggablePaneviewPanel.d.ts +3 -1
- package/dist/cjs/paneview/draggablePaneviewPanel.js +27 -26
- package/dist/cjs/paneview/options.d.ts +4 -3
- package/dist/dockview-core.js +2199 -834
- 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 +2202 -837
- package/dist/esm/dnd/backend.d.ts +70 -0
- package/dist/esm/dnd/backend.js +148 -0
- package/dist/esm/dnd/dropOverlay.d.ts +20 -0
- package/dist/esm/dnd/dropOverlay.js +192 -0
- package/dist/esm/dnd/droptarget.d.ts +20 -6
- package/dist/esm/dnd/droptarget.js +16 -210
- package/dist/esm/dnd/pointer/index.d.ts +11 -0
- package/dist/esm/dnd/pointer/index.js +5 -0
- package/dist/esm/dnd/pointer/longPress.d.ts +32 -0
- package/dist/esm/dnd/pointer/longPress.js +127 -0
- package/dist/esm/dnd/pointer/pointerDragController.d.ts +60 -0
- package/dist/esm/dnd/pointer/pointerDragController.js +191 -0
- package/dist/esm/dnd/pointer/pointerDragSource.d.ts +61 -0
- package/dist/esm/dnd/pointer/pointerDragSource.js +171 -0
- package/dist/esm/dnd/pointer/pointerDropTarget.d.ts +39 -0
- package/dist/esm/dnd/pointer/pointerDropTarget.js +168 -0
- package/dist/esm/dnd/pointer/pointerGhost.d.ts +30 -0
- package/dist/esm/dnd/pointer/pointerGhost.js +39 -0
- package/dist/esm/dnd/pointer/types.d.ts +16 -0
- package/dist/esm/dnd/pointer/types.js +1 -0
- package/dist/esm/dockview/components/panel/content.d.ts +3 -1
- package/dist/esm/dockview/components/panel/content.js +33 -16
- package/dist/esm/dockview/components/popupService.js +34 -0
- package/dist/esm/dockview/components/tab/tab.d.ts +11 -3
- package/dist/esm/dockview/components/tab/tab.js +139 -114
- package/dist/esm/dockview/components/titlebar/tabGroupChip.d.ts +9 -2
- package/dist/esm/dockview/components/titlebar/tabGroupChip.js +15 -6
- package/dist/esm/dockview/components/titlebar/tabGroups.d.ts +33 -5
- package/dist/esm/dockview/components/titlebar/tabGroups.js +177 -12
- package/dist/esm/dockview/components/titlebar/tabs.d.ts +38 -1
- package/dist/esm/dockview/components/titlebar/tabs.js +348 -227
- package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +5 -3
- package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +6 -2
- package/dist/esm/dockview/components/titlebar/voidContainer.js +179 -31
- package/dist/esm/dockview/contextMenu.js +19 -4
- package/dist/esm/dockview/dndCapabilities.d.ts +19 -0
- package/dist/esm/dockview/dndCapabilities.js +36 -0
- package/dist/esm/dockview/dockviewComponent.d.ts +1 -0
- package/dist/esm/dockview/dockviewComponent.js +55 -34
- package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +9 -5
- package/dist/esm/dockview/dockviewGroupPanelModel.js +24 -11
- package/dist/esm/dockview/events.d.ts +2 -1
- package/dist/esm/dockview/events.js +1 -0
- package/dist/esm/dockview/options.d.ts +18 -3
- package/dist/esm/dockview/options.js +1 -0
- package/dist/esm/dom.js +7 -3
- package/dist/esm/overlay/overlay.d.ts +12 -0
- package/dist/esm/overlay/overlay.js +85 -17
- package/dist/esm/paneview/draggablePaneviewPanel.d.ts +3 -1
- package/dist/esm/paneview/draggablePaneviewPanel.js +26 -20
- package/dist/esm/paneview/options.d.ts +4 -3
- package/dist/package/main.cjs.js +2202 -837
- package/dist/package/main.cjs.min.js +2 -2
- package/dist/package/main.esm.min.mjs +2 -2
- package/dist/package/main.esm.mjs +2202 -837
- package/dist/styles/dockview.css +117 -1
- package/package.json +3 -1
- package/dist/cjs/dnd/abstractDragHandler.d.ts +0 -14
- package/dist/cjs/dnd/abstractDragHandler.js +0 -86
- package/dist/cjs/dnd/groupDragHandler.d.ts +0 -12
- package/dist/cjs/dnd/groupDragHandler.js +0 -104
- package/dist/esm/dnd/abstractDragHandler.d.ts +0 -14
- package/dist/esm/dnd/abstractDragHandler.js +0 -63
- package/dist/esm/dnd/groupDragHandler.d.ts +0 -12
- package/dist/esm/dnd/groupDragHandler.js +0 -81
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { getPanelData,
|
|
2
|
-
import { addClasses,
|
|
1
|
+
import { getPanelData, } from '../../../dnd/dataTransfer';
|
|
2
|
+
import { addClasses, isChildEntirelyVisibleWithinParent, OverflowObserver, removeClasses, toggleClass, } from '../../../dom';
|
|
3
3
|
import { addDisposableListener, Emitter } from '../../../events';
|
|
4
4
|
import { CompositeDisposable, Disposable, MutableDisposable, } from '../../../lifecycle';
|
|
5
5
|
import { Scrollbar } from '../../../scrollbar';
|
|
6
|
+
import { PointerDragController } from '../../../dnd/pointer/pointerDragController';
|
|
6
7
|
import { DockviewWillShowOverlayLocationEvent } from '../../events';
|
|
7
8
|
import { Tab } from '../tab/tab';
|
|
8
9
|
import { TabGroupManager } from './tabGroups';
|
|
@@ -102,6 +103,7 @@ export class Tabs extends CompositeDisposable {
|
|
|
102
103
|
for (const tab of this._tabs) {
|
|
103
104
|
tab.value.setDirection(value);
|
|
104
105
|
}
|
|
106
|
+
this._tabGroupManager.updateDirection();
|
|
105
107
|
}
|
|
106
108
|
constructor(group, accessor, options) {
|
|
107
109
|
super();
|
|
@@ -121,7 +123,7 @@ export class Tabs extends CompositeDisposable {
|
|
|
121
123
|
this._voidContainer = null;
|
|
122
124
|
this._voidContainerListeners = null;
|
|
123
125
|
this._extendedDropZone = null;
|
|
124
|
-
this.
|
|
126
|
+
this._pointerInsideTabsList = false;
|
|
125
127
|
this._onTabDragStart = new Emitter();
|
|
126
128
|
this.onTabDragStart = this._onTabDragStart.event;
|
|
127
129
|
this._onDrop = new Emitter();
|
|
@@ -156,13 +158,40 @@ export class Tabs extends CompositeDisposable {
|
|
|
156
158
|
onChipDragStart: (tabGroup, chip, event) => {
|
|
157
159
|
this._handleChipDragStart(tabGroup, chip, event);
|
|
158
160
|
},
|
|
161
|
+
onChipDragEnd: () => {
|
|
162
|
+
// HTML5 chip dragend (incl. cancels). The Html5DragSource
|
|
163
|
+
// owns the listener on the chip element, so this fires
|
|
164
|
+
// even if the chip was detached cross-group — the
|
|
165
|
+
// element keeps its listeners until the source is
|
|
166
|
+
// disposed. resetDragAnimation is a no-op after a
|
|
167
|
+
// successful drop (anim state already null) thanks to
|
|
168
|
+
// the gating inside it.
|
|
169
|
+
this.resetDragAnimation();
|
|
170
|
+
},
|
|
171
|
+
onChipDrop: (tabGroup, event) => {
|
|
172
|
+
this._handleChipDrop(tabGroup, event);
|
|
173
|
+
},
|
|
159
174
|
});
|
|
160
175
|
this.addDisposables(this._onOverflowTabsChange, this._observerDisposable, this._onWillShowOverlay, this._onDrop, this._onTabDragStart, {
|
|
161
176
|
dispose: () => {
|
|
162
177
|
var _a;
|
|
163
178
|
(_a = this._flipTransitionCleanup) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
164
179
|
},
|
|
165
|
-
},
|
|
180
|
+
},
|
|
181
|
+
// Pointer-side cleanup: when any pointer drag ends, tear
|
|
182
|
+
// down smooth-reorder anim state the dragover bridge may
|
|
183
|
+
// have installed. The chip's pointer drag source handles
|
|
184
|
+
// its own transfer payload + iframe-shield cleanup.
|
|
185
|
+
PointerDragController.getInstance().onDragEnd(() => {
|
|
186
|
+
this._pointerInsideTabsList = false;
|
|
187
|
+
this.resetDragAnimation();
|
|
188
|
+
}),
|
|
189
|
+
// Pointer-event mirror of the HTML5 dragover / dragleave handlers
|
|
190
|
+
// below. Drives smooth-reorder for `dndStrategy: 'pointer'` and
|
|
191
|
+
// for touch drags in `'auto'`.
|
|
192
|
+
PointerDragController.getInstance().onDragMove((e) => {
|
|
193
|
+
this._handlePointerDragMove(e.clientX, e.clientY);
|
|
194
|
+
}), addDisposableListener(this.element, 'pointerdown', (event) => {
|
|
166
195
|
if (event.defaultPrevented) {
|
|
167
196
|
return;
|
|
168
197
|
}
|
|
@@ -170,135 +199,60 @@ export class Tabs extends CompositeDisposable {
|
|
|
170
199
|
if (isLeftClick) {
|
|
171
200
|
this.accessor.doSetGroupActive(this.group);
|
|
172
201
|
}
|
|
173
|
-
}),
|
|
174
|
-
|
|
175
|
-
|
|
202
|
+
}),
|
|
203
|
+
// Trackpad / wheel forwarding. The strip scrolls along its own
|
|
204
|
+
// axis (x for horizontal headers, y for vertical), so deltaY
|
|
205
|
+
// from a plain mouse wheel maps onto the strip's axis too —
|
|
206
|
+
// this gives the VS Code-style "scroll over tab bar to page
|
|
207
|
+
// through tabs" feel. We only consume the event when the strip
|
|
208
|
+
// is actually overflowing in the direction the user wheeled in,
|
|
209
|
+
// so a wheel at the edge of a non-overflowing strip still
|
|
210
|
+
// bubbles up and scrolls the page. `{ passive: false }` is
|
|
211
|
+
// required because we call preventDefault().
|
|
212
|
+
addDisposableListener(this._tabsList, 'wheel', (event) => {
|
|
213
|
+
const isVertical = this._direction === 'vertical';
|
|
214
|
+
const primary = isVertical
|
|
215
|
+
? event.deltaY || event.deltaX
|
|
216
|
+
: event.deltaX || event.deltaY;
|
|
217
|
+
if (primary === 0) {
|
|
176
218
|
return;
|
|
177
219
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
data.groupId !== this.group.id &&
|
|
185
|
-
this._animState.sourceTabGroupId !== data.tabGroupId) {
|
|
186
|
-
this._animState = null;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
if (!this._animState) {
|
|
190
|
-
const data = getPanelData();
|
|
191
|
-
// In default animation mode, individual tab drops
|
|
192
|
-
// are handled by per-tab Droptargets. But tab group
|
|
193
|
-
// chip drags still need tab-list-level handling so
|
|
194
|
-
// that drops on gaps / void space work.
|
|
195
|
-
if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) ===
|
|
196
|
-
'default' &&
|
|
197
|
-
!(data === null || data === void 0 ? void 0 : data.tabGroupId)) {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
if (data &&
|
|
201
|
-
(data.panelId || data.tabGroupId) &&
|
|
202
|
-
data.groupId !== this.group.id) {
|
|
203
|
-
const avgWidth = this.getAverageTabWidth();
|
|
204
|
-
if (data.tabGroupId) {
|
|
205
|
-
// External group drag — look up the
|
|
206
|
-
// source tab group to size the gap
|
|
207
|
-
const sourceGroup = this.accessor.getPanel(data.groupId);
|
|
208
|
-
const sourceTg = sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.getTabGroups().find((tg) => tg.id === data.tabGroupId);
|
|
209
|
-
const panelCount = (_b = sourceTg === null || sourceTg === void 0 ? void 0 : sourceTg.panelIds.length) !== null && _b !== void 0 ? _b : 1;
|
|
210
|
-
const groupGapWidth = avgWidth * panelCount + avgWidth;
|
|
211
|
-
this._animState = {
|
|
212
|
-
sourceTabId: '',
|
|
213
|
-
sourceIndex: -1,
|
|
214
|
-
tabPositions: this.snapshotTabPositions(),
|
|
215
|
-
chipPositions: this._tabGroupManager.snapshotChipWidths(),
|
|
216
|
-
currentInsertionIndex: null,
|
|
217
|
-
targetTabGroupId: null,
|
|
218
|
-
sourceTabGroupId: data.tabGroupId,
|
|
219
|
-
sourceGroupPanelIds: sourceTg
|
|
220
|
-
? new Set(sourceTg.panelIds)
|
|
221
|
-
: new Set(),
|
|
222
|
-
sourceChipWidth: avgWidth,
|
|
223
|
-
cursorOffsetFromDragLeft: groupGapWidth / 2,
|
|
224
|
-
sourceGapWidth: groupGapWidth,
|
|
225
|
-
containerLeft: this._tabsList.getBoundingClientRect()
|
|
226
|
-
.left,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
this._animState = {
|
|
231
|
-
sourceTabId: data.panelId,
|
|
232
|
-
sourceIndex: -1,
|
|
233
|
-
tabPositions: this.snapshotTabPositions(),
|
|
234
|
-
chipPositions: this._tabGroupManager.snapshotChipWidths(),
|
|
235
|
-
currentInsertionIndex: null,
|
|
236
|
-
targetTabGroupId: null,
|
|
237
|
-
sourceTabGroupId: null,
|
|
238
|
-
sourceGroupPanelIds: null,
|
|
239
|
-
sourceChipWidth: 0,
|
|
240
|
-
cursorOffsetFromDragLeft: avgWidth / 2,
|
|
241
|
-
sourceGapWidth: avgWidth,
|
|
242
|
-
containerLeft: this._tabsList.getBoundingClientRect()
|
|
243
|
-
.left,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
event.preventDefault(); // allow drop to fire on the container
|
|
252
|
-
// For intra-group drag (sourceIndex >= 0) the gap
|
|
253
|
-
// animation is the sole visual indicator — clear any
|
|
254
|
-
// stale anchor overlay that may have been set while the
|
|
255
|
-
// cursor was over the panel content area or another zone.
|
|
256
|
-
// External drags (sourceIndex === -1) leave the overlay
|
|
257
|
-
// to the individual tab Droptargets so cross-group
|
|
258
|
-
// animation is not disrupted.
|
|
259
|
-
if (this._animState.sourceIndex !== -1) {
|
|
260
|
-
(_d = (_c = this.group.model.dropTargetContainer) === null || _c === void 0 ? void 0 : _c.model) === null || _d === void 0 ? void 0 : _d.clear();
|
|
261
|
-
}
|
|
262
|
-
this.handleDragOver(event);
|
|
263
|
-
}, true), addDisposableListener(this._tabsList, 'dragleave', (event) => {
|
|
264
|
-
var _a, _b, _c;
|
|
265
|
-
if (!this._animState) {
|
|
220
|
+
const max = isVertical
|
|
221
|
+
? this._tabsList.scrollHeight -
|
|
222
|
+
this._tabsList.clientHeight
|
|
223
|
+
: this._tabsList.scrollWidth -
|
|
224
|
+
this._tabsList.clientWidth;
|
|
225
|
+
if (max <= 0) {
|
|
266
226
|
return;
|
|
267
227
|
}
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
228
|
+
const current = isVertical
|
|
229
|
+
? this._tabsList.scrollTop
|
|
230
|
+
: this._tabsList.scrollLeft;
|
|
231
|
+
// At the edge in the wheel direction: let the page
|
|
232
|
+
// scroll instead of trapping the gesture.
|
|
233
|
+
if ((primary < 0 && current <= 0) ||
|
|
234
|
+
(primary > 0 && current >= max)) {
|
|
271
235
|
return;
|
|
272
236
|
}
|
|
273
|
-
|
|
274
|
-
//
|
|
275
|
-
//
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
237
|
+
event.preventDefault();
|
|
238
|
+
// Custom-scrollbar mode wraps the tabs list and installs
|
|
239
|
+
// its own wheel listener that rewrites scrollLeft from a
|
|
240
|
+
// deltaY-only tracker. Without stopPropagation that
|
|
241
|
+
// handler would clobber our deltaX-aware update.
|
|
242
|
+
event.stopPropagation();
|
|
243
|
+
if (isVertical) {
|
|
244
|
+
this._tabsList.scrollTop = current + primary;
|
|
280
245
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
// still land at the end position.
|
|
284
|
-
const rt = event.relatedTarget;
|
|
285
|
-
const isVoid = this._voidContainer &&
|
|
286
|
-
rt &&
|
|
287
|
-
(rt === this._voidContainer ||
|
|
288
|
-
this._voidContainer.contains(rt));
|
|
289
|
-
if (isVoid) {
|
|
290
|
-
return;
|
|
246
|
+
else {
|
|
247
|
+
this._tabsList.scrollLeft = current + primary;
|
|
291
248
|
}
|
|
292
|
-
|
|
293
|
-
if (this.
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
this._animState = null;
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
this._animState.currentInsertionIndex = null;
|
|
300
|
-
}
|
|
249
|
+
}, { passive: false }), addDisposableListener(this._tabsList, 'dragover', (event) => {
|
|
250
|
+
if (this._processDragOver(event.clientX)) {
|
|
251
|
+
// Allow `drop` to fire on the tabs list container.
|
|
252
|
+
event.preventDefault();
|
|
301
253
|
}
|
|
254
|
+
}, true), addDisposableListener(this._tabsList, 'dragleave', (event) => {
|
|
255
|
+
this._processDragLeave(event.relatedTarget);
|
|
302
256
|
}, true), addDisposableListener(this._tabsList, 'dragend', () => {
|
|
303
257
|
this.resetDragAnimation();
|
|
304
258
|
}), addDisposableListener(this._tabsList, 'drop', (event) => {
|
|
@@ -420,6 +374,9 @@ export class Tabs extends CompositeDisposable {
|
|
|
420
374
|
const disposable = new CompositeDisposable(tab.onDragStart((event) => {
|
|
421
375
|
var _a;
|
|
422
376
|
this._onTabDragStart.fire({ nativeEvent: event, panel });
|
|
377
|
+
// Both HTML5 and pointer drags initialize _animState. Cleanup
|
|
378
|
+
// is wired in both paths: HTML5 via dragend/drop on _tabsList,
|
|
379
|
+
// pointer via PointerDragController.onDragEnd subscriptions.
|
|
423
380
|
if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) === 'smooth') {
|
|
424
381
|
const tabWidth = tab.element.getBoundingClientRect().width;
|
|
425
382
|
const sourceIndex = this._tabs.findIndex((x) => x.value === tab);
|
|
@@ -682,6 +639,7 @@ export class Tabs extends CompositeDisposable {
|
|
|
682
639
|
for (const tab of this._tabs) {
|
|
683
640
|
tab.value.updateDragAndDropState();
|
|
684
641
|
}
|
|
642
|
+
this._tabGroupManager.updateDragAndDropState();
|
|
685
643
|
}
|
|
686
644
|
/**
|
|
687
645
|
* Synchronize chip elements and CSS classes for all tab groups
|
|
@@ -693,6 +651,13 @@ export class Tabs extends CompositeDisposable {
|
|
|
693
651
|
refreshTabGroupAccent() {
|
|
694
652
|
this._tabGroupManager.refreshAccents();
|
|
695
653
|
}
|
|
654
|
+
/**
|
|
655
|
+
* Tabs-list-specific side effects of a chip drag start. The chip's
|
|
656
|
+
* drag sources (constructed by `TabGroupManager`) own the transfer
|
|
657
|
+
* payload, iframe shielding, dataTransfer setup, and the HTML5 drag
|
|
658
|
+
* image. This method just sets up the smooth-reorder anim state and
|
|
659
|
+
* collapses the source-group tabs in the tabs list.
|
|
660
|
+
*/
|
|
696
661
|
_handleChipDragStart(tabGroup, chip, event) {
|
|
697
662
|
var _a;
|
|
698
663
|
const firstPanelId = tabGroup.panelIds[0];
|
|
@@ -723,89 +688,79 @@ export class Tabs extends CompositeDisposable {
|
|
|
723
688
|
sourceGapWidth: groupGapWidth,
|
|
724
689
|
containerLeft: this._tabsList.getBoundingClientRect().left,
|
|
725
690
|
};
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
};
|
|
747
|
-
chipElement.addEventListener('dragend', onChipDragEnd);
|
|
748
|
-
this._chipDragCleanup = {
|
|
749
|
-
dispose: () => {
|
|
750
|
-
chipElement.removeEventListener('dragend', onChipDragEnd);
|
|
751
|
-
panelTransfer.clearData(PanelTransfer.prototype);
|
|
752
|
-
iframes.release();
|
|
753
|
-
},
|
|
754
|
-
};
|
|
755
|
-
if (event.dataTransfer) {
|
|
756
|
-
event.dataTransfer.effectAllowed = 'move';
|
|
757
|
-
if (event.dataTransfer.items.length === 0) {
|
|
758
|
-
event.dataTransfer.setData('text/plain', '');
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) === 'smooth') {
|
|
762
|
-
// Collapse group tabs + chip after the browser
|
|
763
|
-
// captures the drag image, then open the gap at the
|
|
764
|
-
// source position — all instant (no transitions).
|
|
765
|
-
const groupPanelIds = new Set(tabGroup.panelIds);
|
|
766
|
-
this._pendingCollapse = true;
|
|
767
|
-
requestAnimationFrame(() => {
|
|
768
|
-
var _a;
|
|
769
|
-
var _b;
|
|
770
|
-
this._pendingCollapse = false;
|
|
771
|
-
if (!this._animState) {
|
|
772
|
-
return;
|
|
773
|
-
}
|
|
774
|
-
// Collapse all group tabs instantly
|
|
775
|
-
for (const t of this._tabs) {
|
|
776
|
-
if (groupPanelIds.has(t.value.panel.id)) {
|
|
777
|
-
t.value.element.style.transition = 'none';
|
|
778
|
-
toggleClass(t.value.element, 'dv-tab--dragging', true);
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
// Collapse the group chip instantly
|
|
782
|
-
const chipEntry = this._tabGroupManager.chipRenderers.get(tabGroup.id);
|
|
783
|
-
if (chipEntry) {
|
|
784
|
-
chipEntry.chip.element.style.transition = 'none';
|
|
785
|
-
toggleClass(chipEntry.chip.element, 'dv-tab-group-chip--dragging', true);
|
|
786
|
-
}
|
|
787
|
-
// Single reflow for the entire batch
|
|
788
|
-
void this._tabsList.offsetHeight;
|
|
789
|
-
const underline = this._tabGroupManager.groupUnderlines.get(tabGroup.id);
|
|
790
|
-
if (underline) {
|
|
791
|
-
underline.style.display = 'none';
|
|
792
|
-
}
|
|
793
|
-
(_a = (_b = this._animState).currentInsertionIndex) !== null && _a !== void 0 ? _a : (_b.currentInsertionIndex = firstIdx);
|
|
794
|
-
// Apply gap with transitions disabled
|
|
795
|
-
this.applyDragOverTransforms(true);
|
|
796
|
-
// Re-enable transitions for subsequent moves
|
|
797
|
-
for (const t of this._tabs) {
|
|
798
|
-
if (groupPanelIds.has(t.value.panel.id)) {
|
|
799
|
-
t.value.element.style.removeProperty('transition');
|
|
800
|
-
}
|
|
691
|
+
if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) !== 'smooth') {
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
// Collapse group tabs + chip after the browser captures the drag
|
|
695
|
+
// image, then open the gap at the source position — all instant
|
|
696
|
+
// (no transitions).
|
|
697
|
+
const groupPanelIds = new Set(tabGroup.panelIds);
|
|
698
|
+
this._pendingCollapse = true;
|
|
699
|
+
requestAnimationFrame(() => {
|
|
700
|
+
var _a;
|
|
701
|
+
var _b;
|
|
702
|
+
this._pendingCollapse = false;
|
|
703
|
+
if (!this._animState) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
// Collapse all group tabs instantly
|
|
707
|
+
for (const t of this._tabs) {
|
|
708
|
+
if (groupPanelIds.has(t.value.panel.id)) {
|
|
709
|
+
t.value.element.style.transition = 'none';
|
|
710
|
+
toggleClass(t.value.element, 'dv-tab--dragging', true);
|
|
801
711
|
}
|
|
802
|
-
|
|
803
|
-
|
|
712
|
+
}
|
|
713
|
+
// Collapse the group chip instantly
|
|
714
|
+
const chipEntry = this._tabGroupManager.chipRenderers.get(tabGroup.id);
|
|
715
|
+
if (chipEntry) {
|
|
716
|
+
chipEntry.chip.element.style.transition = 'none';
|
|
717
|
+
toggleClass(chipEntry.chip.element, 'dv-tab-group-chip--dragging', true);
|
|
718
|
+
}
|
|
719
|
+
// Single reflow for the entire batch
|
|
720
|
+
void this._tabsList.offsetHeight;
|
|
721
|
+
const underline = this._tabGroupManager.groupUnderlines.get(tabGroup.id);
|
|
722
|
+
if (underline) {
|
|
723
|
+
underline.style.display = 'none';
|
|
724
|
+
}
|
|
725
|
+
(_a = (_b = this._animState).currentInsertionIndex) !== null && _a !== void 0 ? _a : (_b.currentInsertionIndex = firstIdx);
|
|
726
|
+
this.applyDragOverTransforms(true);
|
|
727
|
+
for (const t of this._tabs) {
|
|
728
|
+
if (groupPanelIds.has(t.value.panel.id)) {
|
|
729
|
+
t.value.element.style.removeProperty('transition');
|
|
804
730
|
}
|
|
805
|
-
}
|
|
731
|
+
}
|
|
732
|
+
if (chipEntry) {
|
|
733
|
+
chipEntry.chip.element.style.removeProperty('transition');
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* A drop on a tab group chip means "insert before this group". Resolve to
|
|
739
|
+
* the index of the group's first tab, adjusting for same-group removal
|
|
740
|
+
* (when the source tab is currently to the left of the target slot, its
|
|
741
|
+
* removal shifts the insertion index down by one). Always clears
|
|
742
|
+
* `targetTabGroupId` so the dropped tab lands outside the group.
|
|
743
|
+
*/
|
|
744
|
+
_handleChipDrop(tabGroup, event) {
|
|
745
|
+
const firstPanelId = tabGroup.panelIds[0];
|
|
746
|
+
if (!firstPanelId) {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
const insertionIndex = this._tabs.findIndex((x) => x.value.panel.id === firstPanelId);
|
|
750
|
+
if (insertionIndex === -1) {
|
|
751
|
+
return;
|
|
806
752
|
}
|
|
807
|
-
|
|
808
|
-
this.
|
|
753
|
+
const data = getPanelData();
|
|
754
|
+
const sourceIndex = data && data.groupId === this.group.id && data.panelId
|
|
755
|
+
? this._tabs.findIndex((x) => x.value.panel.id === data.panelId)
|
|
756
|
+
: -1;
|
|
757
|
+
const adjustedIndex = insertionIndex -
|
|
758
|
+
(sourceIndex !== -1 && sourceIndex < insertionIndex ? 1 : 0);
|
|
759
|
+
this._onDrop.fire({
|
|
760
|
+
event: event.nativeEvent,
|
|
761
|
+
index: adjustedIndex,
|
|
762
|
+
targetTabGroupId: null,
|
|
763
|
+
});
|
|
809
764
|
}
|
|
810
765
|
/**
|
|
811
766
|
* Sets the broader container that is part of the same logical drop surface
|
|
@@ -867,6 +822,164 @@ export class Tabs extends CompositeDisposable {
|
|
|
867
822
|
}
|
|
868
823
|
return total / this._tabs.length;
|
|
869
824
|
}
|
|
825
|
+
/**
|
|
826
|
+
* Pointer-event entry point. The HTML5 path enters via the per-element
|
|
827
|
+
* `dragover` listener; this one hit-tests the global pointer-drag
|
|
828
|
+
* position against the tabs list and routes through the same shared
|
|
829
|
+
* `_processDragOver` / `_processDragLeave` helpers.
|
|
830
|
+
*/
|
|
831
|
+
_handlePointerDragMove(clientX, clientY) {
|
|
832
|
+
var _a;
|
|
833
|
+
const sourceDoc = (_a = this._tabsList.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
834
|
+
const elAtPoint = sourceDoc.elementFromPoint(clientX, clientY);
|
|
835
|
+
const inside = !!elAtPoint &&
|
|
836
|
+
(this._tabsList.contains(elAtPoint) ||
|
|
837
|
+
(!!this._extendedDropZone &&
|
|
838
|
+
this._extendedDropZone.contains(elAtPoint)));
|
|
839
|
+
if (!inside) {
|
|
840
|
+
if (this._pointerInsideTabsList) {
|
|
841
|
+
this._pointerInsideTabsList = false;
|
|
842
|
+
this._processDragLeave(elAtPoint);
|
|
843
|
+
}
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
this._pointerInsideTabsList = true;
|
|
847
|
+
this._processDragOver(clientX);
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Shared body of the dragover entry point. Refreshes stale anim state
|
|
851
|
+
* for a changed drag identity, initializes anim state for incoming
|
|
852
|
+
* cross-group drags, and dispatches to the gap-following math in
|
|
853
|
+
* `handleDragOver`. Returns true when this tabs list has taken
|
|
854
|
+
* ownership of the drag — HTML5 callers use this to gate
|
|
855
|
+
* `event.preventDefault()`.
|
|
856
|
+
*/
|
|
857
|
+
_processDragOver(clientX) {
|
|
858
|
+
var _a, _b, _c, _d;
|
|
859
|
+
if (this.accessor.options.disableDnd) {
|
|
860
|
+
return false;
|
|
861
|
+
}
|
|
862
|
+
// Stale-state guard: if a previous drag's anim state is still here
|
|
863
|
+
// but the current drag is a different identity, drop the stale one
|
|
864
|
+
// so the new drag starts from a clean slate.
|
|
865
|
+
if (this._animState) {
|
|
866
|
+
const data = getPanelData();
|
|
867
|
+
if ((data === null || data === void 0 ? void 0 : data.tabGroupId) &&
|
|
868
|
+
data.groupId !== this.group.id &&
|
|
869
|
+
this._animState.sourceTabGroupId !== data.tabGroupId) {
|
|
870
|
+
this._animState = null;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
if (!this._animState) {
|
|
874
|
+
const data = getPanelData();
|
|
875
|
+
// In default animation mode, individual tab drops are handled
|
|
876
|
+
// by per-tab Droptargets; only chip drags need tabs-list-level
|
|
877
|
+
// handling so drops on void space still work.
|
|
878
|
+
if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) === 'default' &&
|
|
879
|
+
!(data === null || data === void 0 ? void 0 : data.tabGroupId)) {
|
|
880
|
+
return false;
|
|
881
|
+
}
|
|
882
|
+
if (data &&
|
|
883
|
+
(data.panelId || data.tabGroupId) &&
|
|
884
|
+
data.groupId !== this.group.id) {
|
|
885
|
+
const avgWidth = this.getAverageTabWidth();
|
|
886
|
+
if (data.tabGroupId) {
|
|
887
|
+
// External group drag — look up the source group to
|
|
888
|
+
// size the gap.
|
|
889
|
+
const sourceGroup = this.accessor.getPanel(data.groupId);
|
|
890
|
+
const sourceTg = sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.getTabGroups().find((tg) => tg.id === data.tabGroupId);
|
|
891
|
+
const panelCount = (_b = sourceTg === null || sourceTg === void 0 ? void 0 : sourceTg.panelIds.length) !== null && _b !== void 0 ? _b : 1;
|
|
892
|
+
const groupGapWidth = avgWidth * panelCount + avgWidth;
|
|
893
|
+
this._animState = {
|
|
894
|
+
sourceTabId: '',
|
|
895
|
+
sourceIndex: -1,
|
|
896
|
+
tabPositions: this.snapshotTabPositions(),
|
|
897
|
+
chipPositions: this._tabGroupManager.snapshotChipWidths(),
|
|
898
|
+
currentInsertionIndex: null,
|
|
899
|
+
targetTabGroupId: null,
|
|
900
|
+
sourceTabGroupId: data.tabGroupId,
|
|
901
|
+
sourceGroupPanelIds: sourceTg
|
|
902
|
+
? new Set(sourceTg.panelIds)
|
|
903
|
+
: new Set(),
|
|
904
|
+
sourceChipWidth: avgWidth,
|
|
905
|
+
cursorOffsetFromDragLeft: groupGapWidth / 2,
|
|
906
|
+
sourceGapWidth: groupGapWidth,
|
|
907
|
+
containerLeft: this._tabsList.getBoundingClientRect().left,
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
else {
|
|
911
|
+
this._animState = {
|
|
912
|
+
sourceTabId: data.panelId,
|
|
913
|
+
sourceIndex: -1,
|
|
914
|
+
tabPositions: this.snapshotTabPositions(),
|
|
915
|
+
chipPositions: this._tabGroupManager.snapshotChipWidths(),
|
|
916
|
+
currentInsertionIndex: null,
|
|
917
|
+
targetTabGroupId: null,
|
|
918
|
+
sourceTabGroupId: null,
|
|
919
|
+
sourceGroupPanelIds: null,
|
|
920
|
+
sourceChipWidth: 0,
|
|
921
|
+
cursorOffsetFromDragLeft: avgWidth / 2,
|
|
922
|
+
sourceGapWidth: avgWidth,
|
|
923
|
+
containerLeft: this._tabsList.getBoundingClientRect().left,
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
else {
|
|
928
|
+
return false;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
// For intra-group drag (sourceIndex >= 0) the gap animation is the
|
|
932
|
+
// sole visual indicator — clear any stale anchor overlay that may
|
|
933
|
+
// have been set while the cursor was over the panel content area or
|
|
934
|
+
// another zone. External drags (sourceIndex === -1) leave the
|
|
935
|
+
// overlay to the individual tab Droptargets so cross-group
|
|
936
|
+
// animation is not disrupted.
|
|
937
|
+
if (this._animState.sourceIndex !== -1) {
|
|
938
|
+
(_d = (_c = this.group.model.dropTargetContainer) === null || _c === void 0 ? void 0 : _c.model) === null || _d === void 0 ? void 0 : _d.clear();
|
|
939
|
+
}
|
|
940
|
+
this.handleDragOver({ clientX });
|
|
941
|
+
return true;
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Shared body of the dragleave entry point. Preserves anim state when
|
|
945
|
+
* the drag moves between tabs-list children, into the extended drop
|
|
946
|
+
* zone, or into the void container; tears it down otherwise.
|
|
947
|
+
*/
|
|
948
|
+
_processDragLeave(related) {
|
|
949
|
+
var _a, _b, _c;
|
|
950
|
+
if (!this._animState) {
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
// Moves between children of the tabs list aren't real leaves.
|
|
954
|
+
if (related && this._tabsList.contains(related)) {
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
// Moving into the broader drop zone (e.g. void container, left
|
|
958
|
+
// actions) — keep anim state alive so external listeners can
|
|
959
|
+
// continue the gap animation.
|
|
960
|
+
if (related && ((_a = this._extendedDropZone) === null || _a === void 0 ? void 0 : _a.contains(related))) {
|
|
961
|
+
this.resetTabTransforms();
|
|
962
|
+
this._animState.currentInsertionIndex = null;
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
// Leaving toward the void container (empty header space to the
|
|
966
|
+
// right): keep anim state so a drop can still land at the end.
|
|
967
|
+
const isVoid = this._voidContainer &&
|
|
968
|
+
related &&
|
|
969
|
+
(related === this._voidContainer ||
|
|
970
|
+
this._voidContainer.contains(related));
|
|
971
|
+
if (isVoid) {
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
this.resetTabTransforms();
|
|
975
|
+
if (this._animState.sourceIndex === -1) {
|
|
976
|
+
(_c = (_b = this.group.model.dropTargetContainer) === null || _b === void 0 ? void 0 : _b.model) === null || _c === void 0 ? void 0 : _c.clear();
|
|
977
|
+
this._animState = null;
|
|
978
|
+
}
|
|
979
|
+
else {
|
|
980
|
+
this._animState.currentInsertionIndex = null;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
870
983
|
handleDragOver(event) {
|
|
871
984
|
var _a, _b, _c, _d, _e;
|
|
872
985
|
if (!this._animState) {
|
|
@@ -1276,20 +1389,23 @@ export class Tabs extends CompositeDisposable {
|
|
|
1276
1389
|
* in the model, and run a FLIP animation.
|
|
1277
1390
|
*/
|
|
1278
1391
|
_commitGroupMove(sourceTabGroupId, insertionIndex) {
|
|
1279
|
-
var _a, _b
|
|
1280
|
-
// Read transfer data
|
|
1281
|
-
// _chipDragCleanup clears the global LocalSelectionTransfer
|
|
1282
|
-
// singleton which getPanelData() reads from.
|
|
1392
|
+
var _a, _b;
|
|
1393
|
+
// Read transfer data first.
|
|
1283
1394
|
const data = getPanelData();
|
|
1284
|
-
|
|
1285
|
-
|
|
1395
|
+
// Synchronously dispose the source chip's drag sources, which
|
|
1396
|
+
// clears the panelTransfer payload + iframe shield. Cross-group
|
|
1397
|
+
// moves dissolve the source chip on a microtask, which is too
|
|
1398
|
+
// late: a synchronous `getPanelData()` after this method (or any
|
|
1399
|
+
// sibling dragover handler firing in the same tick) would
|
|
1400
|
+
// otherwise see stale data still referencing the old tabGroupId.
|
|
1401
|
+
this._tabGroupManager.disposeChipDrag(sourceTabGroupId);
|
|
1286
1402
|
// Check if the tab group exists in this group (within-group reorder)
|
|
1287
1403
|
// or in another group (cross-group move).
|
|
1288
1404
|
const isLocal = this.group.model
|
|
1289
1405
|
.getTabGroups()
|
|
1290
1406
|
.some((tg) => tg.id === sourceTabGroupId);
|
|
1291
1407
|
if (isLocal) {
|
|
1292
|
-
if (((
|
|
1408
|
+
if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) === 'smooth') {
|
|
1293
1409
|
this._clearGroupDragClasses(sourceTabGroupId);
|
|
1294
1410
|
const firstPositions = this.snapshotTabPositions();
|
|
1295
1411
|
this.resetTabTransforms();
|
|
@@ -1317,7 +1433,7 @@ export class Tabs extends CompositeDisposable {
|
|
|
1317
1433
|
this.accessor.moveGroupOrPanel({
|
|
1318
1434
|
from: {
|
|
1319
1435
|
groupId: data.groupId,
|
|
1320
|
-
tabGroupId: (
|
|
1436
|
+
tabGroupId: (_b = data.tabGroupId) !== null && _b !== void 0 ? _b : sourceTabGroupId,
|
|
1321
1437
|
},
|
|
1322
1438
|
to: {
|
|
1323
1439
|
group: this.group,
|
|
@@ -1345,22 +1461,27 @@ export class Tabs extends CompositeDisposable {
|
|
|
1345
1461
|
this._tabGroupManager.skipNextCollapseAnimation = true;
|
|
1346
1462
|
}
|
|
1347
1463
|
resetDragAnimation() {
|
|
1348
|
-
var _a, _b;
|
|
1349
1464
|
this._pendingCollapse = false;
|
|
1350
|
-
|
|
1351
|
-
//
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1465
|
+
// After a drop, `tab.onDrop` consumes _animState (sets it to null)
|
|
1466
|
+
// and immediately calls `runFlipAnimation`, which sets transforms
|
|
1467
|
+
// and queues an rAF to trigger the CSS transition. dragend fires
|
|
1468
|
+
// synchronously on the source element BEFORE that rAF runs — if
|
|
1469
|
+
// we cleared transforms here we'd clobber the in-flight FLIP, so
|
|
1470
|
+
// gate the cleanup on _animState still being set (i.e. drag was
|
|
1471
|
+
// cancelled rather than dropped).
|
|
1472
|
+
if (this._animState) {
|
|
1473
|
+
this.resetTabTransforms();
|
|
1474
|
+
if (this._animState.sourceTabGroupId) {
|
|
1475
|
+
this._clearGroupDragClasses(this._animState.sourceTabGroupId);
|
|
1476
|
+
}
|
|
1477
|
+
else {
|
|
1478
|
+
this._removeClassInstantlyBatch(this._tabs.map((t) => t.value.element), 'dv-tab--dragging');
|
|
1479
|
+
}
|
|
1480
|
+
this._animState = null;
|
|
1481
|
+
// Restore any hidden underlines from group drags.
|
|
1482
|
+
for (const [, el] of this._tabGroupManager.groupUnderlines) {
|
|
1483
|
+
el.style.removeProperty('display');
|
|
1484
|
+
}
|
|
1364
1485
|
}
|
|
1365
1486
|
}
|
|
1366
1487
|
runFlipAnimation(firstPositions, sourceTabId, isCrossGroup = false, animRange) {
|