title: View Transition Playground sidebar_position: 5

Use the Tama Elements StackBlitz template to try the transition queue without cloning the repository.

  1. Open the linked template and replace the contents of src/App.tsx with the snippet below.
  2. Save the file. StackBlitz will hot-reload and run the transition handlers in the browser.
  3. Tweak the animation timings or add more handlers to see how TamaJs keeps the previous view alive until all of them resolve.
src/App.tsx
import "./style.css" import { Tama } from "@denshya/tama" const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) function App(this: Tama.Component) { this.view.transitions = [ async (transit, previous, next) => { const previousEl = this.inflator.inflate<HTMLElement>(previous) previousEl.dataset.state = "leaving" await delay(140) const nextEl = this.inflator.inflate<HTMLElement>(next) nextEl.dataset.state = "entering" await transit() requestAnimationFrame(() => { nextEl.dataset.state = "active" }) }, document.startViewTransition?.bind(document) as any, ] const screens = ["Dashboard", "Billing", "Settings"] let index = 0 if (this.view.current == null) { this.view.set(<section className="screen">{screens[index]}section>) } return ( <main className="app"> <header> <h1>Tama View Transitionsh1> <button type="button" onClick={() => { index = (index + 1) % screens.length this.view.setAsync(<section className="screen">{screens[index]}section>) }} > Next screen button> header> <div className="stage">{this.view.current}div> main> ) } export default App
src/style.css
:root { color-scheme: dark; font-family: system-ui, sans-serif; background: radial-gradient(circle at top, #243b55 0%, #141e30 100%); } .app { min-height: 100vh; padding: 4rem; display: grid; gap: 3rem; } .stage { position: relative; height: 320px; border-radius: 30px; overflow: hidden; box-shadow: 0 24px 80px rgba(0, 0, 0, 0.3); } .screen { position: absolute; inset: 0; display: grid; place-items: center; font-size: 2.5rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; transition: transform 160ms ease, opacity 160ms ease; } .screen[data-state="active"] { opacity: 1; transform: translateX(0); } .screen[data-state="leaving"] { opacity: 0; transform: translateX(-12%); } .screen[data-state="entering"] { opacity: 0; transform: translateX(12%); }

Tip: You can mix and match multiple handlers. Tama keeps running them in sequence and only resolves setAsync when every handler finishes.