Skip to main content
The @zendeskgarden/react-buttons package provides a set of accessible button components that cover the full range of interaction patterns: primary actions, icon-only buttons, toggle states, split-button menus, and more.

Installation

npm install @zendeskgarden/react-buttons

# Peer dependencies
npm install react react-dom styled-components @zendeskgarden/react-theming
Place a ThemeProvider from @zendeskgarden/react-theming at the root of your React application. All Garden components must be rendered inside a ThemeProvider.

Button

The core Button component renders an accessible <button> element. Use the appearance props to communicate intent.

Basic usage

import { ThemeProvider } from '@zendeskgarden/react-theming';
import { Button } from '@zendeskgarden/react-buttons';

const Example = () => (
  <ThemeProvider>
    <Button onClick={() => console.log('clicked')}>Default</Button>
    <Button isPrimary>Primary</Button>
    <Button isDanger>Danger</Button>
    <Button isPrimary isDanger>Primary danger</Button>
    <Button isBasic>Basic</Button>
    <Button isLink>Link</Button>
  </ThemeProvider>
);

With icons

Use Button.StartIcon and Button.EndIcon to place icons at either end of a button label. Pass isRotated to animate a chevron.
import React, { useState } from 'react';
import { Button } from '@zendeskgarden/react-buttons';
import ShieldIcon from '@zendeskgarden/icons/src/16/shield-stroke.svg';
import ChevronDownIcon from '@zendeskgarden/icons/src/16/chevron-down-stroke.svg';

const MediaButton = ({ children, ...props }) => {
  const [isOpen, setOpen] = useState(false);

  return (
    <Button onClick={() => setOpen(!isOpen)} {...props}>
      <Button.StartIcon>
        <ShieldIcon />
      </Button.StartIcon>
      {children}
      <Button.EndIcon isRotated={isOpen}>
        <ChevronDownIcon />
      </Button.EndIcon>
    </Button>
  );
};

Props

isPrimary
boolean
Applies primary (filled) button styling.
isDanger
boolean
Applies danger styling. Can be combined with isPrimary for a filled danger button.
isBasic
boolean
Applies basic (borderless) button styling.
Renders the button with link (anchor) styling and an underline.
isNeutral
boolean
Applies neutral color styling.
isPill
boolean
Applies pill-shaped (fully rounded) button styling.
isStretched
boolean
Stretches the button to fill its container width.
size
'small' | 'medium' | 'large'
default:"medium"
Controls the button size.
focusInset
boolean
Applies an inset box-shadow on focus instead of an outset ring.

Button.StartIcon props

isRotated
boolean
Rotates the icon 180 degrees. Useful for open/close chevrons.

Button.EndIcon props

isRotated
boolean
Rotates the icon 180 degrees. Useful for open/close chevrons.

IconButton

IconButton renders an icon-only button with no visible label. Defaults to isBasic and isPill styling. Always provide an aria-label for accessibility.
import { IconButton } from '@zendeskgarden/react-buttons';
import SettingsIcon from '@zendeskgarden/icons/src/16/settings-stroke.svg';

const Example = () => (
  <ThemeProvider>
    <IconButton aria-label="Settings">
      <SettingsIcon />
    </IconButton>
    <IconButton aria-label="Delete" isDanger>
      <TrashIcon />
    </IconButton>
  </ThemeProvider>
);

Props

IconButton accepts all Button props except isStretched and isLink, plus:
isRotated
boolean
Rotates the icon 180 degrees.

ToggleButton

ToggleButton extends Button to manage a pressed/unpressed state via the isPressed prop. It sets aria-pressed automatically.
import React, { useState } from 'react';
import { ToggleButton } from '@zendeskgarden/react-buttons';

const Example = () => {
  const [isPressed, setPressed] = useState(false);

  return (
    <ThemeProvider>
      <ToggleButton isPressed={isPressed} onClick={() => setPressed(!isPressed)}>
        Bold
      </ToggleButton>
    </ThemeProvider>
  );
};

Props

ToggleButton accepts all Button props, plus:
isPressed
boolean | 'mixed'
Indicates whether the button is in a pressed state. Use "mixed" when the toggle controls multiple elements with different values.

SplitButton

SplitButton groups a primary action button alongside a ChevronButton (or IconButton) for a dropdown trigger. The context automatically applies inset focus styling to grouped buttons.
import { Button, SplitButton, ChevronButton } from '@zendeskgarden/react-buttons';

const Example = () => (
  <ThemeProvider>
    <SplitButton>
      <Button isPrimary>Submit</Button>
      <ChevronButton isPrimary aria-label="More options" />
    </SplitButton>
  </ThemeProvider>
);
SplitButton renders a <div> wrapper that provides a context for its children. Pair it with a Menu or Dropdown component to build a full split-button menu.

ChevronButton

ChevronButton is a pre-built IconButton that renders a downward-pointing chevron icon. Use it as the dropdown trigger in a SplitButton.
import { ChevronButton } from '@zendeskgarden/react-buttons';

const Example = () => (
  <ThemeProvider>
    <ChevronButton aria-label="Open menu" />
    <ChevronButton aria-label="Open menu" isPrimary />
  </ThemeProvider>
);
ChevronButton accepts the same props as IconButton. Its defaults are isBasic={false} and isPill={false}.

Anchor

Anchor renders an accessible <a> element styled to match Garden’s button link style.
import { Anchor } from '@zendeskgarden/react-buttons';

const Example = () => (
  <ThemeProvider>
    <Anchor href="https://zendeskgarden.github.io" isExternal>
      Garden Design System
    </Anchor>
  </ThemeProvider>
);

Props

isDanger
boolean
Applies danger (red) link styling.
isExternal
boolean
Attaches target="_blank" and rel="noopener noreferrer" and renders an external link icon.
externalIconLabel
string
Accessible label for the external link icon. Provide a translated string when targeting non-English locales.
isUnderlined
boolean
Shows an underline on the anchor.

ToggleIconButton

ToggleIconButton combines IconButton with toggle behavior. Set isPressed to control its state and aria-label for screen readers.
import React, { useState } from 'react';
import { ToggleIconButton } from '@zendeskgarden/react-buttons';
import StarIcon from '@zendeskgarden/icons/src/16/star-stroke.svg';

const Example = () => {
  const [isPressed, setPressed] = useState(false);

  return (
    <ThemeProvider>
      <ToggleIconButton
        aria-label={isPressed ? 'Unstar' : 'Star'}
        isPressed={isPressed}
        onClick={() => setPressed(!isPressed)}
      >
        <StarIcon />
      </ToggleIconButton>
    </ThemeProvider>
  );
};
ToggleIconButton accepts all IconButton props plus the isPressed prop from ToggleButton.

Exports

The following are exported from @zendeskgarden/react-buttons:
ExportDescription
ButtonBase button with Button.StartIcon and Button.EndIcon subcomponents
AnchorStyled anchor element
ChevronButtonIcon button pre-loaded with a chevron icon
IconButtonIcon-only button
SplitButtonWrapper for grouped action + dropdown buttons
ToggleButtonButton with aria-pressed state management
ToggleIconButtonIcon-only button with aria-pressed state management

Build docs developers (and LLMs) love