Icon Button
Compact button that renders an icon with optional text label, supporting ghost, secondary, and primary variants.
<arc-icon-button> Overview
>
IconButton is a versatile interactive element designed for actions where an icon is the primary affordance. It renders as a square button when used icon-only, or expands into a compact labeled button when the `text` prop is provided. This makes it ideal for toolbars, action bars, card headers, and anywhere space is limited but functionality needs to be discoverable.
The component supports three visual variants: `ghost` (transparent background, the default), `secondary` (bordered with accent glow on hover), and `primary` (solid accent-primary background with a glow effect). Four sizes are available — `xs`, `sm`, `md`, and `lg` — each with distinct dimensions for both icon-only and icon-plus-text modes. The icon-only mode enforces a 1:1 aspect ratio for visual consistency.
When an `href` is provided, IconButton renders as an anchor tag instead of a `<button>`, making it suitable for navigation links that should look like action buttons. The `name` prop references an icon from the arc-icon library, but you can also pass custom SVG content through the default slot if the built-in icon set does not cover your use case.Guidelines
When to use
- Always provide a `label` or `text` prop so the button has an accessible name for screen readers
- Use the `ghost` variant for secondary or tertiary actions in toolbars to reduce visual noise
- Use `href` for navigation actions so the element renders as a semantic anchor tag
- Match the `size` to surrounding elements — use `xs` or `sm` in dense UIs like table rows
- Pair with `arc-tooltip` to explain icon-only buttons on hover
When not to use
- Do not use IconButton for primary page actions that need a full-width call to action — use Button instead
- Do not omit the `label` prop on icon-only buttons — they will be invisible to assistive technology
- Do not combine `disabled` with `href` — anchor tags cannot be natively disabled
- Do not use long `text` values — the uppercase styling and compact padding are designed for 1-2 word labels
- Avoid placing many `primary` variant icon buttons in the same row — reserve the solid fill for the single most important action
Features
- Three visual variants: ghost (default transparent), secondary (bordered with blue glow), and primary (solid accent fill)
- Four sizes — xs (28px), sm (32px), md (36px), lg (44px) — with automatic icon size mapping
- Optional `text` prop that expands the button from a square icon into a labeled action button with uppercase styling
- Renders as an `<a>` tag when `href` is provided, enabling accessible navigation links
- Active-press animation with `scale(0.93)` transform for tactile feedback
- Built-in `arc-icon` integration via the `name` prop, or custom content via the default slot
- Focus-visible glow ring using the shared `--focus-glow` token for keyboard navigation
- Accessible `aria-label` derived automatically from `label`, `text`, or manual override
Preview
Usage
Layout and styling work without JavaScript via the HTML/CSS versions. Interactive features like events and state management require the Web Component or a framework wrapper.
<script type="module" src="@arclux/arc-ui"></script>
<!-- Toolbar with mixed variants -->
<div style="display:flex; gap:8px; align-items:center;">
<arc-icon-button name="pencil" label="Edit" variant="ghost"></arc-icon-button>
<arc-icon-button name="copy" label="Duplicate" variant="ghost"></arc-icon-button>
<arc-icon-button name="trash" label="Delete" variant="ghost"></arc-icon-button>
<arc-icon-button name="share" label="Share" variant="secondary"></arc-icon-button>
<arc-icon-button name="plus" text="New Item" variant="primary"></arc-icon-button>
</div>
<!-- Sizes -->
<div style="display:flex; gap:8px; align-items:center; margin-top:16px;">
<arc-icon-button name="star" label="Favorite" size="xs"></arc-icon-button>
<arc-icon-button name="star" label="Favorite" size="sm"></arc-icon-button>
<arc-icon-button name="star" label="Favorite" size="md"></arc-icon-button>
<arc-icon-button name="star" label="Favorite" size="lg"></arc-icon-button>
</div>
<!-- Navigation link -->
<arc-icon-button name="gear" text="Settings" variant="secondary" href="/settings"></arc-icon-button> import { IconButton } from '@arclux/arc-ui-react';
function DocumentToolbar({ onSave, onDelete }) {
return (
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
<IconButton name="pencil" label="Edit" />
<IconButton name="copy" label="Duplicate" />
<IconButton name="download" label="Download" variant="secondary" />
<IconButton name="trash" label="Delete" variant="secondary"
onClick={onDelete} />
<IconButton name="floppy-disk" text="Save" variant="primary"
onClick={onSave} />
</div>
);
}
function SocialActions() {
return (
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
<IconButton name="heart" label="Like" size="lg" variant="primary" />
<IconButton name="share" label="Share" size="lg" variant="secondary" />
<IconButton name="bookmark" label="Bookmark" size="lg" />
</div>
);
} <script setup>
import { IconButton } from '@arclux/arc-ui-vue';
function handleEdit() { console.log('Editing...'); }
function handleDelete() { console.log('Deleting...'); }
</script>
<template>
<!-- Card action bar -->
<div style="display:flex; gap:8px; align-items:center;">
<IconButton name="pencil" label="Edit" @click="handleEdit" />
<IconButton name="copy" label="Duplicate" variant="ghost" />
<IconButton name="trash" label="Delete" variant="secondary" @click="handleDelete" />
</div>
<!-- With text labels for clarity -->
<div style="display:flex; gap:8px; align-items:center; margin-top:16px;">
<IconButton name="download" text="Export" variant="secondary" />
<IconButton name="share" text="Share" variant="ghost" />
<IconButton name="plus" text="Add" variant="primary" />
</div>
</template> <script>
import { IconButton } from '@arclux/arc-ui-svelte';
let liked = false;
</script>
<!-- Toggle-style icon button -->
<IconButton
name={liked ? 'heart-fill' : 'heart'}
label={liked ? 'Unlike' : 'Like'}
variant={liked ? 'primary' : 'ghost'}
on:click={() => liked = !liked}
/>
<!-- Compact toolbar -->
<div style="display:flex; gap:4px;">
<IconButton name="pencil" label="Edit" size="sm" />
<IconButton name="copy" label="Copy" size="sm" />
<IconButton name="link" label="Copy Link" size="sm" />
<IconButton name="trash" label="Delete" size="sm" variant="secondary" />
</div> import { Component } from '@angular/core';
import { IconButton } from '@arclux/arc-ui-angular';
@Component({
imports: [IconButton],
template: `
<div style="display:flex; gap:8px; align-items:center;">
<arc-icon-button name="pencil" label="Edit" (click)="onEdit()"></arc-icon-button>
<arc-icon-button name="copy" label="Duplicate" variant="ghost"></arc-icon-button>
<arc-icon-button name="trash" label="Delete" variant="secondary" (click)="onDelete()"></arc-icon-button>
<arc-icon-button name="plus" text="New Item" variant="primary" (click)="onCreate()"></arc-icon-button>
</div>
<!-- Navigation links -->
<div style="display:flex; gap:8px; margin-top:16px;">
<arc-icon-button name="gear" text="Settings" variant="secondary" href="/settings"></arc-icon-button>
<arc-icon-button name="bell" text="Notifications" variant="ghost" href="/notifications"></arc-icon-button>
</div>
`,
})
export class ToolbarComponent {
onEdit() { console.log('Edit'); }
onDelete() { console.log('Delete'); }
onCreate() { console.log('Create'); }
} import { IconButton } from '@arclux/arc-ui-solid';
function TableRowActions(props: { onEdit: () => void; onDelete: () => void }) {
return (
<div style={{ display: 'flex', gap: '4px' }}>
<IconButton name="pencil" label="Edit" size="xs" onClick={props.onEdit} />
<IconButton name="copy" label="Duplicate" size="xs" />
<IconButton name="trash" label="Delete" size="xs" variant="secondary" onClick={props.onDelete} />
</div>
);
}
function PageHeader() {
return (
<div style={{ display: 'flex', gap: '8px', 'align-items': 'center' }}>
<IconButton name="arrow-left" label="Back" href="/" />
<IconButton name="share" text="Share" variant="secondary" />
<IconButton name="download" text="Export" variant="primary" />
</div>
);
} import { IconButton } from '@arclux/arc-ui-preact';
function MediaControls() {
return (
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
<IconButton name="skip-back" label="Previous" size="sm" />
<IconButton name="play" label="Play" variant="primary" size="lg" />
<IconButton name="skip-forward" label="Next" size="sm" />
<IconButton name="speaker-high" label="Volume" size="sm" variant="ghost" />
<IconButton name="heart" label="Favorite" size="sm" />
</div>
);
} <!-- arc-icon-button is interactive — requires JS -->
<arc-icon-button></arc-icon-button> <!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-icon-button — requires icon-button.css + tokens.css (or arc-ui.css) -->
<span class="arc-icon-button">
<a href="#" aria-label="Label"></a>
</span> API
-
namestring'' - Name of the arc-icon to render. When empty, the default slot is used for custom icon content.
-
textstring'' - Optional text label displayed next to the icon. When provided, the button expands from a square to a wider labeled button with uppercase styling.
-
variant'ghost' | 'secondary' | 'primary''ghost' - Visual style variant. Ghost is transparent, secondary has a border with glow, primary has a solid accent-primary fill.
-
size'xs' | 'sm' | 'md' | 'lg''md' - Button size controlling dimensions and icon scale. Icon-only sizes are circular: xs=28px, sm=32px, md=36px, lg=44px. The labeled form stays a rounded rectangle.
-
labelstring'' - Accessible label for the button. Falls back to `text` if not provided. Required for icon-only usage.
-
hrefstring'' - When set, renders the button as an anchor tag for navigation links.
-
disabledbooleanfalse - Disables the button, reducing opacity to 40% and blocking pointer events.
-
typestring'button' - HTML button type attribute. Only applies when `href` is not set.
See Also
- Button Primary call-to-action element with three visual variants that map to action hierarchy. Supports prefix and suffix slots for icons. Renders as an anchor when given an href, making it ideal for navigation-driven actions across landing pages, toolbars, and forms.
- Copy Button One-click copy-to-clipboard button with confirmation.
- Tooltip Contextual hint that appears on hover or focus, providing supplementary information without cluttering the UI. Supports four placement positions and a configurable show delay.