Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/segmented-control-aria-pressed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---

Use `aria-pressed` instead of `aria-current` on `SegmentedControl.Button` and `SegmentedControl.IconButton` so JAWS announces the selected state when a segment is activated.
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@
width: 0;
}

&[aria-disabled='true']:not([aria-current='true']) {
&[aria-disabled='true']:not([aria-pressed='true']) {
cursor: not-allowed;
color: var(--fgColor-disabled);
background-color: transparent;
Expand Down Expand Up @@ -305,7 +305,7 @@
justify-content: center;
}

.Button[aria-current='true'] {
.Button[aria-pressed='true'] {
padding: 0;
font-weight: var(--base-text-weight-semibold);

Expand All @@ -321,7 +321,7 @@
}
}

.Button:not([aria-current='true'], [aria-disabled='true']) {
.Button:not([aria-pressed='true'], [aria-disabled='true']) {
&:hover .Content {
background-color: var(--controlTrack-bgColor-hover);
}
Expand Down
23 changes: 18 additions & 5 deletions packages/react/src/SegmentedControl/SegmentedControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe('SegmentedControl', () => {

const selectedButton = getByText('Raw').closest('button')

expect(selectedButton?.getAttribute('aria-current')).toBe('true')
expect(selectedButton?.getAttribute('aria-pressed')).toBe('true')
})
Comment thread
liuliu-dev marked this conversation as resolved.

it('renders with a selected segment - uncontrolled', () => {
Expand All @@ -101,7 +101,7 @@ describe('SegmentedControl', () => {

const selectedButton = getByText('Raw').closest('button')

expect(selectedButton?.getAttribute('aria-current')).toBe('true')
expect(selectedButton?.getAttribute('aria-pressed')).toBe('true')
})

it('renders the dropdown variant', () => {
Expand Down Expand Up @@ -148,7 +148,7 @@ describe('SegmentedControl', () => {

const selectedButton = getByText('Preview').closest('button')

expect(selectedButton?.getAttribute('aria-current')).toBe('true')
expect(selectedButton?.getAttribute('aria-pressed')).toBe('true')
})

it('renders segments with segment labels that have leading icons', () => {
Expand Down Expand Up @@ -183,6 +183,19 @@ describe('SegmentedControl', () => {
}
})

it('renders IconButton with aria-pressed when selected', () => {
const {getByRole} = render(
<SegmentedControl aria-label="File view">
{segmentData.map(({label, icon}, index) => (
<SegmentedControl.IconButton icon={icon} aria-label={label} selected={index === 1} key={label} />
))}
</SegmentedControl>,
)

expect(getByRole('button', {name: 'Raw'})).toHaveAttribute('aria-pressed', 'true')
expect(getByRole('button', {name: 'Preview'})).toHaveAttribute('aria-pressed', 'false')
})

it('renders icon button with tooltip as label', () => {
const {getByRole, getByText} = render(
<SegmentedControl aria-label="File view">
Expand Down Expand Up @@ -252,11 +265,11 @@ describe('SegmentedControl', () => {

const buttonToClick = getByText('Raw').closest('button')

expect(buttonToClick?.getAttribute('aria-current')).toBe('false')
expect(buttonToClick?.getAttribute('aria-pressed')).toBe('false')
if (buttonToClick) {
await user.click(buttonToClick)
}
expect(buttonToClick?.getAttribute('aria-current')).toBe('true')
expect(buttonToClick?.getAttribute('aria-pressed')).toBe('true')
})

it('calls segment button onClick if it is passed', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const SegmentedControlButton: FCWithSlotMarker<React.PropsWithChildren<Segmented
data-component="SegmentedControl.Button"
>
<button
aria-current={selected}
aria-pressed={selected}
aria-disabled={disabled || ariaDisabled || undefined}
className={clsx(classes.Button, className)}
type="button"
Comment thread
liuliu-dev marked this conversation as resolved.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const SegmentedControlIconButton: FCWithSlotMarker<React.PropsWithChildre
>
<button
type="button"
aria-current={selected}
aria-pressed={selected}
// If description is provided, we will use the tooltip to describe the button, so we need to keep the aria-label to label the button.
aria-label={description ? ariaLabel : undefined}
Comment thread
liuliu-dev marked this conversation as resolved.
aria-disabled={disabled || ariaDisabled || undefined}
Expand Down
Loading