react-dip
v0.0.3-beta.10
Published
Simple & declarative transition animations for React
Downloads
21
Maintainers
Readme
react-dip
Simple & declarative transition animations for React.
DISCLAIMER
THIS IS EARLY WORK IN PROGRESS AND NOT "RELEASED TO PUBLIC" YET, THOUGH THIS SHOULD HAPPEN ANYTIME SOON.
FEEL FREE TO WATCH 👓, STAR ⭐ OR CONTACT ME TO BE NOTIFIED ABOUT PROGRESS.
TODO: Video / gif here
Why?
Ever wanted to implement one of those incredible designs you find on dribble or Muzli where one element beautifully transforms into another upon page transition? And then realized "But I want my code to stay statefull, decoupled, scalable, declarative", so you ended up with regular "hard cuts" instead? – To me this happend very very often!
react-dip
solves this by providing animated transisions in an effortless way, that just worksTM, by using the FLIP technique.
Table of contents
- Installation
- Quick Start
- Props
- Polyfill
- Examples
- Dip-WHAT???
- How it works (TODO)
- Browser Compatiblity
- Caveats (TODO)
- Inspired by
- Huge Thanks to
- TODOs
Installation
$ yarn add react-dip
# or using npm
$ npm install --save react-dip
Using a module bundler like webpack or parcel, import your depency just as any other:
// Using ES6 modules
import Dip from 'react-dip'
// or using CommonJS modules
var Dip = require('react-dip')
UMD builds are also available via unpkg:
<script src="https://unpkg.com/react-dip/dist/react-dip.umd.min.js" />
Quick Start
The API is as small as possible, almost everything is optional, so you see results immediately. Just wrap your Items in a Dip
import React, {Component} from 'react'
import Dip from 'react-dip'
function Component1() {
return (
<Dip dipId="quickStart" style={{background: 'red'}}>
some content
</Dip>
)
}
function Component2() {
return (
<Dip
dipId="quickStart"
style={{position: 'absolute', top: '100px', background: 'green'}}
>
some other content <br />
etc...
</Dip>
)
}
// use complex state here
// or a routing solution such as react-router
// or connect it to redux, or ustated
export default class MyStatefulParent extends Component {
state = {currentStep: 0}
toggleState = () =>
this.setState(state => ({
currentStep: (state.currentStep + 1) % 2,
}))
render() {
return (
<section>
<h1> Quick Start example </h1>
<button onClick={this.toggleState}>toggle me</button>
{this.state.currentStep === 0 ? <Component1 /> : <Component2 />}
</section>
)
}
}
Note: Using inline styles
as well as absolute
positioning is usually not considered a good way and is applied here for the sake of simplicity.
You can use any type CSS
or CSS-in-JS
styling and fluid
/ flex
/ grid
layout.
Props
The API surface is intetended to be as simple as possible. Only dipId
and children
(or render
) are required props. The rest is optional and helps you fine tuning your animations.
dipId
string
| Required!
The id
that groups two different dip elements. React-dip will only create animated transitions between to Elements with the same dipId
, consider them as potential from- and to-hints.
children
React Element
| Required unless usingrender
-prop!
Content that is rendered as part of that Dip
.
render
function({ref: function(), styles: {}})
| Required unless usingchildren
-prop!
Function that should return the content that is rendered as part of that Dip
. Allows for more advanced pattern and skips the wrapping Element. See render prop for further details.
Warning: <Dip render>
takes precedence over <Dip children>
so don’t use both in the same <Dip />
.
duration
number
| optional, defaults to200
Time in milliseconds the animation will take when transitioning to this dip.
easing
string
| optional, defaults to"ease-out"
Specifies the desired timing function. Accepts the pre-defined values linear
, ease
, ease-in
, ease-out
, and ease-in-out
, or a custom cubic-bezier
value like cubic-bezier(0.42, 0, 0.58, 1)
.
element
string
| optional, defaults to"div"
Specify the desired HTML-tag here (eg. <Dip element="li">
) in case you don't want your children wrapped in a div
.
optInCssStyles
Array(string)
| optional, defaults to an emptyarray
By default react-dip
will morph your components only regarding their sizes and positions using css transforms
which is usually a good default regarding performance.
In case you want to morph more css properties you can specify them here, such as optInCssStyles={["borderRadius", "backgroundColor"]}
. optional
className, id, style, aria-..., role, etc.
default
react
/HTML attributes
| optional
Any provided standard attribute is passed to the child-container.
Polyfill
As some browsers do not support the Web Animations API, we recommend using the web-animations-js Polyfill.
- Install the dependency
$ yarn add web-animations-js
# or using npm
$ npm install --save web-animations-js
- include the dependency into your project.
import('web-animations-js') // We recommend dynamic imports to keep initial bundlesize small
Examples
- Quick Start Example
- Styled Components, render Props & beautiful images
- With React Router and Material-UI
Dip-WHAT???
No DEEEE-EYE-PEEE, just dip your taco into some tasty salsa. 🌮
How it works (TODO)
- Dip-Communication, dipId, from & to
- FLIP
Browser Compatiblity
| Chrome | Firefox | Safari | Edge | IE | iOS | | ------ | ------- | --------------- | --------------- | --------------- | --------------- | | ✅ | ✅ | ✅* | ✅* | ✅* | ✅* |
Caveats (TODO)
- Block-Elements h1 etc
- nested Elements
- transitioning to elements in scrolled lists (via browser back)
- text can get distorted
- styles from nested queries eg: animating
h1
which is styled viasection h1
(might be fixable a little bit, not sure if it is worth though, as it is somehow considered bad practices anyhow?)
Inspired by
- https://github.com/joshwcomeau/react-flip-move
Huge Thanks to
- Kent C. Dodds for his inspiring work, such as kcd-scripts
- Ives van Horne amongst other for CodeSandbox
TODOs
There are tons of ideas for improving react-dip
such as adding fine grained control to your transitions, but the primary goal will stay to keep the API as symple as possible.
To be done before anouncing
- [x] add chapter about polyfilling
- [x] render props (of course)
- [x] add support for custom timing functions
- [ ] add complex examples with renderProps, routing etc.
- [ ] add possibility of declaring alternative components that are shown whilst animating
- [ ] export types for flow and typescript
- [ ] add contributing guide lines
- [x] add error handling for props
- [ ] add error handling for refs
- [x] move animation to proper element, allowing for parents with
overflow: hidden
and avoiding z-index issues
For some near future milestone
- [ ] add support for staggering
- [ ] add real tests
- [ ] export types for flowtyped and typescript
- [ ] add optional
placeholder
component that is shown whilst animating - [ ] add documentation, (maybe even abstractions) for image transitions from low-res to high-res
- [ ] make animation-layer custmizable, so regular items can be in front of them (
z
-wise) - [ ] investigate possible optimizations for the scrolling issues