Skip to content
v2.5.0
English
Русский
Documentation

IconButton

IconButton is the icon-only action variant built on the same button foundation as Button.

Patterns

Compact Toolbar Action

When to use:

  • Dense toolbars or headers need compact actions.

Composition notes:

  • Keep labels explicit through aria-label.
  • Reserve icon-only treatment for familiar actions.

Trade-offs:

  • Saves space.
  • Less explicit than text buttons.
basic-usage.tsx · 27 lines
import { Icon, IconButton, Text } from '@vega-ui/react';
import { EllipsisIcon, PencilIcon, Share2Icon } from '@vega-ui/icons';
import { useState } from 'react';

export default function BasicUsage() {
  const [lastAction, setLastAction] = useState('');

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--spacing-2)', width: '100%' }}>
      <header style={{ display: 'flex', alignItems: 'center', gap: 'var(--spacing-2)' }}>
        <Text size={4} fontWeight={600} style={{ flex: 1, minWidth: 0 }}>Brand guidelines</Text>
        <IconButton type='button' size='sm' variant='secondary' appearance='transparent' aria-label='Rename document' onClick={() => setLastAction('Rename')}>

Inline Clear Action

When to use:

  • A small local control clears or removes adjacent state.

Composition notes:

  • Place the button close to the thing it affects.
  • Keep the action narrowly scoped.

Trade-offs:

  • Very compact.
  • Easy to overuse in forms without enough context.
inline-clear-action.tsx · 55 lines
import type { CSSProperties } from 'react';
import { Icon, IconButton, Label, TextField, TextFieldInput } from '@vega-ui/react';
import { SearchIcon, XIcon } from '@vega-ui/icons';
import { FormEvent, useRef, useState } from 'react';

export default function InlineClearAction() {
  const input = useRef<HTMLInputElement>(null);
  const [query, setQuery] = useState('quarterly report');
  const [submitted, setSubmitted] = useState('');

  const clear = () => {
    setQuery('');

When to use:

  • Navigation needs icon-button visuals while preserving link semantics.

Composition notes:

  • Use asChild with a real anchor.
  • Keep the destination obvious from the surrounding context and accessible label.

Trade-offs:

  • Strong visual consistency.
  • Easy to misuse for ambiguous navigation.
navigational-icon-surface.tsx · 26 lines
import { Icon, IconButton } from '@vega-ui/react';
import { BookOpenIcon, LifeBuoyIcon, RssIcon } from '@vega-ui/icons';

const links = [
  { href: '/docs', label: 'Documentation', icon: <BookOpenIcon /> },
  { href: '/support', label: 'Help center', icon: <LifeBuoyIcon /> },
  { href: '/blog/rss.xml', label: 'Blog RSS feed', icon: <RssIcon /> },
];

export default function NavigationalIconSurface() {
  return (
    <nav aria-label='Resources'>

Comparison

Quick Decision Rule

Use IconButton when the action is compact, common, and already recognizable without visible text.

IconButton vs Button

Use IconButton when:

  • space is constrained
  • the action is common and recognizable

Use Button when:

  • visible text improves clarity

Main trade-off: icon button is denser, while button is clearer.

Use IconButton when:

  • the interaction is an action

Use Link when:

  • the interaction primarily navigates

Main trade-off: icon button is action semantics, while link is navigation semantics.

IconButton vs ButtonBase

Use IconButton when:

  • the product explicitly wants the icon-button size and layout contract

Use ButtonBase when:

  • a lower-level custom icon action surface is being built

Choose This Component When

  • The action is icon-first and well understood.
  • Space is constrained.
  • The UI still needs a button-like action surface.
  • the action should stay compact without becoming a generic low-level primitive

Do Not Choose This Component When

  • The action meaning is unclear without visible text.
  • The interaction primarily navigates.
  • A regular button would improve comprehension.

Troubleshooting

Action Meaning Is Unclear

Symptom

Users see the icon but do not know what the action does.

Likely Cause

IconButton was used for an action that needs visible text or stronger context.

How To Verify

  • Hide surrounding context and inspect whether the action is still obvious.
  • Check whether the same icon has a stable meaning elsewhere in the product.

Fix

  • Switch to Button if visible text improves clarity.
  • Keep icon-only treatment for familiar actions.

Missing Accessible Name

Symptom

The button works visually but has no clear accessible label.

Likely Cause

No aria-label or equivalent supported labeling was provided.

How To Verify

  • Inspect the rendered markup.
  • Test with accessibility tooling or screen reader output.

Fix

  • Provide an explicit accessible label.

Polymorphic IconButton Behaves Strangely

Symptom

The icon-button visuals render, but the child element does not support the intended semantics or props.

Likely Cause

asChild was used with an incompatible child element.

How To Verify

  • Inspect the rendered child element.
  • Check whether it matches the intended action or navigation semantics.

Fix

  • Use a child that supports the intended behavior.
  • Keep default rendering when polymorphism is unnecessary.