As a user who relies on keyboard shortcuts to quickly interact with the web interface, I would like to see improved focus management so that the focus is properly trapped in the currently active component and keyboard events are handled by the correct event handlers.
While the initial element focus is correctly set by common/view.js, e.g. when opening a new page or a modal dialog, tests have shown that the focus can return to another element such as <body> after interactions like pressing a button, which requires the user to click inside the dialog or page again in order to use keyboard shortcuts:
|
// Automatically focus the active component if its element tabindex attribute is set to "1": |
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex |
|
if (focusElement) { |
|
setFocus(focusElement, focusSelector, false); |
|
} else { |
|
setFocus(findFocusElement(c), false, false); |
|
} |
Note that the retainFocus property of the VDialog component is set to false by default, as it conflicted with PhotoSwipe which is used for viewing photos and videos - but setting it to true did not seem to change or improve things:
|
VDialog: { |
|
scrim: true, |
|
scrollable: true, |
|
retainFocus: false, |
|
transition: false, |
|
persistent: true, |
|
openDelay: 0, |
|
closeDelay: 0, |
|
attach: document.body, |
|
}, |
It seems possible that the behavior is caused by the VSnackbar component, which is used to display notifications at the bottom of the screen, or some other part of Vuetify:
|
<v-snackbar |
|
v-if="visible && message.text" |
|
v-model="snackbar" |
|
:class="'p-notify--' + message.color" |
|
class="p-notify clickable" |
|
@click.stop.prevent="showNext" |
|
> |
To test this, you can e.g. open the Edit dialog, change the Caption, click Apply, and then check the active element by running console.log(document.activeElement); in the browser's JS console. The focus should now (incorrectly) be on the <body> instead of the <div> containing the dialog which prevents navigation with the left and right keys, see the related issue below.
A possible solution to this problem could be to use a library like https://github.com/focus-trap/focus-trap, which can be loaded and initialized in common/view.js (see above). Unfortunately, it wasn't possible to fix the observed problems with it in the time available, so this issue was created to document the findings and make sure it is taken care of later.
Any help with that would be much appreciated! ❤
Related Issues:
As a user who relies on keyboard shortcuts to quickly interact with the web interface, I would like to see improved focus management so that the focus is properly trapped in the currently active component and keyboard events are handled by the correct event handlers.
While the initial element focus is correctly set by
common/view.js, e.g. when opening a new page or a modal dialog, tests have shown that the focus can return to another element such as<body>after interactions like pressing a button, which requires the user to click inside the dialog or page again in order to use keyboard shortcuts:photoprism/frontend/src/common/view.js
Lines 317 to 323 in 64f051e
Note that the
retainFocusproperty of theVDialogcomponent is set to false by default, as it conflicted with PhotoSwipe which is used for viewing photos and videos - but setting it to true did not seem to change or improve things:photoprism/frontend/src/component/defaults.js
Lines 169 to 178 in 64f051e
It seems possible that the behavior is caused by the
VSnackbarcomponent, which is used to display notifications at the bottom of the screen, or some other part of Vuetify:photoprism/frontend/src/component/notify.vue
Lines 3 to 9 in 64f051e
To test this, you can e.g. open the Edit dialog, change the Caption, click Apply, and then check the active element by running
console.log(document.activeElement);in the browser's JS console. The focus should now (incorrectly) be on the<body>instead of the<div>containing the dialog which prevents navigation with the left and right keys, see the related issue below.A possible solution to this problem could be to use a library like https://github.com/focus-trap/focus-trap, which can be loaded and initialized in
common/view.js(see above). Unfortunately, it wasn't possible to fix the observed problems with it in the time available, so this issue was created to document the findings and make sure it is taken care of later.Any help with that would be much appreciated! ❤
Related Issues: