Proper use of focus trap
This commit is contained in:
parent
be6a640edb
commit
c05f151b1a
4 changed files with 63 additions and 84 deletions
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<FocusTrap
|
||||
:active="false"
|
||||
ref="focusTrap"
|
||||
v-model:active="isActive"
|
||||
:return-focus-on-deactivate="!noReturnFocus"
|
||||
:initial-focus="() => itemsEl.children[0]"
|
||||
@deactivate="emit('close')"
|
||||
>
|
||||
<div tabindex="-1">
|
||||
<div>
|
||||
<div
|
||||
ref="itemsEl"
|
||||
class="rrevdjwt _popup _shadow"
|
||||
|
@ -14,6 +16,7 @@
|
|||
maxHeight: maxHeight ? maxHeight + 'px' : '',
|
||||
}"
|
||||
@contextmenu.self="(e) => e.preventDefault()"
|
||||
tabindex="-1"
|
||||
>
|
||||
<template v-for="(item, i) in items2">
|
||||
<div v-if="item === null" class="divider"></div>
|
||||
|
@ -173,6 +176,7 @@
|
|||
:root-element="itemsEl"
|
||||
showing
|
||||
@actioned="childActioned"
|
||||
@closed="closeChild"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -303,23 +307,7 @@ function close(actioned = false) {
|
|||
emit("close", actioned);
|
||||
}
|
||||
|
||||
function focusUp() {
|
||||
focusPrev(document.activeElement);
|
||||
}
|
||||
|
||||
function focusDown() {
|
||||
focusNext(document.activeElement);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
focusTrap.value.activate();
|
||||
|
||||
if (props.viaKeyboard) {
|
||||
nextTick(() => {
|
||||
focusNext(itemsEl.children[0], true, false);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("mousedown", onGlobalMousedown, {
|
||||
passive: true,
|
||||
});
|
||||
|
|
|
@ -14,17 +14,17 @@
|
|||
:duration="transitionDuration"
|
||||
appear
|
||||
@after-leave="emit('closed')"
|
||||
@keyup.esc="emit('click')"
|
||||
@enter="emit('opening')"
|
||||
@after-enter="onOpened"
|
||||
>
|
||||
<FocusTrap
|
||||
v-model:active="isActive"
|
||||
:initial-focus="() => $refs.content"
|
||||
:return-focus-on-deactivate="!noReturnFocus"
|
||||
@deactivate="close"
|
||||
>
|
||||
<div
|
||||
v-show="manualShowing != null ? manualShowing : showing"
|
||||
v-hotkey.global="keymap"
|
||||
:class="[
|
||||
$style.root,
|
||||
{
|
||||
|
@ -44,7 +44,6 @@
|
|||
'--transformOrigin': transformOrigin,
|
||||
}"
|
||||
tabindex="-1"
|
||||
v-focus
|
||||
>
|
||||
<div
|
||||
class="_modalBg data-cy-bg"
|
||||
|
@ -180,7 +179,7 @@ let transitionDuration = $computed(() =>
|
|||
|
||||
let contentClicking = false;
|
||||
|
||||
const focusedElement = document.activeElement;
|
||||
// const focusedElement = document.activeElement;
|
||||
function close(ev, opts: { useSendAnimation?: boolean } = {}) {
|
||||
// removeEventListener("popstate", close);
|
||||
// if (props.preferType == "dialog") {
|
||||
|
@ -194,16 +193,16 @@ function close(ev, opts: { useSendAnimation?: boolean } = {}) {
|
|||
if (props.src) props.src.style.pointerEvents = "auto";
|
||||
showing = false;
|
||||
emit("close");
|
||||
if (!props.noReturnFocus) {
|
||||
focusedElement.focus();
|
||||
}
|
||||
// if (!props.noReturnFocus) {
|
||||
// focusedElement.focus();
|
||||
// }
|
||||
}
|
||||
|
||||
function onBgClick() {
|
||||
if (contentClicking) return;
|
||||
if (!props.noReturnFocus) {
|
||||
focusedElement.focus();
|
||||
}
|
||||
// if (!props.noReturnFocus) {
|
||||
// focusedElement.focus();
|
||||
// }
|
||||
emit("click");
|
||||
}
|
||||
|
||||
|
@ -211,10 +210,6 @@ if (type === "drawer") {
|
|||
maxHeight = window.innerHeight / 1.5;
|
||||
}
|
||||
|
||||
const keymap = {
|
||||
esc: () => emit("esc"),
|
||||
};
|
||||
|
||||
const MARGIN = 16;
|
||||
|
||||
const align = () => {
|
||||
|
|
|
@ -6,58 +6,55 @@
|
|||
@keyup.esc="$emit('close')"
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<FocusTrap v-model:active="isActive">
|
||||
<div
|
||||
ref="rootEl"
|
||||
class="ebkgoccj"
|
||||
:style="{
|
||||
width: `${width}px`,
|
||||
height: scroll
|
||||
? height
|
||||
? `${height}px`
|
||||
: null
|
||||
: height
|
||||
? `min(${height}px, 100%)`
|
||||
: '100%',
|
||||
}"
|
||||
@keydown="onKeydown"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div ref="headerEl" class="header">
|
||||
<button
|
||||
v-if="withOkButton"
|
||||
:aria-label="i18n.t('close')"
|
||||
class="_button"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<i class="ph-x ph-bold ph-lg"></i>
|
||||
</button>
|
||||
<span class="title">
|
||||
<slot name="header"></slot>
|
||||
</span>
|
||||
<button
|
||||
v-if="!withOkButton"
|
||||
:aria-label="i18n.t('close')"
|
||||
class="_button"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<i class="ph-x ph-bold ph-lg"></i>
|
||||
</button>
|
||||
<button
|
||||
v-if="withOkButton"
|
||||
:aria-label="i18n.t('ok')"
|
||||
class="_button"
|
||||
:disabled="okButtonDisabled"
|
||||
@click="$emit('ok')"
|
||||
>
|
||||
<i class="ph-check ph-bold ph-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div
|
||||
ref="rootEl"
|
||||
class="ebkgoccj"
|
||||
:style="{
|
||||
width: `${width}px`,
|
||||
height: scroll
|
||||
? height
|
||||
? `${height}px`
|
||||
: null
|
||||
: height
|
||||
? `min(${height}px, 100%)`
|
||||
: '100%',
|
||||
}"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div ref="headerEl" class="header">
|
||||
<button
|
||||
v-if="withOkButton"
|
||||
:aria-label="i18n.t('close')"
|
||||
class="_button"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<i class="ph-x ph-bold ph-lg"></i>
|
||||
</button>
|
||||
<span class="title">
|
||||
<slot name="header"></slot>
|
||||
</span>
|
||||
<button
|
||||
v-if="!withOkButton"
|
||||
:aria-label="i18n.t('close')"
|
||||
class="_button"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<i class="ph-x ph-bold ph-lg"></i>
|
||||
</button>
|
||||
<button
|
||||
v-if="withOkButton"
|
||||
:aria-label="i18n.t('ok')"
|
||||
class="_button"
|
||||
:disabled="okButtonDisabled"
|
||||
@click="$emit('ok')"
|
||||
>
|
||||
<i class="ph-check ph-bold ph-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
</FocusTrap>
|
||||
<div class="body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</MkModal>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
@click="modal.close()"
|
||||
@closed="emit('closed')"
|
||||
tabindex="-1"
|
||||
v-focus
|
||||
>
|
||||
<MkMenu
|
||||
:items="items"
|
||||
|
|
Loading…
Reference in a new issue