feat: allow customisation of how the select box works.

This commit is contained in:
Jack Fishwick
2022-11-22 11:05:45 +00:00
parent f25c7fe8a2
commit 09ebd0c84a
5 changed files with 18 additions and 2 deletions
@@ -8,7 +8,7 @@ import shallow from 'zustand/shallow';
import { useStore, useStoreApi } from '../../hooks/useStore';
import { getSelectionChanges } from '../../utils/changes';
import { getConnectedEdges, getNodesInside } from '../../utils/graph';
import type { XYPosition, ReactFlowState, NodeChange, EdgeChange, Rect } from '../../types';
import type { XYPosition, ReactFlowState, NodeChange, EdgeChange, Rect, ReactFlowProps } from '../../types';
type SelectionRect = Rect & {
startX: number;
@@ -19,6 +19,7 @@ type EventHandlers = { [key: string]: React.MouseEventHandler | React.WheelEvent
type UserSelectionProps = {
isSelectionMode: boolean;
selectBoxMode?: ReactFlowProps['selectBoxMode'];
onSelectionStart?: (e: React.MouseEvent) => void;
onSelectionEnd?: (e: React.MouseEvent) => void;
onClick?: (e: React.MouseEvent) => void;
@@ -60,6 +61,7 @@ const selector = (s: ReactFlowState) => ({
const UserSelection = memo(
({
isSelectionMode,
selectBoxMode = 'Contained',
onSelectionStart,
onSelectionEnd,
onClick,
@@ -130,7 +132,14 @@ const UserSelection = memo(
const { nodeInternals, edges, transform, onNodesChange, onEdgesChange, nodeOrigin } = store.getState();
const nodes = Array.from(nodeInternals.values());
const selectedNodes = getNodesInside(nodeInternals, nextUserSelectRect, transform, true, true, nodeOrigin);
const selectedNodes = getNodesInside(
nodeInternals,
nextUserSelectRect,
transform,
selectBoxMode === 'Overlap',
true,
nodeOrigin
);
const selectedEdgeIds = getConnectedEdges(selectedNodes, edges).map((e) => e.id);
const selectedNodeIds = selectedNodes.map((n) => n.id);
@@ -45,6 +45,7 @@ const FlowRenderer = ({
onMoveEnd,
selectionKeyCode,
selectBoxOnDrag,
selectBoxMode,
onSelectionStart,
onSelectionEnd,
multiSelectionKeyCode,
@@ -123,6 +124,7 @@ const FlowRenderer = ({
onContextMenu={onContextMenu}
onWheel={onWheel}
isSelectionMode={isSelectionMode}
selectBoxMode={selectBoxMode}
>
{children}
{nodesSelectionActive && (
@@ -59,6 +59,7 @@ const GraphView = ({
connectionLineContainerStyle,
selectionKeyCode,
selectBoxOnDrag,
selectBoxMode,
multiSelectionKeyCode,
zoomActivationKeyCode,
deleteKeyCode,
@@ -114,6 +115,7 @@ const GraphView = ({
deleteKeyCode={deleteKeyCode}
selectionKeyCode={selectionKeyCode}
selectBoxOnDrag={selectBoxOnDrag}
selectBoxMode={selectBoxMode}
onSelectionStart={onSelectionStart}
onSelectionEnd={onSelectionEnd}
multiSelectionKeyCode={multiSelectionKeyCode}
@@ -102,6 +102,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
deleteKeyCode = 'Backspace',
selectionKeyCode = 'Shift',
selectBoxOnDrag = false,
selectBoxMode = 'Contained',
multiSelectionKeyCode = 'Meta',
zoomActivationKeyCode = 'Meta',
snapToGrid = false,
@@ -197,6 +198,7 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
connectionLineContainerStyle={connectionLineContainerStyle}
selectionKeyCode={selectionKeyCode}
selectBoxOnDrag={selectBoxOnDrag}
selectBoxMode={selectBoxMode}
deleteKeyCode={deleteKeyCode}
multiSelectionKeyCode={multiSelectionKeyCode}
zoomActivationKeyCode={zoomActivationKeyCode}
@@ -97,6 +97,7 @@ export type ReactFlowProps = HTMLAttributes<HTMLDivElement> & {
deleteKeyCode?: KeyCode | null;
selectionKeyCode?: KeyCode | null;
selectBoxOnDrag?: boolean;
selectBoxMode?: 'Overlap' | 'Contained';
multiSelectionKeyCode?: KeyCode | null;
zoomActivationKeyCode?: KeyCode | null;
snapToGrid?: boolean;