From 67d211d9cdb0c82beab0a1f1a2c53f2cc8f6396c Mon Sep 17 00:00:00 2001 From: Jessica Date: Sat, 22 Dec 2018 18:19:13 +0900 Subject: [PATCH 1/4] Add missing reexports from /hooks --- types/hooks.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/types/hooks.d.ts b/types/hooks.d.ts index b9e80fd06d..d85d9ff182 100644 --- a/types/hooks.d.ts +++ b/types/hooks.d.ts @@ -6,6 +6,10 @@ import { } from './universal' export { SpringConfig, SpringBaseProps, TransitionKeyProps, State } +export { config, interpolate } from './universal' +// hooks are currently web-only +export { animated } from './web' + /** List from `function getForwardProps` in `src/shared/helpers` */ type ExcludedProps = | 'to' From 349c806871d6f3efbf068fcee878371375fe2411 Mon Sep 17 00:00:00 2001 From: Jessica Date: Sat, 22 Dec 2018 18:56:48 +0900 Subject: [PATCH 2/4] Add overloads with CSSProperties for autocomplete aid --- types/hooks.d.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/types/hooks.d.ts b/types/hooks.d.ts index d85d9ff182..1864118ccd 100644 --- a/types/hooks.d.ts +++ b/types/hooks.d.ts @@ -1,3 +1,4 @@ +import { CSSProperties } from 'react' import { SpringConfig, SpringBaseProps, @@ -57,8 +58,8 @@ export interface UseSpringBaseProps extends HooksBaseProps { config?: SpringBaseProps['config'] } -export type UseSpringProps = Merge< - DS, +export type UseSpringProps = Merge< + DS & UseSpringBaseProps, { from?: InferFrom /** @@ -69,6 +70,12 @@ export type UseSpringProps = Merge< > // there's a third value in the tuple but it's not public API (?) +export function useSpring( + values: UseSpringProps +): ForwardedProps +export function useSpring( + getProps: () => UseSpringProps +): [ForwardedProps, SetUpdateFn] export function useSpring( getProps: () => UseSpringProps ): [ForwardedProps, SetUpdateFn] @@ -77,6 +84,14 @@ export function useSpring( ): ForwardedProps // there's a third value in the tuple but it's not public API (?) +export function useTrail( + count: number, + getProps: () => UseSpringProps +): [ForwardedProps[], SetUpdateFn] +export function useTrail( + count: number, + values: UseSpringProps +): ForwardedProps[] // safe to modify (result of .map) export function useTrail( count: number, getProps: () => UseSpringProps @@ -136,6 +151,9 @@ export interface UseTransitionResult { props: ForwardedProps } +export function useTransition( + values: Merge> +): UseTransitionResult>[] // result array is safe to modify export function useTransition( values: Merge> ): UseTransitionResult>[] // result array is safe to modify @@ -183,6 +201,13 @@ export namespace useKeyframes { // fun fact: the state is literally named "undefined" if you're using this overload // the docs are vague but it seems this just loops the one animation forever? + export function spring( + animation: + | ReadonlyArray + | ReadonlyArray> + | KeyframeFn, + initialProps?: UseSpringProps + ): UseSpringKeyframes export function spring( animation: | ReadonlyArray @@ -190,16 +215,38 @@ export namespace useKeyframes { | KeyframeFn, initialProps?: UseSpringProps ): UseSpringKeyframes + // this overload does provide CSSProperties autocompletes, but only as long as config, delay, onRest + // et al are not specified. It's not possible to say TSlotNames can be + // "string but not keyof SpringKeyframeSlotsConfig". + export function spring< + TSlotNames extends string, + TSlots extends Record + >( + slots: TSlots & + Record & + SpringKeyframeSlotsConfig, + initialProps?: UseSpringProps + ): UseSpringKeyframesWithSlots // unfortunately, it's not possible to infer the type of the callback functions (if any are given) - // while also remaining possible to infer the slot names. Callback functions have to be cast with + // while also remaining possible to infer the slot contents. Callback functions have to be cast with // `as useKeyframes.KeyframeFn<{ ... }>`. // it's also not possible to specify the types of the values inside TSlots. This is a mess. - export function spring( + export function spring< + TSlotNames extends string, + TSlots extends Record + >( slots: TSlots & SpringKeyframeSlotsConfig, // also unfortunately not possible to strongly type this either initialProps?: UseSpringProps ): UseSpringKeyframesWithSlots + export function trail( + animation: + | ReadonlyArray + | ReadonlyArray> + | KeyframeFn, + initialProps?: UseSpringProps + ): UseTrailKeyframes export function trail( animation: | ReadonlyArray @@ -207,6 +254,10 @@ export namespace useKeyframes { | KeyframeFn, initialProps?: UseSpringProps ): UseTrailKeyframes + // we unfortunately can't use the same trick in trail as we did in spring to have autocomplete for + // CSS properties, for the same reason the spring trick stops working when a config key is given. + // It would fail as soon as `items`, a required property, is specified, as its value + // (necessarily an array-like) would not be compatible with CSSProperties. export function trail( slots: TSlots & TrailKeyframeSlotsConfig, initialProps?: UseSpringProps From f7c98e50eb15134faaf070d5cac97eaeff88526c Mon Sep 17 00:00:00 2001 From: Jessica Date: Sat, 22 Dec 2018 19:08:46 +0900 Subject: [PATCH 3/4] Add types for useChain --- types/hooks.d.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/types/hooks.d.ts b/types/hooks.d.ts index 1864118ccd..c51f168af1 100644 --- a/types/hooks.d.ts +++ b/types/hooks.d.ts @@ -1,4 +1,4 @@ -import { CSSProperties } from 'react' +import { CSSProperties, RefObject } from 'react' import { SpringConfig, SpringBaseProps, @@ -48,10 +48,26 @@ export type SetUpdateFn = (ds: DS) => void // The hooks do emulate React's 'ref' by accepting { ref?: React.RefObject } and // updating it. However, there are no types for Controller, and I assume it is intentionally so. +// This is a partial interface for Controller that has only the properties needed for useChain to work. +export interface ReactSpringHook { + start(): void + stop(): void +} + +export function useChain(refs: ReadonlyArray>): void +// this looks like it can just be a single overload, but we don't want to allow +// timeFrame to be specifiable when timeSteps is explicitly "undefined" +export function useChain( + refs: ReadonlyArray>, + timeSteps: number[], + timeFrame?: number +): void + export interface HooksBaseProps extends Pick> { // there is an undocumented onKeyframesHalt which passes the controller instance, // so it also cannot be typed unless Controller types are written + ref?: React.RefObject } export interface UseSpringBaseProps extends HooksBaseProps { From e622f17471c49926424033d8c46c2f3c9e78059a Mon Sep 17 00:00:00 2001 From: Jessica Date: Sat, 22 Dec 2018 19:46:17 +0900 Subject: [PATCH 4/4] Fix SpringProps so it extends SpringBaseProps --- types/universal.d.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/types/universal.d.ts b/types/universal.d.ts index 90377e82f5..8339442163 100644 --- a/types/universal.d.ts +++ b/types/universal.d.ts @@ -64,7 +64,7 @@ export interface SpringBaseProps { onStart?(): void } -export interface SpringProps { +export interface SpringProps extends SpringBaseProps { /** * Base styles * @default {} @@ -87,11 +87,6 @@ export interface SpringProps { * Takes a function that receives interpolated styles */ children?: SpringRendererFunc - /** - * Prevents animation if true, you can also pass individual keys - * @default false - */ - immediate?: boolean | string[] | ((key: string) => boolean) /** * Inject props * @default undefined