React DND typescript support
I've got it working with the DT types package on 2.1. It doesn't compile with strictNullChecks and I haven't been able to track down the reason why. (When you decorate your components with @DragSource and @DropTarget, you somehow change the return type of the render function from Element to Element | null, but I can't see how.)
The other niggle is that all of the props that are inserted by the collecting function are undefined when you first instantiate your components in a render method, so your options are to pass a bunch of {undefined as any}
or else declare your collector-injected props as optionals and typeguard them out every where you look at them. Overall the type declaration file is not bad and I found the typing to be more helpful than harmful when getting to know the library.
import { ConnectDragSource, DragDropContext, DragSource, DragSourceSpec, DragSourceCollector, DragSourceConnector, DragSourceMonitor, DragElementWrapper, ConnectDropTarget, DropTarget, DropTargetConnector, DropTargetMonitor, ClientOffset, DropTargetSpec } from 'react-dnd';let HTML5Backend = require('react-dnd-html5-backend');import { AdjacencyMatrixGraph } from "Geometry/Graph";import * as React from "react";import * as Sauce from "Sauce";import * as ReactDOM from "react-dom";import * as $ from "jquery";import { Position2 } from "Geometry";import * as Rx from "rxjs";import * as Util from "Util";require("./GraphBuilder.scss");interface NodeProps { label?: string; position: ClientOffset;}/* New node from the node well */export interface NodeSourceProps { isDragging : boolean; connectDragSource: ConnectDragSource;}export interface NodeSourceState {}// Spec: drag events to handle.let nodeSourceSpec: DragSourceSpec<NodeSourceProps> = { beginDrag: (props: NodeSourceProps) => ({}),};// Collect: Put drag state into propslet nodeSourceCollector = (connect: DragSourceConnector, monitor: DragSourceMonitor) => { return { connectDragSource: connect.dragSource(), isDragging: monitor.isDragging() }};@DragSource("new-node", nodeSourceSpec, nodeSourceCollector)export class NodeSource extends React.Component<NodeSourceProps, NodeSourceState> { constructor(props: NodeSourceProps) { super(props); } render() { const { connectDragSource, isDragging } = this.props; return connectDragSource(<span className="node-source">{'\u2683'}</span>); }}/* main graph area */interface GraphCanvasProps { connectDropTarget: ConnectDropTarget, isOver: boolean, graph: AdjacencyMatrixGraph<NodeProps>;}interface GraphCanvasState {}const canvasDropTargetSpecification: DropTargetSpec<GraphCanvasProps> = { drop(props: GraphCanvasProps, monitor: DropTargetMonitor, component: React.Component<GraphCanvasProps, any>) { // console.log("Handling drop", print_monitor(monitor)); let pos = monitor.getSourceClientOffset(); if (monitor.getItemType() === "main-node-move") { let node = (monitor.getItem() as any); graph.setData(node.id, { position: pos }); } else if (monitor.getItemType() === "new-node") { graph.addNode("node-" + graph.order(), { position: pos }); } },};function canvasDropTargetCollectingFunction(connect: DropTargetConnector, monitor: DropTargetMonitor) { let rv = { connectDropTarget: connect.dropTarget(), isOver: monitor.isOver(), }; return rv;}/* ... here's a DropTarget ... */@DropTarget(["main-node-move", "new-node"], canvasDropTargetSpecification, canvasDropTargetCollectingFunction)export class GraphCanvas extends React.Component<GraphCanvasProps, GraphCanvasState> { constructor(props: GraphCanvasProps) { super(props); } render(): JSX.Element | null { const { connectDropTarget, graph } = this.props; let nodes = graph.nodes(); let nodeEls = Object.keys(nodes).map(k => { let node = nodes[k]; return <CanvasNode key={k} id={k} node={node} graph={graph} connectNodeDrop={null as any} connectMoveNodeDragger={(null)}/> }); return connectDropTarget(<div className="graph-canvas"> {nodeEls} </div>); }}/* ... Here's a the DragContext decorator ... */@DragDropContext(HTML5Backend)class Markov extends React.Component<MarkovProps, MarkovState> {