Skip to Content

Button

Buttons allow users to take actions and make choices with a single tap or click.

import * as React from 'react';
import { Button } from '@itwin/itwinui-react';

export default () => {
  return (
    <div className='demo-container'>
      <Button>Default</Button>
      <Button styleType='cta'>Call-to-action</Button>
      <Button styleType='high-visibility'>High Visibility</Button>
      <Button styleType='borderless'>Borderless</Button>
    </div>
  );
};

Buttons have states and events and should be used when a form is submitted or where the button represents a clear call to action on a page. In some cases, buttons can also be used in place of href links to draw special attention to that action.

Variants

Default

The default button should be used in most circumstances. If you are unsure as to what button to use, use this button!

import * as React from 'react';
import { Button } from '@itwin/itwinui-react';
import { SvgAdd, SvgCheckmarkSmall } from '@itwin/itwinui-icons-react';

export default () => {
  return (
    <div className='demo-container'>
      <Button>Default</Button>
      <Button disabled>Disabled</Button>
      <Button startIcon={<SvgAdd />}>With startIcon</Button>
      <Button endIcon={<SvgCheckmarkSmall />}>With endIcon</Button>
    </div>
  );
};

High visibility

This is the button to emphasize an action applicable to an area of the page or a dialog. High visibility buttons are used to draw the user’s attention to the main action of the page. There should only be one high visibility button per area of the user interface.

import * as React from 'react';
import { Button } from '@itwin/itwinui-react';
import { SvgAdd, SvgCheckmarkSmall } from '@itwin/itwinui-icons-react';

export default () => {
  return (
    <div className='demo-container'>
      <Button styleType='high-visibility'>Default</Button>
      <Button styleType='high-visibility' disabled>
        Disabled
      </Button>
      <Button styleType='high-visibility' startIcon={<SvgAdd />}>
        With startIcon
      </Button>
      <Button styleType='high-visibility' endIcon={<SvgCheckmarkSmall />}>
        With endIcon
      </Button>
    </div>
  );
};

Call-to-action

The call-to-action button, also referred to as the CTA, is the button that is used for most full page layouts and whole-page overlays (think Next in stepper interactions). This is the biggest and most noticeable button. One call-to-action button per visible page is the rule. Treat it as a large, “CLICK HERE” guide for the user.

import * as React from 'react';
import { Button } from '@itwin/itwinui-react';
import { SvgAdd, SvgCheckmarkSmall } from '@itwin/itwinui-icons-react';

export default () => {
  return (
    <div className='demo-container'>
      <Button styleType='cta'>Default</Button>
      <Button styleType='cta' disabled>
        Disabled
      </Button>
      <Button styleType='cta' startIcon={<SvgAdd />}>
        With startIcon
      </Button>
      <Button styleType='cta' endIcon={<SvgCheckmarkSmall />}>
        With endIcon
      </Button>
    </div>
  );
};

Borderless

The borderless button is useful in tighter areas where using a default button would visibly cause too many boxes.

import * as React from 'react';
import { Button } from '@itwin/itwinui-react';
import { SvgAdd, SvgCheckmarkSmall } from '@itwin/itwinui-icons-react';

export default () => {
  return (
    <div className='demo-container'>
      <Button styleType='borderless'>Default</Button>
      <Button styleType='borderless' disabled>
        Disabled
      </Button>
      <Button styleType='borderless' startIcon={<SvgAdd />}>
        With startIcon
      </Button>
      <Button styleType='borderless' endIcon={<SvgCheckmarkSmall />}>
        With endIcon
      </Button>
    </div>
  );
};

The borderless button is often used by actionable icons in relation to another component. They are commonly used within table rows and widgets.

Size

There are 3 different sizes available, which can be applied to any button. The medium size is a default and should always be the first choice, unless there are good reasons to use the small or large version.

import * as React from 'react';
import { Button } from '@itwin/itwinui-react';

export default () => {
  return (
    <div className='demo-container'>
      <Button size='small'>Small</Button>
      <Button>Medium</Button>
      <Button size='large'>Large</Button>
    </div>
  );
};

Button props

Prop Description Default
size
Modify size of the button.
"small" | "large"
styleType
Style of the button. Use 'borderless' to hide outline.
"default" | "cta" | "high-visibility" | "borderless"
'default'
startIcon
Icon shown before the main button content.
Element
endIcon
Icon shown after the main button content.
Element
labelProps
Passes props to the button label.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
startIconProps
Passes props to the start icon.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
endIconProps
Passes props to the end icon.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
htmlDisabled
Built-in html disabled attribute
boolean
as
"symbol" | "object" | "button" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "canvas" | ... 159 more ... | FunctionComponent<...>

SplitButton

Pressing the left side of this button will commit the action. Pressing the right side of the button will open a menu.

import * as React from 'react';
import { MenuItem, SplitButton } from '@itwin/itwinui-react';

export default () => {
  const onMenuItemClick = (index, close) => () => {
    close();
  };

  const buttonMenuItems = (close) => [
    <MenuItem key={1} onClick={onMenuItemClick(1, close)}>
      Item #1
    </MenuItem>,
    <MenuItem key={2} onClick={onMenuItemClick(2, close)}>
      Item #2
    </MenuItem>,
    <MenuItem key={3} onClick={onMenuItemClick(3, close)}>
      Item #3
    </MenuItem>,
  ];

  return (
    <SplitButton
      onClick={() => {}}
      menuItems={buttonMenuItems}
      styleType='default'
    >
      Default
    </SplitButton>
  );
};

Props

Prop Description Default
size
Modify size of the button.
"small" | "large"
styleType
Style of the button. Use 'borderless' to hide outline.
"default" | "cta" | "high-visibility" | "borderless"
'default'
startIcon
Icon shown before the main button content.
Element
endIcon
Icon shown after the main button content.
Element
labelProps
Passes props to the button label.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
startIconProps
Passes props to the start icon.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
endIconProps
Passes props to the end icon.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
htmlDisabled
Built-in html disabled attribute
boolean
menuItems
Items in the dropdown menu. Pass a function that takes the close argument (to close the menu), and returns a list of MenuItem components.
(close: () => void) => Element[]
menuPlacement
Placement of the dropdown menu.
Placement
'bottom-end'
children
Content of primary button.
ReactNode
wrapperProps
Passes props to SplitButton wrapper.
DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
menuButtonProps
Passes props to SplitButton menu button.
Omit<Omit<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & { ...; }, "label" | ... 6 more ... | "iconProps"> & { ...; } & Omit<...> & { ...; }, "label" | "size">
portal
Where should the element be portaled to?
If true, it will portal into nearest ThemeContext.portalContainer.
If false, it will not be portaled.
Otherwise, it will portal to the element passed to to.
If to/to() === null/undefined, the default behavior will be used (i.e. as if portal is not passed).
boolean | { to: HTMLElement | (() => HTMLElement); }
true
as
"symbol" | "object" | "button" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "canvas" | ... 159 more ... | FunctionComponent<...>

Pressing this button will always open a menu. Upon selecting an option from the menu, the action immediately takes place. The menu button should only be styled as default buttons and borderless buttons.

import * as React from 'react';
import { MenuItem, DropdownButton } from '@itwin/itwinui-react';

export default () => {
  const buttonMenuItems = (close) => [
    <MenuItem key={1} onClick={() => close()}>
      Item #1
    </MenuItem>,
    <MenuItem key={2} onClick={() => close()}>
      Item #2
    </MenuItem>,
    <MenuItem key={3} onClick={() => close()}>
      Item #3
    </MenuItem>,
  ];

  return (
    <DropdownButton menuItems={buttonMenuItems} styleType='default'>
      Default
    </DropdownButton>
  );
};

Props

Prop Description Default
menuItems
Items in the dropdown menu. Pass a function that takes the close argument (to close the menu), and returns a list of MenuItem components.
(close: () => void) => Element[]
styleType
Style of the dropdown button. Use 'borderless' to hide outline.
"default" | "borderless" | "high-visibility"
'default'
dropdownMenuProps
Props for the DropdownMenu which extends PopoverProps.
Omit<DropdownMenuProps, "children" | "menuItems">
htmlDisabled
Built-in html disabled attribute
boolean
size
Modify size of the button.
"small" | "large"
startIcon
Icon shown before the main button content.
Element
labelProps
Passes props to the button label.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
startIconProps
Passes props to the start icon.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
endIconProps
Passes props to the end icon.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
as
"symbol" | "object" | "button" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "canvas" | ... 159 more ... | FunctionComponent<...>

IconButton

Icon button gives the icon the correct styling as well as adds some clickable padding within the button, ensuring icons meet the necessary touch target size.

import * as React from 'react';
import { IconButton } from '@itwin/itwinui-react';
import { SvgAdd, SvgClose } from '@itwin/itwinui-icons-react';

export default () => {
  return (
    <div className='demo-container'>
      <IconButton label='Add'>
        <SvgAdd />
      </IconButton>
      <IconButton styleType='borderless' label='Close'>
        <SvgClose />
      </IconButton>
    </div>
  );
};

Props

Prop Description Default
isActive
Button gets active style.
boolean
false
label
Name of the button, shown in a tooltip and exposed to assistive technologies.
ReactNode
labelProps
Props passed to the Tooltip that contains the label. Can be used for customizing the tooltip's placement, etc.
Omit<Omit<Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ...; }, "as" | ... 3 more ... | keyof TooltipOptions> & { ...; } & PortalProps & TooltipOptions & { ...; }, "ref">, "content" | ... 2 more ... | "ariaStrategy">
iconProps
Passes props to IconButton icon.
DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
htmlDisabled
Built-in html disabled attribute
boolean
size
Modify size of the button.
"small" | "large"
styleType
Style of the button. Use 'borderless' to hide outline.
"default" | "cta" | "high-visibility" | "borderless"
'default'
as
"symbol" | "object" | "button" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "canvas" | ... 159 more ... | FunctionComponent<...>

IdeasButton

The Ideas button is unique and should only be used under certain circumstances. You will need to perform an audit of your application to ensure that the feedback button does not cover / obscure any tools.

import * as React from 'react';
import { IdeasButton } from '@itwin/itwinui-react';

export default () => {
  return (
    /** Creating a container only for demo purposes. Normally this will be fixed to viewport. */
    <div className='demo-container'>
      <IdeasButton onClick={() => {}} />
    </div>
  );
};

If the button does obscure anything important, we suggest adding empty space at the bottom of the page so the user can scroll far enough down that the button doesn’t overlap the underlying tools.

Props

Prop Description Default
onClick
On click handler.
() => void
feedbackLabel
Localize 'Feedback' label if needed.
string
'Feedback'
as
"symbol" | "object" | "button" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "canvas" | ... 159 more ... | FunctionComponent<...>

Usage

Style types

  • Use default button just about everywhere.
  • One high visibility button per section such as within a dialog, or above a table.
  • One call-to-action button on a page at a time, and it should always appear within a dedicated page footer.
  • Borderless buttons should be used in places where a default and icon button could cause too much visual clutter.
  • Icon buttons should not have high visibility or call-to-action styletypes.

Labels

Strive for a single action word with a well-understood meaning such as a verb. Remember that all labels will need translation, so if the button absolutely requires a longer string, adhere to the twentycharacterlimit rule.

Icon and label buttons

To reinforce the meaning of a button it can be useful to display both an icon and a label. Use this option sparingly, and reserve if for the most important / frequently used buttons only. If you are unsure if an icon should be used, probably it shouldn’t.