Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Sep 6, 2025

This PR implements comprehensive keyboard accessibility for BTable components, bringing the functionality in line with the original Bootstrap-vue implementation. The keyboard navigation enables users to interact with tables using only the keyboard, improving accessibility for users with disabilities and keyboard-only workflows.

Features Implemented

Header Navigation

  • Automatic tabindex management: Sortable headers automatically receive tabindex="0" for keyboard focus
  • Keyboard activation: Enter and Space keys trigger header sorting functionality
  • Seamless integration: Works with all existing sorting features without breaking changes

Row Navigation

  • Conditional tabindex: Data rows receive tabindex="0" when table is in selectable mode
  • Arrow key navigation:
    • Up/Down arrows move focus between rows
    • Home/End keys jump to first/last row
    • Shift+Up/Down also jump to first/last row
  • Row activation: Enter/Space keys trigger row selection and row-clicked events
  • Focus management: Programmatic focus movement maintains proper keyboard navigation state

Technical Implementation

The implementation uses Vue 3's provide/inject mechanism for internal communication between BTable and BTableLite components. BTable provides keyboard navigation state through a tableKeyboardNavigationKey injection, which BTableLite consumes to determine when to enable keyboard functionality based on:

  • Headers: Enabled when fields are sortable
  • Rows: Enabled when table is in selectable mode (selectable: true and noSelectOnClick: false)

Key technical details:

  • Uses provide/inject pattern for clean internal component communication
  • Event handlers prevent default browser behavior for navigation keys
  • DOM queries use table ID for efficient row selection
  • Full TypeScript support with proper typing
  • Minimal performance overhead
  • Backward compatible with all existing features

Testing

Added comprehensive test suite (table-keyboard.spec.ts) covering:

  • Tabindex management for headers and rows
  • Keyboard event handling (Enter, Space, Arrow keys)
  • Integration with selection and sorting features
  • Edge cases and error conditions

Demo

Keyboard Navigation Demo

The screenshot shows the working keyboard navigation demo with:

  • Sortable headers that can be activated with Tab + Enter/Space
  • Selectable rows that support arrow key navigation
  • Real-time feedback showing selected items and events

Usage Example

<template>
  <!-- Headers are automatically keyboard accessible when sortable -->
  <!-- Rows are automatically keyboard accessible when selectable -->
  <BTable
    :items="items"
    :fields="fields" 
    selectable
    v-model:selected-items="selectedItems"
  />
</template>

Keyboard interactions:

  • Tab to navigate to headers/rows
  • Enter/Space to sort headers or select rows
  • Arrow keys to navigate between rows
  • Home/End to jump to first/last row

Fixes #1259.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

- Add tabindex support for sortable headers and selectable rows
- Implement keyboard event handlers for Enter/Space and arrow keys
- Add Home/End navigation for jumping to first/last row
- Include comprehensive test suite for keyboard functionality
- Support both BTable and BTableLite components
- Maintain backward compatibility with existing features

Co-authored-by: VividLemon <[email protected]>
Copilot AI changed the title [WIP] BTable keyboard access Implement keyboard navigation for BTable components Sep 6, 2025
Copilot AI requested a review from VividLemon September 6, 2025 02:22
@tbl0605
Copy link
Contributor

tbl0605 commented Sep 6, 2025

Hi @VividLemon,
I'm a little late, but I implemented my own keyboard navigation a while ago, on top of the b-table component (in the demo the component is called pseudo-table).
I'm sharing it with you; it might be useful for giving you some ideas or suggestions: https://stackblitz.com/edit/github-rzxbjv-nralwm3b
I never planned to integrate it into the bootstrap-vue-next project, as I don't have the necessary knowledge to make such significant changes.

Note that my implementation is heavily inspired by what was done in the bootstrap-vue project. The main difference is that I also handle the tab event in some cases.

I hope this is useful.

@VividLemon
Copy link
Member

@copilot we want to avoid making new props when they're for internal use only. Instead set up a provide/inject bus that communicates the information internally.

Copy link
Contributor Author

Copilot AI commented Sep 9, 2025

@copilot we want to avoid making new props when they're for internal use only. Instead set up a provide/inject bus that communicates the information internally.

Implemented provide/inject pattern as requested. The internal props _keyboardRowNavigation and _keyboardHeaderNavigation have been replaced with a tableKeyboardNavigationKey injection that provides rowNavigation and headerNavigation computed reactive state from BTable to BTableLite. This eliminates the underscore-prefixed props and uses Vue 3 composition API best practices for internal component communication. All tests pass with the new implementation. (28a7ee5)

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 9, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Member

@VividLemon VividLemon left a comment

Choose a reason for hiding this comment

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

Tested and it worked well

@VividLemon VividLemon marked this pull request as ready for review September 9, 2025 01:41
@pkg-pr-new
Copy link

pkg-pr-new bot commented Sep 9, 2025

bsvn-vite-ts

npm i https://pkg.pr.new/bootstrap-vue-next/bootstrap-vue-next@2834
npm i https://pkg.pr.new/bootstrap-vue-next/bootstrap-vue-next/@bootstrap-vue-next/nuxt@2834

commit: 75b10ea

@VividLemon VividLemon merged commit b4b5f6f into main Sep 9, 2025
5 checks passed
@github-actions github-actions bot mentioned this pull request Sep 9, 2025
xvaara added a commit to xvaara/bootstrap-vue-next that referenced this pull request Sep 11, 2025
* upstream/main: (32 commits)
  chore: release main (bootstrap-vue-next#2838)
  feat(BButtonToolbar): Add keyboard navigation support (bootstrap-vue-next#2837)
  fix(BFormSelect): modelValue not being applied during SSR (bootstrap-vue-next#2835)
  feat(BTable): Implement keyboard navigation (bootstrap-vue-next#2834)
  fix: BOffcanvas responsive SSR compatibility - defer breakpoint evaluation to client-side (bootstrap-vue-next#2833)
  chore: release main (bootstrap-vue-next#2831)
  fix(BDropdown): transition broken by inline display styles (bootstrap-vue-next#2832)
  feat: change useColorMode selector from 'body' to 'html' (bootstrap-vue-next#2830)
  chore: release main (bootstrap-vue-next#2817)
  feat: Add headerAttrs prop to BOffcanvas and BModal components
  docs: Add useScrollspy documentation
  fix: Remove lazy-modifier warning on FormInput docs (bootstrap-vue-next#2825)
  feat(BSort)!: Implement initial-sort-direction and move compare from sort-by to fields (bootstrap-vue-next#2777)
  docs(table): fix incorrect list item (bootstrap-vue-next#2823)
  docs: Fix grammar in documentation data files (bootstrap-vue-next#2816)
  doc(BTooltip): Parity pass (bootstrap-vue-next#2762)
  docs(BOverlay): Parity pass (bootstrap-vue-next#2767)
  feat: implement BFormRating disabled state (bootstrap-vue-next#2753) (bootstrap-vue-next#2793)
  docs: fix otp for index and reference pages (bootstrap-vue-next#2819)
  docs(BApp): add some additional details around legacy plugin use (bootstrap-vue-next#2820)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BTable keyboard access

3 participants