react-dnd
Advanced tools
Comparing version 7.3.2 to 7.4.0
import * as React from 'react'; | ||
import { DragDropManager, Identifier } from 'dnd-core'; | ||
import { DndComponentClass } from './interfaces'; | ||
import { DndComponent } from './interfaces'; | ||
export interface DecorateHandlerArgs<Props, ItemIdType> { | ||
@@ -22,3 +22,3 @@ DecoratedComponent: any; | ||
} | ||
export default function decorateHandler<Props, ItemIdType>({ DecoratedComponent, createHandler, createMonitor, createConnector, registerHandler, containerDisplayName, getType, collect, options, }: DecorateHandlerArgs<Props, ItemIdType>): DndComponentClass<Props>; | ||
export default function decorateHandler<Props, CollectedProps, ItemIdType>({ DecoratedComponent, createHandler, createMonitor, createConnector, registerHandler, containerDisplayName, getType, collect, options, }: DecorateHandlerArgs<Props, ItemIdType>): DndComponent<Props>; | ||
export {}; |
@@ -44,2 +44,3 @@ "use strict"; | ||
var _this = _super.call(this, props) || this; | ||
_this.decoratedRef = React.createRef(); | ||
_this.handleChange = function () { | ||
@@ -60,6 +61,4 @@ var nextState = _this.getCurrentState(); | ||
DragDropContainer.prototype.getDecoratedComponentInstance = function () { | ||
if (!this.handler) { | ||
return null; | ||
} | ||
return this.handler.ref.current; | ||
invariant(this.decoratedRef.current, 'In order to access an instance of the decorated component it can not be a stateless component.'); | ||
return this.decoratedRef.current; | ||
}; | ||
@@ -100,3 +99,3 @@ DragDropContainer.prototype.shouldComponentUpdate = function (nextProps, nextState) { | ||
this.currentType = type; | ||
var _a = registerHandler(type, this.handler, this.manager), handlerId = _a.handlerId, unregister = _a.unregister; | ||
var _a = registerHandler(type, this.handler, this.manager), handlerId = _a[0], unregister = _a[1]; | ||
this.handlerId = handlerId; | ||
@@ -119,3 +118,3 @@ this.handlerMonitor.receiveHandlerId(handlerId); | ||
} | ||
var nextState = collect(this.handlerConnector.hooks, this.handlerMonitor); | ||
var nextState = collect(this.handlerConnector.hooks, this.handlerMonitor, this.props); | ||
if (process.env.NODE_ENV !== 'production') { | ||
@@ -132,9 +131,7 @@ invariant(isPlainObject(nextState), 'Expected `collect` specified as the second argument to ' + | ||
var dragDropManager = _a.dragDropManager; | ||
if (dragDropManager === undefined) { | ||
return null; | ||
} | ||
_this.receiveDragDropManager(dragDropManager); | ||
return (React.createElement(Decorated, __assign({}, _this.props, _this.getCurrentState(), { ref: _this.handler && isClassComponent(Decorated) | ||
? _this.handler.ref | ||
: undefined }))); | ||
requestAnimationFrame(function () { return _this.handlerConnector.reconnect(); }); | ||
return (React.createElement(Decorated, __assign({}, _this.props, _this.getCurrentState(), { | ||
// NOTE: if Decorated is a Function Component, decoratedRef will not be populated unless it's a refforwarding component. | ||
ref: isClassComponent(Decorated) ? _this.decoratedRef : null }))); | ||
})); | ||
@@ -146,10 +143,12 @@ }; | ||
} | ||
this.manager = dragDropManager; | ||
invariant(typeof dragDropManager === 'object', 'Could not find the drag and drop manager in the context of %s. ' + | ||
invariant(dragDropManager !== undefined, 'Could not find the drag and drop manager in the context of %s. ' + | ||
'Make sure to wrap the top-level component of your app with DragDropContext. ' + | ||
'Read more: http://react-dnd.github.io/react-dnd/docs-troubleshooting.html#could-not-find-the-drag-and-drop-manager-in-the-context', displayName, displayName); | ||
var itemRef = React.createRef(); | ||
if (dragDropManager === undefined) { | ||
return; | ||
} | ||
this.manager = dragDropManager; | ||
this.handlerMonitor = createMonitor(dragDropManager); | ||
this.handlerConnector = createConnector(dragDropManager.getBackend()); | ||
this.handler = createHandler(this.handlerMonitor, itemRef); | ||
this.handler = createHandler(this.handlerMonitor, this.decoratedRef); | ||
}; | ||
@@ -156,0 +155,0 @@ DragDropContainer.DecoratedComponent = DecoratedComponent; |
@@ -32,3 +32,2 @@ "use strict"; | ||
var hoistStatics = require('hoist-non-react-statics'); | ||
var isClassComponent = require('recompose/isClassComponent').default; | ||
/** | ||
@@ -58,9 +57,2 @@ * Create the React Context | ||
var contextValue = createChildContext(backend, context, debugMode); | ||
React.useEffect(function () { | ||
return function () { | ||
return contextValue.dragDropManager.dispatch({ | ||
type: 'DragDropContextProvider::Exiting', | ||
}); | ||
}; | ||
}); | ||
return React.createElement(exports.Provider, { value: contextValue }, children); | ||
@@ -94,3 +86,3 @@ }; | ||
return (React.createElement(exports.Provider, { value: childContext }, | ||
React.createElement(Decorated, __assign({}, this.props, { ref: isClassComponent(Decorated) ? this.ref : undefined })))); | ||
React.createElement(Decorated, __assign({}, this.props, { ref: this.ref })))); | ||
}; | ||
@@ -97,0 +89,0 @@ DragDropContextContainer.DecoratedComponent = DecoratedComponent; |
@@ -1,3 +0,2 @@ | ||
import * as React from 'react'; | ||
import { DragLayerCollector, DndOptions, DndComponentClass } from './interfaces'; | ||
export default function DragLayer<Props, CollectedProps = {}>(collect: DragLayerCollector<Props, CollectedProps>, options?: DndOptions<Props>): <T>(DecoratedComponent: React.ComponentType<T>) => DndComponentClass<Props>; | ||
import { DragLayerCollector, DndOptions, DndComponentEnhancer } from './interfaces'; | ||
export default function DragLayer<RequiredProps, CollectedProps = {}>(collect: DragLayerCollector<RequiredProps, CollectedProps>, options?: DndOptions<RequiredProps>): DndComponentEnhancer<CollectedProps>; |
@@ -34,3 +34,2 @@ "use strict"; | ||
var shallowEqual = require('shallowequal'); | ||
var isClassComponent = require('recompose/isClassComponent').default; | ||
function DragLayer(collect, options) { | ||
@@ -98,3 +97,3 @@ if (options === void 0) { options = {}; } | ||
} | ||
return (React.createElement(Decorated, __assign({}, _this.props, _this.state, { ref: isClassComponent(Decorated) ? _this.ref : undefined }))); | ||
return (React.createElement(Decorated, __assign({}, _this.props, _this.state, { ref: _this.ref }))); | ||
})); | ||
@@ -101,0 +100,0 @@ }; |
@@ -1,4 +0,4 @@ | ||
import * as React from 'react'; | ||
import { SourceType } from 'dnd-core'; | ||
import { DragSourceSpec, DragSourceCollector, DndOptions, DndComponentClass } from './interfaces'; | ||
import { DragSourceSpec, DragSourceCollector, DndOptions } from './interfaces'; | ||
import { DndComponentEnhancer } from './interfaces'; | ||
/** | ||
@@ -11,2 +11,2 @@ * Decorates a component as a dragsource | ||
*/ | ||
export default function DragSource<Props, CollectedProps = {}, DragObject = {}>(type: SourceType | ((props: Props) => SourceType), spec: DragSourceSpec<Props, DragObject>, collect: DragSourceCollector<CollectedProps>, options?: DndOptions<Props>): <T>(DecoratedComponent: React.ComponentType<T>) => DndComponentClass<Props>; | ||
export default function DragSource<RequiredProps, CollectedProps = {}, DragObject = {}>(type: SourceType | ((props: RequiredProps) => SourceType), spec: DragSourceSpec<RequiredProps, DragObject>, collect: DragSourceCollector<CollectedProps, RequiredProps>, options?: DndOptions<RequiredProps>): DndComponentEnhancer<CollectedProps>; |
@@ -8,3 +8,3 @@ "use strict"; | ||
var DragSourceMonitorImpl_1 = require("./DragSourceMonitorImpl"); | ||
var createSourceConnector_1 = require("./createSourceConnector"); | ||
var SourceConnector_1 = require("./SourceConnector"); | ||
var isValidType_1 = require("./utils/isValidType"); | ||
@@ -48,6 +48,6 @@ var invariant = require('invariant'); | ||
registerHandler: registerSource_1.default, | ||
createConnector: function (backend) { return new SourceConnector_1.default(backend); }, | ||
createMonitor: function (manager) { | ||
return new DragSourceMonitorImpl_1.default(manager); | ||
}, | ||
createConnector: createSourceConnector_1.default, | ||
DecoratedComponent: DecoratedComponent, | ||
@@ -54,0 +54,0 @@ getType: getType, |
@@ -1,4 +0,3 @@ | ||
import * as React from 'react'; | ||
import { TargetType } from 'dnd-core'; | ||
import { DropTargetSpec, DndOptions, DropTargetCollector, DndComponentClass } from './interfaces'; | ||
export default function DropTarget<Props, CollectedProps = {}>(type: TargetType | ((props: Props) => TargetType), spec: DropTargetSpec<Props>, collect: DropTargetCollector<CollectedProps>, options?: DndOptions<Props>): <T>(DecoratedComponent: React.ComponentType<T>) => DndComponentClass<Props>; | ||
import { DropTargetSpec, DndOptions, DropTargetCollector, DndComponentEnhancer } from './interfaces'; | ||
export default function DropTarget<RequiredProps, CollectedProps = {}>(type: TargetType | ((props: RequiredProps) => TargetType), spec: DropTargetSpec<RequiredProps>, collect: DropTargetCollector<CollectedProps, RequiredProps>, options?: DndOptions<RequiredProps>): DndComponentEnhancer<CollectedProps>; |
@@ -7,5 +7,5 @@ "use strict"; | ||
var createTargetFactory_1 = require("./createTargetFactory"); | ||
var createTargetConnector_1 = require("./createTargetConnector"); | ||
var isValidType_1 = require("./utils/isValidType"); | ||
var DropTargetMonitorImpl_1 = require("./DropTargetMonitorImpl"); | ||
var TargetConnector_1 = require("./TargetConnector"); | ||
var invariant = require('invariant'); | ||
@@ -44,3 +44,3 @@ var isPlainObject = require('lodash/isPlainObject'); | ||
}, | ||
createConnector: createTargetConnector_1.default, | ||
createConnector: function (backend) { return new TargetConnector_1.default(backend); }, | ||
DecoratedComponent: DecoratedComponent, | ||
@@ -47,0 +47,0 @@ getType: getType, |
export * from './useDrag'; | ||
export * from './useDrop'; | ||
export * from './useDragLayer'; | ||
export * from './useDragPreview'; |
@@ -9,2 +9,1 @@ "use strict"; | ||
__export(require("./useDragLayer")); | ||
__export(require("./useDragPreview")); |
@@ -1,1 +0,7 @@ | ||
export declare function useCollector<T, S>(monitor: T, collect: (monitor: T) => S): [S, () => void]; | ||
/** | ||
* | ||
* @param monitor The monitor to colelct state from | ||
* @param collect The collecting function | ||
* @param onUpdate A method to invoke when updates occur | ||
*/ | ||
export declare function useCollector<T, S>(monitor: T, collect: (monitor: T) => S, onUpdate?: () => void): [S, () => void]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// declare var require: any | ||
// const shallowEqual = require('shallowequal') | ||
var react_1 = require("react"); | ||
var shallowEqual = require('shallowequal'); | ||
function useCollector(monitor, collect) { | ||
/** | ||
* | ||
* @param monitor The monitor to colelct state from | ||
* @param collect The collecting function | ||
* @param onUpdate A method to invoke when updates occur | ||
*/ | ||
function useCollector(monitor, collect, onUpdate) { | ||
var _a = react_1.useState(function () { return collect(monitor); }), collected = _a[0], setCollected = _a[1]; | ||
var updateCollected = function () { | ||
var nextValue = collect(monitor); | ||
if (!shallowEqual(collected, nextValue)) { | ||
setCollected(nextValue); | ||
// TODO: we need this shallowequal check to work | ||
// so that we can operate performantly, but the examples | ||
// are broken with it in currently | ||
// if (!shallowEqual(collected, nextValue)) { | ||
setCollected(nextValue); | ||
if (onUpdate) { | ||
onUpdate(); | ||
} | ||
// } | ||
}; | ||
@@ -13,0 +26,0 @@ return [collected, updateCollected]; |
@@ -1,3 +0,2 @@ | ||
import { HandlerManager } from '../../interfaces'; | ||
import { DragDropMonitor } from 'dnd-core'; | ||
export declare function useMonitorOutput<Monitor extends DragDropMonitor & HandlerManager, Collected>(monitor: Monitor, collect: (monitor: Monitor) => Collected): Collected; | ||
import { HandlerManager, MonitorEventEmitter } from '../../interfaces'; | ||
export declare function useMonitorOutput<Monitor extends HandlerManager, Collected>(monitor: Monitor & MonitorEventEmitter, collect: (monitor: Monitor) => Collected, onCollect?: () => void): Collected; |
@@ -5,6 +5,4 @@ "use strict"; | ||
var useCollector_1 = require("./useCollector"); | ||
function useMonitorOutput(monitor, collect) { | ||
var _a = useCollector_1.useCollector(monitor, collect), collected = _a[0], updateCollected = _a[1]; | ||
// This runs on every render. There will be ways to optimise this, but for | ||
// now, this is the most correct thing to do. | ||
function useMonitorOutput(monitor, collect, onCollect) { | ||
var _a = useCollector_1.useCollector(monitor, collect, onCollect), collected = _a[0], updateCollected = _a[1]; | ||
react_1.useEffect(function subscribeToMonitorStateChange() { | ||
@@ -15,8 +13,9 @@ var handlerId = monitor.getHandlerId(); | ||
} | ||
return monitor.subscribeToStateChange(updateCollected, { | ||
var unsubscribe = monitor.subscribeToStateChange(updateCollected, { | ||
handlerIds: [handlerId], | ||
}); | ||
}); | ||
return unsubscribe; | ||
}, [monitor]); | ||
return collected; | ||
} | ||
exports.useMonitorOutput = useMonitorOutput; |
@@ -1,3 +0,2 @@ | ||
/// <reference types="react" /> | ||
import { DragSourceHookSpec, DragObjectWithType } from '../interfaces'; | ||
import { DragSourceHookSpec, DragObjectWithType, ConnectDragSource, ConnectDragPreview } from '../interfaces'; | ||
/** | ||
@@ -7,2 +6,2 @@ * useDragSource hook (This API is experimental and subject to breaking changes in non-major versions) | ||
*/ | ||
export declare function useDrag<DragObject extends DragObjectWithType, DropResult, CollectedProps>(spec: DragSourceHookSpec<DragObject, DropResult, CollectedProps>): [CollectedProps, React.RefObject<any>]; | ||
export declare function useDrag<DragObject extends DragObjectWithType, DropResult, CollectedProps>(spec: DragSourceHookSpec<DragObject, DropResult, CollectedProps>): [CollectedProps, ConnectDragSource, ConnectDragPreview]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var useMonitorOutput_1 = require("./internal/useMonitorOutput"); | ||
var drag_1 = require("./internal/drag"); | ||
var react_1 = require("react"); | ||
var useDragSourceMonitor_1 = require("./internal/useDragSourceMonitor"); | ||
var useDragDropManager_1 = require("./internal/useDragDropManager"); | ||
var util_1 = require("./util"); | ||
var useMonitorOutput_1 = require("./internal/useMonitorOutput"); | ||
var invariant = require('invariant'); | ||
@@ -14,35 +12,25 @@ /** | ||
function useDrag(spec) { | ||
var item = spec.item, options = spec.options, preview = spec.preview, previewOptions = spec.previewOptions, collect = spec.collect; | ||
var ref = spec.ref; | ||
invariant(item != null, 'item must be defined'); | ||
invariant(item.type != null, 'item type must be defined'); | ||
var manager = useDragDropManager_1.useDragDropManager(); | ||
var backend = manager.getBackend(); | ||
var monitor = useDragSourceMonitor_1.useDragSourceMonitor(manager, spec); | ||
if (!ref) { | ||
ref = react_1.useRef(null); | ||
} | ||
/* | ||
* Connect the Drag Source Element to the Backend | ||
*/ | ||
react_1.useEffect(function connectDragSource() { | ||
var node = ref.current; | ||
return backend.connectDragSource(monitor.getHandlerId(), node, options); | ||
}, []); | ||
/* | ||
* Connect the Drag Preview Element to the Backend | ||
*/ | ||
react_1.useEffect(function connectDragPreview() { | ||
if (preview) { | ||
var previewNode = util_1.isRef(preview) | ||
? preview.current | ||
: preview; | ||
return backend.connectDragPreview(monitor.getHandlerId(), previewNode, previewOptions); | ||
} | ||
}, [preview && preview.current]); | ||
var result = collect | ||
? useMonitorOutput_1.useMonitorOutput(monitor, collect) | ||
: {}; | ||
return [result, ref]; | ||
var specRef = react_1.useRef(spec); | ||
// TODO: wire options into createSourceConnector | ||
invariant(spec.item != null, 'item must be defined'); | ||
invariant(spec.item.type != null, 'item type must be defined'); | ||
var _a = drag_1.useDragSourceMonitor(), monitor = _a[0], connector = _a[1]; | ||
drag_1.useDragHandler(specRef, monitor, connector); | ||
var result = useMonitorOutput_1.useMonitorOutput(monitor, specRef.current.collect || (function () { return ({}); }), function () { return connector.reconnect(); }); | ||
var connectDragSource = react_1.useMemo(function () { return connector.hooks.dragSource(); }, [ | ||
connector, | ||
]); | ||
var connectDragPreview = react_1.useMemo(function () { return connector.hooks.dragPreview(); }, [ | ||
connector, | ||
]); | ||
react_1.useEffect(function () { | ||
connector.dragSourceOptions = specRef.current.options || null; | ||
connector.reconnect(); | ||
}, [connector]); | ||
react_1.useEffect(function () { | ||
connector.dragPreviewOptions = specRef.current.previewOptions || null; | ||
connector.reconnect(); | ||
}, [connector]); | ||
return [result, connectDragSource, connectDragPreview]; | ||
} | ||
exports.useDrag = useDrag; |
@@ -1,3 +0,2 @@ | ||
/// <reference types="react" /> | ||
import { DropTargetHookSpec } from '../interfaces'; | ||
import { DropTargetHookSpec, ConnectDropTarget, DragObjectWithType } from '../interfaces'; | ||
/** | ||
@@ -7,2 +6,2 @@ * useDropTarget Hook (This API is experimental and subject to breaking changes in non-breaking versions) | ||
*/ | ||
export declare function useDrop<DragObject, DropResult, CollectedProps>(spec: DropTargetHookSpec<DragObject, DropResult, CollectedProps>): [CollectedProps, React.RefObject<any>]; | ||
export declare function useDrop<DragObject extends DragObjectWithType, DropResult, CollectedProps>(spec: DropTargetHookSpec<DragObject, DropResult, CollectedProps>): [CollectedProps, ConnectDropTarget]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var useMonitorOutput_1 = require("./internal/useMonitorOutput"); | ||
var drop_1 = require("./internal/drop"); | ||
var react_1 = require("react"); | ||
var useDragDropManager_1 = require("./internal/useDragDropManager"); | ||
var useDropTargetMonitor_1 = require("./internal/useDropTargetMonitor"); | ||
var useMonitorOutput_1 = require("./internal/useMonitorOutput"); | ||
var invariant = require('invariant'); | ||
@@ -13,27 +12,16 @@ /** | ||
function useDrop(spec) { | ||
var accept = spec.accept, options = spec.options, collect = spec.collect; | ||
invariant(accept != null, 'accept must be defined'); | ||
var ref = spec.ref; | ||
if (!ref) { | ||
ref = react_1.useRef(null); | ||
} | ||
var manager = useDragDropManager_1.useDragDropManager(); | ||
var backend = manager.getBackend(); | ||
var monitor = useDropTargetMonitor_1.useDropTargetMonitor(manager, spec); | ||
/* | ||
* Connect the Drop Target Element to the Backend | ||
*/ | ||
react_1.useEffect(function connectDropTarget() { | ||
if (ref.current) { | ||
var node = ref.current; | ||
if (node) { | ||
return backend.connectDropTarget(monitor.getHandlerId(), node, options); | ||
} | ||
} | ||
}); | ||
var result = collect | ||
? useMonitorOutput_1.useMonitorOutput(monitor, collect) | ||
: {}; | ||
return [result, ref]; | ||
var specRef = react_1.useRef(spec); | ||
invariant(spec.accept != null, 'accept must be defined'); | ||
var _a = drop_1.useDropTargetMonitor(), monitor = _a[0], connector = _a[1]; | ||
drop_1.useDropHandler(specRef, monitor, connector); | ||
var result = useMonitorOutput_1.useMonitorOutput(monitor, specRef.current.collect || (function () { return ({}); }), function () { return connector.reconnect(); }); | ||
var connectDropTarget = react_1.useMemo(function () { return connector.hooks.dropTarget(); }, [ | ||
connector, | ||
]); | ||
react_1.useEffect(function () { | ||
connector.dropTargetOptions = spec.options || null; | ||
connector.reconnect(); | ||
}, [spec.options]); | ||
return [result, connectDropTarget]; | ||
} | ||
exports.useDrop = useDrop; |
@@ -5,4 +5,5 @@ export { DragDropContext, DragDropContextProvider, Consumer as DragDropContextConsumer, DragDropContextProviderProps, } from './DragDropContext'; | ||
export { default as DropTarget } from './DropTarget'; | ||
export { default as DragPreviewImage } from './DragPreviewImage'; | ||
export * from './interfaces'; | ||
import { useDrag, useDragLayer, useDrop, useDragPreview } from './hooks'; | ||
import { useDrag, useDragLayer, useDrop } from './hooks'; | ||
export declare const __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__: { | ||
@@ -12,3 +13,2 @@ useDrag: typeof useDrag; | ||
useDrop: typeof useDrop; | ||
useDragPreview: typeof useDragPreview; | ||
}; |
@@ -13,2 +13,4 @@ "use strict"; | ||
exports.DropTarget = DropTarget_1.default; | ||
var DragPreviewImage_1 = require("./DragPreviewImage"); | ||
exports.DragPreviewImage = DragPreviewImage_1.default; | ||
var hooks_1 = require("./hooks"); | ||
@@ -19,3 +21,2 @@ exports.__EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__ = { | ||
useDrop: hooks_1.useDrop, | ||
useDragPreview: hooks_1.useDragPreview, | ||
}; |
@@ -1,5 +0,6 @@ | ||
/// <reference types="react" /> | ||
import * as React from 'react'; | ||
import { DragDropManager, Identifier } from 'dnd-core'; | ||
import { DropTargetMonitor, DragSourceMonitor, DragLayerMonitor } from './monitors'; | ||
import { DragSourceOptions, DragPreviewOptions } from './options'; | ||
import { NonReactStatics } from 'hoist-non-react-statics'; | ||
/** | ||
@@ -27,9 +28,2 @@ * The React Component that manages the DragDropContext for its children. | ||
/** | ||
* The class interface for a DnD component | ||
*/ | ||
export interface DndComponentClass<Props> extends React.ComponentClass<Props> { | ||
DecoratedComponent: React.ComponentType<Props>; | ||
new (props?: Props, context?: any): DndComponent<Props>; | ||
} | ||
/** | ||
* Interface for the DropTarget specification object | ||
@@ -101,6 +95,7 @@ */ | ||
} | ||
export declare type ConnectedElement = React.ReactElement | Element | null; | ||
export declare type DragElementWrapper<Options> = <Props>(elementOrNode: ConnectedElement, options?: Options) => React.ReactElement<Props>; | ||
export declare type ConnectableElement = React.RefObject<any> | React.ReactElement | Element | null; | ||
export declare type DragElementWrapper<Options> = (elementOrNode: ConnectableElement, options?: Options) => React.ReactElement | null; | ||
export declare type ConnectDragSource = DragElementWrapper<DragSourceOptions>; | ||
export declare type ConnectDragPreview = DragElementWrapper<DragPreviewOptions>; | ||
export declare type ConnectDropTarget = DragElementWrapper<any>; | ||
/** | ||
@@ -116,5 +111,2 @@ * DragSourceConnector is an object passed to a collecting function of the DragSource. | ||
* the render function. | ||
* | ||
* @param elementOrNode | ||
* @param options | ||
*/ | ||
@@ -147,5 +139,41 @@ dragSource(): ConnectDragSource; | ||
} | ||
export declare type ConnectDropTarget = <Props>(elementOrNode: ConnectedElement) => React.ReactElement<Props>; | ||
export declare type DragSourceCollector<CollectedProps> = (connect: DragSourceConnector, monitor: DragSourceMonitor) => CollectedProps; | ||
export declare type DropTargetCollector<CollectedProps> = (connect: DropTargetConnector, monitor: DropTargetMonitor) => CollectedProps; | ||
export declare type DragSourceCollector<CollectedProps, TargetProps> = (connect: DragSourceConnector, monitor: DragSourceMonitor, props: TargetProps) => CollectedProps; | ||
export declare type DropTargetCollector<CollectedProps, TargetProps> = (connect: DropTargetConnector, monitor: DropTargetMonitor, props: TargetProps) => CollectedProps; | ||
export declare type DragLayerCollector<TargetProps, CollectedProps> = (monitor: DragLayerMonitor, props: TargetProps) => CollectedProps; | ||
export declare type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; | ||
/** | ||
* A property P will be present if: | ||
* - it is present in DecorationTargetProps | ||
* | ||
* Its value will be dependent on the following conditions | ||
* - if property P is present in InjectedProps and its definition extends the definition | ||
* in DecorationTargetProps, then its definition will be that of DecorationTargetProps[P] | ||
* - if property P is not present in InjectedProps then its definition will be that of | ||
* DecorationTargetProps[P] | ||
* - if property P is present in InjectedProps but does not extend the | ||
* DecorationTargetProps[P] definition, its definition will be that of InjectedProps[P] | ||
*/ | ||
export declare type Matching<InjectedProps, DecorationTargetProps> = { | ||
[P in keyof DecorationTargetProps]: P extends keyof InjectedProps ? InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : InjectedProps[P] : DecorationTargetProps[P]; | ||
}; | ||
/** | ||
* a property P will be present if : | ||
* - it is present in both DecorationTargetProps and InjectedProps | ||
* - InjectedProps[P] can satisfy DecorationTargetProps[P] | ||
* ie: decorated component can accept more types than decorator is injecting | ||
* | ||
* For decoration, inject props or ownProps are all optionally | ||
* required by the decorated (right hand side) component. | ||
* But any property required by the decorated component must be satisfied by the injected property. | ||
*/ | ||
export declare type Shared<InjectedProps, DecorationTargetProps extends Shared<InjectedProps, DecorationTargetProps>> = { | ||
[P in Extract<keyof InjectedProps, keyof DecorationTargetProps>]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; | ||
}; | ||
/** | ||
* Gets the props interface of a component using inference | ||
*/ | ||
export declare type GetProps<C> = C extends React.ComponentType<infer P> ? P : never; | ||
export declare type DndComponentEnhancer<CollectedProps> = <C extends React.ComponentType<Matching<CollectedProps, GetProps<C>>>>(component: C) => DndComponentClass<C, Omit<GetProps<C>, keyof Shared<CollectedProps, GetProps<C>>>>; | ||
export declare type DndComponentClass<C extends React.ComponentType<any>, P> = React.ComponentClass<JSX.LibraryManagedAttributes<C, P>> & NonReactStatics<C> & { | ||
DecoratedComponent: C; | ||
}; |
import { TargetType, SourceType } from 'dnd-core'; | ||
import { DropTargetMonitor, DragSourceMonitor } from './monitors'; | ||
import { RefObject } from 'react'; | ||
import { DragSourceOptions, DragPreviewOptions } from './options'; | ||
export interface DragSourceHookSpec<DragObject extends DragObjectWithType, DropResult, CollectedProps> { | ||
/** | ||
* The ref object to associated with this dragged itom. If this is not specified it will be | ||
* returned in the `ref` field of the result object. | ||
*/ | ||
ref?: RefObject<any>; | ||
/** | ||
* A plain javascript item describing the data being dragged. | ||
@@ -28,6 +22,2 @@ * This is the only information available to the drop targets about the drag | ||
/** | ||
* An optional dragPreview | ||
*/ | ||
preview?: RefObject<any> | Element; | ||
/** | ||
* DragPreview options | ||
@@ -39,3 +29,3 @@ */ | ||
*/ | ||
begin?: (monitor: DragSourceMonitor) => DragObject | undefined; | ||
begin?: (monitor: DragSourceMonitor) => DragObject | undefined | void; | ||
/** | ||
@@ -78,7 +68,2 @@ * Optional. | ||
/** | ||
* The ref object to associated with this dragged itom. If this is not specified it will be | ||
* returned in the `ref` field of the result object. | ||
*/ | ||
ref?: RefObject<any>; | ||
/** | ||
* The kinds of dragItems this dropTarget accepts | ||
@@ -85,0 +70,0 @@ */ |
@@ -1,2 +0,2 @@ | ||
import { Identifier, XYCoord } from 'dnd-core'; | ||
import { Identifier, XYCoord, Unsubscribe } from 'dnd-core'; | ||
export interface HandlerManager { | ||
@@ -6,3 +6,3 @@ receiveHandlerId: (handlerId: Identifier | null) => void; | ||
} | ||
export interface DragSourceMonitor extends HandlerManager { | ||
export interface DragSourceMonitor extends HandlerManager, MonitorEventEmitter { | ||
/** | ||
@@ -60,3 +60,8 @@ * Returns true if no drag operation is in progress, and the owner's canDrag() returns true or is not defined. | ||
} | ||
export interface DropTargetMonitor extends HandlerManager { | ||
export interface MonitorEventEmitter { | ||
subscribeToStateChange(fn: () => void, options?: { | ||
handlerIds?: Identifier[]; | ||
}): Unsubscribe; | ||
} | ||
export interface DropTargetMonitor extends HandlerManager, MonitorEventEmitter { | ||
/** | ||
@@ -63,0 +68,0 @@ * Returns true if there is a drag operation in progress, and the owner's canDrop() returns true or is not defined. |
import { DragDropManager, DragSource, Unsubscribe, Identifier, SourceType } from 'dnd-core'; | ||
export default function registerSource<Context>(type: SourceType, source: DragSource, manager: DragDropManager<Context>): { | ||
handlerId: Identifier; | ||
unregister: Unsubscribe; | ||
}; | ||
export default function registerSource<Context>(type: SourceType, source: DragSource, manager: DragDropManager<Context>): [Identifier, Unsubscribe]; |
@@ -6,7 +6,4 @@ "use strict"; | ||
var sourceId = registry.addSource(type, source); | ||
return { | ||
handlerId: sourceId, | ||
unregister: function () { return registry.removeSource(sourceId); }, | ||
}; | ||
return [sourceId, function () { return registry.removeSource(sourceId); }]; | ||
} | ||
exports.default = registerSource; |
import { DragDropManager, DropTarget, Unsubscribe, Identifier, TargetType } from 'dnd-core'; | ||
export default function registerTarget<Context>(type: TargetType, target: DropTarget, manager: DragDropManager<Context>): { | ||
handlerId: Identifier; | ||
unregister: Unsubscribe; | ||
}; | ||
export default function registerTarget<Context>(type: TargetType, target: DropTarget, manager: DragDropManager<Context>): [Identifier, Unsubscribe]; |
@@ -6,7 +6,4 @@ "use strict"; | ||
var targetId = registry.addTarget(type, target); | ||
return { | ||
handlerId: targetId, | ||
unregister: function () { return registry.removeTarget(targetId); }, | ||
}; | ||
return [targetId, function () { return registry.removeTarget(targetId); }]; | ||
} | ||
exports.default = registerTarget; |
@@ -24,3 +24,5 @@ "use strict"; | ||
hook(node, options); | ||
return undefined; | ||
// return the node so it can be chained (e.g. when within callback refs | ||
// <div ref={node => connectDragSource(connectDropTarget(node))}/> | ||
return node; | ||
} | ||
@@ -41,4 +43,10 @@ // If passed a ReactElement, clone it and attach this function as a ref. | ||
var hook = hooks[key]; | ||
var wrappedHook = wrapHookToRecognizeElement(hook); | ||
wrappedHooks[key] = function () { return wrappedHook; }; | ||
// ref objects should be passed straight through without wrapping | ||
if (key.endsWith('Ref')) { | ||
wrappedHooks[key] = hooks[key]; | ||
} | ||
else { | ||
var wrappedHook_1 = wrapHookToRecognizeElement(hook); | ||
wrappedHooks[key] = function () { return wrappedHook_1; }; | ||
} | ||
}); | ||
@@ -45,0 +53,0 @@ return wrappedHooks; |
import * as React from 'react'; | ||
import { DragDropManager, Identifier } from 'dnd-core'; | ||
import { DndComponentClass } from './interfaces'; | ||
import { DndComponent } from './interfaces'; | ||
export interface DecorateHandlerArgs<Props, ItemIdType> { | ||
@@ -22,3 +22,3 @@ DecoratedComponent: any; | ||
} | ||
export default function decorateHandler<Props, ItemIdType>({ DecoratedComponent, createHandler, createMonitor, createConnector, registerHandler, containerDisplayName, getType, collect, options, }: DecorateHandlerArgs<Props, ItemIdType>): DndComponentClass<Props>; | ||
export default function decorateHandler<Props, CollectedProps, ItemIdType>({ DecoratedComponent, createHandler, createMonitor, createConnector, registerHandler, containerDisplayName, getType, collect, options, }: DecorateHandlerArgs<Props, ItemIdType>): DndComponent<Props>; | ||
export {}; |
@@ -16,2 +16,3 @@ import * as React from 'react'; | ||
super(props); | ||
this.decoratedRef = React.createRef(); | ||
this.handleChange = () => { | ||
@@ -31,6 +32,4 @@ const nextState = this.getCurrentState(); | ||
getDecoratedComponentInstance() { | ||
if (!this.handler) { | ||
return null; | ||
} | ||
return this.handler.ref.current; | ||
invariant(this.decoratedRef.current, 'In order to access an instance of the decorated component it can not be a stateless component.'); | ||
return this.decoratedRef.current; | ||
} | ||
@@ -71,3 +70,3 @@ shouldComponentUpdate(nextProps, nextState) { | ||
this.currentType = type; | ||
const { handlerId, unregister } = registerHandler(type, this.handler, this.manager); | ||
const [handlerId, unregister] = registerHandler(type, this.handler, this.manager); | ||
this.handlerId = handlerId; | ||
@@ -90,3 +89,3 @@ this.handlerMonitor.receiveHandlerId(handlerId); | ||
} | ||
const nextState = collect(this.handlerConnector.hooks, this.handlerMonitor); | ||
const nextState = collect(this.handlerConnector.hooks, this.handlerMonitor, this.props); | ||
if (process.env.NODE_ENV !== 'production') { | ||
@@ -101,9 +100,7 @@ invariant(isPlainObject(nextState), 'Expected `collect` specified as the second argument to ' + | ||
return (React.createElement(Consumer, null, ({ dragDropManager }) => { | ||
if (dragDropManager === undefined) { | ||
return null; | ||
} | ||
this.receiveDragDropManager(dragDropManager); | ||
return (React.createElement(Decorated, Object.assign({}, this.props, this.getCurrentState(), { ref: this.handler && isClassComponent(Decorated) | ||
? this.handler.ref | ||
: undefined }))); | ||
requestAnimationFrame(() => this.handlerConnector.reconnect()); | ||
return (React.createElement(Decorated, Object.assign({}, this.props, this.getCurrentState(), { | ||
// NOTE: if Decorated is a Function Component, decoratedRef will not be populated unless it's a refforwarding component. | ||
ref: isClassComponent(Decorated) ? this.decoratedRef : null }))); | ||
})); | ||
@@ -115,10 +112,12 @@ } | ||
} | ||
this.manager = dragDropManager; | ||
invariant(typeof dragDropManager === 'object', 'Could not find the drag and drop manager in the context of %s. ' + | ||
invariant(dragDropManager !== undefined, 'Could not find the drag and drop manager in the context of %s. ' + | ||
'Make sure to wrap the top-level component of your app with DragDropContext. ' + | ||
'Read more: http://react-dnd.github.io/react-dnd/docs-troubleshooting.html#could-not-find-the-drag-and-drop-manager-in-the-context', displayName, displayName); | ||
const itemRef = React.createRef(); | ||
if (dragDropManager === undefined) { | ||
return; | ||
} | ||
this.manager = dragDropManager; | ||
this.handlerMonitor = createMonitor(dragDropManager); | ||
this.handlerConnector = createConnector(dragDropManager.getBackend()); | ||
this.handler = createHandler(this.handlerMonitor, itemRef); | ||
this.handler = createHandler(this.handlerMonitor, this.decoratedRef); | ||
} | ||
@@ -125,0 +124,0 @@ } |
@@ -6,3 +6,2 @@ import * as React from 'react'; | ||
const hoistStatics = require('hoist-non-react-statics'); | ||
const isClassComponent = require('recompose/isClassComponent').default; | ||
/** | ||
@@ -30,7 +29,2 @@ * Create the React Context | ||
const contextValue = createChildContext(backend, context, debugMode); | ||
React.useEffect(() => { | ||
return () => contextValue.dragDropManager.dispatch({ | ||
type: 'DragDropContextProvider::Exiting', | ||
}); | ||
}); | ||
return React.createElement(Provider, { value: contextValue }, children); | ||
@@ -62,3 +56,3 @@ }; | ||
return (React.createElement(Provider, { value: childContext }, | ||
React.createElement(Decorated, Object.assign({}, this.props, { ref: isClassComponent(Decorated) ? this.ref : undefined })))); | ||
React.createElement(Decorated, Object.assign({}, this.props, { ref: this.ref })))); | ||
} | ||
@@ -65,0 +59,0 @@ } |
@@ -1,3 +0,2 @@ | ||
import * as React from 'react'; | ||
import { DragLayerCollector, DndOptions, DndComponentClass } from './interfaces'; | ||
export default function DragLayer<Props, CollectedProps = {}>(collect: DragLayerCollector<Props, CollectedProps>, options?: DndOptions<Props>): <T>(DecoratedComponent: React.ComponentType<T>) => DndComponentClass<Props>; | ||
import { DragLayerCollector, DndOptions, DndComponentEnhancer } from './interfaces'; | ||
export default function DragLayer<RequiredProps, CollectedProps = {}>(collect: DragLayerCollector<RequiredProps, CollectedProps>, options?: DndOptions<RequiredProps>): DndComponentEnhancer<CollectedProps>; |
@@ -8,3 +8,2 @@ import * as React from 'react'; | ||
const shallowEqual = require('shallowequal'); | ||
const isClassComponent = require('recompose/isClassComponent').default; | ||
export default function DragLayer(collect, options = {}) { | ||
@@ -67,3 +66,3 @@ checkDecoratorArguments('DragLayer', 'collect[, options]', collect, options); | ||
} | ||
return (React.createElement(Decorated, Object.assign({}, this.props, this.state, { ref: isClassComponent(Decorated) ? this.ref : undefined }))); | ||
return (React.createElement(Decorated, Object.assign({}, this.props, this.state, { ref: this.ref }))); | ||
})); | ||
@@ -70,0 +69,0 @@ } |
@@ -1,4 +0,4 @@ | ||
import * as React from 'react'; | ||
import { SourceType } from 'dnd-core'; | ||
import { DragSourceSpec, DragSourceCollector, DndOptions, DndComponentClass } from './interfaces'; | ||
import { DragSourceSpec, DragSourceCollector, DndOptions } from './interfaces'; | ||
import { DndComponentEnhancer } from './interfaces'; | ||
/** | ||
@@ -11,2 +11,2 @@ * Decorates a component as a dragsource | ||
*/ | ||
export default function DragSource<Props, CollectedProps = {}, DragObject = {}>(type: SourceType | ((props: Props) => SourceType), spec: DragSourceSpec<Props, DragObject>, collect: DragSourceCollector<CollectedProps>, options?: DndOptions<Props>): <T>(DecoratedComponent: React.ComponentType<T>) => DndComponentClass<Props>; | ||
export default function DragSource<RequiredProps, CollectedProps = {}, DragObject = {}>(type: SourceType | ((props: RequiredProps) => SourceType), spec: DragSourceSpec<RequiredProps, DragObject>, collect: DragSourceCollector<CollectedProps, RequiredProps>, options?: DndOptions<RequiredProps>): DndComponentEnhancer<CollectedProps>; |
@@ -6,3 +6,3 @@ import checkDecoratorArguments from './utils/checkDecoratorArguments'; | ||
import DragSourceMonitorImpl from './DragSourceMonitorImpl'; | ||
import createSourceConnector from './createSourceConnector'; | ||
import SourceConnector from './SourceConnector'; | ||
import isValidType from './utils/isValidType'; | ||
@@ -45,4 +45,4 @@ const invariant = require('invariant'); | ||
registerHandler: registerSource, | ||
createConnector: (backend) => new SourceConnector(backend), | ||
createMonitor: (manager) => new DragSourceMonitorImpl(manager), | ||
createConnector: createSourceConnector, | ||
DecoratedComponent, | ||
@@ -49,0 +49,0 @@ getType, |
@@ -1,4 +0,3 @@ | ||
import * as React from 'react'; | ||
import { TargetType } from 'dnd-core'; | ||
import { DropTargetSpec, DndOptions, DropTargetCollector, DndComponentClass } from './interfaces'; | ||
export default function DropTarget<Props, CollectedProps = {}>(type: TargetType | ((props: Props) => TargetType), spec: DropTargetSpec<Props>, collect: DropTargetCollector<CollectedProps>, options?: DndOptions<Props>): <T>(DecoratedComponent: React.ComponentType<T>) => DndComponentClass<Props>; | ||
import { DropTargetSpec, DndOptions, DropTargetCollector, DndComponentEnhancer } from './interfaces'; | ||
export default function DropTarget<RequiredProps, CollectedProps = {}>(type: TargetType | ((props: RequiredProps) => TargetType), spec: DropTargetSpec<RequiredProps>, collect: DropTargetCollector<CollectedProps, RequiredProps>, options?: DndOptions<RequiredProps>): DndComponentEnhancer<CollectedProps>; |
@@ -5,5 +5,5 @@ import checkDecoratorArguments from './utils/checkDecoratorArguments'; | ||
import createTargetFactory from './createTargetFactory'; | ||
import createTargetConnector from './createTargetConnector'; | ||
import isValidType from './utils/isValidType'; | ||
import DropTargetMonitorImpl from './DropTargetMonitorImpl'; | ||
import TargetConnector from './TargetConnector'; | ||
const invariant = require('invariant'); | ||
@@ -39,3 +39,3 @@ const isPlainObject = require('lodash/isPlainObject'); | ||
createMonitor: (manager) => new DropTargetMonitorImpl(manager), | ||
createConnector: createTargetConnector, | ||
createConnector: (backend) => new TargetConnector(backend), | ||
DecoratedComponent, | ||
@@ -42,0 +42,0 @@ getType, |
export * from './useDrag'; | ||
export * from './useDrop'; | ||
export * from './useDragLayer'; | ||
export * from './useDragPreview'; |
export * from './useDrag'; | ||
export * from './useDrop'; | ||
export * from './useDragLayer'; | ||
export * from './useDragPreview'; |
@@ -1,1 +0,7 @@ | ||
export declare function useCollector<T, S>(monitor: T, collect: (monitor: T) => S): [S, () => void]; | ||
/** | ||
* | ||
* @param monitor The monitor to colelct state from | ||
* @param collect The collecting function | ||
* @param onUpdate A method to invoke when updates occur | ||
*/ | ||
export declare function useCollector<T, S>(monitor: T, collect: (monitor: T) => S, onUpdate?: () => void): [S, () => void]; |
@@ -0,12 +1,25 @@ | ||
// declare var require: any | ||
// const shallowEqual = require('shallowequal') | ||
import { useState } from 'react'; | ||
const shallowEqual = require('shallowequal'); | ||
export function useCollector(monitor, collect) { | ||
/** | ||
* | ||
* @param monitor The monitor to colelct state from | ||
* @param collect The collecting function | ||
* @param onUpdate A method to invoke when updates occur | ||
*/ | ||
export function useCollector(monitor, collect, onUpdate) { | ||
const [collected, setCollected] = useState(() => collect(monitor)); | ||
const updateCollected = () => { | ||
const nextValue = collect(monitor); | ||
if (!shallowEqual(collected, nextValue)) { | ||
setCollected(nextValue); | ||
// TODO: we need this shallowequal check to work | ||
// so that we can operate performantly, but the examples | ||
// are broken with it in currently | ||
// if (!shallowEqual(collected, nextValue)) { | ||
setCollected(nextValue); | ||
if (onUpdate) { | ||
onUpdate(); | ||
} | ||
// } | ||
}; | ||
return [collected, updateCollected]; | ||
} |
@@ -1,3 +0,2 @@ | ||
import { HandlerManager } from '../../interfaces'; | ||
import { DragDropMonitor } from 'dnd-core'; | ||
export declare function useMonitorOutput<Monitor extends DragDropMonitor & HandlerManager, Collected>(monitor: Monitor, collect: (monitor: Monitor) => Collected): Collected; | ||
import { HandlerManager, MonitorEventEmitter } from '../../interfaces'; | ||
export declare function useMonitorOutput<Monitor extends HandlerManager, Collected>(monitor: Monitor & MonitorEventEmitter, collect: (monitor: Monitor) => Collected, onCollect?: () => void): Collected; |
import { useEffect } from 'react'; | ||
import { useCollector } from './useCollector'; | ||
export function useMonitorOutput(monitor, collect) { | ||
const [collected, updateCollected] = useCollector(monitor, collect); | ||
// This runs on every render. There will be ways to optimise this, but for | ||
// now, this is the most correct thing to do. | ||
export function useMonitorOutput(monitor, collect, onCollect) { | ||
const [collected, updateCollected] = useCollector(monitor, collect, onCollect); | ||
useEffect(function subscribeToMonitorStateChange() { | ||
@@ -12,7 +10,8 @@ const handlerId = monitor.getHandlerId(); | ||
} | ||
return monitor.subscribeToStateChange(updateCollected, { | ||
const unsubscribe = monitor.subscribeToStateChange(updateCollected, { | ||
handlerIds: [handlerId], | ||
}); | ||
}); | ||
return unsubscribe; | ||
}, [monitor]); | ||
return collected; | ||
} |
@@ -1,3 +0,2 @@ | ||
/// <reference types="react" /> | ||
import { DragSourceHookSpec, DragObjectWithType } from '../interfaces'; | ||
import { DragSourceHookSpec, DragObjectWithType, ConnectDragSource, ConnectDragPreview } from '../interfaces'; | ||
/** | ||
@@ -7,2 +6,2 @@ * useDragSource hook (This API is experimental and subject to breaking changes in non-major versions) | ||
*/ | ||
export declare function useDrag<DragObject extends DragObjectWithType, DropResult, CollectedProps>(spec: DragSourceHookSpec<DragObject, DropResult, CollectedProps>): [CollectedProps, React.RefObject<any>]; | ||
export declare function useDrag<DragObject extends DragObjectWithType, DropResult, CollectedProps>(spec: DragSourceHookSpec<DragObject, DropResult, CollectedProps>): [CollectedProps, ConnectDragSource, ConnectDragPreview]; |
@@ -1,6 +0,4 @@ | ||
import { useEffect, useRef } from 'react'; | ||
import { useDragSourceMonitor } from './internal/useDragSourceMonitor'; | ||
import { useDragDropManager } from './internal/useDragDropManager'; | ||
import { isRef } from './util'; | ||
import { useMonitorOutput } from './internal/useMonitorOutput'; | ||
import { useDragSourceMonitor, useDragHandler } from './internal/drag'; | ||
import { useEffect, useRef, useMemo } from 'react'; | ||
const invariant = require('invariant'); | ||
@@ -12,34 +10,24 @@ /** | ||
export function useDrag(spec) { | ||
const { item, options, preview, previewOptions, collect } = spec; | ||
let { ref } = spec; | ||
invariant(item != null, 'item must be defined'); | ||
invariant(item.type != null, 'item type must be defined'); | ||
const manager = useDragDropManager(); | ||
const backend = manager.getBackend(); | ||
const monitor = useDragSourceMonitor(manager, spec); | ||
if (!ref) { | ||
ref = useRef(null); | ||
} | ||
/* | ||
* Connect the Drag Source Element to the Backend | ||
*/ | ||
useEffect(function connectDragSource() { | ||
const node = ref.current; | ||
return backend.connectDragSource(monitor.getHandlerId(), node, options); | ||
}, []); | ||
/* | ||
* Connect the Drag Preview Element to the Backend | ||
*/ | ||
useEffect(function connectDragPreview() { | ||
if (preview) { | ||
const previewNode = isRef(preview) | ||
? preview.current | ||
: preview; | ||
return backend.connectDragPreview(monitor.getHandlerId(), previewNode, previewOptions); | ||
} | ||
}, [preview && preview.current]); | ||
const result = collect | ||
? useMonitorOutput(monitor, collect) | ||
: {}; | ||
return [result, ref]; | ||
const specRef = useRef(spec); | ||
// TODO: wire options into createSourceConnector | ||
invariant(spec.item != null, 'item must be defined'); | ||
invariant(spec.item.type != null, 'item type must be defined'); | ||
const [monitor, connector] = useDragSourceMonitor(); | ||
useDragHandler(specRef, monitor, connector); | ||
const result = useMonitorOutput(monitor, specRef.current.collect || (() => ({})), () => connector.reconnect()); | ||
const connectDragSource = useMemo(() => connector.hooks.dragSource(), [ | ||
connector, | ||
]); | ||
const connectDragPreview = useMemo(() => connector.hooks.dragPreview(), [ | ||
connector, | ||
]); | ||
useEffect(() => { | ||
connector.dragSourceOptions = specRef.current.options || null; | ||
connector.reconnect(); | ||
}, [connector]); | ||
useEffect(() => { | ||
connector.dragPreviewOptions = specRef.current.previewOptions || null; | ||
connector.reconnect(); | ||
}, [connector]); | ||
return [result, connectDragSource, connectDragPreview]; | ||
} |
@@ -1,3 +0,2 @@ | ||
/// <reference types="react" /> | ||
import { DropTargetHookSpec } from '../interfaces'; | ||
import { DropTargetHookSpec, ConnectDropTarget, DragObjectWithType } from '../interfaces'; | ||
/** | ||
@@ -7,2 +6,2 @@ * useDropTarget Hook (This API is experimental and subject to breaking changes in non-breaking versions) | ||
*/ | ||
export declare function useDrop<DragObject, DropResult, CollectedProps>(spec: DropTargetHookSpec<DragObject, DropResult, CollectedProps>): [CollectedProps, React.RefObject<any>]; | ||
export declare function useDrop<DragObject extends DragObjectWithType, DropResult, CollectedProps>(spec: DropTargetHookSpec<DragObject, DropResult, CollectedProps>): [CollectedProps, ConnectDropTarget]; |
@@ -1,5 +0,4 @@ | ||
import { useEffect, useRef } from 'react'; | ||
import { useDragDropManager } from './internal/useDragDropManager'; | ||
import { useDropTargetMonitor } from './internal/useDropTargetMonitor'; | ||
import { useMonitorOutput } from './internal/useMonitorOutput'; | ||
import { useDropHandler, useDropTargetMonitor } from './internal/drop'; | ||
import { useEffect, useRef, useMemo } from 'react'; | ||
const invariant = require('invariant'); | ||
@@ -11,26 +10,15 @@ /** | ||
export function useDrop(spec) { | ||
const { accept, options, collect } = spec; | ||
invariant(accept != null, 'accept must be defined'); | ||
let { ref } = spec; | ||
if (!ref) { | ||
ref = useRef(null); | ||
} | ||
const manager = useDragDropManager(); | ||
const backend = manager.getBackend(); | ||
const monitor = useDropTargetMonitor(manager, spec); | ||
/* | ||
* Connect the Drop Target Element to the Backend | ||
*/ | ||
useEffect(function connectDropTarget() { | ||
if (ref.current) { | ||
const node = ref.current; | ||
if (node) { | ||
return backend.connectDropTarget(monitor.getHandlerId(), node, options); | ||
} | ||
} | ||
}); | ||
const result = collect | ||
? useMonitorOutput(monitor, collect) | ||
: {}; | ||
return [result, ref]; | ||
const specRef = useRef(spec); | ||
invariant(spec.accept != null, 'accept must be defined'); | ||
const [monitor, connector] = useDropTargetMonitor(); | ||
useDropHandler(specRef, monitor, connector); | ||
const result = useMonitorOutput(monitor, specRef.current.collect || (() => ({})), () => connector.reconnect()); | ||
const connectDropTarget = useMemo(() => connector.hooks.dropTarget(), [ | ||
connector, | ||
]); | ||
useEffect(() => { | ||
connector.dropTargetOptions = spec.options || null; | ||
connector.reconnect(); | ||
}, [spec.options]); | ||
return [result, connectDropTarget]; | ||
} |
@@ -5,4 +5,5 @@ export { DragDropContext, DragDropContextProvider, Consumer as DragDropContextConsumer, DragDropContextProviderProps, } from './DragDropContext'; | ||
export { default as DropTarget } from './DropTarget'; | ||
export { default as DragPreviewImage } from './DragPreviewImage'; | ||
export * from './interfaces'; | ||
import { useDrag, useDragLayer, useDrop, useDragPreview } from './hooks'; | ||
import { useDrag, useDragLayer, useDrop } from './hooks'; | ||
export declare const __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__: { | ||
@@ -12,3 +13,2 @@ useDrag: typeof useDrag; | ||
useDrop: typeof useDrop; | ||
useDragPreview: typeof useDragPreview; | ||
}; |
@@ -5,3 +5,4 @@ export { DragDropContext, DragDropContextProvider, Consumer as DragDropContextConsumer, } from './DragDropContext'; | ||
export { default as DropTarget } from './DropTarget'; | ||
import { useDrag, useDragLayer, useDrop, useDragPreview } from './hooks'; | ||
export { default as DragPreviewImage } from './DragPreviewImage'; | ||
import { useDrag, useDragLayer, useDrop } from './hooks'; | ||
export const __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__ = { | ||
@@ -11,3 +12,2 @@ useDrag, | ||
useDrop, | ||
useDragPreview, | ||
}; |
@@ -1,5 +0,6 @@ | ||
/// <reference types="react" /> | ||
import * as React from 'react'; | ||
import { DragDropManager, Identifier } from 'dnd-core'; | ||
import { DropTargetMonitor, DragSourceMonitor, DragLayerMonitor } from './monitors'; | ||
import { DragSourceOptions, DragPreviewOptions } from './options'; | ||
import { NonReactStatics } from 'hoist-non-react-statics'; | ||
/** | ||
@@ -27,9 +28,2 @@ * The React Component that manages the DragDropContext for its children. | ||
/** | ||
* The class interface for a DnD component | ||
*/ | ||
export interface DndComponentClass<Props> extends React.ComponentClass<Props> { | ||
DecoratedComponent: React.ComponentType<Props>; | ||
new (props?: Props, context?: any): DndComponent<Props>; | ||
} | ||
/** | ||
* Interface for the DropTarget specification object | ||
@@ -101,6 +95,7 @@ */ | ||
} | ||
export declare type ConnectedElement = React.ReactElement | Element | null; | ||
export declare type DragElementWrapper<Options> = <Props>(elementOrNode: ConnectedElement, options?: Options) => React.ReactElement<Props>; | ||
export declare type ConnectableElement = React.RefObject<any> | React.ReactElement | Element | null; | ||
export declare type DragElementWrapper<Options> = (elementOrNode: ConnectableElement, options?: Options) => React.ReactElement | null; | ||
export declare type ConnectDragSource = DragElementWrapper<DragSourceOptions>; | ||
export declare type ConnectDragPreview = DragElementWrapper<DragPreviewOptions>; | ||
export declare type ConnectDropTarget = DragElementWrapper<any>; | ||
/** | ||
@@ -116,5 +111,2 @@ * DragSourceConnector is an object passed to a collecting function of the DragSource. | ||
* the render function. | ||
* | ||
* @param elementOrNode | ||
* @param options | ||
*/ | ||
@@ -147,5 +139,41 @@ dragSource(): ConnectDragSource; | ||
} | ||
export declare type ConnectDropTarget = <Props>(elementOrNode: ConnectedElement) => React.ReactElement<Props>; | ||
export declare type DragSourceCollector<CollectedProps> = (connect: DragSourceConnector, monitor: DragSourceMonitor) => CollectedProps; | ||
export declare type DropTargetCollector<CollectedProps> = (connect: DropTargetConnector, monitor: DropTargetMonitor) => CollectedProps; | ||
export declare type DragSourceCollector<CollectedProps, TargetProps> = (connect: DragSourceConnector, monitor: DragSourceMonitor, props: TargetProps) => CollectedProps; | ||
export declare type DropTargetCollector<CollectedProps, TargetProps> = (connect: DropTargetConnector, monitor: DropTargetMonitor, props: TargetProps) => CollectedProps; | ||
export declare type DragLayerCollector<TargetProps, CollectedProps> = (monitor: DragLayerMonitor, props: TargetProps) => CollectedProps; | ||
export declare type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; | ||
/** | ||
* A property P will be present if: | ||
* - it is present in DecorationTargetProps | ||
* | ||
* Its value will be dependent on the following conditions | ||
* - if property P is present in InjectedProps and its definition extends the definition | ||
* in DecorationTargetProps, then its definition will be that of DecorationTargetProps[P] | ||
* - if property P is not present in InjectedProps then its definition will be that of | ||
* DecorationTargetProps[P] | ||
* - if property P is present in InjectedProps but does not extend the | ||
* DecorationTargetProps[P] definition, its definition will be that of InjectedProps[P] | ||
*/ | ||
export declare type Matching<InjectedProps, DecorationTargetProps> = { | ||
[P in keyof DecorationTargetProps]: P extends keyof InjectedProps ? InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : InjectedProps[P] : DecorationTargetProps[P]; | ||
}; | ||
/** | ||
* a property P will be present if : | ||
* - it is present in both DecorationTargetProps and InjectedProps | ||
* - InjectedProps[P] can satisfy DecorationTargetProps[P] | ||
* ie: decorated component can accept more types than decorator is injecting | ||
* | ||
* For decoration, inject props or ownProps are all optionally | ||
* required by the decorated (right hand side) component. | ||
* But any property required by the decorated component must be satisfied by the injected property. | ||
*/ | ||
export declare type Shared<InjectedProps, DecorationTargetProps extends Shared<InjectedProps, DecorationTargetProps>> = { | ||
[P in Extract<keyof InjectedProps, keyof DecorationTargetProps>]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; | ||
}; | ||
/** | ||
* Gets the props interface of a component using inference | ||
*/ | ||
export declare type GetProps<C> = C extends React.ComponentType<infer P> ? P : never; | ||
export declare type DndComponentEnhancer<CollectedProps> = <C extends React.ComponentType<Matching<CollectedProps, GetProps<C>>>>(component: C) => DndComponentClass<C, Omit<GetProps<C>, keyof Shared<CollectedProps, GetProps<C>>>>; | ||
export declare type DndComponentClass<C extends React.ComponentType<any>, P> = React.ComponentClass<JSX.LibraryManagedAttributes<C, P>> & NonReactStatics<C> & { | ||
DecoratedComponent: C; | ||
}; |
import { TargetType, SourceType } from 'dnd-core'; | ||
import { DropTargetMonitor, DragSourceMonitor } from './monitors'; | ||
import { RefObject } from 'react'; | ||
import { DragSourceOptions, DragPreviewOptions } from './options'; | ||
export interface DragSourceHookSpec<DragObject extends DragObjectWithType, DropResult, CollectedProps> { | ||
/** | ||
* The ref object to associated with this dragged itom. If this is not specified it will be | ||
* returned in the `ref` field of the result object. | ||
*/ | ||
ref?: RefObject<any>; | ||
/** | ||
* A plain javascript item describing the data being dragged. | ||
@@ -28,6 +22,2 @@ * This is the only information available to the drop targets about the drag | ||
/** | ||
* An optional dragPreview | ||
*/ | ||
preview?: RefObject<any> | Element; | ||
/** | ||
* DragPreview options | ||
@@ -39,3 +29,3 @@ */ | ||
*/ | ||
begin?: (monitor: DragSourceMonitor) => DragObject | undefined; | ||
begin?: (monitor: DragSourceMonitor) => DragObject | undefined | void; | ||
/** | ||
@@ -78,7 +68,2 @@ * Optional. | ||
/** | ||
* The ref object to associated with this dragged itom. If this is not specified it will be | ||
* returned in the `ref` field of the result object. | ||
*/ | ||
ref?: RefObject<any>; | ||
/** | ||
* The kinds of dragItems this dropTarget accepts | ||
@@ -85,0 +70,0 @@ */ |
@@ -1,2 +0,2 @@ | ||
import { Identifier, XYCoord } from 'dnd-core'; | ||
import { Identifier, XYCoord, Unsubscribe } from 'dnd-core'; | ||
export interface HandlerManager { | ||
@@ -6,3 +6,3 @@ receiveHandlerId: (handlerId: Identifier | null) => void; | ||
} | ||
export interface DragSourceMonitor extends HandlerManager { | ||
export interface DragSourceMonitor extends HandlerManager, MonitorEventEmitter { | ||
/** | ||
@@ -60,3 +60,8 @@ * Returns true if no drag operation is in progress, and the owner's canDrag() returns true or is not defined. | ||
} | ||
export interface DropTargetMonitor extends HandlerManager { | ||
export interface MonitorEventEmitter { | ||
subscribeToStateChange(fn: () => void, options?: { | ||
handlerIds?: Identifier[]; | ||
}): Unsubscribe; | ||
} | ||
export interface DropTargetMonitor extends HandlerManager, MonitorEventEmitter { | ||
/** | ||
@@ -63,0 +68,0 @@ * Returns true if there is a drag operation in progress, and the owner's canDrop() returns true or is not defined. |
import { DragDropManager, DragSource, Unsubscribe, Identifier, SourceType } from 'dnd-core'; | ||
export default function registerSource<Context>(type: SourceType, source: DragSource, manager: DragDropManager<Context>): { | ||
handlerId: Identifier; | ||
unregister: Unsubscribe; | ||
}; | ||
export default function registerSource<Context>(type: SourceType, source: DragSource, manager: DragDropManager<Context>): [Identifier, Unsubscribe]; |
export default function registerSource(type, source, manager) { | ||
const registry = manager.getRegistry(); | ||
const sourceId = registry.addSource(type, source); | ||
return { | ||
handlerId: sourceId, | ||
unregister: () => registry.removeSource(sourceId), | ||
}; | ||
return [sourceId, () => registry.removeSource(sourceId)]; | ||
} |
import { DragDropManager, DropTarget, Unsubscribe, Identifier, TargetType } from 'dnd-core'; | ||
export default function registerTarget<Context>(type: TargetType, target: DropTarget, manager: DragDropManager<Context>): { | ||
handlerId: Identifier; | ||
unregister: Unsubscribe; | ||
}; | ||
export default function registerTarget<Context>(type: TargetType, target: DropTarget, manager: DragDropManager<Context>): [Identifier, Unsubscribe]; |
export default function registerTarget(type, target, manager) { | ||
const registry = manager.getRegistry(); | ||
const targetId = registry.addTarget(type, target); | ||
return { | ||
handlerId: targetId, | ||
unregister: () => registry.removeTarget(targetId), | ||
}; | ||
return [targetId, () => registry.removeTarget(targetId)]; | ||
} |
@@ -20,3 +20,5 @@ import { isValidElement } from 'react'; | ||
hook(node, options); | ||
return undefined; | ||
// return the node so it can be chained (e.g. when within callback refs | ||
// <div ref={node => connectDragSource(connectDropTarget(node))}/> | ||
return node; | ||
} | ||
@@ -37,6 +39,12 @@ // If passed a ReactElement, clone it and attach this function as a ref. | ||
const hook = hooks[key]; | ||
const wrappedHook = wrapHookToRecognizeElement(hook); | ||
wrappedHooks[key] = () => wrappedHook; | ||
// ref objects should be passed straight through without wrapping | ||
if (key.endsWith('Ref')) { | ||
wrappedHooks[key] = hooks[key]; | ||
} | ||
else { | ||
const wrappedHook = wrapHookToRecognizeElement(hook); | ||
wrappedHooks[key] = () => wrappedHook; | ||
} | ||
}); | ||
return wrappedHooks; | ||
} |
{ | ||
"name": "react-dnd", | ||
"version": "7.3.2", | ||
"version": "7.4.0", | ||
"description": "Drag and Drop for React", | ||
@@ -21,7 +21,6 @@ "main": "lib/cjs/index.js", | ||
"test": "run-s clean build", | ||
"watch": "tsc -w --preserveWatchOutput", | ||
"start": "npm run watch" | ||
"start": "tsc -b tsconfig.cjs.json -w --preserveWatchOutput" | ||
}, | ||
"dependencies": { | ||
"dnd-core": "^7.2.0", | ||
"dnd-core": "^7.4.0", | ||
"hoist-non-react-statics": "^3.3.0", | ||
@@ -36,2 +35,3 @@ "invariant": "^2.1.0", | ||
"@babel/core": "^7.3.4", | ||
"@types/hoist-non-react-statics": "^3.3.0", | ||
"@types/react": "^16.8.7", | ||
@@ -53,3 +53,3 @@ "@types/react-dom": "^16.8.2", | ||
}, | ||
"gitHead": "e3fb069a3f6eac67821cd24c487f5e580b728abf" | ||
"gitHead": "941dc2eb67e41ad924a31e4cbb793fa5dd3add71" | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
71
177
614978
14
7388
Updateddnd-core@^7.4.0