refactor(selection): make it possible to start a selection above a node #5342
This commit is contained in:
@@ -95,6 +95,8 @@ export function Pane({
|
||||
const selectionInProgress = useRef<boolean>(false);
|
||||
const selectionStarted = useRef<boolean>(false);
|
||||
|
||||
const isNoKeyEvent = useRef<boolean | null>(null);
|
||||
|
||||
const onClick = (event: ReactMouseEvent) => {
|
||||
// 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
|
||||
@@ -119,20 +121,40 @@ export function Pane({
|
||||
|
||||
const onWheel = onPaneScroll ? (event: React.WheelEvent) => onPaneScroll(event) : undefined;
|
||||
|
||||
const onMouseDownCapture = (event: ReactMouseEvent) => {
|
||||
isNoKeyEvent.current =
|
||||
isNoKeyEvent.current === null ? !!(event.target as HTMLElement).closest('.nokey') : isNoKeyEvent.current;
|
||||
|
||||
if (isNoKeyEvent.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
const onClickCapture = (event: ReactMouseEvent) => {
|
||||
if (isNoKeyEvent.current) {
|
||||
isNoKeyEvent.current = null;
|
||||
return;
|
||||
}
|
||||
|
||||
isNoKeyEvent.current = null;
|
||||
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
const onPointerDown = (event: ReactPointerEvent): void => {
|
||||
const { resetSelectedElements, domNode } = store.getState();
|
||||
containerBounds.current = domNode?.getBoundingClientRect();
|
||||
isNoKeyEvent.current =
|
||||
isNoKeyEvent.current === null ? !!(event.target as HTMLElement).closest('.nokey') : isNoKeyEvent.current;
|
||||
|
||||
if (
|
||||
!elementsSelectable ||
|
||||
!isSelecting ||
|
||||
event.button !== 0 ||
|
||||
event.target !== container.current ||
|
||||
!containerBounds.current
|
||||
) {
|
||||
if (!elementsSelectable || !isSelecting || event.button !== 0 || !containerBounds.current || isNoKeyEvent.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
(event.target as Partial<Element> | null)?.setPointerCapture?.(event.pointerId);
|
||||
|
||||
selectionStarted.current = true;
|
||||
@@ -234,7 +256,7 @@ export function Pane({
|
||||
|
||||
(event.target as Partial<Element>)?.releasePointerCapture?.(event.pointerId);
|
||||
const { userSelectionRect } = store.getState();
|
||||
|
||||
isNoKeyEvent.current = null;
|
||||
/*
|
||||
* We only want to trigger click functions when in selection mode if
|
||||
* the user did not move the mouse.
|
||||
@@ -270,9 +292,12 @@ export function Pane({
|
||||
onContextMenu={wrapHandler(onContextMenu, container)}
|
||||
onWheel={wrapHandler(onWheel, container)}
|
||||
onPointerEnter={hasActiveSelection ? undefined : onPaneMouseEnter}
|
||||
onPointerDown={hasActiveSelection ? onPointerDown : onPaneMouseMove}
|
||||
onPointerDown={hasActiveSelection ? undefined : onPaneMouseMove}
|
||||
onPointerMove={hasActiveSelection ? onPointerMove : onPaneMouseMove}
|
||||
onPointerUp={hasActiveSelection ? onPointerUp : undefined}
|
||||
onPointerDownCapture={hasActiveSelection ? onPointerDown : undefined}
|
||||
onMouseDownCapture={hasActiveSelection ? onMouseDownCapture : undefined}
|
||||
onClickCapture={hasActiveSelection ? onClickCapture : undefined}
|
||||
onPointerLeave={onPaneMouseLeave}
|
||||
ref={container}
|
||||
style={containerStyle}
|
||||
|
||||
@@ -43,7 +43,6 @@ export function isInputDOMNode(event: KeyboardEvent): boolean {
|
||||
if (target?.nodeType !== 1 /* Node.ELEMENT_NODE */) return false;
|
||||
|
||||
const isInput = inputTags.includes(target.nodeName) || target.hasAttribute('contenteditable');
|
||||
|
||||
// when an input field is focused we don't want to trigger deletion or movement of nodes
|
||||
return isInput || !!target.closest('.nokey');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user