1 | import { Component, ComponentType, ComponentClass } from 'react';
|
2 | import { Identifier } from 'dnd-core';
|
3 | import { DropTargetMonitor, DragSourceMonitor, DragLayerMonitor, ConnectDragPreview, ConnectDropTarget, ConnectDragSource } from '../types';
|
4 | import { NonReactStatics } from 'hoist-non-react-statics';
|
5 | /**
|
6 | * Options for the Drag Sources, Drop Targets, and Drag Layers decorators
|
7 | */
|
8 | export interface DndOptions<Props> {
|
9 | arePropsEqual?: (first: Props, second: Props) => boolean;
|
10 | }
|
11 | /**
|
12 | * A DnD interactive component
|
13 | */
|
14 | export interface DndComponent<Props> extends Component<Props> {
|
15 | getDecoratedComponentInstance(): Component<Props> | null;
|
16 | getHandlerId(): Identifier;
|
17 | }
|
18 | /**
|
19 | * Interface for the DropTarget specification object
|
20 | */
|
21 | export interface DropTargetSpec<Props, DragObject = any, DropResult = any> {
|
22 | /**
|
23 | * Optional.
|
24 | * Called when a compatible item is dropped on the target. You may either return undefined, or a plain object.
|
25 | * If you return an object, it is going to become the drop result and will be available to the drag source in its
|
26 | * endDrag method as monitor.getDropResult(). This is useful in case you want to perform different actions
|
27 | * depending on which target received the drop. If you have nested drop targets, you can test whether a nested
|
28 | * target has already handled drop by checking monitor.didDrop() and monitor.getDropResult(). Both this method and
|
29 | * the source's endDrag method are good places to fire Flux actions. This method will not be called if canDrop()
|
30 | * is defined and returns false.
|
31 | */
|
32 | drop?: (props: Props, monitor: DropTargetMonitor<DragObject, DropResult>, component: any) => DropResult | undefined;
|
33 | /**
|
34 | * Optional.
|
35 | * Called when an item is hovered over the component. You can check monitor.isOver({ shallow: true }) to test whether
|
36 | * the hover happens over just the current target, or over a nested one. Unlike drop(), this method will be called even
|
37 | * if canDrop() is defined and returns false. You can check monitor.canDrop() to test whether this is the case.
|
38 | */
|
39 | hover?: (props: Props, monitor: DropTargetMonitor<DragObject, DropResult>, component: any) => void;
|
40 | /**
|
41 | * Optional. Use it to specify whether the drop target is able to accept the item. If you want to always allow it, just
|
42 | * omit this method. Specifying it is handy if you'd like to disable dropping based on some predicate over props or
|
43 | * monitor.getItem(). Note: You may not call monitor.canDrop() inside this method.
|
44 | */
|
45 | canDrop?: (props: Props, monitor: DropTargetMonitor<DragObject, DropResult>) => boolean;
|
46 | }
|
47 | export interface DragSourceSpec<Props, DragObject = any, DropResult = any> {
|
48 | /**
|
49 | * Required.
|
50 | * When the dragging starts, beginDrag is called. You must return a plain JavaScript object describing the
|
51 | * data being dragged. What you return is the only information available to the drop targets about the drag
|
52 | * source so it's important to pick the minimal data they need to know. You may be tempted to put a reference
|
53 | * to the component into it, but you should try very hard to avoid doing this because it couples the drag
|
54 | * sources and drop targets. It's a good idea to return something like { id: props.id } from this method.
|
55 | */
|
56 | beginDrag: (props: Props, monitor: DragSourceMonitor<DragObject, DropResult>, component: any) => DragObject;
|
57 | /**
|
58 | * Optional.
|
59 | * When the dragging stops, endDrag is called. For every beginDrag call, a corresponding endDrag call is guaranteed.
|
60 | * You may call monitor.didDrop() to check whether or not the drop was handled by a compatible drop target. If it was handled,
|
61 | * and the drop target specified a drop result by returning a plain object from its drop() method, it will be available as
|
62 | * monitor.getDropResult(). This method is a good place to fire a Flux action. Note: If the component is unmounted while dragging,
|
63 | * component parameter is set to be null.
|
64 | */
|
65 | endDrag?: (props: Props, monitor: DragSourceMonitor<DragObject, DropResult>, component: any) => void;
|
66 | /**
|
67 | * Optional.
|
68 | * Use it to specify whether the dragging is currently allowed. If you want to always allow it, just omit this method.
|
69 | * Specifying it is handy if you'd like to disable dragging based on some predicate over props. Note: You may not call
|
70 | * monitor.canDrag() inside this method.
|
71 | */
|
72 | canDrag?: (props: Props, monitor: DragSourceMonitor<DragObject, DropResult>) => boolean;
|
73 | /**
|
74 | * Optional.
|
75 | * By default, only the drag source that initiated the drag operation is considered to be dragging. You can
|
76 | * override this behavior by defining a custom isDragging method. It might return something like props.id === monitor.getItem().id.
|
77 | * Do this if the original component may be unmounted during the dragging and later “resurrected” with a different parent.
|
78 | * For example, when moving a card across the lists in a Kanban board, you want it to retain the dragged appearance—even though
|
79 | * technically, the component gets unmounted and a different one gets mounted every time you move it to another list.
|
80 | *
|
81 | * Note: You may not call monitor.isDragging() inside this method.
|
82 | */
|
83 | isDragging?: (props: Props, monitor: DragSourceMonitor<DragObject, DropResult>) => boolean;
|
84 | }
|
85 | /**
|
86 | * DragSourceConnector is an object passed to a collecting function of the DragSource.
|
87 | * Its methods return functions that let you assign the roles to your component's DOM nodes.
|
88 | */
|
89 | export interface DragSourceConnector {
|
90 | /**
|
91 | * Returns a function that must be used inside the component to assign the drag source role to a node. By
|
92 | * returning { connectDragSource: connect.dragSource() } from your collecting function, you can mark any React
|
93 | * element as the draggable node. To do that, replace any element with this.props.connectDragSource(element) inside
|
94 | * the render function.
|
95 | */
|
96 | dragSource(): ConnectDragSource;
|
97 | /**
|
98 | * Optional. Returns a function that may be used inside the component to assign the drag preview role to a node. By
|
99 | * returning { connectDragPreview: connect.dragPreview() } from your collecting function, you can mark any React element
|
100 | * as the drag preview node. To do that, replace any element with this.props.connectDragPreview(element) inside the render
|
101 | * function. The drag preview is the node that will be screenshotted by the HTML5 backend when the drag begins. For example,
|
102 | * if you want to make something draggable by a small custom handle, you can mark this handle as the dragSource(), but also
|
103 | * mark an outer, larger component node as the dragPreview(). Thus the larger drag preview appears on the screenshot, but
|
104 | * only the smaller drag source is actually draggable. Another possible customization is passing an Image instance to dragPreview
|
105 | * from a lifecycle method like componentDidMount. This lets you use the actual images for drag previews. (Note that IE does not
|
106 | * support this customization). See the example code below for the different usage examples.
|
107 | */
|
108 | dragPreview(): ConnectDragPreview;
|
109 | }
|
110 | /**
|
111 | * DropTargetConnector is an object passed to a collecting function of the DropTarget. Its only method dropTarget() returns a function
|
112 | * that lets you assign the drop target role to one of your component's DOM nodes.
|
113 | */
|
114 | export interface DropTargetConnector {
|
115 | /**
|
116 | * Returns a function that must be used inside the component to assign the drop target role to a node.
|
117 | * By returning { connectDropTarget: connect.dropTarget() } from your collecting function, you can mark any React element
|
118 | * as the droppable node. To do that, replace any element with this.props.connectDropTarget(element) inside the render function.
|
119 | */
|
120 | dropTarget(): ConnectDropTarget;
|
121 | }
|
122 | export declare type DragSourceCollector<CollectedProps, TargetProps> = (connect: DragSourceConnector, monitor: DragSourceMonitor, props: TargetProps) => CollectedProps;
|
123 | export declare type DropTargetCollector<CollectedProps, TargetProps> = (connect: DropTargetConnector, monitor: DropTargetMonitor, props: TargetProps) => CollectedProps;
|
124 | export declare type DragLayerCollector<TargetProps, CollectedProps> = (monitor: DragLayerMonitor, props: TargetProps) => CollectedProps;
|
125 | export declare type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
126 | /**
|
127 | * A property P will be present if:
|
128 | * - it is present in DecorationTargetProps
|
129 | *
|
130 | * Its value will be dependent on the following conditions
|
131 | * - if property P is present in InjectedProps and its definition extends the definition
|
132 | * in DecorationTargetProps, then its definition will be that of DecorationTargetProps[P]
|
133 | * - if property P is not present in InjectedProps then its definition will be that of
|
134 | * DecorationTargetProps[P]
|
135 | * - if property P is present in InjectedProps but does not extend the
|
136 | * DecorationTargetProps[P] definition, its definition will be that of InjectedProps[P]
|
137 | */
|
138 | export declare type Matching<InjectedProps, DecorationTargetProps> = {
|
139 | [P in keyof DecorationTargetProps]: P extends keyof InjectedProps ? InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : InjectedProps[P] : DecorationTargetProps[P];
|
140 | };
|
141 | /**
|
142 | * a property P will be present if :
|
143 | * - it is present in both DecorationTargetProps and InjectedProps
|
144 | * - InjectedProps[P] can satisfy DecorationTargetProps[P]
|
145 | * ie: decorated component can accept more types than decorator is injecting
|
146 | *
|
147 | * For decoration, inject props or ownProps are all optionally
|
148 | * required by the decorated (right hand side) component.
|
149 | * But any property required by the decorated component must be satisfied by the injected property.
|
150 | */
|
151 | export declare type Shared<InjectedProps, DecorationTargetProps> = {
|
152 | [P in Extract<keyof InjectedProps, keyof DecorationTargetProps>]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never;
|
153 | };
|
154 | /**
|
155 | * Gets the props interface of a component using inference
|
156 | */
|
157 | export declare type GetProps<C> = C extends ComponentType<infer P> ? P : never;
|
158 | export declare type DndComponentEnhancer<CollectedProps> = <C extends ComponentType<Matching<CollectedProps, GetProps<C>>>>(component: C) => DndComponentClass<C, Omit<GetProps<C>, keyof Shared<CollectedProps, GetProps<C>>>>;
|
159 | export declare type DndComponentClass<C extends ComponentType<any>, P> = ComponentClass<JSX.LibraryManagedAttributes<C, P>> & NonReactStatics<C> & {
|
160 | DecoratedComponent: C;
|
161 | };
|