Skip to main content
IconButton
@coinbase/cds-web@8.30.1
A Button with an Icon for content.
Import
import { IconButton } from '@coinbase/cds-web/buttons/IconButton'
SourceView source codeStorybookView StorybookFigmaView Figma (internal only)
Related components
View as Markdown

IconButton is a compact button that displays only an icon. Use it for actions where the icon alone clearly communicates the purpose.

Basics

The only required props are name (which determines the icon) and accessibilityLabel (for screen readers).

Loading...
Live Code
<HStack gap={2} flexWrap="wrap">
  <IconButton name="gear" accessibilityLabel="Open settings" onClick={console.log} />
  <IconButton name="close" accessibilityLabel="Close modal" onClick={console.log} />
  <IconButton name="refresh" accessibilityLabel="Refresh data" onClick={console.log} />
</HStack>

Variants

Use variants to denote intent and importance. The active prop fills the icon when enabled.

Loading...
Live Code
<HStack gap={2} flexWrap="wrap">
  <IconButton
    active
    name="orderHistory"
    accessibilityLabel="View transaction history"
    variant="primary"
    onClick={console.log}
  />
  <IconButton
    active
    name="gear"
    accessibilityLabel="View settings"
    variant="secondary"
    onClick={console.log}
  />
  <IconButton
    name="phone"
    accessibilityLabel="Call support"
    variant="tertiary"
    onClick={console.log}
  />
  <IconButton
    name="checkmark"
    accessibilityLabel="Approve transaction"
    variant="foregroundMuted"
    onClick={console.log}
  />
</HStack>

Transparent

Use the transparent prop to remove the background until the user interacts with the button.

Loading...
Live Code
<HStack gap={2} flexWrap="wrap">
  <IconButton
    active
    name="orderHistory"
    accessibilityLabel="View past order history"
    variant="primary"
    transparent
    onClick={console.log}
  />
  <IconButton
    active
    name="gear"
    accessibilityLabel="Update settings"
    variant="secondary"
    transparent
    onClick={console.log}
  />
  <IconButton
    name="phone"
    accessibilityLabel="Call support"
    variant="tertiary"
    transparent
    onClick={console.log}
  />
  <IconButton
    name="checkmark"
    accessibilityLabel="Verify your identity"
    variant="foregroundMuted"
    transparent
    onClick={console.log}
  />
</HStack>

States

Loading

Use the loading prop to show a spinner when an action is in progress. The button becomes non-interactive and displays a loading spinner instead of the icon.

Loading...
Live Code
function LoadingExample() {
  const [isLoading, setIsLoading] = useState(false);

  const handleSubmit = () => {
    setIsLoading(true);
    setTimeout(() => setIsLoading(false), 2000);
  };

  return (
    <HStack gap={2} flexWrap="wrap">
      <IconButton
        name="checkmark"
        accessibilityLabel={isLoading ? 'Processing submission' : 'Submit form'}
        variant="primary"
        loading={isLoading}
        onClick={handleSubmit}
      />
      <IconButton
        name="refresh"
        accessibilityLabel={isLoading ? 'Refreshing data' : 'Refresh data'}
        variant="secondary"
        loading={isLoading}
        onClick={handleSubmit}
      />
    </HStack>
  );
}

Disabled

Use the disabled prop to prevent interaction and show a disabled visual state.

Loading...
Live Code
<HStack gap={2} flexWrap="wrap">
  <IconButton
    active
    name="orderHistory"
    accessibilityLabel="View transaction history"
    variant="primary"
    disabled
    onClick={console.log}
  />
  <IconButton
    active
    name="gear"
    accessibilityLabel="View settings"
    variant="secondary"
    disabled
    onClick={console.log}
  />
  <IconButton
    name="checkmark"
    accessibilityLabel="Approve transaction"
    variant="foregroundMuted"
    disabled
    onClick={console.log}
  />
</HStack>

Sizing

IconButtons are compact by default. Use compact={false} for larger touch targets.

Loading...
Live Code
<HStack gap={2} flexWrap="wrap" alignItems="center">
  <IconButton
    active
    name="gear"
    accessibilityLabel="Settings - compact"
    variant="primary"
    compact
    onClick={console.log}
  />
  <IconButton
    active
    name="gear"
    accessibilityLabel="Settings - regular"
    variant="primary"
    compact={false}
    onClick={console.log}
  />
</HStack>

Accessibility

Since icon buttons have no visible text, an accessibilityLabel is required to describe the button's purpose for screen readers.

<IconButton name="close" accessibilityLabel="Close trade modal" />

When composing a button with a visible label, use accessibilityLabelledBy to reference the label's id instead. See the Claim Drop example below.

Composed Examples

Claim Drop

A toggleable icon button with an adjacent label. Uses accessibilityLabelledBy to associate the button with its visible label.

Loading...
Live Code
function ClaimDropExample() {
  const [active, setActive] = useState(false);
  const variant = useMemo(() => (active ? 'primary' : 'foregroundMuted'), [active]);
  const label = useMemo(() => (active ? 'Reject drop' : 'Claim drop'), [active]);

  return (
    <HStack gap={2} alignItems="center">
      <IconButton
        name="drops"
        active={active}
        variant={variant}
        onClick={() => setActive((active) => !active)}
        id="claim-drop-button"
        accessibilityLabelledBy="claim-drop-label"
      />
      <Text font="label1" as="label" htmlFor="claim-drop-button" id="claim-drop-label">
        {label}
      </Text>
    </HStack>
  );
}

Notification Bell

An icon button with a badge showing the notification count. Uses DotCount to display the number of unread notifications.

Loading...
Live Code
<DotCount count={3} overlap="circular" pin="top-end">
  <IconButton
    name="bell"
    accessibilityLabel="Notifications, 3 unread"
    variant="secondary"
    onClick={console.log}
  />
</DotCount>

Is this page useful?

Coinbase Design is an open-source, adaptable system of guidelines, components, and tools that aid the best practices of user interface design for crypto products.