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.
Usage
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>
);
};
Stretched
To make a button stretch to the full width of its parent, use the stretched
prop.
This is useful in narrow containers and mobile views. Don’t overuse this!
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> | |
stretched | Whether the button should stretch to fill the width of the container. This is useful on narrow containers and mobile views. boolean | |
loading | Specify a loading state for the button. boolean | |
htmlDisabled | Built-in html disabled attributeboolean | |
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> | |
stretched | Whether the button should stretch to fill the width of the container. This is useful on narrow containers and mobile views. boolean | |
loading | Specify a loading state for the button. boolean | |
htmlDisabled | Built-in html disabled attributeboolean | |
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" | ... 8 more ... | "iconProps"> & { ...; } & Omit<...> & { ...; }, "label" | "size"> | |
dropdownMenuProps | Props to customize menu behavior. Pick<PopoverOptions & { autoUpdateOptions?: { ancestorScroll?: boolean; ancestorResize?: boolean; elementResize?: boolean; animationFrame?: boolean; layoutShift?: boolean; }; interactions?: { ...; }; role?: "dialog" | ... 1 more ... | "listbox"; matchWidth?: boolean; } & Omit<...>, "middleware"> | |
portal | Where should the element be portaled to? If true, it will portal into nearest ThemeProvider's 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<...> |
DropdownButton
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 attributeboolean | |
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> | |
stretched | Whether the button should stretch to fill the width of the container. This is useful on narrow containers and mobile views. boolean | |
loading | Specify a loading state for the button. boolean | |
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.
Make sure to provide a short label
that describes the action the button will perform. This label will be shown in a tooltip and also exposed to assistive technologies.
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> | |
title | @deprecated Use label instead.string | |
htmlDisabled | Built-in html disabled attributeboolean | |
size | Modify size of the button. "small" | "large" | |
styleType | Style of the button.
Use 'borderless' to hide outline. "default" | "cta" | "high-visibility" | "borderless" | 'default' |
stretched | Whether the button should stretch to fill the width of the container. This is useful on narrow containers and mobile views. boolean | |
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 guidelines
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.