Skip to example

Svelte: Layout animation

An example of using Motion's animateLayout function in Svelte. The update function calls flushSync() so Svelte applies the state change before Motion measures the new layout.

Svelte

Source code

<script>
  import { animateLayout } from "motion"
  import { flushSync } from "svelte"

  let isOn = $state(false)
  let container

  function toggle() {
    animateLayout(
      container,
      () => {
        isOn = !isOn
        // Apply the state change to the DOM before Motion measures
        // the new layout.
        flushSync()
      },
      { type: "spring", visualDuration: 0.2, bounce: 0.2 }
    )
  }
</script>

<button
  class="toggle-container"
  class:on={isOn}
  aria-pressed={isOn}
  aria-label="Toggle"
  onclick={toggle}
  bind:this={container}
>
  <div class="toggle-handle" data-layout></div>
</button>

<style>
  .toggle-container {
    width: 100px;
    height: 50px;
    background-color: var(--hue-5-transparent);
    border-radius: 50px;
    cursor: pointer;
    display: flex;
    padding: 10px;
    border: none;
    justify-content: flex-start;
    box-sizing: content-box;
  }

  .toggle-container.on {
    justify-content: flex-end;
  }

  .toggle-handle {
    width: 50px;
    height: 50px;
    background-color: var(--hue-5);
    border-radius: 50%;
  }
</style>