UNPKG

dockview-core

Version:

Zero dependency layout manager supporting tabs, groups, grids and splitviews for vanilla TypeScript

449 lines (448 loc) 20.5 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TabsContainer = void 0; var lifecycle_1 = require("../../../lifecycle"); var events_1 = require("../../../events"); var voidContainer_1 = require("./voidContainer"); var dom_1 = require("../../../dom"); var events_2 = require("../../events"); var dataTransfer_1 = require("../../../dnd/dataTransfer"); var tabs_1 = require("./tabs"); var tabOverflowControl_1 = require("./tabOverflowControl"); var tabGroupAccent_1 = require("../../tabGroupAccent"); var TabsContainer = /** @class */ (function (_super) { __extends(TabsContainer, _super); function TabsContainer(accessor, group) { var _this = _super.call(this) || this; _this.accessor = accessor; _this.group = group; _this._hidden = false; _this._direction = 'horizontal'; _this.dropdownPart = null; _this._overflowTabs = []; _this._overflowTabGroups = []; _this._dropdownDisposable = new lifecycle_1.MutableDisposable(); _this._onDrop = new events_1.Emitter(); _this.onDrop = _this._onDrop.event; _this._onGroupDragStart = new events_1.Emitter(); _this.onGroupDragStart = _this._onGroupDragStart.event; _this._onWillShowOverlay = new events_1.Emitter(); _this.onWillShowOverlay = _this._onWillShowOverlay.event; _this._element = document.createElement('div'); _this._element.className = 'dv-tabs-and-actions-container'; (0, dom_1.toggleClass)(_this._element, 'dv-full-width-single-tab', _this.accessor.options.singleTabMode === 'fullwidth'); _this.rightActionsContainer = document.createElement('div'); _this.rightActionsContainer.className = 'dv-right-actions-container'; _this.leftActionsContainer = document.createElement('div'); _this.leftActionsContainer.className = 'dv-left-actions-container'; _this.preActionsContainer = document.createElement('div'); _this.preActionsContainer.className = 'dv-pre-actions-container'; _this.tabs = new tabs_1.Tabs(group, accessor, { showTabsOverflowControl: !accessor.options.disableTabsOverflowList, }); _this.voidContainer = new voidContainer_1.VoidContainer(_this.accessor, _this.group); _this.tabs.voidContainer = _this.voidContainer.element; _this._element.appendChild(_this.preActionsContainer); _this._element.appendChild(_this.tabs.element); _this._element.appendChild(_this.leftActionsContainer); _this._element.appendChild(_this.voidContainer.element); _this._element.appendChild(_this.rightActionsContainer); _this.tabs.setExtendedDropZone(_this._element); _this.addDisposables(_this.tabs.onDrop(function (e) { return _this._onDrop.fire(e); }), _this.tabs.onWillShowOverlay(function (e) { return _this._onWillShowOverlay.fire(e); }), accessor.onDidOptionsChange(function () { _this.tabs.showTabsOverflowControl = !accessor.options.disableTabsOverflowList; }), _this.tabs.onOverflowTabsChange(function (event) { _this.toggleDropdown(event); }), _this.tabs, _this._onWillShowOverlay, _this._onDrop, _this._onGroupDragStart, _this.voidContainer, _this.voidContainer.onDragStart(function (event) { _this._onGroupDragStart.fire({ nativeEvent: event, group: _this.group, }); }), _this.voidContainer.onDrop(function (event) { // If an active group drag is in progress, let Tabs handle it if (_this.tabs.handleVoidDrop()) { return; } _this._onDrop.fire({ event: event.nativeEvent, index: _this.tabs.size, }); }), _this.voidContainer.onWillShowOverlay(function (event) { _this._onWillShowOverlay.fire(new events_2.DockviewWillShowOverlayLocationEvent(event, { kind: 'header_space', panel: _this.group.activePanel, api: _this.accessor.api, group: _this.group, getData: dataTransfer_1.getPanelData, })); }), (0, events_1.addDisposableListener)(_this.leftActionsContainer, 'dragleave', function (event) { var related = event.relatedTarget; if (!_this.leftActionsContainer.contains(related) && !_this._element.contains(related)) { // Left the header entirely _this.tabs.clearExternalAnimState(); } }), (0, events_1.addDisposableListener)(_this.voidContainer.element, 'dragleave', function (event) { var related = event.relatedTarget; if (!_this.voidContainer.element.contains(related)) { if (_this._element.contains(related)) { // Moved to another part of the header — keep state _this.tabs.setExternalInsertionIndex(null); } else { // Left the header entirely _this.tabs.clearExternalAnimState(); } } }), (0, events_1.addDisposableListener)(_this.voidContainer.element, 'pointerdown', function (event) { if (event.defaultPrevented) { return; } var isFloatingGroupsEnabled = !_this.accessor.options.disableFloatingGroups; if (isFloatingGroupsEnabled && event.shiftKey && _this.group.api.location.type !== 'floating' && _this.group.api.location.type !== 'edge') { event.preventDefault(); var _a = _this.element.getBoundingClientRect(), top_1 = _a.top, left = _a.left; var _b = _this.accessor.element.getBoundingClientRect(), rootTop = _b.top, rootLeft = _b.left; _this.accessor.addFloatingGroup(_this.group, { x: left - rootLeft + 20, y: top_1 - rootTop + 20, inDragMode: true, }); } })); return _this; } Object.defineProperty(TabsContainer.prototype, "onTabDragStart", { get: function () { return this.tabs.onTabDragStart; }, enumerable: false, configurable: true }); Object.defineProperty(TabsContainer.prototype, "panels", { get: function () { return this.tabs.panels; }, enumerable: false, configurable: true }); Object.defineProperty(TabsContainer.prototype, "size", { get: function () { return this.tabs.size; }, enumerable: false, configurable: true }); Object.defineProperty(TabsContainer.prototype, "hidden", { get: function () { return this._hidden; }, set: function (value) { this._hidden = value; this.element.style.display = value ? 'none' : ''; }, enumerable: false, configurable: true }); Object.defineProperty(TabsContainer.prototype, "direction", { get: function () { return this._direction; }, set: function (value) { this._direction = value; if (value === 'vertical') { (0, dom_1.addClasses)(this._element, 'dv-groupview-header-vertical'); (0, dom_1.addClasses)(this.rightActionsContainer, 'dv-right-actions-container-vertical'); this.tabs.direction = value; } else { (0, dom_1.removeClasses)(this._element, 'dv-groupview-header-vertical'); (0, dom_1.removeClasses)(this.rightActionsContainer, 'dv-right-actions-container-vertical'); this.tabs.direction = value; } }, enumerable: false, configurable: true }); Object.defineProperty(TabsContainer.prototype, "element", { get: function () { return this._element; }, enumerable: false, configurable: true }); TabsContainer.prototype.show = function () { if (!this.hidden) { this.element.style.display = ''; } }; TabsContainer.prototype.hide = function () { this._element.style.display = 'none'; }; TabsContainer.prototype.setRightActionsElement = function (element) { if (this.rightActions === element) { return; } if (this.rightActions) { this.rightActions.remove(); this.rightActions = undefined; } if (element) { this.rightActionsContainer.appendChild(element); this.rightActions = element; } }; TabsContainer.prototype.setLeftActionsElement = function (element) { if (this.leftActions === element) { return; } if (this.leftActions) { this.leftActions.remove(); this.leftActions = undefined; } if (element) { this.leftActionsContainer.appendChild(element); this.leftActions = element; } }; TabsContainer.prototype.setPrefixActionsElement = function (element) { if (this.preActions === element) { return; } if (this.preActions) { this.preActions.remove(); this.preActions = undefined; } if (element) { this.preActionsContainer.appendChild(element); this.preActions = element; } }; TabsContainer.prototype.isActive = function (tab) { return this.tabs.isActive(tab); }; TabsContainer.prototype.indexOf = function (id) { return this.tabs.indexOf(id); }; TabsContainer.prototype.setActive = function (_isGroupActive) { // noop }; TabsContainer.prototype.delete = function (id) { this.tabs.delete(id); this.updateClassnames(); }; TabsContainer.prototype.setActivePanel = function (panel) { this.tabs.setActivePanel(panel); }; TabsContainer.prototype.openPanel = function (panel, index) { if (index === void 0) { index = this.tabs.size; } this.tabs.openPanel(panel, index); this.updateClassnames(); }; TabsContainer.prototype.closePanel = function (panel) { this.delete(panel.id); }; TabsContainer.prototype.updateClassnames = function () { (0, dom_1.toggleClass)(this._element, 'dv-single-tab', this.size === 1); }; TabsContainer.prototype.toggleDropdown = function (options) { var _this = this; var tabs = options.reset ? [] : options.tabs; var tabGroups = options.reset ? [] : options.tabGroups; this._overflowTabs = tabs; this._overflowTabGroups = tabGroups; var totalCount = this._overflowTabs.length; if (totalCount > 0 && this.dropdownPart) { this.dropdownPart.update({ tabs: totalCount }); return; } if (totalCount === 0) { this._dropdownDisposable.dispose(); return; } var root = document.createElement('div'); root.className = 'dv-tabs-overflow-dropdown-root'; var part = (0, tabOverflowControl_1.createDropdownElementHandle)(); part.update({ tabs: totalCount }); this.dropdownPart = part; root.appendChild(part.element); this.rightActionsContainer.prepend(root); this._dropdownDisposable.value = new lifecycle_1.CompositeDisposable(lifecycle_1.Disposable.from(function () { var _a, _b; root.remove(); (_b = (_a = _this.dropdownPart) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a); _this.dropdownPart = null; }), (0, events_1.addDisposableListener)(root, 'pointerdown', function (event) { event.preventDefault(); }, { capture: true }), (0, events_1.addDisposableListener)(root, 'click', function (event) { var e_1, _a, e_2, _b, e_3, _c; var el = document.createElement('div'); el.style.overflow = 'auto'; el.className = 'dv-tabs-overflow-container'; // Build lookup: panelId → tabGroup for overflow groups var overflowGroupSet = new Set(_this._overflowTabGroups); var allTabGroups = _this.group.model.getTabGroups(); var panelToGroup = new Map(); try { for (var allTabGroups_1 = __values(allTabGroups), allTabGroups_1_1 = allTabGroups_1.next(); !allTabGroups_1_1.done; allTabGroups_1_1 = allTabGroups_1.next()) { var tg = allTabGroups_1_1.value; if (overflowGroupSet.has(tg.id)) { try { for (var _d = (e_2 = void 0, __values(tg.panelIds)), _e = _d.next(); !_e.done; _e = _d.next()) { var pid = _e.value; panelToGroup.set(pid, tg); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_e && !_e.done && (_b = _d.return)) _b.call(_d); } finally { if (e_2) throw e_2.error; } } } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (allTabGroups_1_1 && !allTabGroups_1_1.done && (_a = allTabGroups_1.return)) _a.call(allTabGroups_1); } finally { if (e_1) throw e_1.error; } } // Track which groups have already been rendered var renderedGroups = new Set(); var _loop_1 = function (tab) { var tg = panelToGroup.get(tab.panel.id); // If this tab belongs to an overflow group, render the // group header before its first member tab. if (tg && !renderedGroups.has(tg.id)) { renderedGroups.add(tg.id); var groupHeader = document.createElement('div'); groupHeader.className = 'dv-tabs-overflow-group-header'; var colorDot = document.createElement('span'); colorDot.className = 'dv-tabs-overflow-group-color'; (0, tabGroupAccent_1.applyTabGroupAccent)(colorDot, tg.color, _this.accessor.tabGroupColorPalette); groupHeader.appendChild(colorDot); var labelSpan = document.createElement('span'); labelSpan.className = 'dv-tabs-overflow-group-label'; labelSpan.textContent = tg.label || tg.id; groupHeader.appendChild(labelSpan); if (tg.collapsed) { var badge = document.createElement('span'); badge.className = 'dv-tabs-overflow-group-collapsed-badge'; badge.textContent = "".concat(tg.panelIds.length); groupHeader.appendChild(badge); } groupHeader.addEventListener('click', function () { _this.accessor .getPopupServiceForGroup(_this.group) .close(); if (tg.collapsed) { tg.expand(); } // Activate the first panel in the group var firstPanelId = tg.panelIds[0]; if (firstPanelId) { var panel = _this.group.panels.find(function (p) { return p.id === firstPanelId; }); panel === null || panel === void 0 ? void 0 : panel.api.setActive(); } }); el.appendChild(groupHeader); } var panelObject = _this.group.panels.find(function (panel) { return panel === tab.panel; }); var tabComponent = panelObject.view.createTabRenderer('headerOverflow'); var child = tabComponent.element; var wrapper = document.createElement('div'); (0, dom_1.toggleClass)(wrapper, 'dv-tab', true); (0, dom_1.toggleClass)(wrapper, 'dv-active-tab', panelObject.api.isActive); (0, dom_1.toggleClass)(wrapper, 'dv-inactive-tab', !panelObject.api.isActive); if (tg) { (0, dom_1.toggleClass)(wrapper, 'dv-tab--grouped', true); } wrapper.addEventListener('click', function (event) { _this.accessor .getPopupServiceForGroup(_this.group) .close(); if (event.defaultPrevented) { return; } if (tg === null || tg === void 0 ? void 0 : tg.collapsed) { tg.expand(); } tab.element.scrollIntoView(); tab.panel.api.setActive(); }); wrapper.appendChild(child); el.appendChild(wrapper); }; try { for (var _f = __values(_this.tabs.tabs.filter(function (tab) { return _this._overflowTabs.includes(tab.panel.id); })), _g = _f.next(); !_g.done; _g = _f.next()) { var tab = _g.value; _loop_1(tab); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_g && !_g.done && (_c = _f.return)) _c.call(_f); } finally { if (e_3) throw e_3.error; } } var relativeParent = (0, dom_1.findRelativeZIndexParent)(root); _this.accessor .getPopupServiceForGroup(_this.group) .openPopover(el, { x: event.clientX, y: event.clientY, zIndex: (relativeParent === null || relativeParent === void 0 ? void 0 : relativeParent.style.zIndex) ? "calc(".concat(relativeParent.style.zIndex, " * 2)") : undefined, }); })); }; TabsContainer.prototype.updateDragAndDropState = function () { this.tabs.updateDragAndDropState(); this.voidContainer.updateDragAndDropState(); }; TabsContainer.prototype.updateTabGroups = function () { this.tabs.updateTabGroups(); }; TabsContainer.prototype.refreshTabGroupAccent = function () { this.tabs.refreshTabGroupAccent(); }; return TabsContainer; }(lifecycle_1.CompositeDisposable)); exports.TabsContainer = TabsContainer;