Skip to content

⚡️(frontend) improve accessibility of selected document's sub-menu #1261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

Ovgodd
Copy link
Collaborator

@Ovgodd Ovgodd commented Aug 1, 2025

Purpose

This pull request improves the accessibility of the document tree by allowing keyboard users to:

  • See the action menu (e.g. “more options” and “create sub-document” buttons) when navigating with Tab.
  • Open a sub-document by pressing Enter when the corresponding tree item is focused.

issue : 1160

createsubdoc.mp4

Sub-document navigation is accessible, we can now navigate and open sub-docs using the keyboard.

Implementation note:
A small useTreeItemKeyboardActivate hook listens for Enter or Space only when the current node has focus (node.isFocused). This compensates for a limitation in react-arborist, which doesn't trigger any "activate" behavior on keyboard events.

For the action buttons (like ... or +) that appear when a tree item is focused:
By default, react-arborist uses a "roving tabindex", so these buttons are not reachable with Tab.
To fix this and make them keyboard-accessible:
I added a hook useActionableMode and some algo.

Proposal

  • Add :focus-within on the tree item wrapper to show the contextual action menu when a child receives focus.
  • Add :focus-visible outlines on buttons inside the menu to improve visible feedback.
  • Add aria-label attributes to make icon-only buttons screen reader accessible (e.g. “More options”, “Add chil document”).
  • Add keyboard support for the icon buttons using onKeyDown to handle Enter and Space.

@Ovgodd Ovgodd requested a review from AntoLC August 1, 2025 13:01
@Ovgodd Ovgodd self-assigned this Aug 1, 2025
@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch 2 times, most recently from 3463226 to a4249b3 Compare August 1, 2025 13:02
@Ovgodd Ovgodd marked this pull request as ready for review August 1, 2025 13:02
@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch 23 times, most recently from 6d0eba4 to 069359a Compare August 6, 2025 15:28
@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch from 069359a to 154abdd Compare August 7, 2025 05:54
Copy link
Collaborator

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

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

✨(frontend) add keyboard navigation for subdocs with focus activation
This commit should have a e2e test attached, to clearly understand what is the purpose of it.

Comment on lines 152 to 162
const {
handleMoreOptionsClick,
handleMoreOptionsKeyDown,
handleAddChildClick,
handleAddChildKeyDown,
} = useDocTreeItemHandlers({
isOpen,
onOpenChange,
createChildDoc,
docId: doc.id,
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

It make it a bit complex to follow what is going on here.

I think it would be more clear with 2 dedicated components, and in these components the interactions that belong to them.

For this one, it could be ButtonAddChildDoc:

<BoxButton
as="button"
tabIndex={0}
data-testid="add-child-doc"
onClick={handleAddChildClick}
onKeyDown={handleAddChildKeyDown}
color="primary"
aria-label={
t('Add child document to') +
` ${doc.title || t('Untitled document')}`
}
$hasTransition={false}
>
<Icon
variant="filled"
$variation="800"
$theme="primary"
iconName="add_box"
aria-hidden="true"
/>
</BoxButton>
)}

For this one, it could be ButtonMoreOptions:

<Icon
onClick={handleMoreOptionsClick}
iconName="more_horiz"
variant="filled"
$theme="primary"
$variation="600"
className="icon-button"
tabIndex={0}
role="button"
aria-label={
t('More options for') + ` ${doc.title || t('Untitled document')}`
}
aria-haspopup="true"
aria-expanded={isOpen}
onKeyDown={handleMoreOptionsKeyDown}
/>

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree 100%

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you should rebase, you have made a interesting commit here: 5181bba

We should leverage what was made in this commit instead of creating the same logic again.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a good idea yes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hey! I’ve refactored the keyboard logic a bit to make it cleaner and avoid duplication.

  • useDropdownKeyboardNav still handles the focus and keyboard navigation within dropdown menus, nothing changed there. It just uses a small shared helper now to handle the selection when pressing Enter or Space.
  • useTreeItemKeyboardActivate, which is just about triggering an action when a tree item is focused and Enter/Space is pressed, now reuses that same helper directly.

This way we avoid duplicating the same event listener and cleanup logic, and each hook remains focused on its own specific use case.

Let me know if that sounds good to you !

@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch 2 times, most recently from 82c61fd to 4c57253 Compare August 8, 2025 12:18
@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch from 4c57253 to 12bb25a Compare August 8, 2025 12:21
@Ovgodd
Copy link
Collaborator Author

Ovgodd commented Aug 8, 2025

✨(frontend) add keyboard navigation for subdocs with focus activation This commit should have a e2e test attached, to clearly understand what is the purpose of it.

Ok, I see what you mean. Do you suggest moving the test files from the other commit to this one, or at least the test file that refers to this change?

@Ovgodd Ovgodd requested a review from AntoLC August 8, 2025 12:44
@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch from d753d01 to 584d8f4 Compare August 11, 2025 09:49
Copy link
Collaborator

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

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

When there is a subdocs, I cannot unfold the doc with keyboard.

Enregistrement.de.l.ecran.2025-08-12.125242.mp4

Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we improve the outline visually ?
image

Copy link
Collaborator

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

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

I still don't see a test that show the keyboard interaction on the tree menu. #1261 (review)

Last thing, I can see that we have 2 components DropdownMenu, one coming from ui-kit, and another from src/components, they have different accessibility behaviors, could we unify this behavior ?

import {
DropdownMenu,
DropdownMenuOption,
useTreeContext,
} from '@gouvfr-lasuite/ui-kit';
import { useModal } from '@openfun/cunningham-react';

@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch 2 times, most recently from 70e94ad to d1c09dc Compare August 12, 2025 12:15
@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch from d1c09dc to 7250d07 Compare August 12, 2025 12:23
@Ovgodd Ovgodd force-pushed the fix/1160-sub-doc-access branch from 25cdd61 to af01958 Compare August 12, 2025 12:36
@Ovgodd
Copy link
Collaborator Author

Ovgodd commented Aug 12, 2025

When there is a subdocs, I cannot unfold the doc with keyboard.

Fix !

subdocnav.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants