Initial commit: igny8 project

This commit is contained in:
igny8
2025-11-09 10:27:02 +00:00
commit 60b8188111
27265 changed files with 4360521 additions and 0 deletions

5
frontend/node_modules/react-dnd/src/hooks/index.ts generated vendored Normal file
View File

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

147
frontend/node_modules/react-dnd/src/hooks/types.ts generated vendored Normal file
View File

@@ -0,0 +1,147 @@
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

@@ -0,0 +1,13 @@
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

@@ -0,0 +1,37 @@
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

@@ -0,0 +1,60 @@
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

@@ -0,0 +1,11 @@
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

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

View File

@@ -0,0 +1,45 @@
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

@@ -0,0 +1,21 @@
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

@@ -0,0 +1,31 @@
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

@@ -0,0 +1,13 @@
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

@@ -0,0 +1,15 @@
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

@@ -0,0 +1,35 @@
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

@@ -0,0 +1,14 @@
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

@@ -0,0 +1,21 @@
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

@@ -0,0 +1,34 @@
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

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

View File

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

View File

@@ -0,0 +1,20 @@
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

@@ -0,0 +1,34 @@
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

@@ -0,0 +1,16 @@
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

@@ -0,0 +1,22 @@
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

@@ -0,0 +1,10 @@
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

@@ -0,0 +1,38 @@
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

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

View File

@@ -0,0 +1,26 @@
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

@@ -0,0 +1,16 @@
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)
}