diff --git a/modules/react/action-bar/lib/ActionBarItem.tsx b/modules/react/action-bar/lib/ActionBarItem.tsx
index bfc28986d7..5297c88980 100644
--- a/modules/react/action-bar/lib/ActionBarItem.tsx
+++ b/modules/react/action-bar/lib/ActionBarItem.tsx
@@ -12,12 +12,14 @@ import {useActionBarModel} from './useActionBarModel';
export interface ActionBarItemProps {
/**
* The contents of the action item. This will be the accessible name of the action for screen readers.
+ * Omit it to render an icon-only button, and provide an `aria-label` instead.
*
* ```tsx
* First Action
+ *
* ```
*/
- children: React.ReactNode;
+ children?: React.ReactNode;
/**
* 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
diff --git a/modules/react/action-bar/spec/ActionBar.spec.tsx b/modules/react/action-bar/spec/ActionBar.spec.tsx
index 4f8dc6749e..88e44476fb 100644
--- a/modules/react/action-bar/spec/ActionBar.spec.tsx
+++ b/modules/react/action-bar/spec/ActionBar.spec.tsx
@@ -1,6 +1,23 @@
+import {render} from '@testing-library/react';
+import * as React from 'react';
+
+import {trashIcon} from '@workday/canvas-system-icons-web';
+
import {ActionBar} from '../lib/ActionBar';
import {useActionBarModel} from '../lib/useActionBarModel';
describe('ActionBar.Item', () => {
verifyComponent(ActionBar.Item, {modelFn: useActionBarModel});
+
+ it('should render an icon-only item named by its aria-label', () => {
+ const screen = render(
+
+
+
+
+
+ );
+
+ expect(screen.getByRole('button', {name: 'Delete'})).toBeInTheDocument();
+ });
});
diff --git a/modules/react/action-bar/stories/ActionBar.mdx b/modules/react/action-bar/stories/ActionBar.mdx
index 242c8a4a49..08326d6c70 100644
--- a/modules/react/action-bar/stories/ActionBar.mdx
+++ b/modules/react/action-bar/stories/ActionBar.mdx
@@ -2,6 +2,7 @@ import {Meta} from '@storybook/blocks';
import {ExampleCodeBlock, SymbolDoc} from '@workday/canvas-kit-docs';
import {Basic} from './examples/Basic';
import {Icons} from './examples/Icons';
+import {IconOnly} from './examples/IconOnly';
import {DeleteAction} from './examples/DeleteAction';
import {OverflowActionBar} from './examples/OverflowActionBar';
import {OverflowActionBarCustomButtonCount} from './examples/OverflowActionBarCustomButtonCount';
@@ -42,6 +43,14 @@ with `ActionBar.Item` such as `icon` or `size`.
+### Icon-Only Example
+
+An `ActionBar.Item` can render an icon-only button by passing an `icon` without `children`. Because
+there is no visible text, provide an `aria-label` so the action has an accessible name. Wrapping the
+item in a [Tooltip](/components/popups/tooltip/) also shows the label to sighted users.
+
+
+
### Delete Action Example
`ActionBar.Item` is a `SecondaryButton` by default but it's posible to change it to another element,
diff --git a/modules/react/action-bar/stories/ActionBar.stories.ts b/modules/react/action-bar/stories/ActionBar.stories.ts
index 25a3ee10b7..9da6f96d7d 100644
--- a/modules/react/action-bar/stories/ActionBar.stories.ts
+++ b/modules/react/action-bar/stories/ActionBar.stories.ts
@@ -5,6 +5,7 @@ import {ActionBar} from '@workday/canvas-kit-react/action-bar';
import mdxDoc from './ActionBar.mdx';
import {Basic as BasicExample} from './examples/Basic';
import {DeleteAction as DeleteActionExample} from './examples/DeleteAction';
+import {IconOnly as IconOnlyExample} from './examples/IconOnly';
import {Icons as IconsExample} from './examples/Icons';
import {OverflowActionBar as OverflowActionBarExample} from './examples/OverflowActionBar';
import {OverflowActionBarCustomButtonCount as OverflowActionBarCustomButtonCountExample} from './examples/OverflowActionBarCustomButtonCount';
@@ -28,6 +29,9 @@ export const Basic: Story = {
export const Icons: Story = {
render: IconsExample,
};
+export const IconOnly: Story = {
+ render: IconOnlyExample,
+};
export const DeleteAction: Story = {
render: DeleteActionExample,
};
diff --git a/modules/react/action-bar/stories/examples/IconOnly.tsx b/modules/react/action-bar/stories/examples/IconOnly.tsx
new file mode 100644
index 0000000000..84eddd2ba9
--- /dev/null
+++ b/modules/react/action-bar/stories/examples/IconOnly.tsx
@@ -0,0 +1,15 @@
+import {ActionBar} from '@workday/canvas-kit-react/action-bar';
+import {PrimaryButton} from '@workday/canvas-kit-react/button';
+import {editIcon, trashIcon} from '@workday/canvas-system-icons-web';
+
+export const IconOnly = () => {
+ return (
+
+
+ Save
+
+
+
+
+ );
+};
diff --git a/modules/react/action-bar/stories/examples/index.ts b/modules/react/action-bar/stories/examples/index.ts
index 4f37831963..12efa4dfbd 100644
--- a/modules/react/action-bar/stories/examples/index.ts
+++ b/modules/react/action-bar/stories/examples/index.ts
@@ -1,5 +1,6 @@
export {Basic} from './Basic';
export {DeleteAction} from './DeleteAction';
+export {IconOnly} from './IconOnly';
export {Icons} from './Icons';
export {OverflowActionBar} from './OverflowActionBar';
export {OverflowActionBarCustomButtonCount} from './OverflowActionBarCustomButtonCount';
diff --git a/modules/react/action-bar/stories/visual-testing/testing.stories.tsx b/modules/react/action-bar/stories/visual-testing/testing.stories.tsx
index e16ade025d..1f165125ba 100644
--- a/modules/react/action-bar/stories/visual-testing/testing.stories.tsx
+++ b/modules/react/action-bar/stories/visual-testing/testing.stories.tsx
@@ -4,6 +4,7 @@ import {ActionBar} from '@workday/canvas-kit-react/action-bar';
import {PrimaryButton, SecondaryButton} from '@workday/canvas-kit-react/button';
import {ComponentStatesTable, StaticStates} from '@workday/canvas-kit-react/testing';
import {cssVar, px2rem} from '@workday/canvas-kit-styling';
+import {editIcon, trashIcon} from '@workday/canvas-system-icons-web';
import {base} from '@workday/canvas-tokens-web';
export default {
@@ -55,6 +56,39 @@ export const ActionBarStates = {
),
};
+const ActionBarIconOnlyTest = () => (
+
+
+ {({size, withText}) => (
+
+
+ {withText && (
+
+ Save
+
+ )}
+
+
+
+
+ )}
+
+
+);
+
+export const ActionBarIconOnlyStates = {
+ render: () => ,
+};
+
export const ActionBarWithOverflowMenuStates = {
render: () => {
const [items] = React.useState([