Merge pull request #5573 from xyflow/chore/pane-cleanup
chore(pane): cleanup
This commit is contained in:
@@ -1,19 +1,15 @@
|
|||||||
import {
|
import {
|
||||||
useRef,
|
useRef,
|
||||||
|
type MouseEventHandler,
|
||||||
|
type MutableRefObject,
|
||||||
type MouseEvent as ReactMouseEvent,
|
type MouseEvent as ReactMouseEvent,
|
||||||
type PointerEvent as ReactPointerEvent,
|
type PointerEvent as ReactPointerEvent,
|
||||||
|
type WheelEvent as ReactWheelEvent,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
import {
|
import { getNodesInside, getEventPosition, SelectionMode, areSetsEqual } from '@xyflow/system';
|
||||||
getNodesInside,
|
|
||||||
getEventPosition,
|
|
||||||
SelectionMode,
|
|
||||||
areSetsEqual,
|
|
||||||
type NodeChange,
|
|
||||||
type EdgeChange,
|
|
||||||
} from '@xyflow/system';
|
|
||||||
|
|
||||||
import { UserSelection } from '../../components/UserSelection';
|
import { UserSelection } from '../../components/UserSelection';
|
||||||
import { containerStyle } from '../../styles/utils';
|
import { containerStyle } from '../../styles/utils';
|
||||||
@@ -44,9 +40,9 @@ type PaneProps = {
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
const wrapHandler = (
|
const wrapHandler = (
|
||||||
handler: React.MouseEventHandler | undefined,
|
handler: MouseEventHandler | undefined,
|
||||||
containerRef: React.MutableRefObject<HTMLDivElement | null>
|
containerRef: MutableRefObject<HTMLDivElement | null>
|
||||||
): React.MouseEventHandler => {
|
): MouseEventHandler => {
|
||||||
return (event: ReactMouseEvent) => {
|
return (event: ReactMouseEvent) => {
|
||||||
if (event.target !== containerRef.current) {
|
if (event.target !== containerRef.current) {
|
||||||
return;
|
return;
|
||||||
@@ -85,7 +81,6 @@ export function Pane({
|
|||||||
|
|
||||||
const container = useRef<HTMLDivElement | null>(null);
|
const container = useRef<HTMLDivElement | null>(null);
|
||||||
const containerBounds = useRef<DOMRect>();
|
const containerBounds = useRef<DOMRect>();
|
||||||
|
|
||||||
const selectedNodeIds = useRef<Set<string>>(new Set());
|
const selectedNodeIds = useRef<Set<string>>(new Set());
|
||||||
const selectedEdgeIds = useRef<Set<string>>(new Set());
|
const selectedEdgeIds = useRef<Set<string>>(new Set());
|
||||||
|
|
||||||
@@ -115,7 +110,7 @@ export function Pane({
|
|||||||
onPaneContextMenu?.(event);
|
onPaneContextMenu?.(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onWheel = onPaneScroll ? (event: React.WheelEvent) => onPaneScroll(event) : undefined;
|
const onWheel = onPaneScroll ? (event: ReactWheelEvent) => onPaneScroll(event) : undefined;
|
||||||
|
|
||||||
const onClickCapture = (event: ReactMouseEvent) => {
|
const onClickCapture = (event: ReactMouseEvent) => {
|
||||||
if (selectionInProgress.current) {
|
if (selectionInProgress.current) {
|
||||||
@@ -130,19 +125,16 @@ export function Pane({
|
|||||||
const { resetSelectedElements, domNode } = store.getState();
|
const { resetSelectedElements, domNode } = store.getState();
|
||||||
containerBounds.current = domNode?.getBoundingClientRect();
|
containerBounds.current = domNode?.getBoundingClientRect();
|
||||||
|
|
||||||
const isNoKeyEvent = event.target !== container.current && !!(event.target as HTMLElement).closest('.nokey');
|
if (!containerBounds.current) {
|
||||||
const isSelectionActive =
|
return;
|
||||||
(selectionOnDrag && container.current === event.target) || !selectionOnDrag || selectionKeyPressed;
|
}
|
||||||
|
|
||||||
if (
|
const eventTargetIsContainer = event.target === container.current;
|
||||||
!elementsSelectable ||
|
// if a child element has the 'nokey' class, we don't want to swallow the event and don't start a selection
|
||||||
!isSelecting ||
|
const isNoKeyEvent = !eventTargetIsContainer && !!(event.target as HTMLElement).closest('.nokey');
|
||||||
event.button !== 0 ||
|
const isSelectionActive = (selectionOnDrag && eventTargetIsContainer) || !selectionOnDrag || selectionKeyPressed;
|
||||||
!containerBounds.current ||
|
|
||||||
isNoKeyEvent ||
|
if (isNoKeyEvent || !isSelecting || !isSelectionActive || event.button !== 0 || !event.isPrimary) {
|
||||||
!isSelectionActive ||
|
|
||||||
!event.isPrimary
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +156,7 @@ export function Pane({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (event.target !== container.current || paneClickDistance === 0) {
|
if (!eventTargetIsContainer || paneClickDistance === 0) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@@ -242,12 +234,12 @@ export function Pane({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!areSetsEqual(prevSelectedNodeIds, selectedNodeIds.current)) {
|
if (!areSetsEqual(prevSelectedNodeIds, selectedNodeIds.current)) {
|
||||||
const changes = getSelectionChanges(nodeLookup, selectedNodeIds.current, true) as NodeChange[];
|
const changes = getSelectionChanges(nodeLookup, selectedNodeIds.current, true);
|
||||||
triggerNodeChanges(changes);
|
triggerNodeChanges(changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!areSetsEqual(prevSelectedEdgeIds, selectedEdgeIds.current)) {
|
if (!areSetsEqual(prevSelectedEdgeIds, selectedEdgeIds.current)) {
|
||||||
const changes = getSelectionChanges(edgeLookup, selectedEdgeIds.current) as EdgeChange[];
|
const changes = getSelectionChanges(edgeLookup, selectedEdgeIds.current);
|
||||||
triggerEdgeChanges(changes);
|
triggerEdgeChanges(changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,12 +257,11 @@ export function Pane({
|
|||||||
|
|
||||||
(event.target as Partial<Element>)?.releasePointerCapture?.(event.pointerId);
|
(event.target as Partial<Element>)?.releasePointerCapture?.(event.pointerId);
|
||||||
|
|
||||||
const { userSelectionRect } = store.getState();
|
|
||||||
/*
|
/*
|
||||||
* We only want to trigger click functions when in selection mode if
|
* We only want to trigger click functions when in selection mode if
|
||||||
* the user did not move the mouse.
|
* the user did not move the mouse.
|
||||||
*/
|
*/
|
||||||
if (!userSelectionActive && userSelectionRect && event.target === container.current) {
|
if (!userSelectionActive && event.target === container.current && store.getState().userSelectionRect) {
|
||||||
onClick?.(event);
|
onClick?.(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user