diff --git a/.changeset/early-ghosts-enter.md b/.changeset/early-ghosts-enter.md
new file mode 100644
index 00000000000..f9e99a75774
--- /dev/null
+++ b/.changeset/early-ghosts-enter.md
@@ -0,0 +1,5 @@
+---
+'@primer/react': minor
+---
+
+Add support to ActionList for 'tablist' and 'tab' roles
diff --git a/packages/react/src/ActionList/Item.test.tsx b/packages/react/src/ActionList/Item.test.tsx
index 82bcc2dbb8f..1afeaeee9fd 100644
--- a/packages/react/src/ActionList/Item.test.tsx
+++ b/packages/react/src/ActionList/Item.test.tsx
@@ -354,4 +354,31 @@ describe('ActionList.Item', () => {
expect(item).toHaveTextContent('Item, Description')
expect(item).toHaveAccessibleDescription('Description')
})
+
+ it('should add role="tab" when ActionList has role="tablist"', () => {
+ const {getAllByRole} = HTMLRender(
+
+ Tab 1
+ Tab 2
+ Tab 3
+ ,
+ )
+ const tabs = getAllByRole('tab')
+ expect(tabs[0]).toBeInTheDocument()
+ expect(tabs).toHaveLength(3)
+ })
+
+ it('should allow role="tab" on the li element', () => {
+ const {getAllByRole} = HTMLRender(
+
+ Tab 1
+ Tab 2
+ Tab 3
+ ,
+ )
+ const tabs = getAllByRole('tab')
+ expect(tabs[0]).toBeInTheDocument()
+ expect(tabs[0].nodeType).toBe(Node.ELEMENT_NODE)
+ expect(tabs).toHaveLength(3)
+ })
})
diff --git a/packages/react/src/ActionList/Item.tsx b/packages/react/src/ActionList/Item.tsx
index b25a169bd50..9d2a60d2c4f 100644
--- a/packages/react/src/ActionList/Item.tsx
+++ b/packages/react/src/ActionList/Item.tsx
@@ -123,6 +123,8 @@ const UnwrappedItem = (
else inferredItemRole = 'menuitem'
} else if (listRole === 'listbox') {
if (selectionVariant !== undefined && !role) inferredItemRole = 'option'
+ } else if (listRole === 'tablist') {
+ inferredItemRole = 'tab'
}
const itemRole = role || inferredItemRole
@@ -142,7 +144,11 @@ const UnwrappedItem = (
const itemSelectionAttribute = selectionAttribute || inferredSelectionAttribute
// Ensures ActionList.Item retains list item semantics if a valid ARIA role is applied, or if item is inactive
const listItemSemantics =
- role === 'option' || role === 'menuitem' || role === 'menuitemradio' || role === 'menuitemcheckbox'
+ itemRole === 'option' ||
+ itemRole === 'menuitem' ||
+ itemRole === 'menuitemradio' ||
+ itemRole === 'menuitemcheckbox' ||
+ itemRole === 'tab'
const listRoleTypes = ['listbox', 'menu', 'list']
const listSemantics = (listRole && listRoleTypes.includes(listRole)) || inactive || listItemSemantics