UNPKG

framer-motion

Version:

<p align="center"> <img src="https://user-images.githubusercontent.com/38039349/60953119-d3c6f300-a2fc-11e9-9596-4978e5d52180.png" width="176" height="170" alt="Framer Motion" /> </p>

1,802 lines (1,764 loc) • 154 kB
/// <reference types="react" /> import { ComponentType } from 'react'; import { CSSProperties } from 'react'; import { DetailedHTMLFactory } from 'react'; import { Easing as Easing_2 } from '@popmotion/easing'; import { ForwardRefExoticComponent } from 'react'; import { FunctionComponent } from 'react'; import { HTMLAttributes } from 'react'; import * as React from 'react'; import { ReactElement } from 'react'; import { ReactHTML } from 'react'; import { ReactNode } from 'react'; import { Ref } from 'react'; import { RefAttributes } from 'react'; import { RefObject } from 'react'; import { SpringProps } from 'popmotion'; import { SVGAttributes } from 'react'; /** * The `AnimatePresence` component enables the use of the `exit` prop to animate components * when they're removed from the component tree. * * When adding/removing more than a single child component, every component * **must** be given a unique `key` prop. * * You can propagate exit animations throughout a tree by using variants. * * @library * * You can use any component(s) within `AnimatePresence`, but the first `Frame` in each should * have an `exit` property defined. * * ```jsx * import { Frame, AnimatePresence } from 'framer' * * // As items are added and removed from `items` * export function Items({ items }) { * return ( * <AnimatePresence> * {items.map(item => ( * <Frame * key={item.id} * initial={{ opacity: 0 }} * animate={{ opacity: 1 }} * exit={{ opacity: 0 }} * /> * ))} * </AnimatePresence> * ) * } * ``` * * @motion * * You can use any component(s) within `AnimatePresence`, but the first `motion` component in each should * have an `exit` property defined. * * ```jsx * import { motion, AnimatePresence } from 'framer-motion' * * export const Items = ({ items }) => ( * <AnimatePresence> * {items.map(item => ( * <motion.div * key={item.id} * initial={{ opacity: 0 }} * animate={{ opacity: 1 }} * exit={{ opacity: 0 }} * /> * ))} * </AnimatePresence> * ) * ``` * * @public */ export declare const AnimatePresence: FunctionComponent<AnimatePresenceProps>; /** * @public */ export declare interface AnimatePresenceProps { /** * By passing `initial={false}`, `AnimatePresence` will disable any initial animations on children * that are present when the component is first rendered. * * @library * * ```jsx * <AnimatePresence initial={false}> * {isVisible && ( * <Frame * key="modal" * initial={{ opacity: 0 }} * animate={{ opacity: 1 }} * exit={{ opacity: 0 }} * /> * )} * </AnimatePresence> * ``` * * @motion * * ```jsx * <AnimatePresence initial={false}> * {isVisible && ( * <motion.div * key="modal" * initial={{ opacity: 0 }} * animate={{ opacity: 1 }} * exit={{ opacity: 0 }} * /> * )} * </AnimatePresence> * ``` * * @public */ initial?: boolean; /** * When a component is removed, there's no longer a chance to update its props. So if a component's `exit` * prop is defined as a dynamic variant and you want to pass a new `custom` prop, you can do so via `AnimatePresence`. * This will ensure all leaving components animate using the latest data. * * @public */ custom?: any; /** * Fires when all exiting nodes have completed animating out. * * @public */ onExitComplete?: () => void; /** * `AnimatePresence` locally re-renders its children once exit animations are * complete. This means that if surrounding or parent components are also set to `positionTransition`, * they aren't informed of updates to the layout when they happen asynchronous to a render. * * This prop allows `AnimatePresence` to trigger re-renders at a higher level, so more * components can be made aware of the layout change and animate accordingly. * * In this example, the both the parent and sibling will animate to their new layout * once the div within `AnimatePresence` has finished animating: * * ```jsx * const MyComponent = ({ isVisible }) => { * const forceUpdate = useForceUpdate() // Forces a set state or something * * return ( * <motion.div positionTransition> * <AnimatePresence _syncLayout={forceUpdate}> * <motion.div positionTransition exit={{ opacity: 0 }} /> * </AnimatePresence> * <motion.div positionTransition /> * </motion.div> * ) * } * ``` * * In the final implementation `syncLayout` might be better as a component * that provides this function to children via context, or some other method * that obfuscates * * This isn't generally a problem for most use-cases but this capability will be useful * for advanced uses but also more so for phase 2 of `sizeTransition`, as we'd gain the power * to declaratively relayout entire parts of the page using only performant transforms. * * @internal */ _syncLayout?: () => void; /** * If set to `true`, `AnimatePresence` will only render one component at a time. The exiting component * will finished its exit animation before the entering component is rendered. * * @library * * ```jsx * function MyComponent({ currentItem }) { * return ( * <AnimatePresence exitBeforeEnter> * <Frame key={currentItem} exit={{ opacity: 0 }} /> * </AnimatePresence> * ) * } * ``` * * @motion * * ```jsx * const MyComponent = ({ currentItem }) => ( * <AnimatePresence exitBeforeEnter> * <motion.div key={currentItem} exit={{ opacity: 0 }} /> * </AnimatePresence> * ) * ``` * * @beta */ exitBeforeEnter?: boolean; } /** * Control animations on one or more components. * * @public */ export declare class AnimationControls { /** * Track whether the host component has mounted. * * @internal */ private hasMounted; /** * A default `Transition` to set on linked components. * * @internal */ private defaultTransition; /** * Pending animations that are started before a component is mounted. * * @internal */ private pendingAnimations; /** * A collection of linked component animation controls. * * @internal */ private componentControls; /** * A map of variants that can be later referenced via `start(variantLabel)` * * @internal */ private variants; /** * Set variants on this and all child components. * * @param variants - The variants to set * * @internal */ setVariants(variants: Variants): void; /** * Set a default transition on this and all child components * * @param transition - The default transition to set * * @internal */ setDefaultTransition(transition: Transition): void; /** * Subscribes a component's animation controls to this. * * @param controls - The controls to subscribe * @returns An unsubscribe function. * * @internal */ subscribe(controls: ValueAnimationControls): () => boolean; /** * Starts an animation on all linked components. * * @remarks * * ```jsx * controls.start("variantLabel") * controls.start({ * x: 0, * transition: { duration: 1 } * }) * ``` * * @param definition - Properties or variant label to animate to * @param transition - Optional `transtion` to apply to a variant * @returns - A `Promise` that resolves when all animations have completed. * * @public */ start(definition: AnimationDefinition, transitionOverride?: Transition): Promise<any>; /** * Instantly set to a set of properties or a variant. * * ```jsx * // With properties * controls.set({ opacity: 0 }) * * // With variants * controls.set("hidden") * ``` * * @internalremarks * We could perform a similar trick to `.start` where this can be called before mount * and we maintain a list of of pending actions that get applied on mount. But the * expectation of `set` is that it happens synchronously and this would be difficult * to do before any children have even attached themselves. It's also poor practise * and we should discourage render-synchronous `.start` calls rather than lean into this. * * @public */ set(definition: VariantLabels | TargetAndTransition): void; /** * Stops animations on all linked components. * * ```jsx * controls.stop() * ``` * * @public */ stop(): void; /** * Initialises the animation controls. * * @internal */ mount(): void; /** * Stops all child animations when the host component unmounts. * * @internal */ unmount(): void; } /** * @internal */ export declare const animationControls: () => AnimationControls; declare type AnimationDefinition = VariantLabels | TargetAndTransition | TargetResolver; declare type AnimationOptions = { delay?: number; priority?: number; transitionOverride?: Transition; }; /** * @public */ export declare interface AnimationProps { /** * Values to animate to, variant label(s), or `AnimationControls`. * * @library * * ```jsx * // As values * <Frame animate={{ opacity: 1 }} /> * * // As variant * <Frame animate="visible" variants={variants} /> * * // Multiple variants * <Frame animate={["visible", "active"]} variants={variants} /> * * // AnimationControls * <Frame animate={animation} /> * ``` * * @motion * * ```jsx * // As values * <motion.div animate={{ opacity: 1 }} /> * * // As variant * <motion.div animate="visible" variants={variants} /> * * // Multiple variants * <motion.div animate={["visible", "active"]} variants={variants} /> * * // AnimationControls * <motion.div animate={animation} /> * ``` */ animate?: AnimationControls | TargetAndTransition | VariantLabels; /** * A target to animate to when this component is removed from the tree. * * This component **must** be the first animatable child of an `AnimatePresence` to enable this exit animation. * * This limitation exists because React doesn't allow components to defer unmounting until after * an animation is complete. Once this limitation is fixed, the `AnimatePresence` component will be unnecessary. * * @library * * ```jsx * import { Frame, AnimatePresence } from 'framer' * * export function MyComponent(props) { * return ( * <AnimatePresence> * {props.isVisible && ( * <Frame * initial={{ opacity: 0 }} * animate={{ opacity: 1 }} * exit={{ opacity: 0 }} * /> * )} * </AnimatePresence> * ) * } * ``` * * @motion * * ```jsx * import { AnimatePresence, motion } from 'framer-motion' * * export const MyComponent = ({ isVisible }) => { * return ( * <AnimatePresence> * {isVisible && ( * <motion.div * initial={{ opacity: 0 }} * animate={{ opacity: 1 }} * exit={{ opacity: 0 }} * /> * )} * </AnimatePresence> * ) * } * ``` */ exit?: AnimationControls | TargetAndTransition | VariantLabels; /** * Variants allow you to define animation states and organise them by name. They allow * you to control animations throughout a component tree by switching a single `animate` prop. * * Using `transition` options like `delayChildren` and `staggerChildren`, you can orchestrate * when children animations play relative to their parent. * * @library * * After passing variants to one or more `Frame`'s `variants` prop, these variants * can be used in place of values on the `animate`, `initial`, `whileTap` and `whileHover` props. * * ```jsx * const variants = { * active: { * backgroundColor: "#f00" * }, * inactive: { * backgroundColor: "#fff", * transition: { duration: 2 } * } * } * * <Frame variants={variants} animate="active" /> * ``` * * @motion * * After passing variants to one or more `motion` component's `variants` prop, these variants * can be used in place of values on the `animate`, `initial`, `whileTap` and `whileHover` props. * * ```jsx * const variants = { * active: { * backgroundColor: "#f00" * }, * inactive: { * backgroundColor: "#fff", * transition: { duration: 2 } * } * } * * <motion.div variants={variants} animate="active" /> * ``` */ variants?: Variants; /** * Default transition. If no `transition` is defined in `animate`, it will use the transition defined here. * * @library * * ```jsx * const spring = { * type: "spring", * damping: 10, * stiffness: 100 * } * * <Frame transition={spring} animate={{ scale: 1.2 }} /> * ``` * * @motion * * ```jsx * const spring = { * type: "spring", * damping: 10, * stiffness: 100 * } * * <motion.div transition={spring} animate={{ scale: 1.2 }} /> * ``` */ transition?: Transition; /** * @library * * When a `Frame` is the child of a `Stack`, the `Stack` is responsible for its layout. This makes it harder * for us to know when a `Frame`'s position changes within the `Stack` and make it animate to its new position. * * By adding `positionTransition` to a `Frame`, it'll automatically animate to its new position in the `Stack`, * whether the `Stack` layout has changed or the `Frame` has changed its order within it. * * It can either be set as a `Transition`, or just `true` to use the default layout transition. * * ```jsx * function MyComponent({ distribution = "space-around" }) { * const spring = { * type: "spring", * damping: 10, * stiffness: 100 * } * * return ( * <Stack distribution={distribution}> * <Frame layoutTransition={spring} /> * </Stack> * ) * } * ``` * * @motion * * If `positionTransition` is defined on a `motion` component, it will automatically animate any changes to its layout * using a performant `x`/`y` transform. * * `positionTransition` can either be set as a `Transition`, or just `true` to use the default position transition, which is a snappy spring. * * It can also be set as a function that will resolve when the component has changed layout. This function * should return either a `Transition`, or `true`. For advanced use-cases where you want the component * to visually stay in its previous position, this function can also return `false`. This function will receive * the `delta` of the changed layout. * * ```jsx * const spring = { * type: "spring", * damping: 10, * stiffness: 100 * } * * // This component will animate position when `isVisible` is toggled. * const MyComponent = ({ isOpen }) => { * return ( * <motion.div positionTransition={spring} style={{ left: isOpen ? 0 : 100 }} /> * ) * } * * // This component will animate items to their new position if its place in `items` changes order. * const MyComponent = ({ items }) => { * return items.map((item) => ( * <motion.div key={item.id} positionTransition={spring} /> * )) * } * ``` * * @public */ positionTransition?: Transition | boolean | ResolveLayoutTransition; /** * @library * * When a `Frame` is the child of a `Stack`, the `Stack` is responsible for its layout. This makes it * difficult for to know when the layout changes and smoothly animate components to their new positions. * * By adding `layoutTransition` to a child `Frame`, it'll automatically animate to its new position * when it moves in the `Stack`, whether the `Stack` layout has changed, or the `Frame` has changed order within it. * * It can either be set as a `Transition`, or just `true` to use the default layout transition. * * Animating size with `scale` can introduce visual distortion to the component's children. If unwanted, * the `useInvertedScale` function can be used to undo this distortion. * * ```jsx * function MyComponent({ distribution = "space-around" }) { * const spring = { * type: "spring", * damping: 10, * stiffness: 100 * } * * return ( * <Stack distribution={distribution}> * <Frame layoutTransition={spring} /> * </Stack> * ) * } * ``` * * @motion * * If `layoutTransition` is defined on a `motion` component, the component will automatically * animate any changes to its position **and** size. * * It will do so using performant transforms. So if a `motion` component changes position, it'll animate * to its new position using `x` and `y`. If it changes size, it'll animate using `scaleX` and `scaleY`. * * Animating size with `scale` can introduce visual distortion to the component's children. If unwanted, * the `useInvertedScale` function can be used to undo this distortion. * * `layoutTransition` can either be set as a `Transition`, or just `true` to use the default layout transition, * which is a smooth `0.8` second ease. * * It can also be set as a function that will resolve when the component has changed layout. This function * should return either a `Transition`, or `true`. For advanced use-cases where you want the component * to visually stay in its previous position, this function can also return `false`. This function will receive * the `delta` of the changed layout. * * ```jsx * const spring = { * type: "spring", * damping: 10, * stiffness: 100 * } * * // This component will animate between sizes when `isVisible` is toggled. * const MyComponent = ({ isVisible }) => { * return ( * <motion.div layoutTransition={spring}> * {isVisible && <Content />} * </motion.div> * ) * } * ``` * * @beta */ layoutTransition?: Transition | boolean | ResolveLayoutTransition; } declare type Config<T> = { transformer?: Transformer<T>; parent?: MotionValue<T>; }; declare interface ControlsProp { controls?: ValueAnimationControls; } /** * @internal */ export declare const createMotionComponent: <P extends {}>({ getValueControlsConfig, loadFunctionalityComponents, renderComponent, }: MotionComponentConfig) => React.ForwardRefExoticComponent<React.PropsWithoutRef<P & MotionProps> & React.RefAttributes<Element>>; declare type CSSPropertiesWithoutTransitionOrSingleTransforms = Omit<CSSProperties, "transition" | "rotate" | "scale" | "perspective">; declare interface CustomStyles { /** * Framer Library custom prop types. These are not actually supported in Motion - preferably * we'd have a way of external consumers injecting supported styles into this library. */ size?: string | number; radius?: string | number; shadow?: string; image?: string; } /** * @public */ export declare interface CustomValueType { mix: (from: any, to: any) => (p: number) => number | string; toValue: () => number | string; } declare type Cycle = (i?: number) => void; declare type CycleState<T> = [T, Cycle]; /** * @public */ export declare interface DraggableProps extends DragHandlers { /** * Enable dragging for this element. Set to `false` by default. * Set `true` to drag in both directions. * Set `"x"` or `"y"` to only drag in a specific direction. * * @library * * ```jsx * <Frame drag="x" /> * ``` * * @motion * * ```jsx * <motion.div drag="x" /> * ``` */ drag?: boolean | "x" | "y"; /** * If `true`, this will lock dragging to the initially-detected direction. Defaults to `false`. * * @library * * ```jsx * <Frame drag={true} dragDirectionLock={true} /> * ``` * * @motion * * ```jsx * <motion.div drag dragDirectionLock /> * ``` */ dragDirectionLock?: boolean; /** * Allows drag gesture propagation to child components. Set to `false` by * default. * * @library * * ```jsx * <Frame drag="x" dragPropagation={true} /> * ``` * * @motion * * ```jsx * <motion.div drag="x" dragPropagation /> * ``` */ dragPropagation?: boolean; /** * An object of optional `top`, `left`, `right`, `bottom` pixel values, * beyond which dragging is constrained. * * Another component can be used as drag constraints by creating a `ref` with React's `useRef`.hook. * This `ref` should be passed to that component's `ref` prop and to this component's `dragConstraints` prop. * * @library * * ```jsx * // In pixels * <Frame * drag="x" * dragConstraints={{ left: 0, right: 300 }} * /> * * // As a ref to another component * function MyComponent() { * const constraintsRef = useRef(null) * * return ( * <Frame ref={constraintsRef} width={400} height={400}> * <Frame drag dragConstraints={constraintsRef} /> * </Frame> * ) * } * ``` * * @motion * * ```jsx * // In pixels * <motion.div * drag="x" * dragConstraints={{ left: 0, right: 300 }} * /> * * // As a ref to another component * const MyComponent = () => { * const constraintsRef = useRef(null) * * return ( * <motion.div ref={constraintsRef}> * <motion.div drag dragConstraints={constraintsRef} /> * </motion.div> * ) * } * ``` */ dragConstraints?: false | { top?: number; right?: number; bottom?: number; left?: number; } | RefObject<Element>; /** * The degree of movement allowed outside constraints. 0 = no movement, 1 = * full movement. Set to `0.5` by default. * * @library * * ```jsx * <Frame * drag={true} * dragConstraints={{ left: 0, right: 300 }} * dragElastic={0.2} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragConstraints={{ left: 0, right: 300 }} * dragElastic={0.2} * /> * ``` */ dragElastic?: boolean | number; /** * Apply momentum from the pan gesture to the component when dragging * finishes. Set to `true` by default. * * @library * * ```jsx * <Frame * drag={true} * dragConstraints={{ left: 0, right: 300 }} * dragMomentum={false} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragConstraints={{ left: 0, right: 300 }} * dragMomentum={false} * /> * ``` */ dragMomentum?: boolean; /** * Allows you to change dragging inertia parameters. * When releasing a draggable Frame, an animation with type `inertia` starts. The animation is based on your dragging velocity. This property allows you to customize it. * See {@link https://framer.com/api/animation/#inertia | Inertia} for all properties you can use. * * @library * * ```jsx * <Frame * drag={true} * dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }} * /> * ``` */ dragTransition?: InertiaOptions; /** * @internalremarks * * _dragValueX, _dragValueY and _dragTransitionControls are a way of allowing this * component to be a drag target for another element. * * @internal */ _dragValueX?: MotionValue<number>; /** * @internal */ _dragValueY?: MotionValue<number>; /** * @internal */ _dragTransitionControls?: AnimationControls; /** * Drag position is calculated by applying the pan offset to the x/y origin * measured when the drag gesture begins. * * By manually creating `dragOriginX` as a `MotionValue`, it can be updated * while the gesture is active, for instance to visually offset any movement should * the component change layout. * * @library * * ```jsx * const dragOriginX = useMotionValue(0) * * return <Frame dragOriginX={dragOriginX} /> * ``` * * @motion * * ```jsx * const dragOriginX = useMotionValue(0) * * return <motion.div dragOriginX={dragOriginX} /> * ``` * * @public */ dragOriginX?: MotionValue<number>; /** * Drag position is calculated by applying the pan offset to the x/y origin * measured when the drag gesture begins. * * By manually creating `dragOriginY` as a `MotionValue`, it can be updated * while the gesture is active, for instance to visually offset any movement should * the component change layout. * * @library * * ```jsx * const dragOriginY = useMotionValue(0) * * return <Frame dragOriginY={dragOriginY} /> * ``` * * @motion * * ```jsx * const dragOriginY = useMotionValue(0) * * return <motion.div dragOriginY={dragOriginY} /> * ``` * * @public */ dragOriginY?: MotionValue<number>; } /** @public */ export declare interface DragHandlers { /** * Callback function that fires when dragging starts. * * @library * * ```jsx * function onDragStart(event, info) { * console.log(info.point.x, info.point.y) * } * * <Frame drag onDragStart={onDragStart} /> * ``` * * @motion * * ```jsx * <motion.div * drag * onDragStart={ * (event, info) => console.log(info.point.x, info.point.y) * } * /> * ``` */ onDragStart?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void; /** * Callback function that fires when dragging ends. * * @library * * ```jsx * function onDragEnd(event, info) { * console.log(info.point.x, info.point.y) * } * * <Frame drag onDragEnd={onDragEnd} /> * ``` * * @motion * * ```jsx * <motion.div * drag * onDragEnd={ * (event, info) => console.log(info.point.x, info.point.y) * } * /> * ``` */ onDragEnd?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void; /** * Callback function that fires when the component is dragged. * * @library * * ```jsx * function onDrag(event, info) { * console.log(info.point.x, info.point.y) * } * * <Frame drag onDrag={onDrag} /> * ``` * * @motion * * ```jsx * <motion.div * drag * onDrag={ * (event, info) => console.log(info.point.x, info.point.y) * } * /> * ``` */ onDrag?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void; /** * Callback function that fires a drag direction is determined. * * @library * * ```jsx * function onDirectionLock(axis) { * console.log(axis) * } * * <Frame * drag * dragDirectionLock * onDirectionLock={onDirectionLock} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragDirectionLock * onDirectionLock={axis => console.log(axis)} * /> * ``` */ onDirectionLock?(axis: "x" | "y"): void; /** * Callback function that fires when drag momentum/bounce transition finishes. * * @library * * ```jsx * function onDragTransitionEnd() { * console.log('drag transition has ended') * } * * <Frame * drag * onDragTransitionEnd={onDragTransitionEnd} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * onDragTransitionEnd={() => console.log('Drag transition complete')} * /> * ``` */ onDragTransitionEnd?(): void; } /** * The easing function to use. Set as one of: * * - The name of an in-built easing function. * - An array of four numbers to define a cubic bezier curve. * - An easing function, that accepts and returns a progress value between `0` and `1`. * * @public */ declare type Easing = [number, number, number, number] | "linear" | "easeIn" | "easeOut" | "easeInOut" | "circIn" | "circOut" | "circInOut" | "backIn" | "backOut" | "backInOut" | "anticipate" | EasingFunction; /** * A function that accepts a progress value between `0` and `1` and returns a * new one. * * @library * * ```jsx * const transition = { * ease: progress => progress * progress * } * * <Frame * animate={{ opacity: 0 }} * transition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * animate={{ opacity: 0 }} * transition={{ * duration: 1, * ease: progress => progress * progress * }} * /> * ``` * * @public */ export declare type EasingFunction = (v: number) => number; /** @public */ export declare interface EventInfo { point: Point; } declare interface ExitProps { initial?: false | VariantLabels; isExiting?: boolean; onExitComplete?: () => void; custom?: any; } declare interface FunctionalProps extends MotionProps { controls: ValueAnimationControls; values: MotionValuesMap; innerRef: RefObject<Element>; } /** * @public */ export declare type GestureHandlers = PanHandlers & TapHandlers & HoverHandlers; /** * @public */ export declare interface HoverHandlers { /** * Properties or variant label to animate to while the hover gesture is recognised. * * @library * * ```jsx * <Frame whileHover={{ scale: 1.2 }} /> * ``` * * @motion * * ```jsx * <motion.div whileHover={{ scale: 1.2 }} /> * ``` */ whileHover?: string | TargetAndTransition; /** * Callback function that fires when pointer starts hovering over the component. * * @library * * ```jsx * function onHoverStart(event) { * console.log("Hover starts") * } * * <Frame onHoverStart={onHoverStart} /> * ``` * * @motion * * ```jsx * <motion.div onHoverStart={() => console.log('Hover starts')} /> * ``` */ onHoverStart?(event: MouseEvent, info: EventInfo): void; /** * Callback function that fires when pointer stops hovering over the component. * * @library * * ```jsx * function onHoverEnd(event) { * console.log("Hover ends") * } * * <Frame onHoverEnd={onHoverEnd} /> * ``` * * @motion * * ```jsx * <motion.div onHoverEnd={() => console.log("Hover ends")} /> * ``` */ onHoverEnd?(event: MouseEvent, info: EventInfo): void; } declare type HTMLAttributesWithoutMotionProps<Attributes extends HTMLAttributes<Element>, Element extends HTMLElement> = { [K in Exclude<keyof Attributes, keyof MotionProps>]?: Attributes[K]; }; /** * @public */ export declare type HTMLMotionProps<TagName extends keyof ReactHTML> = HTMLAttributesWithoutMotionProps<UnwrapFactoryAttributes<ReactHTML[TagName]>, UnwrapFactoryElement<ReactHTML[TagName]>> & MotionProps; /** * An animation that decelerates a value based on its initial velocity, * usually used to implement inertial scrolling. * * Optionally, `min` and `max` boundaries can be defined, and inertia * will snap to these with a spring animation. * * This animation will automatically precalculate a target value, * which can be modified with the `modifyTarget` property. * * This allows you to add snap-to-grid or similar functionality. * * Inertia is also the animation used for `dragTransition`, and can be configured via that prop. * * @public */ export declare interface Inertia { /** * Set `type` to animate using the inertia animation. Set to `"tween"` by * default. This can be used for natural deceleration, like momentum scrolling. * * @library * * ```jsx * const transition = { * type: "inertia", * velocity: 50 * } * * <Frame * animate={{ rotate: 180 }} * transition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * animate={{ rotate: 180 }} * transition={{ type: "inertia", velocity: 50 }} * /> * ``` * * @public */ type: "inertia"; /** * A function that receives the automatically-calculated target and returns a new one. Useful for snapping the target to a grid. * * @library * * ```jsx * const transition = { * power: 0, * // Snap calculated target to nearest 50 pixels * modifyTarget: target => Math.round(target / 50) * 50 * } * * <Frame * drag * dragTransition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ * power: 0, * // Snap calculated target to nearest 50 pixels * modifyTarget: target => Math.round(target / 50) * 50 * }} * /> * ``` * * @public */ modifyTarget?(v: number): number; /** * If `min` or `max` is set, this affects the stiffness of the bounce * spring. Higher values will create more sudden movement. Set to `500` by * default. * * @library * * ```jsx * const transition = { * min: 0, * max: 100, * bounceStiffness: 100 * } * * <Frame * drag * dragTransition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ * min: 0, * max: 100, * bounceStiffness: 100 * }} * /> * ``` * * @public */ bounceStiffness?: number; /** * If `min` or `max` is set, this affects the damping of the bounce spring. * If set to `0`, spring will oscillate indefinitely. Set to `10` by * default. * * @library * * ```jsx * const transition = { * min: 0, * max: 100, * bounceDamping: 8 * } * * <Frame * drag * dragTransition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ * min: 0, * max: 100, * bounceDamping: 8 * }} * /> * ``` * * @public */ bounceDamping?: number; /** * A higher power value equals a further target. Set to `0.8` by default. * * @library * * ```jsx * const transition = { * min: 0, * max: 100, * power: 0.2 * } * * <Frame * drag * dragTransition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ power: 0.2 }} * /> * ``` * * @public */ power?: number; /** * Adjusting the time constant will change the duration of the * deceleration, thereby affecting its feel. Set to `700` by default. * * @library * * ```jsx * const transition = { * min: 0, * max: 100, * timeConstant: 200 * } * * <Frame * drag * dragTransition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ timeConstant: 200 }} * /> * ``` * * @public */ timeConstant?: number; /** * End the animation if the distance to the animation target is below this value, and the absolute speed is below `restSpeed`. * When the animation ends, the value gets snapped to the animation target. Set to `0.01` by default. * Generally the default values provide smooth animation endings, only in rare cases should you need to customize these. * * @library * * ```jsx * const transition = { * min: 0, * max: 100, * restDelta: 10 * } * * <Frame * drag * dragTransition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ restDelta: 10 }} * /> * ``` * * @public */ restDelta?: number; /** * Minimum constraint. If set, the value will "bump" against this value (or immediately spring to it if the animation starts as less than this value). * * @library * * ```jsx * <Frame * drag * dragTransition={{ min: 0, max: 100 }} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ min: 0, max: 100 }} * /> * ``` * * @public */ min?: number; /** * Maximum constraint. If set, the value will "bump" against this value (or immediately snap to it, if the initial animation value exceeds this value). * * @library * * ```jsx * <Frame * drag * dragTransition={{ min: 0, max: 100 }} * /> * ``` * * @motion * * ```jsx * <motion.div * drag * dragTransition={{ min: 0, max: 100 }} * /> * ``` * * @public */ max?: number; /** * The value to animate from. By default, this is the current state of the animating value. * * @library * * ```jsx * const transition = { * min: 0, * max: 100, * from: 50 * } * * <Frame * drag * dragTransition={transition} * /> * ``` * * @motion * * ```jsx * <Frame * drag * dragTransition={{ from: 50 }} * /> * ``` * * @public */ from?: number | string; /** * The initial velocity of the animation. * By default this is the current velocity of the component. * * @library * * ```jsx * const transition = { * type: "inertia", * velocity: 200 * } * * <Frame * animate={{ rotate: 180 }} * transition={transition} * /> * ``` * * @motion * * ```jsx * <motion.div * animate={{ rotate: 180 }} * transition={{ type: 'inertia', velocity: 200 }} * /> * ``` * * @public */ velocity?: number; /** * @internal */ delay?: number; } /** * @public */ declare type InertiaOptions = Partial<Omit<Inertia, "velocity" | "type">>; /** * Check whether a prop name is a valid `MotionProp` key. * * @param key - Name of the property to check * @returns `true` is key is a valid `MotionProp`. * * @public */ export declare function isValidMotionProp(key: string): boolean; /** * @internal */ declare interface Just { type: "just"; to?: number | string | ValueTarget; from?: number | string; delay?: number; velocity?: number; } /** * Keyframes tweens between multiple `values`. * * These tweens can be arranged using the `duration`, `easings`, and `times` properties. * * @internalremarks * We could possibly make the `type` property redundant, if not for all animations * then for this one quite easily. * * @internal */ export declare interface Keyframes { /** * Set `type` to `"keyframes"` to animate using the keyframes animation. * Set to `"tween"` by default. This can be used to animate between a series of values. * * @public */ type: "keyframes"; /** * An array of values to animate between. * * @internal */ values: KeyframesTarget; /** * An array of numbers between 0 and 1, where `1` represents the `total` duration. * * Each value represents at which point during the animation each item in the animation target should be hit, so the array should be the same length as `values`. * * Defaults to an array of evenly-spread durations. * * @public */ times?: number[]; /** * An array of easing functions for each generated tween, or a single easing function applied to all tweens. * * This array should be one item less than `values`, as these easings apply to the transitions *between* the `values`. * * ```jsx * const transition = { * backgroundColor: { * type: 'keyframes', * easings: ['circIn', 'circOut'] * } * } * ``` * * @public */ ease?: Easing | Easing[]; /** * Popmotion's easing prop to define individual easings. `ease` will be mapped to this prop in keyframes animations. * * @internal */ easings?: Easing | Easing[]; /** * @internal */ elapsed?: number; /** * The total duration of the animation. Set to `0.3` by default. * * ```jsx * const transition = { * type: "keyframes", * duration: 2 * } * * <Frame * animate={{ opacity: 0 }} * transition={transition} * /> * ``` * * @public */ duration?: number; /** * The number of times to loop the animation. * * Set to `Infinity` for perpetual looping. * * @public */ loop?: number; /** * The number of times to flip the animation by swapping the `to` and `from` values. * Set to `Infinity` for perpetual flipping. * * ```jsx * const transition = { * flip: Infinity, * duration: 2 * } * * <Frame * animate={{ opacity: 0 }} * transition={transition} * /> * ``` * * @public */ flip?: number; /** * The number of times to reverse the animation. * Set to `Infinity` for perpetual reversing. * * ```jsx * const transition = { * yoyo: Infinity, * duration: 2 * } * * <Frame * animate={{ rotate: 180 }} * transition={transition} * /> * * ``` * @public */ yoyo?: number; /** * @public */ repeatDelay?: number; /** * @internal */ from?: number | string; /** * @internal */ to?: number | string | ValueTarget; /** * @internal */ velocity?: number; /** * @internal */ delay?: number; } /** * @public */ export declare type KeyframesTarget = ResolvedKeyframesTarget | [null, ...CustomValueType[]] | CustomValueType[]; declare type LoadFunctionalityComponents<P = {}> = (ref: RefObject<Element>, values: MotionValuesMap, props: P & MotionProps, controls: ValueAnimationControls<P>, inherit: boolean) => ReactElement<FunctionalProps>[]; declare type MakeCustomValueType<T> = { [K in keyof T]: T[K] | CustomValueType; }; declare type MakeKeyframes<T> = { [K in keyof T]: T[K] | T[K][] | [null, ...T[K][]]; }; declare type MakeMotion<T> = MakeCustomValueType<{ [K in keyof T]: T[K] | MotionValue<number> | MotionValue<string> | MotionValue<any>; }>; declare type MakeTargetAnimatable = (target: TargetWithKeyframes, transitionEnd?: Target | undefined) => { target: TargetWithKeyframes; transitionEnd?: Target | undefined; }; /** * HTML & SVG components, optimised for use with gestures and animation. These can be used as * drop-in replacements for any HTML & SVG component, all CSS & SVG properties are supported. * * @internalremarks * * I'd like to make it possible for these to be loaded "on demand" - to reduce bundle size by only * including HTML/SVG stylers, animation and/or gesture support when necessary. * * ```jsx * <motion.div animate={{ x: 100 }} /> * * <motion.p animate={{ height: 200 }} /> * * <svg><motion.circle r={10} animate={{ r: 20 }} /></svg> * ``` * * @public */ export declare const motion: { symbol: ForwardRefExoticComponent<SVGMotionProps<SVGSymbolElement> & RefAttributes<SVGSymbolElement>>; circle: ForwardRefExoticComponent<SVGMotionProps<SVGCircleElement> & RefAttributes<SVGCircleElement>>; clipPath: ForwardRefExoticComponent<SVGMotionProps<SVGClipPathElement> & RefAttributes<SVGClipPathElement>>; defs: ForwardRefExoticComponent<SVGMotionProps<SVGDefsElement> & RefAttributes<SVGDefsElement>>; desc: ForwardRefExoticComponent<SVGMotionProps<SVGDescElement> & RefAttributes<SVGDescElement>>; ellipse: ForwardRefExoticComponent<SVGMotionProps<SVGEllipseElement> & RefAttributes<SVGEllipseElement>>; feBlend: ForwardRefExoticComponent<SVGMotionProps<SVGFEBlendElement> & RefAttributes<SVGFEBlendElement>>; feColorMatrix: ForwardRefExoticComponent<SVGMotionProps<SVGFEColorMatrixElement> & RefAttributes<SVGFEColorMatrixElement>>; feComponentTransfer: ForwardRefExoticComponent<SVGMotionProps<SVGFEComponentTransferElement> & RefAttributes<SVGFEComponentTransferElement>>; feComposite: ForwardRefExoticComponent<SVGMotionProps<SVGFECompositeElement> & RefAttributes<SVGFECompositeElement>>; feConvolveMatrix: ForwardRefExoticComponent<SVGMotionProps<SVGFEConvolveMatrixElement> & RefAttributes<SVGFEConvolveMatrixElement>>; feDiffuseLighting: ForwardRefExoticComponent<SVGMotionProps<SVGFEDiffuseLightingElement> & RefAttributes<SVGFEDiffuseLightingElement>>; feDisplacementMap: ForwardRefExoticComponent<SVGMotionProps<SVGFEDisplacementMapElement> & RefAttributes<SVGFEDisplacementMapElement>>; feDistantLight: ForwardRefExoticComponent<SVGMotionProps<SVGFEDistantLightElement> & RefAttributes<SVGFEDistantLightElement>>; feFlood: ForwardRefExoticComponent<SVGMotionProps<SVGFEFloodElement> & RefAttributes<SVGFEFloodElement>>; feFuncA: ForwardRefExoticComponent<SVGMotionProps<SVGFEFuncAElement> & RefAttributes<SVGFEFuncAElement>>; feFuncB: ForwardRefExoticComponent<SVGMotionProps<SVGFEFuncBElement> & RefAttributes<SVGFEFuncBElement>>; feFuncG: ForwardRefExoticComponent<SVGMotionProps<SVGFEFuncGElement> & RefAttributes<SVGFEFuncGElement>>; feFuncR: ForwardRefExoticComponent<SVGMotionProps<SVGFEFuncRElement> & RefAttributes<SVGFEF