/** * @fileoverview Shared motion presets for premium UI components. * @module packages/ui/components/ui/motion-config * @layer core * * Governance: * CSS transitions (var(--duration-*), var(--ease-*)) → hover, focus, color changes. * These tokens already zero-out via prefers-reduced-motion in motion.css. * * Motion springs → ONLY for mount/unmount, layout, drag, presence, gesture. * Use `useReducedMotion()` to disable springs when the user prefers reduced motion. * * @example * import { spring, useReducedMotion } from "@saasflare/ui"; * const reduced = useReducedMotion(); * */ import type { Transition } from "motion/react"; import { useReducedMotion } from "../../hooks/use-reduced-motion"; /** Re-export reduced-motion hook for convenience */ export { useReducedMotion }; /** Snappy spring — default for buttons, badges, interactive feedback */ export declare const spring: { readonly type: "spring"; readonly stiffness: 400; readonly damping: 25; }; /** Bouncy spring — dialogs, overlays, playful entrances */ export declare const springBouncy: { readonly type: "spring"; readonly stiffness: 300; readonly damping: 15; }; /** Gentle spring — cards, hover lifts, subtle motion */ export declare const springGentle: { readonly type: "spring"; readonly stiffness: 200; readonly damping: 20; }; /** Stiff spring — toggles, switches, tight animations */ export declare const springStiff: { readonly type: "spring"; readonly stiffness: 500; readonly damping: 30; }; /** Instant transition — used when reduced motion is preferred */ export declare const noMotion: { readonly duration: 0; }; /** Fade in preset (mount animation) */ export declare const fadeIn: { readonly initial: { readonly opacity: 0; }; readonly animate: { readonly opacity: 1; }; }; /** Scale in preset (mount animation) */ export declare const scaleIn: { readonly initial: { readonly opacity: 0; readonly scale: 0.95; }; readonly animate: { readonly opacity: 1; readonly scale: 1; }; }; /** Slide up preset (mount animation) */ export declare const slideUp: { readonly initial: { readonly opacity: 0; readonly y: 8; }; readonly animate: { readonly opacity: 1; readonly y: 0; }; }; /** Slide down preset (mount animation) */ export declare const slideDown: { readonly initial: { readonly opacity: 0; readonly y: -8; }; readonly animate: { readonly opacity: 1; readonly y: 0; }; }; /** Resolved motion settings for a Saasflare component. */ export interface SaasflareMotion { /** Spring or noMotion — drop directly onto `transition={…}`. */ transition: Transition; /** True when motion should be skipped — gate `whileHover`, `initial`, etc. */ disabled: boolean; } /** * Resolves the active transition for a component. * * Disables motion when **any** of these are true: * - Consumer opted out (`animated={false}` from prop or ``) * - OS reports `prefers-reduced-motion: reduce` * - Any `extraDisablers` (e.g. `disabled`, `loading`) is `true` * * Single tuning point — when later we differentiate spring tokens per component * (`springBouncy.checkbox`, `springSnappy.dialog`), the variants live next to * this hook and components don't change. * * @example * const sf = useSaasflareProps({ surface, radius, animated }) * const motion = useSaasflareMotion(sf.animated, springBouncy) * * // … * * * @example // Button-style with extra disablers * const motion = useSaasflareMotion(sf.animated, spring, disabled, loading) */ export declare function useSaasflareMotion(animated: boolean, base?: Transition, ...extraDisablers: boolean[]): SaasflareMotion;