Skip to content

Commit

Permalink
Merge pull request #61 from github/kh-arrow-key-aria-disabled
Browse files Browse the repository at this point in the history
Allow arrow key navigation on aria-disabled elements
  • Loading branch information
khiga8 authored Oct 24, 2022
2 parents 63a17e1 + 07b4b38 commit 4719f8c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 10 deletions.
20 changes: 18 additions & 2 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@
text-align: left;
padding: 0;
}
[aria-disabled="true"] {
color: gray;
}
</style>
</head>
<body>
<h1>Base examples</h1>
<h1>Examples</h1>
<h2>Base examples</h2>

<details>
<summary>Best robot: <span data-menu-button>Unknown</span></summary>
Expand Down Expand Up @@ -69,7 +73,19 @@ <h1>Base examples</h1>
</details-menu>
</details>

<h1>Autofocus example</h1>
<h2>`aria-disabled="true" example</h2>
<p>menu items with <code>aria-disabled="true"</code> should be keyboard navigable</p>
<details>
<summary data-menu-button autofocus>Least favorite robots</summary>
<details-menu>
<input type="text" autofocus />
<button name="robot" value="Hubot" aria-disabled="true" role="menuitemradio" data-menu-button-text>Hubot</button>
<button name="robot" value="Bender" role="menuitemradio" data-menu-button-text>Bender</button>
<button name="robot" value="BB-8" role="menuitemradio" data-menu-button-text>BB-8</button>
</details-menu>
</details>

<h2>Autofocus example</h2>
<p><code>summary</code> may have <code>autofocus</code> so it's the initially focused element in the page.</p>
<p>
Then any focusable element inside the popup can declare autofocus too, so it gets focus when the popup is opened.
Expand Down
6 changes: 1 addition & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,7 @@ function focusFirstItem(details: Element) {
}

function sibling(details: Element, next: boolean): HTMLElement | null {
const options = Array.from(
details.querySelectorAll<HTMLElement>(
'[role^="menuitem"]:not([hidden]):not([disabled]):not([aria-disabled="true"])'
)
)
const options = Array.from(details.querySelectorAll<HTMLElement>('[role^="menuitem"]:not([hidden]):not([disabled])'))
const selected = document.activeElement
const index = selected instanceof HTMLElement ? options.indexOf(selected) : -1
const found = next ? options[index + 1] : options[index - 1]
Expand Down
5 changes: 2 additions & 3 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe('details-menu element', function () {
summary.dispatchEvent(new KeyboardEvent('keydown', {key: 'ArrowUp', bubbles: true}))
assert(details.open, 'menu is open')

const last = [...details.querySelectorAll('[role="menuitem"]:not([disabled]):not([aria-disabled])')].pop()
const last = [...details.querySelectorAll('[role="menuitem"]:not([disabled])')].pop()
assert.equal(last, document.activeElement, 'arrow focuses last item')
})

Expand Down Expand Up @@ -219,7 +219,7 @@ describe('details-menu element', function () {
summary.dispatchEvent(new MouseEvent('click', {bubbles: true}))
details.dispatchEvent(new KeyboardEvent('keydown', {key: 'ArrowUp', bubbles: true}))

const notDisabled = details.querySelectorAll('[role="menuitem"]')[2]
const notDisabled = details.querySelectorAll('[role="menuitem"]')[3]
assert.equal(notDisabled, document.activeElement, 'arrow focuses on the last non-disabled item')

const disabled = details.querySelector('[aria-disabled="true"]')
Expand Down Expand Up @@ -423,7 +423,6 @@ describe('details-menu element', function () {
<details>
<summary>Click</summary>
<details-menu>
<button type="button" role="menuitem" aria-disabled="true">Hubot</button>
<button type="button" role="menuitem" disabled>Bender</button>
</details-menu>
</details>
Expand Down

0 comments on commit 4719f8c

Please sign in to comment.