@dvcol/neo-svelte
Version:
Neomorphic ui library for svelte 5
215 lines (214 loc) • 6.26 kB
TypeScript
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>;