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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,18 @@ These settings are available:
npm install
npm test
```

## Troubleshooting

### Combobox options must have unique IDs

Passing a combobox whose options lack IDs results in the following console warning.

> Combobox options must have unique IDs
> See https://github.com/github/combobox-nav/?tab=readme-ov-file#combobox-options-must-have-unique-ids
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL in the documented warning includes ?tab=readme-ov-file, which is a GitHub UI-specific query param and not a stable permalink. Consider switching to a stable README anchor link so the troubleshooting reference doesn't rot.

Suggested change
> See https://github.com/github/combobox-nav/?tab=readme-ov-file#combobox-options-must-have-unique-ids
> See https://github.com/github/combobox-nav#combobox-options-must-have-unique-ids

Copilot uses AI. Check for mistakes.

Without the IDs we lack a unique identifier for [`aria-activedescendant`](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_focus_activedescendant) to reference. As a result, screen readers are unable to announce which option is currently selected.

You can remove this warning by setting IDs on every option in the combobox.
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This troubleshooting section title/message says options must have "unique IDs", but the described trigger is "options lack IDs". Align the documentation with the actual runtime check (missing id vs missing/empty/non-unique ids), otherwise readers may look for duplicate IDs when the warning is really about absent/invalid IDs.

Suggested change
You can remove this warning by setting IDs on every option in the combobox.
You can remove this warning by ensuring every option in the combobox has a non-empty `id` attribute (the warning is triggered when options are missing IDs, not when IDs are duplicated).

Copilot uses AI. Check for mistakes.


7 changes: 7 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ export default class Combobox {
list.id = `combobox-${Math.random().toString().slice(2, 6)}`
}

if (list.querySelectorAll('[role="option"]:not([id])').length > 0) {
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're only checking for existence, querySelector('[role="option"]:not([id])') avoids allocating a full NodeList just to read .length and is simpler.

Suggested change
if (list.querySelectorAll('[role="option"]:not([id])').length > 0) {
if (list.querySelector('[role="option"]:not([id])') !== null) {

Copilot uses AI. Check for mistakes.
console.warn([
'Combobox options must have unique IDs',
'See https://github.com/github/combobox-nav/?tab=readme-ov-file#combobox-options-must-have-unique-ids',
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs URL includes the GitHub UI query param ?tab=readme-ov-file, which is not a stable permalink and may break over time. Prefer a stable README anchor URL (e.g., the repo root #... link or a blob/<branch>/README.md#... link).

Suggested change
'See https://github.com/github/combobox-nav/?tab=readme-ov-file#combobox-options-must-have-unique-ids',
'See https://github.com/github/combobox-nav#combobox-options-must-have-unique-ids',

Copilot uses AI. Check for mistakes.
].join('\n'))
}
Comment on lines +52 to +57
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces a new runtime warning; please add a test that stubs console.warn and asserts it fires when an option is missing an id (and does not fire when all options have valid IDs). This will prevent regressions as the selection logic evolves.

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +57
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will emit a console warning once per Combobox instance, which can get very noisy on pages that create multiple instances (and can flood error tracking if console output is captured). Consider deduplicating (e.g., a module-level flag / Set) so the warning is logged at most once per page/session (or once per list element).

Copilot uses AI. Check for mistakes.

Comment on lines +52 to +58
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warning text says options must have "unique IDs", but the check only detects options missing an id attribute (and it won't catch empty id=""). Either update the detection to validate non-empty + uniqueness, or adjust the warning text to match what is actually being checked.

Suggested change
if (list.querySelectorAll('[role="option"]:not([id])').length > 0) {
console.warn([
'Combobox options must have unique IDs',
'See https://github.com/github/combobox-nav/?tab=readme-ov-file#combobox-options-must-have-unique-ids',
].join('\n'))
}
const optionElements = Array.from(list.querySelectorAll<HTMLElement>('[role="option"]'))
const seenOptionIds = new Set<string>()
let hasOptionIdIssue = false
for (const option of optionElements) {
const id = option.getAttribute('id')
if (!id) {
hasOptionIdIssue = true
break
}
if (seenOptionIds.has(id)) {
hasOptionIdIssue = true
break
}
seenOptionIds.add(id)
}
if (hasOptionIdIssue) {
console.warn(
[
'Combobox options must have unique, non-empty IDs',
'See https://github.com/github/combobox-nav/?tab=readme-ov-file#combobox-options-must-have-unique-ids',
].join('\n'),
)
}

Copilot uses AI. Check for mistakes.
this.ctrlBindings = !!navigator.userAgent.match(/Macintosh/)

this.keyboardEventHandler = event => keyboardBindings(event, this)
Expand Down
Loading