Skip to content

IconButtonFx

Experimental Alpha

This library is a work-in-progress. We are releasing it early to gather feedback, but it is not ready for production.

An icon button component with customizable animation effects that trigger on hover, click, or mount. IconButtonFx extends the base IconButton component with a rich set of visual effects to create engaging, interactive UI elements.

Opt-in Component

IconButtonFx adds a few hundred lines of CSS for animation effects. It's ideal for marketing sites, landing pages, or when visual polish is a priority.

Examples

Vue
Lit
React
Live Preview

Basic Effects

All available effects

Pulse Scale grow (hover)

Bounce Vertical pop (hover)

Wobble Rotate wobble (hover)

Shake Horizontal shake (hover)

Pulse-Wobble Sequential animation (hover)

Jelly Squash/stretch (hover)

Press-Pop Quick press (click)

Grow Scale up (hover)

Shrink Scale down (hover)

Speed Variations

Control animation speed with the fx-speed prop

Easing Functions

Different easing functions create different animation feels

Examples use fx-speed="xl" to make easing differences more visible. For production, prefer "sm" or "md" speeds.
Ease (ease)Ease In (ease-in)Ease Out (ease-out)Bounce(bounce)Spring Small (spring-sm)Spring Medium (spring-md)Spring Large (spring-lg)

Size Variations

For xs and sm sizes, use an icon size 20px or less, or, allow the icon to scale with: width: 100% and height: 100%.

Common Use Cases

Navigation

Actions

Notifications

Social

Disabling Effects

This button has fx="pulse" but :fx-disabled="true" prevents the animation from playing while keeping the button clickable

View Vue Code

<template>
  <div class="examples-container">
    <!-- Basic Effects -->
    <section class="example-section">
      <div class="mbe4">
        <h2>Basic Effects</h2>
        <p class="example-description">All available effects</p>
      </div>

      <!-- Pulse Effect -->
      <div class="effect-group">
        <h3>Pulse <span class="effect-type">Scale grow (hover)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="pulse"
            variant="primary"
            label="Pulse Primary"
          >
            <Heart />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse"
            variant="success"
            label="Pulse Success"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse"
            variant="warning"
            label="Pulse Warning"
          >
            <Star />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse"
            variant="danger"
            label="Pulse Danger"
          >
            <Trash2 />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse"
            variant="ghost"
            label="Pulse Ghost"
          >
            <Settings />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse"
            variant="primary"
            label="Pulse Large"
          >
            <Heart />
          </VueIconButtonFx>
        </div>
      </div>

      <!-- Bounce Effect -->
      <div class="effect-group">
        <h3>Bounce <span class="effect-type">Vertical pop (hover)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="bounce"
            variant="primary"
            label="Bounce Primary"
          >
            <Download />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="bounce"
            variant="success"
            label="Bounce Success"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="bounce"
            variant="warning"
            label="Bounce Warning"
          >
            <Bell />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="bounce"
            variant="danger"
            label="Bounce Danger"
          >
            <Trash2 />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="bounce"
            variant="ghost"
            label="Bounce Ghost"
          >
            <Download />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="bounce"
            variant="success"
            label="Bounce Large"
          >
            <Download />
          </VueIconButtonFx>
        </div>
      </div>

      <!-- Wobble Effect -->
      <div class="effect-group">
        <h3>Wobble <span class="effect-type">Rotate wobble (hover)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="wobble"
            variant="primary"
            label="Wobble Primary"
          >
            <Bell />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="wobble"
            variant="success"
            label="Wobble Success"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="wobble"
            variant="warning"
            label="Wobble Warning"
          >
            <Bell />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="wobble"
            variant="danger"
            label="Wobble Danger"
          >
            <Bell />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="wobble"
            variant="ghost"
            label="Wobble Ghost"
          >
            <Bell />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="wobble"
            variant="warning"
            label="Wobble Large"
          >
            <Bell />
          </VueIconButtonFx>
        </div>
      </div>

      <!-- Shake Effect -->
      <div class="effect-group">
        <h3>Shake <span class="effect-type">Horizontal shake (hover)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="shake"
            variant="primary"
            label="Shake Primary"
          >
            <Trash2 />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shake"
            variant="success"
            label="Shake Success"
          >
            <Trash2 />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shake"
            variant="warning"
            label="Shake Warning"
          >
            <Trash2 />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shake"
            variant="danger"
            label="Shake Danger"
          >
            <Trash2 />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shake"
            variant="ghost"
            label="Shake Ghost"
          >
            <Trash2 />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shake"
            variant="danger"
            label="Shake Large"
          >
            <Trash2 />
          </VueIconButtonFx>
        </div>
      </div>

      <!-- Pulse-Wobble Effect -->
      <div class="effect-group">
        <h3>Pulse-Wobble <span class="effect-type">Sequential animation (hover)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="pulse-wobble"
            fx-speed="xl"
            variant="primary"
            label="Pulse-Wobble Primary"
          >
            <Heart />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse-wobble"
            fx-speed="xl"
            variant="success"
            label="Pulse-Wobble Success"
          >
            <Star />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse-wobble"
            fx-speed="xl"
            variant="warning"
            label="Pulse-Wobble Warning"
          >
            <Bell />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse-wobble"
            fx-speed="xl"
            variant="danger"
            label="Pulse-Wobble Danger"
          >
            <Heart />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse-wobble"
            fx-speed="xl"
            variant="ghost"
            label="Pulse-Wobble Ghost"
          >
            <Heart />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse-wobble"
            fx-speed="xl"
            variant="primary"
            label="Pulse-Wobble Large"
          >
            <Heart />
          </VueIconButtonFx>
        </div>
      </div>

      <!-- Jelly Effect -->
      <div class="effect-group">
        <h3>Jelly <span class="effect-type">Squash/stretch (hover)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="jelly"
            variant="primary"
            label="Jelly Primary"
          >
            <Star />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="jelly"
            variant="success"
            label="Jelly Success"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="jelly"
            variant="warning"
            label="Jelly Warning"
          >
            <Star />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="jelly"
            variant="danger"
            label="Jelly Danger"
          >
            <Star />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="jelly"
            variant="ghost"
            label="Jelly Ghost"
          >
            <Star />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="jelly"
            variant="warning"
            label="Jelly Large"
          >
            <Star />
          </VueIconButtonFx>
        </div>
      </div>

      <!-- Press-Pop Effect -->
      <div class="effect-group">
        <h3>Press-Pop <span class="effect-type">Quick press (click)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="press-pop"
            variant="primary"
            label="Press-Pop Primary"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="press-pop"
            variant="success"
            label="Press-Pop Success"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="press-pop"
            variant="warning"
            label="Press-Pop Warning"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="press-pop"
            variant="danger"
            label="Press-Pop Danger"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="press-pop"
            variant="ghost"
            label="Press-Pop Ghost"
          >
            <Check />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="press-pop"
            variant="success"
            label="Press-Pop Large"
          >
            <Check />
          </VueIconButtonFx>
        </div>
      </div>

      <!-- Grow Effect -->
      <div class="effect-group">
        <h3>Grow <span class="effect-type">Scale up (hover)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="grow"
            variant="primary"
            label="Grow Primary"
          >
            <Plus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="grow"
            variant="success"
            label="Grow Success"
          >
            <Plus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="grow"
            variant="warning"
            label="Grow Warning"
          >
            <Plus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="grow"
            variant="danger"
            label="Grow Danger"
          >
            <Plus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="grow"
            variant="ghost"
            label="Grow Ghost"
          >
            <Plus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="grow"
            variant="primary"
            label="Grow Large"
          >
            <Plus />
          </VueIconButtonFx>
        </div>
      </div>

      <!-- Shrink Effect -->
      <div class="effect-group">
        <h3>Shrink <span class="effect-type">Scale down (hover)</span></h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="shrink"
            variant="primary"
            label="Shrink Primary"
          >
            <Minus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shrink"
            variant="success"
            label="Shrink Success"
          >
            <Minus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shrink"
            variant="warning"
            label="Shrink Warning"
          >
            <Minus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shrink"
            variant="danger"
            label="Shrink Danger"
          >
            <Minus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shrink"
            variant="ghost"
            label="Shrink Ghost"
          >
            <Minus />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shrink"
            variant="danger"
            label="Shrink Large"
          >
            <Minus />
          </VueIconButtonFx>
        </div>
      </div>
    </section>

    <!-- Speed Variations -->
    <section class="example-section">
      <div class="mbe4">
        <h2>Speed Variations</h2>
        <p class="example-description">Control animation speed with the <code>fx-speed</code> prop</p>
      </div>
      <div class="stacked-mobile">
        <VueIconButtonFx
          fx="pulse"
          fx-speed="xs"
          variant="primary"
          label="Extra fast"
        >
          <Heart />
        </VueIconButtonFx>
        <VueIconButtonFx
          fx="pulse"
          fx-speed="sm"
          variant="primary"
          label="Fast"
        >
          <Heart />
        </VueIconButtonFx>
        <VueIconButtonFx
          fx="pulse"
          fx-speed="md"
          variant="primary"
          label="Medium"
        >
          <Heart />
        </VueIconButtonFx>
        <VueIconButtonFx
          fx="pulse"
          fx-speed="lg"
          variant="primary"
          label="Slow"
        >
          <Heart />
        </VueIconButtonFx>
        <VueIconButtonFx
          fx="pulse"
          fx-speed="xl"
          variant="primary"
          label="Extra slow"
        >
          <Heart />
        </VueIconButtonFx>
      </div>
    </section>

    <!-- Easing Functions -->
    <section class="example-section">
      <div class="mbe4">
        <h2>Easing Functions</h2>
        <p class="mbe2">Different easing functions create different animation feels</p>
        <VueAlert :bordered-left="true">
          Examples use <code>fx-speed="xl"</code> to make easing differences more visible.
          For production, prefer <code>"sm"</code> or <code>"md"</code> speeds.
        </VueAlert>
      </div>
      <div
        class="stacked"
        style="width: 40%;"
      >
        <span>Ease <code>(ease)</code></span>
        <VueIconButtonFx
          fx="bounce"
          fx-ease="ease"
          fx-speed="xl"
          variant="primary"
          label="Ease"
        >
          <Heart />
        </VueIconButtonFx>
        <span>Ease In <code>(ease-in)</code></span>
        <VueIconButtonFx
          fx="bounce"
          fx-ease="ease-in"
          fx-speed="xl"
          variant="primary"
          label="Ease-In"
        >
          <Heart />
        </VueIconButtonFx>
        <span>Ease Out <code>(ease-out)</code></span>
        <VueIconButtonFx
          fx="bounce"
          fx-ease="ease-out"
          fx-speed="xl"
          variant="primary"
          label="Ease-Out"
        >
          <Heart />
        </VueIconButtonFx>

        <span>Bounce<code>(bounce)</code></span>
        <VueIconButtonFx
          fx="bounce"
          fx-ease="bounce"
          fx-speed="xl"
          variant="primary"
          label="Bounce"
        >
          <Heart />
        </VueIconButtonFx>
        <span>Spring Small <code>(spring-sm)</code></span>
        <VueIconButtonFx
          fx="bounce"
          fx-ease="spring-sm"
          fx-speed="xl"
          variant="primary"
          label="Spring SM"
        >
          <Heart />
        </VueIconButtonFx>
        <span>Spring Medium <code>(spring-md)</code></span>
        <VueIconButtonFx
          fx="bounce"
          fx-ease="spring-md"
          fx-speed="xl"
          variant="primary"
          label="Spring MD"
        >
          <Heart />
        </VueIconButtonFx>
        <span>Spring Large <code>(spring-lg)</code></span>
        <VueIconButtonFx
          fx="bounce"
          fx-ease="spring-lg"
          fx-speed="xl"
          variant="primary"
          label="Spring LG"
        >
          <Heart />
        </VueIconButtonFx>
      </div>
    </section>

    <!-- Size Variations -->
    <section class="example-section">
      <div class="mbe4">
        <h2>Size Variations</h2>
        <p class="example-description">For <code>xs</code> and <code>sm</code> sizes, use an icon size <code>20px</code> or less, or, allow the icon to scale with: <code>width: 100%</code> and <code>height: 100%</code>.</p>
      </div>
      <div class="stacked-mobile">
        <VueIconButtonFx
          fx="pulse"
          size="xs"
          variant="primary"
          :bordered="true"
          label="Extra small"
        >
          <Heart class="full-w-h" />
        </VueIconButtonFx>
        <VueIconButtonFx
          fx="pulse"
          size="sm"
          variant="primary"
          label="Small"
        >
          <Heart class="full-w-h" />
        </VueIconButtonFx>
        <VueIconButtonFx
          fx="pulse"
          size="md"
          variant="primary"
          label="Medium"
        >
          <Heart class="full-w-h" />
        </VueIconButtonFx>
        <VueIconButtonFx
          fx="pulse"
          size="lg"
          variant="primary"
          label="Large"
        >
          <Heart class="full-w-h" />
        </VueIconButtonFx>
        <VueIconButtonFx
          fx="pulse"
          size="xl"
          variant="primary"
          label="Extra large"
        >
          <Heart class="full-w-h" />
        </VueIconButtonFx>
      </div>
    </section>

    <!-- Common Use Cases -->
    <section class="example-section">
      <div class="mbe4">
        <h2>Common Use Cases</h2>
      </div>

      <div class="use-case-group">
        <h3>Navigation</h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="grow"
            variant="ghost"
            label="Menu"
          >
            <Menu />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="grow"
            variant="ghost"
            label="Home"
          >
            <Home />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="grow"
            variant="ghost"
            label="Search"
          >
            <Search />
          </VueIconButtonFx>
        </div>
      </div>

      <div class="use-case-group">
        <h3>Actions</h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="pulse"
            variant="primary"
            label="Edit"
          >
            <Edit />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="shake"
            variant="danger"
            label="Delete"
          >
            <Trash2 />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="bounce"
            variant="success"
            label="Bookmark"
          >
            <Bookmark />
          </VueIconButtonFx>
        </div>
      </div>

      <div class="use-case-group">
        <h3>Notifications</h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="wobble"
            variant="warning"
            label="Notifications"
          >
            <Bell />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="pulse-wobble"
            variant="danger"
            label="Important notification"
          >
            <Bell />
          </VueIconButtonFx>
        </div>
      </div>

      <div class="use-case-group">
        <h3>Social</h3>
        <div class="stacked-mobile">
          <VueIconButtonFx
            fx="pulse"
            variant="ghost"
            label="Like"
          >
            <ThumbsUp />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="bounce"
            variant="ghost"
            label="Comment"
          >
            <MessageCircle />
          </VueIconButtonFx>
          <VueIconButtonFx
            fx="grow"
            variant="ghost"
            label="Send"
          >
            <Send />
          </VueIconButtonFx>
        </div>
      </div>
    </section>

    <!-- Disabled Effects -->
    <section class="example-section">
      <div class="mbe4">
        <h2>Disabling Effects</h2>
        <p class="example-description">
          This button has <code>fx="pulse"</code> but <code>:fx-disabled="true"</code>
          prevents the animation from playing while keeping the button clickable
        </p>
      </div>
      <div class="stacked-mobile">
        <VueIconButtonFx
          fx="pulse"
          :fx-disabled="true"
          variant="primary"
          label="No animation"
        >
          <Heart />
        </VueIconButtonFx>
      </div>
    </section>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { VueIconButtonFx } from "agnosticui-core/icon-button-fx/vue";
import { VueAlert } from "agnosticui-core/alert/vue";
import {
  Heart,
  Download,
  Bell,
  Trash2,
  Menu,
  Home,
  Search,
  Edit,
  Bookmark,
  ThumbsUp,
  MessageCircle,
  Send,
  Star,
  Check,
  Plus,
  Minus,
  Settings,
} from "lucide-vue-next";

export default defineComponent({
  name: "IconButtonFxExamples",
  components: {
    VueIconButtonFx,
    VueAlert,
    Heart,
    Download,
    Bell,
    Trash2,
    Menu,
    Home,
    Search,
    Edit,
    Bookmark,
    ThumbsUp,
    MessageCircle,
    Send,
    Star,
    Check,
    Plus,
    Minus,
    Settings,
  },
});
</script>
Live Preview
View Lit / Web Component Code
import { LitElement, html, css } from 'lit';
import 'agnosticui-core/icon-button-fx';
import 'agnosticui-core/alert';

export class IconButtonFxLitExamples extends LitElement {
  static styles = css`
    .examples-container {
      width: 100%;
    }
    .example-section {
      margin-block-end: 3rem;
    }
    .effect-group {
      margin-block-end: 2rem;
    }
    .use-case-group {
      margin-block-end: 2rem;
    }
    .example-description {
      color: var(--ag-text-secondary, #666);
      margin-block-end: 1rem;
    }
    .effect-type {
      font-size: 0.875rem;
      color: var(--ag-text-secondary, #666);
      font-weight: normal;
    }
    .full-w-h {
      width: 100%;
      height: 100%;
    }
  `;

  // Render in light DOM to access global utility classes
  createRenderRoot() {
    return this;
  }

  render() {
    return html`
      <div class="examples-container">
        <!-- Basic Effects -->
        <section class="example-section">
          <div class="mbe4">
            <h2>Basic Effects</h2>
            <p class="example-description">All available effects</p>
          </div>

          <!-- Pulse Effect -->
          <div class="effect-group">
            <h3>Pulse <span class="effect-type">Scale grow (hover)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="pulse" variant="primary" label="Pulse Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse" variant="success" label="Pulse Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse" variant="warning" label="Pulse Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse" variant="danger" label="Pulse Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse" variant="ghost" label="Pulse Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <circle cx="12" cy="12" r="3"></circle>
                  <path d="M12 1v6m0 6v6M5.6 5.6l4.2 4.2m4.2 4.2l4.2 4.2M1 12h6m6 0h6M5.6 18.4l4.2-4.2m4.2-4.2l4.2-4.2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse" variant="primary" label="Pulse Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <!-- Bounce Effect -->
          <div class="effect-group">
            <h3>Bounce <span class="effect-type">Vertical pop (hover)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="bounce" variant="primary" label="Bounce Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                  <polyline points="7 10 12 15 17 10"></polyline>
                  <line x1="12" y1="15" x2="12" y2="3"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="bounce" variant="success" label="Bounce Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="bounce" variant="warning" label="Bounce Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="bounce" variant="danger" label="Bounce Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="bounce" variant="ghost" label="Bounce Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                  <polyline points="7 10 12 15 17 10"></polyline>
                  <line x1="12" y1="15" x2="12" y2="3"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="bounce" variant="success" label="Bounce Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                  <polyline points="7 10 12 15 17 10"></polyline>
                  <line x1="12" y1="15" x2="12" y2="3"></line>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <!-- Wobble Effect -->
          <div class="effect-group">
            <h3>Wobble <span class="effect-type">Rotate wobble (hover)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="wobble" variant="primary" label="Wobble Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="wobble" variant="success" label="Wobble Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="wobble" variant="warning" label="Wobble Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="wobble" variant="danger" label="Wobble Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="wobble" variant="ghost" label="Wobble Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="wobble" variant="warning" label="Wobble Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <!-- Shake Effect -->
          <div class="effect-group">
            <h3>Shake <span class="effect-type">Horizontal shake (hover)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="shake" variant="primary" label="Shake Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shake" variant="success" label="Shake Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shake" variant="warning" label="Shake Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shake" variant="danger" label="Shake Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shake" variant="ghost" label="Shake Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shake" variant="danger" label="Shake Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <!-- Pulse-Wobble Effect -->
          <div class="effect-group">
            <h3>Pulse-Wobble <span class="effect-type">Sequential animation (hover)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="pulse-wobble" fx-speed="xl" variant="primary" label="Pulse-Wobble Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse-wobble" fx-speed="xl" variant="success" label="Pulse-Wobble Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse-wobble" fx-speed="xl" variant="warning" label="Pulse-Wobble Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse-wobble" fx-speed="xl" variant="danger" label="Pulse-Wobble Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse-wobble" fx-speed="xl" variant="ghost" label="Pulse-Wobble Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse-wobble" fx-speed="xl" variant="primary" label="Pulse-Wobble Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <!-- Jelly Effect -->
          <div class="effect-group">
            <h3>Jelly <span class="effect-type">Squash/stretch (hover)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="jelly" variant="primary" label="Jelly Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="jelly" variant="success" label="Jelly Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="jelly" variant="warning" label="Jelly Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="jelly" variant="danger" label="Jelly Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="jelly" variant="ghost" label="Jelly Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="jelly" variant="warning" label="Jelly Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <!-- Press-Pop Effect -->
          <div class="effect-group">
            <h3>Press-Pop <span class="effect-type">Quick press (click)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="press-pop" variant="primary" label="Press-Pop Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="press-pop" variant="success" label="Press-Pop Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="press-pop" variant="warning" label="Press-Pop Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="press-pop" variant="danger" label="Press-Pop Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="press-pop" variant="ghost" label="Press-Pop Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="press-pop" variant="success" label="Press-Pop Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <polyline points="20 6 9 17 4 12"></polyline>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <!-- Grow Effect -->
          <div class="effect-group">
            <h3>Grow <span class="effect-type">Scale up (hover)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="grow" variant="primary" label="Grow Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="12" y1="5" x2="12" y2="19"></line>
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="grow" variant="success" label="Grow Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="12" y1="5" x2="12" y2="19"></line>
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="grow" variant="warning" label="Grow Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="12" y1="5" x2="12" y2="19"></line>
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="grow" variant="danger" label="Grow Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="12" y1="5" x2="12" y2="19"></line>
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="grow" variant="ghost" label="Grow Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="12" y1="5" x2="12" y2="19"></line>
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="grow" variant="primary" label="Grow Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="12" y1="5" x2="12" y2="19"></line>
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <!-- Shrink Effect -->
          <div class="effect-group">
            <h3>Shrink <span class="effect-type">Scale down (hover)</span></h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="shrink" variant="primary" label="Shrink Primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shrink" variant="success" label="Shrink Success">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shrink" variant="warning" label="Shrink Warning">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shrink" variant="danger" label="Shrink Danger">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shrink" variant="ghost" label="Shrink Ghost">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shrink" variant="danger" label="Shrink Large">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="5" y1="12" x2="19" y2="12"></line>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>
        </section>

        <!-- Speed Variations -->
        <section class="example-section">
          <div class="mbe4">
            <h2>Speed Variations</h2>
            <p class="example-description">Control animation speed with the <code>fx-speed</code> attribute</p>
          </div>
          <div class="stacked-mobile">
            <ag-icon-button-fx fx="pulse" fx-speed="xs" variant="primary" label="Extra fast">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <ag-icon-button-fx fx="pulse" fx-speed="sm" variant="primary" label="Fast">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <ag-icon-button-fx fx="pulse" fx-speed="md" variant="primary" label="Medium">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <ag-icon-button-fx fx="pulse" fx-speed="lg" variant="primary" label="Slow">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <ag-icon-button-fx fx="pulse" fx-speed="xl" variant="primary" label="Extra slow">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
          </div>
        </section>

        <!-- Easing Functions -->
        <section class="example-section">
          <div class="mbe4">
            <h2>Easing Functions</h2>
            <p class="mbe2">Different easing functions create different animation feels</p>
            <ag-alert bordered-left>
              Examples use <code>fx-speed="xl"</code> to make easing differences more visible.
              For production, prefer <code>"sm"</code> or <code>"md"</code> speeds.
            </ag-alert>
          </div>
          <div class="stacked" style="width: 40%;">
            <span>Ease <code>(ease)</code></span>
            <ag-icon-button-fx fx="bounce" fx-ease="ease" fx-speed="xl" variant="primary" label="Ease">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <span>Ease In <code>(ease-in)</code></span>
            <ag-icon-button-fx fx="bounce" fx-ease="ease-in" fx-speed="xl" variant="primary" label="Ease-In">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <span>Ease Out <code>(ease-out)</code></span>
            <ag-icon-button-fx fx="bounce" fx-ease="ease-out" fx-speed="xl" variant="primary" label="Ease-Out">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>

            <span>Bounce<code>(bounce)</code></span>
            <ag-icon-button-fx fx="bounce" fx-ease="bounce" fx-speed="xl" variant="primary" label="Bounce">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <span>Spring Small <code>(spring-sm)</code></span>
            <ag-icon-button-fx fx="bounce" fx-ease="spring-sm" fx-speed="xl" variant="primary" label="Spring SM">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <span>Spring Medium <code>(spring-md)</code></span>
            <ag-icon-button-fx fx="bounce" fx-ease="spring-md" fx-speed="xl" variant="primary" label="Spring MD">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <span>Spring Large <code>(spring-lg)</code></span>
            <ag-icon-button-fx fx="bounce" fx-ease="spring-lg" fx-speed="xl" variant="primary" label="Spring LG">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
          </div>
        </section>

        <!-- Size Variations -->
        <section class="example-section">
          <div class="mbe4">
            <h2>Size Variations</h2>
            <p class="example-description">For <code>xs</code> and <code>sm</code> sizes, use an icon size <code>20px</code> or less, or, allow the icon to scale with: <code>width: 100%</code> and <code>height: 100%</code>.</p>
          </div>
          <div class="stacked-mobile">
            <ag-icon-button-fx fx="pulse" size="xs" variant="primary" bordered label="Extra small">
              <svg class="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <ag-icon-button-fx fx="pulse" size="sm" variant="primary" label="Small">
              <svg class="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <ag-icon-button-fx fx="pulse" size="md" variant="primary" label="Medium">
              <svg class="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <ag-icon-button-fx fx="pulse" size="lg" variant="primary" label="Large">
              <svg class="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
            <ag-icon-button-fx fx="pulse" size="xl" variant="primary" label="Extra large">
              <svg class="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
          </div>
        </section>

        <!-- Common Use Cases -->
        <section class="example-section">
          <div class="mbe4">
            <h2>Common Use Cases</h2>
          </div>

          <div class="use-case-group">
            <h3>Navigation</h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="grow" variant="ghost" label="Menu">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="3" y1="12" x2="21" y2="12"></line>
                  <line x1="3" y1="6" x2="21" y2="6"></line>
                  <line x1="3" y1="18" x2="21" y2="18"></line>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="grow" variant="ghost" label="Home">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
                  <polyline points="9 22 9 12 15 12 15 22"></polyline>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="grow" variant="ghost" label="Search">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <circle cx="11" cy="11" r="8"></circle>
                  <path d="m21 21-4.35-4.35"></path>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <div class="use-case-group">
            <h3>Actions</h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="pulse" variant="primary" label="Edit">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
                  <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="shake" variant="danger" label="Delete">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M3 6h18"></path>
                  <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                  <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="bounce" variant="success" label="Bookmark">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="m19 21-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z"></path>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <div class="use-case-group">
            <h3>Notifications</h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="wobble" variant="warning" label="Notifications">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="pulse-wobble" variant="danger" label="Important notification">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                  <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>

          <div class="use-case-group">
            <h3>Social</h3>
            <div class="stacked-mobile">
              <ag-icon-button-fx fx="pulse" variant="ghost" label="Like">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M7 10v12"></path>
                  <path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2h0a3.13 3.13 0 0 1 3 3.88Z"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="bounce" variant="ghost" label="Comment">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"></path>
                </svg>
              </ag-icon-button-fx>
              <ag-icon-button-fx fx="grow" variant="ghost" label="Send">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                  <line x1="22" y1="2" x2="11" y2="13"></line>
                  <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
                </svg>
              </ag-icon-button-fx>
            </div>
          </div>
        </section>

        <!-- Disabled Effects -->
        <section class="example-section">
          <div class="mbe4">
            <h2>Disabling Effects</h2>
            <p class="example-description">
              This button has <code>fx="pulse"</code> but <code>fx-disabled="true"</code>
              prevents the animation from playing while keeping the button clickable
            </p>
          </div>
          <div class="stacked-mobile">
            <ag-icon-button-fx fx="pulse" fx-disabled variant="primary" label="No animation">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ag-icon-button-fx>
          </div>
        </section>
      </div>
    `;
  }
}

// Register the custom element
customElements.define('icon-button-fx-lit-examples', IconButtonFxLitExamples);

Interactive Preview: Click the "Open in StackBlitz" button below to see this example running live in an interactive playground.

View React Code
import { ReactIconButtonFx } from "agnosticui-core/icon-button-fx/react";
import { ReactAlert } from "agnosticui-core/alert/react";

export default function IconButtonFxReactExamples() {
  return (
    <div className="examples-container">
      <style>{`
        .examples-container {
          width: 100%;
        }
        .example-section {
          margin-block-end: 3rem;
        }
        .effect-group {
          margin-block-end: 2rem;
        }
        .use-case-group {
          margin-block-end: 2rem;
        }
        .example-description {
          color: var(--ag-text-secondary, #666);
          margin-block-end: 1rem;
        }
        .effect-type {
          font-size: 0.875rem;
          color: var(--ag-text-secondary, #666);
          font-weight: normal;
        }
        .full-w-h {
          width: 100%;
          height: 100%;
        }
      `}</style>

      {/* Basic Effects */}
      <section className="example-section">
        <div className="mbe4">
          <h2>Basic Effects</h2>
          <p className="example-description">All available effects</p>
        </div>

        {/* Pulse Effect */}
        <div className="effect-group">
          <h3>Pulse <span className="effect-type">Scale grow (hover)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="pulse" variant="primary" label="Pulse Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse" variant="success" label="Pulse Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse" variant="warning" label="Pulse Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse" variant="danger" label="Pulse Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse" variant="ghost" label="Pulse Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <circle cx="12" cy="12" r="3"></circle>
                <path d="M12 1v6m0 6v6M5.6 5.6l4.2 4.2m4.2 4.2l4.2 4.2M1 12h6m6 0h6M5.6 18.4l4.2-4.2m4.2-4.2l4.2-4.2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse" variant="primary" label="Pulse Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        {/* Bounce Effect */}
        <div className="effect-group">
          <h3>Bounce <span className="effect-type">Vertical pop (hover)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="bounce" variant="primary" label="Bounce Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                <polyline points="7 10 12 15 17 10"></polyline>
                <line x1="12" y1="15" x2="12" y2="3"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="bounce" variant="success" label="Bounce Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="bounce" variant="warning" label="Bounce Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="bounce" variant="danger" label="Bounce Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="bounce" variant="ghost" label="Bounce Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                <polyline points="7 10 12 15 17 10"></polyline>
                <line x1="12" y1="15" x2="12" y2="3"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="bounce" variant="success" label="Bounce Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                <polyline points="7 10 12 15 17 10"></polyline>
                <line x1="12" y1="15" x2="12" y2="3"></line>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        {/* Wobble Effect */}
        <div className="effect-group">
          <h3>Wobble <span className="effect-type">Rotate wobble (hover)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="wobble" variant="primary" label="Wobble Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="wobble" variant="success" label="Wobble Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="wobble" variant="warning" label="Wobble Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="wobble" variant="danger" label="Wobble Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="wobble" variant="ghost" label="Wobble Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="wobble" variant="warning" label="Wobble Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        {/* Shake Effect */}
        <div className="effect-group">
          <h3>Shake <span className="effect-type">Horizontal shake (hover)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="shake" variant="primary" label="Shake Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shake" variant="success" label="Shake Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shake" variant="warning" label="Shake Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shake" variant="danger" label="Shake Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shake" variant="ghost" label="Shake Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shake" variant="danger" label="Shake Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        {/* Pulse-Wobble Effect */}
        <div className="effect-group">
          <h3>Pulse-Wobble <span className="effect-type">Sequential animation (hover)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="pulse-wobble" fxSpeed="xl" variant="primary" label="Pulse-Wobble Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse-wobble" fxSpeed="xl" variant="success" label="Pulse-Wobble Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse-wobble" fxSpeed="xl" variant="warning" label="Pulse-Wobble Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse-wobble" fxSpeed="xl" variant="danger" label="Pulse-Wobble Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse-wobble" fxSpeed="xl" variant="ghost" label="Pulse-Wobble Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse-wobble" fxSpeed="xl" variant="primary" label="Pulse-Wobble Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        {/* Jelly Effect */}
        <div className="effect-group">
          <h3>Jelly <span className="effect-type">Squash/stretch (hover)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="jelly" variant="primary" label="Jelly Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="jelly" variant="success" label="Jelly Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="jelly" variant="warning" label="Jelly Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="jelly" variant="danger" label="Jelly Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="jelly" variant="ghost" label="Jelly Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="jelly" variant="warning" label="Jelly Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        {/* Press-Pop Effect */}
        <div className="effect-group">
          <h3>Press-Pop <span className="effect-type">Quick press (click)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="press-pop" variant="primary" label="Press-Pop Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="press-pop" variant="success" label="Press-Pop Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="press-pop" variant="warning" label="Press-Pop Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="press-pop" variant="danger" label="Press-Pop Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="press-pop" variant="ghost" label="Press-Pop Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="press-pop" variant="success" label="Press-Pop Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="20 6 9 17 4 12"></polyline>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        {/* Grow Effect */}
        <div className="effect-group">
          <h3>Grow <span className="effect-type">Scale up (hover)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="grow" variant="primary" label="Grow Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="12" y1="5" x2="12" y2="19"></line>
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="grow" variant="success" label="Grow Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="12" y1="5" x2="12" y2="19"></line>
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="grow" variant="warning" label="Grow Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="12" y1="5" x2="12" y2="19"></line>
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="grow" variant="danger" label="Grow Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="12" y1="5" x2="12" y2="19"></line>
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="grow" variant="ghost" label="Grow Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="12" y1="5" x2="12" y2="19"></line>
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="grow" variant="primary" label="Grow Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="12" y1="5" x2="12" y2="19"></line>
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        {/* Shrink Effect */}
        <div className="effect-group">
          <h3>Shrink <span className="effect-type">Scale down (hover)</span></h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="shrink" variant="primary" label="Shrink Primary">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shrink" variant="success" label="Shrink Success">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shrink" variant="warning" label="Shrink Warning">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shrink" variant="danger" label="Shrink Danger">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shrink" variant="ghost" label="Shrink Ghost">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shrink" variant="danger" label="Shrink Large">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="5" y1="12" x2="19" y2="12"></line>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>
      </section>

      {/* Speed Variations */}
      <section className="example-section">
        <div className="mbe4">
          <h2>Speed Variations</h2>
          <p className="example-description">Control animation speed with the <code>fxSpeed</code> prop</p>
        </div>
        <div className="stacked-mobile">
          <ReactIconButtonFx fx="pulse" fxSpeed="xs" variant="primary" label="Extra fast">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <ReactIconButtonFx fx="pulse" fxSpeed="sm" variant="primary" label="Fast">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <ReactIconButtonFx fx="pulse" fxSpeed="md" variant="primary" label="Medium">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <ReactIconButtonFx fx="pulse" fxSpeed="lg" variant="primary" label="Slow">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <ReactIconButtonFx fx="pulse" fxSpeed="xl" variant="primary" label="Extra slow">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
        </div>
      </section>

      {/* Easing Functions */}
      <section className="example-section">
        <div className="mbe4">
          <h2>Easing Functions</h2>
          <p className="mbe2">Different easing functions create different animation feels</p>
          <ReactAlert borderedLeft>
            Examples use <code>fxSpeed="xl"</code> to make easing differences more visible.
            For production, prefer <code>"sm"</code> or <code>"md"</code> speeds.
          </ReactAlert>
        </div>
        <div className="stacked" style={{ width: '40%' }}>
          <span>Ease <code>(ease)</code></span>
          <ReactIconButtonFx fx="bounce" fxEase="ease" fxSpeed="xl" variant="primary" label="Ease">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <span>Ease In <code>(ease-in)</code></span>
          <ReactIconButtonFx fx="bounce" fxEase="ease-in" fxSpeed="xl" variant="primary" label="Ease-In">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <span>Ease Out <code>(ease-out)</code></span>
          <ReactIconButtonFx fx="bounce" fxEase="ease-out" fxSpeed="xl" variant="primary" label="Ease-Out">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>

          <span>Bounce <code>(bounce)</code></span>
          <ReactIconButtonFx fx="bounce" fxEase="bounce" fxSpeed="xl" variant="primary" label="Bounce">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <span>Spring Small <code>(spring-sm)</code></span>
          <ReactIconButtonFx fx="bounce" fxEase="spring-sm" fxSpeed="xl" variant="primary" label="Spring SM">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <span>Spring Medium <code>(spring-md)</code></span>
          <ReactIconButtonFx fx="bounce" fxEase="spring-md" fxSpeed="xl" variant="primary" label="Spring MD">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <span>Spring Large <code>(spring-lg)</code></span>
          <ReactIconButtonFx fx="bounce" fxEase="spring-lg" fxSpeed="xl" variant="primary" label="Spring LG">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
        </div>
      </section>

      {/* Size Variations */}
      <section className="example-section">
        <div className="mbe4">
          <h2>Size Variations</h2>
          <p className="example-description">For <code>xs</code> and <code>sm</code> sizes, use an icon size <code>20px</code> or less, or, allow the icon to scale with: <code>width: 100%</code> and <code>height: 100%</code>.</p>
        </div>
        <div className="stacked-mobile">
          <ReactIconButtonFx fx="pulse" size="xs" variant="primary" bordered label="Extra small">
            <svg className="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <ReactIconButtonFx fx="pulse" size="sm" variant="primary" label="Small">
            <svg className="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <ReactIconButtonFx fx="pulse" size="md" variant="primary" label="Medium">
            <svg className="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <ReactIconButtonFx fx="pulse" size="lg" variant="primary" label="Large">
            <svg className="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
          <ReactIconButtonFx fx="pulse" size="xl" variant="primary" label="Extra large">
            <svg className="full-w-h" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
        </div>
      </section>

      {/* Common Use Cases */}
      <section className="example-section">
        <div className="mbe4">
          <h2>Common Use Cases</h2>
        </div>

        <div className="use-case-group">
          <h3>Navigation</h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="grow" variant="ghost" label="Menu">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="3" y1="12" x2="21" y2="12"></line>
                <line x1="3" y1="6" x2="21" y2="6"></line>
                <line x1="3" y1="18" x2="21" y2="18"></line>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="grow" variant="ghost" label="Home">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
                <polyline points="9 22 9 12 15 12 15 22"></polyline>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="grow" variant="ghost" label="Search">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <circle cx="11" cy="11" r="8"></circle>
                <path d="m21 21-4.35-4.35"></path>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        <div className="use-case-group">
          <h3>Actions</h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="pulse" variant="primary" label="Edit">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
                <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="shake" variant="danger" label="Delete">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M3 6h18"></path>
                <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path>
                <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="bounce" variant="success" label="Bookmark">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="m19 21-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z"></path>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        <div className="use-case-group">
          <h3>Notifications</h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="wobble" variant="warning" label="Notifications">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="pulse-wobble" variant="danger" label="Important notification">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"></path>
                <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"></path>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>

        <div className="use-case-group">
          <h3>Social</h3>
          <div className="stacked-mobile">
            <ReactIconButtonFx fx="pulse" variant="ghost" label="Like">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M7 10v12"></path>
                <path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2h0a3.13 3.13 0 0 1 3 3.88Z"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="bounce" variant="ghost" label="Comment">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"></path>
              </svg>
            </ReactIconButtonFx>
            <ReactIconButtonFx fx="grow" variant="ghost" label="Send">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <line x1="22" y1="2" x2="11" y2="13"></line>
                <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
              </svg>
            </ReactIconButtonFx>
          </div>
        </div>
      </section>

      {/* Disabled Effects */}
      <section className="example-section">
        <div className="mbe4">
          <h2>Disabling Effects</h2>
          <p className="example-description">
            This button has <code>fx="pulse"</code> but <code>fxDisabled={"{true}"}</code>
            prevents the animation from playing while keeping the button clickable
          </p>
        </div>
        <div className="stacked-mobile">
          <ReactIconButtonFx fx="pulse" fxDisabled={true} variant="primary" label="No animation">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
            </svg>
          </ReactIconButtonFx>
        </div>
      </section>
    </div>
  );
}
Open in StackBlitz

Usage

TIP

The framework examples below import AgnosticUI as an npm package. Alternatively, you can use the CLI for complete control, AI/LLM visibility, and full code ownership:

bash
npx ag init --framework FRAMEWORK # react, vue, lit, svelte, etc.
npx ag add IconButtonFx

The CLI copies source code directly into your project, giving you full visibility and control. After running npx ag add, you'll receive exact import instructions.

Vue
vue
<template>
  <VueIconButtonFx
    fx="pulse"
    fx-ease="spring-md"
    variant="primary"
    label="Like"
  >
    <Heart />
  </VueIconButtonFx>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { VueIconButtonFx } from "agnosticui-core/icon-button-fx/vue";
import { Heart } from "lucide-vue-next";
export default defineComponent({
  components: { VueIconButtonFx, Heart },
});
</script>
React
tsx
import { ReactIconButtonFx } from "agnosticui-core/icon-button-fx/react";
import { Heart } from "lucide-react";

export default function Example() {
  return (
    <ReactIconButtonFx
      fx="pulse"
      fxEase="spring-md"
      variant="primary"
      label="Like"
    >
      <Heart />
    </ReactIconButtonFx>
  );
}
Lit (Web Components)
html
<script type="module">
  import "agnosticui-core/icon-button-fx";
  import { createElement } from "lucide";
  import { Heart } from "lucide";

  const iconButtonFx = document.querySelector("ag-icon-button-fx");
  iconButtonFx.icon = createElement(Heart);
</script>
<ag-icon-button-fx
  fx="pulse"
  fx-ease="spring-md"
  variant="primary"
  label="Like"
></ag-icon-button-fx>

Available Effects

Hover Effects

  • bounce - Vertical pop animation
  • pulse - Scale grow effect
  • jelly - Squash and stretch animation
  • grow - Scale up
  • shrink - Scale down
  • push - Press down effect
  • wobble - Rotate wobble
  • shake - Horizontal shake

Click/Active Effects

  • press-pop - Quick press animation

Mount Effects

  • slide-in - Entrance animation

Composite Effects

  • pulse-wobble - Combines pulse and wobble effects sequentially. For this effect it's recommended to use a slower fx-speed.

Props

FX Props

PropTypeDefaultDescription
fxstring''Effect name to apply
fxSpeed'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Animation duration speed
fxEase'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'bounce' | 'spring-sm' | 'spring-md' | 'spring-lg''ease'Animation easing function
fxDisabledbooleanfalseDisable FX effects entirely

IconButton Props

PropTypeDefaultDescription
labelstring''Accessible label for the icon button (required)
variant'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'monochrome' | 'ghost''ghost'Visual style variant
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Size of the button
type'button' | 'submit' | 'reset''button'Button type for form behavior
disabledbooleanfalseDisables the button
pressedbooleanfalseToggles aria-pressed state
loadingbooleanfalseShows loading state
unicodestring''Unicode character to display as icon

Events

EventPayloadDescription
icon-button-clickIconButtonClickEventFired when icon button is clicked
icon-button-activateIconButtonActivateEventFired when icon button is activated

Examples

Basic Effects

Vue
vue
<template>
  <VueIconButtonFx fx="pulse" variant="primary" label="Like">
    <Heart />
  </VueIconButtonFx>
  <VueIconButtonFx fx="bounce" variant="success" label="Download">
    <Download />
  </VueIconButtonFx>
  <VueIconButtonFx fx="wobble" variant="warning" label="Notifications">
    <Bell />
  </VueIconButtonFx>
  <VueIconButtonFx fx="shake" variant="danger" label="Delete">
    <Trash2 />
  </VueIconButtonFx>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { VueIconButtonFx } from "agnosticui-core/icon-button-fx/vue";
import { Heart, Download, Bell, Trash2 } from "lucide-vue-next";
export default defineComponent({
  components: { VueIconButtonFx, Heart, Download, Bell, Trash2 },
});
</script>
React
tsx
import { ReactIconButtonFx } from "agnosticui-core/icon-button-fx/react";
import { Heart, Download, Bell, Trash2 } from "lucide-react";

export default function Example() {
  return (
    <>
      <ReactIconButtonFx fx="pulse" variant="primary" label="Like">
        <Heart />
      </ReactIconButtonFx>
      <ReactIconButtonFx fx="bounce" variant="success" label="Download">
        <Download />
      </ReactIconButtonFx>
      <ReactIconButtonFx fx="wobble" variant="warning" label="Notifications">
        <Bell />
      </ReactIconButtonFx>
      <ReactIconButtonFx fx="shake" variant="danger" label="Delete">
        <Trash2 />
      </ReactIconButtonFx>
    </>
  );
}

Speed Variations

Control animation speed with the fxSpeed prop:

Vue
vue
<VueIconButtonFx fx="pulse" fx-speed="xs" variant="primary" label="Extra fast">
  <Heart />
</VueIconButtonFx>
<VueIconButtonFx fx="pulse" fx-speed="sm" variant="primary" label="Fast">
  <Heart />
</VueIconButtonFx>
<VueIconButtonFx fx="pulse" fx-speed="md" variant="primary" label="Medium">
  <Heart />
</VueIconButtonFx>
<VueIconButtonFx fx="pulse" fx-speed="lg" variant="primary" label="Slow">
  <Heart />
</VueIconButtonFx>
<VueIconButtonFx fx="pulse" fx-speed="xl" variant="primary" label="Extra slow">
  <Heart />
</VueIconButtonFx>

Easing Functions

Customize the animation feel with different easing functions:

Vue
vue
<VueIconButtonFx
  fx="bounce"
  fx-ease="spring-sm"
  variant="primary"
  label="Spring Small"
>
  <Heart />
</VueIconButtonFx>
<VueIconButtonFx
  fx="bounce"
  fx-ease="spring-md"
  variant="primary"
  label="Spring Medium"
>
  <Heart />
</VueIconButtonFx>
<VueIconButtonFx
  fx="bounce"
  fx-ease="spring-lg"
  variant="primary"
  label="Spring Large"
>
  <Heart />
</VueIconButtonFx>
<VueIconButtonFx fx="bounce" fx-ease="bounce" variant="primary" label="Bounce">
  <Heart />
</VueIconButtonFx>

Composite Effect - Pulse Wobble

The special pulse-wobble effect creates a two-stage animation:

Vue
vue
<VueIconButtonFx fx="pulse-wobble" variant="primary" label="Favorite">
  <Heart />
</VueIconButtonFx>
React
tsx
<ReactIconButtonFx fx="pulse-wobble" variant="primary" label="Favorite">
  <Heart />
</ReactIconButtonFx>
Lit (Web Components)
html
<script type="module">
  import "agnosticui-core/icon-button-fx";
  import { createElement } from "lucide";
  import { Heart } from "lucide";

  const iconButtonFx = document.querySelector("#pulse-wobble");
  iconButtonFx.icon = createElement(Heart);
</script>
<ag-icon-button-fx
  id="pulse-wobble"
  fx="pulse-wobble"
  variant="primary"
  label="Favorite"
></ag-icon-button-fx>

Icon Scaling for Small Sizes

Important: Icon Scaling

For xs and sm button sizes, you need to ensure icons scale properly to fill the button's icon container.

Vue
vue
<template>
  <VueIconButtonFx fx="pulse" size="xs" variant="primary" label="Extra small">
    <Heart :size="12" />
  </VueIconButtonFx>
  <VueIconButtonFx fx="pulse" size="sm" variant="primary" label="Small">
    <Heart :size="16" />
  </VueIconButtonFx>

  <VueIconButtonFx fx="pulse" size="md" variant="primary" label="Medium">
    <Heart />
  </VueIconButtonFx>
  <VueIconButtonFx fx="pulse" size="lg" variant="primary" label="Large">
    <Heart />
  </VueIconButtonFx>
  <VueIconButtonFx fx="pulse" size="xl" variant="primary" label="Extra large">
    <Heart />
  </VueIconButtonFx>
</template>
React
tsx
import { ReactIconButtonFx } from "agnosticui-core/icon-button-fx/react";
import { Heart } from "lucide-react";

export default function Example() {
  return (
    <>
      <ReactIconButtonFx
        fx="pulse"
        size="xs"
        variant="primary"
        label="Extra small"
      >
        <Heart width="100%" height="100%" />
      </ReactIconButtonFx>
      <ReactIconButtonFx fx="pulse" size="sm" variant="primary" label="Small">
        <Heart width="100%" height="100%" />
      </ReactIconButtonFx>

      <ReactIconButtonFx fx="pulse" size="md" variant="primary" label="Medium">
        <Heart />
      </ReactIconButtonFx>
      <ReactIconButtonFx fx="pulse" size="lg" variant="primary" label="Large">
        <Heart />
      </ReactIconButtonFx>
      <ReactIconButtonFx
        fx="pulse"
        size="xl"
        variant="primary"
        label="Extra large"
      >
        <Heart />
      </ReactIconButtonFx>
    </>
  );
}
Lit (Web Components)
html
<script type="module">
  import "agnosticui-core/icon-button-fx";
  import { createElement } from "lucide";
  import { Heart } from "lucide";

  const iconXs = document.querySelector("#icon-xs");
  iconXs.icon = createElement(Heart, { width: "100%", height: "100%" });

  const iconSm = document.querySelector("#icon-sm");
  iconSm.icon = createElement(Heart, { width: "100%", height: "100%" });

  const iconMd = document.querySelector("#icon-md");
  iconMd.icon = createElement(Heart);
</script>

<ag-icon-button-fx
  id="icon-xs"
  fx="pulse"
  size="xs"
  variant="primary"
  label="Extra small"
></ag-icon-button-fx>
<ag-icon-button-fx
  id="icon-sm"
  fx="pulse"
  size="sm"
  variant="primary"
  label="Small"
></ag-icon-button-fx>
<ag-icon-button-fx
  id="icon-md"
  fx="pulse"
  size="md"
  variant="primary"
  label="Medium"
></ag-icon-button-fx>

Common Use Cases

Vue
vue
<template>
  <VueIconButtonFx fx="grow" variant="ghost" label="Menu">
    <Menu />
  </VueIconButtonFx>
  <VueIconButtonFx fx="grow" variant="ghost" label="Home">
    <Home />
  </VueIconButtonFx>
  <VueIconButtonFx fx="grow" variant="ghost" label="Search">
    <Search />
  </VueIconButtonFx>

  <VueIconButtonFx fx="pulse" variant="primary" label="Edit">
    <Edit />
  </VueIconButtonFx>
  <VueIconButtonFx fx="shake" variant="danger" label="Delete">
    <Trash2 />
  </VueIconButtonFx>
  <VueIconButtonFx fx="bounce" variant="success" label="Bookmark">
    <Bookmark />
  </VueIconButtonFx>

  <VueIconButtonFx fx="wobble" variant="warning" label="Notifications">
    <Bell />
  </VueIconButtonFx>
  <VueIconButtonFx
    fx="pulse-wobble"
    variant="danger"
    label="Important notification"
  >
    <Bell />
  </VueIconButtonFx>

  <VueIconButtonFx fx="pulse" variant="ghost" label="Like">
    <ThumbsUp />
  </VueIconButtonFx>
  <VueIconButtonFx fx="bounce" variant="ghost" label="Comment">
    <MessageCircle />
  </VueIconButtonFx>
  <VueIconButtonFx fx="grow" variant="primary" label="Send">
    <Send />
  </VueIconButtonFx>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { VueIconButtonFx } from "agnosticui-core/icon-button-fx/vue";
import {
  Menu,
  Home,
  Search,
  Edit,
  Trash2,
  Bookmark,
  Bell,
  ThumbsUp,
  MessageCircle,
  Send,
} from "lucide-vue-next";
export default defineComponent({
  components: {
    VueIconButtonFx,
    Menu,
    Home,
    Search,
    Edit,
    Trash2,
    Bookmark,
    Bell,
    ThumbsUp,
    MessageCircle,
    Send,
  },
});
</script>

Disabling Effects

You can disable effects while keeping the button functional:

Vue
vue
<VueIconButtonFx
  fx="pulse"
  :fx-disabled="true"
  variant="primary"
  label="No animation"
>
  <Heart />
</VueIconButtonFx>
React
tsx
<ReactIconButtonFx
  fx="pulse"
  fxDisabled={true}
  variant="primary"
  label="No animation"
>
  <Heart />
</ReactIconButtonFx>

Accessibility

  • Required Label: The label prop is required for screen reader accessibility. It provides context for users who cannot see the icon.
  • Reduced Motion: All effects automatically respect the prefers-reduced-motion media query. When users have reduced motion enabled in their OS settings, animations are disabled.
  • Keyboard Navigation: IconButtonFx maintains full keyboard accessibility with proper focus states.
  • Screen Readers: The component uses semantic HTML button elements with proper aria-label attributes that work correctly with assistive technologies.
  • Focus Indicators: Clear focus states are maintained even with effects applied.
  • Color Contrast: All button variants meet WCAG AA contrast requirements.
  • Icon-only Buttons: Since these are icon-only buttons, the label prop is essential for accessibility. Never omit it.

Best Practices

  1. Always Provide Labels: Never omit the label prop. It's critical for screen reader users to understand the button's purpose.
  2. Choose Appropriate Effects: Match effects to button purpose:
    • shake for destructive actions (delete, remove)
    • pulse or pulse-wobble for important actions (favorite, like)
    • wobble for notifications and alerts
    • bounce for positive actions (download, bookmark)
    • grow for navigation and general interactions
  3. Icon Scaling: For xs and sm button sizes, always specify icon dimensions to ensure proper scaling within the button container.
  4. Performance: Limit the number of animated icon buttons on a single page for optimal performance.
  5. Consistency: Use consistent effects across similar actions in your application.
  6. Subtlety: Start with medium speeds and springs; adjust based on user testing.
  7. Testing: Always test with prefers-reduced-motion enabled to ensure graceful degradation.

Browser Support

IconButtonFx uses modern CSS features and is supported in all evergreen browsers:

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+

Animations gracefully degrade in older browsers while maintaining functionality.