Add yet-another-react-lightbox package and update .gitignore to exclude node_modules

This commit is contained in:
IGNY8 VPS (Salman)
2025-11-12 18:50:30 +00:00
parent bd2a5570a9
commit c92f4a5edd
9304 changed files with 29 additions and 2008667 deletions

View File

@@ -1,16 +0,0 @@
import type { DragDropManager } from 'dnd-core'
import { createContext } from 'react'
/**
* The React context type
*/
export interface DndContextType {
dragDropManager: DragDropManager | undefined
}
/**
* Create the React Context
*/
export const DndContext = createContext<DndContextType>({
dragDropManager: undefined,
})

View File

@@ -1,93 +0,0 @@
import type { BackendFactory, DragDropManager } from 'dnd-core'
import { createDragDropManager } from 'dnd-core'
import type { FC, ReactNode } from 'react'
import { memo, useEffect } from 'react'
import { DndContext } from './DndContext.js'
export type DndProviderProps<BackendContext, BackendOptions> =
| {
children?: ReactNode
manager: DragDropManager
}
| {
backend: BackendFactory
children?: ReactNode
context?: BackendContext
options?: BackendOptions
debugMode?: boolean
}
let refCount = 0
const INSTANCE_SYM = Symbol.for('__REACT_DND_CONTEXT_INSTANCE__')
/**
* A React component that provides the React-DnD context
*/
export const DndProvider: FC<DndProviderProps<unknown, unknown>> = memo(
function DndProvider({ children, ...props }) {
const [manager, isGlobalInstance] = getDndContextValue(props) // memoized from props
/**
* If the global context was used to store the DND context
* then where theres no more references to it we should
* clean it up to avoid memory leaks
*/
useEffect(() => {
if (isGlobalInstance) {
const context = getGlobalContext()
++refCount
return () => {
if (--refCount === 0) {
context[INSTANCE_SYM] = null
}
}
}
return
}, [])
return <DndContext.Provider value={manager}>{children}</DndContext.Provider>
},
)
function getDndContextValue(props: DndProviderProps<unknown, unknown>) {
if ('manager' in props) {
const manager = { dragDropManager: props.manager }
return [manager, false]
}
const manager = createSingletonDndContext(
props.backend,
props.context,
props.options,
props.debugMode,
)
const isGlobalInstance = !props.context
return [manager, isGlobalInstance]
}
function createSingletonDndContext<BackendContext, BackendOptions>(
backend: BackendFactory,
context: BackendContext = getGlobalContext(),
options: BackendOptions,
debugMode?: boolean,
) {
const ctx = context as any
if (!ctx[INSTANCE_SYM]) {
ctx[INSTANCE_SYM] = {
dragDropManager: createDragDropManager(
backend,
context,
options,
debugMode,
),
}
}
return ctx[INSTANCE_SYM]
}
declare const global: any
function getGlobalContext() {
return typeof global !== 'undefined' ? global : (window as any)
}

View File

@@ -1,34 +0,0 @@
import type { FC } from 'react'
import { memo, useEffect } from 'react'
import type { ConnectDragPreview } from '../types/index.js'
export interface DragPreviewImageProps {
connect: ConnectDragPreview
src: string
}
/**
* A utility for rendering a drag preview image
*/
export const DragPreviewImage: FC<DragPreviewImageProps> = memo(
function DragPreviewImage({ connect, src }) {
useEffect(() => {
if (typeof Image === 'undefined') return
let connected = false
const img = new Image()
img.src = src
img.onload = () => {
connect(img)
connected = true
}
return () => {
if (connected) {
connect(null)
}
}
})
return null
},
)

View File

@@ -1,3 +0,0 @@
export * from './DndContext.js'
export * from './DndProvider.js'
export * from './DragPreviewImage.js'

View File

@@ -1,5 +0,0 @@
export * from './types.js'
export * from './useDrag/index.js'
export * from './useDragDropManager.js'
export * from './useDragLayer.js'
export * from './useDrop/index.js'

View File

@@ -1,147 +0,0 @@
import type { SourceType, TargetType } from 'dnd-core'
import type {
DragPreviewOptions,
DragSourceMonitor,
DragSourceOptions,
DropTargetMonitor,
DropTargetOptions,
} from '../types/index.js'
export type FactoryOrInstance<T> = T | (() => T)
export type DragObjectFactory<T> = (monitor: DragSourceMonitor<T>) => T | null
export interface DragSourceHookSpec<DragObject, DropResult, CollectedProps> {
/**
* The type of item being dragged. This is required when using the function form of spec.item.
* If spec.item is a static object, the type may either be defined on that object as `item.type`, or it may
* be defined here.
*/
type: SourceType
/**
* This property generates or defines a plain javascript item describing
* the data being dragged. This is the only information available to the
* drop targets about the drag source so it's important to pick the minimal
* data they need to know.
*
* You may be tempted to put a reference to the component or complex object here,
* but you should try very hard to avoid doing this because it couples the
* drag sources and drop targets. It's a good idea to use something like
* { id: props.id }
*
* If a function-form is used, it is invoked when the drag begins and returns a draggable item.
* If the function returns null, the drag is canceled
*
*/
item?: DragObject | DragObjectFactory<DragObject>
/**
* The drag source options
*/
options?: DragSourceOptions
/**
* DragPreview options
*/
previewOptions?: DragPreviewOptions
/**
* Optional.
* When the dragging stops, endDrag is called. For every beginDrag call, a corresponding endDrag call is guaranteed.
* You may call monitor.didDrop() to check whether or not the drop was handled by a compatible drop target. If it was handled,
* and the drop target specified a drop result by returning a plain object from its drop() method, it will be available as
* monitor.getDropResult(). This method is a good place to fire a Flux action. Note: If the component is unmounted while dragging,
* component parameter is set to be null.
*/
end?: (
draggedItem: DragObject,
monitor: DragSourceMonitor<DragObject, DropResult>,
) => void
/**
* Optional.
* Use it to specify whether the dragging is currently allowed. If you want to always allow it, just omit this method.
* Specifying it is handy if you'd like to disable dragging based on some predicate over props. Note: You may not call
* monitor.canDrag() inside this method.
*/
canDrag?:
| boolean
| ((monitor: DragSourceMonitor<DragObject, DropResult>) => boolean)
/**
* Optional.
* By default, only the drag source that initiated the drag operation is considered to be dragging. You can
* override this behavior by defining a custom isDragging method. It might return something like props.id === monitor.getItem().id.
* Do this if the original component may be unmounted during the dragging and later “resurrected” with a different parent.
* For example, when moving a card across the lists in a Kanban board, you want it to retain the dragged appearance—even though
* technically, the component gets unmounted and a different one gets mounted every time you move it to another list.
*
* Note: You may not call monitor.isDragging() inside this method.
*/
isDragging?: (monitor: DragSourceMonitor<DragObject, DropResult>) => boolean
/**
* A function to collect rendering properties
*/
collect?: (
monitor: DragSourceMonitor<DragObject, DropResult>,
) => CollectedProps
}
/**
* Interface for the DropTarget specification object
*/
export interface DropTargetHookSpec<DragObject, DropResult, CollectedProps> {
/**
* The kinds of dragItems this dropTarget accepts
*/
accept: TargetType
/**
* The drop target options
*/
options?: DropTargetOptions
/**
* Optional.
* Called when a compatible item is dropped on the target. You may either return undefined, or a plain object.
* If you return an object, it is going to become the drop result and will be available to the drag source in its
* endDrag method as monitor.getDropResult(). This is useful in case you want to perform different actions
* depending on which target received the drop. If you have nested drop targets, you can test whether a nested
* target has already handled drop by checking monitor.didDrop() and monitor.getDropResult(). Both this method and
* the source's endDrag method are good places to fire Flux actions. This method will not be called if canDrop()
* is defined and returns false.
*/
drop?: (
item: DragObject,
monitor: DropTargetMonitor<DragObject, DropResult>,
) => DropResult | undefined
/**
* Optional.
* Called when an item is hovered over the component. You can check monitor.isOver({ shallow: true }) to test whether
* the hover happens over just the current target, or over a nested one. Unlike drop(), this method will be called even
* if canDrop() is defined and returns false. You can check monitor.canDrop() to test whether this is the case.
*/
hover?: (
item: DragObject,
monitor: DropTargetMonitor<DragObject, DropResult>,
) => void
/**
* Optional. Use it to specify whether the drop target is able to accept the item. If you want to always allow it, just
* omit this method. Specifying it is handy if you'd like to disable dropping based on some predicate over props or
* monitor.getItem(). Note: You may not call monitor.canDrop() inside this method.
*/
canDrop?: (
item: DragObject,
monitor: DropTargetMonitor<DragObject, DropResult>,
) => boolean
/**
* A function to collect rendering properties
*/
collect?: (
monitor: DropTargetMonitor<DragObject, DropResult>,
) => CollectedProps
}

View File

@@ -1,13 +0,0 @@
import type { Connector } from '../internals/index.js'
import type { HandlerManager, MonitorEventEmitter } from '../types/index.js'
import { useMonitorOutput } from './useMonitorOutput.js'
export function useCollectedProps<Collected, Monitor extends HandlerManager>(
collector: ((monitor: Monitor) => Collected) | undefined,
monitor: Monitor & MonitorEventEmitter,
connector: Connector,
) {
return useMonitorOutput(monitor, collector || (() => ({} as Collected)), () =>
connector.reconnect(),
)
}

View File

@@ -1,37 +0,0 @@
import equal from 'fast-deep-equal'
import { useCallback, useState } from 'react'
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect.js'
/**
*
* @param monitor The monitor to collect state from
* @param collect The collecting function
* @param onUpdate A method to invoke when updates occur
*/
export function useCollector<T, S>(
monitor: T,
collect: (monitor: T) => S,
onUpdate?: () => void,
): [S, () => void] {
const [collected, setCollected] = useState(() => collect(monitor))
const updateCollected = useCallback(() => {
const nextValue = collect(monitor)
// This needs to be a deep-equality check because some monitor-collected values
// include XYCoord objects that may be equivalent, but do not have instance equality.
if (!equal(collected, nextValue)) {
setCollected(nextValue)
if (onUpdate) {
onUpdate()
}
}
}, [collected, monitor, onUpdate])
// update the collected properties after react renders.
// Note that the "Dustbin Stress Test" fails if this is not
// done when the component updates
useIsomorphicLayoutEffect(updateCollected)
return [collected, updateCollected]
}

View File

@@ -1,60 +0,0 @@
import type { DragDropMonitor, DragSource, Identifier } from 'dnd-core'
import type { Connector } from '../../internals/index.js'
import type { DragSourceMonitor } from '../../types/index.js'
import type { DragObjectFactory, DragSourceHookSpec } from '../types.js'
export class DragSourceImpl<O, R, P> implements DragSource {
public constructor(
public spec: DragSourceHookSpec<O, R, P>,
private monitor: DragSourceMonitor<O, R>,
private connector: Connector,
) {}
public beginDrag() {
const spec = this.spec
const monitor = this.monitor
let result: O | null = null
if (typeof spec.item === 'object') {
result = spec.item as O
} else if (typeof spec.item === 'function') {
result = (spec.item as DragObjectFactory<O>)(monitor)
} else {
result = {} as O
}
return result ?? null
}
public canDrag() {
const spec = this.spec
const monitor = this.monitor
if (typeof spec.canDrag === 'boolean') {
return spec.canDrag
} else if (typeof spec.canDrag === 'function') {
return spec.canDrag(monitor)
} else {
return true
}
}
public isDragging(globalMonitor: DragDropMonitor, target: Identifier) {
const spec = this.spec
const monitor = this.monitor
const { isDragging } = spec
return isDragging
? isDragging(monitor)
: target === globalMonitor.getSourceId()
}
public endDrag() {
const spec = this.spec
const monitor = this.monitor
const connector = this.connector
const { end } = spec
if (end) {
end(monitor.getItem(), monitor)
}
connector.reconnect()
}
}

View File

@@ -1,11 +0,0 @@
import { useMemo } from 'react'
import type { SourceConnector } from '../../internals/index.js'
export function useConnectDragSource(connector: SourceConnector) {
return useMemo(() => connector.hooks.dragSource(), [connector])
}
export function useConnectDragPreview(connector: SourceConnector) {
return useMemo(() => connector.hooks.dragPreview(), [connector])
}

View File

@@ -1 +0,0 @@
export * from './useDrag.js'

View File

@@ -1,45 +0,0 @@
import { invariant } from '@react-dnd/invariant'
import type {
ConnectDragPreview,
ConnectDragSource,
} from '../../types/index.js'
import type { DragSourceHookSpec, FactoryOrInstance } from '../types.js'
import { useCollectedProps } from '../useCollectedProps.js'
import { useOptionalFactory } from '../useOptionalFactory.js'
import { useConnectDragPreview, useConnectDragSource } from './connectors.js'
import { useDragSourceConnector } from './useDragSourceConnector.js'
import { useDragSourceMonitor } from './useDragSourceMonitor.js'
import { useRegisteredDragSource } from './useRegisteredDragSource.js'
/**
* useDragSource hook
* @param sourceSpec The drag source specification (object or function, function preferred)
* @param deps The memoization deps array to use when evaluating spec changes
*/
export function useDrag<
DragObject = unknown,
DropResult = unknown,
CollectedProps = unknown,
>(
specArg: FactoryOrInstance<
DragSourceHookSpec<DragObject, DropResult, CollectedProps>
>,
deps?: unknown[],
): [CollectedProps, ConnectDragSource, ConnectDragPreview] {
const spec = useOptionalFactory(specArg, deps)
invariant(
!(spec as any).begin,
`useDrag::spec.begin was deprecated in v14. Replace spec.begin() with spec.item(). (see more here - https://react-dnd.github.io/react-dnd/docs/api/use-drag)`,
)
const monitor = useDragSourceMonitor<DragObject, DropResult>()
const connector = useDragSourceConnector(spec.options, spec.previewOptions)
useRegisteredDragSource(spec, monitor, connector)
return [
useCollectedProps(spec.collect, monitor, connector),
useConnectDragSource(connector),
useConnectDragPreview(connector),
]
}

View File

@@ -1,21 +0,0 @@
import { useEffect, useMemo } from 'react'
import type { Connector } from '../../internals/index.js'
import type { DragSourceMonitor } from '../../types/index.js'
import type { DragSourceHookSpec } from '../types.js'
import { DragSourceImpl } from './DragSourceImpl.js'
export function useDragSource<O, R, P>(
spec: DragSourceHookSpec<O, R, P>,
monitor: DragSourceMonitor<O, R>,
connector: Connector,
) {
const handler = useMemo(
() => new DragSourceImpl(spec, monitor, connector),
[monitor, connector],
)
useEffect(() => {
handler.spec = spec
}, [spec])
return handler
}

View File

@@ -1,31 +0,0 @@
import { useMemo } from 'react'
import { SourceConnector } from '../../internals/index.js'
import type {
DragPreviewOptions,
DragSourceOptions,
} from '../../types/index.js'
import { useDragDropManager } from '../useDragDropManager.js'
import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect.js'
export function useDragSourceConnector(
dragSourceOptions: DragSourceOptions | undefined,
dragPreviewOptions: DragPreviewOptions | undefined,
): SourceConnector {
const manager = useDragDropManager()
const connector = useMemo(
() => new SourceConnector(manager.getBackend()),
[manager],
)
useIsomorphicLayoutEffect(() => {
connector.dragSourceOptions = dragSourceOptions || null
connector.reconnect()
return () => connector.disconnectDragSource()
}, [connector, dragSourceOptions])
useIsomorphicLayoutEffect(() => {
connector.dragPreviewOptions = dragPreviewOptions || null
connector.reconnect()
return () => connector.disconnectDragPreview()
}, [connector, dragPreviewOptions])
return connector
}

View File

@@ -1,13 +0,0 @@
import { useMemo } from 'react'
import { DragSourceMonitorImpl } from '../../internals/index.js'
import type { DragSourceMonitor } from '../../types/index.js'
import { useDragDropManager } from '../useDragDropManager.js'
export function useDragSourceMonitor<O, R>(): DragSourceMonitor<O, R> {
const manager = useDragDropManager()
return useMemo<DragSourceMonitor<O, R>>(
() => new DragSourceMonitorImpl(manager),
[manager],
)
}

View File

@@ -1,15 +0,0 @@
import { invariant } from '@react-dnd/invariant'
import type { Identifier } from 'dnd-core'
import { useMemo } from 'react'
import type { DragSourceHookSpec } from '../types.js'
export function useDragType(
spec: DragSourceHookSpec<any, any, any>,
): Identifier {
return useMemo(() => {
const result: Identifier = spec.type
invariant(result != null, 'spec.type must be defined')
return result
}, [spec])
}

View File

@@ -1,35 +0,0 @@
import type { SourceConnector } from '../../internals/index.js'
import { registerSource } from '../../internals/index.js'
import type { DragSourceMonitor } from '../../types/index.js'
import type { DragSourceHookSpec } from '../types.js'
import { useDragDropManager } from '../useDragDropManager.js'
import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect.js'
import { useDragSource } from './useDragSource.js'
import { useDragType } from './useDragType.js'
export function useRegisteredDragSource<O, R, P>(
spec: DragSourceHookSpec<O, R, P>,
monitor: DragSourceMonitor<O, R>,
connector: SourceConnector,
): void {
const manager = useDragDropManager()
const handler = useDragSource(spec, monitor, connector)
const itemType = useDragType(spec)
useIsomorphicLayoutEffect(
function registerDragSource() {
if (itemType != null) {
const [handlerId, unregister] = registerSource(
itemType,
handler,
manager,
)
monitor.receiveHandlerId(handlerId)
connector.receiveHandlerId(handlerId)
return unregister
}
return
},
[manager, monitor, connector, handler, itemType],
)
}

View File

@@ -1,14 +0,0 @@
import { invariant } from '@react-dnd/invariant'
import type { DragDropManager } from 'dnd-core'
import { useContext } from 'react'
import { DndContext } from '../core/index.js'
/**
* A hook to retrieve the DragDropManager from Context
*/
export function useDragDropManager(): DragDropManager {
const { dragDropManager } = useContext(DndContext)
invariant(dragDropManager != null, 'Expected drag drop context')
return dragDropManager as DragDropManager
}

View File

@@ -1,21 +0,0 @@
import { useEffect } from 'react'
import type { DragLayerMonitor } from '../types/index.js'
import { useCollector } from './useCollector.js'
import { useDragDropManager } from './useDragDropManager.js'
/**
* useDragLayer Hook
* @param collector The property collector
*/
export function useDragLayer<CollectedProps, DragObject = any>(
collect: (monitor: DragLayerMonitor<DragObject>) => CollectedProps,
): CollectedProps {
const dragDropManager = useDragDropManager()
const monitor = dragDropManager.getMonitor()
const [collected, updateCollected] = useCollector(monitor, collect)
useEffect(() => monitor.subscribeToOffsetChange(updateCollected))
useEffect(() => monitor.subscribeToStateChange(updateCollected))
return collected
}

View File

@@ -1,34 +0,0 @@
import type { DropTarget } from 'dnd-core'
import type { DropTargetMonitor } from '../../types/index.js'
import type { DropTargetHookSpec } from '../types.js'
export class DropTargetImpl<O, R, P> implements DropTarget {
public constructor(
public spec: DropTargetHookSpec<O, R, P>,
private monitor: DropTargetMonitor<O, R>,
) {}
public canDrop() {
const spec = this.spec
const monitor = this.monitor
return spec.canDrop ? spec.canDrop(monitor.getItem(), monitor) : true
}
public hover() {
const spec = this.spec
const monitor = this.monitor
if (spec.hover) {
spec.hover(monitor.getItem(), monitor)
}
}
public drop() {
const spec = this.spec
const monitor = this.monitor
if (spec.drop) {
return spec.drop(monitor.getItem(), monitor)
}
return
}
}

View File

@@ -1,7 +0,0 @@
import { useMemo } from 'react'
import type { TargetConnector } from '../../internals/index.js'
export function useConnectDropTarget(connector: TargetConnector) {
return useMemo(() => connector.hooks.dropTarget(), [connector])
}

View File

@@ -1 +0,0 @@
export * from './useDrop.js'

View File

@@ -1,20 +0,0 @@
import { invariant } from '@react-dnd/invariant'
import type { Identifier } from 'dnd-core'
import { useMemo } from 'react'
import type { DropTargetHookSpec } from '../types.js'
/**
* Internal utility hook to get an array-version of spec.accept.
* The main utility here is that we aren't creating a new array on every render if a non-array spec.accept is passed in.
* @param spec
*/
export function useAccept<O, R, P>(
spec: DropTargetHookSpec<O, R, P>,
): Identifier[] {
const { accept } = spec
return useMemo(() => {
invariant(spec.accept != null, 'accept must be defined')
return Array.isArray(accept) ? accept : [accept]
}, [accept])
}

View File

@@ -1,34 +0,0 @@
import type { ConnectDropTarget } from '../../types/index.js'
import type { DropTargetHookSpec, FactoryOrInstance } from '../types.js'
import { useCollectedProps } from '../useCollectedProps.js'
import { useOptionalFactory } from '../useOptionalFactory.js'
import { useConnectDropTarget } from './connectors.js'
import { useDropTargetConnector } from './useDropTargetConnector.js'
import { useDropTargetMonitor } from './useDropTargetMonitor.js'
import { useRegisteredDropTarget } from './useRegisteredDropTarget.js'
/**
* useDropTarget Hook
* @param spec The drop target specification (object or function, function preferred)
* @param deps The memoization deps array to use when evaluating spec changes
*/
export function useDrop<
DragObject = unknown,
DropResult = unknown,
CollectedProps = unknown,
>(
specArg: FactoryOrInstance<
DropTargetHookSpec<DragObject, DropResult, CollectedProps>
>,
deps?: unknown[],
): [CollectedProps, ConnectDropTarget] {
const spec = useOptionalFactory(specArg, deps)
const monitor = useDropTargetMonitor<DragObject, DropResult>()
const connector = useDropTargetConnector(spec.options)
useRegisteredDropTarget(spec, monitor, connector)
return [
useCollectedProps(spec.collect, monitor, connector),
useConnectDropTarget(connector),
]
}

View File

@@ -1,16 +0,0 @@
import { useEffect, useMemo } from 'react'
import type { DropTargetMonitor } from '../../types/index.js'
import type { DropTargetHookSpec } from '../types.js'
import { DropTargetImpl } from './DropTargetImpl.js'
export function useDropTarget<O, R, P>(
spec: DropTargetHookSpec<O, R, P>,
monitor: DropTargetMonitor<O, R>,
) {
const dropTarget = useMemo(() => new DropTargetImpl(spec, monitor), [monitor])
useEffect(() => {
dropTarget.spec = spec
}, [spec])
return dropTarget
}

View File

@@ -1,22 +0,0 @@
import { useMemo } from 'react'
import { TargetConnector } from '../../internals/index.js'
import type { DropTargetOptions } from '../../types/index.js'
import { useDragDropManager } from '../useDragDropManager.js'
import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect.js'
export function useDropTargetConnector(
options: DropTargetOptions,
): TargetConnector {
const manager = useDragDropManager()
const connector = useMemo(
() => new TargetConnector(manager.getBackend()),
[manager],
)
useIsomorphicLayoutEffect(() => {
connector.dropTargetOptions = options || null
connector.reconnect()
return () => connector.disconnectDropTarget()
}, [options])
return connector
}

View File

@@ -1,10 +0,0 @@
import { useMemo } from 'react'
import { DropTargetMonitorImpl } from '../../internals/index.js'
import type { DropTargetMonitor } from '../../types/index.js'
import { useDragDropManager } from '../useDragDropManager.js'
export function useDropTargetMonitor<O, R>(): DropTargetMonitor<O, R> {
const manager = useDragDropManager()
return useMemo(() => new DropTargetMonitorImpl(manager), [manager])
}

View File

@@ -1,38 +0,0 @@
import type { TargetConnector } from '../../internals/index.js'
import { registerTarget } from '../../internals/index.js'
import type { DropTargetMonitor } from '../../types/index.js'
import type { DropTargetHookSpec } from '../types.js'
import { useDragDropManager } from '../useDragDropManager.js'
import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect.js'
import { useAccept } from './useAccept.js'
import { useDropTarget } from './useDropTarget.js'
export function useRegisteredDropTarget<O, R, P>(
spec: DropTargetHookSpec<O, R, P>,
monitor: DropTargetMonitor<O, R>,
connector: TargetConnector,
): void {
const manager = useDragDropManager()
const dropTarget = useDropTarget(spec, monitor)
const accept = useAccept(spec)
useIsomorphicLayoutEffect(
function registerDropTarget() {
const [handlerId, unregister] = registerTarget(
accept,
dropTarget,
manager,
)
monitor.receiveHandlerId(handlerId)
connector.receiveHandlerId(handlerId)
return unregister
},
[
manager,
monitor,
dropTarget,
connector,
accept.map((a) => a.toString()).join('|'),
],
)
}

View File

@@ -1,5 +0,0 @@
import { useEffect, useLayoutEffect } from 'react'
// suppress the useLayoutEffect warning on server side.
export const useIsomorphicLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect

View File

@@ -1,26 +0,0 @@
import type { HandlerManager, MonitorEventEmitter } from '../types/index.js'
import { useCollector } from './useCollector.js'
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect.js'
export function useMonitorOutput<Monitor extends HandlerManager, Collected>(
monitor: Monitor & MonitorEventEmitter,
collect: (monitor: Monitor) => Collected,
onCollect?: () => void,
): Collected {
const [collected, updateCollected] = useCollector(monitor, collect, onCollect)
useIsomorphicLayoutEffect(
function subscribeToMonitorStateChange() {
const handlerId = monitor.getHandlerId()
if (handlerId == null) {
return
}
return monitor.subscribeToStateChange(updateCollected, {
handlerIds: [handlerId],
})
},
[monitor, updateCollected],
)
return collected
}

View File

@@ -1,16 +0,0 @@
import { useMemo } from 'react'
import type { FactoryOrInstance } from './types.js'
export function useOptionalFactory<T>(
arg: FactoryOrInstance<T>,
deps?: unknown[],
): T {
const memoDeps = [...(deps || [])]
if (deps == null && typeof arg !== 'function') {
memoDeps.push(arg)
}
return useMemo<T>(() => {
return typeof arg === 'function' ? (arg as () => T)() : (arg as T)
}, memoDeps)
}

View File

@@ -1,3 +0,0 @@
export * from './core/index.js'
export * from './hooks/index.js'
export * from './types/index.js'

View File

@@ -1,142 +0,0 @@
import { invariant } from '@react-dnd/invariant'
import type {
DragDropManager,
DragDropMonitor,
Identifier,
Listener,
Unsubscribe,
XYCoord,
} from 'dnd-core'
import type { DragSourceMonitor } from '../types/index.js'
let isCallingCanDrag = false
let isCallingIsDragging = false
export class DragSourceMonitorImpl implements DragSourceMonitor {
private internalMonitor: DragDropMonitor
private sourceId: Identifier | null = null
public constructor(manager: DragDropManager) {
this.internalMonitor = manager.getMonitor()
}
public receiveHandlerId(sourceId: Identifier | null): void {
this.sourceId = sourceId
}
public getHandlerId(): Identifier | null {
return this.sourceId
}
public canDrag(): boolean {
invariant(
!isCallingCanDrag,
'You may not call monitor.canDrag() inside your canDrag() implementation. ' +
'Read more: http://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor',
)
try {
isCallingCanDrag = true
return this.internalMonitor.canDragSource(this.sourceId as Identifier)
} finally {
isCallingCanDrag = false
}
}
public isDragging(): boolean {
if (!this.sourceId) {
return false
}
invariant(
!isCallingIsDragging,
'You may not call monitor.isDragging() inside your isDragging() implementation. ' +
'Read more: http://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor',
)
try {
isCallingIsDragging = true
return this.internalMonitor.isDraggingSource(this.sourceId)
} finally {
isCallingIsDragging = false
}
}
public subscribeToStateChange(
listener: Listener,
options?: { handlerIds?: Identifier[] },
): Unsubscribe {
return this.internalMonitor.subscribeToStateChange(listener, options)
}
public isDraggingSource(sourceId: Identifier): boolean {
return this.internalMonitor.isDraggingSource(sourceId)
}
public isOverTarget(
targetId: Identifier,
options?: { shallow: boolean },
): boolean {
return this.internalMonitor.isOverTarget(targetId, options)
}
public getTargetIds(): Identifier[] {
return this.internalMonitor.getTargetIds()
}
public isSourcePublic(): boolean | null {
return this.internalMonitor.isSourcePublic()
}
public getSourceId(): Identifier | null {
return this.internalMonitor.getSourceId()
}
public subscribeToOffsetChange(listener: Listener): Unsubscribe {
return this.internalMonitor.subscribeToOffsetChange(listener)
}
public canDragSource(sourceId: Identifier): boolean {
return this.internalMonitor.canDragSource(sourceId)
}
public canDropOnTarget(targetId: Identifier): boolean {
return this.internalMonitor.canDropOnTarget(targetId)
}
public getItemType(): Identifier | null {
return this.internalMonitor.getItemType()
}
public getItem(): any {
return this.internalMonitor.getItem()
}
public getDropResult(): any {
return this.internalMonitor.getDropResult()
}
public didDrop(): boolean {
return this.internalMonitor.didDrop()
}
public getInitialClientOffset(): XYCoord | null {
return this.internalMonitor.getInitialClientOffset()
}
public getInitialSourceClientOffset(): XYCoord | null {
return this.internalMonitor.getInitialSourceClientOffset()
}
public getSourceClientOffset(): XYCoord | null {
return this.internalMonitor.getSourceClientOffset()
}
public getClientOffset(): XYCoord | null {
return this.internalMonitor.getClientOffset()
}
public getDifferenceFromInitialOffset(): XYCoord | null {
return this.internalMonitor.getDifferenceFromInitialOffset()
}
}

View File

@@ -1,101 +0,0 @@
import { invariant } from '@react-dnd/invariant'
import type {
DragDropManager,
DragDropMonitor,
Identifier,
Listener,
Unsubscribe,
XYCoord,
} from 'dnd-core'
import type { DropTargetMonitor } from '../types/index.js'
let isCallingCanDrop = false
export class DropTargetMonitorImpl implements DropTargetMonitor {
private internalMonitor: DragDropMonitor
private targetId: Identifier | null = null
public constructor(manager: DragDropManager) {
this.internalMonitor = manager.getMonitor()
}
public receiveHandlerId(targetId: Identifier | null): void {
this.targetId = targetId
}
public getHandlerId(): Identifier | null {
return this.targetId
}
public subscribeToStateChange(
listener: Listener,
options?: { handlerIds?: Identifier[] },
): Unsubscribe {
return this.internalMonitor.subscribeToStateChange(listener, options)
}
public canDrop(): boolean {
// Cut out early if the target id has not been set. This should prevent errors
// where the user has an older version of dnd-core like in
// https://github.com/react-dnd/react-dnd/issues/1310
if (!this.targetId) {
return false
}
invariant(
!isCallingCanDrop,
'You may not call monitor.canDrop() inside your canDrop() implementation. ' +
'Read more: http://react-dnd.github.io/react-dnd/docs/api/drop-target-monitor',
)
try {
isCallingCanDrop = true
return this.internalMonitor.canDropOnTarget(this.targetId)
} finally {
isCallingCanDrop = false
}
}
public isOver(options?: { shallow?: boolean }): boolean {
if (!this.targetId) {
return false
}
return this.internalMonitor.isOverTarget(this.targetId, options)
}
public getItemType(): Identifier | null {
return this.internalMonitor.getItemType()
}
public getItem(): any {
return this.internalMonitor.getItem()
}
public getDropResult(): any {
return this.internalMonitor.getDropResult()
}
public didDrop(): boolean {
return this.internalMonitor.didDrop()
}
public getInitialClientOffset(): XYCoord | null {
return this.internalMonitor.getInitialClientOffset()
}
public getInitialSourceClientOffset(): XYCoord | null {
return this.internalMonitor.getInitialSourceClientOffset()
}
public getSourceClientOffset(): XYCoord | null {
return this.internalMonitor.getSourceClientOffset()
}
public getClientOffset(): XYCoord | null {
return this.internalMonitor.getClientOffset()
}
public getDifferenceFromInitialOffset(): XYCoord | null {
return this.internalMonitor.getDifferenceFromInitialOffset()
}
}

View File

@@ -1,231 +0,0 @@
import { shallowEqual } from '@react-dnd/shallowequal'
import type { Backend, Identifier, Unsubscribe } from 'dnd-core'
import type { ReactElement, Ref, RefObject } from 'react'
import type { DragPreviewOptions, DragSourceOptions } from '../types/index.js'
import { isRef } from './isRef.js'
import { wrapConnectorHooks } from './wrapConnectorHooks.js'
export interface Connector {
hooks: any
connectTarget: any
receiveHandlerId(handlerId: Identifier | null): void
reconnect(): void
}
export class SourceConnector implements Connector {
public hooks = wrapConnectorHooks({
dragSource: (
node: Element | ReactElement | Ref<any>,
options?: DragSourceOptions,
) => {
this.clearDragSource()
this.dragSourceOptions = options || null
if (isRef(node)) {
this.dragSourceRef = node as RefObject<any>
} else {
this.dragSourceNode = node
}
this.reconnectDragSource()
},
dragPreview: (node: any, options?: DragPreviewOptions) => {
this.clearDragPreview()
this.dragPreviewOptions = options || null
if (isRef(node)) {
this.dragPreviewRef = node
} else {
this.dragPreviewNode = node
}
this.reconnectDragPreview()
},
})
private handlerId: Identifier | null = null
// The drop target may either be attached via ref or connect function
private dragSourceRef: RefObject<any> | null = null
private dragSourceNode: any
private dragSourceOptionsInternal: DragSourceOptions | null = null
private dragSourceUnsubscribe: Unsubscribe | undefined
// The drag preview may either be attached via ref or connect function
private dragPreviewRef: RefObject<any> | null = null
private dragPreviewNode: any
private dragPreviewOptionsInternal: DragPreviewOptions | null = null
private dragPreviewUnsubscribe: Unsubscribe | undefined
private lastConnectedHandlerId: Identifier | null = null
private lastConnectedDragSource: any = null
private lastConnectedDragSourceOptions: any = null
private lastConnectedDragPreview: any = null
private lastConnectedDragPreviewOptions: any = null
private readonly backend: Backend
public constructor(backend: Backend) {
this.backend = backend
}
public receiveHandlerId(newHandlerId: Identifier | null): void {
if (this.handlerId === newHandlerId) {
return
}
this.handlerId = newHandlerId
this.reconnect()
}
public get connectTarget(): any {
return this.dragSource
}
public get dragSourceOptions(): DragSourceOptions | null {
return this.dragSourceOptionsInternal
}
public set dragSourceOptions(options: DragSourceOptions | null) {
this.dragSourceOptionsInternal = options
}
public get dragPreviewOptions(): DragPreviewOptions | null {
return this.dragPreviewOptionsInternal
}
public set dragPreviewOptions(options: DragPreviewOptions | null) {
this.dragPreviewOptionsInternal = options
}
public reconnect(): void {
const didChange = this.reconnectDragSource()
this.reconnectDragPreview(didChange)
}
private reconnectDragSource(): boolean {
const dragSource = this.dragSource
// if nothing has changed then don't resubscribe
const didChange =
this.didHandlerIdChange() ||
this.didConnectedDragSourceChange() ||
this.didDragSourceOptionsChange()
if (didChange) {
this.disconnectDragSource()
}
if (!this.handlerId) {
return didChange
}
if (!dragSource) {
this.lastConnectedDragSource = dragSource
return didChange
}
if (didChange) {
this.lastConnectedHandlerId = this.handlerId
this.lastConnectedDragSource = dragSource
this.lastConnectedDragSourceOptions = this.dragSourceOptions
this.dragSourceUnsubscribe = this.backend.connectDragSource(
this.handlerId,
dragSource,
this.dragSourceOptions,
)
}
return didChange
}
private reconnectDragPreview(forceDidChange = false): void {
const dragPreview = this.dragPreview
// if nothing has changed then don't resubscribe
const didChange =
forceDidChange ||
this.didHandlerIdChange() ||
this.didConnectedDragPreviewChange() ||
this.didDragPreviewOptionsChange()
if (didChange) {
this.disconnectDragPreview()
}
if (!this.handlerId) {
return
}
if (!dragPreview) {
this.lastConnectedDragPreview = dragPreview
return
}
if (didChange) {
this.lastConnectedHandlerId = this.handlerId
this.lastConnectedDragPreview = dragPreview
this.lastConnectedDragPreviewOptions = this.dragPreviewOptions
this.dragPreviewUnsubscribe = this.backend.connectDragPreview(
this.handlerId,
dragPreview,
this.dragPreviewOptions,
)
}
}
private didHandlerIdChange(): boolean {
return this.lastConnectedHandlerId !== this.handlerId
}
private didConnectedDragSourceChange(): boolean {
return this.lastConnectedDragSource !== this.dragSource
}
private didConnectedDragPreviewChange(): boolean {
return this.lastConnectedDragPreview !== this.dragPreview
}
private didDragSourceOptionsChange(): boolean {
return !shallowEqual(
this.lastConnectedDragSourceOptions,
this.dragSourceOptions,
)
}
private didDragPreviewOptionsChange(): boolean {
return !shallowEqual(
this.lastConnectedDragPreviewOptions,
this.dragPreviewOptions,
)
}
public disconnectDragSource() {
if (this.dragSourceUnsubscribe) {
this.dragSourceUnsubscribe()
this.dragSourceUnsubscribe = undefined
}
}
public disconnectDragPreview() {
if (this.dragPreviewUnsubscribe) {
this.dragPreviewUnsubscribe()
this.dragPreviewUnsubscribe = undefined
this.dragPreviewNode = null
this.dragPreviewRef = null
}
}
private get dragSource() {
return (
this.dragSourceNode || (this.dragSourceRef && this.dragSourceRef.current)
)
}
private get dragPreview() {
return (
this.dragPreviewNode ||
(this.dragPreviewRef && this.dragPreviewRef.current)
)
}
private clearDragSource() {
this.dragSourceNode = null
this.dragSourceRef = null
}
private clearDragPreview() {
this.dragPreviewNode = null
this.dragPreviewRef = null
}
}

View File

@@ -1,125 +0,0 @@
import { shallowEqual } from '@react-dnd/shallowequal'
import type { Backend, Identifier, Unsubscribe } from 'dnd-core'
import type { RefObject } from 'react'
import type { DropTargetOptions } from '../types/index.js'
import { isRef } from './isRef.js'
import type { Connector } from './SourceConnector.js'
import { wrapConnectorHooks } from './wrapConnectorHooks.js'
export class TargetConnector implements Connector {
public hooks = wrapConnectorHooks({
dropTarget: (node: any, options: DropTargetOptions) => {
this.clearDropTarget()
this.dropTargetOptions = options
if (isRef(node)) {
this.dropTargetRef = node
} else {
this.dropTargetNode = node
}
this.reconnect()
},
})
private handlerId: Identifier | null = null
// The drop target may either be attached via ref or connect function
private dropTargetRef: RefObject<any> | null = null
private dropTargetNode: any
private dropTargetOptionsInternal: DropTargetOptions | null = null
private unsubscribeDropTarget: Unsubscribe | undefined
private lastConnectedHandlerId: Identifier | null = null
private lastConnectedDropTarget: any = null
private lastConnectedDropTargetOptions: DropTargetOptions | null = null
private readonly backend: Backend
public constructor(backend: Backend) {
this.backend = backend
}
public get connectTarget(): any {
return this.dropTarget
}
public reconnect(): void {
// if nothing has changed then don't resubscribe
const didChange =
this.didHandlerIdChange() ||
this.didDropTargetChange() ||
this.didOptionsChange()
if (didChange) {
this.disconnectDropTarget()
}
const dropTarget = this.dropTarget
if (!this.handlerId) {
return
}
if (!dropTarget) {
this.lastConnectedDropTarget = dropTarget
return
}
if (didChange) {
this.lastConnectedHandlerId = this.handlerId
this.lastConnectedDropTarget = dropTarget
this.lastConnectedDropTargetOptions = this.dropTargetOptions
this.unsubscribeDropTarget = this.backend.connectDropTarget(
this.handlerId,
dropTarget,
this.dropTargetOptions,
)
}
}
public receiveHandlerId(newHandlerId: Identifier | null): void {
if (newHandlerId === this.handlerId) {
return
}
this.handlerId = newHandlerId
this.reconnect()
}
public get dropTargetOptions(): DropTargetOptions {
return this.dropTargetOptionsInternal
}
public set dropTargetOptions(options: DropTargetOptions) {
this.dropTargetOptionsInternal = options
}
private didHandlerIdChange(): boolean {
return this.lastConnectedHandlerId !== this.handlerId
}
private didDropTargetChange(): boolean {
return this.lastConnectedDropTarget !== this.dropTarget
}
private didOptionsChange(): boolean {
return !shallowEqual(
this.lastConnectedDropTargetOptions,
this.dropTargetOptions,
)
}
public disconnectDropTarget() {
if (this.unsubscribeDropTarget) {
this.unsubscribeDropTarget()
this.unsubscribeDropTarget = undefined
}
}
private get dropTarget() {
return (
this.dropTargetNode || (this.dropTargetRef && this.dropTargetRef.current)
)
}
private clearDropTarget() {
this.dropTargetRef = null
this.dropTargetNode = null
}
}

View File

@@ -1,5 +0,0 @@
export * from './DragSourceMonitorImpl.js'
export * from './DropTargetMonitorImpl.js'
export * from './registration.js'
export * from './SourceConnector.js'
export * from './TargetConnector.js'

View File

@@ -1,12 +0,0 @@
export interface Ref<T> {
current: T
}
export function isRef(obj: unknown): boolean {
return (
// eslint-disable-next-line no-prototype-builtins
obj !== null &&
typeof obj === 'object' &&
Object.prototype.hasOwnProperty.call(obj, 'current')
)
}

View File

@@ -1,31 +0,0 @@
import type {
DragDropManager,
DragSource,
DropTarget,
Identifier,
SourceType,
TargetType,
Unsubscribe,
} from 'dnd-core'
export function registerTarget(
type: TargetType,
target: DropTarget,
manager: DragDropManager,
): [Identifier, Unsubscribe] {
const registry = manager.getRegistry()
const targetId = registry.addTarget(type, target)
return [targetId, () => registry.removeTarget(targetId)]
}
export function registerSource(
type: SourceType,
source: DragSource,
manager: DragDropManager,
): [Identifier, Unsubscribe] {
const registry = manager.getRegistry()
const sourceId = registry.addSource(type, source)
return [sourceId, () => registry.removeSource(sourceId)]
}

View File

@@ -1,93 +0,0 @@
import { invariant } from '@react-dnd/invariant'
import type { ReactElement } from 'react'
import { cloneElement, isValidElement } from 'react'
function throwIfCompositeComponentElement(element: ReactElement<any>) {
// Custom components can no longer be wrapped directly in React DnD 2.0
// so that we don't need to depend on findDOMNode() from react-dom.
if (typeof element.type === 'string') {
return
}
const displayName =
(element.type as any).displayName || element.type.name || 'the component'
throw new Error(
'Only native element nodes can now be passed to React DnD connectors.' +
`You can either wrap ${displayName} into a <div>, or turn it into a ` +
'drag source or a drop target itself.',
)
}
function wrapHookToRecognizeElement(hook: (node: any, options: any) => void) {
return (elementOrNode = null, options = null) => {
// When passed a node, call the hook straight away.
if (!isValidElement(elementOrNode)) {
const node = elementOrNode
hook(node, options)
// return the node so it can be chained (e.g. when within callback refs
// <div ref={node => connectDragSource(connectDropTarget(node))}/>
return node
}
// If passed a ReactElement, clone it and attach this function as a ref.
// This helps us achieve a neat API where user doesn't even know that refs
// are being used under the hood.
const element: ReactElement | null = elementOrNode
throwIfCompositeComponentElement(element as any)
// When no options are passed, use the hook directly
const ref = options ? (node: Element) => hook(node, options) : hook
return cloneWithRef(element, ref)
}
}
export function wrapConnectorHooks(hooks: any) {
const wrappedHooks: any = {}
Object.keys(hooks).forEach((key) => {
const hook = hooks[key]
// 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
}
function setRef(ref: any, node: any) {
if (typeof ref === 'function') {
ref(node)
} else {
ref.current = node
}
}
function cloneWithRef(element: any, newRef: any): ReactElement<any> {
const previousRef = element.ref
invariant(
typeof previousRef !== 'string',
'Cannot connect React DnD to an element with an existing string ref. ' +
'Please convert it to use a callback ref instead, or wrap it into a <span> or <div>. ' +
'Read more: https://reactjs.org/docs/refs-and-the-dom.html#callback-refs',
)
if (!previousRef) {
// When there is no ref on the element, use the new ref directly
return cloneElement(element, {
ref: newRef,
})
} else {
return cloneElement(element, {
ref: (node: any) => {
setRef(previousRef, node)
setRef(newRef, node)
},
})
}
}

View File

@@ -1,14 +0,0 @@
import type { ReactElement, RefObject } from 'react'
import type { DragPreviewOptions, DragSourceOptions } from './options'
export type ConnectableElement = RefObject<any> | ReactElement | Element | null
export type DragElementWrapper<Options> = (
elementOrNode: ConnectableElement,
options?: Options,
) => ReactElement | null
export type ConnectDragSource = DragElementWrapper<DragSourceOptions>
export type ConnectDropTarget = DragElementWrapper<any>
export type ConnectDragPreview = DragElementWrapper<DragPreviewOptions>

View File

@@ -1,3 +0,0 @@
export * from './connectors.js'
export * from './monitors.js'
export * from './options.js'

View File

@@ -1,210 +0,0 @@
import type { Identifier, Unsubscribe } from 'dnd-core'
export interface XYCoord {
x: number
y: number
}
export interface HandlerManager {
receiveHandlerId: (handlerId: Identifier | null) => void
getHandlerId: () => Identifier | null
}
export interface DragSourceMonitor<DragObject = unknown, DropResult = unknown>
extends HandlerManager,
MonitorEventEmitter {
/**
* Returns true if no drag operation is in progress, and the owner's canDrag() returns true or is not defined.
*/
canDrag(): 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
/**
* Returns a string or a symbol identifying the type of the current dragged item. Returns null if no item is being dragged.
*/
getItemType(): Identifier | null
/**
* Returns a plain object representing the currently dragged item. Every drag source must specify it by returning an object from its beginDrag() method.
* Returns null if no item is being dragged.
*/
getItem<T = DragObject>(): T
/**
* 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 explicitly returns its own result from drop()
* overrides the child drop result previously set by the child. Returns null if called outside endDrag().
*/
getDropResult<T = DropResult>(): T | null
/**
* Returns true if some drop target has handled the drop event, false otherwise. Even if a target did not return a drop result, didDrop() returns true.
* Use it inside endDrag() to test whether any drop target has handled the drop. Returns false if called outside endDrag().
*/
didDrop(): boolean
/**
* Returns the { x, y } client offset of the pointer at the time when the current drag operation has started. Returns null if no item is being dragged.
*/
getInitialClientOffset(): XYCoord | null
/**
* Returns the { x, y } client offset of the drag source component's root DOM node at the time when the current drag operation has started.
* Returns null if no item is being dragged.
*/
getInitialSourceClientOffset(): XYCoord | null
/**
* Returns the last recorded { x, y } client offset of the pointer while a drag operation is in progress. Returns null if no item is being dragged.
*/
getClientOffset(): XYCoord | null
/**
* Returns the { x, y } difference between the last recorded client offset of the pointer and the client offset when the current drag operation has started.
* Returns null if no item is being dragged.
*/
getDifferenceFromInitialOffset(): XYCoord | null
/**
* Returns the projected { x, y } client offset of the drag source component's root DOM node, based on its position at the time when the current drag operation has
* started, and the movement difference. Returns null if no item is being dragged.
*/
getSourceClientOffset(): XYCoord | null
/**
* Returns the ids of the potential drop targets.
*/
getTargetIds(): Identifier[]
}
export interface MonitorEventEmitter {
subscribeToStateChange(
fn: () => void,
options?: { handlerIds?: Identifier[] },
): Unsubscribe
}
export interface DropTargetMonitor<DragObject = unknown, DropResult = unknown>
extends HandlerManager,
MonitorEventEmitter {
/**
* Returns true if there is a drag operation in progress, and the owner's canDrop() returns true or is not defined.
*/
canDrop(): boolean
/**
* Returns true if there is a drag operation in progress, and the pointer is currently hovering over the owner.
* You may optionally pass { shallow: true } to strictly check whether only the owner is being hovered, as opposed
* to a nested target.
*/
isOver(options?: { shallow?: boolean }): boolean
/**
* Returns a string or a symbol identifying the type of the current dragged item. Returns null if no item is being dragged.
*/
getItemType(): Identifier | null
/**
* Returns a plain object representing the currently dragged item. Every drag source must specify it by returning an object from
* its beginDrag() method. Returns null if no item is being dragged.
*/
getItem<T = DragObject>(): T
/**
* 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 explicitly
* returns its own result from drop() overrides the drop result previously set by the child. Returns null if called outside drop().
*/
getDropResult<T = DropResult>(): T | null
/**
* Returns true if some drop target has handled the drop event, false otherwise. Even if a target did not return a drop result,
* didDrop() returns true. Use it inside drop() to test whether any nested drop target has already handled the drop. Returns false
* if called outside drop().
*/
didDrop(): boolean
/**
* Returns the { x, y } client offset of the pointer at the time when the current drag operation has started. Returns null if no item
* is being dragged.
*/
getInitialClientOffset(): XYCoord | null
/**
* Returns the { x, y } client offset of the drag source component's root DOM node at the time when the current drag operation has started.
* Returns null if no item is being dragged.
*/
getInitialSourceClientOffset(): XYCoord | null
/**
* Returns the last recorded { x, y } client offset of the pointer while a drag operation is in progress. Returns null if no item is being dragged.
*/
getClientOffset(): XYCoord | null
/**
* Returns the { x, y } difference between the last recorded client offset of the pointer and the client offset when current the drag operation has
* started. Returns null if no item is being dragged.
*/
getDifferenceFromInitialOffset(): XYCoord | null
/**
* Returns the projected { x, y } client offset of the drag source component's root DOM node, based on its position at the time when the current
* drag operation has started, and the movement difference. Returns null if no item is being dragged.
*/
getSourceClientOffset(): XYCoord | null
}
export interface DragLayerMonitor<DragObject = unknown> {
/**
* Returns true if a drag operation is in progress. Returns false otherwise.
*/
isDragging(): boolean
/**
* Returns a string or a symbol identifying the type of the current dragged item.
* Returns null if no item is being dragged.
*/
getItemType(): Identifier | null
/**
* Returns a plain object representing the currently dragged item.
* Every drag source must specify it by returning an object from its beginDrag() method.
* Returns null if no item is being dragged.
*/
getItem<T = DragObject>(): T
/**
* Returns the { x, y } client offset of the pointer at the time when the current drag operation has started.
* Returns null if no item is being dragged.
*/
getInitialClientOffset(): XYCoord | null
/**
* Returns the { x, y } client offset of the drag source component's root DOM node at the time when the current
* drag operation has started. Returns null if no item is being dragged.
*/
getInitialSourceClientOffset(): XYCoord | null
/**
* Returns the last recorded { x, y } client offset of the pointer while a drag operation is in progress.
* Returns null if no item is being dragged.
*/
getClientOffset(): XYCoord | null
/**
* Returns the { x, y } difference between the last recorded client offset of the pointer and the client
* offset when current the drag operation has started. Returns null if no item is being dragged.
*/
getDifferenceFromInitialOffset(): XYCoord | null
/**
* Returns the projected { x, y } client offset of the drag source component's root DOM node, based on its
* position at the time when the current drag operation has started, and the movement difference.
* Returns null if no item is being dragged.
*/
getSourceClientOffset(): XYCoord | null
}

View File

@@ -1,48 +0,0 @@
export interface DragSourceOptions {
/**
* Optional. A string. By default, 'move'. In the browsers that support this feature, specifying 'copy'
* shows a special “copying” cursor, while 'move' corresponds to the “move” cursor. You might want to use
* this option to provide a hint to the user about whether an action is destructive.
*/
dropEffect?: string
}
export interface DragPreviewOptions {
/**
* Optional. A boolean. By default, false. If true, the component will learn that it is being dragged immediately as the drag
* starts instead of the next tick. This means that the screenshotting would occur with monitor.isDragging() already being true,
* and if you apply any styling like a decreased opacity to the dragged element, this styling will also be reflected on the
* screenshot. This is rarely desirable, so false is a sensible default. However, you might want to set it to true in rare cases,
* such as if you want to make the custom drag layers work in IE and you need to hide the original element without resorting to
* an empty drag preview which IE doesn't support.
*/
captureDraggingState?: boolean
/**
* Optional. A number between 0 and 1. By default, 0.5. Specifies how the offset relative to the drag source node is translated
* into the horizontal offset of the drag preview when their sizes don't match. 0 means “dock the preview to the left”, 0.5 means
* “interpolate linearly” and 1 means “dock the preview to the right”.
*/
anchorX?: number
/**
* Optional. A number between 0 and 1. By default, 0.5. Specifies how the offset relative to the drag source node is translated into
* the vertical offset of the drag preview when their sizes don't match. 0 means “dock the preview to the top, 0.5 means “interpolate
* linearly” and 1 means “dock the preview to the bottom.
*/
anchorY?: number
/**
* Optional. A number or null if not needed. By default, null. Specifies the vertical offset between the cursor and the drag preview
* element. If offsetX has a value, anchorX won't be used.
*/
offsetX?: number
/**
* Optional. A number or null if not needed. By default, null. Specifies the vertical offset between the cursor and the drag
* preview element. If offsetY has a value, anchorY won't be used.
*/
offsetY?: number
}
export type DropTargetOptions = any