allow paneClick events to happen more leniantly
This commit is contained in:
@@ -67,6 +67,7 @@ export function Pane({
|
||||
selectionKeyPressed,
|
||||
selectionMode = SelectionMode.Full,
|
||||
panOnDrag,
|
||||
paneClickDistance = 0,
|
||||
selectionOnDrag,
|
||||
onSelectionStart,
|
||||
onSelectionEnd,
|
||||
@@ -117,14 +118,9 @@ export function Pane({
|
||||
const onWheel = onPaneScroll ? (event: React.WheelEvent) => onPaneScroll(event) : undefined;
|
||||
|
||||
const onClickCapture = (event: ReactMouseEvent) => {
|
||||
const isSelectionOnDragActive =
|
||||
(selectionOnDrag && container.current === event.target) || !selectionOnDrag || selectionKeyPressed;
|
||||
|
||||
if (!isSelectionOnDragActive) {
|
||||
return;
|
||||
if (selectionInProgress.current) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
// We are using capture here in order to prevent other pointer events
|
||||
@@ -149,9 +145,6 @@ export function Pane({
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
(event.target as Partial<Element>)?.setPointerCapture?.(event.pointerId);
|
||||
|
||||
selectionStarted.current = true;
|
||||
@@ -159,8 +152,6 @@ export function Pane({
|
||||
|
||||
const { x, y } = getEventPosition(event.nativeEvent, containerBounds.current);
|
||||
|
||||
resetSelectedElements();
|
||||
|
||||
store.setState({
|
||||
userSelectionRect: {
|
||||
width: 0,
|
||||
@@ -172,7 +163,14 @@ export function Pane({
|
||||
},
|
||||
});
|
||||
|
||||
onSelectionStart?.(event);
|
||||
if (event.target !== container.current || paneClickDistance === 0) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
resetSelectedElements();
|
||||
|
||||
onSelectionStart?.(event);
|
||||
}
|
||||
};
|
||||
|
||||
const onPointerMove = (event: ReactPointerEvent): void => {
|
||||
@@ -191,11 +189,23 @@ export function Pane({
|
||||
return;
|
||||
}
|
||||
|
||||
selectionInProgress.current = true;
|
||||
|
||||
const { x: mouseX, y: mouseY } = getEventPosition(event.nativeEvent, containerBounds.current);
|
||||
const { startX, startY } = userSelectionRect;
|
||||
|
||||
if (
|
||||
!selectionInProgress.current &&
|
||||
event.target === container.current &&
|
||||
!selectionKeyPressed &&
|
||||
paneClickDistance > 0
|
||||
) {
|
||||
const distance = Math.hypot(mouseX - startX, mouseY - startY);
|
||||
if (distance <= paneClickDistance) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectionInProgress.current = true;
|
||||
|
||||
const nextUserSelectRect = {
|
||||
startX,
|
||||
startY,
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
let {
|
||||
store = $bindable(),
|
||||
panOnDrag = true,
|
||||
paneClickDistance = 1,
|
||||
selectionOnDrag,
|
||||
onpaneclick,
|
||||
onpanecontextmenu,
|
||||
@@ -67,7 +68,7 @@
|
||||
let panOnDragActive = $derived(store.panActivationKeyPressed || panOnDrag);
|
||||
let isSelecting = $derived(
|
||||
store.selectionKeyPressed ||
|
||||
store.selectionRect ||
|
||||
!!store.selectionRect ||
|
||||
(selectionOnDrag && panOnDragActive !== true)
|
||||
);
|
||||
let hasActiveSelection = $derived(
|
||||
@@ -76,19 +77,7 @@
|
||||
|
||||
// Used to prevent click events when the user lets go of the selectionKey during a selection
|
||||
let selectionInProgress = false;
|
||||
|
||||
function onClick(event: MouseEvent) {
|
||||
// We prevent click events when the user let go of the selectionKey during a selection
|
||||
// We also prevent click events when a connection is in progress
|
||||
if (selectionInProgress || store.connection.inProgress) {
|
||||
selectionInProgress = false;
|
||||
return;
|
||||
}
|
||||
|
||||
onpaneclick?.({ event });
|
||||
store.unselectNodesAndEdges();
|
||||
store.selectionRectMode = null;
|
||||
}
|
||||
let selectionStarted = false;
|
||||
|
||||
// We start the selection process when the user clicks down on the pane
|
||||
function onPointerDownCapture(event: PointerEvent) {
|
||||
@@ -114,14 +103,12 @@
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
(event.target as Partial<Element>)?.setPointerCapture?.(event.pointerId);
|
||||
|
||||
const { x, y } = getEventPosition(event, containerBounds);
|
||||
selectionStarted = true;
|
||||
selectionInProgress = false;
|
||||
|
||||
store.unselectNodesAndEdges();
|
||||
const { x, y } = getEventPosition(event, containerBounds);
|
||||
|
||||
store.selectionRect = {
|
||||
width: 0,
|
||||
@@ -132,7 +119,14 @@
|
||||
y
|
||||
};
|
||||
|
||||
onselectionstart?.(event);
|
||||
if (event.target !== container || paneClickDistance === 0) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
store.unselectNodesAndEdges();
|
||||
|
||||
onselectionstart?.(event);
|
||||
}
|
||||
}
|
||||
|
||||
function onPointerMove(event: PointerEvent) {
|
||||
@@ -140,11 +134,23 @@
|
||||
return;
|
||||
}
|
||||
|
||||
selectionInProgress = true;
|
||||
|
||||
const mousePos = getEventPosition(event, containerBounds);
|
||||
const { startX = 0, startY = 0 } = store.selectionRect;
|
||||
|
||||
if (
|
||||
!selectionInProgress &&
|
||||
event.target === container &&
|
||||
!store.selectionKeyPressed &&
|
||||
paneClickDistance > 0
|
||||
) {
|
||||
const distance = Math.hypot(mousePos.x - startX, mousePos.y - startY);
|
||||
if (distance <= paneClickDistance) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
selectionInProgress = true;
|
||||
|
||||
const nextUserSelectRect = {
|
||||
...store.selectionRect,
|
||||
x: mousePos.x < startX ? mousePos.x : startX,
|
||||
@@ -195,7 +201,7 @@
|
||||
}
|
||||
|
||||
function onPointerUp(event: PointerEvent) {
|
||||
if (event.button !== 0) {
|
||||
if (event.button !== 0 || !selectionStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,22 +209,20 @@
|
||||
|
||||
// We only want to trigger click functions when in selection mode if
|
||||
// the user did not move the mouse.
|
||||
if (!isSelecting && store.selectionRectMode === 'user' && event.target === container) {
|
||||
|
||||
if (!selectionInProgress && event.target === container) {
|
||||
onClick?.(event);
|
||||
}
|
||||
|
||||
store.selectionRect = null;
|
||||
|
||||
if (selectedNodeIds.size > 0) {
|
||||
if (selectionInProgress && selectedNodeIds.size > 0) {
|
||||
store.selectionRectMode = 'nodes';
|
||||
}
|
||||
|
||||
// If the user kept holding the selectionKey during the selection,
|
||||
// we need to reset the selectionInProgress, so the next click event is not prevented
|
||||
if (store.selectionKeyPressed) {
|
||||
selectionInProgress = false;
|
||||
}
|
||||
|
||||
onselectionend?.(event);
|
||||
|
||||
selectionStarted = false;
|
||||
}
|
||||
|
||||
const onContextMenu = (event: MouseEvent) => {
|
||||
@@ -231,17 +235,25 @@
|
||||
};
|
||||
|
||||
const onClickCapture = (event: MouseEvent) => {
|
||||
const isSelectionActive =
|
||||
(selectionOnDrag && container === event.target) ||
|
||||
!selectionOnDrag ||
|
||||
store.selectionKeyPressed;
|
||||
if (selectionInProgress) {
|
||||
event.stopPropagation();
|
||||
selectionInProgress = false;
|
||||
}
|
||||
};
|
||||
|
||||
if (!isSelectionActive) {
|
||||
function onClick(event: MouseEvent) {
|
||||
// We prevent click events when the user let go of the selectionKey during a selection
|
||||
// We also prevent click events when a connection is in progress
|
||||
if (selectionInProgress || store.connection.inProgress) {
|
||||
selectionInProgress = false;
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
};
|
||||
onpaneclick?.({ event });
|
||||
store.unselectNodesAndEdges();
|
||||
store.selectionRectMode = null;
|
||||
store.selectionRect = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
|
||||
Reference in New Issue
Block a user