UNPKG

dockview-core

Version:

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

335 lines (334 loc) 13.8 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 __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Droptarget = exports.WillShowOverlayEvent = void 0; exports.directionToPosition = directionToPosition; exports.positionToDirection = positionToDirection; exports.calculateQuadrantAsPercentage = calculateQuadrantAsPercentage; exports.calculateQuadrantAsPixels = calculateQuadrantAsPixels; var events_1 = require("../events"); var lifecycle_1 = require("../lifecycle"); var dnd_1 = require("./dnd"); var dropOverlay_1 = require("./dropOverlay"); var WillShowOverlayEvent = /** @class */ (function (_super) { __extends(WillShowOverlayEvent, _super); function WillShowOverlayEvent(options) { var _this = _super.call(this) || this; _this.options = options; return _this; } Object.defineProperty(WillShowOverlayEvent.prototype, "nativeEvent", { get: function () { return this.options.nativeEvent; }, enumerable: false, configurable: true }); Object.defineProperty(WillShowOverlayEvent.prototype, "position", { get: function () { return this.options.position; }, enumerable: false, configurable: true }); return WillShowOverlayEvent; }(events_1.DockviewEvent)); exports.WillShowOverlayEvent = WillShowOverlayEvent; function directionToPosition(direction) { switch (direction) { case 'above': return 'top'; case 'below': return 'bottom'; case 'left': return 'left'; case 'right': return 'right'; case 'within': return 'center'; default: throw new Error("invalid direction '".concat(direction, "'")); } } function positionToDirection(position) { switch (position) { case 'top': return 'above'; case 'bottom': return 'below'; case 'left': return 'left'; case 'right': return 'right'; case 'center': return 'within'; default: throw new Error("invalid position '".concat(position, "'")); } } var DEFAULT_ACTIVATION_SIZE = { value: 20, type: 'percentage', }; var Droptarget = /** @class */ (function (_super) { __extends(Droptarget, _super); function Droptarget(element, options) { var _this = _super.call(this) || this; _this.element = element; _this.options = options; _this._onDrop = new events_1.Emitter(); _this.onDrop = _this._onDrop.event; _this._onWillShowOverlay = new events_1.Emitter(); _this.onWillShowOverlay = _this._onWillShowOverlay.event; _this._disabled = false; // use a set to take advantage of #<set>.has _this._acceptedTargetZonesSet = new Set(_this.options.acceptedTargetZones); _this.dnd = new dnd_1.DragAndDropObserver(_this.element, { onDragEnter: function () { var _a, _b, _c; (_c = (_b = (_a = _this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.getElements(); }, onDragOver: function (e) { var _a, _b, _c, _d, _e, _f, _g; Droptarget.ACTUAL_TARGET = _this; var overrideTarget = (_b = (_a = _this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a); if (_this._acceptedTargetZonesSet.size === 0) { if (overrideTarget) { return; } _this.removeDropTarget(); return; } var target = (_e = (_d = (_c = _this.options).getOverlayOutline) === null || _d === void 0 ? void 0 : _d.call(_c)) !== null && _e !== void 0 ? _e : _this.element; var width = target.offsetWidth; var height = target.offsetHeight; if (width === 0 || height === 0) { return; // avoid div!0 } var rect = e.currentTarget.getBoundingClientRect(); var x = ((_f = e.clientX) !== null && _f !== void 0 ? _f : 0) - rect.left; var y = ((_g = e.clientY) !== null && _g !== void 0 ? _g : 0) - rect.top; var quadrant = _this.calculateQuadrant(_this._acceptedTargetZonesSet, x, y, width, height); /** * If the event has already been used by another DropTarget instance * then don't show a second drop target, only one target should be * active at any one time */ if (_this.isAlreadyUsed(e) || quadrant === null) { // no drop target should be displayed _this.removeDropTarget(); return; } if (!_this.options.canDisplayOverlay(e, quadrant)) { if (overrideTarget) { return; } _this.removeDropTarget(); return; } var willShowOverlayEvent = new WillShowOverlayEvent({ nativeEvent: e, position: quadrant, }); /** * Provide an opportunity to prevent the overlay appearing and in turn * any dnd behaviours */ _this._onWillShowOverlay.fire(willShowOverlayEvent); if (willShowOverlayEvent.defaultPrevented) { _this.removeDropTarget(); return; } _this.markAsUsed(e); if (overrideTarget) { // } else if (!_this.targetElement) { var els = (0, dropOverlay_1.createOverlayElements)(); _this.targetElement = els.dropzone; _this.overlayElement = els.selection; _this._state = 'center'; target.classList.add('dv-drop-target'); target.append(_this.targetElement); } _this.toggleClasses(quadrant, width, height); _this._state = quadrant; }, onDragLeave: function () { var _a, _b; var target = (_b = (_a = _this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a); if (target) { return; } _this.removeDropTarget(); }, onDragEnd: function (e) { var _a, _b; var target = (_b = (_a = _this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a); if (target && Droptarget.ACTUAL_TARGET === _this) { if (_this._state) { // only stop the propagation of the event if we are dealing with it // which is only when the target has state e.stopPropagation(); _this._onDrop.fire({ position: _this._state, nativeEvent: e, }); } } _this.removeDropTarget(); target === null || target === void 0 ? void 0 : target.clear(); }, onDrop: function (e) { var _a, _b, _c; e.preventDefault(); var state = _this._state; _this.removeDropTarget(); (_c = (_b = (_a = _this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.clear(); if (state) { // only stop the propagation of the event if we are dealing with it // which is only when the target has state e.stopPropagation(); _this._onDrop.fire({ position: state, nativeEvent: e }); } }, }); _this.addDisposables(_this._onDrop, _this._onWillShowOverlay, _this.dnd); return _this; } Object.defineProperty(Droptarget.prototype, "disabled", { get: function () { return this._disabled; }, set: function (value) { this._disabled = value; }, enumerable: false, configurable: true }); Object.defineProperty(Droptarget.prototype, "state", { get: function () { return this._state; }, enumerable: false, configurable: true }); Droptarget.prototype.setTargetZones = function (acceptedTargetZones) { this._acceptedTargetZonesSet = new Set(acceptedTargetZones); }; Droptarget.prototype.setOverlayModel = function (model) { this.options.overlayModel = model; }; Droptarget.prototype.dispose = function () { this.removeDropTarget(); _super.prototype.dispose.call(this); }; /** * Add a property to the event object for other potential listeners to check */ Droptarget.prototype.markAsUsed = function (event) { event[Droptarget.USED_EVENT_ID] = true; }; /** * Check is the event has already been used by another instance of DropTarget */ Droptarget.prototype.isAlreadyUsed = function (event) { var value = event[Droptarget.USED_EVENT_ID]; return typeof value === 'boolean' && value; }; Droptarget.prototype.toggleClasses = function (quadrant, width, height) { var _a, _b, _c, _d, _e; var target = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a); if (target) { var outlineEl = (_e = (_d = (_c = this.options).getOverlayOutline) === null || _d === void 0 ? void 0 : _d.call(_c)) !== null && _e !== void 0 ? _e : this.element; (0, dropOverlay_1.renderAnchoredOverlay)({ outlineElement: outlineEl, targetModel: target, quadrant: quadrant, width: width, height: height, overlayModel: this.options.overlayModel, className: this.options.className, }); return; } if (!this.overlayElement) { return; } (0, dropOverlay_1.renderInPlaceOverlay)(this.overlayElement, quadrant, width, height, this.options.overlayModel); }; Droptarget.prototype.calculateQuadrant = function (overlayType, x, y, width, height) { var _a, _b; var activationSizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.activationSize) !== null && _b !== void 0 ? _b : DEFAULT_ACTIVATION_SIZE; var isPercentage = activationSizeOptions.type === 'percentage'; if (isPercentage) { return calculateQuadrantAsPercentage(overlayType, x, y, width, height, activationSizeOptions.value); } return calculateQuadrantAsPixels(overlayType, x, y, width, height, activationSizeOptions.value); }; Droptarget.prototype.removeDropTarget = function () { var _a; if (this.targetElement) { this._state = undefined; (_a = this.targetElement.parentElement) === null || _a === void 0 ? void 0 : _a.classList.remove('dv-drop-target'); this.targetElement.remove(); this.targetElement = undefined; this.overlayElement = undefined; } }; Droptarget.USED_EVENT_ID = '__dockview_droptarget_event_is_used__'; return Droptarget; }(lifecycle_1.CompositeDisposable)); exports.Droptarget = Droptarget; function calculateQuadrantAsPercentage(overlayType, x, y, width, height, threshold) { var xp = (100 * x) / width; var yp = (100 * y) / height; if (overlayType.has('left') && xp < threshold) { return 'left'; } if (overlayType.has('right') && xp > 100 - threshold) { return 'right'; } if (overlayType.has('top') && yp < threshold) { return 'top'; } if (overlayType.has('bottom') && yp > 100 - threshold) { return 'bottom'; } if (!overlayType.has('center')) { return null; } return 'center'; } function calculateQuadrantAsPixels(overlayType, x, y, width, height, threshold) { if (overlayType.has('left') && x < threshold) { return 'left'; } if (overlayType.has('right') && x > width - threshold) { return 'right'; } if (overlayType.has('top') && y < threshold) { return 'top'; } if (overlayType.has('bottom') && y > height - threshold) { return 'bottom'; } if (!overlayType.has('center')) { return null; } return 'center'; }