devextreme
Version:
JavaScript/TypeScript Component Suite for Responsive Web Development
227 lines (225 loc) • 9.08 kB
JavaScript
/**
* DevExtreme (cjs/__internal/ui/popup/m_popup_drag.js)
* Version: 26.1.3
* Build date: Wed Jun 10 2026
*
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _translator = require("../../../common/core/animation/translator");
var _events_engine = _interopRequireDefault(require("../../../common/core/events/core/events_engine"));
var _drag = require("../../../common/core/events/drag");
var _utils = require("../../../common/core/events/utils");
var _dom_adapter = _interopRequireDefault(require("../../../core/dom_adapter"));
var _math = require("../../../core/utils/math");
var _size = require("../../../core/utils/size");
var _type = require("../../../core/utils/type");
function _interopRequireDefault(e) {
return e && e.__esModule ? e : {
default: e
}
}
const KEYBOARD_DRAG_STEP = 5;
class PopupDrag {
constructor(configuration) {
this._namespace = "overlayDrag";
this.init(configuration)
}
init(configuration) {
const {
positionController: positionController,
draggableElement: draggableElement,
handle: handle,
dragEnabled: dragEnabled
} = configuration;
this._positionController = positionController;
this._draggableElement = draggableElement;
this._handle = handle;
this._dragEnabled = dragEnabled;
this.unsubscribe();
if (!dragEnabled) {
return
}
this.subscribe()
}
moveDown(e) {
this._moveTo(5, 0, e)
}
moveUp(e) {
this._moveTo(-5, 0, e)
}
moveLeft(e) {
this._moveTo(0, -5, e)
}
moveRight(e) {
this._moveTo(0, 5, e)
}
subscribe() {
const eventNames = this._getEventNames();
_events_engine.default.on(this._handle, eventNames.startEventName, e => {
this._dragStartHandler(e)
});
_events_engine.default.on(this._handle, eventNames.updateEventName, e => {
this._dragUpdateHandler(e)
});
_events_engine.default.on(this._handle, eventNames.endEventName, e => {
this._dragEndHandler(e)
})
}
unsubscribe() {
const eventNames = this._getEventNames();
_events_engine.default.off(this._handle, eventNames.startEventName);
_events_engine.default.off(this._handle, eventNames.updateEventName);
_events_engine.default.off(this._handle, eventNames.endEventName)
}
_getEventNames() {
const startEventName = (0, _utils.addNamespace)(_drag.start, this._namespace);
const updateEventName = (0, _utils.addNamespace)(_drag.move, this._namespace);
const endEventName = (0, _utils.addNamespace)(_drag.end, this._namespace);
return {
startEventName: startEventName,
updateEventName: updateEventName,
endEventName: endEventName
}
}
_dragStartHandler(e) {
const allowedOffsets = this._getAllowedOffsets();
this._prevOffset = {
x: 0,
y: 0
};
e.targetElements = [];
e.maxTopOffset = allowedOffsets.top;
e.maxBottomOffset = allowedOffsets.bottom;
e.maxLeftOffset = allowedOffsets.left;
e.maxRightOffset = allowedOffsets.right
}
_dragUpdateHandler(e) {
var _this$_prevOffset, _this$_prevOffset2;
const targetOffset = {
top: e.offset.y - ((null === (_this$_prevOffset = this._prevOffset) || void 0 === _this$_prevOffset ? void 0 : _this$_prevOffset.y) ?? 0),
left: e.offset.x - ((null === (_this$_prevOffset2 = this._prevOffset) || void 0 === _this$_prevOffset2 ? void 0 : _this$_prevOffset2.x) ?? 0)
};
this._moveByOffset(targetOffset);
this._prevOffset = e.offset
}
_dragEndHandler(event) {
var _this$_positionContro, _this$_positionContro2;
null === (_this$_positionContro = this._positionController) || void 0 === _this$_positionContro || _this$_positionContro.dragHandled();
null === (_this$_positionContro2 = this._positionController) || void 0 === _this$_positionContro2 || _this$_positionContro2.detectVisualPositionChange(event)
}
_moveTo(top, left, e) {
if (!this._dragEnabled) {
return
}
e.preventDefault();
e.stopPropagation();
const offset = this._fitOffsetIntoAllowedRange(top, left);
this._moveByOffset(offset);
this._dragEndHandler(e)
}
_fitOffsetIntoAllowedRange(top, left) {
const allowedOffsets = this._getAllowedOffsets();
return {
top: (0, _math.fitIntoRange)(top, -allowedOffsets.top, allowedOffsets.bottom),
left: (0, _math.fitIntoRange)(left, -allowedOffsets.left, allowedOffsets.right)
}
}
_getContainerDimensions() {
var _this$_positionContro3;
const document = _dom_adapter.default.getDocument();
const container = null === (_this$_positionContro3 = this._positionController) || void 0 === _this$_positionContro3 || null === (_this$_positionContro3 = _this$_positionContro3.$dragResizeContainer) || void 0 === _this$_positionContro3 ? void 0 : _this$_positionContro3.get(0);
let containerWidth = (0, _size.getOuterWidth)(container);
let containerHeight = (0, _size.getOuterHeight)(container);
if ((0, _type.isWindow)(container)) {
containerHeight = Math.max(document.body.clientHeight, containerHeight);
containerWidth = Math.max(document.body.clientWidth, containerWidth)
}
return {
width: containerWidth,
height: containerHeight
}
}
_getContainerPosition() {
var _this$_positionContro4;
const container = null === (_this$_positionContro4 = this._positionController) || void 0 === _this$_positionContro4 || null === (_this$_positionContro4 = _this$_positionContro4.$dragResizeContainer) || void 0 === _this$_positionContro4 ? void 0 : _this$_positionContro4.get(0);
return (0, _type.isWindow)(container) ? {
top: 0,
left: 0
} : (0, _size.getOffset)(container)
}
_getElementPosition() {
return (0, _size.getOffset)(this._draggableElement)
}
_getInnerDelta() {
const containerDimensions = this._getContainerDimensions();
const elementDimensions = this._getElementDimensions();
return {
x: containerDimensions.width - (elementDimensions.width ?? 0),
y: containerDimensions.height - (elementDimensions.height ?? 0)
}
}
_getOuterDelta() {
const {
width: width = 0,
height: height = 0
} = this._getElementDimensions();
const {
outsideDragFactor: outsideDragFactor = 0
} = this._positionController ?? {};
return {
x: width * outsideDragFactor,
y: height * outsideDragFactor
}
}
_getFullDelta() {
const fullDelta = this._getInnerDelta();
const outerDelta = this._getOuterDelta();
return {
x: fullDelta.x + outerDelta.x,
y: fullDelta.y + outerDelta.y
}
}
_getElementDimensions() {
var _this$_draggableEleme, _this$_draggableEleme2;
return {
width: null === (_this$_draggableEleme = this._draggableElement) || void 0 === _this$_draggableEleme ? void 0 : _this$_draggableEleme.offsetWidth,
height: null === (_this$_draggableEleme2 = this._draggableElement) || void 0 === _this$_draggableEleme2 ? void 0 : _this$_draggableEleme2.offsetHeight
}
}
_getAllowedOffsets() {
const fullDelta = this._getFullDelta();
const isDragAllowed = fullDelta.y >= 0 && fullDelta.x >= 0;
if (!isDragAllowed) {
return {
top: 0,
bottom: 0,
left: 0,
right: 0
}
}
const elementPosition = this._getElementPosition();
const containerPosition = this._getContainerPosition();
const outerDelta = this._getOuterDelta();
return {
top: elementPosition.top - containerPosition.top + outerDelta.y,
bottom: -elementPosition.top + containerPosition.top + fullDelta.y,
left: elementPosition.left - containerPosition.left + outerDelta.x,
right: -elementPosition.left + containerPosition.left + fullDelta.x
}
}
_moveByOffset(offset) {
const currentPosition = (0, _translator.locate)(this._draggableElement);
const newPosition = {
left: currentPosition.left + offset.left,
top: currentPosition.top + offset.top
};
(0, _translator.move)(this._draggableElement, newPosition)
}
}
exports.default = PopupDrag;