Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/danielitoCode/compose_svelted/llms.txt

Use this file to discover all available pages before exploring further.

AnimatedContent watches a targetState value and animates the transition whenever that value changes. While the outgoing state plays its exit CSS animation the incoming state is already mounted, creating a smooth crossfade between two pieces of UI. The transition style is controlled by a ContentTransition value, which encodes enter and exit inline styles together with a shared duration. This component is the foundation for declarative state-driven animations in Compose Svelted. It is also used internally by NavHost to animate screen-to-screen navigation.

Props

targetState
any
required
The value that determines which content is currently active. Whenever this value changes, AnimatedContent triggers its transition sequence — playing the exit style on the outgoing content, then swapping to the new state and playing the enter style.
transition
ContentTransition
default:"fade()"
The ContentTransition object that defines the enter inline style, the exit inline style, and how long the transition lasts in milliseconds. Defaults to a simple 300 ms opacity crossfade.
The default value fade() is applied internally. The fade factory function accepts any duration you pass; fade() without arguments uses 300 ms.

How it works

AnimatedContent renders its slot inside a positioned container that fills its parent:
position: relative; width: 100%; height: 100%; overflow: hidden;
display: flex; flex-direction: column;
An inner <div> carries the inline CSS transition for opacity and transform using transition.duration. When targetState changes:
  1. exiting is set to true — the inner div switches to transition.exit styles.
  2. After transition.duration milliseconds, currentKey is updated to the new state and exiting resets to false, restoring transition.enter styles.
Because the slot re-renders based on targetState (which in the slot content you control via {#if} or similar), the new UI is painted with the enter style as soon as the transition completes.

ContentTransition factory functions

All three factories are exported from @danielito1996/compose-svelted.

fade(duration?)

Crossfades between states using opacity only. Accepts an optional duration in ms. Default 300 ms.

scaleFade()

Combines a subtle scale (0.95 → 1) with an opacity crossfade. Fixed duration 220 ms.

slideHorizontal()

Slides the outgoing content to the left (translateX(-100%)) while the incoming content fades in at its natural position. Fixed duration 300 ms.

ContentTransition type reference

type ContentTransition = {
  enter: string;   // Inline CSS applied when this state is the active one
  exit: string;    // Inline CSS applied while this state is transitioning out
  duration: number; // Milliseconds — controls both the CSS transition and the swap timer
};

Examples

Switching between two views

<script>
  import {
    AnimatedContent,
    scaleFade
  } from '@danielito1996/compose-svelted';

  let currentView: 'a' | 'b' = 'a';
</script>

<button onclick={() => currentView = currentView === 'a' ? 'b' : 'a'}>
  Switch view
</button>

<AnimatedContent targetState={currentView} transition={scaleFade()}>
  {#if currentView === 'a'}
    <ViewA />
  {:else}
    <ViewB />
  {/if}
</AnimatedContent>

Default fade transition

<script>
  import { AnimatedContent } from '@danielito1996/compose-svelted';

  let state: 'A' | 'B' = 'A';
</script>

<button onclick={() => state = state === 'A' ? 'B' : 'A'}>
  Change state
</button>

<AnimatedContent targetState={state}>
  <Text textStyle={TextStyle.HeadlineMedium}>{state}</Text>
</AnimatedContent>

Horizontal slide (navigation-style)

<script>
  import {
    AnimatedContent,
    slideHorizontal
  } from '@danielito1996/compose-svelted';

  let page = 0;
</script>

<button onclick={() => page++}>Next page</button>

<AnimatedContent targetState={page} transition={slideHorizontal()}>
  {#if page === 0}
    <PageOne />
  {:else if page === 1}
    <PageTwo />
  {:else}
    <PageThree />
  {/if}
</AnimatedContent>

Extended fade with custom duration

<script>
  import {
    AnimatedContent,
    fade
  } from '@danielito1996/compose-svelted';

  let tab = 'overview';
</script>

<AnimatedContent targetState={tab} transition={fade(500)}>
  {#if tab === 'overview'}
    <OverviewTab />
  {:else if tab === 'details'}
    <DetailsTab />
  {/if}
</AnimatedContent>

Usage with NavHost

NavHost uses AnimatedContent internally to animate transitions between registered screens. You do not need to wrap NavHost in AnimatedContent yourself — the transition is already applied. You can however configure which ContentTransition NavHost uses by passing a transition prop.
<script>
  import {
    NavHost,
    scaleFade
  } from '@danielito1996/compose-svelted';
</script>

<NavHost transition={scaleFade()}>
  <!-- screen definitions -->
</NavHost>
When using AnimatedContent directly, make sure the parent element has a defined height. The inner container uses height: 100% to fill its parent, so a parent with no height will collapse the transition area.

Build docs developers (and LLMs) love