From bd3b9f992ff156c5ee0e48c23dc065d573dcfb76 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 17 Jan 2021 12:40:54 -0500 Subject: [PATCH] feat: let interpolated values be static In some cases, an interpolated variable may be either a static or dynamic value, so supporting both kinds makes things easier. --- packages/core/src/Interpolation.ts | 21 +++++++++++---------- packages/core/src/interpolate.ts | 22 +++++++++++++--------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/packages/core/src/Interpolation.ts b/packages/core/src/Interpolation.ts index 01f47d2b8c..d747d3cf3c 100644 --- a/packages/core/src/Interpolation.ts +++ b/packages/core/src/Interpolation.ts @@ -1,9 +1,4 @@ -import { - Arrify, - InterpolatorArgs, - InterpolatorFn, - OneOrMore, -} from '@react-spring/types' +import { Arrify, InterpolatorArgs, InterpolatorFn } from '@react-spring/types' import { is, raf, @@ -18,6 +13,7 @@ import { callFluidObservers, addFluidObserver, removeFluidObserver, + hasFluidValue, } from '@react-spring/shared' import { FrameValue, isFrameValue } from './FrameValue' @@ -51,7 +47,7 @@ export class Interpolation extends FrameValue { constructor( /** The source of input values */ - readonly source: OneOrMore, + readonly source: unknown, args: InterpolatorArgs ) { super() @@ -106,7 +102,9 @@ export class Interpolation extends FrameValue { 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) @@ -121,7 +119,9 @@ export class Interpolation extends FrameValue { // 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) @@ -148,7 +148,8 @@ export class Interpolation extends FrameValue { // 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 ) } diff --git a/packages/core/src/interpolate.ts b/packages/core/src/interpolate.ts index 1327bc6c51..ad9e9d35ad 100644 --- a/packages/core/src/interpolate.ts +++ b/packages/core/src/interpolate.ts @@ -20,7 +20,11 @@ export const interpolate: Interpolator = (source: any, ...args: [any]) => ( /** Extract the raw value types that are being interpolated */ export type Interpolated> = { - [P in keyof T]: T[P] extends { get(): infer U } ? U : never + [P in keyof T]: T[P] extends infer Element + ? Element extends FluidValue + ? U + : Element + : never } /** @@ -28,18 +32,18 @@ export type Interpolated> = { * The exported `interpolate` function uses this type. */ export interface Interpolator { - // Single parent - ( - parent: FluidValue, - interpolator: InterpolatorFn - ): Interpolation - - // Tuple of parents - , Out>( + // Tuple of parent values + , Out>( parents: In, interpolator: (...args: Interpolated) => Out ): Interpolation + // Single parent value + ( + parent: FluidValue | In, + interpolator: InterpolatorFn + ): Interpolation + // Interpolation config ( parents: OneOrMore,