Skip to content

Add keyboard navigation to alphabetical and changes lists - #2023

Merged
UnniKohonen merged 8 commits into
mainfrom
issue1982-sidebar-concept-list-keyboard-usage
May 26, 2026
Merged

Add keyboard navigation to alphabetical and changes lists#2023
UnniKohonen merged 8 commits into
mainfrom
issue1982-sidebar-concept-list-keyboard-usage

Conversation

@UnniKohonen

@UnniKohonen UnniKohonen commented May 26, 2026

Copy link
Copy Markdown
Contributor

Reasons for creating this PR

Concept lists in sidebar are not currently navigable using the keyboard. This PR adds keyboard navigation to alphabetical and changes tabs.

Link to relevant issue(s), if any

Description of the changes in this PR

  • Add keyboard navigation to alphabetical concept list
    • Enter into/out of list using tab
    • Move up/down concept list using arrow keys
    • Move focus to last item with end key and to first with home
    • Open link using space key
  • Add keyboard navigation to changes concept list
    • Enter into/out of list using tab
    • Move up/down concept list using arrow keys
    • Move focus to last item with end key and to first with home
    • Open link using space key
  • Cypress tests for both

Known problems or uncertainties in this PR

Checklist

  • phpUnit tests pass locally with my changes
  • I have added tests that show that the new code works, or tests are not relevant for this PR (e.g. only HTML/CSS changes)
  • The PR doesn't reduce accessibility of the front-end code (e.g. tab focus, scaling to different resolutions, use of .sr-only class, color contrast)
  • The PR doesn't introduce unintended code changes (e.g. empty lines or useless reindentation)

@qltysh

qltysh Bot commented May 26, 2026

Copy link
Copy Markdown

2 new issues

Tool Category Rule Count
qlty Structure Function with high complexity (count = 9): handleKeydownEvent 2

Comment thread resource/js/tab-alpha.js
this.conceptInFocus -= 1
}
this.$refs['concept' + this.conceptInFocus][0].focus()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Function with high complexity (count = 7): handleKeydownEvent [qlty:function-complexity]

this.conceptInFocus -= 1
}
this.$refs['concept' + this.conceptInFocus][0].focus()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Function with high complexity (count = 7): handleKeydownEvent [qlty:function-complexity]

@codecov

codecov Bot commented May 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.42%. Comparing base (6a513ed) to head (e986760).

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #2023   +/-   ##
=========================================
  Coverage     70.42%   70.42%           
  Complexity     1703     1703           
=========================================
  Files            34       34           
  Lines          4436     4436           
=========================================
  Hits           3124     3124           
  Misses         1312     1312           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@UnniKohonen
UnniKohonen marked this pull request as ready for review May 26, 2026 08:12
@UnniKohonen
UnniKohonen requested a review from osma May 26, 2026 09:34
@osma
osma requested a review from Copilot May 26, 2026 09:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds keyboard navigation (Arrow up/down, Home, End, Space) to the sidebar concept lists on the Alphabetical and Changes tabs, partially addressing accessibility issue #1982. Tab enters/exits the list (only the focused item is in the tab order via roving tabindex), and Cypress tests verify the basic up/down behavior on both tabs.

Changes:

  • Implement roving-tabindex keyboard navigation in tab-alpha.js and tab-changes.js via a new conceptInFocus data property, per-link refs, and a handleKeydownEvent method on each list link.
  • Introduce indexedConcepts / changedConceptsLength computed properties in tab-changes.js to assign a unique focus index to each link (including replacedBy targets).
  • Add Cypress tests in sidebar-alpha.cy.js and sidebar-changes.cy.js that exercise Tab + Arrow Down + Arrow Up.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
resource/js/tab-alpha.js Adds conceptInFocus state, per-link refs and tabindex, and arrow/home/end/space keyboard handler for the alphabetical concept list.
resource/js/tab-changes.js Adds conceptInFocus state, computed indexedConcepts / changedConceptsLength, per-link refs and tabindex, and keyboard handler covering both prefLabel and replacedBy links.
tests/cypress/template/sidebar-alpha.cy.js Extends the alphabetical-index test to assert Tab/ArrowDown/ArrowUp focus behavior on the loaded list.
tests/cypress/template/sidebar-changes.cy.js Adds a new keyboard-navigation test for the changes tab covering Tab/ArrowDown/ArrowUp.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +230 to 260
handleKeydownEvent (e) {
if (e.key === ' ') {
// Click on link currently in focus
e.preventDefault()
this.$refs['concept' + this.conceptInFocus][0].click()
} else if (e.key === 'ArrowDown') {
// On last element move focus to first list item, otherwise next list item
e.preventDefault()
this.conceptInFocus = (this.conceptInFocus + 1) % this.changedConceptsLength
this.$refs['concept' + this.conceptInFocus][0].focus()
} else if (e.key === 'ArrowUp') {
// On first element move focus to last list item, otherwise to previous list item
e.preventDefault()
if (this.conceptInFocus === 0) {
this.conceptInFocus = this.changedConceptsLength - 1
} else {
this.conceptInFocus -= 1
}
this.$refs['concept' + this.conceptInFocus][0].focus()
} else if (e.key === 'End') {
// Move focus to last list item
e.preventDefault()
this.conceptInFocus = this.changedConceptsLength - 1
this.$refs['concept' + this.conceptInFocus][0].focus()
} else if (e.key === 'Home') {
// Move focus to first list item
e.preventDefault()
this.conceptInFocus = 0
this.$refs['concept' + this.conceptInFocus][0].focus()
}
}
Comment thread resource/js/tab-changes.js Outdated
Comment on lines +216 to +220
changedConceptsLength () {
return [...this.changedConcepts.values()]
.flat()
.reduce((acc, entry) => acc + 1 + (entry.replacedBy ? 1 : 0), 0)
}

@osma osma left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it looks good and seems to work based on the testing I did.

The Cypress tests should also check that opening concepts with the keyboard is working properly.

I asked Copilot for a review. The second comment it generated is worth checking out - is it possible to simplify the calculations?

cy.get('.aria-live-message').invoke('text').should('equal', 'Concepts loaded for letter B')
// Check that new concepts are loaded
cy.get('#tab-alphabetical').find('.sidebar-list li').first().invoke('text').should('contain', 'birch bark manuscripts')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This test only verifies moving between entries, but not opening them (with space and/or enter). I think that's pretty crucial functionality so it should be tested as well.


})
})
it('Keyboard navigation', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ditto, test opening (with space/enter) as well.

@UnniKohonen
UnniKohonen merged commit 10ae9e6 into main May 26, 2026
18 of 19 checks passed
@UnniKohonen
UnniKohonen deleted the issue1982-sidebar-concept-list-keyboard-usage branch May 26, 2026 11:08
@github-project-automation github-project-automation Bot moved this from In progress to Issue/PR closed in Skosmos 3.x Backlog May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Issue/PR closed

Development

Successfully merging this pull request may close these issues.

3 participants