@omicrxn/mercury
Version:
Mercury is a Svelte animation library powered by Motion. It simplifies complex animations with Svelte actions, provides layout and exit animations, and integrates seamlessly with Svelte features.
120 lines (119 loc) • 4.45 kB
TypeScript
import type { Easing } from 'motion';
export type { Easing };
export interface AnimationTransition {
type?: 'decay' | 'spring' | 'keyframes' | 'tween' | 'inertia';
duration?: number;
/** Visual duration (seconds) for springs. Overrides `duration` when set. */
visualDuration?: number;
autoplay?: boolean;
delay?: number;
ease?: Easing | Easing[];
/** Keyframe positions (0-1), one per animated keyframe. */
times?: number[];
repeat?: number;
repeatType?: 'loop' | 'reverse' | 'mirror';
repeatDelay?: number;
/**
* Spring bounciness (0 = no bounce, 1 = very bouncy) for duration-based springs.
* Ignored by Motion if `stiffness`/`damping`/`mass` are set.
*/
bounce?: number;
stiffness?: number;
damping?: number;
mass?: number;
velocity?: number;
restSpeed?: number;
restDelta?: number;
}
/** Mirrors Motion's animation playback lifecycle callbacks. */
export interface AnimationCallbacks {
onPlay?: () => void;
onComplete?: () => void;
onUpdate?: (latest: any) => void;
onRepeat?: () => void;
onStop?: () => void;
}
export interface AnimationAttributes {
[key: string]: any;
}
export interface InteractionAnimation extends AnimationAttributes {
transition?: AnimationTransition;
}
export type PresenceMode = 'sync' | 'wait' | 'popLayout';
/** One side of a presence animation (enter or exit). */
export interface PresenceSpec extends AnimationAttributes {
/** Overrides the shared `transition` for this direction. */
transition?: AnimationTransition;
}
export interface PresenceAnimation extends AnimationAttributes {
transition?: AnimationTransition;
mode?: PresenceMode;
/**
* The hidden state the element enters from (motion's `initial`). On enter it
* animates from these values to its settled CSS styles. Array values are
* treated as full keyframes.
*/
initial?: PresenceSpec;
/** Exit spec (motion's `exit`): values the element animates to before removal. */
exit?: PresenceSpec;
}
export interface ScrollInteractionAnimation extends InteractionAnimation {
root?: HTMLElement;
margin?: string;
amount?: number | 'all' | 'some' | undefined;
enter?: AnimationAttributes;
exit?: AnimationAttributes;
}
export interface DragOptions {
axis?: 'x' | 'y' | 'lock' | undefined;
bounds?: {
left?: number;
right?: number;
top?: number;
bottom?: number;
} | HTMLElement | {
current: HTMLElement | null;
};
rubberband?: boolean | number;
}
export interface AnimationParams {
instance?: (instance: AnimationInstance) => void;
/**
* Whether `animate` plays the first time the attachment is applied to an element.
* Defaults to `true`. Set to `false` (Motion's `initial={false}`) to render the
* element directly in its `animate` state on mount — keyframe arrays snap to their
* last frame — and only animate on subsequent updates.
*
* Note: this is NOT a from-state. The attachment runs after the element is already
* in the DOM, so it cannot paint a hidden starting style before the first frame.
* For "enter from a hidden state" use `initial` on `transition:presence` instead.
*/
animateOnMount?: boolean;
animate?: AnimationAttributes;
transition?: AnimationTransition;
onHoverStart?: (event: PointerEvent) => void;
onHoverEnd?: (event: PointerEvent) => void;
whileHover?: InteractionAnimation;
onTapStart?: (event: PointerEvent) => void;
onTapEnd?: (event: PointerEvent) => void;
whileTap?: InteractionAnimation;
drag?: boolean;
/**
* Configures how the drag behaves: `axis` lock, `bounds`, and `rubberband` elasticity.
* This is drag *configuration*, not an animation — it does not animate the element
* while dragging.
*/
dragOptions?: DragOptions;
onDragStart?: (event: PointerEvent | MouseEvent | TouchEvent | KeyboardEvent) => void;
onDragEnd?: (event: PointerEvent | MouseEvent | TouchEvent | KeyboardEvent) => void;
scroll?: ScrollInteractionAnimation;
callbacks?: AnimationCallbacks;
}
export interface AnimationInstance {
play: () => any | void;
pause: () => any | void;
stop: () => any | void;
cancel: () => any | void;
onComplete: (onResolve: VoidFunction, onReject?: VoidFunction) => Promise<any>;
completed: boolean;
}