/// import * as CSS from 'csstype'; import { CSSProperties } from 'react'; import { DetailedHTMLFactory } from 'react'; import { Easing as Easing_2 } from '@popmotion/easing'; import { ForwardRefExoticComponent } from 'react'; import { HTMLAttributes } from 'react'; import { PropsWithoutRef } from 'react'; import * as PropTypes from 'prop-types'; import * as React from 'react'; import { ReactHTML } from 'react'; import { Ref } from 'react'; import { RefAttributes } from 'react'; import { RefObject } from 'react'; import { SpringProps } from 'popmotion'; import { SVGAttributes } from 'react'; /** * @internal */ export declare function addScaleCorrection(correctors: ScaleCorrectionDefinitionMap): void; declare type AlwaysPresent = [true, null]; /** * @public */ export declare const AnimateLayoutFeature: MotionFeature; /** * `AnimatePresence` enables the animation of components that have been removed from the tree. * * When adding/removing more than a single child, every child **must** be given a unique `key` prop. * * @library * * Any `Frame` components that have an `exit` property defined will animate out when removed from * the tree. * * ```jsx * import { Frame, AnimatePresence } from 'framer' * * // As items are added and removed from `items` * export function Items({ items }) { * return ( * * {items.map(item => ( * * ))} * * ) * } * ``` * * You can sequence exit animations throughout a tree using variants. * * @motion * * Any `motion` components that have an `exit` property defined will animate out when removed from * the tree. * * ```jsx * import { motion, AnimatePresence } from 'framer-motion' * * export const Items = ({ items }) => ( * * {items.map(item => ( * * ))} * * ) * ``` * * You can sequence exit animations throughout a tree using variants. * * If a child contains multiple `motion` components with `exit` props, it will only unmount the child * once all `motion` components have finished animating out. Likewise, any components using * `usePresence` all need to call `safeToRemove`. * * @public */ export declare const AnimatePresence: React.FunctionComponent; /** * @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 * * {isVisible && ( * * )} * * ``` * * @motion * * ```jsx * * {isVisible && ( * * )} * * ``` * * @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; /** * 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 ( * * * * ) * } * ``` * * @motion * * ```jsx * const MyComponent = ({ currentItem }) => ( * * * * ) * ``` * * @beta */ exitBeforeEnter?: boolean; } /** * @public */ export declare class AnimateSharedLayout extends React.Component { /** * A list of all the children in the shared layout */ private children; /** * As animate components with a defined `layoutId` are added/removed to the tree, * we store them in order. When one is added, it will animate out from the * previous one, and when it's removed, it'll animate to the previous one. */ private stacks; /** * Track whether the component has mounted. If it hasn't, the presence of added children * are set to Present, whereas if it has they're considered Entering */ private hasMounted; /** * Track whether we already have an update scheduled. If we don't, we'll run snapshots * and schedule one. */ private updateScheduled; /** * Tracks whether we already have a render scheduled. If we don't, we'll force one with this.forceRender */ private renderScheduled; /** * The methods provided to all children in the shared layout tree. */ syncContext: SharedLayoutSyncMethods; componentDidMount(): void; componentDidUpdate(): void; shouldComponentUpdate(): boolean; startLayoutAnimation(): void; updateStacks(): void; scheduleUpdate(force?: boolean): void; addChild(child: HTMLVisualElement): void; removeChild(child: HTMLVisualElement): void; addToStack(child: HTMLVisualElement): void; removeFromStack(child: HTMLVisualElement): void; /** * Return a stack of animate children based on the provided layoutId. * Will create a stack if none currently exists with that layoutId. */ getStack(id?: string): LayoutStack | undefined; render(): JSX.Element; } /** * 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: VisualElementAnimationControls): () => 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; /** * 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 but it's deprecated and warns /** * Accepts a context object (the value returned from `React.createContext`) and returns the current * context value, as given by the nearest context provider for the given context. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usecontext */ function useContext(context: Context/*, (not public API) observedBits?: number|boolean */): T; /** * Returns a stateful value, and a function to update it. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usestate */ function useState(initialState: S | (() => S)): [S, Dispatch>]; // convenience overload when first argument is ommitted /** * Returns a stateful value, and a function to update it. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usestate */ function useState(): [S | undefined, Dispatch>]; /** * An alternative to `useState`. * * `useReducer` is usually preferable to `useState` when you have complex state logic that involves * multiple sub-values. It also lets you optimize performance for components that trigger deep * updates because you can pass `dispatch` down instead of callbacks. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usereducer */ // overload where dispatch could accept 0 arguments. function useReducer, I>( reducer: R, initializerArg: I, initializer: (arg: I) => ReducerStateWithoutAction ): [ReducerStateWithoutAction, DispatchWithoutAction]; /** * An alternative to `useState`. * * `useReducer` is usually preferable to `useState` when you have complex state logic that involves * multiple sub-values. It also lets you optimize performance for components that trigger deep * updates because you can pass `dispatch` down instead of callbacks. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usereducer */ // overload where dispatch could accept 0 arguments. function useReducer>( reducer: R, initializerArg: ReducerStateWithoutAction, initializer?: undefined ): [ReducerStateWithoutAction, DispatchWithoutAction]; /** * An alternative to `useState`. * * `useReducer` is usually preferable to `useState` when you have complex state logic that involves * multiple sub-values. It also lets you optimize performance for components that trigger deep * updates because you can pass `dispatch` down instead of callbacks. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usereducer */ // overload where "I" may be a subset of ReducerState; used to provide autocompletion. // If "I" matches ReducerState exactly then the last overload will allow initializer to be ommitted. // the last overload effectively behaves as if the identity function (x => x) is the initializer. function useReducer, I>( reducer: R, initializerArg: I & ReducerState, initializer: (arg: I & ReducerState) => ReducerState ): [ReducerState, Dispatch>]; /** * An alternative to `useState`. * * `useReducer` is usually preferable to `useState` when you have complex state logic that involves * multiple sub-values. It also lets you optimize performance for components that trigger deep * updates because you can pass `dispatch` down instead of callbacks. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usereducer */ // overload for free "I"; all goes as long as initializer converts it into "ReducerState". function useReducer, I>( reducer: R, initializerArg: I, initializer: (arg: I) => ReducerState ): [ReducerState, Dispatch>]; /** * An alternative to `useState`. * * `useReducer` is usually preferable to `useState` when you have complex state logic that involves * multiple sub-values. It also lets you optimize performance for components that trigger deep * updates because you can pass `dispatch` down instead of callbacks. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usereducer */ // I'm not sure if I keep this 2-ary or if I make it (2,3)-ary; it's currently (2,3)-ary. // The Flow types do have an overload for 3-ary invocation with undefined initializer. // NOTE: without the ReducerState indirection, TypeScript would reduce S to be the most common // supertype between the reducer's return type and the initialState (or the initializer's return type), // which would prevent autocompletion from ever working. // TODO: double-check if this weird overload logic is necessary. It is possible it's either a bug // in older versions, or a regression in newer versions of the typescript completion service. function useReducer>( reducer: R, initialState: ReducerState, initializer?: undefined ): [ReducerState, Dispatch>]; /** * `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument * (`initialValue`). The returned object will persist for the full lifetime of the component. * * Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable * value around similar to how you’d use instance fields in classes. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#useref */ // TODO (TypeScript 3.0): function useRef(initialValue: T): MutableRefObject; // convenience overload for refs given as a ref prop as they typically start with a null value /** * `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument * (`initialValue`). The returned object will persist for the full lifetime of the component. * * Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable * value around similar to how you’d use instance fields in classes. * * Usage note: if you need the result of useRef to be directly mutable, include `| null` in the type * of the generic argument. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#useref */ // TODO (TypeScript 3.0): function useRef(initialValue: T|null): RefObject; // convenience overload for potentially undefined initialValue / call with 0 arguments // has a default to stop it from defaulting to {} instead /** * `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument * (`initialValue`). The returned object will persist for the full lifetime of the component. * * Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable * value around similar to how you’d use instance fields in classes. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#useref */ // TODO (TypeScript 3.0): function useRef(): MutableRefObject; /** * The signature is identical to `useEffect`, but it fires synchronously after all DOM mutations. * Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside * `useLayoutEffect` will be flushed synchronously, before the browser has a chance to paint. * * Prefer the standard `useEffect` when possible to avoid blocking visual updates. * * If you’re migrating code from a class component, `useLayoutEffect` fires in the same phase as * `componentDidMount` and `componentDidUpdate`. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#uselayouteffect */ function useLayoutEffect(effect: EffectCallback, deps?: DependencyList): void; /** * Accepts a function that contains imperative, possibly effectful code. * * @param effect Imperative function that can return a cleanup function * @param deps If present, effect will only activate if the values in the list change. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#useeffect */ function useEffect(effect: EffectCallback, deps?: DependencyList): void; // NOTE: this does not accept strings, but this will have to be fixed by removing strings from type Ref /** * `useImperativeHandle` customizes the instance value that is exposed to parent components when using * `ref`. As always, imperative code using refs should be avoided in most cases. * * `useImperativeHandle` should be used with `React.forwardRef`. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#useimperativehandle */ function useImperativeHandle(ref: Ref|undefined, init: () => R, deps?: DependencyList): void; // I made 'inputs' required here and in useMemo as there's no point to memoizing without the memoization key // useCallback(X) is identical to just using X, useMemo(() => Y) is identical to just using Y. /** * `useCallback` will return a memoized version of the callback that only changes if one of the `inputs` * has changed. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usecallback */ // TODO (TypeScript 3.0): unknown> function useCallback any>(callback: T, deps: DependencyList): T; /** * `useMemo` will only recompute the memoized value when one of the `deps` has changed. * * Usage note: if calling `useMemo` with a referentially stable function, also give it as the input in * the second argument. * * ```ts * function expensive () { ... } * * function Component () { * const expensiveResult = useMemo(expensive, [expensive]) * return ... * } * ``` * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usememo */ // allow undefined, but don't make it optional as that is very likely a mistake function useMemo(factory: () => T, deps: DependencyList | undefined): T; /** * `useDebugValue` can be used to display a label for custom hooks in React DevTools. * * NOTE: We don’t recommend adding debug values to every custom hook. * It’s most valuable for custom hooks that are part of shared libraries. * * @version 16.8.0 * @see https://reactjs.org/docs/hooks-reference.html#usedebugvalue */ // the name of the custom hook is itself derived from the function name at runtime: // it's just the function name without the "use" prefix. function useDebugValue(value: T, format?: (value: T) => any): void; // // Event System // ---------------------------------------------------------------------- // TODO: change any to unknown when moving to TS v3 interface BaseSyntheticEvent { nativeEvent: E; currentTarget: C; target: T; bubbles: boolean; cancelable: boolean; defaultPrevented: boolean; eventPhase: number; isTrusted: boolean; preventDefault(): void; isDefaultPrevented(): boolean; stopPropagation(): void; isPropagationStopped(): boolean; persist(): void; timeStamp: number; type: string; } /** * currentTarget - a reference to the element on which the event listener is registered. * * target - a reference to the element from which the event was originally dispatched. * This might be a child element to the element on which the event listener is registered. * If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/11508#issuecomment-256045682 */ interface SyntheticEvent extends BaseSyntheticEvent {} interface ClipboardEvent extends SyntheticEvent { clipboardData: DataTransfer; } interface CompositionEvent extends SyntheticEvent { data: string; } interface DragEvent extends MouseEvent { dataTransfer: DataTransfer; } interface PointerEvent extends MouseEvent { pointerId: number; pressure: number; tangentialPressure: number; tiltX: number; tiltY: number; twist: number; width: number; height: number; pointerType: 'mouse' | 'pen' | 'touch'; isPrimary: boolean; } interface FocusEvent extends SyntheticEvent { relatedTarget: EventTarget | null; target: EventTarget & T; } // tslint:disable-next-line:no-empty-interface interface FormEvent extends SyntheticEvent { } interface InvalidEvent extends SyntheticEvent { target: EventTarget & T; } interface ChangeEvent extends SyntheticEvent { target: EventTarget & T; } interface KeyboardEvent extends SyntheticEvent { altKey: boolean; charCode: number; ctrlKey: boolean; /** * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method. */ getModifierState(key: string): boolean; /** * See the [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#named-key-attribute-values). for possible values */ key: string; keyCode: number; locale: string; location: number; metaKey: boolean; repeat: boolean; shiftKey: boolean; /** @deprecated */ which: number; } interface MouseEvent extends UIEvent { altKey: boolean; button: number; buttons: number; clientX: number; clientY: number; ctrlKey: boolean; /** * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method. */ getModifierState(key: string): boolean; metaKey: boolean; movementX: number; movementY: number; pageX: number; pageY: number; relatedTarget: EventTarget | null; screenX: number; screenY: number; shiftKey: boolean; } interface TouchEvent extends UIEvent { altKey: boolean; changedTouches: TouchList; ctrlKey: boolean; /** * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method. */ getModifierState(key: string): boolean; metaKey: boolean; shiftKey: boolean; targetTouches: TouchList; touches: TouchList; } interface UIEvent extends SyntheticEvent { detail: number; view: AbstractView; } interface WheelEvent extends MouseEvent { deltaMode: number; deltaX: number; deltaY: number; deltaZ: number; } interface AnimationEvent extends SyntheticEvent { animationName: string; elapsedTime: number; pseudoElement: string; } interface TransitionEvent extends SyntheticEvent { elapsedTime: number; propertyName: string; pseudoElement: string; } // // Event Handler Types // ---------------------------------------------------------------------- type EventHandler> = { bivarianceHack(event: E): void }["bivarianceHack"]; type ReactEventHandler = EventHandler>; type ClipboardEventHandler = EventHandler>; type CompositionEventHandler = EventHandler>; type DragEventHandler = EventHandler>; type FocusEventHandler = EventHandler>; type FormEventHandler = EventHandler>; type ChangeEventHandler = EventHandler>; type KeyboardEventHandler = EventHandler>; type MouseEventHandler = EventHandler>; type TouchEventHandler = EventHandler>; type PointerEventHandler = EventHandler>; type UIEventHandler = EventHandler>; type WheelEventHandler = EventHandler>; type AnimationEventHandler = EventHandler>; type TransitionEventHandler = EventHandler>; // // Props / DOM Attributes // ---------------------------------------------------------------------- /** * @deprecated. This was used to allow clients to pass `ref` and `key` * to `createElement`, which is no longer necessary due to intersection * types. If you need to declare a props object before passing it to * `createElement` or a factory, use `ClassAttributes`: * * ```ts * var b: Button | null; * var props: ButtonProps & ClassAttributes