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