IconButton
Accessible, unstyled icon-only button primitive.
| Package | @vizejs/ui/icon-button |
| Maturity | stable |
| Own the source | vize lib pull icon-button |
| Requires | — |
| Aliases | icon button, toolbar icon, icon-only action, glyph button |
| Covers | HTML button, WAI-ARIA Button Pattern, React Aria Button |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { IconButton } from "@vizejs/ui/icon-button";
Or copy the source into your project with vize lib pull icon-button (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Icon-only buttons that carry their accessible name through aria-label. -->
<script setup lang="ts">
import { ref } from "vue";
import { IconButton } from "@vizejs/ui/icon-button";
const count = ref(0);
function addItem(): void {
count.value += 1;
}
</script>
<template>
<div>
<IconButton ariaLabel="Add item" variant="solid" tone="accent" @press="addItem">
<svg
viewBox="0 0 24 24"
width="1em"
height="1em"
fill="none"
stroke="currentColor"
aria-hidden="true"
>
<path d="M12 5v14M5 12h14" />
</svg>
</IconButton>
<IconButton ariaLabel="Delete item" tone="danger" disabled>
<svg
viewBox="0 0 24 24"
width="1em"
height="1em"
fill="none"
stroke="currentColor"
aria-hidden="true"
>
<path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" />
</svg>
</IconButton>
<output>{{ count }} items</output>
</div>
</template>
API
IconButton
Source: src/families/layout/icon/icon-button.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as |
PrimitiveAs |
"button" |
Native element, custom element, or component to render as the root. |
native |
boolean |
true when |
Whether the rendered target already implements native button semantics. |
type |
IconButtonType |
"button" |
Native button submission behavior. |
disabled |
boolean |
false |
Remove the control from activation and sequential keyboard focus. |
loading |
boolean |
false |
Announce in-progress work and prevent repeated activation while preserving focus. |
size |
IconButtonSize |
"md" |
Consumer styling size mirrored to data-size. |
tone |
IconButtonTone |
"neutral" |
Consumer styling tone mirrored to data-tone. |
variant |
IconButtonVariant |
"plain" |
Consumer styling variant mirrored to data-variant. |
ariaDescribedby |
string |
undefined |
Element ids that describe the icon button. |
ariaLabel |
string |
undefined |
Direct accessible name. |
ariaLabelledby |
string |
undefined |
Events
| Event | Payload | Description |
|---|---|---|
press |
[event: MouseEvent] |
Fired when pointer or keyboard activation reaches the rendered control. Carries the resulting MouseEvent. |
Slots
| Slot | Slot props | Description |
|---|---|---|
default |
IconButtonSlotState |
Renders the icon-only contents with current availability and styling hooks. |
Exposed
| Member | Type | Description |
|---|---|---|
disabled |
boolean |
|
loading |
boolean |
|
size |
IconButtonSize |
|
state |
IconButtonState |
|
tone |
IconButtonTone |
|
unavailable |
boolean |
|
variant |
IconButtonVariant |
|
element |
IconButtonElement | null |
|
focus |
(options?: FocusOptions) => void |
Behavior
| Case | Required behavior |
|---|---|
icon-button.vue source |
Owns the canonical IconButton SFC implementation and every row in this table. |
| Accessible name | Public IconButtonProps require ariaLabel or ariaLabelledby; rendered markup forwards the resolved name and marks data-name. |
| Native button | Defaults to a native button with type="button", data-vize-ui="icon-button", part="root", no class/style output, and exact once-per-activation press emits. |
| Non-native button | Non-native hosts render role="button", enter the tab order, and emulate native Enter/Space activation timing. |
| Unavailable states | disabled removes activation and sequential focus; loading announces aria-busy, mirrors aria-disabled, preserves focus, and suppresses press. |
| Styling hooks | size, tone, and variant are strict tokens exposed through slot state, defineExpose, and data-*; no CSS is emitted. |
| SSR and hydration | Server markup is stable and hydrates without diagnostics or root replacement. |