Skip to content

Commit

Permalink
fix(frontend): フォーカス/タブ移動に関する挙動を調整 (#226)
Browse files Browse the repository at this point in the history
Cherry-pick commit e8c0306

Co-authored-by: taiyme <[email protected]>
  • Loading branch information
kakkokari-gtyih and taiyme committed Jul 9, 2024
1 parent 5372b25 commit d8cf64a
Show file tree
Hide file tree
Showing 23 changed files with 439 additions and 285 deletions.
1 change: 0 additions & 1 deletion packages/frontend/src/components/MkButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ function onMousedown(evt: MouseEvent): void {
}

&:focus-visible {
outline: solid 2px var(--focus);
outline-offset: 2px;
}

Expand Down
12 changes: 1 addition & 11 deletions packages/frontend/src/components/MkChannelFollowButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,7 @@ async function onClick() {
}

&:focus-visible {
&:after {
content: "";
pointer-events: none;
position: absolute;
top: -5px;
right: -5px;
bottom: -5px;
left: -5px;
border: 2px solid var(--focus);
border-radius: 32px;
}
outline-offset: 2px;
}

&:hover {
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/src/components/MkContextMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:leaveToClass="defaultStore.state.animation ? $style.transition_fade_leaveTo : ''"
>
<div ref="rootEl" :class="$style.root" :style="{ zIndex }" @contextmenu.prevent.stop="() => {}">
<MkMenu :items="items" :align="'left'" @close="$emit('closed')"/>
<MkMenu :items="items" :align="'left'" :returnFocusElement="returnFocusElement" @close="emit('closed')"/>
</div>
</Transition>
</template>
Expand All @@ -28,6 +28,7 @@ import * as os from '@/os.js';
const props = defineProps<{
items: MenuItem[];
ev: MouseEvent;
returnFocusElement?: HTMLElement | null;
}>();

const emit = defineEmits<{
Expand Down
5 changes: 0 additions & 5 deletions packages/frontend/src/components/MkEmojiPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -702,11 +702,6 @@ defineExpose({
border-radius: 4px;
font-size: 24px;

&:focus-visible {
outline: solid 2px var(--focus);
z-index: 1;
}

&:hover {
background: rgba(0, 0, 0, 0.05);
}
Expand Down
12 changes: 1 addition & 11 deletions packages/frontend/src/components/MkFollowButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -185,17 +185,7 @@ onBeforeUnmount(() => {
}

&:focus-visible {
&:after {
content: "";
pointer-events: none;
position: absolute;
top: -5px;
right: -5px;
bottom: -5px;
left: -5px;
border: 2px solid var(--focus);
border-radius: 32px;
}
outline-offset: 2px;
}

&:hover {
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/components/MkImgWithBlurhash.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ SPDX-License-Identifier: AGPL-3.0-only
:enterToClass="defaultStore.state.animation && props.transition?.enterToClass || undefined"
:leaveFromClass="defaultStore.state.animation && props.transition?.leaveFromClass || undefined"
>
<canvas v-show="hide" key="canvas" ref="canvas" :class="$style.canvas" :width="canvasWidth" :height="canvasHeight" :title="title ?? undefined"/>
<img v-show="!hide" key="img" ref="img" :height="imgHeight" :width="imgWidth" :class="$style.img" :src="src ?? undefined" :title="title ?? undefined" :alt="alt ?? undefined" loading="eager" decoding="async"/>
<canvas v-show="hide" key="canvas" ref="canvas" :class="$style.canvas" :width="canvasWidth" :height="canvasHeight" :title="title ?? undefined" tabindex="-1"/>
<img v-show="!hide" key="img" ref="img" :height="imgHeight ?? undefined" :width="imgWidth ?? undefined" :class="$style.img" :src="src ?? undefined" :title="title ?? undefined" :alt="alt ?? undefined" loading="eager" decoding="async" tabindex="-1"/>
</TransitionGroup>
</div>
</template>
Expand Down
30 changes: 26 additions & 4 deletions packages/frontend/src/components/MkMediaAudio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,37 @@ SPDX-License-Identifier: AGPL-3.0-only
<audio
ref="audioEl"
preload="metadata"
@keydown.prevent="() => {}"
>
<source :src="audio.url">
</audio>
<div :class="[$style.controlsChild, $style.controlsLeft]">
<button class="_button" :class="$style.controlButton" @click="togglePlayPause">
<button
:class="['_button', $style.controlButton]"
tabindex="-1"
@click.stop="togglePlayPause"
>
<i v-if="isPlaying" class="ti ti-player-pause-filled"></i>
<i v-else class="ti ti-player-play-filled"></i>
</button>
</div>
<div :class="[$style.controlsChild, $style.controlsRight]">
<button class="_button" :class="$style.controlButton" @click="showMenu">
<button
:class="['_button', $style.controlButton]"
tabindex="-1"
@click.stop="() => {}"
@mousedown.prevent.stop="showMenu"
>
<i class="ti ti-settings"></i>
</button>
</div>
<div :class="[$style.controlsChild, $style.controlsTime]">{{ hms(elapsedTimeMs) }}</div>
<div :class="[$style.controlsChild, $style.controlsVolume]">
<button class="_button" :class="$style.controlButton" @click="toggleMute">
<button
:class="['_button', $style.controlButton]"
tabindex="-1"
@click.stop="toggleMute"
>
<i v-if="volume === 0" class="ti ti-volume-3"></i>
<i v-else class="ti ti-volume"></i>
</button>
Expand All @@ -64,6 +78,10 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.volumeSeekbar"
/>
</div>
<MkMediaRange
v-model="volume"
:class="$style.volumeSeekbar"
/>
<MkMediaRange
v-model="rangePercent"
:class="$style.seekbarRoot"
Expand Down Expand Up @@ -371,7 +389,7 @@ onDeactivated(() => {
border-radius: var(--radius);
overflow: clip;

&:focus {
&:focus-visible {
outline: none;
}
}
Expand Down Expand Up @@ -437,6 +455,10 @@ onDeactivated(() => {
color: var(--accent);
background-color: var(--accentedBg);
}

&:focus-visible {
outline: none;
}
}
}

Expand Down
54 changes: 38 additions & 16 deletions packages/frontend/src/components/MkMediaList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import XVideo from '@/components/MkMediaVideo.vue';
import * as os from '@/os.js';
import { FILE_TYPE_BROWSERSAFE } from '@/const.js';
import { defaultStore } from '@/store.js';
import { focusParent } from '@/scripts/tms/focus.js';

const props = defineProps<{
mediaList: Misskey.entities.DriveFile[];
Expand All @@ -49,7 +50,9 @@ const gallery = shallowRef<HTMLDivElement>();
const pswpZIndex = os.claimZIndex('middle');
document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString());
const count = computed(() => props.mediaList.filter(media => previewable(media)).length);
let lightbox: PhotoSwipeLightbox | null;
let lightbox: PhotoSwipeLightbox | null = null;

let activeEl: HTMLElement | null = null;

const popstateHandler = (): void => {
if (lightbox?.pswp && lightbox.pswp.isOpen === true) {
Expand All @@ -60,7 +63,7 @@ const popstateHandler = (): void => {
async function calcAspectRatio() {
if (!gallery.value) return;

let img = props.mediaList[0];
const img = props.mediaList[0];

if (props.mediaList.length !== 1 || !(img.properties.width && img.properties.height)) {
gallery.value.style.aspectRatio = '';
Expand Down Expand Up @@ -131,6 +134,7 @@ onMounted(() => {
bgOpacity: 1,
showAnimationDuration: 100,
hideAnimationDuration: 100,
returnFocus: false,
pswpModule: PhotoSwipe,
});

Expand Down Expand Up @@ -159,46 +163,64 @@ onMounted(() => {
lightbox.on('uiRegister', () => {
lightbox?.pswp?.ui?.registerElement({
name: 'altText',
className: 'pwsp__alt-text-container',
className: 'pswp__alt-text-container',
appendTo: 'wrapper',
onInit: (el, pwsp) => {
let textBox = document.createElement('p');
textBox.className = 'pwsp__alt-text _acrylic';
onInit: (el, pswp) => {
const textBox = document.createElement('p');
textBox.className = 'pswp__alt-text _acrylic';
el.appendChild(textBox);

pwsp.on('change', () => {
textBox.textContent = pwsp.currSlide?.data.comment;
pswp.on('change', () => {
textBox.textContent = pswp.currSlide?.data.comment;
});
},
});
});

lightbox.init();

window.addEventListener('popstate', popstateHandler);

lightbox.on('beforeOpen', () => {
lightbox.on('afterInit', () => {
activeEl = document.activeElement instanceof HTMLElement ? document.activeElement : null;
focusParent(activeEl, true, true);
lightbox?.pswp?.element?.focus({
preventScroll: true,
});
history.pushState(null, '', '#pswp');
});

lightbox.on('close', () => {
lightbox.on('destroy', () => {
focusParent(activeEl, true, false);
activeEl = null;
if (window.location.hash === '#pswp') {
history.back();
}
});

window.addEventListener('popstate', popstateHandler);

lightbox.init();
});

onUnmounted(() => {
window.removeEventListener('popstate', popstateHandler);
lightbox?.destroy();
lightbox = null;
activeEl = null;
});

const previewable = (file: Misskey.entities.DriveFile): boolean => {
if (file.type === 'image/svg+xml') return true; // svgのwebpublic/thumbnailはpngなのでtrue
// FILE_TYPE_BROWSERSAFEに適合しないものはブラウザで表示するのに不適切
return (file.type.startsWith('video') || file.type.startsWith('image')) && FILE_TYPE_BROWSERSAFE.includes(file.type);
};

const openGallery = () => {
if (props.mediaList.filter(media => previewable(media)).length > 0) {
lightbox?.loadAndOpen(0);
}
};

defineExpose({
openGallery,
});
</script>

<style lang="scss" module>
Expand Down Expand Up @@ -298,7 +320,7 @@ const previewable = (file: Misskey.entities.DriveFile): boolean => {
backdrop-filter: var(--modalBgFilter);
}

.pwsp__alt-text-container {
.pswp__alt-text-container {
display: flex;
flex-direction: row;
align-items: center;
Expand All @@ -312,7 +334,7 @@ const previewable = (file: Misskey.entities.DriveFile): boolean => {
max-width: 800px;
}

.pwsp__alt-text {
.pswp__alt-text {
color: var(--fg);
margin: 0 auto;
text-align: center;
Expand Down
10 changes: 9 additions & 1 deletion packages/frontend/src/components/MkMediaVideo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ onDeactivated(() => {
position: relative;
overflow: clip;

&:focus {
&:focus-visible {
outline: none;
}
}
Expand Down Expand Up @@ -588,6 +588,10 @@ onDeactivated(() => {
border-radius: 99rem;

font-size: 1.1rem;

&:focus-visible {
outline: none;
}
}

.videoLoading {
Expand Down Expand Up @@ -651,6 +655,10 @@ onDeactivated(() => {
&:hover {
background-color: var(--accent);
}

&:focus-visible {
outline: none;
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions packages/frontend/src/components/MkMenu.child.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>

<script lang="ts" setup>
import { nextTick, onMounted, onUnmounted, shallowRef, watch } from 'vue';
import { nextTick, onMounted, onUnmounted, provide, shallowRef, watch } from 'vue';
import MkMenu from './MkMenu.vue';
import { MenuItem } from '@/types/menu.js';

Expand All @@ -19,14 +19,15 @@ const props = defineProps<{
targetElement: HTMLElement;
rootElement: HTMLElement;
width?: number;
viaKeyboard?: boolean;
}>();

const emit = defineEmits<{
(ev: 'closed'): void;
(ev: 'actioned'): void;
}>();

provide('isNestingMenu', true);

const el = shallowRef<HTMLElement>();
const align = 'left';

Expand Down
Loading

0 comments on commit d8cf64a

Please sign in to comment.