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>
|
<template>
|
||||||
<MkA
|
<MkA
|
||||||
class="rivslvers"
|
class="rivslvers"
|
||||||
tabindex="-1"
|
|
||||||
:class="{
|
:class="{
|
||||||
isMe: isMe(message),
|
isMe: isMe(message),
|
||||||
isRead: message.groupId
|
isRead: message.groupId
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
: message.user
|
: message.user
|
||||||
"
|
"
|
||||||
:show-indicator="true"
|
:show-indicator="true"
|
||||||
|
disableLink
|
||||||
/>
|
/>
|
||||||
<header v-if="message.groupId">
|
<header v-if="message.groupId">
|
||||||
<span class="name">{{ message.group.name }}</span>
|
<span class="name">{{ message.group.name }}</span>
|
||||||
|
|
|
@ -59,6 +59,7 @@ defineExpose({
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
._button {
|
._button {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
z-index: 2;
|
||||||
> span {
|
> span {
|
||||||
background: var(--cwBg) !important;
|
background: var(--cwBg) !important;
|
||||||
color: var(--cwFg);
|
color: var(--cwFg);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<MkA :to="`/gallery/${post.id}`" class="ttasepnz _panel" tabindex="-1">
|
<MkA :to="`/gallery/${post.id}`" class="ttasepnz _panel">
|
||||||
<div class="thumbnail">
|
<div class="thumbnail">
|
||||||
<ImgWithBlurhash
|
<ImgWithBlurhash
|
||||||
class="img"
|
class="img"
|
||||||
|
@ -34,7 +34,7 @@ const props = defineProps<{
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
|
|
||||||
&:hover {
|
&:hover, &:focus {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-media-banner">
|
<div class="mk-media-banner" @click.stop>
|
||||||
<div
|
<div
|
||||||
v-if="media.isSensitive && hide"
|
v-if="media.isSensitive && hide"
|
||||||
class="sensitive"
|
class="sensitive"
|
||||||
|
|
|
@ -108,6 +108,7 @@ onMounted(() => {
|
||||||
},
|
},
|
||||||
imageClickAction: "close",
|
imageClickAction: "close",
|
||||||
tapAction: "toggle-controls",
|
tapAction: "toggle-controls",
|
||||||
|
preloadFirstSlide: false,
|
||||||
pswpModule: PhotoSwipe,
|
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();
|
lightbox.init();
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
removeEventListener("popstate", close);
|
||||||
|
history.forward();
|
||||||
|
lightbox.pswp.close();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const previewable = (file: misskey.entities.DriveFile): boolean => {
|
const previewable = (file: misskey.entities.DriveFile): boolean => {
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<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 * as os from "@/os";
|
||||||
import { isTouchUsing } from "@/scripts/touch";
|
import { isTouchUsing } from "@/scripts/touch";
|
||||||
import { defaultStore } from "@/store";
|
import { defaultStore } from "@/store";
|
||||||
|
@ -176,7 +176,11 @@ let transitionDuration = $computed(() =>
|
||||||
let contentClicking = false;
|
let contentClicking = false;
|
||||||
|
|
||||||
const focusedElement = document.activeElement;
|
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) {
|
if (opts.useSendAnimation) {
|
||||||
useSendAnime = true;
|
useSendAnime = true;
|
||||||
}
|
}
|
||||||
|
@ -354,6 +358,10 @@ const onOpened = () => {
|
||||||
},
|
},
|
||||||
{ passive: true }
|
{ passive: true }
|
||||||
);
|
);
|
||||||
|
if (props.preferType == "dialog") {
|
||||||
|
history.pushState(null, "", location.href);
|
||||||
|
}
|
||||||
|
addEventListener("popstate", close);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -379,6 +387,12 @@ onMounted(() => {
|
||||||
}).observe(content!);
|
}).observe(content!);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
removeEventListener("popstate", close);
|
||||||
|
if (props.preferType == "dialog") {
|
||||||
|
history.back();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
close,
|
close,
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<slot :width="bodyWidth" :height="bodyHeight"></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</FocusTrap>
|
</FocusTrap>
|
||||||
|
@ -59,7 +59,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted } from "vue";
|
|
||||||
import { FocusTrap } from "focus-trap-vue";
|
import { FocusTrap } from "focus-trap-vue";
|
||||||
import MkModal from "./MkModal.vue";
|
import MkModal from "./MkModal.vue";
|
||||||
|
|
||||||
|
@ -90,8 +89,6 @@ const emit = defineEmits<{
|
||||||
let modal = $shallowRef<InstanceType<typeof MkModal>>();
|
let modal = $shallowRef<InstanceType<typeof MkModal>>();
|
||||||
let rootEl = $shallowRef<HTMLElement>();
|
let rootEl = $shallowRef<HTMLElement>();
|
||||||
let headerEl = $shallowRef<HTMLElement>();
|
let headerEl = $shallowRef<HTMLElement>();
|
||||||
let bodyWidth = $ref(0);
|
|
||||||
let bodyHeight = $ref(0);
|
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
modal.close();
|
modal.close();
|
||||||
|
@ -101,30 +98,6 @@ const onBgClick = () => {
|
||||||
emit("click");
|
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({
|
defineExpose({
|
||||||
close,
|
close,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<button v-if="modelValue" class="fade _button" @click.stop="toggle">
|
<button ref="el" class="_button" :class="{ fade: modelValue, showLess: !modelValue }" @click.stop="toggle">
|
||||||
<span>{{ i18n.ts.showMore }}</span>
|
<span>{{ modelValue ? i18n.ts.showMore : i18n.ts.showLess }}</span>
|
||||||
</button>
|
|
||||||
<button v-if="!modelValue" class="showLess _button" @click.stop="toggle">
|
|
||||||
<span>{{ i18n.ts.showLess }}</span>
|
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: boolean;
|
modelValue: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const el = ref<HTMLElement>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(ev: "update:modelValue", v: boolean): void;
|
(ev: "update:modelValue", v: boolean): void;
|
||||||
}>();
|
}>();
|
||||||
|
@ -20,6 +20,14 @@ const emit = defineEmits<{
|
||||||
const toggle = () => {
|
const toggle = () => {
|
||||||
emit("update:modelValue", !props.modelValue);
|
emit("update:modelValue", !props.modelValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function focus() {
|
||||||
|
el.value.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
focus,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.fade {
|
.fade {
|
||||||
|
@ -28,6 +36,7 @@ const toggle = () => {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
z-index: 2;
|
||||||
> span {
|
> span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: var(--panel);
|
background: var(--panel);
|
||||||
|
|
|
@ -40,6 +40,12 @@
|
||||||
disableAnim: disableMfm,
|
disableAnim: disableMfm,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
<XShowMoreButton
|
||||||
|
ref="showMoreButton"
|
||||||
|
v-if="isLong && collapsed"
|
||||||
|
v-model="collapsed"
|
||||||
|
v-on:keydown="focusFooter"
|
||||||
|
></XShowMoreButton>
|
||||||
<XCwButton
|
<XCwButton
|
||||||
ref="cwButton"
|
ref="cwButton"
|
||||||
v-if="note.cw && !showContent"
|
v-if="note.cw && !showContent"
|
||||||
|
@ -50,7 +56,7 @@
|
||||||
<div
|
<div
|
||||||
class="body"
|
class="body"
|
||||||
v-bind="{
|
v-bind="{
|
||||||
'aria-label': !showContent ? '' : null,
|
'aria-hidden': !showContent ? 'true' : null,
|
||||||
tabindex: !showContent ? '-1' : null,
|
tabindex: !showContent ? '-1' : null,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
@ -115,16 +121,16 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div
|
<div
|
||||||
v-if="note.cw && !showContent"
|
v-if="note.cw && !showContent || showMoreButton && collapsed"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
v-on:focus="cwButton?.focus()"
|
v-on:focus="cwButton?.focus(); showMoreButton?.focus()"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
<XShowMoreButton
|
<XShowMoreButton
|
||||||
v-if="isLong"
|
v-if="isLong && !collapsed"
|
||||||
v-model="collapsed"
|
v-model="collapsed"
|
||||||
></XShowMoreButton>
|
></XShowMoreButton>
|
||||||
<XCwButton v-if="note.cw" v-model="showContent" :note="note" />
|
<XCwButton v-if="note.cw && showContent" v-model="showContent" :note="note" />
|
||||||
</div>
|
</div>
|
||||||
<MkButton
|
<MkButton
|
||||||
v-if="hasMfm && defaultStore.state.animatedMfm"
|
v-if="hasMfm && defaultStore.state.animatedMfm"
|
||||||
|
@ -171,6 +177,7 @@ const emit = defineEmits<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const cwButton = ref<HTMLElement>();
|
const cwButton = ref<HTMLElement>();
|
||||||
|
const showMoreButton = ref<HTMLElement>();
|
||||||
const isLong =
|
const isLong =
|
||||||
!props.detailedView &&
|
!props.detailedView &&
|
||||||
props.note.cw == null &&
|
props.note.cw == null &&
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
v-on:change="(x) => onChange(x)"
|
v-on:change="(x) => onChange(x)"
|
||||||
@focus="tooltipShow"
|
@focus="tooltipShow"
|
||||||
@blur="tooltipHide"
|
@blur="tooltipHide"
|
||||||
|
@touchstart="tooltipShow"
|
||||||
|
@touchend="tooltipHide"
|
||||||
@mouseenter="tooltipShow"
|
@mouseenter="tooltipShow"
|
||||||
@mouseleave="tooltipHide"
|
@mouseleave="tooltipHide"
|
||||||
@input="(x) => (inputVal = x.target.value)"
|
@input="(x) => (inputVal = x.target.value)"
|
||||||
|
|
|
@ -52,6 +52,7 @@ html {
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
text-size-adjust: 100%;
|
text-size-adjust: 100%;
|
||||||
tab-size: 2;
|
tab-size: 2;
|
||||||
|
scroll-padding: 60px;
|
||||||
|
|
||||||
&.f-1 {
|
&.f-1 {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|
Loading…
Reference in New Issue