UNPKG

@vdnd/v3

Version:

A Vue drag-and-drop component library that is easy to use.

564 lines (552 loc) 24.1 kB
import * as vue from 'vue'; import { HTMLAttributes, MaybeRef, ComputedRef, DefineSetupFnComponent } from 'vue'; type DndHandleProps = HTMLAttributes & { tag?: string; }; declare const DndHandle$1: vue.DefineSetupFnComponent<DndHandleProps, {}, {}, HTMLAttributes & { tag?: string; } & {}, vue.PublicProps>; type DndElement = { label: string; data: any; }; type DndDropzoneProps<T extends DndElement> = HTMLAttributes & (T['data'] extends undefined ? { tag?: string; label: T['label']; data?: T['data']; } : { tag?: string; label: T['label']; /** * Don't pass `undefined` as `data`. * * The union with `undefined` here is to ensure that the type inferring of the `label` is friendly enough. */ data: T['data'] | undefined; }); type DistributeDndDropzoneProps<T extends DndElement = DndElement> = T extends any ? DndDropzoneProps<T> : never; type DndSourceProps<T extends DndElement> = HTMLAttributes & (T['data'] extends undefined ? { tag?: string; label: T['label']; data?: T['data']; } : { tag?: string; label: T['label']; /** * Don't pass `undefined` as `data`. * * The union with `undefined` here is to ensure that the type inferring of the `label` is friendly enough. */ data: T['data'] | undefined; }); type DistributeDndSourceProps<T extends DndElement = DndElement> = T extends any ? DndSourceProps<T> : never; type DragEvent<S extends DndElement = DndElement, Over extends DndElement = DndElement> = { type: 'drag'; /** * The current drag source. */ source: S; /** * The current drop target. */ over: Over | undefined; originalEvent: globalThis.DragEvent; }; type DragStartEvent<S extends DndElement = DndElement> = { type: 'dragstart'; /** * The current drag source. */ source: S; originalEvent: globalThis.DragEvent; }; type DragPreventEvent<S extends DndElement = DndElement> = { type: 'dragprevent'; /** * The disabled drag source. */ source: S; originalEvent: globalThis.DragEvent; }; type DragEnterEvent<S extends DndElement = DndElement, Enter extends DndElement = DndElement> = { type: 'dragenter'; /** * The current drag source. */ source: S; /** * The current drop target. */ enter: Enter; originalEvent: globalThis.DragEvent; }; type DragOverEvent<S extends DndElement = DndElement, Over extends DndElement = DndElement> = { type: 'dragover'; /** * The current drag source. */ source: S; /** * The current drop target. */ over: Over; originalEvent: globalThis.DragEvent; }; type DragLeaveEvent<S extends DndElement = DndElement, Leave extends DndElement = DndElement, Enter extends DndElement = Leave> = { type: 'dragleave'; /** * The current drag source. */ source: S; /** * The previous current drop target. */ leave: Leave; /** * The current drop target. */ enter: Enter | undefined; originalEvent: globalThis.DragEvent; }; type DropEvent<S extends DndElement = DndElement, Dropzone extends DndElement = DndElement> = { type: 'drop'; /** * The current drag source. */ source: S; /** * The current drop target. */ dropzone: Dropzone; originalEvent: globalThis.DragEvent; }; type DragEndEvent<S extends DndElement = DndElement, Over extends DndElement = DndElement> = { type: 'dragend'; /** * The current drag source. */ source: S; /** * The current drop target. */ over: Over | undefined; originalEvent: globalThis.DragEvent; }; type PickDndElement<T extends DndElement, Label extends string> = Extract<T, { label: Label; }>; type NonNullableProps<O extends object> = { [K in keyof O]: NonNullable<O[K]>; }; type OnDrag<S extends DndElement, Over extends DndElement, Event extends DragEvent<S, Over> = DragEvent<S, Over>> = (e: Event) => void; type OnDragStart<S extends DndElement> = (e: DragStartEvent<S>) => void; type OnDragPrevent<S extends DndElement> = (e: DragPreventEvent<S>) => void; type OnDragEnter<S extends DndElement, Enter extends DndElement> = (e: DragEnterEvent<S, Enter>) => void; type OnDragOver<S extends DndElement, Over extends DndElement> = (e: DragOverEvent<S, Over>) => void; type OnDragLeave<S extends DndElement, Leave extends DndElement, Enter extends DndElement> = (e: DragLeaveEvent<S, Leave, Enter>) => void; type OnDrop<S extends DndElement, Dropzone extends DndElement> = (e: DropEvent<S, Dropzone>) => void; type OnDragEnd<S extends DndElement, Over extends DndElement, Event extends DragEndEvent<S, Over> = DragEndEvent<S, Over>> = (e: Event) => void; type Draggable<S extends DndElement = DndElement> = MaybeRef<boolean> | ComputedRef<boolean> | ((source: S) => boolean); type Droppable<S extends DndElement = DndElement, D extends DndElement = DndElement> = MaybeRef<boolean> | ComputedRef<boolean> | ((dropzone: D, source: S) => boolean); type DropEffect<S extends DndElement = DndElement, D extends DndElement = DndElement> = MaybeRef<Exclude<DataTransfer['dropEffect'], 'none'>> | ComputedRef<Exclude<DataTransfer['dropEffect'], 'none'>> | ((dropzone: D, source: S) => Exclude<DataTransfer['dropEffect'], 'none'>); type DndInteraction1<S extends DndElement = DndElement, D extends DndElement = DndElement> = { scope: '*'; draggable?: Draggable<S>; droppable?: Droppable<S, D>; onDrag?: OnDrag<S, D>; onDragStart?: OnDragStart<S>; onDragPrevent?: OnDragPrevent<S>; onDragEnter?: OnDragEnter<S, D>; onDragOver?: OnDragOver<S, D>; onDragLeave?: OnDragLeave<S, D, D>; onDrop?: OnDrop<S, D>; onDragEnd?: OnDragEnd<S, D>; }; type DndInteraction2<S extends DndElement = DndElement, D extends DndElement = DndElement, SLabel extends S['label'] = S['label']> = { scope: 's'; source: SLabel; draggable?: Draggable<PickDndElement<S, SLabel>>; onDrag?: OnDrag<PickDndElement<S, SLabel>, D>; onDragStart?: OnDragStart<PickDndElement<S, SLabel>>; onDragPrevent?: OnDragPrevent<PickDndElement<S, SLabel>>; onDragEnter?: OnDragEnter<PickDndElement<S, SLabel>, D>; onDragOver?: OnDragOver<PickDndElement<S, SLabel>, D>; onDragLeave?: OnDragLeave<PickDndElement<S, SLabel>, D, D>; onDrop?: OnDrop<PickDndElement<S, SLabel>, D>; onDragEnd?: OnDragEnd<PickDndElement<S, SLabel>, D>; }; type DistributiveDndInteraction2<S extends DndElement, D extends DndElement> = S extends any ? DndInteraction2<S, D> : never; type DndInteraction3<S extends DndElement = DndElement, D extends DndElement = DndElement, E0 extends DndElement = D, DLabel extends D['label'] = D['label']> = { scope: 'd'; dropzone: DLabel; droppable?: Droppable<S, PickDndElement<D, DLabel>>; onDrag?: OnDrag<S, PickDndElement<D, DLabel>, NonNullableProps<DragEvent<S, PickDndElement<D, DLabel>>>>; onDragEnter?: OnDragEnter<S, PickDndElement<D, DLabel>>; onDragOver?: OnDragOver<S, PickDndElement<D, DLabel>>; onDragLeave?: OnDragLeave<S, PickDndElement<D, DLabel>, E0>; onDrop?: OnDrop<S, PickDndElement<D, DLabel>>; onDragEnd?: OnDragEnd<S, PickDndElement<D, DLabel>, NonNullableProps<DragEndEvent<S, PickDndElement<D, DLabel>>>>; }; type DistributiveDndInteraction3<S extends DndElement, D extends DndElement, E0 extends DndElement = D> = D extends any ? DndInteraction3<S, D, E0> : never; type DndInteraction4<S extends DndElement = DndElement, D extends DndElement = DndElement, E0 extends DndElement = D, SLabel extends S['label'] = S['label'], DLabel extends D['label'] = D['label']> = { scope: 's+d'; source: SLabel; dropzone: DLabel; droppable?: Droppable<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>>; dropEffect?: DropEffect<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>>; onDrag?: OnDrag<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>, NonNullableProps<DragEvent<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>>>>; onDragEnter?: OnDragEnter<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>>; onDragOver?: OnDragOver<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>>; onDragLeave?: OnDragLeave<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>, E0>; onDrop?: OnDrop<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>>; onDragEnd?: OnDragEnd<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>, NonNullableProps<DragEndEvent<PickDndElement<S, SLabel>, PickDndElement<D, DLabel>>>>; }; type DistributiveDndInteraction4<S extends DndElement, D extends DndElement, E0 extends DndElement = D> = S extends any ? (D extends any ? DndInteraction4<S, D, E0> : never) : never; type DndInteraction<S extends DndElement = DndElement, D extends DndElement = DndElement, E0 extends DndElement = D> = DndInteraction1<S, D> | DistributiveDndInteraction2<S, D> | DistributiveDndInteraction3<S, D, E0> | DistributiveDndInteraction4<S, D, E0>; type DndClasses = { container?: string; source?: string; dropzone?: string; handle?: string; 'source:dragging'?: string | string[]; 'source:draggable'?: string | string[]; 'source:disabled'?: string | string[]; 'dropzone:over'?: string | string[]; 'dropzone:droppable'?: string | string[]; 'dropzone:disabled'?: string | string[]; }; type DndModelOptions<Source extends DndElement = DndElement, Dropzone extends DndElement = DndElement> = { classes?: DndClasses; interactions?: DndInteraction<Source, Dropzone>[]; }; type DndModel<Source extends DndElement = DndElement, Dropzone extends DndElement = DndElement> = ReturnType<typeof useDndModel$1<Source, Dropzone>>; type NativeElement<T extends DndElement = DndElement> = { role: 'container'; htmlEl: HTMLElement; dndEl: undefined; } | { role: 'source'; htmlEl: HTMLElement; dndEl: T; } | { role: 'dropzone'; htmlEl: HTMLElement; dndEl: T; } | { role: 'handle'; htmlEl: HTMLElement; dndEl: undefined; }; type NativeElementRole = NativeElement['role']; declare function useDndModel$1<Source extends DndElement = DndElement, Dropzone extends DndElement = DndElement>(options?: DndModelOptions<Source, Dropzone> | DndInteraction<Source, Dropzone>[]): vue.Raw<{ readonly classes: Readonly<Required<DndClasses>>; readonly interactions: DndInteraction<Source, Dropzone>[]; readonly initialized: boolean; readonly currentSource: Source | undefined; readonly currentTarget: Dropzone | undefined; isDragging: { (): boolean; (label: Source["label"]): boolean; <Label extends Source["label"]>(label: Label, data: Extract<Source, { label: Label; }>["data"]): boolean; (source: Source): boolean; (predicate: (source: Source) => boolean): boolean; }; isDraggable: { (source: Source): boolean; <Label extends Source["label"]>(label: Label, data: Extract<Source, { label: Label; }>["data"]): boolean; }; isOver: { (): boolean; (label: Dropzone["label"]): boolean; <Label extends Dropzone["label"]>(label: Label, data: Extract<Dropzone, { label: Label; }>["data"]): boolean; (dropzone: Dropzone): boolean; (predicate: (dropzone: Dropzone) => boolean): boolean; }; isDroppable: { (dropzone: Dropzone): boolean; <Label extends Dropzone["label"]>(label: Label, data: Extract<Dropzone, { label: Label; }>["data"]): boolean; }; defineInteraction: (interaction: DndInteraction<Source, Dropzone>) => void; findHTMLElement: { (role: "container"): HTMLElement | undefined; <Role extends "source" | "dropzone">(role: Role, dndEl: Role extends "source" ? Source : Dropzone): HTMLElement | undefined; }; findHTMLElements: { (role: "handle"): HTMLElement[]; <Role extends "source" | "dropzone">(role: Role, label?: Role extends "source" ? Source["label"] : Dropzone["label"]): HTMLElement[]; }; findHandlesIn: (source: HTMLElement | Source) => HTMLElement[]; /** * @internal */ $findDndElement: { (role: "source", htmlEl: HTMLElement): Source | undefined; (role: "dropzone", htmlEl: HTMLElement): Dropzone | undefined; }; /** * @internal */ $addNativeElement: <Role extends NativeElementRole>(role: Role, htmlEl: HTMLElement, dndEl: Role extends "source" | "dropzone" ? DndElement : undefined) => void; /** * @internal */ $removeNativeElement: (role: NativeElementRole, htmlEl: HTMLElement) => void; /** * @internal */ $setInitialized: (flag: boolean) => void; /** * @internal */ $setCurrentTarget: (value: Dropzone | undefined) => void; /** * @internal */ $setCurrentSource: (value: Source | undefined) => void; }>; declare function injectDndModel$1<Source extends DndElement = DndElement, Dropzone extends DndElement = DndElement>(): vue.Raw<{ readonly classes: Readonly<Required<DndClasses>>; readonly interactions: DndInteraction<Source, Dropzone>[]; readonly initialized: boolean; readonly currentSource: Source | undefined; readonly currentTarget: Dropzone | undefined; isDragging: { (): boolean; (label: Source["label"]): boolean; <Label extends Source["label"]>(label: Label, data: Extract<Source, { label: Label; }>["data"]): boolean; (source: Source): boolean; (predicate: (source: Source) => boolean): boolean; }; isDraggable: { (source: Source): boolean; <Label extends Source["label"]>(label: Label, data: Extract<Source, { label: Label; }>["data"]): boolean; }; isOver: { (): boolean; (label: Dropzone["label"]): boolean; <Label extends Dropzone["label"]>(label: Label, data: Extract<Dropzone, { label: Label; }>["data"]): boolean; (dropzone: Dropzone): boolean; (predicate: (dropzone: Dropzone) => boolean): boolean; }; isDroppable: { (dropzone: Dropzone): boolean; <Label extends Dropzone["label"]>(label: Label, data: Extract<Dropzone, { label: Label; }>["data"]): boolean; }; defineInteraction: (interaction: DndInteraction<Source, Dropzone>) => void; findHTMLElement: { (role: "container"): HTMLElement | undefined; <Role extends "source" | "dropzone">(role: Role, dndEl: Role extends "source" ? Source : Dropzone): HTMLElement | undefined; }; findHTMLElements: { (role: "handle"): HTMLElement[]; <Role extends "source" | "dropzone">(role: Role, label?: (Role extends "source" ? Source["label"] : Dropzone["label"]) | undefined): HTMLElement[]; }; findHandlesIn: (source: HTMLElement | Source) => HTMLElement[]; /** * @internal */ $findDndElement: { (role: "source", htmlEl: HTMLElement): Source | undefined; (role: "dropzone", htmlEl: HTMLElement): Dropzone | undefined; }; /** * @internal */ $addNativeElement: <Role extends NativeElementRole>(role: Role, htmlEl: HTMLElement, dndEl: Role extends "source" | "dropzone" ? DndElement : undefined) => void; /** * @internal */ $removeNativeElement: (role: NativeElementRole, htmlEl: HTMLElement) => void; /** * @internal */ $setInitialized: (flag: boolean) => void; /** * @internal */ $setCurrentTarget: (value: Dropzone | undefined) => void; /** * @internal */ $setCurrentSource: (value: Source | undefined) => void; }> | undefined; type DndContainerProps<Source extends DndElement = DndElement, Dropzone extends DndElement = DndElement> = HTMLAttributes & { tag?: string; model: DndModel<Source, Dropzone>; }; type IDndSuite<Source extends DndElement = DndElement, Dropzone extends DndElement = DndElement> = { useDndModel: typeof useDndModel$1<Source, Dropzone>; /** * Inject the dnd-model provided by the `DndContainer`. * * The `DndContainer` will provide the model it received for its descendant components. */ injectDndModel: typeof injectDndModel$1<Source, Dropzone>; /** * `DndContainer` defines the boundaries for drag-and-drop (DND) interactions and performs two key functions: * * 1、It detects DND interactions occurring within the container and synchronizes them with the `model`. * Example: When a user drags a source and selects an element as the current drop target, the `DndContainer` calls the `onDragStart` and `onDragEnter` callbacks in the `model`. * * 2、It influences actual user interactions based on the interaction properties of the `model`. * Example: If the `draggable` property of a source is set to false, the `DndContainer` prevents the user from dragging that source and calls the `onDragPrevent` callbacks in the `model`. */ DndContainer: DefineSetupFnComponent<DndContainerProps<Source, Dropzone>>; /** * `DndSource` represents an element that is allowed to be dragged, which we refer to as the "source". * * The source supports marking its type using the `label` property and binding custom data via the `data` property. */ DndSource: DefineSetupFnComponent<DistributeDndSourceProps<Source>>; /** * `DndDropzone` represents an area where the current drag source can be dropped, which we refer to as the "drop target". * * The drop target supports marking its type using the `label` property and binding custom data via the `data` property. */ DndDropzone: DefineSetupFnComponent<DistributeDndDropzoneProps<Dropzone>>; /** * `DndHandle` is the drag trigger for the source(`<DndSource />`). * * If we want to drag a source that contains drag triggers, we can only drag the source by dragging one of the triggers. * * Dragging other elements in the source will not put the source into drag mode, and the entire DND interaction will not begin. */ DndHandle: typeof DndHandle$1; }; declare const DndSuite: IDndSuite; declare const useDndModel: (options?: DndModelOptions<DndElement, DndElement> | DndInteraction<DndElement, DndElement>[] | undefined) => vue.Raw<{ readonly classes: Readonly<Required<DndClasses>>; readonly interactions: DndInteraction<DndElement, DndElement>[]; readonly initialized: boolean; readonly currentSource: DndElement | undefined; readonly currentTarget: DndElement | undefined; isDragging: { (): boolean; (label: string): boolean; <Label extends string>(label: Label, data: Extract<DndElement, { label: Label; }>["data"]): boolean; (source: DndElement): boolean; (predicate: (source: DndElement) => boolean): boolean; }; isDraggable: { (source: DndElement): boolean; <Label extends string>(label: Label, data: Extract<DndElement, { label: Label; }>["data"]): boolean; }; isOver: { (): boolean; (label: string): boolean; <Label extends string>(label: Label, data: Extract<DndElement, { label: Label; }>["data"]): boolean; (dropzone: DndElement): boolean; (predicate: (dropzone: DndElement) => boolean): boolean; }; isDroppable: { (dropzone: DndElement): boolean; <Label extends string>(label: Label, data: Extract<DndElement, { label: Label; }>["data"]): boolean; }; defineInteraction: (interaction: DndInteraction<DndElement, DndElement>) => void; findHTMLElement: { (role: "container"): HTMLElement | undefined; <Role extends "source" | "dropzone">(role: Role, dndEl: Role extends "source" ? DndElement : DndElement): HTMLElement | undefined; }; findHTMLElements: { (role: "handle"): HTMLElement[]; <Role extends "source" | "dropzone">(role: Role, label?: (Role extends "source" ? string : string) | undefined): HTMLElement[]; }; findHandlesIn: (source: DndElement | HTMLElement) => HTMLElement[]; $findDndElement: { (role: "source", htmlEl: HTMLElement): DndElement | undefined; (role: "dropzone", htmlEl: HTMLElement): DndElement | undefined; }; $addNativeElement: <Role extends "container" | "source" | "dropzone" | "handle">(role: Role, htmlEl: HTMLElement, dndEl: Role extends "source" | "dropzone" ? DndElement : undefined) => void; $removeNativeElement: (role: "container" | "source" | "dropzone" | "handle", htmlEl: HTMLElement) => void; $setInitialized: (flag: boolean) => void; $setCurrentTarget: (value: DndElement | undefined) => void; $setCurrentSource: (value: DndElement | undefined) => void; }>; declare const injectDndModel: () => vue.Raw<{ readonly classes: Readonly<Required<DndClasses>>; readonly interactions: DndInteraction<DndElement, DndElement>[]; readonly initialized: boolean; readonly currentSource: DndElement | undefined; readonly currentTarget: DndElement | undefined; isDragging: { (): boolean; (label: string): boolean; <Label extends string>(label: Label, data: Extract<DndElement, { label: Label; }>["data"]): boolean; (source: DndElement): boolean; (predicate: (source: DndElement) => boolean): boolean; }; isDraggable: { (source: DndElement): boolean; <Label extends string>(label: Label, data: Extract<DndElement, { label: Label; }>["data"]): boolean; }; isOver: { (): boolean; (label: string): boolean; <Label extends string>(label: Label, data: Extract<DndElement, { label: Label; }>["data"]): boolean; (dropzone: DndElement): boolean; (predicate: (dropzone: DndElement) => boolean): boolean; }; isDroppable: { (dropzone: DndElement): boolean; <Label extends string>(label: Label, data: Extract<DndElement, { label: Label; }>["data"]): boolean; }; defineInteraction: (interaction: DndInteraction<DndElement, DndElement>) => void; findHTMLElement: { (role: "container"): HTMLElement | undefined; <Role extends "source" | "dropzone">(role: Role, dndEl: Role extends "source" ? DndElement : DndElement): HTMLElement | undefined; }; findHTMLElements: { (role: "handle"): HTMLElement[]; <Role extends "source" | "dropzone">(role: Role, label?: (Role extends "source" ? string : string) | undefined): HTMLElement[]; }; findHandlesIn: (source: DndElement | HTMLElement) => HTMLElement[]; $findDndElement: { (role: "source", htmlEl: HTMLElement): DndElement | undefined; (role: "dropzone", htmlEl: HTMLElement): DndElement | undefined; }; $addNativeElement: <Role extends "container" | "source" | "dropzone" | "handle">(role: Role, htmlEl: HTMLElement, dndEl: Role extends "source" | "dropzone" ? DndElement : undefined) => void; $removeNativeElement: (role: "container" | "source" | "dropzone" | "handle", htmlEl: HTMLElement) => void; $setInitialized: (flag: boolean) => void; $setCurrentTarget: (value: DndElement | undefined) => void; $setCurrentSource: (value: DndElement | undefined) => void; }> | undefined; declare const DndContainer: vue.DefineSetupFnComponent<DndContainerProps<DndElement, DndElement>>; declare const DndSource: vue.DefineSetupFnComponent<DndSourceProps<DndElement>>; declare const DndDropzone: vue.DefineSetupFnComponent<DndDropzoneProps<DndElement>>; declare const DndHandle: vue.DefineSetupFnComponent<DndHandleProps, {}, {}, vue.HTMLAttributes & { tag?: string; } & {}, vue.PublicProps>; export { DndContainer, DndDropzone, DndHandle, DndSource, DndSuite, injectDndModel, useDndModel }; export type { DndClasses, DndElement, DndInteraction, DndModel, DndModelOptions, IDndSuite };