diff --git a/react-motion/react-motion-tests.tsx b/react-motion/react-motion-tests.tsx index 0ff53dae4a..db7a28c921 100644 --- a/react-motion/react-motion-tests.tsx +++ b/react-motion/react-motion-tests.tsx @@ -3,7 +3,7 @@ /// import * as React from 'react'; -import {Motion, spring} from 'react-motion'; +import {StaggeredMotion, Motion, spring, TransitionMotion, TransitionPlainStyle, TransitionStyle, Style, PlainStyle} from 'react-motion'; class Root extends React.Component<{}, {}> { @@ -15,3 +15,88 @@ class Root extends React.Component<{}, {}> { ); } } + +class TransitionTest extends React.Component<{}, {}> { + render() { + return ( + + {this.renderItems.bind(this)} + + ); + } + + getDefaultStyles(): TransitionPlainStyle[] { + return [1, 2, 3].map(num => { + const style: PlainStyle = { + height: 0 + }; + return { + key: `${num}`, + data: num, + style: style + }; + }) + } + + getStyles(): TransitionStyle[] { + return [1, 2, 3].map(num => { + const style: Style = { + height: spring(10) + }; + return { + key: `${num}`, + data: num, + style: style + } + }); + } + + renderItems(interpolatedItems: TransitionStyle[]): JSX.Element { + return ( +
+ {interpolatedItems.map(config => { + return ( +
+ style={{ height: config.style['height'] }} + > + {config.data} +
+ ); + }) } +
+ ) + } +} + +class StaggeredTest extends React.Component<{}, {}> { + render() { + return ( + + + ) + } + + getStyles(prevInterpolatedStyles: PlainStyle[]): Style[] { + return prevInterpolatedStyles.map((prevStyle, index) => { + const style: Style = {}; + style['h'] = (index === 0) ? spring(100) : spring(prevInterpolatedStyles[index - 1]['h']); + return style; + }) + } + + renderItems(interpolatedItems: PlainStyle[]): JSX.Element { + return ( +
+ {interpolatedItems.map((style, index) => { + return ( +
+ ) + })} +
+ ) + } +} diff --git a/react-motion/react-motion.d.ts b/react-motion/react-motion.d.ts index f868d084d2..627717d118 100644 --- a/react-motion/react-motion.d.ts +++ b/react-motion/react-motion.d.ts @@ -1,12 +1,13 @@ // Type definitions for react-motion // Project: https://github.com/chenglou/react-motion -// Definitions by: Stepan Mikhaylyuk +// Definitions by: Stepan Mikhaylyuk , Alexey Svetliakov // Definitions: https://github.com/borisyankov/DefinitelyTyped /// declare module "react-motion" { - import { Component } from 'react'; + import { Component, ReactElement } from 'react'; + // your typical style object given in props. Maps to a number or a spring config export type Style = { [key: string]: number | OpaqueConfig }; @@ -16,37 +17,82 @@ declare module "react-motion" { // internal velocity object. Similar to PlainStyle, but whose numbers represent // speed. Might be exposed one day. export type Velocity = { [key: string]: number }; + + /** + * Spring additional configuration + */ interface SpringHelperConfig { - stiffness: number; - damping: number; /** - * Specifies both the rounding of the interpolated value and the speed (internal). - */ + * Specified stiffness + * @defaults 170 + */ + stiffness?: number; + /** + * Specifies damping + * @defaults 26 + */ + damping?: number; + /** + * Specifies both the rounding of the interpolated value and the speed (internal). + * @defaults 0.01 + */ precision?: number; - // TODO: add onRest. Not public yet } + export interface OpaqueConfig { val: number; stiffness: number; damping: number; precision: number; - // TODO: add onRest. Not public yet } + /** + * properties + */ interface MotionProps { - defaultStyle?: any; - style: any; + /** + * The default style. Being ignored on subsequent renders + * @default Object with same keys as in style whose values are the initial numbers you're interpolating on + */ + defaultStyle?: PlainStyle; + /** + * Object that maps to either number or opaque config returned by spring(). + * Must keep same keys throughout component's existence + */ + style: Style; + /** + * Callback with your interpolated styles. Must return one react element to render + * @param interpolatedStyle + */ + children?: (interpolatedStyle: PlainStyle) => ReactElement; + /** + * The callback that fires when the animation comes to a rest. + */ + onRest?: () => void; } export class Motion extends Component { } // === TransitionMotion === interface TransitionStyle { - key: any; // unique ID to identify component across render animations - data?: any; // optional data you want to carry along the style, e.g. itemText + /** + * The ID that TransitionMotion uses to track which configuration is which across renders, even when things are reordered. + * Typically reused as the component key when you map over the interpolated styles. + */ + key: string; + /** + * Anything you'd like to carry along. Will be preserved on re-renders until key off + */ + data?: any; + /** + * Actual starting style configuration + */ style: Style; // actual style you're passing } + /** + * Default style for transition + */ interface TransitionPlainStyle { key: any; data?: any; @@ -54,18 +100,43 @@ declare module "react-motion" { style: PlainStyle; } type InterpolateFunction = (previousInterpolatedStyles?: Array) => Array; - type Styles = Array | InterpolateFunction; + /** + * Transition properties + */ interface TransitionProps { + /** + * Default styles on first render + */ defaultStyles?: Array; - styles: Styles; - children: (interpolatedStyles: Array) => __React.ReactElement; + /** + * Styles to interpolate. Accepts array of TransitionStyle objects or interpolated function similar as for + * + */ + styles: Array | InterpolateFunction; + children?: (interpolatedStyles: Array) => ReactElement; + /** + * Triggers when new elements appears + * @param styleThatEntered + */ willEnter?: (styleThatEntered: TransitionStyle) => PlainStyle; - willLeave?: (styleThatLeft: TransitionStyle) => Style; + /** + * Triggers when new element disappears + * @param styleThatLeft + */ + willLeave?: (styleThatLeft: TransitionStyle) => Style | void; } - export class TransitionMotion extends Component { } + export class TransitionMotion extends Component { } + interface StaggeredMotionProps { + /** + * Default styles + */ defaultStyles?: Array; + /** + * Styles to interpolate + * @param previousInterpolatedStyles The previously interpolating (array of) styles (undefined at first render, unless defaultStyles is provided). + */ styles: (previousInterpolatedStyles?: Array) => Array