IconButtonFx
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
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
fx-speed="xl" to make easing differences more visible. For production, prefer "sm" or "md" speeds. (ease)(ease-in)(ease-out)(bounce)(spring-sm)(spring-md)(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>
);
}
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:
npx ag init --framework FRAMEWORK # react, vue, lit, svelte, etc.
npx ag add IconButtonFxThe 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
<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
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)
<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
| Prop | Type | Default | Description |
|---|---|---|---|
fx | string | '' | 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 |
fxDisabled | boolean | false | Disable FX effects entirely |
IconButton Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | '' | 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 |
disabled | boolean | false | Disables the button |
pressed | boolean | false | Toggles aria-pressed state |
loading | boolean | false | Shows loading state |
unicode | string | '' | Unicode character to display as icon |
Events
| Event | Payload | Description |
|---|---|---|
icon-button-click | IconButtonClickEvent | Fired when icon button is clicked |
icon-button-activate | IconButtonActivateEvent | Fired when icon button is activated |
Examples
Basic Effects
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
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
<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
<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
<VueIconButtonFx fx="pulse-wobble" variant="primary" label="Favorite">
<Heart />
</VueIconButtonFx>React
<ReactIconButtonFx fx="pulse-wobble" variant="primary" label="Favorite">
<Heart />
</ReactIconButtonFx>Lit (Web Components)
<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
<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
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)
<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
<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
<VueIconButtonFx
fx="pulse"
:fx-disabled="true"
variant="primary"
label="No animation"
>
<Heart />
</VueIconButtonFx>React
<ReactIconButtonFx
fx="pulse"
fxDisabled={true}
variant="primary"
label="No animation"
>
<Heart />
</ReactIconButtonFx>Accessibility
- Required Label: The
labelprop 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-motionmedia 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-labelattributes 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
labelprop is essential for accessibility. Never omit it.
Best Practices
- Always Provide Labels: Never omit the
labelprop. It's critical for screen reader users to understand the button's purpose. - Choose Appropriate Effects: Match effects to button purpose:
shakefor destructive actions (delete, remove)pulseorpulse-wobblefor important actions (favorite, like)wobblefor notifications and alertsbouncefor positive actions (download, bookmark)growfor navigation and general interactions
- Icon Scaling: For
xsandsmbutton sizes, always specify icon dimensions to ensure proper scaling within the button container. - Performance: Limit the number of animated icon buttons on a single page for optimal performance.
- Consistency: Use consistent effects across similar actions in your application.
- Subtlety: Start with medium speeds and springs; adjust based on user testing.
- Testing: Always test with
prefers-reduced-motionenabled 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.