import { destructor, optional, record, xy } from '@synnaxlabs/x';
import { default as React, DragEvent, DragEventHandler, PropsWithChildren, ReactElement, RefObject } from 'react';
import { z } from 'zod';
import { state } from '../state';
export declare const itemZ: z.ZodObject<{
    key: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
    type: z.ZodString;
    elementID: z.ZodOptional<z.ZodString>;
    data: z.ZodOptional<z.ZodRecord<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodUnknown>>;
}, z.core.$strip>;
export interface Item {
    key: record.Key;
    type: string;
    elementID?: string;
    data?: record.Unknown;
}
export declare const draggingStateZ: z.ZodObject<{
    source: z.ZodObject<{
        key: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
        type: z.ZodString;
        elementID: z.ZodOptional<z.ZodString>;
        data: z.ZodOptional<z.ZodRecord<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodUnknown>>;
    }, z.core.$strip>;
    items: z.ZodArray<z.ZodObject<{
        key: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
        type: z.ZodString;
        elementID: z.ZodOptional<z.ZodString>;
        data: z.ZodOptional<z.ZodRecord<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodUnknown>>;
    }, z.core.$strip>>;
}, z.core.$strip>;
export interface DraggingState {
    source: Item;
    items: Item[];
}
export declare const ZERO_ITEM: Item;
export declare const ZERO_DRAGGING_STATE: DraggingState;
interface DropProps {
    target: Item;
    dropped: Item[];
}
export declare const FILE_TYPE = "file";
export declare const FILE: Item;
export declare const isFileDrag: (event: DragEvent, dragging: DraggingState) => boolean;
interface DragEndInterceptor {
    (state: DraggingState, cursor: xy.XY): DropProps | null;
}
export interface ContextValue {
    state: DraggingState;
    start: (source: Item, items: Item[], onSuccessfulDrop?: (props: OnSuccessfulDropProps) => void) => void;
    end: (cursor: xy.XY) => void;
    drop: (props: DropProps) => void;
    bind: (interceptor: DragEndInterceptor) => destructor.Destructor;
}
declare const useContext: () => ContextValue | null;
export { useContext };
export interface ProviderProps extends PropsWithChildren {
    useState?: state.PureUse<DraggingState>;
    onDropOutside?: (props: OnDropProps) => Item[];
}
export declare const Provider: React.MemoExoticComponent<({ children, useState, onDropOutside, }: ProviderProps) => ReactElement>;
export declare const useDraggingRef: () => RefObject<DraggingState>;
export declare const useDraggingState: () => DraggingState;
export interface OnSuccessfulDropProps {
    target: Item;
    hauled: Item[];
    dropped: Item[];
}
export interface UseDragProps extends optional.Optional<Item, "key"> {
}
export interface UseDragReturn {
    startDrag: (items: Item[], onSuccessfulDrop?: (props: OnSuccessfulDropProps) => void) => void;
    onDragEnd: (e: DragEvent | MouseEvent) => void;
}
export declare const useDrag: ({ type, key }: UseDragProps) => UseDragReturn;
export interface CanDrop {
    (state: DraggingState): boolean;
}
export interface OnDropProps extends DraggingState {
    event?: DragEvent;
}
export interface OnDrop {
    (props: OnDropProps): Item[];
}
export interface OnDragOverProps extends OnDropProps {
}
export interface UseDropProps extends optional.Optional<Item, "key"> {
    canDrop: CanDrop;
    onDrop: OnDrop;
    onDragOver?: (props: OnDragOverProps) => void;
}
export interface UseDropReturn {
    onDragOver: DragEventHandler;
    onDrop: DragEventHandler;
}
export declare const useDrop: ({ type, key, canDrop, onDrop, onDragOver, }: UseDropProps) => UseDropReturn;
export interface UseDragAndDropProps extends Omit<UseDragProps, "source">, Omit<UseDropProps, "target">, optional.Optional<Item, "key"> {
}
export interface UseDragAndDropReturn extends UseDragReturn, UseDropReturn {
}
export declare const useDragAndDrop: ({ type, key, ...rest }: UseDragAndDropProps) => UseDragAndDropReturn;
export declare const canDropOfType: (type: string) => CanDrop;
export declare const filterByType: (type: string, entities: Item[]) => Item[];
export declare const useFilterByTypeCallback: (type: string, fn: OnDrop, deps: unknown[]) => OnDrop;
export interface UseDropOutsideProps extends Omit<UseDropProps, "onDrop"> {
    onDrop: (props: OnDropProps, cursor: xy.XY) => Item[];
}
//# sourceMappingURL=Haul.d.ts.map