Skip to content

Commit

Permalink
feat: let interpolated values be static
Browse files Browse the repository at this point in the history
In some cases, an interpolated variable may be either a static or dynamic value, so supporting both kinds makes things easier.
  • Loading branch information
aleclarson committed Jan 17, 2021
1 parent daa71c0 commit bd3b9f9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 19 deletions.
21 changes: 11 additions & 10 deletions packages/core/src/Interpolation.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
Arrify,
InterpolatorArgs,
InterpolatorFn,
OneOrMore,
} from '@react-spring/types'
import { Arrify, InterpolatorArgs, InterpolatorFn } from '@react-spring/types'
import {
is,
raf,
Expand All @@ -18,6 +13,7 @@ import {
callFluidObservers,
addFluidObserver,
removeFluidObserver,
hasFluidValue,
} from '@react-spring/shared'

import { FrameValue, isFrameValue } from './FrameValue'
Expand Down Expand Up @@ -51,7 +47,7 @@ export class Interpolation<In = any, Out = any> extends FrameValue<Out> {

constructor(
/** The source of input values */
readonly source: OneOrMore<FluidValue>,
readonly source: unknown,
args: InterpolatorArgs<In, Out>
) {
super()
Expand Down Expand Up @@ -106,7 +102,9 @@ export class Interpolation<In = any, Out = any> extends FrameValue<Out> {
protected _attach() {
let priority = 1
each(toArray(this.source), source => {
addFluidObserver(source, this)
if (hasFluidValue(source)) {
addFluidObserver(source, this)
}
if (isFrameValue(source)) {
if (!source.idle) {
this._active.add(source)
Expand All @@ -121,7 +119,9 @@ export class Interpolation<In = any, Out = any> extends FrameValue<Out> {
// Stop observing our sources once we have no observers.
protected _detach() {
each(toArray(this.source), source => {
removeFluidObserver(source, this)
if (hasFluidValue(source)) {
removeFluidObserver(source, this)
}
})
this._active.clear()
becomeIdle(this)
Expand All @@ -148,7 +148,8 @@ export class Interpolation<In = any, Out = any> extends FrameValue<Out> {
// our value won't be updated until our parents have updated.
else if (event.type == 'priority') {
this.priority = toArray(this.source).reduce(
(max, source: any) => Math.max(max, (source.priority || 0) + 1),
(highest: number, parent) =>
Math.max(highest, (isFrameValue(parent) ? parent.priority : 0) + 1),
0
)
}
Expand Down
22 changes: 13 additions & 9 deletions packages/core/src/interpolate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,30 @@ export const interpolate: Interpolator = (source: any, ...args: [any]) => (

/** Extract the raw value types that are being interpolated */
export type Interpolated<T extends ReadonlyArray<any>> = {
[P in keyof T]: T[P] extends { get(): infer U } ? U : never
[P in keyof T]: T[P] extends infer Element
? Element extends FluidValue<infer U>
? U
: Element
: never
}

/**
* This interpolates one or more `FluidValue` objects.
* The exported `interpolate` function uses this type.
*/
export interface Interpolator {
// Single parent
<In, Out>(
parent: FluidValue<In>,
interpolator: InterpolatorFn<In, Out>
): Interpolation<Out>

// Tuple of parents
<In extends ReadonlyArray<FluidValue>, Out>(
// Tuple of parent values
<In extends ReadonlyArray<any>, Out>(
parents: In,
interpolator: (...args: Interpolated<In>) => Out
): Interpolation<Out>

// Single parent value
<In, Out>(
parent: FluidValue<In> | In,
interpolator: InterpolatorFn<In, Out>
): Interpolation<Out>

// Interpolation config
<Out>(
parents: OneOrMore<FluidValue>,
Expand Down

0 comments on commit bd3b9f9

Please sign in to comment.