Actions Core Stable
IconButton
Square or circular icon-only button built on Button, with a required accessible label
Preview
svelte
<script lang="ts">
import { IconButton } from "fancy-ui-svelte";
let liked = $state(false);
</script>
<IconButton
label={liked ? "Unlike" : "Like"}
variant={liked ? "accent" : "outline"}
shape="circle"
onclick={() => (liked = !liked)}
>
<svg
class="size-4"
viewBox="0 0 24 24"
fill={liked ? "currentColor" : "none"}
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M12 20s-7-4.35-9.5-9A5.5 5.5 0 0 1 12 6a5.5 5.5 0 0 1 9.5 5c-2.5 4.65-9.5 9-9.5 9Z" />
</svg>
</IconButton>Installation
pnpm add fancy-ui-svelte
import { IconButton } from 'fancy-ui-svelte'
Usage
svelte
<script lang="ts">
import { IconButton } from 'fancy-ui-svelte';
</script>
<IconButton />Examples
Basic Usage
svelte
<script lang="ts">
import { IconButton } from "$lib/fancy-ui/icon-button";
let liked = $state(false);
</script>
<IconButton
label={liked ? "Unlike" : "Like"}
variant={liked ? "accent" : "outline"}
shape="circle"
onclick={() => (liked = !liked)}
>
<svg
class="size-4"
viewBox="0 0 24 24"
fill={liked ? "currentColor" : "none"}
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M12 20s-7-4.35-9.5-9A5.5 5.5 0 0 1 12 6a5.5 5.5 0 0 1 9.5 5c-2.5 4.65-9.5 9-9.5 9Z" />
</svg>
</IconButton>Variants
svelte
<script lang="ts">
import { IconButton } from "$lib/fancy-ui/icon-button";
</script>
<div class="flex flex-wrap items-center gap-3">
<IconButton label="Edit" variant="primary">
<svg
class="size-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M12 20h9" />
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z" />
</svg>
</IconButton>
<IconButton label="Duplicate" variant="secondary">
<svg
class="size-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<rect x="9" y="9" width="11" height="11" rx="2" />
<path d="M5 15V5a2 2 0 0 1 2-2h10" />
</svg>
</IconButton>
<IconButton label="Settings" variant="outline">
<svg
class="size-4"
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" />
<path
d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"
/>
</svg>
</IconButton>
<IconButton label="Like" variant="ghost">
<svg
class="size-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path
d="M12 20s-7-4.35-9.5-9A5.5 5.5 0 0 1 12 6a5.5 5.5 0 0 1 9.5 5c-2.5 4.65-9.5 9-9.5 9Z"
/>
</svg>
</IconButton>
<IconButton label="Add" variant="accent">
<svg
class="size-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M12 5v14M5 12h14" />
</svg>
</IconButton>
<IconButton label="Delete" variant="destructive">
<svg
class="size-4"
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 d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
<path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
</svg>
</IconButton>
</div>Sizes
svelte
<script lang="ts">
import { IconButton } from "$lib/fancy-ui/icon-button";
</script>
<div class="flex flex-wrap items-center gap-3">
<IconButton label="Settings" size="sm">
<svg
class="size-3.5"
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" />
<path
d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"
/>
</svg>
</IconButton>
<IconButton label="Settings" size="md">
<svg
class="size-4"
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" />
<path
d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"
/>
</svg>
</IconButton>
<IconButton label="Settings" size="lg">
<svg
class="size-[18px]"
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" />
<path
d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"
/>
</svg>
</IconButton>
</div>Shapes
svelte
<script lang="ts">
import { IconButton } from "$lib/fancy-ui/icon-button";
</script>
<div class="flex flex-wrap items-center gap-3">
<IconButton label="Settings (square)" variant="outline" shape="square">
<svg
class="size-4"
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" />
<path
d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"
/>
</svg>
</IconButton>
<IconButton label="Settings (circle)" variant="outline" shape="circle">
<svg
class="size-4"
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" />
<path
d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"
/>
</svg>
</IconButton>
<IconButton label="Like (square)" variant="ghost" shape="square">
<svg
class="size-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path
d="M12 20s-7-4.35-9.5-9A5.5 5.5 0 0 1 12 6a5.5 5.5 0 0 1 9.5 5c-2.5 4.65-9.5 9-9.5 9Z"
/>
</svg>
</IconButton>
<IconButton label="Like (circle)" variant="ghost" shape="circle">
<svg
class="size-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path
d="M12 20s-7-4.35-9.5-9A5.5 5.5 0 0 1 12 6a5.5 5.5 0 0 1 9.5 5c-2.5 4.65-9.5 9-9.5 9Z"
/>
</svg>
</IconButton>
</div>Props
| Prop | Type | Default | Description |
|---|---|---|---|
label * | string | - | Accessible name. Required — there is no visible text to fall back on |
variant | "primary" | "secondary" | "outline" | "ghost" | "accent" | "destructive" | "outline" | Visual treatment, forwarded to the underlying Button |
size | "sm" | "md" | "lg" | "md" | Square footprint (30 / 36 / 42px) and resting radius |
shape | "square" | "circle" | "square" | Square keeps the size's own radius; circle rounds it fully |
type | "button" | "submit" | "reset" | "button" | Native type; ignored once href renders an anchor instead |
disabled | boolean | false | Greys the control out and blocks activation |
loading | boolean | false | Spinner in place of the icon, aria-busy, blocks activation |
href | string | - | Renders an <a> instead of a <button> when set |
target | string | - | Anchor target. "_blank" forces a safe rel |
rel | string | - | Anchor rel, widened rather than replaced when target="_blank" |
onclick | (event: MouseEvent) => void | - | Fires on activation; never called while disabled or loading |
class | string | - | Additional CSS classes |
ref | HTMLButtonElement | HTMLAnchorElement | null | null | Bindable element reference |
Slots
| Slot | Description |
|---|---|
children | The icon, rendered centred |
Links
Related components
Bu
Button
The foundational push-button: six variants, three sizes, a loading state, and a polymorphic href/anchor mode
Actions Stable
Bu
ButtonGroup
Joins a row of adjacent actions into one seamless control — one border, one divider, no doubled edges
Actions Stable
Co
CopyButton
Button preset wired to the clipboard, swapping its icon and label to a success skin for a moment after a successful copy
Actions Stable