dockview-core
Version:
Zero dependency layout manager supporting tabs, groups, grids and splitviews for vanilla TypeScript
198 lines (197 loc) • 8.67 kB
JavaScript
"use strict";
// Two render paths: in-place (dropzone appended to drop element) and
// anchored (overlay rendered into an external anchor container).
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOverlayElements = createOverlayElements;
exports.renderInPlaceOverlay = renderInPlaceOverlay;
exports.renderAnchoredOverlay = renderAnchoredOverlay;
var dom_1 = require("../dom");
var math_1 = require("../math");
var DEFAULT_SIZE = { value: 50, type: 'percentage' };
var SMALL_WIDTH_BOUNDARY = 100;
var SMALL_HEIGHT_BOUNDARY = 100;
function createOverlayElements() {
var dropzone = document.createElement('div');
dropzone.className = 'dv-drop-target-dropzone';
var selection = document.createElement('div');
selection.className = 'dv-drop-target-selection';
dropzone.appendChild(selection);
return { dropzone: dropzone, selection: selection };
}
function computeOverlayShape(quadrant, width, height, overlayModel) {
var _a, _b, _c;
var smallWidthBoundary = (_a = overlayModel === null || overlayModel === void 0 ? void 0 : overlayModel.smallWidthBoundary) !== null && _a !== void 0 ? _a : SMALL_WIDTH_BOUNDARY;
var smallHeightBoundary = (_b = overlayModel === null || overlayModel === void 0 ? void 0 : overlayModel.smallHeightBoundary) !== null && _b !== void 0 ? _b : SMALL_HEIGHT_BOUNDARY;
var isSmallX = width < smallWidthBoundary;
var isSmallY = height < smallHeightBoundary;
var isLeft = quadrant === 'left';
var isRight = quadrant === 'right';
var isTop = quadrant === 'top';
var isBottom = quadrant === 'bottom';
var rightClass = !isSmallX && isRight;
var leftClass = !isSmallX && isLeft;
var topClass = !isSmallY && isTop;
var bottomClass = !isSmallY && isBottom;
var size = 1;
var sizeOptions = (_c = overlayModel === null || overlayModel === void 0 ? void 0 : overlayModel.size) !== null && _c !== void 0 ? _c : DEFAULT_SIZE;
if (sizeOptions.type === 'percentage') {
size = (0, math_1.clamp)(sizeOptions.value, 0, 100) / 100;
}
else {
if (rightClass || leftClass) {
size = (0, math_1.clamp)(0, sizeOptions.value, width) / width;
}
if (topClass || bottomClass) {
size = (0, math_1.clamp)(0, sizeOptions.value, height) / height;
}
}
return {
isSmallX: isSmallX,
isSmallY: isSmallY,
isLeft: isLeft,
isRight: isRight,
isTop: isTop,
isBottom: isBottom,
rightClass: rightClass,
leftClass: leftClass,
topClass: topClass,
bottomClass: bottomClass,
size: size,
};
}
function renderInPlaceOverlay(overlay, quadrant, width, height, overlayModel) {
var shape = computeOverlayShape(quadrant, width, height, overlayModel);
var rightClass = shape.rightClass, leftClass = shape.leftClass, topClass = shape.topClass, bottomClass = shape.bottomClass, size = shape.size;
var box = { top: '0px', left: '0px', width: '100%', height: '100%' };
if (rightClass) {
box.left = "".concat(100 * (1 - size), "%");
box.width = "".concat(100 * size, "%");
}
else if (leftClass) {
box.width = "".concat(100 * size, "%");
}
else if (topClass) {
box.height = "".concat(100 * size, "%");
}
else if (bottomClass) {
box.top = "".concat(100 * (1 - size), "%");
box.height = "".concat(100 * size, "%");
}
if (shape.isSmallX && shape.isLeft) {
box.width = '4px';
}
if (shape.isSmallX && shape.isRight) {
box.left = "".concat(width - 4, "px");
box.width = '4px';
}
if (shape.isSmallY && shape.isTop) {
box.height = '4px';
}
if (shape.isSmallY && shape.isBottom) {
box.top = "".concat(height - 4, "px");
box.height = '4px';
}
overlay.style.top = box.top;
overlay.style.left = box.left;
overlay.style.width = box.width;
overlay.style.height = box.height;
overlay.style.visibility = 'visible';
if (!overlay.style.transform || overlay.style.transform === '') {
overlay.style.transform = 'translate3d(0, 0, 0)';
}
var isLine = (shape.isSmallX && (shape.isLeft || shape.isRight)) ||
(shape.isSmallY && (shape.isTop || shape.isBottom));
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-small-vertical', shape.isSmallY);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-small-horizontal', shape.isSmallX);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-selection-line', isLine);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-left', shape.isLeft);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-right', shape.isRight);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-top', shape.isTop);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-bottom', shape.isBottom);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-center', quadrant === 'center');
}
function checkAnchoredBoundsChanged(overlay, bounds) {
var topPx = "".concat(Math.round(bounds.top), "px");
var leftPx = "".concat(Math.round(bounds.left), "px");
var widthPx = "".concat(Math.round(bounds.width), "px");
var heightPx = "".concat(Math.round(bounds.height), "px");
return (overlay.style.top !== topPx ||
overlay.style.left !== leftPx ||
overlay.style.width !== widthPx ||
overlay.style.height !== heightPx);
}
function applyAnchoredBounds(overlay, bounds) {
overlay.style.top = "".concat(Math.round(bounds.top), "px");
overlay.style.left = "".concat(Math.round(bounds.left), "px");
overlay.style.width = "".concat(Math.round(bounds.width), "px");
overlay.style.height = "".concat(Math.round(bounds.height), "px");
overlay.style.visibility = 'visible';
if (!overlay.style.transform || overlay.style.transform === '') {
overlay.style.transform = 'translate3d(0, 0, 0)';
}
}
/** `boundsChanged: false` lets callers skip redundant work on tight drag loops. */
function renderAnchoredOverlay(args) {
var shape = computeOverlayShape(args.quadrant, args.width, args.height, args.overlayModel);
var rightClass = shape.rightClass, leftClass = shape.leftClass, topClass = shape.topClass, bottomClass = shape.bottomClass, size = shape.size;
var elBox = args.outlineElement.getBoundingClientRect();
var ta = args.targetModel.getElements(undefined, args.outlineElement);
var el = ta.root;
var overlay = ta.overlay;
var bigbox = el.getBoundingClientRect();
var rootTop = elBox.top - bigbox.top;
var rootLeft = elBox.left - bigbox.left;
var box = {
top: rootTop,
left: rootLeft,
width: args.width,
height: args.height,
};
if (rightClass) {
box.left = rootLeft + args.width * (1 - size);
box.width = args.width * size;
}
else if (leftClass) {
box.width = args.width * size;
}
else if (topClass) {
box.height = args.height * size;
}
else if (bottomClass) {
box.top = rootTop + args.height * (1 - size);
box.height = args.height * size;
}
if (shape.isSmallX && shape.isLeft) {
box.width = 4;
}
if (shape.isSmallX && shape.isRight) {
box.left = rootLeft + args.width - 4;
box.width = 4;
}
if (shape.isSmallY && shape.isTop) {
box.height = 4;
}
if (shape.isSmallY && shape.isBottom) {
box.top = rootTop + args.height - 4;
box.height = 4;
}
if (!checkAnchoredBoundsChanged(overlay, box)) {
return { boundsChanged: false, targetChanged: ta.changed };
}
applyAnchoredBounds(overlay, box);
overlay.className = "dv-drop-target-anchor".concat(args.className ? " ".concat(args.className) : '');
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-left', shape.isLeft);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-right', shape.isRight);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-top', shape.isTop);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-bottom', shape.isBottom);
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-anchor-line', (shape.isSmallX && (shape.isLeft || shape.isRight)) ||
(shape.isSmallY && (shape.isTop || shape.isBottom)));
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-center', args.quadrant === 'center');
if (ta.changed) {
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-anchor-container-changed', true);
setTimeout(function () {
(0, dom_1.toggleClass)(overlay, 'dv-drop-target-anchor-container-changed', false);
}, 10);
}
return { boundsChanged: true, targetChanged: ta.changed };
}