Action Bar
Action Bars contain primary and secondary actions related to a page or task.
Anatomy

- Primary Button: A button that is discoverable and used as the most important action to take on a page.
- Secondary Button: A button or set of buttons that is less important than the Primary Button.
- Overflow Menu: An Icon-Only Secondary Button Variant with an Ellipsis Icon used for responsive screens or small page width to show more actions.
- Container Bar: The Container Bar is used to house action buttons and is anchored at the bottom of the screen.
Usage Guidance
- Primary Buttons should only be used once per screen. If there are other buttons on screen, use the Secondary or Tertiary Buttons. However, Tertiary Buttons should not be on the Action Bar unless it’s in the Overflow Menu.
- Action Bars are placed at the bottom of the screen, and will stick as the user scrolls.
- Although actions may change, the placement of the Action Bar should persist until the task is successfully submitted.
- Action Bars can contain up to 3 actions and an Overflow Menu when appropriate.
- If there are more than 3 actions, hide the 4th and other remaining actions in an Overflow Menu that is launched by clicking the Icon Only Secondary Button Variant.
- There should be between 1-7 items to choose from in an Overflow Menu.
- Buttons placed in Action Bars should be grouped logically, either by usage or importance.
When to Use
- Use Action Bars for tasks that require navigating between pages, saving progress, submitting a task, or cancelling a task.
When to Use Something Else
- Consider taking a Button outside of the Action Bar if the action is not related to the progress or status of a task.
- Consider using a Text Button instead of an Action Bar if an action is less popular or less important.
Examples
Basic Example
ActionBar includes a container ActionBar component and the following subcomponent:
ActionBar.List which should contains ActionBar.Item.
In a basic example of an ActionBar there are two buttons. The primary action button should be used
only once and left aligned if content is left to right, followed by secondary buttons. Tertiary
buttons should not be used in the Action Bar.
import {ActionBar} from '@workday/canvas-kit-react/action-bar';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
export default () => {
return (
<ActionBar>
<ActionBar.List position="relative" as="section" aria-label="Action Bar">
<ActionBar.Item as={PrimaryButton} onClick={() => console.log('first action')}>
First Action
</ActionBar.Item>
<ActionBar.Item>Second Action</ActionBar.Item>
</ActionBar.List>
</ActionBar>
);
};
Icons Example
ActionBar.Item renders a SecondaryButton as default, so it’s possible to use other Button props
with ActionBar.Item such as icon or size.
import {ActionBar} from '@workday/canvas-kit-react/action-bar';
import {notificationsIcon, alarmClockIcon} from '@workday/canvas-system-icons-web';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
export default () => {
return (
<ActionBar>
<ActionBar.List position="relative" as="section" aria-label="Action Bar">
<ActionBar.Item as={PrimaryButton} icon={notificationsIcon}>
First Action
</ActionBar.Item>
<ActionBar.Item icon={alarmClockIcon}>Second Action</ActionBar.Item>
</ActionBar.List>
</ActionBar>
);
};
Delete Action Example
ActionBar.Item is a SecondaryButton by default but it’s posible to change it to another element,
such as DeleteButton, by using as prop.
import {ActionBar} from '@workday/canvas-kit-react/action-bar';
import {DeleteButton} from '@workday/canvas-kit-react/button';
export default () => {
return (
<ActionBar>
<ActionBar.List position="relative" as="section" aria-label="Action Bar">
<ActionBar.Item as={DeleteButton}>Delete Action</ActionBar.Item>
<ActionBar.Item>Second Action</ActionBar.Item>
</ActionBar.List>
</ActionBar>
);
};
Overflow Example
ActionBar container can contain up to 3 actions and an Overflow Menu if there are more than 3
actions, the other remaining actions should be placed into an Overflow Menu that is launched by
clicking the Overflow Button.
Also, ActionBar is a responsive component based on the width of its container. If the rendered
actions exceed the width of the ActionBar.List, an overflow menu will be rendered. This only works
against the dynamic API where you give the ActionBarModel an array of items to be rendered. The
dynamic API handles the React key for you based on the item’s identifier. The dynamic API requires
either an id on each item object or a getId function that returns an identifier based on the
item. The below example uses an id property on each item.
The dynamic API takes in any object, but since nothing is known about your object, a render prop is necessary to instruct a list how it should render.
import React from 'react';
import {breakpoints} from '@workday/canvas-kit-react/common';
import {ActionBar, useActionBarModel} from '@workday/canvas-kit-react/action-bar';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
import {SegmentedControl} from '@workday/canvas-kit-preview-react/segmented-control';
import {Box} from '@workday/canvas-kit-react/layout';
type MyActionItem = {
id: string;
text: React.ReactNode;
};
export default () => {
const [items] = React.useState<MyActionItem[]>([
{id: 'first', text: 'First Action'},
{id: 'second', text: 'Second Action'},
{id: 'third', text: 'Third Action'},
{id: 'fourth', text: 'Fourth Action'},
{id: 'fifth', text: 'Fifth Action'},
]);
const model = useActionBarModel({items});
const [containerWidth, setContainerWidth] = React.useState<string | number>('100%');
return (
<div>
<Box maxWidth={containerWidth} marginBottom="xl">
<ActionBar model={model}>
<ActionBar.List
position="relative"
as="section"
aria-label="Action Bar"
overflowButton={<ActionBar.OverflowButton aria-label="More actions" />}
>
{(item: MyActionItem, index) => (
<ActionBar.Item
as={index === 0 ? PrimaryButton : undefined}
onClick={() => console.log(item.id)}
>
{item.text}
</ActionBar.Item>
)}
</ActionBar.List>
<ActionBar.Menu.Popper>
<ActionBar.Menu.Card maxWidth={300} maxHeight={200}>
<ActionBar.Menu.List>
{(item: MyActionItem) => (
<ActionBar.Menu.Item onClick={() => console.log(item.id)}>
{item.text}
</ActionBar.Menu.Item>
)}
</ActionBar.Menu.List>
</ActionBar.Menu.Card>
</ActionBar.Menu.Popper>
</ActionBar>
</Box>
<footer>
<h4>Change Action Bar container size</h4>
<SegmentedControl onSelect={data => setContainerWidth(data.id)}>
<SegmentedControl.List role="group" aria-label="container width control" marginBottom="m">
<SegmentedControl.Item data-id="100%">100%</SegmentedControl.Item>
<SegmentedControl.Item data-id={`${breakpoints.m}px`}>Small</SegmentedControl.Item>
<SegmentedControl.Item data-id="420px">420px</SegmentedControl.Item>
<SegmentedControl.Item data-id={`${breakpoints.s}px`}>
Extra Small
</SegmentedControl.Item>
</SegmentedControl.List>
</SegmentedControl>
<p>Selected: {containerWidth}</p>
</footer>
</div>
);
};
The number of visible buttons can also be adjusted by using the model’s maximumVisible attribute.
You can change it from the default of 3 to any number greater than 1 and less than items.length.
import React from 'react';
import {ActionBar} from '@workday/canvas-kit-react/action-bar';
type MyActionItem = {
id: string;
text: React.ReactNode;
};
export default () => {
const [items] = React.useState<MyActionItem[]>([
{id: 'view', text: 'View'},
{id: 'edit', text: 'Edit'},
{id: 'delete', text: 'Delete'},
]);
return (
<ActionBar items={items} maximumVisible={2}>
<ActionBar.List
as="section"
aria-label="Custom button count overflow example"
position="relative"
overflowButton={<ActionBar.OverflowButton aria-label="More actions" />}
>
{(item: MyActionItem) => (
<ActionBar.Item onClick={() => console.log(item.id)}>{item.text}</ActionBar.Item>
)}
</ActionBar.List>
<ActionBar.Menu.Popper>
<ActionBar.Menu.Card>
<ActionBar.Menu.List>
{(item: MyActionItem) => (
<ActionBar.Menu.Item onClick={() => console.log(item.id)}>
{item.text}
</ActionBar.Menu.Item>
)}
</ActionBar.Menu.List>
</ActionBar.Menu.Card>
</ActionBar.Menu.Popper>
</ActionBar>
);
};
Accessibility
Grouping the actions into an HTML <section> element with an aria-label string is recommended.
This can be useful for helping screen reader users quickly jump down to the actions at the bottom of
a page.
Refer to Button and Menus for more information about accessibiliy of these components in the Action Bar.
Component API
ActionBar
ActionBar is a container component that is responsible for creating an {@link ActionBarModel }
and sharing it with its subcomponents using React context. It does not represent a real element.
<ActionBar items={[]}>{Child components}</ActionBar>
Alternatively, you may pass in a model using the hoisted model pattern.
const model = useActionBarModel({
items: [],
});
<ActionBar model={model}>{Child components}</ActionBar>;
Props
Props extend from . If a model is passed, props from ActionBarModelConfig are ignored.
| Name | Type | Description | Default |
|---|---|---|---|
children | ReactNode | The contents of the ActionBar. Can be | |
model | | Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context. | |
elemPropsHook | ( | Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one. |
ActionBar.List
ActionBar.List is a {@link Flex } element. It is a container for
subcomponents. To render an overflow button for
ActionBar with overflow behavior overflowButton prop with overflow button component as a
value should be passed.
// without overflow
<ActionBar.List>{ActionBar.Items}</ActionBar.List>
// with overflow
<ActionBar.List overflowButton={<ActionBar.OverflowButton aria-label="More actions"/>}>
{ActionBar.Items}
</ActionBar.List>
Layout Component
ActionBar.List supports all props from thelayout component.
Props
Props extend from div. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
children | (( | If items are passed to a | |
overflowButton | ReactNode |
| |
cs | | The | |
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | div |
ref | React.Ref<R = div> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If | |
model | | Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context. | |
elemPropsHook | ( | Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one. |
useOverflowListMeasure
This elemProps hook measures a list and reports it to an OverflowListModel. This is used in
overflow detection.
(
model: ,
elemProps: {},
ref: React.Ref
) => {
ref: (instance: | null) => void;
}ActionBar.Item
ActionBar.Item is a button element, by default it's a SecondaryButton unless an as
prop is passed.
<ActionBar.Item as={PrimaryButton} onClick={() => console.log('first action')}>
First Action
</ActionBar.Item>
Props
Props extend from . Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
children | ReactNode | The contents of the action item. This will be the accessible name of the action for screen readers. | |
data-id | string | The identifier of the action. This identifier will be used for correct overflow behavior. If this property is not provided, it will default to a string representation of the the zero-based index of the Item when it was initialized. | |
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | |
ref | React.Ref<R = > | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If | |
model | | Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context. | |
elemPropsHook | ( | Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one. |
useActionBarItem
(
,
)ActionBar.OverflowButton
Layout Component
ActionBar.OverflowButton supports all props from thelayout component.
Props
Props extend from button. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
aria-label | string | ||
variant | 'inverse' | Variant has an option for | |
iconPosition | 'start' | 'end' | Button icon positions can either be | 'start' |
shouldMirrorIcon | boolean | If set to | false |
shouldMirrorIconInRTL | boolean | If set to | false |
size | | There are four button sizes: | |
colors | | Override default colors of a button. The default will depend on the button type | |
icon | | The icon of the Button.
Note: Not displayed at | |
fill | string | The fill color of the SystemIcon. This overrides | |
background | string | The background color of the SystemIcon. | |
color | string | The color of the SystemIcon. This defines | |
shouldMirror | boolean | If set to | false |
shouldMirrorInRTL | boolean | If set to | false |
cs | | The | |
children | ReactNode | ||
accent | string | The accent color of the SystemIcon. This overrides | |
accentHover | string | The accent color of the SystemIcon on hover. This overrides | |
backgroundHover | string | The background color of the SystemIcon on hover. | |
colorHover | string | The hover color of the SystemIcon. This defines | |
fillHover | string | The fill color of the SystemIcon on hover. This overrides | |
fillIcon | boolean | Whether the icon should received filled (colored background layer) or regular styles.
Corresponds to | |
grow | boolean | True if the component should grow to its container's width. False otherwise. | |
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | button |
ref | React.Ref<R = button> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If | |
model | | Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context. | |
elemPropsHook | ( | Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one. |
useActionBarOverflowButton
(
(
model: ,
elemProps: {},
ref: React.Ref
) => {
aria-haspopup: true;
},
,
(
(model: ) => ,
)
)ActionBar.Menu
Basic type information:
MenuModel
useActionBarModel
useActionBarModel (config: ): Content Guidelines
- When naming buttons within an Action Bar, refer to the Buttons and Calls to Action section of the Content Style Guide.
Anatomy

- Primary Button: Used as the most important action on a page or task.
- Secondary Button: Actions that are less important than Primary Buttons.
- Overflow Button: A Secondary Icon-Only Button that opens an Overflow Menu.
- Bar Container: Container that groups buttons, anchored to the bottom of the screen.
Variations
Mobile
Mobile action bars can contain up to one Primary Button and one Secondary Button, with additional actions placed in an Overflow Menu.
Overflow
In the case of more than two calls to action in the bar, any overflowing actions should be placed in the Overflow Menu. Tapping on the Overflow Button will open a Menu with those Secondary or Tertiary Actions.

If the text within the Primary Button is too long to fit, the Secondary or Tertiary button(s) should move into the Overflow Menu to allow room for a full-width Primary Button.

Vertical Button Stack
While the horizontal stack is the default and preferred configuration, the buttons will automatically display in a vertical stack when truncation occurs within button labels. Alternatively if your use case places a priority on the action bar (E.g. empty states) you can use the vertical stack regardless of the truncation rule. When using the vertical stack be aware of previous or following page layouts that may be using a horizontal stack resulting in inconsistent layouts. The vertical stack is only available for phones; it’s not applicable to tablets.

Tablet
Action Bars on tablets may include up to one Primary and two Secondary Buttons.

Overflow
In the case of more than two calls to action in the bar, all overflowing actions should be placed in the Overflow Menu. Tapping on the Overflow Button will open a Menu containing those Secondary or Tertiary Actions.

If the Primary Button length is too long to fit the Secondary Button beside it, the Secondary Button should be placed in the Overflow Menu.

Usage Guidance
- There should only be one Primary Button in the Action Bar. If there are additional actions, use Secondary Buttons. Tertiary Buttons should only appear as actions in the Overflow Menu.
- Action Bars are placed at the bottom of the screen. If there is scrollable content, the Action Bar should remain sticky as the user scrolls.
- Although actions may change, the placement of the Action Bar should persist until the task is successfully submitted.
- Mobile Action Bars can contain up to two visible actions. If there are more than two actions, hide the third and any other actions in an Overflow Menu that is launched by tapping on the Icon Only Secondary Button Variant.
- Tablet Action Bars can contain up to three visible actions. If there are more than three actions, hide the fourth and any other actions in an Overflow Menu that is launched by tapping on the Icon Only Secondary Button Variant.
- Limit the Overflow Menu to a maximum of seven items.
- Group buttons in Action Bars logically, either by usage or ordered by importance.
When to Use
- Use Action Bars for tasks that require navigating between pages, saving progress, submitting a task, or canceling a task.
When to Use Something Else
- Consider taking a Button outside of the Action Bar if the action is not related to the progress or status of a task.
- Consider using a Tertiary Button instead of an Action Bar if an action is less popular or less important.
- If actions are not related to a full screen task, consider using a group of buttons instead.
Mobile Guidance
Button Placement
Mobile Action Bars place Primary Buttons on the right-most side to account for a majority of right handed users.

Do
Place Primary Buttons on the right for easy access.

Don't
Align Primary Buttons to the left of Action Bar
Button Resizing
Buttons in Mobile Action Bars stretch to fit the entire screen width, respecting padding and spacing tokens.
Only Show Depth if Content is Scrollable
If there is scrollable content, provide scrolling indication through use of Depth. If there is no scrollable content, no Depth is used on the Action Bar with a plain French Vanilla 100 background.

Do
Show Depth if there is scrollable content.

Don't
Apply Depth if there is no scrollable content
Device Considerations
8dp of bottom padding is taken away from the action bar if it’s rendered on a iPhoneX to account for the extra spacing for the home indicator.
Text Overflow
Buttons within Actions Bars should never wrap to multiple lines. Instead, truncate text when Buttons reach screen margins.

Do
Truncate text when Buttons reach Action Bar margins.

Don't
Have Button text wrap to multiple lines.
API Guidelines
Methods
Class name: ActionBarV2 Module name: UIComponentsPlugin
public init(
actions: [ActionBarItemModel],
style: ActionBarV2Internal.Style = .regular,
isContentScrollable: Bool = false,
localizer: LocalizationAdapting,
featureData: FeatureMetricsData
)Adds an ActionBar to any content as per Workday design requirements.
Parameters
| Name | Description |
|---|---|
| actions | An array of ActionBarItemModel that will be parsed into primary, secondary, and overflow actions based on the ActionBarStyle and device type. The first item of the array will always be the primary action, |
| style | ActionBarStyle that decides the layout of various actions in the ActionBar. Default is regular. Please refer to ActionBarStyle documentation for more details. |
| isContentScrollable | Boolean that indicates whether the parent view’s content is scrollable. If yes, ActionBar would have a specific styling with shadow on top. |
| localizer | Localization provider |
| featureData | The feature name/context and the screen ID in which the component appears |
Content Guidelines
- When naming buttons within an Action Bar, refer to the Buttons and Calls to Action section of the Content Style Guide.
Anatomy

- Primary Button: Used as the most important action on a page or task.
- Secondary Button: Actions that are less important than Primary Buttons.
- Overflow Button: A Secondary Icon-Only Button that opens an Overflow Menu.
- Bar Container: Container that groups buttons, anchored to the bottom of the screen.
Variations
Mobile
Mobile action bars can contain up to one Primary Button and one Secondary Button, with additional actions placed in an Overflow Menu.

Overflow
In the case of more than two calls to action in the bar, all overflowing actions should be placed in the Overflow Menu. Tapping on the Overflow Button will open a Menu with those Secondary or Tertiary Actions.
If the text within the Primary Button is too long to fit, the Secondary or Tertiary button(s) should move into the Overflow Menu to allow room for a full-width Primary Button.

Vertical Button Stack
While the horizontal stack is the default and preferred configuration, the buttons will automatically display in a vertical stack when truncation occurs within button labels. Alternatively if your use case places a priority on the action bar (E.g. empty states) you can use the vertical stack regardless of the truncation rule. When using the vertical stack be aware of previous or following page layouts that may be using a horizontal stack resulting in inconsistent layouts. The vertical stack is only available for phones; it’s not applicable to tablets.

Usage Guidance
- There should only be one Primary Button in the Action Bar. If there are additional actions, use Secondary Buttons. Tertiary Buttons should only appear as actions in the Overflow Menu.
- Action Bars are placed at the bottom of the screen. If there is scrollable content, the Action Bar should remain sticky as the user scrolls.
- Although actions may change, the placement of the Action Bar should persist until the task is successfully submitted.
- Mobile Action Bars can contain up to two visible actions. If there are more than two actions, hide the third and any other actions in an Overflow Menu that is launched by tapping on the Icon Only Secondary Button Variant.
- Tablet Action Bars can contain up to three visible actions. If there are more than three actions, hide the fourth and any other actions in an Overflow Menu that is launched by tapping on the Icon Only Secondary Button Variant.
- Limit the Overflow Menu to a maximum of seven items.
- Group buttons in Action Bars logically, either by usage or ordered by importance.
When to Use
- Use Action Bars for tasks that require navigating between pages, saving progress, submitting a task, or canceling a task.
When to Use Something Else
- Consider taking a Button outside of the Action Bar if the action is not related to the progress or status of a task.
- Consider using a Tertiary Button instead of an Action Bar if an action is less popular or less important.
- If actions are not related to a full screen task, consider using a group of buttons instead.
Mobile Guidance
Button Placement
Mobile Action Bars place Primary Buttons on the right-most side to account for a majority of right handed users.

Do
Place Primary Buttons on the right for easy access.

Don't
Align Primary Buttons to the left of Action Bar
Button Resizing
Buttons in Mobile Action Bars stretch to fit the entire screen width, respecting padding and spacing tokens.
Only Show Depth if Content is Scrollable
If there is scrollable content, provide scrolling indication through use of Depth. If there is no scrollable content, no Depth is used on the Action Bar with a plain French Vanilla 100 background.

Do
Show Depth if there is scrollable content.

Don't
Apply Depth if there is no scrollable content
Device Considerations
8dp of bottom padding is taken away from the action bar if it’s rendered on a iPhoneX to account for the extra spacing for the home indicator.
Text Overflow
Buttons within Actions Bars should never wrap to multiple lines. Instead, truncate text when Buttons reach screen margins.

Do
Truncate text when Buttons reach Action Bar margins.

Don't
Have Button text wrap to multiple lines.
API Guidelines
Component Definition
@Composable
fun [ActionBarUiComponent](
modifier: Modifier = Modifier,
numButtonsShown: [Int] = 1,
isScrollable: [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) = true,
buttonList: [List]<[ActionBarButtonItem]>
) {Parameters
| Name | Description |
|---|---|
| numButtonsShown | Number of individual buttons to be shown Phones will be restricted to 2 buttons and any additional buttons will be pushed into the menu |
| isScrollable | Boolean to let the component know if the screen is scrollable. When the screen is scrollable, the action bar will have a divider above the action bar. |
| buttonList | List of button name, onClickAction pairs Given a list of onClickAction pairs, the first pair on the list will be the primary action button |
Content Guidelines
- When naming buttons within an Action Bar, refer to the Buttons and Calls to Action section of the Content Style Guide.
Can't Find What You Need?
Check out our FAQ section which may help you find the information you're looking for. For further information, contact the #ask-canvas-design or #ask-canvas-kitchannels on Slack.