@react-spring/core
Version:
The platform-agnostic core of `react-spring`
1,247 lines (1,216 loc) • 54.4 kB
text/typescript
import { InterpolatorFn, InterpolatorArgs, EasingFunction, Lookup, Any, UnknownProps, Falsy, OneOrMore, Remap, ObjectFromUnion, Constrain, ObjectType, Merge, NoInfer, InterpolatorConfig, Animatable, ExtrapolateType } from '@react-spring/types';
export * from '@react-spring/types';
import { FluidValue, Timeout, FluidProps } from '@react-spring/shared';
export { Globals, createInterpolator, easings, useIsomorphicLayoutEffect, useReducedMotion } from '@react-spring/shared';
import { AnimatedValue, Animated } from '@react-spring/animated';
import * as react from 'react';
import { ReactNode, JSX, DependencyList, MutableRefObject, RefObject } from 'react';
/**
* An `Interpolation` is a memoized value that's computed whenever one of its
* `FluidValue` dependencies has its value changed.
*
* Other `FrameValue` objects can depend on this. For example, passing an
* `Interpolation` as the `to` prop of a `useSpring` call will trigger an
* animation toward the memoized value.
*/
declare class Interpolation<Input = any, Output = any> extends FrameValue<Output> {
/** The source of input values */
readonly source: unknown;
/** Useful for debugging. */
key?: string;
/** Equals false when in the frameloop */
idle: boolean;
/** The function that maps inputs values to output */
readonly calc: InterpolatorFn<Input, Output>;
/** The inputs which are currently animating */
protected _active: Set<FluidValue<any, any>>;
constructor(
/** The source of input values */
source: unknown, args: InterpolatorArgs<Input, Output>);
advance(_dt?: number): void;
protected _get(): Output;
protected _start(): void;
protected _attach(): void;
protected _detach(): void;
/** @internal */
eventObserved(event: FrameValue.Event): void;
}
/**
* A kind of `FluidValue` that manages an `AnimatedValue` node.
*
* Its underlying value can be accessed and even observed.
*/
declare abstract class FrameValue<T = any> extends FluidValue<T, FrameValue.Event<T>> {
readonly id: number;
abstract key?: string;
abstract get idle(): boolean;
protected _priority: number;
get priority(): number;
set priority(priority: number);
/** Get the current value */
get(): T;
/** Create a spring that maps our value to another value */
to<Out>(...args: InterpolatorArgs<T, Out>): Interpolation<T, Out>;
/** @deprecated Use the `to` method instead. */
interpolate<Out>(...args: InterpolatorArgs<T, Out>): Interpolation<T, Out>;
toJSON(): T;
protected observerAdded(count: number): void;
protected observerRemoved(count: number): void;
/** @internal */
abstract advance(dt: number): void;
/** @internal */
abstract eventObserved(_event: FrameValue.Event): void;
/** Called when the first child is added. */
protected _attach(): void;
/** Called when the last child is removed. */
protected _detach(): void;
/** Tell our children about our new value */
protected _onChange(value: T, idle?: boolean): void;
/** Tell our children about our new priority */
protected _onPriorityChange(priority: number): void;
}
declare namespace FrameValue {
/** A parent changed its value */
interface ChangeEvent<T = any> {
parent: FrameValue<T>;
type: 'change';
value: T;
idle: boolean;
}
/** A parent changed its priority */
interface PriorityEvent<T = any> {
parent: FrameValue<T>;
type: 'priority';
priority: number;
}
/** A parent is done animating */
interface IdleEvent<T = any> {
parent: FrameValue<T>;
type: 'idle';
}
/** Events sent to children of `FrameValue` objects */
type Event<T = any> = ChangeEvent<T> | PriorityEvent<T> | IdleEvent<T>;
}
declare class AnimationConfig {
/**
* With higher tension, the spring will resist bouncing and try harder to stop at its end value.
*
* When tension is zero, no animation occurs.
*
* @default 170
*/
tension: number;
/**
* The damping ratio coefficient, or just the damping ratio when `speed` is defined.
*
* When `speed` is defined, this value should be between 0 and 1.
*
* Higher friction means the spring will slow down faster.
*
* @default 26
*/
friction: number;
/**
* The natural frequency (in seconds), which dictates the number of bounces
* per second when no damping exists.
*
* When defined, `tension` is derived from this, and `friction` is derived
* from `tension` and `damping`.
*/
frequency?: number;
/**
* The damping ratio, which dictates how the spring slows down.
*
* Set to `0` to never slow down. Set to `1` to slow down without bouncing.
* Between `0` and `1` is for you to explore.
*
* Only works when `frequency` is defined.
*
* @default 1
*/
damping: number;
/**
* Higher mass means more friction is required to slow down.
*
* Defaults to 1, which works fine most of the time.
*
* @default 1
*/
mass: number;
/**
* The initial velocity of one or more values.
*
* @default 0
*/
velocity: number | number[];
/**
* The smallest velocity before the animation is considered "not moving".
*
* When undefined, `precision` is used instead.
*/
restVelocity?: number;
/**
* The smallest distance from a value before that distance is essentially zero.
*
* This helps in deciding when a spring is "at rest". The spring must be within
* this distance from its final value, and its velocity must be lower than this
* value too (unless `restVelocity` is defined).
*
* @default 0.01
*/
precision?: number;
/**
* For `duration` animations only. Note: The `duration` is not affected
* by this property.
*
* Defaults to `0`, which means "start from the beginning".
*
* Setting to `1+` makes an immediate animation.
*
* Setting to `0.5` means "start from the middle of the easing function".
*
* Any number `>= 0` and `<= 1` makes sense here.
*/
progress?: number;
/**
* Animation length in number of milliseconds.
*/
duration?: number;
/**
* The animation curve. Only used when `duration` is defined.
*
* Defaults to quadratic ease-in-out.
*/
easing: EasingFunction;
/**
* Avoid overshooting by ending abruptly at the goal value.
*
* @default false
*/
clamp: boolean;
/**
* When above zero, the spring will bounce instead of overshooting when
* exceeding its goal value. Its velocity is multiplied by `-1 + bounce`
* whenever its current value equals or exceeds its goal. For example,
* setting `bounce` to `0.5` chops the velocity in half on each bounce,
* in addition to any friction.
*/
bounce?: number;
/**
* "Decay animations" decelerate without an explicit goal value.
* Useful for scrolling animations.
*
* Use `true` for the default exponential decay factor (`0.998`).
*
* When a `number` between `0` and `1` is given, a lower number makes the
* animation slow down faster. And setting to `1` would make an unending
* animation.
*
* @default false
*/
decay?: boolean | number;
/**
* While animating, round to the nearest multiple of this number.
* The `from` and `to` values are never rounded, as well as any value
* passed to the `set` method of an animated value.
*/
round?: number;
constructor();
}
/** The object type of the `config` prop. */
type SpringConfig = Partial<AnimationConfig>;
/** The object given to the `onRest` prop and `start` promise. */
interface AnimationResult<T extends Readable = any> {
value: T extends Readable<infer U> ? U : never;
/** When true, no animation ever started. */
noop?: boolean;
/** When true, the animation was neither cancelled nor stopped prematurely. */
finished?: boolean;
/** When true, the animation was cancelled before it could finish. */
cancelled?: boolean;
}
/** The promised result of an animation. */
type AsyncResult<T extends Readable = any> = Promise<AnimationResult<T>>;
/** Map an object type to allow `SpringValue` for any property */
type Springify<T> = Lookup<SpringValue<unknown> | undefined> & {
[P in keyof T]: T[P] | SpringValue<T[P]>;
};
/**
* The set of `SpringValue` objects returned by a `useSpring` call (or similar).
*/
type SpringValues<T extends Lookup = any> = [T] extends [Any] ? Lookup<SpringValue<unknown> | undefined> : {
[P in keyof T]: SpringWrap<T[P]>;
};
type SpringWrap<T> = [
Exclude<T, FluidValue>,
Extract<T, readonly any[]>
] extends [object | void, never] ? never : SpringValue<Exclude<T, FluidValue | void>> | Extract<T, void>;
/** @internal */
interface Readable<T = any> {
get(): T;
}
/** @internal */
type InferState<T extends Readable> = T extends Controller<infer State> ? State : T extends SpringValue<infer U> ? U : unknown;
/** @internal */
type InferProps<T extends Readable> = T extends Controller<infer State> ? ControllerUpdate<State> : T extends SpringValue<infer U> ? SpringUpdate<U> : Lookup;
/** @internal */
type InferTarget<T> = T extends object ? T extends ReadonlyArray<number | string> ? SpringValue<T> : Controller<T> : SpringValue<T>;
/** @internal */
interface AnimationTarget<T = any> extends Readable<T> {
start(props: any): AsyncResult<this>;
stop: Function;
item?: unknown;
}
/** @internal */
interface AnimationRange<T> {
to: T | FluidValue<T> | undefined;
from: T | FluidValue<T> | undefined;
}
/** @internal */
type AnimationResolver<T extends Readable> = (result: AnimationResult<T> | AsyncResult<T>) => void;
/** @internal */
type EventKey = Exclude<keyof ReservedEventProps, 'onResolve' | 'onDestroyed'>;
/** @internal */
type PickEventFns<T> = {
[P in Extract<keyof T, EventKey>]?: Extract<T[P], Function>;
};
/** An animation being executed by the frameloop */
declare class Animation<T = any> {
changed: boolean;
values: readonly AnimatedValue[];
toValues: readonly number[] | null;
fromValues: readonly number[];
to: T | FluidValue<T>;
from: T | FluidValue<T>;
config: AnimationConfig;
immediate: boolean;
}
interface Animation<T> extends PickEventFns<SpringProps<T>> {
}
type AsyncTo<T> = SpringChain<T> | SpringToFn<T>;
/** @internal */
type RunAsyncProps<T extends AnimationTarget = any> = InferProps<T> & {
callId: number;
parentId?: number;
cancel: boolean;
to?: any;
};
/** @internal */
interface RunAsyncState<T extends AnimationTarget = any> {
paused: boolean;
pauseQueue: Set<() => void>;
resumeQueue: Set<() => void>;
timeouts: Set<Timeout>;
delayed?: boolean;
asyncId?: number;
asyncTo?: AsyncTo<InferState<T>>;
promise?: AsyncResult<T>;
cancelId?: number;
}
/** This error is thrown to signal an interrupted async animation. */
declare class BailSignal extends Error {
result: AnimationResult;
constructor();
}
interface DefaultSpringProps<T> extends Pick<SpringProps<T>, 'pause' | 'cancel' | 'immediate' | 'config'>, PickEventFns<SpringProps<T>> {
}
/**
* Only numbers, strings, and arrays of numbers/strings are supported.
* Non-animatable strings are also supported.
*/
declare class SpringValue<T = any> extends FrameValue<T> {
/** The property name used when `to` or `from` is an object. Useful when debugging too. */
key?: string;
/** The animation state */
animation: Animation<T>;
/** The queue of pending props */
queue?: SpringUpdate<T>[];
/** Some props have customizable default values */
defaultProps: DefaultSpringProps<T>;
/** The state for `runAsync` calls */
protected _state: RunAsyncState<SpringValue<T>>;
/** The promise resolvers of pending `start` calls */
protected _pendingCalls: Set<AnimationResolver<this>>;
/** The counter for tracking `scheduleProps` calls */
protected _lastCallId: number;
/** The last `scheduleProps` call that changed the `to` prop */
protected _lastToId: number;
protected _memoizedDuration: number;
constructor(from: Exclude<T, object>, props?: SpringUpdate<T>);
constructor(props?: SpringUpdate<T>);
/** Equals true when not advancing on each frame. */
get idle(): boolean;
get goal(): T;
get velocity(): VelocityProp<T>;
/**
* When true, this value has been animated at least once.
*/
get hasAnimated(): boolean;
/**
* When true, this value has an unfinished animation,
* which is either active or paused.
*/
get isAnimating(): boolean;
/**
* When true, all current and future animations are paused.
*/
get isPaused(): boolean;
/**
*
*
*/
get isDelayed(): boolean | undefined;
/** Advance the current animation by a number of milliseconds */
advance(dt: number): void;
/** Set the current value, while stopping the current animation */
set(value: T | FluidValue<T>): this;
/**
* Freeze the active animation in time, as well as any updates merged
* before `resume` is called.
*/
pause(): void;
/** Resume the animation if paused. */
resume(): void;
/** Skip to the end of the current animation. */
finish(): this;
/** Push props into the pending queue. */
update(props: SpringUpdate<T>): this;
/**
* Update this value's animation using the queue of pending props,
* and unpause the current animation (if one is frozen).
*
* When arguments are passed, a new animation is created, and the
* queued animations are left alone.
*/
start(): AsyncResult<this>;
start(props: SpringUpdate<T>): AsyncResult<this>;
start(to: T, props?: SpringProps<T>): AsyncResult<this>;
/**
* Stop the current animation, and cancel any delayed updates.
*
* Pass `true` to call `onRest` with `cancelled: true`.
*/
stop(cancel?: boolean): this;
/** Restart the animation. */
reset(): void;
/** @internal */
eventObserved(event: FrameValue.Event): void;
/**
* Parse the `to` and `from` range from the given `props` object.
*
* This also ensures the initial value is available to animated components
* during the render phase.
*/
protected _prepareNode(props: {
to?: any;
from?: any;
reverse?: boolean;
default?: any;
}): {
to: any;
from: any;
};
/** Every update is processed by this method before merging. */
protected _update({ ...props }: SpringProps<T>, isLoop?: boolean): AsyncResult<SpringValue<T>>;
/** Merge props into the current animation */
protected _merge(range: AnimationRange<T>, props: RunAsyncProps<SpringValue<T>>, resolve: AnimationResolver<SpringValue<T>>): void;
/** Update the `animation.to` value, which might be a `FluidValue` */
protected _focus(value: T | FluidValue<T>): void;
protected _attach(): void;
protected _detach(): void;
/**
* Update the current value from outside the frameloop,
* and return the `Animated` node.
*/
protected _set(arg: T | FluidValue<T>, idle?: boolean): Animated | undefined;
protected _onStart(): void;
protected _onChange(value: T, idle?: boolean): void;
protected _start(): void;
protected _resume(): void;
/**
* Exit the frameloop and notify `onRest` listeners.
*
* Always wrap `_stop` calls with `batchedUpdates`.
*/
protected _stop(goal?: any, cancel?: boolean): void;
}
/** Queue of pending updates for a `Controller` instance. */
interface ControllerQueue<State extends Lookup = Lookup> extends Array<ControllerUpdate<State, any> & {
/** The keys affected by this update. When null, all keys are affected. */
keys: string[] | null;
}> {
}
declare class Controller<State extends Lookup = Lookup> {
readonly id: number;
/** The animated values */
springs: SpringValues<State>;
/** The queue of props passed to the `update` method. */
queue: ControllerQueue<State>;
/**
* The injected ref. When defined, render-based updates are pushed
* onto the `queue` instead of being auto-started.
*/
ref?: SpringRef<State>;
/** Custom handler for flushing update queues */
protected _flush?: ControllerFlushFn<this>;
/** These props are used by all future spring values */
protected _initialProps?: Lookup;
/** The counter for tracking `scheduleProps` calls */
protected _lastAsyncId: number;
/** The values currently being animated */
protected _active: Set<FrameValue<any>>;
/** The values that changed recently */
protected _changed: Set<FrameValue<any>>;
/** Equals false when `onStart` listeners can be called */
protected _started: boolean;
private _item?;
/** State used by the `runAsync` function */
protected _state: RunAsyncState<this>;
/** The event queues that are flushed once per frame maximum */
protected _events: {
onStart: Map<OnStart<SpringValue<State>, Controller<State>, any>, AnimationResult<any>>;
onChange: Map<OnChange<SpringValue<State>, Controller<State>, any>, AnimationResult<any>>;
onRest: Map<OnRest<SpringValue<State>, Controller<State>, any>, AnimationResult<any>>;
};
constructor(props?: ControllerUpdate<State> | null, flush?: ControllerFlushFn<any>);
/**
* Equals `true` when no spring values are in the frameloop, and
* no async animation is currently active.
*/
get idle(): boolean;
get item(): any;
set item(item: any);
/** Get the current values of our springs */
get(): State & UnknownProps;
/** Set the current values without animating. */
set(values: Partial<State>): void;
/** Push an update onto the queue of each value. */
update(props: ControllerUpdate<State> | Falsy): this;
/**
* Start the queued animations for every spring, and resolve the returned
* promise once all queued animations have finished or been cancelled.
*
* When you pass a queue (instead of nothing), that queue is used instead of
* the queued animations added with the `update` method, which are left alone.
*/
start(props?: OneOrMore<ControllerUpdate<State>> | null): AsyncResult<this>;
/** Stop all animations. */
stop(): this;
/** Stop animations for the given keys. */
stop(keys: OneOrMore<string>): this;
/** Cancel all animations. */
stop(cancel: boolean): this;
/** Cancel animations for the given keys. */
stop(cancel: boolean, keys: OneOrMore<string>): this;
/** Stop some or all animations. */
stop(keys?: OneOrMore<string>): this;
/** Cancel some or all animations. */
stop(cancel: boolean, keys?: OneOrMore<string>): this;
/** Freeze the active animation in time */
pause(keys?: OneOrMore<string>): this;
/** Resume the animation if paused. */
resume(keys?: OneOrMore<string>): this;
/** Call a function once per spring value */
each(iterator: (spring: SpringValue, key: string) => void): void;
/** @internal Called at the end of every animation frame */
protected _onFrame(): void;
/** @internal */
eventObserved(event: FrameValue.Event): void;
}
/** Replace the type of each `T` property with `never` (unless compatible with `U`) */
type Valid<T, U> = NeverProps<T, InvalidKeys<T, U>>;
/** Replace the type of each `P` property with `never` */
type NeverProps<T, P extends keyof T> = Remap<Pick<T, Exclude<keyof T, P>> & {
[K in P]: never;
}>;
/** Return a union type of every key whose `T` value is incompatible with its `U` value */
type InvalidKeys<T, U> = {
[P in keyof T & keyof U]: T[P] extends U[P] ? never : P;
}[keyof T & keyof U];
/** Unwrap any `FluidValue` object types */
type RawValues<T extends object> = {
[P in keyof T]: T[P] extends FluidValue<infer U> ? U : T[P];
};
/**
* For testing whether a type is an object but not an array.
*
* T extends IsPlainObject<T> ? true : false
*
* When `any` is passed, the resolved type is `true | false`.
*/
type IsPlainObject<T> = T extends ReadonlyArray<any> ? Any : T extends object ? object : Any;
type StringKeys<T> = T extends IsPlainObject<T> ? string & keyof T : string;
/** The flush function that handles `start` calls */
type ControllerFlushFn<T extends Controller<any> = Controller> = (ctrl: T, queue: ControllerQueue<InferState<T>>) => AsyncResult<T>;
/**
* An async function that can update or stop the animations of a spring.
* Typically defined as the `to` prop.
*
* The `T` parameter can be a set of animated values (as an object type)
* or a primitive type for a single animated value.
*/
interface SpringToFn<T = any> {
(start: StartFn<T>, stop: StopFn<T>): Promise<any> | void;
}
type StartFn<T> = InferTarget<T> extends {
start: infer T;
} ? T : never;
type StopFn<T> = InferTarget<T> extends {
stop: infer T;
} ? T : never;
/**
* Update the props of an animation.
*
* The `T` parameter can be a set of animated values (as an object type)
* or a primitive type for a single animated value.
*/
type SpringUpdateFn<T = any> = T extends IsPlainObject<T> ? UpdateValuesFn<T> : UpdateValueFn<T>;
interface AnyUpdateFn<T extends SpringValue | Controller<any>, Props extends object = InferProps<T>, State = InferState<T>> {
(to: SpringTo<State>, props?: Props): AsyncResult<T>;
(props: {
to?: SpringToFn<T> | Falsy;
} & Props): AsyncResult<T>;
(props: {
to?: SpringChain<State> | Falsy;
} & Props): AsyncResult<T>;
}
/**
* Update the props of a `Controller` object or `useSpring` call.
*
* The `T` parameter must be a set of animated values (as an object type).
*/
interface UpdateValuesFn<State extends Lookup = Lookup> extends AnyUpdateFn<Controller<State>> {
(props: InlineToProps<State> & ControllerProps<State>): AsyncResult<Controller<State>>;
(props: {
to?: GoalValues<State> | Falsy;
} & ControllerProps<State>): AsyncResult<Controller<State>>;
}
/**
* Update the props of a spring.
*
* The `T` parameter must be a primitive type for a single animated value.
*/
interface UpdateValueFn<T = any> extends AnyUpdateFn<SpringValue<T>> {
(props: {
to?: GoalValue<T>;
} & SpringProps<T>): AsyncResult<SpringValue<T>>;
}
type EventHandler<TResult extends Readable = any, TSource = unknown, Item = undefined> = (result: AnimationResult<TResult>, ctrl: TSource, item?: Item) => void;
/**
* Called before the first frame of every animation.
* From inside the `requestAnimationFrame` callback.
*/
type OnStart<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
/** Called when a `SpringValue` changes */
type OnChange<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
type OnPause<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
type OnResume<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
/** Called once the animation comes to a halt */
type OnRest<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
type OnResolve<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
/**
* Called after an animation is updated by new props,
* even if the animation remains idle.
*/
type OnProps<T = unknown> = (props: Readonly<SpringProps<T>>, spring: SpringValue<T>) => void;
declare enum TransitionPhase {
/** This transition is being mounted */
MOUNT = "mount",
/** This transition is entering or has entered */
ENTER = "enter",
/** This transition had its animations updated */
UPDATE = "update",
/** This transition will expire after animating */
LEAVE = "leave"
}
/** The phases of a `useTransition` item */
type TransitionKey = 'initial' | 'enter' | 'update' | 'leave';
/**
* Extract a union of animated values from a set of `useTransition` props.
*/
type TransitionValues<Props extends object> = unknown & ForwardProps<ObjectFromUnion<Constrain<ObjectType<Props[TransitionKey & keyof Props] extends infer T ? T extends ReadonlyArray<infer Element> ? Element : T extends (...args: any[]) => infer Return ? Return extends ReadonlyArray<infer ReturnElement> ? ReturnElement : Return : T : never>, {}>>>;
type UseTransitionProps<Item = any> = Merge<Omit<ControllerProps<UnknownProps, Item>, 'onResolve'>, {
from?: TransitionFrom<Item>;
initial?: TransitionFrom<Item>;
enter?: TransitionTo<Item>;
update?: TransitionTo<Item>;
leave?: TransitionTo<Item>;
keys?: ItemKeys<Item>;
sort?: (a: Item, b: Item) => number;
trail?: number;
exitBeforeEnter?: boolean;
/**
* When `true` or `<= 0`, each item is unmounted immediately after its
* `leave` animation is finished.
*
* When `false`, items are never unmounted.
*
* When `> 0`, this prop is used in a `setTimeout` call that forces a
* rerender if the component that called `useTransition` doesn't rerender
* on its own after an item's `leave` animation is finished.
*/
expires?: boolean | number | ((item: Item) => boolean | number);
config?: SpringConfig | ((item: Item, index: number, state: TransitionPhase) => AnimationProps['config']);
/**
* Called after a transition item is unmounted.
*/
onDestroyed?: (item: Item, key: Key) => void;
/**
* Used to access the imperative API.
*
* Animations never auto-start when `ref` is defined.
*/
ref?: SpringRef;
}>;
type TransitionComponentProps<Item, Props extends object = any> = unknown & UseTransitionProps<Item> & {
keys?: ItemKeys<NoInfer<Item>>;
items: OneOrMore<Item>;
children: TransitionRenderFn<NoInfer<Item>, PickAnimated<Props>>;
};
type Key = string | number;
type ItemKeys<T = any> = OneOrMore<Key> | ((item: T) => Key) | null;
/** The function returned by `useTransition` */
interface TransitionFn<Item = any, State extends Lookup = Lookup> {
(render: TransitionRenderFn<Item, State>): JSX.Element;
}
interface TransitionRenderFn<Item = any, State extends Lookup = Lookup> {
(values: SpringValues<State>, item: Item, transition: TransitionState<Item, State>, index: number): ReactNode;
}
interface TransitionState<Item = any, State extends Lookup = Lookup> {
key: any;
item: Item;
ctrl: Controller<State>;
phase: TransitionPhase;
expired?: boolean;
expirationId?: number;
}
type TransitionFrom<Item> = Falsy | GoalProp<UnknownProps> | ((item: Item, index: number) => GoalProp<UnknownProps> | Falsy);
type TransitionTo<Item, State extends Lookup = Lookup> = Falsy | OneOrMore<ControllerUpdate<State, Item>> | Function | ((item: Item, index: number) => ControllerUpdate<State, Item> | SpringChain<State> | SpringToFn<State> | Falsy);
interface Change {
phase: TransitionPhase;
springs: SpringValues<UnknownProps>;
payload: ControllerUpdate;
}
/**
* Move all non-reserved props into the `to` prop.
*/
type InferTo<T extends object> = Merge<{
to: ForwardProps<T>;
}, Pick<T, keyof T & keyof ReservedProps>>;
/**
* The props of a `useSpring` call or its async `update` function.
*
* The `T` parameter can be a set of animated values (as an object type)
* or a primitive type for a single animated value.
*/
type SpringUpdate<T = any> = ToProps<T> & SpringProps<T>;
type SpringsUpdate<State extends Lookup = UnknownProps> = OneOrMore<ControllerUpdate<State>> | ((index: number, ctrl: Controller<State>) => ControllerUpdate<State> | null);
/**
* Use the `SpringUpdate` type if you need the `to` prop to exist.
* For function types, prefer one overload per possible `to` prop
* type (for better type inference).
*
* The `T` parameter can be a set of animated values (as an object type)
* or a primitive type for a single animated value.
*/
interface SpringProps<T = any> extends AnimationProps<T> {
from?: GoalValue<T>;
loop?: LoopProp<SpringUpdate>;
/**
* Called after an animation is updated by new props,
* even if the animation remains idle.
*/
onProps?: EventProp<OnProps<T>>;
/**
* Called when an animation moves for the first time.
*/
onStart?: EventProp<OnStart<SpringValue<T>, SpringValue<T>>>;
/**
* Called when a spring has its value changed.
*/
onChange?: EventProp<OnChange<SpringValue<T>, SpringValue<T>>>;
onPause?: EventProp<OnPause<SpringValue<T>, SpringValue<T>>>;
onResume?: EventProp<OnResume<SpringValue<T>, SpringValue<T>>>;
/**
* Called when all animations come to a stand-still.
*/
onRest?: EventProp<OnRest<SpringValue<T>, SpringValue<T>>>;
}
/**
* A union type of all possible `to` prop values.
*
* This is not recommended for function types. Instead, you should declare
* an overload for each `to` type. See `SpringUpdateFn` for an example.
*
* The `T` parameter can be a set of animated values (as an object type)
* or a primitive type for a single animated value.
*/
type ToProps<T = any> = {
to?: GoalProp<T> | SpringToFn<T> | SpringChain<T>;
} | ([T] extends [IsPlainObject<T>] ? InlineToProps<T> : never);
/**
* A value or set of values that can be animated from/to.
*
* The `T` parameter can be a set of animated values (as an object type)
* or a primitive type for a single animated value.
*/
type GoalProp<T> = [T] extends [IsPlainObject<T>] ? GoalValues<T> | Falsy : GoalValue<T>;
/** A set of values for a `Controller` to animate from/to. */
type GoalValues<T> = FluidProps<T> extends infer Props ? {
[P in keyof Props]?: Props[P] | null;
} : never;
/**
* A value that `SpringValue` objects can animate from/to.
*
* The `UnknownProps` type lets you pass in { a: 1 } if the `key`
* property of `SpringValue` equals "a".
*/
type GoalValue<T> = T | FluidValue<T> | UnknownProps | null | undefined;
/**
* Where `to` is inferred from non-reserved props
*
* The `T` parameter can be a set of animated values (as an object type)
* or a primitive type for a single animated value.
*/
type InlineToProps<T = any> = Remap<GoalValues<T> & {
to?: undefined;
}>;
/** A serial queue of spring updates. */
interface SpringChain<T = any> extends Array<[
T
] extends [IsPlainObject<T>] ? ControllerUpdate<T> : SpringTo<T> | SpringUpdate<T>> {
}
/** A value that any `SpringValue` or `Controller` can animate to. */
type SpringTo<T = any> = ([T] extends [IsPlainObject<T>] ? never : T | FluidValue<T>) | SpringChain<T> | SpringToFn<T> | Falsy;
type ControllerUpdate<State extends Lookup = Lookup, Item = undefined> = unknown & ToProps<State> & ControllerProps<State, Item>;
/**
* Props for `Controller` methods and constructor.
*/
interface ControllerProps<State extends Lookup = Lookup, Item = undefined> extends AnimationProps<State> {
ref?: SpringRef<State>;
from?: GoalValues<State> | Falsy;
loop?: LoopProp<ControllerUpdate>;
/**
* Called when the # of animating values exceeds 0
*
* Also accepts an object for per-key events
*/
onStart?: OnStart<SpringValue<State>, Controller<State>, Item> | {
[P in keyof State]?: OnStart<SpringValue<State[P]>, Controller<State>, Item>;
};
/**
* Called when the # of animating values hits 0
*
* Also accepts an object for per-key events
*/
onRest?: OnRest<SpringValue<State>, Controller<State>, Item> | {
[P in keyof State]?: OnRest<SpringValue<State[P]>, Controller<State>, Item>;
};
/**
* Called once per frame when animations are active
*
* Also accepts an object for per-key events
*/
onChange?: OnChange<SpringValue<State>, Controller<State>, Item> | {
[P in keyof State]?: OnChange<SpringValue<State[P]>, Controller<State>, Item>;
};
onPause?: OnPause<SpringValue<State>, Controller<State>, Item> | {
[P in keyof State]?: OnPause<SpringValue<State[P]>, Controller<State>, Item>;
};
onResume?: OnResume<SpringValue<State>, Controller<State>, Item> | {
[P in keyof State]?: OnResume<SpringValue<State[P]>, Controller<State>, Item>;
};
/**
* Called after an animation is updated by new props.
* Useful for manipulation
*
* Also accepts an object for per-key events
*/
onProps?: OnProps<State> | {
[P in keyof State]?: OnProps<State[P]>;
};
/**
* Called when the promise for this update is resolved.
*/
onResolve?: OnResolve<SpringValue<State>, Controller<State>, Item>;
}
type LoopProp<T extends object> = boolean | T | (() => boolean | T);
type VelocityProp<T = any> = T extends ReadonlyArray<number | string> ? number[] : number;
/** For props that can be set on a per-key basis. */
type MatchProp<T> = boolean | OneOrMore<StringKeys<T>> | ((key: StringKeys<T>) => boolean);
/** Event props can be customized per-key. */
type EventProp<T> = T | Lookup<T | undefined>;
/**
* Most of the reserved animation props, except `to`, `from`, `loop`,
* and the event props.
*/
interface AnimationProps<T = any> {
/**
* Configure the spring behavior for each key.
*/
config?: SpringConfig | ((key: StringKeys<T>) => SpringConfig);
/**
* Milliseconds to wait before applying the other props.
*/
delay?: number | ((key: StringKeys<T>) => number);
/**
* When true, props jump to their goal values instead of animating.
*/
immediate?: MatchProp<T>;
/**
* Cancel all animations by using `true`, or some animations by using a key
* or an array of keys.
*/
cancel?: MatchProp<T>;
/**
* Pause all animations by using `true`, or some animations by using a key
* or an array of keys.
*/
pause?: MatchProp<T>;
/**
* Start the next animations at their values in the `from` prop.
*/
reset?: MatchProp<T>;
/**
* Swap the `to` and `from` props.
*/
reverse?: boolean;
/**
* Override the default props with this update.
*/
default?: boolean | SpringProps<T>;
}
/**
* Extract the custom props that are treated like `to` values
*/
type ForwardProps<T extends object> = RawValues<Omit<Constrain<T, {}>, keyof ReservedProps>>;
/**
* Property names that are reserved for animation config
*/
interface ReservedProps extends ReservedEventProps {
config?: any;
from?: any;
to?: any;
ref?: any;
loop?: any;
pause?: any;
reset?: any;
cancel?: any;
reverse?: any;
immediate?: any;
default?: any;
delay?: any;
items?: any;
trail?: any;
sort?: any;
expires?: any;
initial?: any;
enter?: any;
update?: any;
leave?: any;
children?: any;
keys?: any;
callId?: any;
parentId?: any;
}
interface ReservedEventProps {
onProps?: any;
onStart?: any;
onChange?: any;
onPause?: any;
onResume?: any;
onRest?: any;
onResolve?: any;
onDestroyed?: any;
}
/**
* Pick the properties of these object props...
*
* "to", "from", "initial", "enter", "update", "leave"
*
* ...as well as any forward props.
*/
type PickAnimated<Props extends object, Fwd = true> = unknown & ([Props] extends [Any] ? Lookup : [object] extends [Props] ? Lookup : ObjectFromUnion<Props extends {
from: infer From;
} ? From extends () => any ? ReturnType<From> : ObjectType<From> : TransitionKey & keyof Props extends never ? ToValues<Props, Fwd> : TransitionValues<Props>>);
/**
* Pick the values of the `to` prop. Forward props are *not* included.
*/
type ToValues<Props extends object, AndForward = true> = unknown & (AndForward extends true ? ForwardProps<Props> : unknown) & (Props extends {
to?: any;
} ? Exclude<Props['to'], Function | ReadonlyArray<any>> extends infer To ? ForwardProps<[To] extends [object] ? To : Partial<Extract<To, object>>> : never : unknown);
interface ControllerUpdateFn<State extends Lookup = Lookup> {
(i: number, ctrl: Controller<State>): ControllerUpdate<State> | Falsy;
}
interface SpringRef<State extends Lookup = Lookup> {
(props?: ControllerUpdate<State> | ControllerUpdateFn<State>): AsyncResult<Controller<State>>[];
current: Controller<State>[];
/** Add a controller to this ref */
add(ctrl: Controller<State>): void;
/** Remove a controller from this ref */
delete(ctrl: Controller<State>): void;
/** Pause all animations. */
pause(): this;
/** Pause animations for the given keys. */
pause(keys: OneOrMore<string>): this;
/** Pause some or all animations. */
pause(keys?: OneOrMore<string>): this;
/** Resume all animations. */
resume(): this;
/** Resume animations for the given keys. */
resume(keys: OneOrMore<string>): this;
/** Resume some or all animations. */
resume(keys?: OneOrMore<string>): this;
/** Update the state of each controller without animating. */
set(values: Partial<State>): void;
/** Update the state of each controller without animating based on their passed state. */
set(values: (index: number, ctrl: Controller<State>) => Partial<State>): void;
/** Start the queued animations of each controller. */
start(): AsyncResult<Controller<State>>[];
/** Update every controller with the same props. */
start(props: ControllerUpdate<State>): AsyncResult<Controller<State>>[];
/** Update controllers based on their state. */
start(props: ControllerUpdateFn<State>): AsyncResult<Controller<State>>[];
/** Start animating each controller. */
start(props?: ControllerUpdate<State> | ControllerUpdateFn<State>): AsyncResult<Controller<State>>[];
/** Stop all animations. */
stop(): this;
/** Stop animations for the given keys. */
stop(keys: OneOrMore<string>): this;
/** Cancel all animations. */
stop(cancel: boolean): this;
/** Cancel animations for the given keys. */
stop(cancel: boolean, keys: OneOrMore<string>): this;
/** Stop some or all animations. */
stop(keys?: OneOrMore<string>): this;
/** Cancel some or all animations. */
stop(cancel: boolean, keys?: OneOrMore<string>): this;
/** Add the same props to each controller's update queue. */
update(props: ControllerUpdate<State>): this;
/** Generate separate props for each controller's update queue. */
update(props: ControllerUpdateFn<State>): this;
/** Add props to each controller's update queue. */
update(props: ControllerUpdate<State> | ControllerUpdateFn<State>): this;
_getProps(arg: ControllerUpdate<State> | ControllerUpdateFn<State>, ctrl: Controller<State>, index: number): ControllerUpdate<State> | Falsy;
}
declare const SpringRef: <State extends Lookup = Lookup<any>>() => SpringRef<State>;
/**
* Used to orchestrate animation hooks in sequence with one another.
* This is best used when you specifically want to orchestrate different
* types of animation hook e.g. `useSpring` & `useTransition` in
* sequence as opposed to multiple `useSpring` hooks.
*
*
* ```jsx
* export const MyComponent = () => {
* //...
* useChain([springRef, transitionRef])
* //...
* }
* ```
*
* @param refs – An array of `SpringRef`s.
* @param timeSteps – Optional array of numbers that define the
* delay between each animation from 0-1. The length should correlate
* to the length of `refs`.
* @param timeFrame – Optional number that defines the total duration
*
* @public
*/
declare function useChain(refs: ReadonlyArray<SpringRef>, timeSteps?: number[], timeFrame?: number): void;
/**
* The props that `useSpring` recognizes.
*/
type UseSpringProps<Props extends object = any> = unknown & PickAnimated<Props> extends infer State ? State extends Lookup ? Remap<ControllerUpdate<State> & {
/**
* Used to access the imperative API.
*
* When defined, the render animation won't auto-start.
*/
ref?: SpringRef<State>;
}> : never : never;
/**
* The `props` function is only called on the first render, unless
* `deps` change (when defined). State is inferred from forward props.
*/
declare function useSpring<Props extends object>(props: Function | (() => (Props & Valid<Props, UseSpringProps<Props>>) | UseSpringProps), deps?: readonly any[] | undefined): PickAnimated<Props> extends infer State ? State extends Lookup ? [SpringValues<State>, SpringRef<State>] : never : never;
/**
* Updated on every render, with state inferred from forward props.
*/
declare function useSpring<Props extends object>(props: (Props & Valid<Props, UseSpringProps<Props>>) | UseSpringProps): SpringValues<PickAnimated<Props>>;
/**
* Updated only when `deps` change, with state inferred from forward props.
*/
declare function useSpring<Props extends object>(props: (Props & Valid<Props, UseSpringProps<Props>>) | UseSpringProps, deps: readonly any[] | undefined): PickAnimated<Props> extends infer State ? State extends Lookup ? [SpringValues<State>, SpringRef<State>] : never : never;
type UseSpringsProps<State extends Lookup = Lookup> = unknown & ControllerUpdate<State> & {
ref?: SpringRef<State>;
};
/**
* When the `deps` argument exists, the `props` function is called whenever
* the `deps` change on re-render.
*
* Without the `deps` argument, the `props` function is only called once.
*/
declare function useSprings<Props extends UseSpringProps>(length: number, props: (i: number, ctrl: Controller) => Props, deps?: readonly any[]): PickAnimated<Props> extends infer State ? State extends Lookup<any> ? [SpringValues<State>[], SpringRef<State>] : never : never;
/**
* Animations are updated on re-render.
*/
declare function useSprings<Props extends UseSpringsProps>(length: number, props: Props[] & UseSpringsProps<PickAnimated<Props>>[]): SpringValues<PickAnimated<Props>>[];
/**
* When the `deps` argument exists, you get the `update` and `stop` function.
*/
declare function useSprings<Props extends UseSpringsProps>(length: number, props: Props[] & UseSpringsProps<PickAnimated<Props>>[], deps: DependencyList): PickAnimated<Props> extends infer State ? State extends Lookup<any> ? [SpringValues<State>[], SpringRef<State>] : never : never;
declare const useSpringRef: <State extends Lookup = Lookup<any>>() => SpringRef<State>;
/**
* Creates a constant single `SpringValue` that can be interacted
* with imperatively. This is an advanced API and does not react
* to updates from the parent component e.g. passing a new initial value
*
*
* ```jsx
* export const MyComponent = () => {
* const opacity = useSpringValue(1)
*
* return <animated.div style={{ opacity }} />
* }
* ```
*
* @param initial – The initial value of the `SpringValue`.
* @param props – Typically the same props as `useSpring` e.g. `config`, `loop` etc.
*
* @public
*/
declare const useSpringValue: <T>(initial: Exclude<T, object>, props?: SpringUpdate<T>) => SpringValue<T>;
type UseTrailProps<Props extends object = any> = UseSpringProps<Props>;
declare function useTrail<Props extends object>(length: number, props: (i: number, ctrl: Controller) => UseTrailProps | (Props & Valid<Props, UseTrailProps<Props>>), deps?: readonly any[]): PickAnimated<Props> extends infer State ? State extends Lookup<any> ? [SpringValues<State>[], SpringRef<State>] : never : never;
/**
* This hook is an abstraction around `useSprings` and is designed to
* automatically orchestrate the springs to stagger one after the other
*
* ```jsx
* export const MyComponent = () => {
* const trails = useTrail(3, {opacity: 0})
*
* return trails.map(styles => <animated.div style={styles} />)
* }
* ```
*
* @param length – The number of springs you want to create
* @param propsArg – The props to pass to the internal `useSprings` hook,
* therefore is the same as `useSprings`.
*
* @public
*/
declare function useTrail<Props extends object>(length: number, props: UseTrailProps | (Props & Valid<Props, UseTrailProps<Props>>)): SpringValues<PickAnimated<Props>>[];
/**
* This hook is an abstraction around `useSprings` and is designed to
* automatically orchestrate the springs to stagger one after the other
*
* ```jsx
* export const MyComponent = () => {
* const trails = useTrail(3, {opacity: 0}, [])
*
* return trails.map(styles => <animated.div style={styles} />)
* }
* ```
*
* @param length – The number of springs you want to create
* @param propsArg – The props to pass to the internal `useSprings` hook,
* therefore is the same as `useSprings`.
* @param deps – The optional array of dependencies to pass to the internal
* `useSprings` hook, therefore is the same as `useSprings`.
*
* @public
*/
declare function useTrail<Props extends object>(length: number, props: UseTrailProps | (Props & Valid<Props, UseTrailProps<Props>>), deps: readonly any[]): PickAnimated<Props> extends infer State ? State extends Lookup<any> ? [SpringValues<State>[], SpringRef<State>] : never : never;
declare function useTransition<Item, Props extends object>(data: OneOrMore<Item>, props: () => UseTransitionProps<Item> | (Props & Valid<Props, UseTransitionProps<Item>>), deps?: any[]): PickAnimated<Props> extends infer State ? State extends Lookup ? [TransitionFn<Item, PickAnimated<Props>>, SpringRef<State>] : never : never;
declare function useTransition<Item, Props extends object>(data: OneOrMore<Item>, props: UseTransitionProps<Item> | (Props & Valid<Props, UseTransitionProps<Item>>)): TransitionFn<Item, PickAnimated<Props>>;
declare function useTransition<Item, Props extends object>(data: OneOrMore<Item>, props: UseTransitionProps<Item> | (Props & Valid<Props, UseTransitionProps<Item>>), deps: any[] | undefined): PickAnimated<Props> extends infer State ? State extends Lookup ? [TransitionFn<Item, State>, SpringRef<State>] : never : never;
interface UseScrollOptions extends Omit<SpringProps, 'to' | 'from'> {
container?: MutableRefObject<HTMLElement>;
}
/**
* A small utility abstraction around our signature useSpring hook. It's a great way to create
* a scroll-linked animation. With either the raw value of distance or a 0-1 progress value.
* You can either use the scroll values of the whole document, or just a specific element.
*
*
```jsx
import { useScroll, animated } from '@react-spring/web'
function MyComponent() {
const { scrollYProgress } = useScroll()
return (
<animated.div style={{ opacity: scrollYProgress }}>
Hello World
</animated.div>
)
}
```
*
* @param {UseScrollOptions} useScrollOptions options for the useScroll hook.
* @param {MutableRefObject<HTMLElement>} useScrollOptions.container the container to listen to scroll events on, defaults to the window.
*
* @returns {SpringValues<{scrollX: number; scrollY: number; scrollXProgress: number; scrollYProgress: number}>} SpringValues the collection of values returned from the inner hook
*/
declare const useScroll: ({ container, ...springOptions }?: UseScrollOptions) => SpringValues<{
scrollX: number;
scrollY: number;
scrollXProgress: number;
scrollYProgress: number;
}>;
interface UseResizeOptions extends Omit<SpringProps, 'to' | 'from'> {
container?: MutableRefObject<HTMLElement | null | undefined>;
}
/**
* A small abstraction around the `useSpring` hook. It returns a `SpringValues`
* object with the `width` and `height` of the element it's attached to & doesn't
* necessarily have to be attached to the window, by passing a `container` you
* can observe that element's size instead.
*
```jsx
import { useResize, animated } from '@react-spring/web'
function MyComponent() {
const { width } = useResize()
return (
<animated.div style={{ width }}>
Hello World
</animated.div>
)
}
```
*
* @param {UseResizeOptions} UseResizeOptions options for the useScroll hook.
* @param {MutableRefObject<HTMLElement>} UseResizeOptions.container the container to listen to scroll events on, defaults to the window.
*
* @returns {SpringValues<{width: number; height: number;}>} SpringValues the collection of values returned from the inner hook
*/
declare const useResize: ({ container, ...springOptions }: UseResizeOptions) => SpringValues<{
width: number;
height: number;
}>;
interface IntersectionArgs extends Omit<IntersectionObserverInit, 'root' | 'threshold'> {
root?: React.MutableRefObject<HTMLElement>;
once?: boolean;
amount?: 'any' | 'all' | number | number[];
}
declare function useInView(args?: IntersectionArgs): [RefObject<any>, boolean];
declare function useInView<Props extends object>(
/**
* TODO: make this narrower to only accept reserved props.
*/
props: () => Props & Valid<Props, UseSpringProps<Props>>, args?: IntersectionArgs): PickAnimated<Props> extends infer State ? State extends Lookup ? [RefObject<any>, SpringValues<State>] : never : never;
type SpringComponentProps<State extends object = UnknownProps> = unknown & UseSpringProps<State> & {
children: (values: SpringValues<State>) => React.JSX.Element | null;
};
declare function Spring<State extends object>(props: {
from: State;
to?: SpringChain<NoInfer<State>> | SpringToFn<NoInfer<State>>;
} & Omit<SpringComponentProps<NoInfer<State>>, 'from' | 'to'>): JSX.Element | null;
declare function Spring<State extends object>(props: {
to: State;
} & Omit<SpringComponentProps<NoInfer<State>>, 'to'>): JSX.Element | null;
type TrailComponentProps<Item, Props extends object = any> = unknown & UseSpringProps<Props> & {
items: readonly Item[];
children: (item: NoInfer<Item>, index: number) => ((values: SpringValues<PickAnimated<Props>>) => ReactNode) | Falsy;
};
declare function Trail<Item, Props exten