Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

preact-router and preact-transition-group #187

Open
mattdesl opened this issue May 5, 2017 · 12 comments
Open

preact-router and preact-transition-group #187

mattdesl opened this issue May 5, 2017 · 12 comments

Comments

@mattdesl
Copy link

mattdesl commented May 5, 2017

Hi, first of all thanks for Preact and its tooling, it's really great. 馃憤

I'm looking to add preact-transition-group to my routing so that each component can handle componentWillEnter, componentWillAppear and componentWillLeave.

So far I haven't found a clean way of integrating these two together without patching this module.

Experience-Monks@966d4f2#diff-1fdf421c05c1140f6d71444ea2b27638L248

Is there another way this might be possible?

@developit
Copy link
Member

Maybe something like this would work, as a wrapper around router?

import Router from 'preact-router';
import TransitionGroup from 'preact-transition-group';

const TransitionRouter = ({ children, ...props }) => {
  <Router {...props}>
    { children.map( child =>
      <TransitionGroup {...child.attributes}>
        {child}
      </TransitionGroup>
    ) }
  </Router>
}

If not, I wondered about just doing it inline:

<Router>
  <TransitionGroup path="/" default>
    <SomeRoute a="b" />
  </TransitionGroup>
  <TransitionGroup path="/one">
    <OtherRoute />
  </TransitionGroup>
  <TransitionGroup path="/two">
    <AnotherRoute />
  </TransitionGroup>
</Router>

@mattdesl
Copy link
Author

mattdesl commented May 9, 2017

Thanks for the reply! I tried both but unfortunately neither give me acceptable results.

In your examples you have one transition group per component, but really we should just have one TransitionGroup for all routes/components 鈥斅爐hat way it can keep track of which components are appearing/leaving in that group.

Also, it seems like the Router only looks at top-level children, so first example is trying to match against TransitionGroups instead of the routes.

So it should ultimately look like this, somehow:

<Router><TransitionGroup>{childrenToMatch}</TransitionGroup></Router>

@developit
Copy link
Member

Correct, it only supports one level of children. I think the only way to make this work would be to use a function-as-children approach, which is not currently supported in preact-router, but seems like it could be. Unfortunately the nesting approach you suggested isn't possible because it assumes the component tree to be pre-resolved, whereas children may be derived from some inner render.

<Router>
  { ({ match }) =>
    <TransitionGroup>
      { match([
        <SomeRoute path="/" default a="b" />,
        <OtherRoute path="/one" />,
        <AnotherRoute path="/two" />
      ]) }
    </TransitionGroup>
  }
</Router>

Not sure on the API though. This is a tricky one. Really it'd be nice if Router could pierce the hierarchy, but that'd be quite a bit more complexity. It's something I'd love to do, but it would be a rewrite.

@mattdesl
Copy link
Author

mattdesl commented May 11, 2017

Thanks, for now I am happy to use my fork. We eventually might clean it up a bit and re-release it with more documentation on transitions, as an alternative to preact-router for more specialized animated apps.

Cheers. 馃槃

@developit
Copy link
Member

sounds awesome, looking forward to it!

@t47io
Copy link

t47io commented May 29, 2017

Also looking for a solution for CSS transitioning between <Route/>s. Tried this #187 (comment), but does not work as expected.

@developit
Copy link
Member

developit commented Jun 3, 2017

One option here might be to allow passing a "wrap" function to the router. The router would pass the active child through that function, so you could consistently wrap each route in a TransitionGroup:

<Router wrap={ c => <CSSTransitionGroup>{c}</CSSTransitionGroup> }>
  <A path="/" />
  <B path="/b" />
  <C path="/c" />
</Router>

I'm curious why the direct wrapping doesn't work though. Maybe it's because CSSTransitionGroup doesn't passthrough props to its child? Could fix that like so:

import { h, cloneElement } from 'preact';
const TransitionGroup = ({ children, transitionEnter, transitionLeave, component, ...props }) => (
  <CSSTransitionGroup {...{ transitionEnter, transitionLeave, component }}>
    {cloneElement(children[0], props)}
  </CSSTransitionGroup>
);

<Router>
  <TransitionGroup path="/" transitionEnter="enter" transitionLeave="leave">
    <A />
  </TransitionGroup>
  <TransitionGroup path="/b" transitionEnter="enter" transitionLeave="leave">
    <B />
  </TransitionGroup>
</Router>

@danalloway
Copy link

@mattdesl would extending the router work for you?

import { h } from 'preact';
import Router from 'preact-router';
import TransitionGroup from 'preact-transition-group';

export default class TransitionRouter extends Router {
    render(props, state) {
        return (
            <TransitionGroup component="div">
                {super.render(props, state)}
            </TransitionGroup>
        );
    }
}

@danalloway
Copy link

also, there is this -> https://github.com/prateekbh/liquid-route

@fantasia949
Copy link

fantasia949 commented Oct 8, 2017

@danalloway 's tip works for me,
This fiddle shows how to make it work.
However, the transition will be broken if I use prateekbh/preact-async-route to wrap route components (both sync and async use).

@glegenty
Copy link

glegenty commented May 2, 2020

Hi ! The tips from @danalloway is not working for me, is this way of using preact router and preact transition group is still relevant ?
@fantasia949 i also tried the code from your fiddle, the components seems to not mount with the last version of preact.
i'm using :

"preact": "^10.3.2",
"preact-router": "^3.2.1",
"preact-transition-group": "^1.1.1",

@glegenty
Copy link

glegenty commented May 3, 2020

Finally i managed to make it work with the last version of react-transition-group. I had to switch to react-snap for prerendering, the prerender from preact-cli seems to not work with react-transition-group.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants