refactor(figma-controls): update prop names and types

This commit is contained in:
moklick
2022-12-08 21:08:45 +01:00
parent badacf763b
commit 57064ff096
8 changed files with 81 additions and 66 deletions
@@ -6,6 +6,7 @@ import ReactFlow, {
Edge, Edge,
useReactFlow, useReactFlow,
useKeyPress, useKeyPress,
SelectionMode,
} from 'reactflow'; } from 'reactflow';
const MULTI_SELECT_KEY = ['Meta', 'Shift']; const MULTI_SELECT_KEY = ['Meta', 'Shift'];
@@ -26,6 +27,8 @@ const defaultEdgeOptions = { zIndex: 0 };
const logEvent = (e: any) => console.log(e); const logEvent = (e: any) => console.log(e);
const onPaneClick = (e: any) => console.log('click pane', e);
const BasicFlow = () => { const BasicFlow = () => {
const instance = useReactFlow(); const instance = useReactFlow();
const spaceBarPressed = useKeyPress('Space'); const spaceBarPressed = useKeyPress('Space');
@@ -60,8 +63,8 @@ const BasicFlow = () => {
<ReactFlow <ReactFlow
defaultNodes={initialNodes} defaultNodes={initialNodes}
defaultEdges={initialEdges} defaultEdges={initialEdges}
selectBoxOnDrag selectionOnDrag
selectBoxMode="Overlap" selectionMode={SelectionMode.Overlap}
panOnDrag={spaceBarPressed ? true : 'RightClick'} panOnDrag={spaceBarPressed ? true : 'RightClick'}
panOnScroll panOnScroll
onPaneContextMenu={logEvent} onPaneContextMenu={logEvent}
@@ -70,6 +73,7 @@ const BasicFlow = () => {
className="react-flow-basic-example" className="react-flow-basic-example"
minZoom={0.2} minZoom={0.2}
maxZoom={4} maxZoom={4}
onPaneClick={onPaneClick}
fitView fitView
defaultEdgeOptions={defaultEdgeOptions} defaultEdgeOptions={defaultEdgeOptions}
selectNodesOnDrag={false} selectNodesOnDrag={false}
@@ -2,7 +2,7 @@
* The user selection rectangle gets displayed when a user drags the mouse while pressing shift * The user selection rectangle gets displayed when a user drags the mouse while pressing shift
*/ */
import { memo, useState, useRef } from 'react'; import { memo, useState, useRef, MouseEvent as ReactMouseEvent } from 'react';
import shallow from 'zustand/shallow'; import shallow from 'zustand/shallow';
import cc from 'classcat'; import cc from 'classcat';
@@ -10,7 +10,8 @@ import { containerStyle } from '../../styles';
import { useStore, useStoreApi } from '../../hooks/useStore'; import { useStore, useStoreApi } from '../../hooks/useStore';
import { getSelectionChanges } from '../../utils/changes'; import { getSelectionChanges } from '../../utils/changes';
import { getConnectedEdges, getNodesInside } from '../../utils/graph'; import { getConnectedEdges, getNodesInside } from '../../utils/graph';
import type { XYPosition, ReactFlowState, NodeChange, EdgeChange, Rect, ReactFlowProps } from '../../types'; import { SelectionMode } from '../../types';
import type { XYPosition, ReactFlowState, NodeChange, EdgeChange, Rect } from '../../types';
type SelectionRect = Rect & { type SelectionRect = Rect & {
startX: number; startX: number;
@@ -21,19 +22,20 @@ type EventHandlers = { [key: string]: React.MouseEventHandler | React.WheelEvent
type UserSelectionProps = { type UserSelectionProps = {
isSelectionMode: boolean; isSelectionMode: boolean;
selectBoxMode?: ReactFlowProps['selectBoxMode']; selectionMode?: SelectionMode;
onSelectionStart?: (e: React.MouseEvent) => void; panOnDrag?: boolean | 'RightClick';
onSelectionEnd?: (e: React.MouseEvent) => void; onSelectionStart?: (e: ReactMouseEvent) => void;
onClick?: (e: React.MouseEvent) => void; onSelectionEnd?: (e: ReactMouseEvent) => void;
onContextMenu?: (e: React.MouseEvent) => void; onPaneClick?: (e: ReactMouseEvent) => void;
onWheel?: (e: React.WheelEvent) => void; onPaneContextMenu?: (e: ReactMouseEvent) => void;
onMouseEnter?: (e: React.MouseEvent) => void; onPaneScroll?: (e: React.WheelEvent) => void;
onMouseMove?: (e: React.MouseEvent) => void; onPaneMouseEnter?: (e: ReactMouseEvent) => void;
onMouseLeave?: (e: React.MouseEvent) => void; onPaneMouseMove?: (e: ReactMouseEvent) => void;
onPaneMouseLeave?: (e: ReactMouseEvent) => void;
children: React.ReactNode; children: React.ReactNode;
}; };
function getMousePosition(event: React.MouseEvent, containerBounds: DOMRect): XYPosition { function getMousePosition(event: ReactMouseEvent, containerBounds: DOMRect): XYPosition {
return { return {
x: event.clientX - containerBounds.left, x: event.clientX - containerBounds.left,
y: event.clientY - containerBounds.top, y: event.clientY - containerBounds.top,
@@ -44,7 +46,7 @@ const wrapHandler = (
handler: React.MouseEventHandler | undefined, handler: React.MouseEventHandler | undefined,
containerRef: React.MutableRefObject<HTMLDivElement | null> containerRef: React.MutableRefObject<HTMLDivElement | null>
): React.MouseEventHandler => { ): React.MouseEventHandler => {
return (event: React.MouseEvent) => { return (event: ReactMouseEvent) => {
if (event.target !== containerRef.current) { if (event.target !== containerRef.current) {
return; return;
} }
@@ -67,15 +69,16 @@ const selector = (s: ReactFlowState) => ({
const UserSelection = memo( const UserSelection = memo(
({ ({
isSelectionMode, isSelectionMode,
selectBoxMode = 'Contained', selectionMode = SelectionMode.Contained,
panOnDrag,
onSelectionStart, onSelectionStart,
onSelectionEnd, onSelectionEnd,
onClick, onPaneClick,
onContextMenu, onPaneContextMenu,
onWheel, onPaneScroll,
onMouseEnter: onPaneMouseEnter, onPaneMouseEnter,
onMouseMove: onPaneMouseMove, onPaneMouseMove,
onMouseLeave: onPaneMouseLeave, onPaneMouseLeave,
children, children,
}: UserSelectionProps) => { }: UserSelectionProps) => {
const container = useRef<HTMLDivElement | null>(null); const container = useRef<HTMLDivElement | null>(null);
@@ -95,7 +98,24 @@ const UserSelection = memo(
prevSelectedEdgesCount.current = 0; prevSelectedEdgesCount.current = 0;
}; };
const onMouseDown = (event: React.MouseEvent): void => { const onClick = (event: ReactMouseEvent) => {
onPaneClick?.(event);
store.getState().resetSelectedElements();
store.setState({ nodesSelectionActive: false });
};
const onContextMenu = (event: ReactMouseEvent) => {
if (panOnDrag === 'RightClick') {
event.preventDefault();
return;
}
onPaneContextMenu?.(event);
};
const onWheel = onPaneScroll ? (event: React.WheelEvent) => onPaneScroll(event) : undefined;
const onMouseDown = (event: ReactMouseEvent): void => {
if (!elementsSelectable || !isSelectionMode || event.button !== 0 || event.target !== container.current) { if (!elementsSelectable || !isSelectionMode || event.button !== 0 || event.target !== container.current) {
return; return;
} }
@@ -119,7 +139,7 @@ const UserSelection = memo(
onSelectionStart?.(event); onSelectionStart?.(event);
}; };
const onMouseMove = (event: React.MouseEvent): void => { const onMouseMove = (event: ReactMouseEvent): void => {
if (!isSelectionMode || !containerBounds.current || !userSelectionRect) { if (!isSelectionMode || !containerBounds.current || !userSelectionRect) {
return; return;
} }
@@ -144,7 +164,7 @@ const UserSelection = memo(
nodeInternals, nodeInternals,
nextUserSelectRect, nextUserSelectRect,
transform, transform,
selectBoxMode === 'Overlap', selectionMode === SelectionMode.Overlap,
true, true,
nodeOrigin nodeOrigin
); );
@@ -170,7 +190,7 @@ const UserSelection = memo(
setUserSelectionRect(nextUserSelectRect); setUserSelectionRect(nextUserSelectRect);
}; };
const onMouseUp = (event: React.MouseEvent) => { const onMouseUp = (event: ReactMouseEvent) => {
// 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 && userSelectionRect && event.target === container.current) {
@@ -184,7 +204,7 @@ const UserSelection = memo(
onSelectionEnd?.(event); onSelectionEnd?.(event);
}; };
const onMouseLeave = (event: React.MouseEvent) => { const onMouseLeave = (event: ReactMouseEvent) => {
if (userSelectionActive) { if (userSelectionActive) {
store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 }); store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 });
onSelectionEnd?.(event); onSelectionEnd?.(event);
@@ -43,8 +43,8 @@ const FlowRenderer = ({
onMoveStart, onMoveStart,
onMoveEnd, onMoveEnd,
selectionKeyCode, selectionKeyCode,
selectBoxOnDrag, selectionOnDrag,
selectBoxMode, selectionMode,
onSelectionStart, onSelectionStart,
onSelectionEnd, onSelectionEnd,
multiSelectionKeyCode, multiSelectionKeyCode,
@@ -67,29 +67,13 @@ const FlowRenderer = ({
noPanClassName, noPanClassName,
disableKeyboardA11y, disableKeyboardA11y,
}: FlowRendererProps) => { }: FlowRendererProps) => {
const store = useStoreApi();
const nodesSelectionActive = useStore(selector); const nodesSelectionActive = useStore(selector);
const selectionKeyPressed = useKeyPress(selectionKeyCode); const selectionKeyPressed = useKeyPress(selectionKeyCode);
const isSelectionMode = selectionKeyPressed || (selectBoxOnDrag && panOnDrag !== true); const isSelectionMode = selectionKeyPressed || (selectionOnDrag && panOnDrag !== true);
useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode }); useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode });
const onClick = (event: MouseEvent) => {
onPaneClick?.(event);
store.getState().resetSelectedElements();
store.setState({ nodesSelectionActive: false });
};
const onContextMenu = (event: MouseEvent) => {
if (panOnDrag === 'RightClick') {
event.preventDefault();
} else {
onPaneContextMenu?.(event);
}
};
const onWheel = onPaneScroll ? (event: WheelEvent) => onPaneScroll(event) : undefined;
return ( return (
<ZoomPane <ZoomPane
onMove={onMove} onMove={onMove}
@@ -116,14 +100,15 @@ const FlowRenderer = ({
<UserSelection <UserSelection
onSelectionStart={onSelectionStart} onSelectionStart={onSelectionStart}
onSelectionEnd={onSelectionEnd} onSelectionEnd={onSelectionEnd}
onClick={onClick} onPaneClick={onPaneClick}
onMouseEnter={onPaneMouseEnter} onPaneMouseEnter={onPaneMouseEnter}
onMouseMove={onPaneMouseMove} onPaneMouseMove={onPaneMouseMove}
onMouseLeave={onPaneMouseLeave} onPaneMouseLeave={onPaneMouseLeave}
onContextMenu={onContextMenu} onPaneContextMenu={onPaneContextMenu}
onWheel={onWheel} onPaneScroll={onPaneScroll}
panOnDrag={panOnDrag}
isSelectionMode={!!isSelectionMode} isSelectionMode={!!isSelectionMode}
selectBoxMode={selectBoxMode} selectionMode={selectionMode}
> >
{children} {children}
{nodesSelectionActive && ( {nodesSelectionActive && (
@@ -58,8 +58,8 @@ const GraphView = ({
connectionLineComponent, connectionLineComponent,
connectionLineContainerStyle, connectionLineContainerStyle,
selectionKeyCode, selectionKeyCode,
selectBoxOnDrag, selectionOnDrag,
selectBoxMode, selectionMode,
multiSelectionKeyCode, multiSelectionKeyCode,
zoomActivationKeyCode, zoomActivationKeyCode,
deleteKeyCode, deleteKeyCode,
@@ -114,8 +114,8 @@ const GraphView = ({
onPaneScroll={onPaneScroll} onPaneScroll={onPaneScroll}
deleteKeyCode={deleteKeyCode} deleteKeyCode={deleteKeyCode}
selectionKeyCode={selectionKeyCode} selectionKeyCode={selectionKeyCode}
selectBoxOnDrag={selectBoxOnDrag} selectionOnDrag={selectionOnDrag}
selectBoxMode={selectBoxMode} selectionMode={selectionMode}
onSelectionStart={onSelectionStart} onSelectionStart={onSelectionStart}
onSelectionEnd={onSelectionEnd} onSelectionEnd={onSelectionEnd}
multiSelectionKeyCode={multiSelectionKeyCode} multiSelectionKeyCode={multiSelectionKeyCode}
@@ -17,7 +17,7 @@ import GraphView from '../GraphView';
import Wrapper from './Wrapper'; import Wrapper from './Wrapper';
import { infiniteExtent } from '../../store/initialState'; import { infiniteExtent } from '../../store/initialState';
import { useNodeOrEdgeTypes } from './utils'; import { useNodeOrEdgeTypes } from './utils';
import { ConnectionLineType, ConnectionMode, PanOnScrollMode } from '../../types'; import { ConnectionLineType, ConnectionMode, PanOnScrollMode, SelectionMode } from '../../types';
import type { import type {
EdgeTypes, EdgeTypes,
EdgeTypesWrapped, EdgeTypesWrapped,
@@ -101,8 +101,8 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
connectionLineContainerStyle, connectionLineContainerStyle,
deleteKeyCode = 'Backspace', deleteKeyCode = 'Backspace',
selectionKeyCode = 'Shift', selectionKeyCode = 'Shift',
selectBoxOnDrag = false, selectionOnDrag = false,
selectBoxMode = 'Contained', selectionMode = SelectionMode.Contained,
multiSelectionKeyCode = 'Meta', multiSelectionKeyCode = 'Meta',
zoomActivationKeyCode = 'Meta', zoomActivationKeyCode = 'Meta',
snapToGrid = false, snapToGrid = false,
@@ -197,8 +197,8 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
connectionLineComponent={connectionLineComponent} connectionLineComponent={connectionLineComponent}
connectionLineContainerStyle={connectionLineContainerStyle} connectionLineContainerStyle={connectionLineContainerStyle}
selectionKeyCode={selectionKeyCode} selectionKeyCode={selectionKeyCode}
selectBoxOnDrag={selectBoxOnDrag} selectionOnDrag={selectionOnDrag}
selectBoxMode={selectBoxMode} selectionMode={selectionMode}
deleteKeyCode={deleteKeyCode} deleteKeyCode={deleteKeyCode}
multiSelectionKeyCode={multiSelectionKeyCode} multiSelectionKeyCode={multiSelectionKeyCode}
zoomActivationKeyCode={zoomActivationKeyCode} zoomActivationKeyCode={zoomActivationKeyCode}
@@ -21,7 +21,7 @@ type ZoomPaneProps = Omit<
| 'multiSelectionKeyCode' | 'multiSelectionKeyCode'
| 'noDragClassName' | 'noDragClassName'
| 'disableKeyboardA11y' | 'disableKeyboardA11y'
| 'selectBoxOnDrag' | 'selectionOnDrag'
>; >;
const viewChanged = (prevViewport: Viewport, eventViewport: any): boolean => const viewChanged = (prevViewport: Viewport, eventViewport: any): boolean =>
+3 -2
View File
@@ -35,6 +35,7 @@ import type {
NodeOrigin, NodeOrigin,
EdgeMouseHandler, EdgeMouseHandler,
HandleType, HandleType,
SelectionMode,
} from '.'; } from '.';
export type ReactFlowProps = HTMLAttributes<HTMLDivElement> & { export type ReactFlowProps = HTMLAttributes<HTMLDivElement> & {
@@ -96,8 +97,8 @@ export type ReactFlowProps = HTMLAttributes<HTMLDivElement> & {
connectionMode?: ConnectionMode; connectionMode?: ConnectionMode;
deleteKeyCode?: KeyCode | null; deleteKeyCode?: KeyCode | null;
selectionKeyCode?: KeyCode | null; selectionKeyCode?: KeyCode | null;
selectBoxOnDrag?: boolean; selectionOnDrag?: boolean;
selectBoxMode?: 'Overlap' | 'Contained'; selectionMode?: SelectionMode;
multiSelectionKeyCode?: KeyCode | null; multiSelectionKeyCode?: KeyCode | null;
zoomActivationKeyCode?: KeyCode | null; zoomActivationKeyCode?: KeyCode | null;
snapToGrid?: boolean; snapToGrid?: boolean;
+6 -1
View File
@@ -3,7 +3,7 @@ import type { MouseEvent as ReactMouseEvent, ComponentType, MemoExoticComponent
import type { D3DragEvent, Selection as D3Selection, SubjectPosition, ZoomBehavior } from 'd3'; import type { D3DragEvent, Selection as D3Selection, SubjectPosition, ZoomBehavior } from 'd3';
import type { XYPosition, Rect, Transform, CoordinateExtent } from './utils'; import type { XYPosition, Rect, Transform, CoordinateExtent } from './utils';
import type { NodeChange, EdgeChange, NodePositionChange } from './changes'; import type { NodeChange, EdgeChange } from './changes';
import type { import type {
Node, Node,
NodeInternals, NodeInternals,
@@ -248,3 +248,8 @@ export type ProOptions = {
}; };
export type UseDragEvent = D3DragEvent<HTMLDivElement, null, SubjectPosition>; export type UseDragEvent = D3DragEvent<HTMLDivElement, null, SubjectPosition>;
export enum SelectionMode {
Overlap = 'overlap',
Contained = 'contained',
}