diff --git a/types/react-dragtastic/index.d.ts b/types/react-dragtastic/index.d.ts new file mode 100644 index 0000000000..64ce099e2f --- /dev/null +++ b/types/react-dragtastic/index.d.ts @@ -0,0 +1,167 @@ +// Type definitions for react-dragtastic 2.4 +// Project: https://github.com/chrisjpatty/react-dragtastic#readme +// Definitions by: Nicolás Scarcella +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.6 + +import { ReactNode, Component, MouseEventHandler, TouchEventHandler } from 'react'; + +export type Id = string | number; +export type Type = string | number; +export type Accepts = string | ReadonlyArray; + +export interface State { + /** The user's current horizontal position on the page. */ + x: number; + /** The user's current vertical position on the page. */ + y: number; + /** The user's initial horizontal position on the page when they started dragging. */ + startingX: number; + /** The user's initial vertical position on the page when they started dragging. */ + startingY: number; + /** A boolean representing whether the user is currently dragging. */ + isDragging: boolean; + /** The id of the currently dragging element. */ + currentlyDraggingId?: Id; + /** The id of the currently being hovered. */ + currentlyHoveredDroppableId?: Id; + /** The accepts property of the currently being hovered. */ + currentlyHoveredDroppableAccepts?: Accepts; + /** Data from the data property of the which is currently active. null if not dragging. */ + data: any; + /** The type of the component being currently dragged. null if not dragging. */ + type?: Type; +} + +// ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +// DRAGGABLE +// ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + +export interface DraggableProps { + /** An id which will be used in the draggable zone's target */ + id?: Id; + /** A string, or array of strings, used to limit which droppable zones will accept 's attached to this draggable. */ + type?: Type; + /** Data of any type which will be passed to the onDrop function of any which accepts this 's type. */ + data?: any; + /** A function which will be called when the zone is activated (The user started dragging). */ + onDragStart?: (data: any) => void; + /** A function which will be called when the zone is deactivated (The user stopped dragging). */ + onDragEnd?: (data: any) => void; + /** A function which will be called every time the user's cursor moves while dragging. */ + onDrag?: () => void; + /** + * An optional array of strings. For performance reasons you can limit which keys in the dragState your component subscribes to. + * For example, you may pass ['type', 'data'] to only rerender if these keys change. + */ + subscribeTo?: ReadonlyArray | null; + /** An optional int representing the distance in pixels the user's pointer must travel to activate the draggable. Defaults to 8 */ + delay?: number; + + children: (arg: State & { + /** A boolean representing if the draggable is currently active. */ + isActive: boolean; + events: { + onMouseDown: MouseEventHandler, + onTouchStart: TouchEventHandler + } + }) => ReactNode; +} + +/** + * This defines a draggable zone. At a minimum, spread the events over the element that should be draggable (usually the root element). + */ +export class Draggable extends Component { } + +// ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +// DROPPABLE +// ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + +export interface DroppableProps { + /** An id which will be used in the draggable zone's target */ + id?: Id; + /** A string type corresponding to the type property of the zone for which this should accept drop events. */ + accepts?: Accepts; + /** A function which will be called when a user drops a on this with an accepted type. */ + onDrop?: (data: any) => void; + /** + * A function which will be called when the user's cursor enters the while dragging. + * This function will be called regardless of whether the droppable accepts the draggable currently being dragged. + */ + onDragEnter?: () => void; + /** + * A function which will be called when the user's cursor leaves the while dragging. + * This function will be called regardless of whether the droppable accepts the draggable currently being dragged. + */ + onDragLeave?: () => void; + /** + * An optional array of strings. For performance reasons you can limit which keys in the dragState your component subscribes to. + * For example, you may pass ['type', 'data'] to only rerender if these keys change. + */ + subscribeTo?: ReadonlyArray | null; + + children: (arg: State & { + /** A boolean representing if the user is currently hovering the . */ + isOver: boolean, + /** A boolean representing if this droppable will accept the currently dragging . */ + willAccept: boolean, + events: { + onMouseEnter: () => void, + onMouseLeave: () => void, + onMouseUp: () => void, + } + }) => ReactNode; +} + +/** + * This defines a droppable zone. At a minimum, spread the events over the element that should be droppable (usually the root element). + */ +export class Droppable extends Component { } + +// ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +// DRAG +// ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + +export interface DragComponentProps { + /* A string corresponding to the id property of the zone that should trigger this component to start rendering. */ + for?: Id; + /** A function which will be called every time a user drags. */ + onDrag?: () => void; + /** A boolean determining whether or not the DragComponent should always render. Defaults to false. */ + alwaysRender?: boolean; + /** + * An optional array of strings. For performance reasons you can limit which keys in the dragState your component subscribes to. + * For example, you may pass ['type', 'data'] to only rerender if these keys change. + */ + subscribeTo?: ReadonlyArray | null; + + children: (arg: State & { + /** A boolean representing whether the user is currently hovering a that accepts the type of the currently active */ + isOverAccepted: boolean + }) => ReactNode; +} + +/** + * By default, children passed to this component will only render if the user is currently dragging, but this can be overridden. + */ +export class DragComponent extends Component { } + +// ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +// DRAG STATE +// ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + +export interface DragStateProps { + /** + * An optional array of strings. For performance reasons you can limit which keys in the dragState your component subscribes to. + * For example, you may pass ['type', 'data'] to only rerender if these keys change. + */ + subscribeTo?: ReadonlyArray | null; + + children: (arg: State) => ReactNode; +} + +/** + * This component is used just like a draggable or droppable, but does not accept or trigger any drag events. + * Use it if you need to notify a component about changes in the dragState without making that component a draggable or droppable zone. + */ +export class DragState extends Component { } diff --git a/types/react-dragtastic/react-dragtastic-tests.tsx b/types/react-dragtastic/react-dragtastic-tests.tsx new file mode 100644 index 0000000000..87a8e828e1 --- /dev/null +++ b/types/react-dragtastic/react-dragtastic-tests.tsx @@ -0,0 +1,57 @@ +import * as React from 'react'; +import { Draggable, Droppable, DragComponent, DragState } from 'react-dragtastic'; + +class DraggableZone extends React.Component { + render() { + return ( + + {dragState =>
I'm a draggable zone
} +
+ ); + } +} + +class DroppableZone extends React.Component { + render() { + return ( + + {dragState =>
I'm a droppable zone
} +
+ ); + } +} + +class DragComponentWrapper extends React.Component { + render() { + return ( + + {dragState => ( +
+ I will render when my Draggable zone is activated +
+ )} +
+ ); + } +} + +class CompWithDragState extends React.Component { + render() { + return ( + + {dragState => ( +
+ I always render, and have access to the global dragState. +
+ )} +
+ ); + } +} diff --git a/types/react-dragtastic/tsconfig.json b/types/react-dragtastic/tsconfig.json new file mode 100644 index 0000000000..7c07bab561 --- /dev/null +++ b/types/react-dragtastic/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "jsx": "react", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "react-dragtastic-tests.tsx" + ] +} \ No newline at end of file diff --git a/types/react-dragtastic/tslint.json b/types/react-dragtastic/tslint.json new file mode 100644 index 0000000000..30a1bdde2e --- /dev/null +++ b/types/react-dragtastic/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "dtslint/dt.json" +} \ No newline at end of file