Skip to content

Comments

fix(a11y): Make recurrence modal fully keyboard-accessible#1533

Open
jensens wants to merge 1 commit intomasterfrom
fix/recurrence-keyboard-accessibility
Open

fix(a11y): Make recurrence modal fully keyboard-accessible#1533
jensens wants to merge 1 commit intomasterfrom
fix/recurrence-keyboard-accessibility

Conversation

@jensens
Copy link
Member

@jensens jensens commented Feb 12, 2026

Summary

Fixes plone/Products.CMFPlone#4272

The recurrence modal had two keyboard accessibility issues:

  1. "End recurrence" only accessible when tabbing backwards — the modal's focus trap built a static list of focusable elements at open time, missing dynamically shown/hidden fields
  2. "Selected dates" and "exclude" buttons unreachable without mouse — occurrence action links loaded via AJAX were never in the focus trap, and used <a href="#"> instead of proper <button> elements

Changes

  • Dynamic focus trap (pat/modal/modal.js): activateFocusTrap() now re-queries visible focusable elements on each Tab keypress instead of using a static list captured at init. This benefits all modals across Plone, not just recurrence.
  • Semantic buttons (occurrence.xml, display.xml, recurrence.js): Changed occurrence action links and display widget "Add"/"Delete" links from <a href="#"> to <button type="button"> for proper semantics and native keyboard support (Enter + Space).
  • CSS updates (recurrence.scss): Updated selector from div.ridisplay .rimain a to div.ridisplay .rimain button. Added :focus-visible outline for occurrence action buttons.
  • Tests (recurrence.test.js): Added tests verifying <button> elements are used for display controls and dynamically added date actions.

Test plan

  • All 194 existing tests pass (28 suites)
  • 2 new tests added and passing
  • Manual testing: open an Event edit form, click "Edit" on recurrence, verify Tab reaches all controls including "End recurrence" range options and occurrence exclude/include buttons
  • Verify Shift+Tab wraps correctly through the modal
  • Verify the "Add"/"Delete rules" buttons in the display widget are keyboard-accessible

@jensens jensens marked this pull request as draft February 12, 2026 11:28
Fixes plone/Products.CMFPlone#4272

- Make modal focus trap dynamic: re-query visible focusable elements on
  each Tab press so that AJAX-loaded content (occurrence lists) and
  dynamically shown/hidden fields are always reachable via keyboard.
- Change occurrence action links (<a href="#">) to <button> elements
  for proper semantics and native keyboard support (Enter + Space).
- Change display widget "Add"/"Delete" links to <button> elements.
- Update all matching JS selectors and CSS rules.
- Add focus-visible outline styles for occurrence action buttons.
- Add tests verifying button elements are used.
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.

Accessibility issue: Recurrence in events is not configurable via keyboard

1 participant