Mirror: React hooks for accessible, common web interactions. UI super powers without the UI.

Restore selection in useDialogFocus and useMenuFocus

Restore selection in focus hooks when target focus is invalid,
i.e. not in the original focus target.

Changed files
+11 -1
src
+5
src/useDialogFocus.ts
···
document.addEventListener('keydown', onKey);
return () => {
element.removeEventListener('mousedown', onClick);
document.body.removeEventListener('focusin', onFocus);
document.removeEventListener('keydown', onKey);
···
document.addEventListener('keydown', onKey);
return () => {
+
const active = document.activeElement as HTMLElement;
+
if (!active || contains(element, active)) {
+
restoreSelection(selection);
+
}
+
element.removeEventListener('mousedown', onClick);
document.body.removeEventListener('focusin', onFocus);
document.removeEventListener('keydown', onKey);
+5
src/useMenuFocus.ts
···
document.addEventListener('keydown', onKey);
return () => {
document.body.removeEventListener('focusin', onFocus);
document.removeEventListener('keydown', onKey);
};
···
document.addEventListener('keydown', onKey);
return () => {
+
const active = document.activeElement as HTMLElement;
+
if (!active || contains(element, active)) {
+
restoreSelection(selection);
+
}
+
document.body.removeEventListener('focusin', onFocus);
document.removeEventListener('keydown', onKey);
};
+1 -1
src/utils/selection.ts
···
const selection = window.getSelection && window.getSelection();
if (selection && selection.rangeCount) {
const range = selection.getRangeAt(0);
-
if (contains(target, range.startContainer)) {
return { element, method: 'range', range };
}
}
···
const selection = window.getSelection && window.getSelection();
if (selection && selection.rangeCount) {
const range = selection.getRangeAt(0);
+
if (range.startContainer && contains(target, range.startContainer)) {
return { element, method: 'range', range };
}
}