solid-spring
Version:
Like react-spring, but for SolidJS
1,163 lines (1,147 loc) • 46.4 kB
TypeScript
import { Accessor, JSX } from 'solid-js';
/**
* MIT License
* Copyright (c) Alec Larson
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* Extend this class for automatic TypeScript support when passing this
* value to `fluids`-compatible libraries.
*/
declare const $get: unique symbol;
declare const $observers: unique symbol;
/** An event sent to `FluidObserver` objects. */
interface FluidEvent<T = any> {
type: string;
parent: FluidValue<T>;
}
/** Add the `FluidValue` type to every property. */
declare type FluidProps<T> = T extends object ? {
[P in keyof T]: T[P] | FluidValue<Exclude<T[P], void>>;
} : unknown;
/** An observer of `FluidValue` objects. */
declare type FluidObserver<E extends FluidEvent = any> = {
eventObserved(event: E): void;
} | {
(event: E): void;
};
declare abstract class FluidValue<T = any, E extends FluidEvent<T> = any> {
private [$get];
private [$observers]?;
constructor(get?: () => T);
/** Get the current value. */
protected get?(): T;
/** Called after an observer is added. */
protected observerAdded?(count: number, observer: FluidObserver<E>): void;
/** Called after an observer is removed. */
protected observerRemoved?(count: number, observer: FluidObserver<E>): 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 type Animatable<T = any> = T extends number ? number : T extends string ? string : T extends ReadonlyArray<number | string> ? Array<number | string> extends T ? ReadonlyArray<number | string> : {
[P in keyof T]: Animatable<T[P]>;
} : never;
/** Ensure each type of `T` is an array */
declare type Arrify<T> = [T, T] extends [infer T, infer DT] ? DT extends ReadonlyArray<any> ? Array<DT[number]> extends DT ? ReadonlyArray<T extends ReadonlyArray<infer U> ? U : T> : DT : ReadonlyArray<T extends ReadonlyArray<infer U> ? U : T> : never;
declare type ExtrapolateType = 'identity' | 'clamp' | 'extend';
/** Better type errors for overloads with generic types */
declare type Constrain<T, U> = [T] extends [Any] ? U : [T] extends [U] ? T : U;
declare type EasingFunction$1 = (t: number) => number;
declare type InterpolatorConfig<Out = Animatable> = {
/**
* What happens when the spring goes below its target value.
*
* - `extend` continues the interpolation past the target value
* - `clamp` limits the interpolation at the max value
* - `identity` sets the value to the interpolation input as soon as it hits the boundary
*
* @default 'extend'
*/
extrapolateLeft?: ExtrapolateType;
/**
* What happens when the spring exceeds its target value.
*
* - `extend` continues the interpolation past the target value
* - `clamp` limits the interpolation at the max value
* - `identity` sets the value to the interpolation input as soon as it hits the boundary
*
* @default 'extend'
*/
extrapolateRight?: ExtrapolateType;
/**
* What happens when the spring exceeds its target value.
* Shortcut to set `extrapolateLeft` and `extrapolateRight`.
*
* - `extend` continues the interpolation past the target value
* - `clamp` limits the interpolation at the max value
* - `identity` sets the value to the interpolation input as soon as it hits the boundary
*
* @default 'extend'
*/
extrapolate?: ExtrapolateType;
/**
* Input ranges mapping the interpolation to the output values.
*
* @example
*
* range: [0, 0.5, 1], output: ['yellow', 'orange', 'red']
*
* @default [0,1]
*/
range?: readonly number[];
/**
* Output values from the interpolation function. Should match the length of the `range` array.
*/
output: readonly Constrain<Out, Animatable>[];
/**
* Transformation to apply to the value before interpolation.
*/
map?: (value: number) => number;
/**
* Custom easing to apply in interpolator.
*/
easing?: EasingFunction$1;
};
declare type InterpolatorArgs<In = any, Out = any> = [InterpolatorFn<Arrify<In>, Out>] | [InterpolatorConfig<Out>] | [
readonly number[],
readonly Constrain<Out, Animatable>[],
(ExtrapolateType | undefined)?
];
declare type InterpolatorFn<In, Out> = (...inputs: Arrify<In>) => Out;
/**
* 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<In = any, Out = any> extends FrameValue<Out> {
/** 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<In, Out>;
/** The inputs which are currently animating */
protected _active: Set<FluidValue<any, any>>;
constructor(
/** The source of input values */
source: unknown, args: InterpolatorArgs<In, Out>);
advance(_dt?: number): void;
protected _get(): Out;
protected _start(): void;
protected _attach(): void;
protected _detach(): void;
/** @internal */
eventObserved(event: FrameValue.Event): void;
}
declare abstract class Animated<T = any> {
/** The cache of animated values */
protected payload?: Payload;
constructor();
/** Get the current value. Pass `true` for only animated values. */
abstract getValue(animated?: boolean): T;
/** Set the current value. Returns `true` if the value changed. */
abstract setValue(value: T): boolean | void;
/** Reset any animation state. */
abstract reset(goal?: T): void;
/** Get every `AnimatedValue` used by this node. */
getPayload(): Payload;
}
declare type Payload = readonly AnimatedValue[];
/** An animated number or a native attribute value */
declare class AnimatedValue<T = any> extends Animated {
protected _value: T;
done: boolean;
elapsedTime: number;
lastPosition: number;
lastVelocity?: number | null;
v0?: number | null;
durationProgress: number;
constructor(_value: T);
/** @internal */
static create(value: any): AnimatedValue<any>;
getPayload(): Payload;
getValue(): T;
setValue(value: T, step?: number): boolean;
reset(): void;
}
/** 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>> {
}
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;
/** 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<any> = Lookup<any>>() => SpringRef<State>;
/** 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<((result: AnimationResult<SpringValue<State>>, ctrl: Controller<State>, item?: any) => void) | ((result: AnimationResult<SpringValue<State>>, ctrl: Controller<State>, item: any) => void), AnimationResult<any>>;
onChange: Map<((result: AnimationResult<SpringValue<State>>, ctrl: Controller<State>, item?: any) => void) | ((result: AnimationResult<SpringValue<State>>, ctrl: Controller<State>, item: any) => void), AnimationResult<any>>;
onRest: Map<((result: AnimationResult<SpringValue<State>>, ctrl: Controller<State>, item?: any) => void) | ((result: AnimationResult<SpringValue<State>>, ctrl: Controller<State>, item: any) => void), 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;
}
declare type AsyncTo<T> = SpringChain<T> | SpringToFn<T>;
/** @internal */
declare type InferState<T extends Readable> = T extends Controller<infer State> ? State : T extends SpringValue<infer U> ? U : unknown;
/** @internal */
declare type InferProps<T extends Readable> = T extends Controller<infer State> ? ControllerUpdate<State> : T extends SpringValue<infer U> ? SpringUpdate<U> : Lookup;
/** @internal */
declare 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;
}
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;
}
declare class Any {
private _;
}
declare type VelocityProp<T = any> = T extends ReadonlyArray<number | string> ? number[] : number;
/** The flush function that handles `start` calls */
declare type ControllerFlushFn<T extends Controller<any> = Controller> = (ctrl: T, queue: ControllerQueue<InferState<T>>) => AsyncResult<T>;
/** Override the property types of `A` with `B` and merge any new properties */
declare type Merge<A, B> = Remap<{
[P in keyof A]: P extends keyof B ? B[P] : A[P];
} & Omit<B, keyof A>>;
/** Unwrap any `FluidValue` object types */
declare type RawValues<T extends object> = {
[P in keyof T]: T[P] extends FluidValue<infer U> ? U : T[P];
};
declare type NonObject<T> = Extract<T, string | number | ReadonlyArray<string | number>> | Exclude<T, object | void>;
/** The promised result of an animation. */
declare type AsyncResult<T extends Readable = any> = Promise<AnimationResult<T>>;
interface Lookup<T = any> {
[key: string]: T;
}
/** Convert a union to an intersection */
declare type Intersect<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
/** Intersect a union of objects but merge property types with _unions_ */
declare type ObjectFromUnion<T extends object> = Remap<{
[P in keyof Intersect<T>]: T extends infer U ? P extends keyof U ? U[P] : never : never;
}>;
/** Ensure the given type is an object type */
declare type ObjectType<T> = T extends object ? T : {};
/** The phases of a `useTransition` item */
declare type TransitionKey = "initial" | "enter" | "update" | "leave";
/**
* Extract a union of animated values from a set of `useTransition` props.
*/
declare 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>, {}>>>;
/**
* Pick the values of the `to` prop. Forward props are *not* included.
*/
declare 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);
/**
* Pick the properties of these object props...
*
* "to", "from", "initial", "enter", "update", "leave"
*
* ...as well as any forward props.
*/
declare 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>>);
/** Return a union type of every key whose `T` value is incompatible with its `U` value */
declare type InvalidKeys<T, U> = {
[P in keyof T & keyof U]: T[P] extends U[P] ? never : P;
}[keyof T & keyof U];
/** Replace the type of each `P` property with `never` */
declare type NeverProps<T, P extends keyof T> = Remap<Pick<T, Exclude<keyof T, P>> & {
[K in P]: never;
}>;
/** Replace the type of each `T` property with `never` (unless compatible with `U`) */
declare type Valid<T, U> = NeverProps<T, InvalidKeys<T, U>>;
interface Timeout {
time: number;
handler: () => void;
cancel: () => void;
}
declare type EasingFunction = (t: number) => number;
declare const config: {
readonly default: {
readonly tension: 170;
readonly friction: 26;
};
readonly gentle: {
readonly tension: 120;
readonly friction: 14;
};
readonly wobbly: {
readonly tension: 180;
readonly friction: 12;
};
readonly stiff: {
readonly tension: 210;
readonly friction: 20;
};
readonly slow: {
readonly tension: 280;
readonly friction: 60;
};
readonly molasses: {
readonly tension: 280;
readonly friction: 120;
};
};
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.
*/
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.
*/
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.
*
* Defaults to 1
*/
damping: number;
/**
* Higher mass means more friction is required to slow down.
*
* Defaults to 1, which works fine most of the time.
*/
mass: number;
/**
* The initial velocity of one or more values.
*/
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).
*/
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.
*/
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.
*/
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. */
declare type SpringConfig = Partial<AnimationConfig>;
/**
* 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`.
*/
declare type IsPlainObject<T> = T extends ReadonlyArray<any> ? Any : T extends object ? object : Any;
declare type StringKeys<T> = T extends IsPlainObject<T> ? string & keyof T : string;
declare type OneOrMore<T> = T | readonly T[];
/** For props that can be set on a per-key basis. */
declare type MatchProp<T> = boolean | OneOrMore<StringKeys<T>> | ((key: StringKeys<T>) => boolean);
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>;
}
/** Intersected with other object types to allow for unknown properties */
interface UnknownProps extends Lookup<unknown> {
}
declare type GoalValue<T> = T | FluidValue<T> | UnknownProps | null | undefined;
/** A set of values for a `Controller` to animate from/to. */
declare type GoalValues<T extends Lookup> = FluidProps<T> extends infer Props ? {
[P in keyof Props]?: Props[P] | null;
} : never;
declare type Falsy = false | null | undefined;
/**
* 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.
*/
declare type GoalProp<T> = [T] extends [IsPlainObject<T>] ? GoalValues<T> | Falsy : GoalValue<T>;
/** Try to simplify `&` out of an object type */
declare type Remap<T> = {} & {
[P in keyof T]: T[P];
};
/**
* 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.
*/
declare type InlineToProps<T = any> = Remap<GoalValues<T> & {
to?: undefined;
}>;
declare type StartFn<T> = InferTarget<T> extends {
start: infer T;
} ? T : never;
declare type StopFn<T> = InferTarget<T> extends {
stop: infer T;
} ? T : never;
/**
* 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;
}
/**
* 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>;
}
declare type ControllerUpdate<State extends Lookup = Lookup, Item = undefined> = unknown & ToProps<State> & ControllerProps<State, Item>;
/** A value that any `SpringValue` or `Controller` can animate to. */
declare type SpringTo<T = any> = ([T] extends [IsPlainObject<T>] ? never : T | FluidValue<T>) | SpringChain<T> | SpringToFn<T> | Falsy;
/** A serial queue of spring updates. */
interface SpringChain<T = any> extends Array<[
T
] extends [IsPlainObject<T>] ? ControllerUpdate<T> : SpringTo<T> | SpringUpdate<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.
*/
declare type ToProps<T = any> = {
to?: GoalProp<T> | SpringToFn<T> | SpringChain<T>;
} | ([T] extends [IsPlainObject<T>] ? InlineToProps<T> : never);
declare type SpringUpdate<T = any> = ToProps<T> & SpringProps<T>;
declare type LoopProp<T extends object> = boolean | T | (() => boolean | T);
/** Event props can be customized per-key. */
declare type EventProp<T> = T | Lookup<T | undefined>;
declare type SpringWrap<T> = [
Exclude<T, FluidValue>,
Extract<T, readonly any[]>
] extends [object | void, never] ? never : SpringValue<Exclude<T, FluidValue | void>> | Extract<T, void>;
declare type SpringValues<T extends Lookup = any> = [T] extends [Any] ? Lookup<SpringValue<unknown> | undefined> : {
[P in keyof T]: SpringWrap<T[P]>;
};
interface ReservedEventProps {
onProps?: any;
onStart?: any;
onChange?: any;
onPause?: any;
onResume?: any;
onRest?: any;
onResolve?: any;
onDestroyed?: any;
}
/** @internal */
interface AnimationRange<T> {
to: T | FluidValue<T> | undefined;
from: T | FluidValue<T> | undefined;
}
/** @internal */
declare type AnimationResolver<T extends Readable> = (result: AnimationResult<T> | AsyncResult<T>) => void;
/** @internal */
declare type PickEventFns<T> = {
[P in Extract<keyof T, EventKey>]?: Extract<T[P], Function>;
};
/** @internal */
declare type EventKey = Exclude<keyof ReservedEventProps, "onResolve" | "onDestroyed">;
/** @internal */
interface AnimationTarget<T = any> extends Readable<T> {
start(props: any): AsyncResult<this>;
stop: Function;
item?: unknown;
}
/** @internal */
declare type InferTarget<T> = T extends object ? T extends ReadonlyArray<number | string> ? SpringValue<T> : Controller<T> : SpringValue<T>;
/** @internal */
interface Readable<T = any> {
get(): T;
}
/**
* Called after an animation is updated by new props,
* even if the animation remains idle.
*/
declare type OnProps<T = unknown> = (props: Readonly<SpringProps<T>>, spring: SpringValue<T>) => void;
/** 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;
}
declare type EventHandler<TResult extends Readable = any, TSource = unknown, Item = undefined> = Item extends undefined ? (result: AnimationResult<TResult>, ctrl: TSource, item?: Item) => void : (result: AnimationResult<TResult>, ctrl: TSource, item: Item) => void;
/**
* Called before the first frame of every animation.
* From inside the `requestAnimationFrame` callback.
*/
declare type OnStart<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
/** Called when a `SpringValue` changes */
declare type OnChange<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
declare type OnPause<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
declare type OnResume<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
/** Called once the animation comes to a halt */
declare type OnRest<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
declare type OnResolve<TResult extends Readable, TSource, Item = undefined> = EventHandler<TResult, TSource, Item>;
/**
* 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>>>;
}
/**
* 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;
}
/**
* Extract the custom props that are treated like `to` values
*/
declare type ForwardProps<T extends object> = RawValues<Omit<Constrain<T, {}>, keyof ReservedProps>>;
declare type CreateSpringsProps<State extends Lookup = Lookup> = unknown & ControllerUpdate<State> & {
ref?: SpringRef<State>;
};
declare function createSprings<Props extends CreateSpringsProps>(lengthFn: number | (() => number), props: Props[] & CreateSpringsProps<PickAnimated<Props>>[]): Accessor<SpringValues<PickAnimated<Props>>[]> & {
ref: SpringRef<PickAnimated<Props>>;
};
declare function createSprings<Props extends CreateSpringsProps>(lengthFn: number | (() => number), props: (i: number, ctrl: Controller) => Props): Accessor<SpringValues<PickAnimated<Props>>[]> & {
ref: SpringRef<PickAnimated<Props>>;
};
/**
* The props that `useSpring` recognizes.
*/
declare type CreateSpringProps<Props extends object = any> = unknown & PickAnimated<Props> extends infer State ? Remap<ControllerUpdate<State> & {
/**
* Used to access the imperative API.
*
* When defined, the render animation won't auto-start.
*/
ref?: SpringRef<State>;
}> : never;
declare function createSpring<Props extends object>(props: () => (Props & Valid<Props, CreateSpringProps<Props>>) | CreateSpringProps<Props>): Accessor<SpringValues<PickAnimated<Props>>> & {
ref: SpringRef<PickAnimated<Props>>;
};
declare function createSpring<Props extends object>(props: (Props & Valid<Props, CreateSpringProps<Props>>) | CreateSpringProps<Props>): Accessor<SpringValues<PickAnimated<Props>>> & {
ref: SpringRef<PickAnimated<Props>>;
};
declare type Angle = number | string;
declare type Length = number | string;
declare type TransformProps = {
transform?: string;
x?: Length;
y?: Length;
z?: Length;
translate?: Length | readonly [Length, Length];
translateX?: Length;
translateY?: Length;
translateZ?: Length;
translate3d?: readonly [Length, Length, Length];
rotate?: Angle;
rotateX?: Angle;
rotateY?: Angle;
rotateZ?: Angle;
rotate3d?: readonly [number, number, number, Angle];
scale?: number | readonly [number, number] | string;
scaleX?: number;
scaleY?: number;
scaleZ?: number;
scale3d?: readonly [number, number, number];
skew?: Angle | readonly [Angle, Angle];
skewX?: Angle;
skewY?: Angle;
matrix?: readonly [number, number, number, number, number, number];
matrix3d?: readonly [
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number
];
};
declare type CSSProperties = JSX.IntrinsicElements["a"]["style"];
declare type StyleProps = Merge<CSSProperties, TransformProps>;
declare type WithAnimated = ((Component: any) => any) & {
[K in keyof JSX.IntrinsicElements]: (props: AnimatedProps<Merge<JSX.IntrinsicElements[K], {
style?: StyleProps;
}>> & FluidProps<{
scrollTop?: number;
scrollLeft?: number;
}>) => JSX.Element;
};
/** The props of an `animated()` component */
declare type AnimatedProps<Props extends object> = {
[P in keyof Props]: P extends "ref" | "key" ? Props[P] : AnimatedProp<Props[P]>;
};
declare type AnimatedProp<T> = [T, T] extends [infer T, infer DT] ? [DT] extends [never] ? never : DT extends void ? undefined : DT extends string | number ? DT | AnimatedLeaf<T> : DT extends object ? [ValidStyleProps<DT>] extends [never] ? DT extends ReadonlyArray<any> ? AnimatedStyles<DT> : DT : AnimatedStyle<T> : DT | AnimatedLeaf<T> : never;
declare type AnimatedStyle<T> = [T, T] extends [infer T, infer DT] ? DT extends void ? undefined : [DT] extends [never] ? never : DT extends string | number ? DT | AnimatedLeaf<T> : DT extends object ? AnimatedObject<DT> : DT | AnimatedLeaf<T> : never;
declare type AnimatedObject<T extends object> = {
[P in keyof T]: AnimatedStyle<T[P]>;
} | (T extends ReadonlyArray<number | string> ? FluidValue<Readonly<T>> : never);
declare type AnimatedStyles<T extends ReadonlyArray<any>> = {
[P in keyof T]: [T[P]] extends [infer DT] ? DT extends object ? [ValidStyleProps<DT>] extends [never] ? DT extends ReadonlyArray<any> ? AnimatedStyles<DT> : DT : {
[P in keyof DT]: AnimatedProp<DT[P]>;
} : DT : never;
};
declare type AnimatedLeaf<T> = NonObject<T> extends infer U ? [U] extends [never] ? never : FluidValue<U> : never;
declare type StylePropKeys = keyof StyleProps;
declare type ValidStyleProps<T extends object> = {
[P in keyof T & StylePropKeys]: T[P] extends StyleProps[P] ? P : never;
}[keyof T & StylePropKeys];
declare const animated: WithAnimated;
declare const to: (source: any, args_0: any) => Interpolation<any, any>;
export { CreateSpringProps, CreateSpringsProps, animated as a, animated, config, createSpring, createSprings, to };