Shared Layout

Move a decorative element between conditional locations with a shared layout id.

Overview

LayoutGroup scopes related layout ids, while SharedLayout carries the last measured rectangle to the next element with the same id. It is especially useful for indicators, selected pills, and active underlines.

Behaviour and customization

Only one matching SharedLayout should be mounted in a group at a time. A named LayoutGroup can persist a rectangle in session storage so the next route consumes it once.

Keep shared elements decorative. Shared layout transfers geometry, not focus, event handlers, or application content. Choose a stable layoutId and scope it with a named group.

Interactive example

Usage

Usage
<script lang="ts">
	import { LayoutGroup, SharedLayout } from 'fractalsvelte/motion';

	let active = $state('Overview');
</script>

<LayoutGroup id="settings-tabs">
	{#each ['Overview', 'Security'] as tab}
		<button onclick={() => (active = tab)}>
			{tab}
			{#if active === tab}<SharedLayout layoutId="active-indicator" />{/if}
		</button>
	{/each}
</LayoutGroup>

API

PropTypeDefaultDescription
LayoutGroup idstring-Scope for related layout ids.
persistbooleanfalseCarry a rectangle across the next route mount.
layoutIdstring-Identity shared by the outgoing and incoming element.

Components and blocks

Use this primitive directly for custom interfaces; Fractalsvelte also applies it or its motion language in these areas:

  • Tabs indicator
  • Toggle Group selection
  • Tree View selection

For exact built-in component timing and reduced-motion behaviour, see the Motion guide.