All Projects → TaitoUnited → react-sheltr

TaitoUnited / react-sheltr

Licence: MIT license
Shared element transition helper components for React

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to react-sheltr

React Powerplug
🔌 Renderless Containers
Stars: ✭ 2,704 (+8093.94%)
Mutual labels:  render-props
paginated
⚛️ React render props component & custom hook for pagination.
Stars: ✭ 20 (-39.39%)
Mutual labels:  render-props
react-gearbox
⚙️📦 Gearbox - Renderless state provisioning and composition
Stars: ✭ 31 (-6.06%)
Mutual labels:  render-props
Fluidtransitions
Fluid Transitions for React Navigation
Stars: ✭ 2,814 (+8427.27%)
Mutual labels:  shared-element-transition
redebounce
↘️ Render Props component to debounce the given value
Stars: ✭ 14 (-57.58%)
Mutual labels:  render-props
react-combine-contexts
🚀Use multiple React Contexts without pain.
Stars: ✭ 23 (-30.3%)
Mutual labels:  render-props
Material Ui Popup State
boilerplate for common Material-UI Menu, Popover and Popper use cases
Stars: ✭ 186 (+463.64%)
Mutual labels:  render-props
render-props
Easily and reliably support Render Props, Component Injection, and Function as a Child
Stars: ✭ 82 (+148.48%)
Mutual labels:  render-props
react-save-localstorage
🗄 React component to save data to localStorage on render phase safely
Stars: ✭ 26 (-21.21%)
Mutual labels:  render-props
redux-render
Ergonomic Redux bindings for React using render functions
Stars: ✭ 54 (+63.64%)
Mutual labels:  render-props
reason-epitath
CPS sugar usage for React Render Props composition in ReasonML
Stars: ✭ 16 (-51.52%)
Mutual labels:  render-props
stickyard
Make your React component sticky the easy way
Stars: ✭ 83 (+151.52%)
Mutual labels:  render-props
repromised
🤝 Declarative promise resolver as a render props component
Stars: ✭ 20 (-39.39%)
Mutual labels:  render-props
v-shared-element
Declarative shared-element transitions for Vue.js
Stars: ✭ 203 (+515.15%)
Mutual labels:  shared-element-transition
react-virtual-container
Optimise your React apps by only rendering components when in proximity to the viewport.
Stars: ✭ 52 (+57.58%)
Mutual labels:  render-props
React Firestore
React components to fetch data from firestore using render props
Stars: ✭ 228 (+590.91%)
Mutual labels:  render-props
react-callbag-listener
👂 A React render-prop component that listens to values emitted by callbags
Stars: ✭ 21 (-36.36%)
Mutual labels:  render-props
react-treefold
A renderless tree component for your hierarchical React views
Stars: ✭ 37 (+12.12%)
Mutual labels:  render-props
squeezy
1 kB React component for accessible accordions / collapse UI
Stars: ✭ 31 (-6.06%)
Mutual labels:  render-props
react-immer
No nonsense state management with Immer and React hooks
Stars: ✭ 13 (-60.61%)
Mutual labels:  render-props







React Sheltr

Shared Element Transitions (Sh El Tr -> Sheltr) for your React applications.

Installation

npm install @taito/react-sheltr

Table of Contents

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 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.

import Sheltr from '@taito/react-sheltr';

<Sheltr>
  {/* other components go here */}
</Sheltr>

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.

import { SharedElement } from '@taito/react-sheltr';

// Component A
<SharedElement sharedId={id}>
  {sheltrProps => (
    <ImageA {...sheltrProps} />
  )}
</SharedElement>

// Component B
<SharedElement sharedId={id} startOnUnmount>
  {sheltrProps => (
    <ImageB {...sheltrProps} />
  )}
</SharedElement>

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.

<SharedElement sharedId={id}>
  {({ onClick, ...rest }) => (
    <Wrapper onClick={onClick}>
      <Image {...rest} />
    </Wrapper>
  )}
</SharedElement>

// Or

<SharedElement sharedId={id}>
  {({ onClick, ...rest }) => (
    <Wrapper onClick={() => {
      this.handleClick(someData);
      onClick();
    }}>
      <Image {...rest} />
    </Wrapper>
  )}
</SharedElement>

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.

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 (
      <Wrapper>
        {items.map(item => {
          return (
            <Item onClick={() => this.handleClick(item.id)}>
              <Thumbnail src={item.image} {...sheltr.getProps(item.id)} />
              {/* other things... */}
            </Item>
          );
        })}
      </Wrapper>
    );
  }
}

export default withSheltr(ComponentA);
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 (
      <Wrapper>
        <Img src={image.src} {...sheltr.getProps(image.id)} />
        {/* other things... */}
      </Wrapper>
    );
  }
}

export default withSheltr(ComponentB);

API Reference

* = required.

<Sheltr /> (default export)

Prop Type Default Note
delay number 0ms The delay for all transition animations inside Sheltr provider.
duration number 400ms 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.

<SharedElement />

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
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].