Skip to content
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

Desktop: Accessibility: Improve focus handling for plugin and prompt dialogs #10801

Conversation

personalizedrefrigerator
Copy link
Collaborator

@personalizedrefrigerator personalizedrefrigerator commented Jul 30, 2024

Summary

This pull request improves focus handling for additional dialog types in a way similar to #10779. Specifically, for

  • the "go to anything" dialog,
  • the note statistics and note properties dialogs,
  • prompt dialogs (e.g. "add tags", "set alarm", ...), and
  • plugin dialogs.

This is done by migrating these dialogs to the gui/Dialog component. Since #10779, Dialog prevents items behind the dialog modal container from having keyboard focus.

Why?

This change brings Joplin closer to compliance with WCAG 2.2 (issue #10795).

From the WCAG 2.2's "Understanding SC 2.4.11: Focus Not Obscured (Minimum) (Level AA)",

A dialog-like overlay that does not take focus on appearance and does not either constrain interaction to the overlay or dismiss itself on loss of focus (thus allowing focus to exit into the content behind it) will be at risk of failing this SC, where it is positioned such that it can obscure other focusable items.
https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum#dialogs

Before this pull request, it was possible for focus to be hidden by plugin, prompt, statistics, and the go-to-anything dialogs. This pull request uses a modal <dialog> element to prevent keyboard focus from escaping, and thus potentially being hidden by, visible dialogs.

Stylistic changes

Switching to the Dialog component also changes the CSS used to style the dialog container. These changes are shown below.

Prompt dialog/text: Rounded corners and slightly more padding above:

before after comparison screenshot


Prompt dialog/date time: Rounded corners, the date time input now has focus by default. This currently causes the calendar to be visible by default. Previously, keyboard focus remained on the control that opened the dialog.

before after comparison screenshot


Plugin dialogs/one dialog open: When just one dialog is open, styles should be roughly the same:

before after comparison screenshot


Plugin dialogs/multiple dialogs open: When multiple dialogs are opened, the last-opened dialog now needs to be dismissed before the other dialog(s) can be used:

before after comparison screenshot


Go-to-anything dialog: Rounded corners:
before after comparison screenshot

Testing

This pull request includes automated tests for the following:

  • Clicking outside "go to anything" dismisses the dialog.
    • This is now handled in Dialog.tsx (rather than in GotoAnything.tsx). As such, this also tests the relevant logic in Dialog.tsx.
  • Pressing "Escape" while "go to anything" is open closes the dialog.
    • This is also handled by Dialog.tsx.
  • "Go to anything" can be opened again after being closed.
  • The "add or remove tags" dialog can be opened by running :setTags from "Go to anything".

The following manual testing has also been done on Ubuntu 24.04:

  1. Create a task
  2. Open the alarm dialog by clicking the alarm button.
  3. Set the alarm for tomorrow.
  4. Cycle through the focusable entries in the dialog by pressing tab.
  5. Verify that after "Clear" is focused, pressing tab again focuses the alarm text field.
  6. Close the dialog by clicking "OK".
  7. Clear the alarm for the current task.
  8. Repeat steps 2-5, but close the dialog by clicking "cancel". Verify that the alarm is still unset.
  9. Open the sync wizard. Close it by pressing the escape key.
  10. Open a plugin dialog (tested with "select a note to compare with" from the diff plugin).
  11. Change the width of the element in the dialog with ID joplin-plugin-content using the developer tools (set to 500px).
  12. Verify that the dialog container also changed size.
  13. Open "Go to anything" and run :insertDrawing (from the Freehand Drawing plugin)
  14. Verify that the drawing dialog is now open and is full screen (assumes that the Freehand Drawing "Dialog Mode" setting is unchecked).
  15. Open settings.
  16. Verify that neither plugin dialog is visible.
  17. Close settings.
  18. Verify that the "insert drawing" dialog is still visible.
  19. Close the dialog by pressing "Exit", then "discard".
  20. Choose a different note in the "select a note to compare with" dialog and click "OK".
  21. Verify that all dialogs are now closed.
  22. Open the "note properties" dialog.
  23. Close the "note properties" dialog by pressing "escape".
  24. Open the "statistics" dialog.
  25. Close the "statistics" dialog by clicking "close".

Comment on lines -26 to +27
background-color: rgba(0,0,0,0.6);
background-color: rgba(0,0,0,0.5);
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 CSS change prevents this pull request from changing the backdrop color for plugin dialogs.

Comment on lines -247 to +243
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public onKeyDown(event: any) {
if (event.keyCode === 27) { // ESCAPE
this.props.dispatch({
pluginName: PLUGIN_NAME,
type: 'PLUGINLEGACY_DIALOG_SET',
open: false,
});
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
private modalLayer_onClick(event: any) {
if (event.currentTarget === event.target) {
this.props.dispatch({
pluginName: PLUGIN_NAME,
type: 'PLUGINLEGACY_DIALOG_SET',
open: false,
});
}
}
private modalLayer_onDismiss = () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Dismissing the dialog with escape or clicking outside of the dialog is now handled by Dialog.tsx. As such, this logic has been removed from GotoAnything.tsx.

@laurent22
Copy link
Owner

That looks good, thanks for implementing this!

The difference before/after looks good to me. Rounded corners on dialogs are fine I guess.

@laurent22 laurent22 merged commit 596bcd8 into laurent22:dev Jul 31, 2024
10 checks passed
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.

2 participants