Skip to content

Commit

Permalink
Hooks API (#1244)
Browse files Browse the repository at this point in the history
* feat: initial hooks experiment

* fix: get chess example working

* fix: ts issues

* refactor: break out hook definitions (WIP)

Also, creating new interfaces for DragSource, DropTarget specification interfaces

* refactor: add component arg for now (investigating)

* refactor: remove styled-components from examples

* refactor: break up useDragSource/useDropTarget hooks

* refactor: use react.fc instead of react.sfc

* fix: update documentation examples peerdeps

* fix: use local links for react/react-dnd to resolve hooks issues

* fix: update useDragSource, usedropTarget

* refactor: simplify the public dnd hooks

* feat: migrate customDragLayer example to hooks

* fix: update the customDragLayer example

* refactor: update some dnd-core interfaces to use identifier

* fix: html5 backend
  • Loading branch information
darthtrevino committed Mar 7, 2019
1 parent 20ded76 commit 3b19a79
Show file tree
Hide file tree
Showing 55 changed files with 734 additions and 1,025 deletions.
3 changes: 2 additions & 1 deletion packages/dnd-core/src/actions/dragDrop/drop.ts
Expand Up @@ -4,6 +4,7 @@ import {
DropPayload,
DragDropMonitor,
HandlerRegistry,
Identifier,
} from '../../interfaces'
import { DROP } from './types'

Expand Down Expand Up @@ -44,7 +45,7 @@ function verifyInvariants(monitor: DragDropMonitor) {
}

function determineDropResult(
targetId: string,
targetId: Identifier,
index: number,
registry: HandlerRegistry,
monitor: DragDropMonitor,
Expand Down
62 changes: 31 additions & 31 deletions packages/dnd-core/src/interfaces.ts
Expand Up @@ -28,21 +28,21 @@ export interface DragDropMonitor {
subscribeToStateChange(
listener: Listener,
options?: {
handlerIds: string[] | undefined
handlerIds: Identifier[] | undefined
},
): Unsubscribe
subscribeToOffsetChange(listener: Listener): Unsubscribe
canDragSource(sourceId: string | undefined): boolean
canDropOnTarget(targetId: string | undefined): boolean
canDragSource(sourceId: Identifier | undefined): boolean
canDropOnTarget(targetId: Identifier | undefined): boolean

/**
* Returns true if a drag operation is in progress, and either the owner initiated the drag, or its isDragging()
* is defined and returns true.
*/
isDragging(): boolean
isDraggingSource(sourceId: string): boolean
isDraggingSource(sourceId: Identifier | undefined): boolean
isOverTarget(
targetId: string,
targetId: Identifier | undefined,
options?: {
shallow?: boolean
},
Expand All @@ -58,8 +58,8 @@ export interface DragDropMonitor {
* from its beginDrag() method. Returns null if no item is being dragged.
*/
getItem(): any
getSourceId(): string | null
getTargetIds(): string[]
getSourceId(): Identifier | null
getTargetIds(): Identifier[]
/**
* Returns a plain object representing the last recorded drop result. The drop targets may optionally specify it by returning an
* object from their drop() methods. When a chain of drop() is dispatched for the nested targets, bottom up, any parent that
Expand Down Expand Up @@ -105,27 +105,27 @@ export interface DragDropMonitor {
}

export interface HandlerRegistry {
addSource(type: SourceType, source: DragSource): string
addTarget(type: TargetType, target: DropTarget): string
addSource(type: SourceType, source: DragSource): Identifier
addTarget(type: TargetType, target: DropTarget): Identifier
containsHandler(handler: DragSource | DropTarget): boolean
getSource(sourceId: string, includePinned?: boolean): DragSource
getSourceType(sourceId: string): SourceType
getTargetType(targetId: string): TargetType
getTarget(targetId: string): DropTarget
isSourceId(handlerId: string): boolean
isTargetId(handlerId: string): boolean
removeSource(sourceId: string): void
removeTarget(targetId: string): void
pinSource(sourceId: string): void
getSource(sourceId: Identifier, includePinned?: boolean): DragSource
getSourceType(sourceId: Identifier): SourceType
getTargetType(targetId: Identifier): TargetType
getTarget(targetId: Identifier): DropTarget
isSourceId(handlerId: Identifier): boolean
isTargetId(handlerId: Identifier): boolean
removeSource(sourceId: Identifier): void
removeTarget(targetId: Identifier): void
pinSource(sourceId: Identifier): void
unpinSource(): void
}

export interface Action<Payload> {
type: string
type: Identifier
payload: Payload
}
export interface SentinelAction {
type: string
type: Identifier
}

export type ActionCreator<Payload> = (args: any[]) => Action<Payload>
Expand Down Expand Up @@ -164,17 +164,17 @@ export interface DropPayload {
}

export interface TargetIdPayload {
targetId: string
targetId: Identifier
}

export interface SourceIdPayload {
sourceId: string
sourceId: Identifier
}

export interface DragDropActions {
beginDrag(sourceIds: string[], options?: any): Action<BeginDragPayload>
beginDrag(sourceIds: Identifier[], options?: any): Action<BeginDragPayload>
publishDragSource(): SentinelAction
hover(targetIds: string[], options?: any): Action<HoverPayload>
hover(targetIds: Identifier[], options?: any): Action<HoverPayload>
drop(options?: any): void
endDrag(): SentinelAction
}
Expand All @@ -191,14 +191,14 @@ export interface DragDropManager<Context> {
export type BackendFactory = (dragDropManager: DragDropManager<any>) => Backend

export interface DragSource {
beginDrag(monitor: DragDropMonitor, targetId: string): void
endDrag(monitor: DragDropMonitor, targetId: string): void
canDrag(monitor: DragDropMonitor, targetId: string): boolean
isDragging(monitor: DragDropMonitor, targetId: string): boolean
beginDrag(monitor: DragDropMonitor, targetId: Identifier): void
endDrag(monitor: DragDropMonitor, targetId: Identifier): void
canDrag(monitor: DragDropMonitor, targetId: Identifier): boolean
isDragging(monitor: DragDropMonitor, targetId: Identifier): boolean
}

export interface DropTarget {
canDrop(monitor: DragDropMonitor, targetId: string): boolean
hover(monitor: DragDropMonitor, targetId: string): void
drop(monitor: DragDropMonitor, targetId: string): any
canDrop(monitor: DragDropMonitor, targetId: Identifier): boolean
hover(monitor: DragDropMonitor, targetId: Identifier): void
drop(monitor: DragDropMonitor, targetId: Identifier): any
}
11 changes: 5 additions & 6 deletions packages/documentation-examples/package.json
Expand Up @@ -21,27 +21,26 @@
"dependencies": {
"@types/faker": "^4.1.5",
"@types/query-string": "^6.2.0",
"@types/styled-components": "^4.1.12",
"dnd-core": "^7.1.0",
"faker": "^4.1.0",
"immutability-helper": "^3.0.0",
"lodash": "^4.17.11",
"query-string": "^6.3.0",
"react-dnd": "^7.1.0",
"react-dnd-html5-backend": "^7.1.0",
"react-frame-component": "^4.1.0",
"styled-components": "^4.1.3"
"react-frame-component": "^4.1.0"
},
"devDependencies": {
"@types/react": "^16.8.7",
"@types/react-dom": "^16.8.2",
"npm-run-all": "^4.1.5",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react": "link:../react-dnd/node_modules/react",
"react-dom": "link:../react-dnd/node_modules/react-dom",
"rimraf": "^2.6.3",
"typescript": "^3.3.3333"
},
"peerDependencies": {
"react": ">= 16.3"
"react": ">= 16.8.4",
"react-dom": ">= 16.8.4"
}
}
26 changes: 14 additions & 12 deletions packages/documentation-examples/src/00 Chessboard/Board.tsx
@@ -1,27 +1,29 @@
import * as React from 'react'
import styled from 'styled-components'
import BoardSquare from './BoardSquare'
import Knight from './Knight'

import { BoardSquare } from './BoardSquare'
import { Knight } from './Knight'
export interface BoardProps {
knightPosition: [number, number]
}

const Container = styled.div`
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
`

export default class Board extends React.Component<BoardProps> {
public render() {
const squares = []
for (let i = 0; i < 64; i += 1) {
squares.push(this.renderSquare(i))
}

return <Container>{squares}</Container>
return (
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
flexWrap: 'wrap',
}}
>
{squares}
</div>
)
}

private renderSquare(i: number) {
Expand Down
83 changes: 29 additions & 54 deletions packages/documentation-examples/src/00 Chessboard/BoardSquare.tsx
@@ -1,68 +1,43 @@
import * as React from 'react'
import {
DropTarget,
DropTargetMonitor,
DropTargetConnector,
DropTargetCollector,
ConnectDropTarget,
} from 'react-dnd'
import Square from './Square'
import { useDropTarget } from 'react-dnd'
import { Square } from './Square'
import { canMoveKnight, moveKnight } from './Game'
import ItemTypes from './ItemTypes'
import Overlay from './Overlay'

interface CollectedProps {
isOver: boolean
canDrop: boolean
connectDropTarget: ConnectDropTarget
}
export interface BoardSquareProps {
x: number
y: number
children: any
}

const squareTarget = {
canDrop(props: BoardSquareProps) {
return canMoveKnight(props.x, props.y)
},

drop(props: BoardSquareProps) {
moveKnight(props.x, props.y)
},
}

const collect: DropTargetCollector<CollectedProps> = (
connect: DropTargetConnector,
monitor: DropTargetMonitor,
export const BoardSquare: React.FC<BoardSquareProps> = (
props: BoardSquareProps,
) => {
return {
connectDropTarget: connect.dropTarget(),
isOver: !!monitor.isOver(),
canDrop: !!monitor.canDrop(),
}
}

class BoardSquare extends React.Component<BoardSquareProps & CollectedProps> {
public render() {
const { x, y, connectDropTarget, isOver, canDrop, children } = this.props
const black = (x + y) % 2 === 1
const ref = React.useRef(null)
const { isOver, canDrop } = useDropTarget(ref, ItemTypes.KNIGHT, {
canDrop: () => canMoveKnight(props.x, props.y),
drop: () => moveKnight(props.x, props.y),
collect: mon => ({
isOver: !!mon.isOver(),
canDrop: !!mon.canDrop(),
}),
})
const black = (props.x + props.y) % 2 === 1

return connectDropTarget(
<div
style={{
position: 'relative',
width: '100%',
height: '100%',
}}
>
<Square black={black}>{children}</Square>
{isOver && !canDrop && <Overlay color="red" />}
{!isOver && canDrop && <Overlay color="yellow" />}
{isOver && canDrop && <Overlay color="green" />}
</div>,
)
}
return (
<div
ref={ref}
style={{
position: 'relative',
width: '100%',
height: '100%',
}}
>
<Square black={black}>{props.children}</Square>
{isOver && !canDrop && <Overlay color="red" />}
{!isOver && canDrop && <Overlay color="yellow" />}
{isOver && canDrop && <Overlay color="green" />}
</div>
)
}

export default DropTarget(ItemTypes.KNIGHT, squareTarget, collect)(BoardSquare)

0 comments on commit 3b19a79

Please sign in to comment.