Skip to content

Commit

Permalink
fix(popup): trap drag events inside popup
Browse files Browse the repository at this point in the history
* Do not bubble up dragstart events
* Do not bubble up dragover events
  • Loading branch information
Niklas Kiefer committed Sep 25, 2023
1 parent 60fd05f commit 2243307
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
26 changes: 23 additions & 3 deletions src/components/Popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEffect, useRef } from 'preact/hooks';

import classNames from 'classnames';

import { throttle } from 'min-dash';
import { isFunction } from 'min-dash';

import * as focusTrap from 'focus-trap';

Expand All @@ -24,6 +24,7 @@ const noop = () => {};
* @param {HTMLElement} [props.container]
* @param {string} [props.className]
* @param {boolean} [props.delayInitialFocus]
* @param {Function} [props.emit]
* @param {{x: number, y: number}} [props.position]
* @param {number} [props.width]
* @param {number} [props.height]
Expand Down Expand Up @@ -137,6 +138,7 @@ function Title(props) {
children,
className,
draggable,
emit,
title,
...rest
} = props;
Expand All @@ -152,7 +154,9 @@ function Title(props) {

const titleRef = useRef();

const onMove = throttle((_, delta) => {
const onMove = (event, delta) => {
cancel(event);

const { x: dx, y: dy } = delta;

const newPosition = {
Expand All @@ -164,25 +168,36 @@ function Title(props) {

popupParent.style.top = newPosition.y + 'px';
popupParent.style.left = newPosition.x + 'px';
});

// notify interested parties
isFunction(emit) && emit('dragover', { newPosition, delta });
};

const onMoveStart = (event) => {

// initialize drag handler
const onDragStart = createDragger(onMove, dragPreviewRef.current);
onDragStart(event);

event.stopPropagation();

const popupParent = getPopupParent(titleRef.current);

const bounds = popupParent.getBoundingClientRect();
context.current.startPosition = {
x: bounds.left,
y: bounds.top
};

// notify interested parties
isFunction(emit) && emit('dragstart');
};

const onMoveEnd = () => {
context.current.newPosition = null;

// notify interested parties
isFunction(emit) && emit('dragend');
};

return (
Expand Down Expand Up @@ -244,4 +259,9 @@ function Footer(props) {

function getPopupParent(node) {
return node.closest('.bio-properties-panel-popup');
}

function cancel(event) {
event.preventDefault();
event.stopPropagation();
}
36 changes: 36 additions & 0 deletions test/spec/components/Popup.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,42 @@ describe('<Popup>', function() {
expect(newBounds.x).to.eql(oldBounds.x + 20);
});


it('should not bubble dragging events to parent', function() {

// given
const dragStartSpy = sinon.spy();
const dragOverSpy = sinon.spy();
const dragEnterSpy = sinon.spy();

container.addEventListener('dragstart', dragStartSpy);
container.addEventListener('dragover', dragOverSpy);
container.addEventListener('dragenter', dragEnterSpy);

render(
<Popup container={ container }>
<Popup.Title draggable={ true } />
</Popup>,
{ container }
);

const header = domQuery('.bio-properties-panel-popup__header', container);
const dragger = domQuery('.bio-properties-panel-popup__drag-handle', header);

const draggerBounds = dragger.getBoundingClientRect();

// when
startDragging(dragger);
moveDragging(dragger, { clientX: draggerBounds.x + 20, clientY: draggerBounds.y });
endDragging(dragger);

// then
expect(dragStartSpy).to.not.have.been.called;
expect(dragOverSpy).to.not.have.been.called;
expect(dragEnterSpy).to.not.have.been.called;
});


});

});
Expand Down

0 comments on commit 2243307

Please sign in to comment.