PageTransition
Page transitions — off unless you ask for one.
Walkthrough
1. Presets
Five of the seventeen presets, off unless you ask. Change key and the content transitions; here the key is the step, so the buttons drive it.
<script lang="ts"> import { Button, PageTransition, SegmentedButton } from 'omaris'; import type { PageTransitionName } from 'omaris'; let transition = $state<PageTransitionName>('shared-x'); let step = $state(0); const PANELS = ['Overview', 'Orders', 'Customers'];</script><div class="flex w-full max-w-lg flex-col gap-4"> <SegmentedButton label="Preset" bind:value={transition} items={[ { value: 'fade', label: 'fade' }, { value: 'fade-through', label: 'fade-through' }, { value: 'shared-x', label: 'shared-x' }, { value: 'shared-y', label: 'shared-y' }, { value: 'scale', label: 'scale' } ]} /> <div class="h-32 overflow-hidden rounded-shape-lg border border-border"> <PageTransition key={step} {transition} class="h-full"> <div class="flex h-full items-center justify-center bg-surface-container-low"> <span class="text-title-md">{PANELS[step]}</span> </div> </PageTransition> </div> <div class="flex gap-2"> <Button size="xs" variant="outlined" onclick={() => (step = (step + 2) % 3)}>Back</Button> <Button size="xs" variant="outlined" onclick={() => (step = (step + 1) % 3)}>Forward</Button> </div></div> 2. In a layout
In a real app the key is the pathname, so every navigation transitions and nothing else has to change: ``svelte <PageTransition key={page.url.pathname} transition="shared-x"> {@render children()} </PageTransition> ` direction` is what makes a back button feel like going back.
/orders<script lang="ts"> import { Button, PageTransition } from 'omaris'; let index = $state(0); let direction = $state<'forward' | 'backward'>('forward'); const PAGES = ['/orders', '/orders/4021', '/orders/4021/items']; function go(step: number) { direction = step > 0 ? 'forward' : 'backward'; index = Math.min(PAGES.length - 1, Math.max(0, index + step)); }</script><div class="flex w-full max-w-lg flex-col gap-4"> <div class="h-28 overflow-hidden rounded-shape-lg border border-border"> <PageTransition key={PAGES[index]} transition="shared-x" {direction} class="h-full"> <div class="flex h-full items-center justify-center bg-surface-container-low"> <code class="text-body-md">{PAGES[index]}</code> </div> </PageTransition> </div> <div class="flex gap-2"> <Button size="xs" variant="outlined" disabled={index === 0} onclick={() => go(-1)}>Back</Button> <Button size="xs" variant="outlined" disabled={index === 2} onclick={() => go(1)}> Deeper </Button> </div></div> 3. Native stack
push is the phone's navigation stack: the arriving page slides in over the old one, which parallaxes a third of the way and dims behind it. cover rises over a page that stays put, and reveal slides the top one away.
/orders<script lang="ts"> import { Button, PageTransition, SegmentedButton } from 'omaris'; import type { PageTransitionName } from 'omaris'; let transition = $state<PageTransitionName>('push'); let index = $state(0); const PAGES = ['/orders', '/orders/4021', '/orders/4021/items']; function go(step: number) { index = Math.min(PAGES.length - 1, Math.max(0, index + step)); }</script><div class="flex w-full max-w-lg flex-col gap-4"> <SegmentedButton label="Pattern" bind:value={transition} items={[ { value: 'push', label: 'push' }, { value: 'cover', label: 'cover' }, { value: 'reveal', label: 'reveal' }, { value: 'swap', label: 'swap' } ]} /> <div class="h-28 overflow-hidden rounded-shape-lg border border-border"> <PageTransition key={PAGES[index]} {transition} direction="auto" class="h-full"> <div class="flex h-full items-center justify-center bg-surface-container-low"> <code class="text-body-md">{PAGES[index]}</code> </div> </PageTransition> </div> <div class="flex gap-2"> <Button size="xs" variant="outlined" disabled={index === 0} onclick={() => go(-1)}>Back</Button> <Button size="xs" variant="outlined" disabled={index === 2} onclick={() => go(1)}> Deeper </Button> </div></div> 4. Auto direction
direction="auto" keeps the keys it has seen as a stack: a key it has never seen plays forward, and one already on the stack plays backward and unwinds it. Click across the tabs, then back to one you have been to.
<script lang="ts"> import { PageTransition, SegmentedButton, Text } from 'omaris'; const TABS = ['Overview', 'Orders', 'Menu', 'Staff']; let at = $state('Overview'); let played = $state('—');</script><div class="flex w-full max-w-lg flex-col gap-4"> <SegmentedButton label="Section" bind:value={at} items={TABS.map((tab) => ({ value: tab, label: tab }))} /> <div class="h-28 overflow-hidden rounded-shape-lg border border-border"> <PageTransition key={at} transition="shared-x" direction="auto" class="h-full" onstart={(way) => (played = way)} > <div class="flex h-full items-center justify-center bg-surface-container-low"> <span class="text-title-md">{at}</span> </div> </PageTransition> </div> <Text variant="label-sm" tone="muted">Last transition played: {played}</Text></div>