diff --git a/src/components/CanvasWidget.tsx b/src/components/CanvasWidget.tsx index f68f2de..7684b8d 100644 --- a/src/components/CanvasWidget.tsx +++ b/src/components/CanvasWidget.tsx @@ -1,12 +1,14 @@ import { makeStyles } from '@mui/styles'; import { Box } from '@mui/system'; -import { CanvasWidget as Canvas } from '@projectstorm/react-canvas-core'; +import { + CanvasWidget as Canvas, + CanvasEngine, +} from '@projectstorm/react-canvas-core'; import React, { useCallback } from 'react'; import { DropTargetMonitor, useDrop } from 'react-dnd'; import { CanvasDropTypes } from '../constants'; import vars from './assets/styles/variables'; import { INode, ISidebarNodeProps } from '../types/sidebar'; -import { DiagramEngine } from '@projectstorm/react-diagrams'; const useStyles = makeStyles(_ => ({ container: { @@ -23,7 +25,7 @@ const useStyles = makeStyles(_ => ({ const { canvasBg } = vars; interface ICanvasWidgetProps { - engine: DiagramEngine; + engine: CanvasEngine; className?: string; } @@ -40,11 +42,11 @@ export const CanvasWidget = ({ if (!!node.onNodeDrop) node?.onNodeDrop(monitor, node, engine); }, - [] + [engine] ); // can drop custom hook - const [{}, dropRef] = useDrop({ + const [, dropRef] = useDrop({ accept: CanvasDropTypes.CANVAS_NODE, // canDrop: () => true, drop: onDrop, diff --git a/src/components/sidebar/SidebarItem.tsx b/src/components/sidebar/SidebarItem.tsx index 058eade..4f7ea9e 100644 --- a/src/components/sidebar/SidebarItem.tsx +++ b/src/components/sidebar/SidebarItem.tsx @@ -29,7 +29,7 @@ export const SidebarItem = ({ selected, handleSelection, }: SidebarItemProps) => { - const [{}, dragRef, dragPreview] = useDrag( + const [, dragRef, dragPreview] = useDrag( () => ({ type: CanvasDropTypes.CANVAS_NODE, item: node, diff --git a/src/components/sidebar/SubSidebarItem.tsx b/src/components/sidebar/SubSidebarItem.tsx index 6d8c8ee..fa60096 100644 --- a/src/components/sidebar/SubSidebarItem.tsx +++ b/src/components/sidebar/SubSidebarItem.tsx @@ -13,7 +13,7 @@ export const SubSidebarItem = ({ selected, handleSelection, }: ISubSidebarItemProps) => { - const [{}, dragRef, dragPreview] = useDrag( + const [, dragRef, dragPreview] = useDrag( () => ({ type: CanvasDropTypes.CANVAS_NODE, item: node, diff --git a/src/components/sidebar/SubSiderBar.tsx b/src/components/sidebar/SubSiderBar.tsx index 602f89b..b210c1d 100644 --- a/src/components/sidebar/SubSiderBar.tsx +++ b/src/components/sidebar/SubSiderBar.tsx @@ -11,7 +11,7 @@ export const SubSiderBar = ({ nodes, show = false }: ISubSidebar) => { return ( <> - + {nodes.map(node => ( diff --git a/src/index.tsx b/src/index.tsx index ae0e2b6..3f2b541 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -6,7 +6,7 @@ import { MetaPort } from './models/MetaPort'; import CssBaseline from '@mui/material/CssBaseline'; import { ComponentsMap } from './models/ComponentsMap'; import { LinkModel, PortWidget } from '@projectstorm/react-diagrams'; -import { MetaNodeModel } from './react-diagrams/MetaNodeModel'; +import { MetaNodeModel, MetaPortModel } from './react-diagrams/MetaNodeModel'; import { MetaNodeFactory } from './react-diagrams/MetaNodeFactory'; import { MetaLinkFactory } from './react-diagrams/MetaLinkFactory'; import createEngine, { DiagramModel } from '@projectstorm/react-diagrams'; @@ -69,9 +69,11 @@ const MetaDiagram = forwardRef( ) => { const classes = useStyles(); const linkRef = React.useRef(); + const onMountRef = React.useRef(onMount); // initialize custom diagram state let state = new DefaultState(globalProps?.createLink); + state.isSelection = false; // Sets up the diagram engine @@ -94,7 +96,18 @@ const MetaDiagram = forwardRef( engine .getLinkFactories() // @ts-ignore - .registerFactory(new MetaLinkFactory(componentsMap.links)); + .registerFactory( + !!globalProps.CustomLinkFactory + ? new globalProps.CustomLinkFactory(componentsMap.links) + : new MetaLinkFactory(componentsMap.links) + ); + + if (!!globalProps.CustomPortFactory) { + engine + .getPortFactories() + // @ts-ignore + .registerFactory(new globalProps.CustomPortFactory()); + } // set up the diagram model const model = new DiagramModel(); @@ -193,10 +206,7 @@ const MetaDiagram = forwardRef( if (startsWithSelect && !Boolean(state.isSelection)) { state.isSelection = true; - } else if ( - state.isSelection || - (!startsWithSelect && Boolean(state.isSelection)) - ) { + } else if (Boolean(state.isSelection) || !startsWithSelect) { clearSelection(); state.isSelection = false; } @@ -227,13 +237,13 @@ const MetaDiagram = forwardRef( } useEffect(() => { - if (onMount === undefined) { - onMount = (engine: any) => { + if (onMountRef.current === undefined) { + onMountRef.current = (engine: any) => { console.log(engine); }; } - onMount(engine); - }, []); + onMountRef.current(engine); + }, [engine]); // expose api const addNode = (node: any) => { @@ -283,9 +293,21 @@ const MetaDiagram = forwardRef( ); export default MetaDiagram; -export { MetaNode, MetaLink, MetaPort, MetaNodeModel, ComponentsMap }; +export { + MetaNode, + MetaLink, + MetaPort, + MetaNodeModel, + ComponentsMap, + MetaPortModel, +}; export { PortWidget }; export { MetaLinkModel } from './react-diagrams/MetaLinkModel'; +export { MetaLinkFactory } from './react-diagrams/MetaLinkFactory'; export { PortTypes } from './constants'; export { CallbackTypes } from './constants'; -export { EventTypes, DefaultSidebarNodeTypes } from './constants'; +export { + EventTypes, + DefaultSidebarNodeTypes, + ReactDiagramMetaTypes, +} from './constants'; diff --git a/src/react-diagrams/MetaLinkFactory.tsx b/src/react-diagrams/MetaLinkFactory.tsx index 2b941fa..4180653 100644 --- a/src/react-diagrams/MetaLinkFactory.tsx +++ b/src/react-diagrams/MetaLinkFactory.tsx @@ -5,9 +5,9 @@ import React from 'react'; import { DefaultLinkFactory } from '@projectstorm/react-diagrams'; export class MetaLinkFactory extends DefaultLinkFactory { - componentsMap: Map; + componentsMap: Map; - constructor(componentsMap: Map) { + constructor(componentsMap: Map) { super(ReactDiagramMetaTypes.META_LINK); this.componentsMap = componentsMap; } diff --git a/src/react-diagrams/MetaNodeModel.ts b/src/react-diagrams/MetaNodeModel.ts index 9bf80af..cb2276d 100644 --- a/src/react-diagrams/MetaNodeModel.ts +++ b/src/react-diagrams/MetaNodeModel.ts @@ -3,6 +3,13 @@ import { PortTypes, ReactDiagramMetaTypes, CallbackTypes } from '../constants'; import { DefaultPortModel, NodeModel } from '@projectstorm/react-diagrams'; import { Point } from '@projectstorm/geometry'; import { subPoints } from '../utils'; +import { MetaLinkModel } from './MetaLinkModel'; + +export class MetaPortModel extends DefaultPortModel { + createLinkModel(): MetaLinkModel { + return new MetaLinkModel(); + } +} export class MetaNodeModel extends NodeModel { constructor(options = {}) { @@ -21,7 +28,7 @@ export class MetaNodeModel extends NodeModel { switch (port.getType()) { case PortTypes.INPUT_PORT: this.addPort( - new DefaultPortModel({ + new MetaPortModel({ in: true, name: port.getName(), }) @@ -29,7 +36,7 @@ export class MetaNodeModel extends NodeModel { break; case PortTypes.OUTPUT_PORT: this.addPort( - new DefaultPortModel({ + new MetaPortModel({ in: false, name: port.getName(), }) diff --git a/src/react-diagrams/state/CreateLinkState.ts b/src/react-diagrams/state/CreateLinkState.ts index a080915..54f7de3 100644 --- a/src/react-diagrams/state/CreateLinkState.ts +++ b/src/react-diagrams/state/CreateLinkState.ts @@ -64,7 +64,7 @@ export class CreateLinkState extends State { } else if ( element instanceof PortModel && this.sourcePort && - element != this.sourcePort + element !== this.sourcePort ) { if (this.sourcePort.canLinkToPort(element)) { if (!this.link) return; diff --git a/src/react-diagrams/state/DefaultState.ts b/src/react-diagrams/state/DefaultState.ts index 22989f0..05ca077 100644 --- a/src/react-diagrams/state/DefaultState.ts +++ b/src/react-diagrams/state/DefaultState.ts @@ -1,4 +1,4 @@ -import { MouseEvent } from 'react'; +import { MouseEvent, TouchEvent } from 'react'; import { SelectingState, State, @@ -27,7 +27,7 @@ export class DefaultState extends State { this.dragCanvas = new DragCanvasState(); this.dragItems = new DragDiagramItemsState(); this.createLink = customCreateLink ?? new CreateLinkState(); - this.isSelection = true; + this.isSelection = false; // determine what was clicked on this.registerAction( @@ -68,12 +68,29 @@ export class DefaultState extends State { if ( element instanceof PortModel || - element instanceof MetaNodeModel + (element instanceof MetaNodeModel && !this.isSelection) ) { this.transitionWithEvent(this.createLink, event); } }, }) ); + + // touch drags the canvas + this.registerAction( + new Action({ + type: InputType.TOUCH_START, + fire: (event: ActionEvent) => { + const element = this.engine + .getActionEventBus() + .getModelForEvent(event); + // the canvas was clicked on, transition to the dragging canvas state + if (!!this.dragCanvas.config.allowDrag && !element) { + this.transitionWithEvent(this.dragCanvas, event); + } + // this.transitionWithEvent(this.dragCanvas, event); + }, + }) + ); } }