Skip to content

Commit 4e1a797

Browse files
committed
Update ActionList to work with tablist & tab roles
1 parent 12fad7a commit 4e1a797

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

.changeset/early-ghosts-enter.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@primer/react': patch
3+
---
4+
5+
Add support to ActionList for 'tablist' and 'tab' roles

packages/react/src/ActionList/ActionList.dev.stories.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import {Divider} from './Divider'
88
import {Description} from './Description'
99
import Avatar from '../Avatar'
1010
import {FileDirectoryIcon, HeartFillIcon} from '@primer/octicons-react'
11+
import {TabContainerElement} from '@github/tab-container-element'
1112
import {Stack} from '../Stack'
1213
import {AnchoredOverlay} from '../AnchoredOverlay'
14+
import createComponent from '../utils/create-component'
1315

1416
export default {
1517
title: 'Components/ActionList/Dev',
@@ -375,3 +377,45 @@ export const OverlayWrapping = () => {
375377
</div>
376378
)
377379
}
380+
381+
const TabContainerComponent = createComponent(TabContainerElement, 'tab-container')
382+
383+
export const TabListRoles = () => (
384+
<TabContainerComponent>
385+
<ActionList role="tablist" aria-label="Tabs example">
386+
<ActionList.Item role="tab">Tab 1</ActionList.Item>
387+
<ActionList.Item role="tab">Tab 2</ActionList.Item>
388+
<ActionList.Item role="tab" aria-selected>
389+
Tab 3
390+
</ActionList.Item>
391+
</ActionList>
392+
<div role="tabpanel" data-tab-container-no-tabstop>
393+
Panel 1
394+
</div>
395+
<div role="tabpanel" data-tab-container-no-tabstop hidden>
396+
Panel 2
397+
</div>
398+
<div role="tabpanel" data-tab-container-no-tabstop hidden>
399+
Panel 3
400+
</div>
401+
</TabContainerComponent>
402+
)
403+
404+
export const TabListInfersItemRole = () => (
405+
<TabContainerComponent>
406+
<ActionList role="tablist" aria-label="Tabs example">
407+
<ActionList.Item>Tab 1</ActionList.Item>
408+
<ActionList.Item>Tab 2</ActionList.Item>
409+
<ActionList.Item>Tab 3</ActionList.Item>
410+
</ActionList>
411+
<div role="tabpanel" data-tab-container-no-tabstop>
412+
Panel 1
413+
</div>
414+
<div role="tabpanel" data-tab-container-no-tabstop hidden>
415+
Panel 2
416+
</div>
417+
<div role="tabpanel" data-tab-container-no-tabstop hidden>
418+
Panel 3
419+
</div>
420+
</TabContainerComponent>
421+
)

packages/react/src/ActionList/ActionList.module.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@
186186
}
187187

188188
/* active state [aria-current] */
189-
&:where([data-active]) {
189+
&:where([data-active]),
190+
&:where([aria-selected='true']) {
190191
background: var(--control-transparent-bgColor-selected);
191192

192193
/* provides a visual indication of the current item for Windows high-contrast mode */

packages/react/src/ActionList/Item.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ const UnwrappedItem = <As extends React.ElementType = 'li'>(
123123
else inferredItemRole = 'menuitem'
124124
} else if (listRole === 'listbox') {
125125
if (selectionVariant !== undefined && !role) inferredItemRole = 'option'
126+
} else if (listRole === 'tablist') {
127+
inferredItemRole = 'tab'
126128
}
127129

128130
const itemRole = role || inferredItemRole
@@ -142,7 +144,11 @@ const UnwrappedItem = <As extends React.ElementType = 'li'>(
142144
const itemSelectionAttribute = selectionAttribute || inferredSelectionAttribute
143145
// Ensures ActionList.Item retains list item semantics if a valid ARIA role is applied, or if item is inactive
144146
const listItemSemantics =
145-
role === 'option' || role === 'menuitem' || role === 'menuitemradio' || role === 'menuitemcheckbox'
147+
itemRole === 'option' ||
148+
itemRole === 'menuitem' ||
149+
itemRole === 'menuitemradio' ||
150+
itemRole === 'menuitemcheckbox' ||
151+
itemRole === 'tab'
146152

147153
const listRoleTypes = ['listbox', 'menu', 'list']
148154
const listSemantics = (listRole && listRoleTypes.includes(listRole)) || inactive || listItemSemantics

0 commit comments

Comments
 (0)