Merge pull request 'More focusable elements + allow closing modal's w/ browser back & esc' (#10142) from Freeplay/calckey:keyboard into develop
Reviewed-on: https://codeberg.org/calckey/calckey/pulls/10142
This commit is contained in:
commit
3fc94f9348
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<MkA
|
||||
class="rivslvers"
|
||||
tabindex="-1"
|
||||
:class="{
|
||||
isMe: isMe(message),
|
||||
isRead: message.groupId
|
||||
|
@ -27,6 +26,7 @@
|
|||
: message.user
|
||||
"
|
||||
:show-indicator="true"
|
||||
disableLink
|
||||
/>
|
||||
<header v-if="message.groupId">
|
||||
<span class="name">{{ message.group.name }}</span>
|
||||
|
|
|
@ -59,6 +59,7 @@ defineExpose({
|
|||
<style lang="scss" scoped>
|
||||
._button {
|
||||
font-weight: 700;
|
||||
z-index: 2;
|
||||
> span {
|
||||
background: var(--cwBg) !important;
|
||||
color: var(--cwFg);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<MkA :to="`/gallery/${post.id}`" class="ttasepnz _panel" tabindex="-1">
|
||||
<MkA :to="`/gallery/${post.id}`" class="ttasepnz _panel">
|
||||
<div class="thumbnail">
|
||||
<ImgWithBlurhash
|
||||
class="img"
|
||||
|
@ -34,7 +34,7 @@ const props = defineProps<{
|
|||
position: relative;
|
||||
height: 200px;
|
||||
|
||||
&:hover {
|
||||
&:hover, &:focus {
|
||||
text-decoration: none;
|
||||
color: var(--accent);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="mk-media-banner">
|
||||
<div class="mk-media-banner" @click.stop>
|
||||
<div
|
||||
v-if="media.isSensitive && hide"
|
||||
class="sensitive"
|
||||
|
|
|
@ -108,6 +108,7 @@ onMounted(() => {
|
|||
},
|
||||
imageClickAction: "close",
|
||||
tapAction: "toggle-controls",
|
||||
preloadFirstSlide: false,
|
||||
pswpModule: PhotoSwipe,
|
||||
});
|
||||
|
||||
|
@ -162,7 +163,24 @@ onMounted(() => {
|
|||
});
|
||||
});
|
||||
|
||||
lightbox.on("afterInit", () => {
|
||||
history.pushState(null, "", location.href);
|
||||
addEventListener("popstate", close);
|
||||
// This is a workaround. Not sure why, but when clicking to open, it doesn't move focus to the photoswipe. Preventing using esc to close. However when using keyboard to open it already focuses the lightbox fine.
|
||||
lightbox.pswp.element.focus();
|
||||
})
|
||||
lightbox.on("close", () => {
|
||||
removeEventListener("popstate", close);
|
||||
history.back();
|
||||
})
|
||||
|
||||
lightbox.init();
|
||||
|
||||
function close() {
|
||||
removeEventListener("popstate", close);
|
||||
history.forward();
|
||||
lightbox.pswp.close();
|
||||
}
|
||||
});
|
||||
|
||||
const previewable = (file: misskey.entities.DriveFile): boolean => {
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, watch, provide } from "vue";
|
||||
import { nextTick, onMounted, watch, provide, onUnmounted } from "vue";
|
||||
import * as os from "@/os";
|
||||
import { isTouchUsing } from "@/scripts/touch";
|
||||
import { defaultStore } from "@/store";
|
||||
|
@ -176,7 +176,11 @@ let transitionDuration = $computed(() =>
|
|||
let contentClicking = false;
|
||||
|
||||
const focusedElement = document.activeElement;
|
||||
function close(opts: { useSendAnimation?: boolean } = {}) {
|
||||
function close(ev, opts: { useSendAnimation?: boolean } = {}) {
|
||||
removeEventListener("popstate", close);
|
||||
if (props.preferType == "dialog") {
|
||||
history.forward();
|
||||
}
|
||||
if (opts.useSendAnimation) {
|
||||
useSendAnime = true;
|
||||
}
|
||||
|
@ -354,6 +358,10 @@ const onOpened = () => {
|
|||
},
|
||||
{ passive: true }
|
||||
);
|
||||
if (props.preferType == "dialog") {
|
||||
history.pushState(null, "", location.href);
|
||||
}
|
||||
addEventListener("popstate", close);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
@ -379,6 +387,12 @@ onMounted(() => {
|
|||
}).observe(content!);
|
||||
});
|
||||
});
|
||||
onUnmounted(() => {
|
||||
removeEventListener("popstate", close);
|
||||
if (props.preferType == "dialog") {
|
||||
history.back();
|
||||
}
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
close,
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="body">
|
||||
<slot :width="bodyWidth" :height="bodyHeight"></slot>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</FocusTrap>
|
||||
|
@ -59,7 +59,6 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted } from "vue";
|
||||
import { FocusTrap } from "focus-trap-vue";
|
||||
import MkModal from "./MkModal.vue";
|
||||
|
||||
|
@ -90,8 +89,6 @@ const emit = defineEmits<{
|
|||
let modal = $shallowRef<InstanceType<typeof MkModal>>();
|
||||
let rootEl = $shallowRef<HTMLElement>();
|
||||
let headerEl = $shallowRef<HTMLElement>();
|
||||
let bodyWidth = $ref(0);
|
||||
let bodyHeight = $ref(0);
|
||||
|
||||
const close = () => {
|
||||
modal.close();
|
||||
|
@ -101,30 +98,6 @@ const onBgClick = () => {
|
|||
emit("click");
|
||||
};
|
||||
|
||||
const onKeydown = (evt) => {
|
||||
if (evt.which === 27) {
|
||||
// Esc
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
const ro = new ResizeObserver((entries, observer) => {
|
||||
bodyWidth = rootEl.offsetWidth;
|
||||
bodyHeight = rootEl.offsetHeight - headerEl.offsetHeight;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
bodyWidth = rootEl.offsetWidth;
|
||||
bodyHeight = rootEl.offsetHeight - headerEl.offsetHeight;
|
||||
ro.observe(rootEl);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
ro.disconnect();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
close,
|
||||
});
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<template>
|
||||
<button v-if="modelValue" class="fade _button" @click.stop="toggle">
|
||||
<span>{{ i18n.ts.showMore }}</span>
|
||||
</button>
|
||||
<button v-if="!modelValue" class="showLess _button" @click.stop="toggle">
|
||||
<span>{{ i18n.ts.showLess }}</span>
|
||||
<button ref="el" class="_button" :class="{ fade: modelValue, showLess: !modelValue }" @click.stop="toggle">
|
||||
<span>{{ modelValue ? i18n.ts.showMore : i18n.ts.showLess }}</span>
|
||||
</button>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { i18n } from "@/i18n";
|
||||
import { ref } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean;
|
||||
}>();
|
||||
|
||||
const el = ref<HTMLElement>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: "update:modelValue", v: boolean): void;
|
||||
}>();
|
||||
|
@ -20,6 +20,14 @@ const emit = defineEmits<{
|
|||
const toggle = () => {
|
||||
emit("update:modelValue", !props.modelValue);
|
||||
};
|
||||
|
||||
function focus() {
|
||||
el.value.focus();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
focus,
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.fade {
|
||||
|
@ -28,6 +36,7 @@ const toggle = () => {
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
> span {
|
||||
display: inline-block;
|
||||
background: var(--panel);
|
||||
|
|
|
@ -40,6 +40,12 @@
|
|||
disableAnim: disableMfm,
|
||||
}"
|
||||
>
|
||||
<XShowMoreButton
|
||||
ref="showMoreButton"
|
||||
v-if="isLong && collapsed"
|
||||
v-model="collapsed"
|
||||
v-on:keydown="focusFooter"
|
||||
></XShowMoreButton>
|
||||
<XCwButton
|
||||
ref="cwButton"
|
||||
v-if="note.cw && !showContent"
|
||||
|
@ -50,7 +56,7 @@
|
|||
<div
|
||||
class="body"
|
||||
v-bind="{
|
||||
'aria-label': !showContent ? '' : null,
|
||||
'aria-hidden': !showContent ? 'true' : null,
|
||||
tabindex: !showContent ? '-1' : null,
|
||||
}"
|
||||
>
|
||||
|
@ -115,16 +121,16 @@
|
|||
</div>
|
||||
</template>
|
||||
<div
|
||||
v-if="note.cw && !showContent"
|
||||
v-if="note.cw && !showContent || showMoreButton && collapsed"
|
||||
tabindex="0"
|
||||
v-on:focus="cwButton?.focus()"
|
||||
v-on:focus="cwButton?.focus(); showMoreButton?.focus()"
|
||||
></div>
|
||||
</div>
|
||||
<XShowMoreButton
|
||||
v-if="isLong"
|
||||
v-if="isLong && !collapsed"
|
||||
v-model="collapsed"
|
||||
></XShowMoreButton>
|
||||
<XCwButton v-if="note.cw" v-model="showContent" :note="note" />
|
||||
<XCwButton v-if="note.cw && showContent" v-model="showContent" :note="note" />
|
||||
</div>
|
||||
<MkButton
|
||||
v-if="hasMfm && defaultStore.state.animatedMfm"
|
||||
|
@ -171,6 +177,7 @@ const emit = defineEmits<{
|
|||
}>();
|
||||
|
||||
const cwButton = ref<HTMLElement>();
|
||||
const showMoreButton = ref<HTMLElement>();
|
||||
const isLong =
|
||||
!props.detailedView &&
|
||||
props.note.cw == null &&
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
v-on:change="(x) => onChange(x)"
|
||||
@focus="tooltipShow"
|
||||
@blur="tooltipHide"
|
||||
@touchstart="tooltipShow"
|
||||
@touchend="tooltipHide"
|
||||
@mouseenter="tooltipShow"
|
||||
@mouseleave="tooltipHide"
|
||||
@input="(x) => (inputVal = x.target.value)"
|
||||
|
|
|
@ -52,6 +52,7 @@ html {
|
|||
line-height: 1.6;
|
||||
text-size-adjust: 100%;
|
||||
tab-size: 2;
|
||||
scroll-padding: 60px;
|
||||
|
||||
&.f-1 {
|
||||
font-size: 15px;
|
||||
|
|
Loading…
Reference in New Issue