TylerBarnes / gatsby-plugin-transition-link

A link component for page transitions in gatsby
537 stars 70 forks source link

API change proposal for V2 (Backwards compatible) #42

Closed TylerBarnes closed 5 years ago

TylerBarnes commented 5 years ago

I've been thinking over the API while I work on tutorials for #3 and I came up with what I think would be useful changes. There are enough changes that I think it may warrant a v2. For any of you reading this who are interested and have used TransitionLink, I would love to hear your thoughts on these changes and if you think there is anything else that might be helpful. All changes would be backwards compatible so the current API would still work after these changes.

To make using react-spring and react-pose easier:

For general ease of use:

The changes from #40, #25, #33, #3, and #27 would also be rolled into a V2 release:

With the proposed changes, the Transition component (formerly TransitionState) could be used like so in react-spring:

const to = {
  enter: {
    transform: `translateY(0)`
  },
  exit: {
    transform: `translateY(100px)`
  }
}

const ExampleSpring = ({ children }) => (
  <Transition>
    {({ mount }) => (
      <Spring to={ mount ? to.enter : to.exit }>
        {props => <div style={props}>{children}</div>}
      </Spring>
    )}
  </Transition>
)

or for a more controlled transition

const to = {
  enter: {
    transform: "translateY(0)"
  },
  exit: {
    transform: "translateY(100px)"
  }
}

const ExampleSpring = ({ children }) => (
  <Transition timing={{ delay: "10%", duration: "50%" }}>
    {({ mount, current }) => (
      <Spring
        to={ mount ? to.enter : to.exit }
        config={{ duration: getMs(current.duration) }}
      >
        {props => <div style={props}>{children}</div>}
      </Spring>
    )}
  </Transition>
)

Or like this for react-pose which is much cleaner looking:

const Box = posed.div({
  left: { x: -100 },
  right: { x: 100 }
})

<Transition>
  {({ mount }) => (
    <Box position={ mount ? 'left' : 'right' } />
  )}
</Transition>

On second thought this could also be useful for gsap users since the boolean mount could be passed as a prop to another component which triggers a gsap animation when true. Perhaps another argument unmount might also be useful then.

const ExampleSpring = ({ children }) => (
  <Transition>
    {({ mount, unmount, current: { duration } }) => (
      // example component name
      <AnimatedWithGsap 
        triggerEntry={mount} 
        triggerExit={unmount}
        duration={duration}
      >
       {children}
      </AnimatedWithGsap>
    )}
  </Transition>
)

the code for the component AnimatedWithGsap would be written by the site developer and would be too difficult to write out here without having an actual project with the new api to test on since I've written all this code in the github editor but hopefully you get the idea!

If you made it this far please share your thoughts :) Also if you're interested in collaborating I would greatly welcome sharing the load!

aamorozov commented 5 years ago

I think a good addition to v2 could be to have a hook useTransitionLink or something that will accept entry and exit props. It should provide a simpler usage of the package and also will integrate nicely with spring's hooks. Not sure if gsap are re-writing/providing hook options but react-spring has done that already.

TylerBarnes commented 5 years ago

@aamorozov I've been thinking about hooks support as well and I think it's definitely a good idea. I haven't used hooks much but I'm going to get up to speed with them and integrate them to v2. I don't think gsap will add hooks support since gsap isn't a react library. They're a general JS animation library and probably haven't really thought about hooks. There's likely still a way to integrate them though and I'll check it out while I'm in there trying out other integrations.

TylerBarnes commented 5 years ago

Ok, so making this a V2 doesn't really make sense since none of the changes are breaking changes! That would violate semver. I've already finished most of these changes and they should be available in the latest version (even if they're not yet in the docs).

The two remaining pieces from this issue are now in #68 and #69

Check #65 for how to use the new useTransitionState hook. I decided a useTransitionLink hook doesn't really make sense since the main purpose of hooks is to replace render props which TransitionLink isn't using.