lit-html and LitElement is fast, very fast. Too fast in fact.
Because views are switched in and out in an instant, the view updates immediately. In an app, this makes the app feel very jarring, as if the app isn't working hard enough.
Anyone has any pointers on how to easily implement transitions between view switches?
Maybe you could use shouldUpdate combined with transitionend event?
You'll need to manage the DOM that your components write as a function of a state of the transition you are looking to see. If you go directly from f(view 1 is active) to f(view 2 is active) it will of course present as immediate or jarring. It's important to include as many or as few states as needed to deliver the experience you'd like your users to see, ie f(view 1 is active), f(view 2 is requested), f(view 2 is loading), f(view 2 is loaded), f(view becoming visually available), f(view 2 is visually available), f(view 2 is active) and possibly more that I've not thought of right now.
Take a reasonable series of 1) f(view 1 is active) presents with a single view, 2) f(view 2 is requested) gives the user both views on the DOM but only one visible, 3) f(view becoming visually available) transitions for having the second view not visible to visible, 4) f(view 2 is active) removes the first view and you can use click, onload, and transitionend trigger the state changes between the four. From there, put some smooth/or delayed (as previous research has proven to be useful, https://www.webdesignerdepot.com/2017/09/when-slower-ux-is-better-ux/ 馃槺) transitions between those views.
Check for example how the animated transitions work with Vaadin Router:
https://vaadin.github.io/vaadin-router/vaadin-router/demo/#vaadin-router-animated-transitions-demos
Those examples are not 100% bulletproof and you can manage to break it (by going crazy and clicking very fast) but overall the implementation is working and allows to do what you want.
Here is an example of animated transition between two elements: https://codesandbox.io/s/yw6rzy1oq9
Edit: the link above uses a vanilla element. This is the version with LitElement https://codesandbox.io/s/0xknl3n2kp
Web Animations can be useful in this regards.
Thanks for all the pointers. Useful to compile into the documentation?
@web-padawan I like your approach! Super easy to understand鈥攖he animation utilities are fairly clean to the point that they could become even more reusable in these kinds of transitional scenarios. Thanks for sharing.
I've looked at the React component CSSTransitionGroup and it seems like it would not be very hard with a community effort to port at least the v1 stable branch) to a lit-element component using slots that can wrap around either customElements or core html groups. What I notice about the @blikblum example is that it is still manipulating the html inside the template without going through the lit-element life-cycle, so it can't be used on elements already present in the template. I've done this sort of manipulations for some very simple transitions, but of course as designed I've been bit by the fact that the actual DOM state doesn't match the state expected by lit-element.
I've done this sort of manipulations for some very simple transitions, but of course as designed I've been bit by the fact that the actual DOM state doesn't match the state expected by lit-element.
lit-html really needs a declarative way of implementing transitions and my examples does not cover this functionality at all. But regarding the dom state, as long the container element is defined statically in lit-html template (no mutations on each render) is safe to append or remove children in it.
I just started tinkering with creating a viewport to support transitions between view elements. I see there being two main types:
Top Level Transitions
These operate on the top level view elements themselves and typically just fade or slide them in and out. They are great as a default fallback if there isn't a specific transition required.
View Specific Transitions
These are more involved when going between two specific views using shared elements combined with the fade / slide effects for the rest, and may be asymmetrical (e.g. going from a list to detail view has different transitions than going the other direction).
I see the viewport first checking if there is a specific source->destination transition, then looking for fallback source->anything and anything->destination transitions, finally falling back to default anything->anything. What you want to play transitioning from a list-to-detail view might be different if going straight to a detail view from a page-load or other view for instance (shared element(s) in the first case, maybe slide or fade in for the second)
Here's a video of a prototype showing two separate view elements transitioning with a shared child element.
https://youtu.be/WcQKUS1dqYo
Useful reading:
https://material.io/design/motion/#transition-anatomy
https://material.io/design/motion/choreography.html#sequencing
https://aerotwist.com/blog/flip-your-animations/
I've been implementing some custom appear transitions on lit-element and will happily share them here once I have some more polish -- but implementing remove transitions seems much harder. Does anyone know if lit-element/lit-html has a callback that is called before an element is scheduled to be removed from the DOM (as opposed to disconnectedCallback which is called too late to implement a transition)
@mscuthbert I believe there was a proposal floating around a while ago to add lifecycle hooks to lit-html's Parts API, but I don't think it got formalized and implemented beyond prototyping.
@sorvell @justinfagnani would you happen to know the status or that?
@emilio-martinez we're prototyping some new directive APIs, but haven't use them for animations yet. We'll report back soon.
Folks who land here looking for a simple solution to transitions with lit-element (or lit-html) may find the lit-transition package to be helpful:
https://github.com/sijakret/lit-transition
https://sijakret.github.io/lit-transition/
I have no affiliation with the project, but stumbled on it while looking for info about implementing transitions with lit-element. I have found it to be a nifty drop-in solution for implementing a few simple enter, leave, and change transitions within my templates.
Most helpful comment
@emilio-martinez we're prototyping some new directive APIs, but haven't use them for animations yet. We'll report back soon.