;
/**
* 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: AnimationDefinition): 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 interface AnimationControlsConfig {
makeTargetAnimatable?: MakeTargetAnimatable;
}
declare type AnimationDefinition = VariantLabels | TargetAndTransition | TargetResolver;
/**
* @public
*/
export declare const AnimationFeature: MotionFeature;
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
*
*
* // As variant
*
*
* // Multiple variants
*
*
* // AnimationControls
*
* ```
*
* @motion
*
* ```jsx
* // As values
*
*
* // As variant
*
*
* // Multiple variants
*
*
* // AnimationControls
*
* ```
*/
animate?: AnimationControls | TargetAndTransition | VariantLabels | boolean;
/**
* 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 (
*
* {props.isVisible && (
*
* )}
*
* )
* }
* ```
*
* @motion
*
* ```jsx
* import { AnimatePresence, motion } from 'framer-motion'
*
* export const MyComponent = ({ isVisible }) => {
* return (
*
* {isVisible && (
*
* )}
*
* )
* }
* ```
*/
exit?: TargetAndTransition | VariantLabels | TargetResolver;
/**
* 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 }
* }
* }
*
*
* ```
*
* @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 }
* }
* }
*
*
* ```
*/
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
* }
*
*
* ```
*
* @motion
*
* ```jsx
* const spring = {
* type: "spring",
* damping: 10,
* stiffness: 100
* }
*
*
* ```
*/
transition?: Transition;
}
declare type AnyPointerEvent = MouseEvent | TouchEvent | PointerEvent;
/**
* A description of a single axis using non-axis specific terms to denote the min and max
* value of any axis.
*
* @public
*/
export declare interface Axis {
min: number;
max: number;
}
/**
* A description of a bounding box describing each axis individually. This allows us
* to treate each axis generically.
*
* @public
*/
export declare interface AxisBox2D {
x: Axis;
y: Axis;
}
/**
* @public
*/
export declare interface AxisBox3D extends AxisBox2D {
z: Axis;
}
/**
* The transform delta that, when applied to Axis a will visually transform it to Axis b
* @public
*/
export declare interface AxisDelta {
translate: number;
scale: number;
origin: number;
originPoint: number;
}
declare type Booleanish = boolean | 'true' | 'false';
/**
* A typically user-facing description of a bounding box using traditional t/l/r/b
*
* @public
*/
export declare interface BoundingBox2D {
top: number;
left: number;
bottom: number;
right: number;
}
/**
* A 3D bounding box
*
* @public
*/
export declare interface BoundingBox3D extends BoundingBox2D {
front: number;
back: number;
}
/**
* The transform delta that, when applied to Box a will visually transform it to Box b.
* @public
*/
export declare interface BoxDelta {
x: AxisDelta;
y: AxisDelta;
}
declare interface ControlsProp {
controls?: VisualElementAnimationControls;
}
/**
* Create a `motion` component.
*
* This function accepts a Component argument, which can be either a string (ie "div"
* for `motion.div`), or an actual React component.
*
* Alongside this is a config option which provides a way of rendering the provided
* component "offline", or outside the React render cycle.
*
* @internal
*/
export declare function createMotionComponent(Component: string | React.ComponentType
, { defaultFeatures, useVisualElement, render, animationControlsConfig, }: MotionComponentConfig): React.ForwardRefExoticComponent & React.RefAttributes>;
declare type CSSPropertiesWithoutTransitionOrSingleTransforms = Omit;
/**
* I'd rather the return type of `custom` to be implicit but this throws
* incorrect relative paths in the exported types and API Extractor throws
* a wobbly.
*/
export declare type CustomDomComponent = React.ForwardRefExoticComponent & React.RefAttributes>;
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, Cycle];
/**
* Configuration for the HTML and SVGVisualElement renderers.
*/
declare interface DOMVisualElementConfig extends VisualElementConfig {
/**
* Whether to permit `transform: none` if the calculated transform equals zero.
*/
allowTransformNone?: boolean;
/**
* Whether to enable hardware acceleration. This will force the layer to the GPU
* by setting `translateZ(0)` to the transform style.
*/
enableHardwareAcceleration?: boolean;
/**
* An optional function that can take a page point and return a new one.
* Used to enable drag and layout animations in the scaled canvases of Framer Desktop preview.
*/
transformPagePoint?: TransformPoint2D;
/**
* A function that can accept the generated transform property and return a new one.
* Used for custom transform property orders. In the medium-term I'd like to ditch this
* and replace with a template function that can scoop up other animated values so
* we can do, for instance:
*
* ```jsx
*
* ```
*/
transformTemplate?: MotionProps["transformTemplate"];
onViewportBoxUpdate?: MotionProps["onViewportBoxUpdate"];
transition?: MotionProps["transition"];
layoutOrder?: number;
}
declare interface DragControlConfig {
visualElement: HTMLVisualElement;
}
declare interface DragControlOptions {
snapToCursor?: boolean;
cursorProgress?: Point2D;
}
/**
* Can manually trigger a drag gesture on one or more `drag`-enabled `motion` components.
*
* @library
*
* ```jsx
* const dragControls = useDragControls()
*
* function startDrag(event) {
* dragControls.start(event, { snapToCursor: true })
* }
*
* return (
* <>
*
*
* >
* )
* ```
*
* @motion
*
* ```jsx
* const dragControls = useDragControls()
*
* function startDrag(event) {
* dragControls.start(event, { snapToCursor: true })
* }
*
* return (
* <>
*
*
* >
* )
* ```
*
* @public
*/
export declare class DragControls {
private componentControls;
/**
* Subscribe a component's internal `VisualElementDragControls` to the user-facing API.
*
* @internal
*/
subscribe(controls: VisualElementDragControls): () => void;
/**
* Start a drag gesture on every `motion` component that has this set of drag controls
* passed into it via the `dragControls` prop.
*
* ```jsx
* dragControls.start(e, {
* snapToCursor: true
* })
* ```
*
* @param event - A mouse/touch/pointer event.
* @param options - Options
*
* @public
*/
start(event: React.MouseEvent | React.TouchEvent | React.PointerEvent | MouseEvent | TouchEvent | PointerEvent, options?: DragControlOptions): void;
}
declare interface DragControlsProps extends DraggableProps {
transformPagePoint?: TransformPoint2D;
}
declare type DragDirection = "x" | "y";
/**
* @public
*/
export declare const DragFeature: MotionFeature;
/**
* @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
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*/
drag?: boolean | "x" | "y";
/**
* If `true`, this will lock dragging to the initially-detected direction. Defaults to `false`.
*
* @library
*
* ```jsx
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*/
dragDirectionLock?: boolean;
/**
* Allows drag gesture propagation to child components. Set to `false` by
* default.
*
* @library
*
* ```jsx
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*/
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
*
*
* // As a ref to another component
* function MyComponent() {
* const constraintsRef = useRef(null)
*
* return (
*
*
*
* )
* }
* ```
*
* @motion
*
* ```jsx
* // In pixels
*
*
* // As a ref to another component
* const MyComponent = () => {
* const constraintsRef = useRef(null)
*
* return (
*
*
*
* )
* }
* ```
*/
dragConstraints?: false | Partial | RefObject;
/**
* The degree of movement allowed outside constraints. 0 = no movement, 1 =
* full movement. Set to `0.5` by default.
*
* @library
*
* ```jsx
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*/
dragElastic?: boolean | number;
/**
* Apply momentum from the pan gesture to the component when dragging
* finishes. Set to `true` by default.
*
* @library
*
* ```jsx
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*/
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
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*/
dragTransition?: InertiaOptions;
/**
* Usually, dragging is initiated by pressing down on a component and moving it. For some
* use-cases, for instance clicking at an arbitrary point on a video scrubber, we
* might want to initiate dragging from a different component than the draggable one.
*
* By creating a `dragControls` using the `useDragControls` hook, we can pass this into
* the draggable component's `dragControls` prop. It exposes a `start` method
* that can start dragging from pointer events on other components.
*
* @library
*
* ```jsx
* const dragControls = useDragControls()
*
* function startDrag(event) {
* dragControls.start(event, { snapToCursor: true })
* }
*
* return (
* <>
*
*
* >
* )
* ```
*
* @motion
*
* ```jsx
* const dragControls = useDragControls()
*
* function startDrag(event) {
* dragControls.start(event, { snapToCursor: true })
* }
*
* return (
* <>
*
*
* >
* )
* ```
*/
dragControls?: DragControls;
/**
* By default, if `drag` is defined on a component then an event listener will be attached
* to automatically initiate dragging when a user presses down on it.
*
* By setting `dragListener` to `false`, this event listener will not be created.
*
* @library
*
* ```jsx
* const dragControls = useDragControls()
*
* function startDrag(event) {
* dragControls.start(event, { snapToCursor: true })
* }
*
* return (
* <>
*
*
* >
* )
* ```
*
* @motion
*
* ```jsx
* const dragControls = useDragControls()
*
* function startDrag(event) {
* dragControls.start(event, { snapToCursor: true })
* }
*
* return (
* <>
*
*
* >
* )
* ```
*/
dragListener?: boolean;
/**
* If `dragConstraints` is set to a React ref, this callback will call with the measured drag constraints.
*
* @public
*/
onMeasureDragConstraints?: (constraints: BoundingBox2D) => BoundingBox2D | void;
}
/**
* @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)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* console.log(info.point.x, info.point.y)
* }
* />
* ```
*
* @public
*/
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)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* console.log(info.point.x, info.point.y)
* }
* />
* ```
*
* @public
*/
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)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* console.log(info.point.x, info.point.y)
* }
* />
* ```
*
* @public
*/
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)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* console.log(axis)}
* />
* ```
*
* @public
*/
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')
* }
*
*
* ```
*
* @motion
*
* ```jsx
* console.log('Drag transition complete')}
* />
* ```
*
* @public
*/
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
* }
*
*
* ```
*
* @motion
*
* ```jsx
* progress * progress
* }}
* />
* ```
*
* @public
*/
export declare type EasingFunction = (v: number) => number;
/** @public */
export declare interface EventInfo {
point: Point;
}
/**
* @public
*/
export declare const ExitFeature: MotionFeature;
/**
* @public
*/
export declare interface FeatureProps extends MotionProps {
visualElement: HTMLVisualElement;
controls: VisualElementAnimationControls;
localContext: MotionContextProps;
parentContext: MotionContextProps;
}
/**
* @public
*/
export declare type ForwardRefComponent = ForwardRefExoticComponent & RefAttributes>;
/**
* @public
*/
export declare type GestureHandlers = PanHandlers & TapHandlers & HoverHandlers;
/**
* @public
*/
export declare const GesturesFeature: MotionFeature;
/**
* @public
*/
export declare interface HoverHandlers {
/**
* Properties or variant label to animate to while the hover gesture is recognised.
*
* @library
*
* ```jsx
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*/
whileHover?: string | TargetAndTransition;
/**
* Callback function that fires when pointer starts hovering over the component.
*
* @library
*
* ```jsx
* function onHoverStart(event) {
* console.log("Hover starts")
* }
*
*
* ```
*
* @motion
*
* ```jsx
* 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")
* }
*
*
* ```
*
* @motion
*
* ```jsx
* console.log("Hover ends")} />
* ```
*/
onHoverEnd?(event: MouseEvent, info: EventInfo): void;
}
declare type HTMLAttributesWithoutMotionProps, Element extends HTMLElement> = {
[K in Exclude]?: Attributes[K];
};
declare type HTMLElements = UnionStringArray;
/**
* @internal
*/
declare const htmlElements: readonly ["a", "abbr", "address", "area", "article", "aside", "audio", "b", "base", "bdi", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "menu", "menuitem", "meta", "meter", "nav", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", "source", "span", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "u", "ul", "var", "video", "wbr", "webview"];
/**
* Motion-optimised versions of React's HTML components.
*
* @public
*/
declare type HTMLMotionComponents = {
[K in HTMLElements]: ForwardRefComponent, HTMLMotionProps>;
};
/**
* @public
*/
export declare type HTMLMotionProps = HTMLAttributesWithoutMotionProps, UnwrapFactoryElement> & MotionProps;
/**
* A VisualElement for HTMLElements
*/
declare class HTMLVisualElement extends VisualElement {
/**
*
*/
protected defaultConfig: DOMVisualElementConfig;
/**
* A mutable record of styles we want to apply directly to the rendered Element
* every frame. We use a mutable data structure to reduce GC during animations.
*/
style: ResolvedValues;
/**
* A record of styles we only want to apply via React. This gets set in useMotionValues
* and applied in the render function. I'd prefer this to live somewhere else to decouple
* VisualElement from React but works for now.
*/
reactStyle: ResolvedValues;
/**
* A mutable record of CSS variables we want to apply directly to the rendered Element
* every frame. We use a mutable data structure to reduce GC during animations.
*/
vars: ResolvedValues;
/**
* Presence data. This is hydrated by useDomVisualElement and used by AnimateSharedLayout
* to decide how to animate entering/exiting layoutId
*/
presence?: Presence;
isPresent?: boolean;
/**
* A mutable record of transforms we want to apply directly to the rendered Element
* every frame. We use a mutable data structure to reduce GC during animations.
*/
protected transform: ResolvedValues;
/**
* A mutable record of transform origins we want to apply directly to the rendered Element
* every frame. We use a mutable data structure to reduce GC during animations.
*/
protected transformOrigin: TransformOrigin;
/**
* A mutable record of transform keys we want to apply to the rendered Element. We order
* this to order transforms in the desired order. We use a mutable data structure to reduce GC during animations.
*/
protected transformKeys: string[];
config: DOMVisualElementConfig;
/**
* When a value is removed, we want to make sure it's removed from all rendered data structures.
*/
removeValue(key: string): void;
/**
* Empty the mutable data structures by re-creating them. We can do this every React render
* as the comparative workload to the rest of the render is very low and this is also when
* we want to reflect values that might have been removed by the render.
*/
clean(): void;
updateConfig(config?: DOMVisualElementConfig): void;
/**
* Read a value directly from the HTMLElement style.
*/
read(key: string): number | string | null;
/**
* Read a value directly from the HTMLElement in case it's not defined by a Motion
* prop. If it's a transform, we just return a pre-defined default value as reading these
* out of a matrix is either error-prone or can incur a big payload for little benefit.
*/
readNativeValue(key: string): any;
/**
* ========================================
* Layout
* ========================================
*/
isLayoutProjectionEnabled: boolean;
enableLayoutProjection(): void;
/**
* A set of layout update event handlers. These are only called once all layouts have been read,
* making it safe to perform DOM write operations.
*/
private layoutUpdateListeners;
/**
* Keep track of whether the viewport box has been updated since the last render.
* If it has, we want to fire the onViewportBoxUpdate listener.
*/
private hasViewportBoxUpdated;
/**
* Optional id. If set, and this is the child of an AnimateSharedLayout component,
* the targetBox can be transerred to a new component with the same ID.
*/
layoutId?: string;
/**
* The measured bounding box as it exists on the page with no transforms applied.
*
* To calculate the visual output of a component in any given frame, we:
*
* 1. box -> boxCorrected
* Apply the delta between the tree transform when the box was measured and
* the tree transform in this frame to the box
* 2. targetBox -> targetBoxFinal
* Apply the VisualElement's `transform` properties to the targetBox
* 3. Calculate the delta between boxCorrected and targetBoxFinal and apply
* it as a transform style.
*/
box: AxisBox2D;
/**
* The `box` layout with transforms applied from up the
* tree. We use this as the final bounding box from which we calculate a transform
* delta to our desired visual position on any given frame.
*
* This is considered mutable to avoid object creation on each frame.
*/
private boxCorrected;
/**
* The visual target we want to project our component into on a given frame
* before applying transforms defined in `animate` or `style`.
*
* This is considered mutable to avoid object creation on each frame.
*/
targetBox: AxisBox2D;
/**
* The visual target we want to project our component into on a given frame
* before applying transforms defined in `animate` or `style`.
*
* This is considered mutable to avoid object creation on each frame.
*/
protected targetBoxFinal: AxisBox2D;
/**
* Can be used to store a snapshot of the measured viewport bounding box before
* a re-render.
*/
prevViewportBox?: AxisBox2D;
/**
* The overall scale of the local coordinate system as transformed by all parents
* of this component. We use this for scale correction on our calculated layouts
* and scale-affected values like `boxShadow`.
*
* This is considered mutable to avoid object creation on each frame.
*/
treeScale: Point2D;
/**
* The delta between the boxCorrected and the desired
* targetBox (before user-set transforms are applied). The calculated output will be
* handed to the renderer and used as part of the style correction calculations, for
* instance calculating how to display the desired border-radius correctly.
*
* This is considered mutable to avoid object creation on each frame.
*/
delta: BoxDelta;
/**
* The delta between the boxCorrected and the desired targetBoxFinal. The calculated
* output will be handed to the renderer and used to project the boxCorrected into
* the targetBoxFinal.
*
* This is considered mutable to avoid object creation on each frame.
*/
deltaFinal: BoxDelta;
/**
* The computed transform string to apply deltaFinal to the element. Currently this is only
* being used to diff and decide whether to render on the current frame, but a minor optmisation
* could be to provide this to the buildHTMLStyle function.
*/
deltaTransform: string;
/**
*
*/
stopLayoutAxisAnimation: {
x: () => void;
y: () => void;
};
isVisible?: boolean;
hide(): void;
show(): void;
/**
* Register an event listener to fire when the layout is updated. We might want to expose support
* for this via a `motion` prop.
*/
onLayoutUpdate(callback: LayoutUpdateHandler): () => boolean;
/**
* To be called when all layouts are successfully updated. In turn we can notify layoutUpdate
* subscribers.
*/
layoutReady(config?: SharedLayoutAnimationConfig): void;
/**
* Measure and return the Element's bounding box. We convert it to a AxisBox2D
* structure to make it easier to work on each individual axis generically.
*/
getBoundingBox(): AxisBox2D;
getBoundingBoxWithoutTransforms(): AxisBox2D;
/**
* Return the computed style after a render.
*/
getComputedStyle(): CSSStyleDeclaration;
/**
*
*/
snapshotBoundingBox(): void;
/**
* The viewport scroll at the time of the previous layout measurement.
*/
viewportScroll: Point2D;
measureLayout(): void;
/**
* Ensure the targetBox reflects the latest visual box on screen
*/
refreshTargetBox(): void;
isTargetBoxLocked: boolean;
lockTargetBox(): void;
unlockTargetBox(): void;
/**
* Reset the transform on the current Element. This is called as part
* of a batched process across the entire layout tree. To remove this write
* cycle it'd be interesting to see if it's possible to "undo" all the current
* layout transforms up the tree in the same way this.getBoundingBoxWithoutTransforms
* works
*/
resetTransform(): void;
/**
* Set new min/max boundaries to project an axis into
*/
setAxisTarget(axis: "x" | "y", min: number, max: number): void;
/**
*
*/
axisProgress: MotionPoint;
/**
*
*/
startLayoutAxisAnimation(axis: "x" | "y", transition: Transition): Promise;
stopLayoutAnimation(): void;
updateLayoutDelta: () => void;
/**
* Update the layout deltas to reflect the relative positions of the layout
* and the desired target box
*/
updateLayoutDeltas(): void;
updateTransformDeltas(): void;
/**
* ========================================
* Build & render
* ========================================
*/
/**
* Build a style prop using the latest resolved MotionValues
*/
build(): void;
/**
* Render the Element by rebuilding and applying the latest styles and vars.
*/
render(): void;
}
/**
* 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
* }
*
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
* }
*
*
* ```
*
* @motion
*
* ```jsx
* 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
* }
*
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
* }
*
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
* }
*
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
* }
*
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
* }
*
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
* }
*
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @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
* }
*
*
* ```
*
* @motion
*
* ```jsx
*
* ```
*
* @public
*/
velocity?: number;
/**
* @internal
*/
delay?: number;
}
/**
* @public
*/
declare type InertiaOptions = Partial>;
/**
* 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
* }
*
*
* ```
*
* @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
* }
*
*
* ```
*
* @public
*/
flip?: number;
/**
* The number of times to reverse the animation.
* Set to `Infinity` for perpetual reversing.
*
* ```jsx
* const transition = {
* yoyo: Infinity,
* duration: 2
* }
*
*
*
* ```
* @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[];
/**
* @public
*/
export declare interface LayoutProps {
/**
* If `true`, this component will automatically animate to its new position when
* its layout changes.
*
* ```jsx
*
* ```
*
* This will perform a layout animation using performant transforms. Part of this technique
* involved animating an element's scale. This can introduce visual distortions on children,
* `boxShadow` and `borderRadius`.
*
* To correct distortion on immediate children, add `layout` to those too.
*
* `boxShadow` and `borderRadius` will automatically be corrected if they are already being
* animated on this component. Otherwise, set them directly via the `initial` prop.
*
* If `layout` is set to `"position"`, the size of the component will change instantly and
* only its position will animate.
*
* @public
*/
layout?: boolean | "position";
/**
* Enable shared layout transitions between components for children of `AnimateSharedLayout`.
*
* When a component with a layoutId is removed from the React tree, and then
* added elsewhere, it will visually animate from the previous component's bounding box
* and its latest animated values.
*
* ```jsx
*
* {items.map(item => (
*
* {item.name}
* {item.isSelected && }
*
* ))}
*
* ```
*
* If the previous component remains in the tree it will either get hidden immediately or,
* if `type="crossfade"` is set on `AnimateSharedLayout`, it will crossfade to the new component.
*
* @public
*/
layoutId?: string;
/**
* A callback that will fire when a layout animation on this component completes.
*
* @public
*/
onLayoutAnimationComplete?(): void;
/**
* A callback that fires whenever the viewport-relative bounding box updates.
*
* @public
*/
onViewportBoxUpdate?(box: AxisBox2D, delta: BoxDelta): void;
}
declare class LayoutStack {
order: HTMLVisualElement[];
lead?: HTMLVisualElement | undefined;
follow?: HTMLVisualElement | undefined;
prevLead?: HTMLVisualElement | undefined;
prevFollow?: HTMLVisualElement | undefined;
snapshot?: Snapshot;
hasChildren: boolean;
add(child: HTMLVisualElement): void;
remove(child: HTMLVisualElement): void;
updateLeadAndFollow(): void;
updateSnapshot(): void;
isLeadPresent(): boolean | undefined;
shouldStackAnimate(): boolean;
getFollowOrigin(): AxisBox2D | undefined;
getFollowTarget(): AxisBox2D | undefined;
getLeadOrigin(): AxisBox2D | undefined;
getLeadTarget(): AxisBox2D | undefined;
getLeadTransition(): Transition | undefined;
}
declare type LayoutUpdateHandler = (layout: AxisBox2D, prev: AxisBox2D, config?: SharedLayoutAnimationConfig) => void;
/**
* @public
*/
export declare const m: HTMLMotionComponents & SVGMotionComponents & {
custom: (Component: string | React.ComponentClass | React.FunctionComponent) => CustomDomComponent;
};
declare type MakeCustomValueType = {
[K in keyof T]: T[K] | CustomValueType;
};
declare type MakeKeyframes = {
[K in keyof T]: T[K] | T[K][] | [null, ...T[K][]];
};
declare type MakeMotion = MakeCustomValueType<{
[K in keyof T]: T[K] | MotionValue | MotionValue | MotionValue;
}>;
declare type MakeTargetAnimatable = (visualElement: VisualElement, target: TargetWithKeyframes, origin?: Target, transitionEnd?: Target) => {
target: TargetWithKeyframes;
origin?: Target;
transitionEnd?: Target;
};
/**
* 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.
*
* @public
*/
export declare const motion: HTMLMotionComponents & SVGMotionComponents & {
custom: (Component: string | React.ComponentClass | React.FunctionComponent) => CustomDomComponent;
};
/**
* @public
*/
export declare interface MotionAdvancedProps {
/**
* Custom data to use to resolve dynamic variants differently for each animating component.
*
* @library
*
* ```jsx
* const variants = {
* visible: (custom) => ({
* opacity: 1,
* transition: { delay: custom * 0.2 }
* })
* }
*
*
*
*
* ```
*
* @motion
*
* ```jsx
* const variants = {
* visible: (custom) => ({
* opacity: 1,
* transition: { delay: custom * 0.2 }
* })
* }
*
*
*
*
* ```
*
* @public
*/
custom?: any;
/**
* @public
* Set to `false` to prevent inheriting variant changes from its parent.
*/
inherit?: boolean;
/**
* @internal
* Set to `true` to block rendering motion values (`animate`, gestures, etcetera)
* on the component. This can be used to temporarily disable animations for performance reasons.
*/
static?: boolean;
}
/**
* @public
*/
export declare interface MotionCallbacks {
/**
* Callback with latest motion values, fired max once per frame.
*
* @library
*
* ```jsx
* function onUpdate(latest) {
* console.log(latest.x, latest.opacity)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onUpdate(latest) {
* console.log(latest.x, latest.opacity)
* }
*
*
* ```
*/
onUpdate?(latest: {
[key: string]: string | number;
}): void;
/**
* Callback when animation defined in `animate` begins.
*
* @library
*
* ```jsx
* function onStart() {
* console.log("Animation completed")
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onStart() {
* console.log("Animation completed")
* }
*
*
* ```
*/
onAnimationStart?(): void;
/**
* Callback when animation defined in `animate` is complete.
*
* @library
*
* ```jsx
* function onComplete() {
* console.log("Animation completed")
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onComplete() {
* console.log("Animation completed")
* }
*
*
* ```
*/
onAnimationComplete?(): void;
}
declare interface MotionComponentConfig {
defaultFeatures: MotionFeature[];
useVisualElement: UseVisualElement;
render: RenderComponent;
animationControlsConfig: AnimationControlsConfig;
}
/**
* MotionConfig can be used in combination with the `m` component to cut bundle size
* and dynamically load only the features you use.
*
* ```jsx
* import {
* m as motion,
* AnimationFeature,
* MotionConfig
* } from "framer-motion"
*
* export function App() {
* return (
*
*
*
* )
* }
* ```
*
* @public
*/
export declare function MotionConfig({ children, features, ...props }: MotionConfigProps): JSX.Element;
/**
* @public
*/
export declare interface MotionConfigContext {
/**
* @internal
*/
transformPagePoint: TransformPoint2D;
/**
* An array of features to provide to children.
*
* @public
*/
features: MotionFeature[];
}
/**
* @public
*/
export declare const MotionConfigContext: React.Context;
declare interface MotionConfigProps extends Partial {
children?: React.ReactNode;
}
/**
* @internal
*/
export declare const MotionContext: React.Context;
declare interface MotionContextProps {
visualElement?: VisualElement;
controls?: VisualElementAnimationControls;
initial?: false | VariantLabels;
animate?: VariantLabels;
static?: boolean;
hasMounted?: RefObject;
presenceId?: number;
isReducedMotion?: boolean | undefined;
}
declare type MotionCSS = MakeMotion>;
/**
* @public
*/
export declare interface MotionFeature {
key: string;
shouldRender: (props: MotionProps, parentContext: MotionContextProps) => boolean;
getComponent: (props: MotionProps) => React.ComponentType | undefined;
}
declare interface MotionPoint {
x: MotionValue;
y: MotionValue;
}
/**
* Props for `motion` components.
*
* @public
*/
export declare interface MotionProps extends AnimationProps, MotionCallbacks, GestureHandlers, DraggableProps, LayoutProps, MotionAdvancedProps {
/**
* Properties, variant label or array of variant labels to start in.
*
* Set to `false` to initialise with the values in `animate` (disabling the mount animation)
*
* @library
*
* ```jsx
* // As values
*
*
* // As variant
*
*
* // Multiple variants
*
*
* // As false (disable mount animation)
*
* ```
*
* @motion
*
* ```jsx
* // As values
*
*
* // As variant
*
*
* // Multiple variants
*
*
* // As false (disable mount animation)
*
* ```
*/
initial?: boolean | Target | VariantLabels;
/**
* @library
*
* The React DOM `style` prop, useful for setting CSS properties that aren't explicitly exposed by `Frame` props.
*
* ```jsx
*
* ```
*
* @motion
*
* The React DOM `style` prop, enhanced with support for `MotionValue`s and separate `transform` values.
*
* ```jsx
* export const MyComponent = () => {
* const x = useMotionValue(0)
*
* return
* }
* ```
*/
style?: MotionStyle;
/**
* By default, Framer Motion generates a `transform` property with a sensible transform order. `transformTemplate`
* can be used to create a different order, or to append/preprend the automatically generated `transform` property.
*
* @library
*
* ```jsx
* function transformTemplate({ x, rotate }) {
* return `rotate(${rotate}deg) translateX(${x}px)`
* }
*
*
* ```
*
* @motion
*
* ```jsx
* `rotate(${rotate}deg) translateX(${x}px)`
* }
* />
* ```
*
* @param transform - The latest animated transform props.
* @param generatedTransform - The transform string as automatically generated by Framer Motion
*
* @public
*/
transformTemplate?(transform: TransformProperties, generatedTransform: string): string;
/**
* This allows values to be transformed before being animated or set as styles.
*
* For instance, this allows custom values in Framer Library like `size` to be converted into `width` and `height`.
* It also allows us a chance to take a value like `Color` and convert it to an animatable color string.
*
* A few structural typing changes need making before this can be a public property:
* - Allow `Target` values to be appended by user-defined types (delete `CustomStyles` - does `size` throw a type error?)
* - Extract `CustomValueType` as a separate user-defined type (delete `CustomValueType` and animate a `Color` - does this throw a type error?).
*
* @param values -
*
* @internal
*/
transformValues?(values: V): V;
}
/**
* @public
*/
export declare type MotionStyle = MotionCSS & MotionTransform & MakeMotion & MakeCustomValueType;
/**
* @public
*/
export declare type MotionTransform = MakeMotion;
/**
* `MotionValue` is used to track the state and velocity of motion values.
*
* @public
*/
export declare class MotionValue {
/**
* The current state of the `MotionValue`.
*
* @internal
*/
private current;
/**
* The previous state of the `MotionValue`.
*
* @internal
*/
private prev;
/**
* Duration, in milliseconds, since last updating frame.
*
* @internal
*/
private timeDelta;
/**
* Timestamp of the last time this `MotionValue` was updated.
*
* @internal
*/
private lastUpdated;
/**
* Functions to notify when the `MotionValue` updates.
*
* @internal
*/
updateSubscribers?: Set>;
/**
* Functions to notify when the `MotionValue` updates and `render` is set to `true`.
*
* @internal
*/
private renderSubscribers?;
/**
* Add a passive effect to this `MotionValue`.
*
* A passive effect intercepts calls to `set`. For instance, `useSpring` adds
* a passive effect that attaches a `spring` to the latest
* set value. Hypothetically there could be a `useSmooth` that attaches an input smoothing effect.
*
* @internal
*/
private passiveEffect?;
/**
* A reference to the currently-controlling Popmotion animation
*
* @internal
*/
private stopAnimation?;
/**
* Tracks whether this value can output a velocity. Currently this is only true
* if the value is numerical, but we might be able to widen the scope here and support
* other value types.
*
* @internal
*/
private canTrackVelocity;
/**
* @param init - The initiating value
* @param config - Optional configuration options
*
* - `transformer`: A function to transform incoming values with.
*
* @internal
*/
constructor(init: V);
/**
* Subscribes a subscriber function to a subscription list.
*
* @param subscriptions - A `Set` of subscribers.
* @param subscription - A subscriber function.
*/
private subscribeTo;
/**
* Adds a function that will be notified when the `MotionValue` is updated.
*
* It returns a function that, when called, will cancel the subscription.
*
* When calling `onChange` inside a React component, it should be wrapped with the
* `useEffect` hook. As it returns an unsubscribe function, this should be returned
* from the `useEffect` function to ensure you don't add duplicate subscribers..
*
* @library
*
* ```jsx
* function MyComponent() {
* const x = useMotionValue(0)
* const y = useMotionValue(0)
* const opacity = useMotionValue(1)
*
* useEffect(() => {
* function updateOpacity() {
* const maxXY = Math.max(x.get(), y.get())
* const newOpacity = transform(maxXY, [0, 100], [1, 0])
* opacity.set(newOpacity)
* }
*
* const unsubscribeX = x.onChange(updateOpacity)
* const unsubscribeY = y.onChange(updateOpacity)
*
* return () => {
* unsubscribeX()
* unsubscribeY()
* }
* }, [])
*
* return
* }
* ```
*
* @motion
*
* ```jsx
* export const MyComponent = () => {
* const x = useMotionValue(0)
* const y = useMotionValue(0)
* const opacity = useMotionValue(1)
*
* useEffect(() => {
* function updateOpacity() {
* const maxXY = Math.max(x.get(), y.get())
* const newOpacity = transform(maxXY, [0, 100], [1, 0])
* opacity.set(newOpacity)
* }
*
* const unsubscribeX = x.onChange(updateOpacity)
* const unsubscribeY = y.onChange(updateOpacity)
*
* return () => {
* unsubscribeX()
* unsubscribeY()
* }
* }, [])
*
* return
* }
* ```
*
* @internalremarks
*
* We could look into a `useOnChange` hook if the above lifecycle management proves confusing.
*
* ```jsx
* useOnChange(x, () => {})
* ```
*
* @param subscriber - A function that receives the latest value.
* @returns A function that, when called, will cancel this subscription.
*
* @public
*/
onChange(subscription: Subscriber): () => void;
clearListeners(): void;
/**
* Adds a function that will be notified when the `MotionValue` requests a render.
*
* @param subscriber - A function that's provided the latest value.
* @returns A function that, when called, will cancel this subscription.
*
* @internal
*/
onRenderRequest(subscription: Subscriber): () => boolean;
/**
* Attaches a passive effect to the `MotionValue`.
*
* @internal
*/
attach(passiveEffect: PassiveEffect): void;
/**
* Sets the state of the `MotionValue`.
*
* @remarks
*
* ```jsx
* const x = useMotionValue(0)
* x.set(10)
* ```
*
* @param latest - Latest value to set.
* @param render - Whether to notify render subscribers. Defaults to `true`
*
* @public
*/
set(v: V, render?: boolean): void;
updateAndNotify: (v: V, render?: boolean) => void;
/**
* Returns the latest state of `MotionValue`
*
* @returns - The latest state of `MotionValue`
*
* @public
*/
get(): V;
/**
* @public
*/
getPrevious(): V;
/**
* Returns the latest velocity of `MotionValue`
*
* @returns - The latest velocity of `MotionValue`. Returns `0` if the state is non-numerical.
*
* @public
*/
getVelocity(): number;
/**
* Notify a subscriber with the latest value.
*
* This is an instanced and bound function to prevent generating a new
* function once per frame.
*
* @param subscriber - The subscriber to notify.
*
* @internal
*/
private notifySubscriber;
/**
* Schedule a velocity check for the next frame.
*
* This is an instanced and bound function to prevent generating a new
* function once per frame.
*
* @internal
*/
private scheduleVelocityCheck;
/**
* Updates `prev` with `current` if the value hasn't been updated this frame.
* This ensures velocity calculations return `0`.
*
* This is an instanced and bound function to prevent generating a new
* function once per frame.
*
* @internal
*/
private velocityCheck;
/**
* Registers a new animation to control this `MotionValue`. Only one
* animation can drive a `MotionValue` at one time.
*
* ```jsx
* value.start()
* ```
*
* @param animation - A function that starts the provided animation
*
* @internal
*/
start(animation: StartAnimation): Promise;
/**
* Stop the currently active animation.
*
* @public
*/
stop(): void;
/**
* Returns `true` if this value is currently animating.
*
* @public
*/
isAnimating(): boolean;
private clearAnimation;
/**
* Destroy and clean up subscribers to this `MotionValue`.
*
* The `MotionValue` hooks like `useMotionValue` and `useTransform` automatically
* handle the lifecycle of the returned `MotionValue`, so this method is only necessary if you've manually
* created a `MotionValue` via the `motionValue` function.
*
* @public
*/
destroy(): void;
}
/**
* @internal
*/
export declare function motionValue(init: V): MotionValue;
declare type NativeAnimationEvent = AnimationEvent;
declare type NativeClipboardEvent = ClipboardEvent;
declare type NativeCompositionEvent = CompositionEvent;
declare type NativeDragEvent = DragEvent;
declare type NativeFocusEvent = FocusEvent;
declare type NativeKeyboardEvent = KeyboardEvent;
declare type NativeMouseEvent = MouseEvent;
declare type NativePointerEvent = PointerEvent;
declare type NativeTouchEvent = TouchEvent;
declare type NativeTransitionEvent = TransitionEvent;
declare type NativeUIEvent = UIEvent;
declare type NativeWheelEvent = WheelEvent;
/**
* @public
*/
export declare interface None {
/**
* Set `type` to `false` for an instant transition.
*
* @public
*/
type: false;
/**
* @internal
*/
from?: number | string;
/**
* @internal
*/
delay?: number;
/**
* @internal
*/
velocity?: number;
}
declare type NotPresent = [false, SafeToRemove];
declare type Omit = Pick>;
/**
* Options for orchestrating the timing of animations.
*
* @public
*/
export declare interface Orchestration {
/**
* Delay the animation by this duration (in seconds). Defaults to `0`.
*
* @remarks
* ```javascript
* const transition = {
* delay: 0.2
* }
* ```
*
* @public
*/
delay?: number;
/**
* Describes the relationship between the transition and its children. Set
* to `false` by default.
*
* @remarks
* When using variants, the transition can be scheduled in relation to its
* children with either `"beforeChildren"` to finish this transition before
* starting children transitions, `"afterChildren"` to finish children
* transitions before starting this transition.
*
* @library
*
* ```jsx
* const container = {
* hidden: {
* opacity: 0,
* transition: { when: "afterChildren" }
* }
* }
*
* const item = {
* hidden: {
* opacity: 0,
* transition: { duration: 2 }
* }
* }
*
* return (
*
*
*
*
* )
* ```
*
* @motion
*
* ```jsx
* const list = {
* hidden: {
* opacity: 0,
* transition: { when: "afterChildren" }
* }
* }
*
* const item = {
* hidden: {
* opacity: 0,
* transition: { duration: 2 }
* }
* }
*
* return (
*
*
*
*
* )
* ```
*
* @public
*/
when?: false | "beforeChildren" | "afterChildren" | string;
/**
* When using variants, children animations will start after this duration
* (in seconds). You can add the `transition` property to both the `Frame` and the `variant` directly. Adding it to the `variant` generally offers more flexibility, as it allows you to customize the delay per visual state.
*
* @library
*
* ```jsx
* const container = {
* hidden: { opacity: 0 },
* show: {
* opacity: 1,
* transition: {
* delayChildren: 0.5
* }
* }
* }
*
* const item = {
* hidden: { opacity: 0 },
* show: { opacity: 1 }
* }
*
* return (
*
*
*
*
* )
* ```
*
* @motion
*
* ```jsx
* const container = {
* hidden: { opacity: 0 },
* show: {
* opacity: 1,
* transition: {
* delayChildren: 0.5
* }
* }
* }
*
* const item = {
* hidden: { opacity: 0 },
* show: { opacity: 1 }
* }
*
* return (
*
*
*
*
* )
* ```
*
* @public
*/
delayChildren?: number;
/**
* When using variants, animations of child components can be staggered by this
* duration (in seconds).
*
* For instance, if `staggerChildren` is `0.01`, the first child will be
* delayed by `0` seconds, the second by `0.01`, the third by `0.02` and so
* on.
*
* The calculated stagger delay will be added to `delayChildren`.
*
* @library
*
* ```jsx
* const container = {
* hidden: { opacity: 0 },
* show: {
* opacity: 1,
* transition: {
* staggerChildren: 0.5
* }
* }
* }
*
* const item = {
* hidden: { opacity: 0 },
* show: { opacity: 1 }
* }
*
* return (
*
*
*
*
* )
* ```
*
* @motion
*
* ```jsx
* const container = {
* hidden: { opacity: 0 },
* show: {
* opacity: 1,
* transition: {
* staggerChildren: 0.5
* }
* }
* }
*
* const item = {
* hidden: { opacity: 0 },
* show: { opacity: 1 }
* }
*
* return (
*
*
*
*
* )
* ```
*
* @public
*/
staggerChildren?: number;
/**
* The direction in which to stagger children.
*
* A value of `1` staggers from the first to the last while `-1`
* staggers from the last to the first.
*
* @library
*
* ```jsx
* const container = {
* hidden: { opacity: 0 },
* show: {
* opacity: 1,
* transition: {
* delayChildren: 0.5,
* staggerDirection: -1
* }
* }
* }
*
* const item = {
* hidden: { opacity: 0 },
* show: { opacity: 1 }
* }
*
* return (
*
*
*
*
* )
* ```
*
* @motion
*
* ```jsx
* const container = {
* hidden: { opacity: 0 },
* show: {
* opacity: 1,
* transition: {
* delayChildren: 0.5,
* staggerDirection: -1
* }
* }
* }
*
* const item = {
* hidden: { opacity: 0 },
* show: { opacity: 1 }
* }
*
* return (
*
*
*
*
* )
* ```
*
* @public
*/
staggerDirection?: number;
}
/**
* @public
*/
export declare interface PanHandlers {
/**
* Callback function that fires when the pan gesture is recognised on this element.
*
* @library
*
* ```jsx
* function onPan(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onPan(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @param event - The originating pointer event.
* @param info - A {@link PanInfo} object containing `x` and `y` values for:
*
* - `point`: Relative to the device or page.
* - `delta`: Distance moved since the last event.
* - `offset`: Offset from the original pan event.
* - `velocity`: Current velocity of the pointer.
*/
onPan?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void;
/**
* Callback function that fires when the pan gesture begins on this element.
*
* @library
*
* ```jsx
* function onPanStart(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onPanStart(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @param event - The originating pointer event.
* @param info - A {@link PanInfo} object containing `x`/`y` values for:
*
* - `point`: Relative to the device or page.
* - `delta`: Distance moved since the last event.
* - `offset`: Offset from the original pan event.
* - `velocity`: Current velocity of the pointer.
*/
onPanStart?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void;
/**
* Callback function that fires when we begin detecting a pan gesture. This
* is analogous to `onMouseStart` or `onTouchStart`.
*
* @library
*
* ```jsx
* function onPanSessionStart(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onPanSessionStart(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @param event - The originating pointer event.
* @param info - An {@link EventInfo} object containing `x`/`y` values for:
*
* - `point`: Relative to the device or page.
*/
onPanSessionStart?(event: MouseEvent | TouchEvent | PointerEvent, info: EventInfo): void;
/**
* Callback function that fires when the pan gesture ends on this element.
*
* @library
*
* ```jsx
* function onPanEnd(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onPanEnd(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @param event - The originating pointer event.
* @param info - A {@link PanInfo} object containing `x`/`y` values for:
*
* - `point`: Relative to the device or page.
* - `delta`: Distance moved since the last event.
* - `offset`: Offset from the original pan event.
* - `velocity`: Current velocity of the pointer.
*/
onPanEnd?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void;
}
/**
* Passed in to pan event handlers like `onPan` the `PanInfo` object contains
* information about the current state of the tap gesture such as its
* `point`, `delta`, `offset` and `velocity`.
*
* @library
*
* ```jsx
* function onPan(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* {
* console.log(info.point.x, info.point.y)
* }} />
* ```
*
* @public
*/
export declare interface PanInfo {
/**
* Contains `x` and `y` values for the current pan position relative
* to the device or page.
*
* @library
*
* ```jsx
* function onPan(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onPan(event, info) {
* console.log(info.point.x, info.point.y)
* }
*
*
* ```
*
* @public
*/
point: Point;
/**
* Contains `x` and `y` values for the distance moved since
* the last event.
*
* @library
*
* ```jsx
* function onPan(event, info) {
* console.log(info.delta.x, info.delta.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onPan(event, info) {
* console.log(info.delta.x, info.delta.y)
* }
*
*
* ```
*
* @public
*/
delta: Point;
/**
* Contains `x` and `y` values for the distance moved from
* the first pan event.
*
* @library
*
* ```jsx
* function onPan(event, info) {
* console.log(info.offset.x, info.offset.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onPan(event, info) {
* console.log(info.offset.x, info.offset.y)
* }
*
*
* ```
*
* @public
*/
offset: Point;
/**
* Contains `x` and `y` values for the current velocity of the pointer.
*
* @library
*
* ```jsx
* function onPan(event, info) {
* console.log(info.velocity.x, info.velocity.y)
* }
*
*
* ```
*
* @motion
*
* ```jsx
* function onPan(event, info) {
* console.log(info.velocity.x, info.velocity.y)
* }
*
*
* ```
*
* @public
*/
velocity: Point;
}
/**
* @public
*/
export declare type PassiveEffect = (v: T, safeSetter: (v: T) => void) => void;
declare type PermissiveTransitionDefinition = {
[key: string]: any;
};
/** @public */
declare interface Point {
x: number;
y: number;
}
/** @public */
declare namespace Point {
/** @beta */
const subtract: (a: Point, b: Point) => Point;
/** @beta */
const relativeTo: (idOrElem: string | HTMLElement) => ({ x, y }: Point) => Point | undefined;
}
/**
* A description of a two-dimensional point
*
* @public
*/
export declare interface Point2D {
x: number;
y: number;
}
/**
* A description of a three-dimensional point
*
* @public
*/
export declare interface Point3D extends Point2D {
z: number;
}
declare enum Presence {
Entering = 0,
Present = 1,
Exiting = 2
}
/**
* @public
*/
export declare const PresenceContext: import("react").Context;
/**
* @public
*/
declare interface PresenceContextProps {
id: number;
isPresent: boolean;
register: (id: number) => () => void;
onExitComplete?: (id: number) => void;
initial?: false | VariantLabels;
custom?: any;
}
declare type Present = [true];
declare interface Props {
children?: any;
/**
* Can be used to explicitly set whether we're in reduced motion mode. Set
* as undefined to resume device detection.
*/
enabled?: boolean | undefined;
}
declare namespace React_2 {
//
// React Elements
// ----------------------------------------------------------------------
type ElementType =
{
[K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] ? K : never
}[keyof JSX.IntrinsicElements] |
ComponentType
;
/**
* @deprecated Please use `ElementType`
*/
type ReactType
= ElementType
;
type ComponentType
= ComponentClass
| FunctionComponent
;
type JSXElementConstructor
=
| ((props: P) => ReactElement | null)
| (new (props: P) => Component
);
interface RefObject {
readonly current: T | null;
}
type RefCallback = { bivarianceHack(instance: T | null): void }["bivarianceHack"];
type Ref = RefCallback | RefObject | null;
type LegacyRef = string | Ref;
/**
* Gets the instance type for a React element. The instance will be different for various component types:
*
* - React class components will be the class instance. So if you had `class Foo extends React.Component<{}> {}`
* and used `React.ElementRef` then the type would be the instance of `Foo`.
* - React stateless functional components do not have a backing instance and so `React.ElementRef`
* (when `Bar` is `function Bar() {}`) will give you the `undefined` type.
* - JSX intrinsics like `div` will give you their DOM instance. For `React.ElementRef<'div'>` that would be
* `HTMLDivElement`. For `React.ElementRef<'input'>` that would be `HTMLInputElement`.
* - React stateless functional components that forward a `ref` will give you the `ElementRef` of the forwarded
* to component.
*
* `C` must be the type _of_ a React component so you need to use typeof as in React.ElementRef.
*
* @todo In Flow, this works a little different with forwarded refs and the `AbstractComponent` that
* `React.forwardRef()` returns.
*/
type ElementRef<
C extends
| ForwardRefExoticComponent
| { new (props: any): Component }
| ((props: any, context?: any) => ReactElement | null)
| keyof JSX.IntrinsicElements
> =
// need to check first if `ref` is a valid prop for ts@3.0
// otherwise it will infer `{}` instead of `never`
"ref" extends keyof ComponentPropsWithRef
? NonNullable["ref"]> extends Ref<
infer Instance
>
? Instance
: never
: never;
type ComponentState = any;
type Key = string | number;
/**
* @internal You shouldn't need to use this type since you never see these attributes
* inside your component or have to validate them.
*/
interface Attributes {
key?: Key;
}
interface RefAttributes extends Attributes {
ref?: Ref;
}
interface ClassAttributes extends Attributes {
ref?: LegacyRef;
}
interface ReactElement = string | JSXElementConstructor> {
type: T;
props: P;
key: Key | null;
}
interface ReactComponentElement<
T extends keyof JSX.IntrinsicElements | JSXElementConstructor,
P = Pick, Exclude, 'key' | 'ref'>>
> extends ReactElement> { }
/**
* @deprecated Please use `FunctionComponentElement`
*/
type SFCElement
= FunctionComponentElement
;
interface FunctionComponentElement
extends ReactElement
> {
ref?: 'ref' extends keyof P ? P extends { ref?: infer R } ? R : never : never;
}
type CElement
> = ComponentElement
;
interface ComponentElement
> extends ReactElement
> {
ref?: LegacyRef;
}
type ClassicElement = CElement
>;
// string fallback for custom web-components
interface DOMElement
| SVGAttributes, T extends Element> extends ReactElement {
ref: LegacyRef;
}
// ReactHTML for ReactHTMLElement
// tslint:disable-next-line:no-empty-interface
interface ReactHTMLElement extends DetailedReactHTMLElement, T> { }
interface DetailedReactHTMLElement, T extends HTMLElement> extends DOMElement
{
type: keyof ReactHTML;
}
// ReactSVG for ReactSVGElement
interface ReactSVGElement extends DOMElement, SVGElement> {
type: keyof ReactSVG;
}
interface ReactPortal extends ReactElement {
key: Key | null;
children: ReactNode;
}
//
// Factories
// ----------------------------------------------------------------------
type Factory = (props?: Attributes & P, ...children: ReactNode[]) => ReactElement
;
/**
* @deprecated Please use `FunctionComponentFactory`
*/
type SFCFactory
= FunctionComponentFactory
;
type FunctionComponentFactory
= (props?: Attributes & P, ...children: ReactNode[]) => FunctionComponentElement
;
type ComponentFactory
> =
(props?: ClassAttributes & P, ...children: ReactNode[]) => CElement;
type CFactory
> = ComponentFactory
;
type ClassicFactory
= CFactory
>;
type DOMFactory
, T extends Element> =
(props?: ClassAttributes & P | null, ...children: ReactNode[]) => DOMElement;
// tslint:disable-next-line:no-empty-interface
interface HTMLFactory extends DetailedHTMLFactory, T> {}
interface DetailedHTMLFactory, T extends HTMLElement> extends DOMFactory
{
(props?: ClassAttributes & P | null, ...children: ReactNode[]): DetailedReactHTMLElement;
}
interface SVGFactory extends DOMFactory, SVGElement> {
(props?: ClassAttributes & SVGAttributes | null, ...children: ReactNode[]): ReactSVGElement;
}
//
// React Nodes
// http://facebook.github.io/react/docs/glossary.html
// ----------------------------------------------------------------------
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
interface ReactNodeArray extends Array {}
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
//
// Top Level API
// ----------------------------------------------------------------------
// DOM Elements
function createFactory(
type: keyof ReactHTML): HTMLFactory;
function createFactory(
type: keyof ReactSVG): SVGFactory;
function createFactory, T extends Element>(
type: string): DOMFactory
;
// Custom components
function createFactory
(type: FunctionComponent
): FunctionComponentFactory
;
function createFactory
(
type: ClassType
, ClassicComponentClass
>): CFactory
>;
function createFactory
, C extends ComponentClass
>(
type: ClassType
): CFactory
;
function createFactory
(type: ComponentClass
): Factory
;
// DOM Elements
// TODO: generalize this to everything in `keyof ReactHTML`, not just "input"
function createElement(
type: "input",
props?: InputHTMLAttributes & ClassAttributes | null,
...children: ReactNode[]): DetailedReactHTMLElement, HTMLInputElement>;
function createElement, T extends HTMLElement>(
type: keyof ReactHTML,
props?: ClassAttributes & P | null,
...children: ReactNode[]): DetailedReactHTMLElement;
function createElement
, T extends SVGElement>(
type: keyof ReactSVG,
props?: ClassAttributes & P | null,
...children: ReactNode[]): ReactSVGElement;
function createElement, T extends Element>(
type: string,
props?: ClassAttributes & P | null,
...children: ReactNode[]): DOMElement;
// Custom components
function createElement
(
type: FunctionComponent
,
props?: Attributes & P | null,
...children: ReactNode[]): FunctionComponentElement
;
function createElement
(
type: ClassType
, ClassicComponentClass
>,
props?: ClassAttributes> & P | null,
...children: ReactNode[]): CElement>;
function createElement
, C extends ComponentClass
>(
type: ClassType
,
props?: ClassAttributes & P | null,
...children: ReactNode[]): CElement;
function createElement
(
type: FunctionComponent
| ComponentClass
| string,
props?: Attributes & P | null,
...children: ReactNode[]): ReactElement
;
// DOM Elements
// ReactHTMLElement
function cloneElement
, T extends HTMLElement>(
element: DetailedReactHTMLElement
,
props?: P,
...children: ReactNode[]): DetailedReactHTMLElement
;
// ReactHTMLElement, less specific
function cloneElement
, T extends HTMLElement>(
element: ReactHTMLElement,
props?: P,
...children: ReactNode[]): ReactHTMLElement;
// SVGElement
function cloneElement, T extends SVGElement>(
element: ReactSVGElement,
props?: P,
...children: ReactNode[]): ReactSVGElement;
// DOM Element (has to be the last, because type checking stops at first overload that fits)
function cloneElement
, T extends Element>(
element: DOMElement
,
props?: DOMAttributes & P,
...children: ReactNode[]): DOMElement;
// Custom components
function cloneElement
(
element: FunctionComponentElement
,
props?: Partial
& Attributes,
...children: ReactNode[]): FunctionComponentElement
;
function cloneElement
>(
element: CElement
,
props?: Partial
& ClassAttributes,
...children: ReactNode[]): CElement;
function cloneElement
(
element: ReactElement
,
props?: Partial
& Attributes,
...children: ReactNode[]): ReactElement
;
// Context via RenderProps
interface ProviderProps {
value: T;
children?: ReactNode;
}
interface ConsumerProps {
children: (value: T) => ReactNode;
}
// TODO: similar to how Fragment is actually a symbol, the values returned from createContext,
// forwardRef and memo are actually objects that are treated specially by the renderer; see:
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/ReactContext.js#L35-L48
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/forwardRef.js#L42-L45
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/memo.js#L27-L31
// However, we have no way of telling the JSX parser that it's a JSX element type or its props other than
// by pretending to be a normal component.
//
// We don't just use ComponentType or SFC types because you are not supposed to attach statics to this
// object, but rather to the original function.
interface ExoticComponent {
/**
* **NOTE**: Exotic components are not callable.
*/
(props: P): (ReactElement|null);
readonly $$typeof: symbol;
}
interface NamedExoticComponent
extends ExoticComponent
{
displayName?: string;
}
interface ProviderExoticComponent
extends ExoticComponent
{
propTypes?: WeakValidationMap
;
}
type ContextType> = C extends Context ? T : never;
// NOTE: only the Context object itself can get a displayName
// https://github.com/facebook/react-devtools/blob/e0b854e4c/backend/attachRendererFiber.js#L310-L325
type Provider = ProviderExoticComponent>;
type Consumer = ExoticComponent>;
interface Context {
Provider: Provider;
Consumer: Consumer;
displayName?: string;
}
function createContext(
// If you thought this should be optional, see
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/24509#issuecomment-382213106
defaultValue: T,
): Context;
function isValidElement(object: {} | null | undefined): object is ReactElement
;
const Children: ReactChildren;
const Fragment: ExoticComponent<{ children?: ReactNode }>;
const StrictMode: ExoticComponent<{ children?: ReactNode }>;
interface SuspenseProps {
children?: ReactNode;
/** A fallback react tree to show when a Suspense child (like React.lazy) suspends */
fallback: NonNullable|null;
}
/**
* This feature is not yet available for server-side rendering.
* Suspense support will be added in a later release.
*/
const Suspense: ExoticComponent;
const version: string;
/**
* {@link https://github.com/bvaughn/rfcs/blob/profiler/text/0000-profiler.md#detailed-design | API}
*/
type ProfilerOnRenderCallback = (
id: string,
phase: "mount" | "update",
actualDuration: number,
baseDuration: number,
startTime: number,
commitTime: number,
interactions: Set,
) => void;
interface ProfilerProps {
children?: ReactNode;
id: string;
onRender: ProfilerOnRenderCallback;
}
const Profiler: ExoticComponent;
//
// Component API
// ----------------------------------------------------------------------
type ReactInstance = Component | Element;
// Base component for plain JS classes
// tslint:disable-next-line:no-empty-interface
interface Component extends ComponentLifecycle
{ }
class Component
{
// tslint won't let me format the sample code in a way that vscode likes it :(
/**
* If set, `this.context` will be set at runtime to the current value of the given Context.
*
* Usage:
*
* ```ts
* type MyContext = number
* const Ctx = React.createContext(0)
*
* class Foo extends React.Component {
* static contextType = Ctx
* context!: React.ContextType
* render () {
* return <>My context's value: {this.context}>;
* }
* }
* ```
*
* @see https://reactjs.org/docs/context.html#classcontexttype
*/
static contextType?: Context;
/**
* If using the new style context, re-declare this in your class to be the
* `React.ContextType` of your `static contextType`.
* Should be used with type annotation or static contextType.
*
* ```ts
* static contextType = MyContext
* // For TS pre-3.7:
* context!: React.ContextType
* // For TS 3.7 and above:
* declare context: React.ContextType
* ```
*
* @see https://reactjs.org/docs/context.html
*/
// TODO (TypeScript 3.0): unknown
context: any;
constructor(props: Readonly);
/**
* @deprecated
* @see https://reactjs.org/docs/legacy-context.html
*/
constructor(props: P, context?: any);
// We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
// See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
// Also, the ` | S` allows intellisense to not be dumbisense
setState(
state: ((prevState: Readonly, props: Readonly) => (Pick | S | null)) | (Pick | S | null),
callback?: () => void
): void;
forceUpdate(callback?: () => void): void;
render(): ReactNode;
// React.Props is now deprecated, which means that the `children`
// property is not available on `P` by default, even though you can
// always pass children as variadic arguments to `createElement`.
// In the future, if we can define its call signature conditionally
// on the existence of `children` in `P`, then we should remove this.
readonly props: Readonly & Readonly<{ children?: ReactNode }>;
state: Readonly;
/**
* @deprecated
* https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs
*/
refs: {
[key: string]: ReactInstance
};
}
class PureComponent
extends Component
{ }
interface ClassicComponent
extends Component
{
replaceState(nextState: S, callback?: () => void): void;
isMounted(): boolean;
getInitialState?(): S;
}
interface ChildContextProvider {
getChildContext(): CC;
}
//
// Class Interfaces
// ----------------------------------------------------------------------
/**
* @deprecated as of recent React versions, function components can no
* longer be considered 'stateless'. Please use `FunctionComponent` instead.
*
* @see [React Hooks](https://reactjs.org/docs/hooks-intro.html)
*/
type SFC = FunctionComponent
;
/**
* @deprecated as of recent React versions, function components can no
* longer be considered 'stateless'. Please use `FunctionComponent` instead.
*
* @see [React Hooks](https://reactjs.org/docs/hooks-intro.html)
*/
type StatelessComponent
= FunctionComponent
;
type FC
= FunctionComponent
;
interface FunctionComponent
{
(props: PropsWithChildren
, context?: any): ReactElement | null;
propTypes?: WeakValidationMap;
contextTypes?: ValidationMap;
defaultProps?: Partial;
displayName?: string;
}
interface ForwardRefRenderFunction {
(props: PropsWithChildren, ref: ((instance: T | null) => void) | MutableRefObject | null): ReactElement | null;
displayName?: string;
// explicit rejected with `never` required due to
// https://github.com/microsoft/TypeScript/issues/36826
/**
* defaultProps are not supported on render functions
*/
defaultProps?: never;
/**
* propTypes are not supported on render functions
*/
propTypes?: never;
}
/**
* @deprecated Use ForwardRefRenderFunction. forwardRef doesn't accept a
* "real" component.
*/
interface RefForwardingComponent extends ForwardRefRenderFunction {}
interface ComponentClass extends StaticLifecycle
{
new (props: P, context?: any): Component
;
propTypes?: WeakValidationMap
;
contextType?: Context;
contextTypes?: ValidationMap;
childContextTypes?: ValidationMap;
defaultProps?: Partial;
displayName?: string;
}
interface ClassicComponentClass
extends ComponentClass
{
new (props: P, context?: any): ClassicComponent
;
getDefaultProps?(): P;
}
/**
* We use an intersection type to infer multiple type parameters from
* a single argument, which is useful for many top-level API defs.
* See https://github.com/Microsoft/TypeScript/issues/7234 for more info.
*/
type ClassType
, C extends ComponentClass
> =
C &
(new (props: P, context?: any) => T);
//
// Component Specs and Lifecycle
// ----------------------------------------------------------------------
// This should actually be something like `Lifecycle
| DeprecatedLifecycle
`,
// as React will _not_ call the deprecated lifecycle methods if any of the new lifecycle
// methods are present.
interface ComponentLifecycle
extends NewLifecycle
, DeprecatedLifecycle
{
/**
* Called immediately after a component is mounted. Setting state here will trigger re-rendering.
*/
componentDidMount?(): void;
/**
* Called to determine whether the change in props and state should trigger a re-render.
*
* `Component` always returns true.
* `PureComponent` implements a shallow comparison on props and state and returns true if any
* props or states have changed.
*
* If false is returned, `Component#render`, `componentWillUpdate`
* and `componentDidUpdate` will not be called.
*/
shouldComponentUpdate?(nextProps: Readonly
, nextState: Readonly, nextContext: any): boolean;
/**
* Called immediately before a component is destroyed. Perform any necessary cleanup in this method, such as
* cancelled network requests, or cleaning up any DOM elements created in `componentDidMount`.
*/
componentWillUnmount?(): void;
/**
* Catches exceptions generated in descendant components. Unhandled exceptions will cause
* the entire component tree to unmount.
*/
componentDidCatch?(error: Error, errorInfo: ErrorInfo): void;
}
// Unfortunately, we have no way of declaring that the component constructor must implement this
interface StaticLifecycle
{
getDerivedStateFromProps?: GetDerivedStateFromProps
;
getDerivedStateFromError?: GetDerivedStateFromError
;
}
type GetDerivedStateFromProps
=
/**
* Returns an update to a component's state based on its new props and old state.
*
* Note: its presence prevents any of the deprecated lifecycle methods from being invoked
*/
(nextProps: Readonly
, prevState: S) => Partial | null;
type GetDerivedStateFromError
=
/**
* This lifecycle is invoked after an error has been thrown by a descendant component.
* It receives the error that was thrown as a parameter and should return a value to update state.
*
* Note: its presence prevents any of the deprecated lifecycle methods from being invoked
*/
(error: any) => Partial | null;
// This should be "infer SS" but can't use it yet
interface NewLifecycle
{
/**
* Runs before React applies the result of `render` to the document, and
* returns an object to be given to componentDidUpdate. Useful for saving
* things such as scroll position before `render` causes changes to it.
*
* Note: the presence of getSnapshotBeforeUpdate prevents any of the deprecated
* lifecycle events from running.
*/
getSnapshotBeforeUpdate?(prevProps: Readonly
, prevState: Readonly): SS | null;
/**
* Called immediately after updating occurs. Not called for the initial render.
*
* The snapshot is only present if getSnapshotBeforeUpdate is present and returns non-null.
*/
componentDidUpdate?(prevProps: Readonly
, prevState: Readonly, snapshot?: SS): void;
}
interface DeprecatedLifecycle
{
/**
* Called immediately before mounting occurs, and before `Component#render`.
* Avoid introducing any side-effects or subscriptions in this method.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use componentDidMount or the constructor instead; will stop working in React 17
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#initializing-state
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
componentWillMount?(): void;
/**
* Called immediately before mounting occurs, and before `Component#render`.
* Avoid introducing any side-effects or subscriptions in this method.
*
* This method will not stop working in React 17.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use componentDidMount or the constructor instead
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#initializing-state
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
UNSAFE_componentWillMount?(): void;
/**
* Called when the component may be receiving new props.
* React may call this even if props have not changed, so be sure to compare new and existing
* props if you only want to handle changes.
*
* Calling `Component#setState` generally does not trigger this method.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use static getDerivedStateFromProps instead; will stop working in React 17
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
componentWillReceiveProps?(nextProps: Readonly
, nextContext: any): void;
/**
* Called when the component may be receiving new props.
* React may call this even if props have not changed, so be sure to compare new and existing
* props if you only want to handle changes.
*
* Calling `Component#setState` generally does not trigger this method.
*
* This method will not stop working in React 17.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use static getDerivedStateFromProps instead
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
UNSAFE_componentWillReceiveProps?(nextProps: Readonly
, nextContext: any): void;
/**
* Called immediately before rendering when new props or state is received. Not called for the initial render.
*
* Note: You cannot call `Component#setState` here.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use getSnapshotBeforeUpdate instead; will stop working in React 17
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#reading-dom-properties-before-an-update
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
componentWillUpdate?(nextProps: Readonly
, nextState: Readonly, nextContext: any): void;
/**
* Called immediately before rendering when new props or state is received. Not called for the initial render.
*
* Note: You cannot call `Component#setState` here.
*
* This method will not stop working in React 17.
*
* Note: the presence of getSnapshotBeforeUpdate or getDerivedStateFromProps
* prevents this from being invoked.
*
* @deprecated 16.3, use getSnapshotBeforeUpdate instead
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#reading-dom-properties-before-an-update
* @see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#gradual-migration-path
*/
UNSAFE_componentWillUpdate?(nextProps: Readonly
, nextState: Readonly, nextContext: any): void;
}
interface Mixin
extends ComponentLifecycle
{
mixins?: Array>;
statics?: {
[key: string]: any;
};
displayName?: string;
propTypes?: ValidationMap;
contextTypes?: ValidationMap;
childContextTypes?: ValidationMap;
getDefaultProps?(): P;
getInitialState?(): S;
}
interface ComponentSpec extends Mixin
{
render(): ReactNode;
[propertyName: string]: any;
}
function createRef(): RefObject;
// will show `ForwardRef(${Component.displayName || Component.name})` in devtools by default,
// but can be given its own specific name
interface ForwardRefExoticComponent extends NamedExoticComponent
{
defaultProps?: Partial
;
propTypes?: WeakValidationMap
;
}
function forwardRef(render: ForwardRefRenderFunction): ForwardRefExoticComponent & RefAttributes>;
/** Ensures that the props do not include ref at all */
type PropsWithoutRef =
// Just Pick would be sufficient for this, but I'm trying to avoid unnecessary mapping over union types
// https://github.com/Microsoft/TypeScript/issues/28339
'ref' extends keyof P
? Pick
>
: P;
/** Ensures that the props do not include string ref, which cannot be forwarded */
type PropsWithRef
=
// Just "P extends { ref?: infer R }" looks sufficient, but R will infer as {} if P is {}.
'ref' extends keyof P
? P extends { ref?: infer R }
? string extends R
? PropsWithoutRef
& { ref?: Exclude }
: P
: P
: P;
type PropsWithChildren = P & { children?: ReactNode };
/**
* NOTE: prefer ComponentPropsWithRef, if the ref is forwarded,
* or ComponentPropsWithoutRef when refs are not supported.
*/
type ComponentProps> =
T extends JSXElementConstructor
? P
: T extends keyof JSX.IntrinsicElements
? JSX.IntrinsicElements[T]
: {};
type ComponentPropsWithRef =
T extends ComponentClass
? PropsWithoutRef & RefAttributes>
: PropsWithRef>;
type ComponentPropsWithoutRef =
PropsWithoutRef>;
// will show `Memo(${Component.displayName || Component.name})` in devtools by default,
// but can be given its own specific name
type MemoExoticComponent> = NamedExoticComponent> & {
readonly type: T;
};
function memo(
Component: SFC
,
propsAreEqual?: (prevProps: Readonly>, nextProps: Readonly>) => boolean
): NamedExoticComponent;
function memo>(
Component: T,
propsAreEqual?: (prevProps: Readonly>, nextProps: Readonly>) => boolean
): MemoExoticComponent;
type LazyExoticComponent> = ExoticComponent> & {
readonly _result: T;
};
function lazy>(
factory: () => Promise<{ default: T }>
): LazyExoticComponent;
//
// React Hooks
// ----------------------------------------------------------------------
// based on the code in https://github.com/facebook/react/pull/13968
// Unlike the class component setState, the updates are not allowed to be partial
type SetStateAction = S | ((prevState: S) => S);
// this technically does accept a second argument, but it's already under a deprecation warning
// and it's not even released so probably better to not define it.
type Dispatch = (value: A) => void;
// Since action _can_ be undefined, dispatch may be called without any parameters.
type DispatchWithoutAction = () => void;
// Unlike redux, the actions _can_ be anything
type Reducer = (prevState: S, action: A) => S;
// If useReducer accepts a reducer without action, dispatch may be called without any parameters.
type ReducerWithoutAction = (prevState: S) => S;
// types used to try and prevent the compiler from reducing S
// to a supertype common with the second argument to useReducer()
type ReducerState> = R extends Reducer ? S : never;
type ReducerAction> = R extends Reducer ? A : never;
// The identity check is done with the SameValue algorithm (Object.is), which is stricter than ===
type ReducerStateWithoutAction> =
R extends ReducerWithoutAction ? S : never;
// TODO (TypeScript 3.0): ReadonlyArray
type DependencyList = ReadonlyArray;
// NOTE: callbacks are _only_ allowed to return either void, or a destructor.
// The destructor is itself only allowed to return void.
type EffectCallback = () => (void | (() => void | undefined));
interface MutableRefObject {
current: T;
}
// This will technically work if you give a Consumer or Provider