Backgrounds

Animated Background

Animated background that follows interactive elements.

AnimatedBackground creates animated background effects that follow interactive elements.

Usage

<template>
  <div class="flex items-center justify-center">
    <MAnimatedBackground
      default-value="overview"
      :transition="{ duration: 300 }"
      background-class="bg-accented rounded-lg"
      class="inline-flex items-center gap-1 rounded-xl border border-default bg-elevated p-1"
    >
      <button
        v-for="tab in tabs"
        :key="tab.id"
        :data-id="tab.id"
        type="button"
        class="relative z-1 rounded-lg px-4 py-2 text-sm font-medium text-muted transition-colors hover:text-highlighted"
      >
        {{ tab.label }}
      </button>
    </MAnimatedBackground>
  </div>
</template>

<script setup>
const tabs = [
  { id: 'overview', label: 'Overview' },
  { id: 'activity', label: 'Activity' },
  { id: 'settings', label: 'Settings' },
]
</script>

Examples

Basic Usage

Overview

A snapshot of your workspace.

<template>
  <div class="w-full max-w-md">
    <MAnimatedBackground
      :default-value="tabs[0].id"
      :transition="{ duration: 250, ease: 'ease-out' }"
      background-class="bg-primary rounded-lg"
      class="flex items-center gap-1 rounded-xl border border-default bg-elevated p-1"
      @value-change="active = $event"
    >
      <button
        v-for="tab in tabs"
        :key="tab.id"
        :data-id="tab.id"
        type="button"
        class="relative z-1 flex flex-1 items-center justify-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors"
        :class="active === tab.id ? 'text-inverted' : 'text-muted hover:text-highlighted'"
      >
        <UIcon
          :name="tab.icon"
          class="size-4"
        />
        {{ tab.label }}
      </button>
    </MAnimatedBackground>

    <div class="mt-4 rounded-xl border border-default bg-elevated p-6">
      <div class="flex items-center gap-3">
        <div class="flex size-11 items-center justify-center rounded-lg bg-primary/10 text-primary">
          <UIcon
            :name="current.icon"
            class="size-5"
          />
        </div>
        <div>
          <p class="font-medium text-highlighted">
            {{ current.label }}
          </p>
          <p class="text-sm text-muted">
            {{ current.description }}
          </p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
const tabs = [
  { id: 'overview', label: 'Overview', icon: 'i-lucide-layout-dashboard', description: 'A snapshot of your workspace.' },
  { id: 'analytics', label: 'Analytics', icon: 'i-lucide-chart-line', description: 'Traffic, conversions, and trends.' },
  { id: 'reports', label: 'Reports', icon: 'i-lucide-file-text', description: 'Download or schedule exports.' },
  { id: 'settings', label: 'Settings', icon: 'i-lucide-settings', description: 'Manage your preferences.' },
]

const active = ref(tabs[0].id)
const current = computed(() => tabs.find(tab => tab.id === active.value) ?? tabs[0])
</script>

Customize

The background moves, the copy does not

Switch tabs to move the gradient.

Customize

Default Valueinbox
Enable Hover
Background Classbg-accented rounded-lg

Props

Prop Type Default Description
defaultValuestring | nullnullDefault active element ID.
enableHoverbooleanfalseEnable hover interactions.
backgroundClassstring'bg-primary/70 rounded-lg'CSS classes for the background element.
containerClassstring''CSS classes for the container.
transitionobject{ duration: 300, ease: 'ease-out' }Transition settings.

Events

Event Payload Description
valueChange(value: string | null) => voidEmitted when the active element changes.

Slots

Slot Props Description
default{ activeId: string | null, setActiveId: (id: string | null) => void }Default slot with active ID and setter function.

UI

This component's theme exposes the slots below. Override any of them per instance with the ui prop, or app-wide under ui.animatedBackground in app.config.ts.

Prop Type Default Description
uiobject-Per-slot classes merged over the theme defaults.
Slot Props Description
root-relative
background-absolute top-0 left-0 pointer-events-none transition-all duration-300 ease-out