Skip to content

Commit

Permalink
Apply correct markup to selected breadcrumb items (#833)
Browse files Browse the repository at this point in the history
  • Loading branch information
rezrah authored Nov 28, 2024
1 parent 6e398ba commit 0f8bfa6
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/sharp-pets-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react-brand': patch
---

`selected` breadcrumb items now use non-interactive elements for improved keyboard navigation and correct semantics.
2 changes: 2 additions & 0 deletions packages/react/src/Breadcrumbs/Breadcrumbs.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
.Breadcrumbs__link--selected {
color: var(--brand-color-text-default);
pointer-events: none;
font-weight: inherit;
letter-spacing: inherit;
}
.Breadcrumbs--default .Breadcrumbs__link--selected {
color: var(--brand-color-text-muted);
Expand Down
34 changes: 24 additions & 10 deletions packages/react/src/Breadcrumbs/Breadcrumbs.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ describe('Breadcrumbs', () => {
<Breadcrumbs>
<Breadcrumbs.Item href="/">Resources</Breadcrumbs.Item>
<Breadcrumbs.Item href="/copilot">GitHub Copilot</Breadcrumbs.Item>
<Breadcrumbs.Item href="/copilot/chat" selected>
Chat
</Breadcrumbs.Item>
<Breadcrumbs.Item href="/copilot/chat">Chat</Breadcrumbs.Item>
</Breadcrumbs>,
)

Expand All @@ -54,8 +52,27 @@ describe('Breadcrumbs', () => {
const item3 = breadcrumbLinkEls[2]
expect(item3.textContent).toBe('Chat')
expect(item3.getAttribute('href')).toBe('/copilot/chat')
expect(item3.classList).toContain('Breadcrumbs__link--selected')
})

it('renders selected items correctly into the document', () => {
const {getByText, getByRole, getAllByRole} = render(
<Breadcrumbs>
<Breadcrumbs.Item href="/">Resources</Breadcrumbs.Item>
<Breadcrumbs.Item href="/copilot">GitHub Copilot</Breadcrumbs.Item>
<Breadcrumbs.Item href="/copilot/chat" selected>
Chat
</Breadcrumbs.Item>
</Breadcrumbs>,
)

expect(getAllByRole('link')).toHaveLength(2)
expect(getByRole('link', {name: 'Resources'})).toHaveAttribute('href', '/')
expect(getByRole('link', {name: 'GitHub Copilot'})).toHaveAttribute('href', '/copilot')

const item3 = getByText('Chat')
expect(item3).toHaveAttribute('aria-current', 'page')
expect(item3.tagName).toBe('span'.toUpperCase())
expect(item3.classList).toContain('Breadcrumbs__link--selected')
})

it('renders accent variant correctly into the document', () => {
Expand All @@ -74,8 +91,8 @@ describe('Breadcrumbs', () => {
})

it('accepts a custom aria-current value to override the default', () => {
const {getByRole} = render(
<Breadcrumbs variant="accent">
const {getByText} = render(
<Breadcrumbs>
<Breadcrumbs.Item href="/">Resources</Breadcrumbs.Item>
<Breadcrumbs.Item href="/copilot">GitHub Copilot</Breadcrumbs.Item>
<Breadcrumbs.Item href="/copilot/chat" selected aria-current="location">
Expand All @@ -84,11 +101,8 @@ describe('Breadcrumbs', () => {
</Breadcrumbs>,
)

const breadcrumbsEl = getByRole('navigation')
expect(breadcrumbsEl).toHaveClass('Breadcrumbs--accent')
const item3 = getByText('Chat')

const breadcrumbLinkEls = breadcrumbsEl.querySelectorAll('a')
const item3 = breadcrumbLinkEls[2]
expect(item3).toHaveAttribute('aria-current', 'location')
})
})
31 changes: 18 additions & 13 deletions packages/react/src/Breadcrumbs/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '@primer/brand-primitives/lib/design-tokens/css/tokens/functional/compone
/** * Main Stylesheet (as a CSS Module) */
import styles from './Breadcrumbs.module.css'
import {InlineLink} from '../InlineLink'
import {Text} from '../Text'

export const BreadcrumbVariants = ['default', 'accent'] as const

Expand Down Expand Up @@ -42,23 +43,27 @@ type ItemProps = {
} & BaseProps<HTMLAnchorElement> &
React.HTMLAttributes<HTMLAnchorElement>

const _Item = forwardRef<HTMLAnchorElement, ItemProps>(
({'aria-current': ariaCurrent, className, children, href, selected, ...rest}, ref) => {
return (
<li className={styles.Breadcrumbs__item}>
<InlineLink
href={href}
ref={ref}
className={clsx(styles.Breadcrumbs__link, selected && styles['Breadcrumbs__link--selected'], className)}
aria-current={ariaCurrent ? ariaCurrent : selected ? 'page' : undefined}
const _Item = forwardRef<HTMLAnchorElement, ItemProps>(({className, children, href, selected, ...rest}, ref) => {
return (
<li className={styles.Breadcrumbs__item}>
{selected ? (
<Text
size="100"
variant="muted"
className={clsx(styles.Breadcrumbs__link, styles['Breadcrumbs__link--selected'], className)}
aria-current="page"
{...rest}
>
{children}
</Text>
) : (
<InlineLink href={href} ref={ref} className={clsx(styles.Breadcrumbs__link, className)} {...rest}>
{children}
</InlineLink>
</li>
)
},
)
)}
</li>
)
})

/**
* Use Breadcrumbs to display the current location within a navigational hierarchy.
Expand Down

0 comments on commit 0f8bfa6

Please sign in to comment.