site logo SVELTE ANIMATED ICON

Triggers

hover, mount, and controlled (active) - when each fires and how to drive it.

The trigger prop decides when the animation runs. Three values cover the whole range.

hover (default)

The icon animates while the cursor is over it. The trigger fires on mouseenter, stops on mouseleave.

<Gear template="spin" />
<!-- equivalent to: -->
<Gear template="spin" trigger="hover" />

Hover triggers are tied to the icon’s own bounding box (the <div class="animated-icon"> wrapper). If you want the icon to animate when the parent is hovered - for example, a button - see the Animate on Hover in Button guide.

mount

Fires exactly once, as soon as the component mounts and the SVG is in the DOM. Useful for first-impression motion on hero elements, page entrances, or any “this thing just appeared” moment.

<Heart template="jelly" trigger="mount" size={48} />

Combine with loop to make a perpetually running loader:

<Gear template="spin" trigger="mount" loop />

See Autoplay and Looping for the full pattern.

controlled

Animation is driven entirely by the active prop. When active is true, the animation runs. When it flips to false, the animation stops and the icon resets to its rest state.

<script>
  let isOpen = $state(false);
</script>

<button onclick={() => (isOpen = !isOpen)}>
  {isOpen ? 'Close' : 'Open'}
  <ArrowRight template="draw" trigger="controlled" active={isOpen} />
</button>

This is the right mode for:

  • Toggles, accordions, popovers, drawers.
  • Status indicators tied to app state (online / offline, saved / unsaved).
  • Async states (idle / loading / success / error).

Switching trigger away from 'controlled' also stops any in-flight (possibly looping) animation, so it’s safe to flip modes at runtime. See Parent-Controlled Animation for the full pattern, including how to bind active to multiple icons at once.

Quick comparison

TriggerFires onBest for
hovermouseenter / mouseleaveToolbars, buttons, list rows
mountComponent first appearsEntrances, hero motion, autoplay loaders
controlledactive becomes trueToggles, app state, async status

Combining with loop

loop is orthogonal to trigger. Pair them whenever you want a perpetually running animation:

<!-- Always spinning once mounted -->
<Gear template="spin" trigger="mount" loop />

<!-- Spinning only while loading is true -->
<Gear template="iris" trigger="controlled" active={isLoading} loop />

See Loop for the details.