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.
Icons Example
ActionBar.Item
renders a PrimaryButton
or SecondaryButton
, so it's possible to use other
Button props with ActionBar.Item
such as icon
or size
.
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.
Change action bar container size
Component API
ActionBar
Usage
ActionBar
is a container component that is responsible for creating a 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
Note that if you pass in a model
configured with useActionBarModel
, configuration props passed
to ActionBar
will be ignored.
Name | Type | Default | Description |
---|---|---|---|
children * | ReactNode | The contents of the ActionBar. Can be `ActionBar` children or any valid elements. | |
id | string | undefined | useUniqueId() | Optional id for the whole `ActionBar` group. If not provided, a unique id will be created. |
orientation | Orientation | undefined | 'horizontal' | The default ActionBar sub-components only handle rendering of button group in a horizontal orientation, but the sub-components could be replaced to handle vertical orientations. |
menuConfig | Partial<{ mode: "multiple" | "single"; returnFocusRef: RefObject<any> | undefined; initialFocusRef: RefObject<any> | undefined; id: string; initialVisibility: Visibility; ... 12 more ...; items: any[]; }> | undefined | ||
initialHiddenIds | string[] | undefined | ||
containerWidth | number | undefined | ||
initialSelectedIds | SelectedIds | undefined | ||
initialUnselectedIds | string[] | undefined | ||
selection | SelectionManager | undefined | ||
initialCursorId | string | undefined | ||
columnCount | number | undefined | ||
navigation | NavigationManager | undefined | ||
getId | ((item: any) => string) | undefined | ||
getTextValue | ((item: any) => string) | undefined | ||
nonInteractiveIds | string[] | undefined | ||
defaultItemHeight | number | undefined | ||
shouldVirtualize | boolean | undefined | ||
items | any[] | undefined | ||
model | { state: { hiddenIds: string[]; nonInteractiveIds: string[]; orientation: Orientation; itemWidthCache: Record<string, number>; containerWidth: number; overflowTargetWidth: number; ... 10 more ...; items: Item<...>[]; }; ... 4 more ...; getId: (item: any) => string; } | undefined | 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 | (<TProps>(model: { state: { hiddenIds: string[]; nonInteractiveIds: string[]; orientation: Orientation; itemWidthCache: Record<string, number>; containerWidth: number; overflowTargetWidth: number; ... 10 more ...; items: Item<...>[]; }; ... 4 more ...; getId: (item: any) => string; }, elemProps: TProps) => any) | un... | 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
Usage
ActionBar.List
is a HStack
element. It is a container for ActionBar.Item
subcomponents. To
apply an overflow behavior for ActionBar showOverflowButton
prop shold be true.
<ActionBar.List>{/* ActionBar.Items */}</ActionBar.List>
Props
Undocumented props are spread to the underlying HStack
element.
Name | Type | Default | Description |
---|---|---|---|
children * | ReactNode | ((item: unknown) => ReactNode) | If items are passed to a `ActionBarModel`, the child of `ActionBar.List` should be a render prop. The List will determine how and when the item will be rendered. @example <ActionBar.List> {(item) => <ActionBar.Item key={item.id} name={item.name}>{item.text}</ActionBar.Item>} </ActionBar.List> | |
flexDirection | "row" | "row-reverse" | undefined | "row" | sets the direction for the stack |
ref | React.Ref<any> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If `as` is set to an element, it will be that element. If `as` is a component, the reference will be to that component (or element if the component uses `React.forwardRef`). | |
model | { state: { hiddenIds: string[]; nonInteractiveIds: string[]; orientation: Orientation; itemWidthCache: Record<string, number>; containerWidth: number; overflowTargetWidth: number; ... 10 more ...; items: Item<...>[]; }; ... 4 more ...; getId: (item: any) => string; } | undefined | 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 | (<TProps>(model: { state: { hiddenIds: string[]; nonInteractiveIds: string[]; orientation: Orientation; itemWidthCache: Record<string, number>; containerWidth: number; overflowTargetWidth: number; ... 10 more ...; items: Item<...>[]; }; ... 4 more ...; getId: (item: any) => string; }, elemProps: TProps) => any) | un... | 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. | |
as | "symbol" | "object" | "small" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | ... 156 more ... | React.ComponentType<any> | 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 `React.forwardRef` and spread extra props to a root element. |
ActionBar.Item
Usage
ActionBar.Item
is a button
element, by default it's a SecondaryButton
unless an as
prop
passed.
<ActionBar.Item as={PrimaryButton} onClick={() => console.log('first action')}>First Action</ActionBar.Item>
Props
Undocumented props are spread to the underlying SecondaryButton
component.
Name | Type | Default | Description |
---|---|---|---|
children * | ReactNode | The contents of the action item. This will be the accessible name of the action for screen readers. ```tsx <ActionBar.Item>First Action</ActionBar.Item> ``` | |
data-id | string | undefined | 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. | |
ref | React.Ref<any> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If `as` is set to an element, it will be that element. If `as` is a component, the reference will be to that component (or element if the component uses `React.forwardRef`). | |
model | { state: { hiddenIds: string[]; nonInteractiveIds: string[]; orientation: Orientation; itemWidthCache: Record<string, number>; containerWidth: number; overflowTargetWidth: number; ... 10 more ...; items: Item<...>[]; }; ... 4 more ...; getId: (item: any) => string; } | undefined | 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 | (<TProps>(model: { state: { hiddenIds: string[]; nonInteractiveIds: string[]; orientation: Orientation; itemWidthCache: Record<string, number>; containerWidth: number; overflowTargetWidth: number; ... 10 more ...; items: Item<...>[]; }; ... 4 more ...; getId: (item: any) => string; }, elemProps: TProps) => any) | un... | 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. | |
as | "symbol" | "object" | "small" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | ... 156 more ... | React.ComponentType<any> | 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 `React.forwardRef` and spread extra props to a root element. |
Model
If ActionBar
was stripped of all its markup, attributes, and styling, what would remain is the
model. The model is an
object composed of two parts: state
which describes the current snapshot in time of the component
and events
which describes events that can be sent to the model.
By default, ActionBar
will create a model and share it internally with its subcomponents using
React context. Alternatively, if you need direct access to the model's state
and events
outside
of the ActionBar
component, you may configure your own model with useActionBarModel
and pass it
to ActionBar
via a pattern called
hoisting the model.
const model = useActionBarModel({items: [],});<ActionBar model={model}>{/* Child components */}</ActionBar>;
Config
useActionBarModel
accepts a configuration object with the following properties and returns a
ActionBarModel
with state
and events
properties.
Accessibility Guidelines
- The Button text and background color must meet the minimum contrast requirement.
- If an Icon Only Secondary Button Variant is used within an Action Bar, an accessible label must be provided to indicate the purpose of the control. Avoid using the words "image" or "icon" in the description label.
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.
FAQ Section