# IconButton

> Square or circular icon-only button built on Button, with a required accessible label.

- Package: `fancy-ui-svelte` (Svelte 5 + Tailwind CSS v4)
- Category: Actions
- Tags: button, icon, action, accessibility
- Dependencies: button
- Docs: https://fancy-ui.rama.app/docs/components/icon-button
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/src/lib/fancy-ui/icon-button

## Import

```svelte
<script lang="ts">
  import { IconButton } from 'fancy-ui-svelte';
</script>
```

Setup (once per project): `npm install fancy-ui-svelte`, then add `@import "fancy-ui-svelte/tailwind.css";` after `@import "tailwindcss";` in your main CSS file. Full guide: https://fancy-ui.rama.app/llms.txt

React: `import { IconButton } from 'fancy-ui-react';` (same prop names; `class` becomes `className`, snippets become `ReactNode`).

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` (required) | `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 |
| `sound` | `boolean` | `false` | Plays the press cue on activation, once the user has enabled sound |

## Snippets

| Snippet | Description |
| --- | --- |
| `children` | The icon, rendered centred |

## Examples

### Basic Usage

```svelte
<script lang="ts">
	import { IconButton } from "fancy-ui-svelte";

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

<IconButton
	sound
	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 "fancy-ui-svelte";
</script>

<div class="flex flex-wrap items-center gap-3">
	<IconButton sound 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 sound 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 sound 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 sound 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 sound 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 sound 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 "fancy-ui-svelte";
</script>

<div class="flex flex-wrap items-center gap-3">
	<IconButton sound 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 sound 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 sound 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 "fancy-ui-svelte";
</script>

<div class="flex flex-wrap items-center gap-3">
	<IconButton sound 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 sound 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 sound 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 sound 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>
```
