import { Ref } from 'vue';

/**
 * Move sortable elements in the list
 * @param list List of sortable elements
 * @param from Original element position
 * @param to New element position
 */
export declare function moveSortableElements<ListItem>({ list, from, to }: MoveSortableElementsOptions<ListItem>): void;

export declare interface MoveSortableElementsOptions<T> {
    list: RefOrGetter<T[]>;
    from: number;
    to: number;
}

/**
 * Like the MaybeRefOrGetter type from Vue, but without the Maybe. Can be used to ensure the most up-to-date value is available.
 */
declare type RefOrGetter<T> = Ref<T> | (() => T);

export declare interface SortableDragEvent extends DragEvent {
    /**
     * The old index of the dragged element
     */
    oldIndex: number;
    /**
     * The new index of the dragged element
     */
    newIndex: number;
}

export declare type SortableOnDragEndEvent = SortableDragEvent;

export declare type SortableOnDragStartEvent = Omit<SortableDragEvent, 'newIndex'>;

declare function useSortable<SortableItem>({ isEnabled, sortInPlace, ...options }: UseSortableOptions<SortableItem>): UseSortableReturn;
export default useSortable;

export declare interface UseSortableOptions<SortableItem> {
    /**
     * The parent element of the sortable elements
     */
    ref: Ref<HTMLElement | null>;
    /**
     * The list of sortable elements to be sorted
     */
    list: Ref<SortableItem[]>;
    /**
     * Enables/Disables drag and drop sorting
     * @default true
     */
    isEnabled?: boolean;
    /**
     * Class name for the ghost element
     * @default ''
     */
    ghostClass?: string;
    /**
     * Class name for the chosen element
     * @default ''
     */
    chosenClass?: string;
    /**
     * Sort the list in place
     * @default true
     */
    sortInPlace?: boolean;
    /**
     * Callback when the dragging starts
     */
    onDragStart?: (e: SortableOnDragStartEvent) => void;
    /**
     * Callback when the dragging ends
     */
    onDragEnd?: (e: SortableOnDragEndEvent) => void;
}

export declare interface UseSortableReturn {
    /**
     * Whether the element is currently being dragged
     */
    isDragging: Ref<boolean>;
    /**
     * The new position of the dragged element
     */
    newIndex: Ref<number>;
    /**
     * The original position of the dragged element
     */
    oldIndex: Ref<number>;
}

export { }
