Skip to content
System

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.

Overview
<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.

Overview
Last transition played: —
<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>