import type { HTMLAttributes } from 'svelte/elements';
import type { NeoHandlePlacements, NeoHandleProps } from '../common/neo-handle.model.js';
import type { NeoDialogPlacement } from '../common/neo-placement.model.js';
export interface NeoMovableSnapTranslate {
    /**
     * Translate duration (in ms).
     *
     * @default 600
     */
    duration?: number;
    /**
     * Easing function.
     *
     * @default 'var(--neo-easing-spring, ease-in-out)'
     */
    easing?: string;
}
export interface NeoMovableSnap {
    /**
     * Whether the movable should snap to the viewport edges & center.
     */
    enabled?: boolean;
    /**
     * Whether the element should only snap to the corners of the viewport.
     */
    corner?: boolean;
    /**
     * Whether snapping to a corner should change the element placement.
     */
    placement?: boolean;
    /**
     * Whether the element can be snapped outside the viewport (with handles peeking in).
     *
     * @default true
     */
    outside?: boolean;
    /**
     * How much of the element should be visible when snapped outside the viewport.
     *
     * @default 25
     */
    offset?: number;
    /**
     * Translate css to apply when snapping to a position
     */
    translate?: NeoMovableSnapTranslate;
}
export type NeoMovableHandle = Pick<NeoHandleProps, 'visible' | 'handle' | 'position' | 'minSize'> & {
    /**
     * Whether the whole element should act as a handle.
     */
    full?: boolean;
};
export interface NeoMovableLimit {
    min?: number;
    max?: number;
}
export interface NeoMovableLimits {
    x?: NeoMovableLimit;
    y?: NeoMovableLimit;
}
export interface NeoMovableThreshold {
    x?: number;
    y?: number;
    top?: number;
    right?: number;
    bottom?: number;
    left?: number;
    outside?: boolean;
}
export type NeoMovable<Parsed extends boolean = false> = Pick<NeoHandleProps, 'enabled' | 'placement' | 'axis' | 'outside'> & {
    /**
     * The step size for dragging the element with arrow keys.
     *
     * @default 4
     */
    step?: number;
    /**
     * The margin around the element when snapping to the viewport edges.
     *
     * @default 16px
     */
    margin?: number;
    /**
     * Whether the element should be contained within to the viewport edges.
     */
    contain?: boolean;
    /**
     * Boundaries for the element movement.
     */
    limits?: NeoMovableLimits;
    /**
     * Whether the element's offset should be reset when it is closed.
     *
     * @default true
     */
    resetOnClose?: boolean;
    /**
     * The threshold offset over which the element should be closed.
     *
     * If falsy, the element will not be closed no matter how far it is dragged.
     *
     * All thresholds are absolute values.
     *
     * @default 0
     */
    closeThreshold?: number | NeoMovableThreshold;
    /**
     * Whether to show a handle for dragging the element.
     * If 'true', the handle will be visible whenever most appropriate.
     *
     * @default true
     */
    handle?: Parsed extends true ? NeoMovableHandle : boolean | NeoMovableHandle;
    /**
     * Whether the element should snap to the viewport edges.
     * If 'corner', the element will snap to the closest corner.
     *
     * @default false
     */
    snap?: Parsed extends true ? NeoMovableSnap : boolean | 'corner' | NeoMovableSnap;
};
export interface NeoMoved {
    x: number;
    y: number;
}
export type NeoMovableOutside = false | NeoHandlePlacements;
export type NeoMovableHandlers<Element extends HTMLElement> = Pick<HTMLAttributes<Element>, 'onpointerdown' | 'onkeydown' | 'onkeyup' | 'onblur'>;
export interface NeoMovableUseOptions<Element extends HTMLElement, Handle extends HTMLElement> {
    /**
     * The element's offset from its original position if any (applied transform).
     */
    offset: NeoMoved;
    /**
     * Whether the element is outside the viewport, and in which direction.
     */
    outside: NeoMovableOutside;
    /**
     * The element original placement.
     */
    placement: NeoDialogPlacement;
    /**
     * Movable options.
     */
    movable?: Partial<NeoMovable>;
    /**
     * Reference to the element to move.
     */
    element?: Element;
    /**
     * Callback to close the element.
     */
    close?: () => unknown | Promise<unknown>;
    /**
     * Event handlers to attach to the handle.
     */
    handlers?: Partial<NeoMovableHandlers<Handle>>;
}
export interface NeoMovableOffsetOptions {
    contain?: boolean;
    outside?: NeoMovableOutside;
    limits?: NeoMovableLimits;
}
export type NeoMovableResetOptions = NeoMovableOffsetOptions & {
    x?: number;
    y?: number;
    translate?: boolean | NeoMovableSnapTranslate;
};
export interface NeoMovableUseResult<Element extends HTMLElement, Handle extends HTMLElement> {
    /**
     * The element's offset from its original position if any (applied transform).
     */
    offset: NeoMoved;
    /**
     * Whether the element is outside the viewport, and in which direction.
     */
    outside: NeoMovableOutside;
    /**
     * The element original placement.
     */
    placement: NeoDialogPlacement;
    /**
     * Original movable options.
     */
    movable: NeoMovable;
    /**
     * Reference to the element to move.
     */
    element?: Element;
    /**
     * The css translate value to apply to the element.
     */
    translate: CSSStyleDeclaration['translate'];
    /**
     * If the element is currently being translated programmatically (snap or arrow keys).
     */
    translating: number;
    /**
     * If the element is currently being moved by the user (drag).
     */
    moving: boolean;
    /**
     * Event handlers to attach to the handle.
     */
    handlers: NeoMovableHandlers<Handle>;
    /**
     * Reset the element's offset to its original position.
     */
    reset: (options?: NeoMovableResetOptions) => Promise<boolean>;
}
export declare const defaultSnap: Required<NeoMovableSnap>;
export declare const defaultHandle: NeoMovableHandle;
export declare const defaultMovable: NeoMovable;
export declare function useMovable<Element extends HTMLElement, Handle extends HTMLElement>(options: NeoMovableUseOptions<Element, Handle>): NeoMovableUseResult<Element, Handle>;
