https://github.com/taitounited/react-sheltr
Shared element transition helper components for React
https://github.com/taitounited/react-sheltr
animation reactjs render-props shared-element-transition
Last synced: about 1 year ago
JSON representation
Shared element transition helper components for React
- Host: GitHub
- URL: https://github.com/taitounited/react-sheltr
- Owner: TaitoUnited
- License: mit
- Created: 2018-05-27T13:12:07.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-06-15T13:44:11.000Z (about 8 years ago)
- Last Synced: 2024-12-30T11:51:46.134Z (over 1 year ago)
- Topics: animation, reactjs, render-props, shared-element-transition
- Language: JavaScript
- Size: 191 KB
- Stars: 31
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# React Sheltr
> Shared Element Transitions (Sh El Tr -> Sheltr) for your React applications.
## Installation
```sh
npm install @taito/react-sheltr
```
## Table of Contents
* [What is it?](#what-is-it-)
* [Usage](#usage)
* [API Reference](#api-reference)
* [Examples](#examples)
## What is it?
A shared element transition is a transition between two views where some
element common for both views is used to smoothly bridge the transition.
In practice there can be two (or more) different elements that are transformed
(scaled and translated) so that it looks like one element that morphs from one state to the other.
Under the hood React Sheltr uses the [FLIP](https://aerotwist.com/blog/flip-your-animations/)
technique to do the heavy lifting for calculating and animating the shared elements.
## Usage
### A word of caution!
React Sheltr uses the official Context API introduced in React v16.3.0
so if you are using an older version of React than that then this module won't work 😕
### Quickstart
Firstly add Sheltr provider somewhere up in the view hierarchy tree just like you
would add your redux Provider or styled-components ThemeProvider.
Note that it doesn't really need to be at the root level but somewhere above
the `SharedElement` components that are used later.
```javascript
import Sheltr from '@taito/react-sheltr';
{/* other components go here */}
```
Then you can use `SharedElement` component to define and wire up your shared elements.
This component use the *render-prop* / *children as a function* pattern to expose
necessary props to the actual components that should be shared for the transition.
Here we have two related image components: Component A that starts the transition flow when
it is clicked, which is the default behaviour, and Component B when it's unmounted.
```javascript
import { SharedElement } from '@taito/react-sheltr';
// Component A
{sheltrProps => (
)}
// Component B
{sheltrProps => (
)}
```
In some cases you might need to apply the individual `sheltrProps` to separate components
or maybe compose them with some existing logic you have.
For this use case you can destruct the provided props and pick the ones you want.
However, remember that you need to spread rest of the props to the component
that should be shared.
```javascript
{({ onClick, ...rest }) => (
)}
// Or
{({ onClick, ...rest }) => (
{
this.handleClick(someData);
onClick();
}}>
)}
```
### The HOC way
If you don't fancy the *render-prop* / *children as a function* pattern
you can use `withSheltr` Higher Order Component to gain access to the underlying
API and manually handle things that `ShareElement` would do for you.
```javascript
import { withSheltr } from '@taito/react-sheltr';
class ComponentA extends Component {
componentDidMount() {
this.props.sheltr.transition();
}
handleClick = id => {
this.props.sheltr.start(id);
};
render() {
const { items, sheltr } = this.props;
return (
{items.map(item => {
return (
this.handleClick(item.id)}>
{/* other things... */}
);
})}
);
}
}
export default withSheltr(ComponentA);
```
```javascript
import { withSheltr } from '@taito/react-sheltr';
class ComponentB extends Component {
componentDidMount() {
this.props.sheltr.transition();
}
componentWillUnmount() {
this.props.sheltr.start(this.props.image.id);
}
render() {
const { image, sheltr } = this.props;
return (
{/* other things... */}
);
}
}
export default withSheltr(ComponentB);
```
## API Reference
`*` = required.
### `` (default export)
| **Prop** | **Type** | **Default** | **Note** |
|----------|----------|-------------|----------|
| `delay` | `number` | `0`ms | The delay for all transition animations inside Sheltr provider.
| `duration` | `number` | `400`ms | The duration for all transition animations inside Sheltr provider.
| `easing` | `string` | `"cubic-bezier(0.075, 0.82, 0.165, 1)"` | Any valid css [transition timing function](https://www.w3schools.com/cssref/css3_pr_transition-timing-function.asp).
### ``
| **Prop** | **Type** | **Default** | **Note** |
|----------|----------|-------------|----------|
| `children`* | `func` | none |
| `sharedId`* | `string` | none | A unique id between two shared elements.
| `startOnClick` | `bool` | true | A flag telling SharedElement to provide a click handler to start the transition flow.
| `startOnUnmount` | `bool` | false | A flag telling SharedElement to start the transition flow when the component unmounts.
| `completeOnUnmount` | `bool` | false | A flag telling SharedElement to complete transition flow when the component unmounts (after handling `startOnUnmount` related actions.
## Examples
To see more real-world-like examples that use `react-router` and `styled-components`
check the **examples** folder for two quite common use cases for shared element transitions:
- List view with thumbnail images that morph into the header of the clicked item's detail view.
- Simple mosaic image gallery