Studio
2

Morph

Usage

Import morph from @mielui/svelte/actions/morph and attach it to a visual wrapper. Change key with the displayed value. Duration defaults to 220 milliseconds.

<script lang="ts">
    import { Moon02Icon as Moon, Sun03Icon as Sun } from '@hugeicons/core-free-icons';
    import { morph } from '@mielui/svelte/actions/morph';
    import { Button } from '@mielui/svelte/components/button';
    import HugeiconsIcon from '@mielui/svelte/hugeicons-icon';

    let night = $state(false);

    function toggleAppearance() {
        night = !night;
    }
</script>
<Button variant="outline" onclick={toggleAppearance} aria-label="Switch appearance preview">
    <span class="inline-flex size-5" aria-hidden="true" use:morph={{ key: night }}>
        <HugeiconsIcon icon={night ? Moon : Sun} size={20} />
    </span>
    <span class="inline-block w-12 text-left" use:morph={{ key: night }}>
        {night ? 'Night' : 'Day'}
    </span>
</Button>

SVG and text

Matching closed SVG shapes interpolate their geometry. Different icon structures use the same fixed-cell rotation, scale, and crossfade as Copy Button. Text changes use a short blur and crossfade.

Composition and accessibility

Use a span inside your existing button, not the button itself. Keep the button's accessible label outside the animation. The visual copy is hidden from assistive technology and cannot receive input. Give text a stable width if surrounding controls should not move.

Reduced-motion preferences skip the animation. The visual layer stays inside its wrapper during scrolling and resizing. Interrupted transitions continue from the current visual state, and unmount restores the original content.

Changing a count

Keep the animated number in a fixed-width wrapper. The surrounding label and button stay in place while the count changes.

API reference

key is required and accepts any value. Change it when the displayed content changes. duration is optional, measured in milliseconds, and defaults to 220. The action attaches to an HTMLElement and cleans up when it unmounts.