summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2023-02-12 08:18:26 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2023-02-12 08:18:26 +0900
commitf6f269194f7cb56534aee1ba23dea4598b98dcb0 (patch)
tree4efcdce419efd7ee68972dae60278fa17a09d532 /packages/frontend/src/components
parentenhance(client): make renote collapsing optional (diff)
parent:art: (diff)
downloadmisskey-f6f269194f7cb56534aee1ba23dea4598b98dcb0.tar.gz
misskey-f6f269194f7cb56534aee1ba23dea4598b98dcb0.tar.bz2
misskey-f6f269194f7cb56534aee1ba23dea4598b98dcb0.zip
Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop
Diffstat (limited to 'packages/frontend/src/components')
-rw-r--r--packages/frontend/src/components/global/MkPageHeader.tabs.vue54
-rw-r--r--packages/frontend/src/components/global/MkPageHeader.vue33
2 files changed, 47 insertions, 40 deletions
diff --git a/packages/frontend/src/components/global/MkPageHeader.tabs.vue b/packages/frontend/src/components/global/MkPageHeader.tabs.vue
index 9b19c5dc87..dae68c7e9c 100644
--- a/packages/frontend/src/components/global/MkPageHeader.tabs.vue
+++ b/packages/frontend/src/components/global/MkPageHeader.tabs.vue
@@ -10,7 +10,7 @@
:class="$style.tabTitle">{{ t.title }}</div>
<Transition v-else @enter="enter" @after-enter="afterEnter" @leave="leave" @after-leave="afterLeave"
mode="in-out">
- <div v-if="t.key === tab" :class="$style.tabTitle">{{ t.title }}</div>
+ <div v-show="t.key === tab" :class="[$style.tabTitle, $style.animate]">{{ t.title }}</div>
</Transition>
</div>
</button>
@@ -34,7 +34,7 @@ export type Tab = {
</script>
<script lang="ts" setup>
-import { onMounted, onUnmounted, watch, nextTick } from 'vue';
+import { onMounted, onUnmounted, watch, nextTick, Transition, shallowRef } from 'vue';
import { defaultStore } from '@/store';
const props = withDefaults(defineProps<{
@@ -50,9 +50,9 @@ const emit = defineEmits<{
(ev: 'tabClick', key: string);
}>();
-let el = $shallowRef<HTMLElement | null>(null);
+const el = shallowRef<HTMLElement | null>(null);
const tabRefs: Record<string, HTMLElement | null> = {};
-let tabHighlightEl = $shallowRef<HTMLElement | null>(null);
+const tabHighlightEl = shallowRef<HTMLElement | null>(null);
function onTabMousedown(tab: Tab, ev: MouseEvent): void {
// ユーザビリティの観点からmousedown時にはonClickは呼ばない
@@ -77,13 +77,13 @@ function onTabClick(t: Tab, ev: MouseEvent): void {
function renderTab() {
const tabEl = props.tab ? tabRefs[props.tab] : undefined;
- if (tabEl && tabHighlightEl && tabHighlightEl.parentElement) {
+ if (tabEl && tabHighlightEl.value && tabHighlightEl.value.parentElement) {
// offsetWidth や offsetLeft は少数を丸めてしまうため getBoundingClientRect を使う必要がある
// https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/offsetWidth#%E5%80%A4
- const parentRect = tabHighlightEl.parentElement.getBoundingClientRect();
+ const parentRect = tabHighlightEl.value.parentElement.getBoundingClientRect();
const rect = tabEl.getBoundingClientRect();
- tabHighlightEl.style.width = rect.width + 'px';
- tabHighlightEl.style.left = (rect.left - parentRect.left + tabHighlightEl.parentElement.scrollLeft) + 'px';
+ tabHighlightEl.value.style.width = rect.width + 'px';
+ tabHighlightEl.value.style.left = (rect.left - parentRect.left + tabHighlightEl.value.parentElement.scrollLeft) + 'px';
}
}
@@ -99,22 +99,32 @@ function onTabWheel(ev: WheelEvent) {
return false;
}
-function enter(el: HTMLElement) {
+let entering = false;
+
+async function enter(el: HTMLElement) {
+ entering = true;
const elementWidth = el.getBoundingClientRect().width;
el.style.width = '0';
- el.offsetWidth; // reflow
+ el.style.paddingLeft = '0';
+ el.offsetWidth; // force reflow
el.style.width = elementWidth + 'px';
- setTimeout(renderTab, 70);
+ el.style.paddingLeft = '';
+ nextTick(() => {
+ entering = false;
+ });
+
+ setTimeout(renderTab, 170);
}
function afterEnter(el: HTMLElement) {
- el.style.width = '';
- nextTick(renderTab);
+ //el.style.width = '';
}
-function leave(el: HTMLElement) {
+async function leave(el: HTMLElement) {
const elementWidth = el.getBoundingClientRect().width;
el.style.width = elementWidth + 'px';
- el.offsetWidth; // reflow
+ el.style.paddingLeft = '';
+ el.offsetWidth; // force reflow
el.style.width = '0';
+ el.style.paddingLeft = '0';
}
function afterLeave(el: HTMLElement) {
el.style.width = '';
@@ -124,14 +134,17 @@ let ro2: ResizeObserver | null;
onMounted(() => {
watch([() => props.tab, () => props.tabs], () => {
- nextTick(() => renderTab());
+ nextTick(() => {
+ if (entering) return;
+ renderTab();
+ });
}, {
immediate: true,
});
if (props.rootEl) {
ro2 = new ResizeObserver((entries, observer) => {
- if (document.body.contains(el as HTMLElement)) {
+ if (document.body.contains(el.value as HTMLElement)) {
nextTick(() => renderTab());
}
});
@@ -194,12 +207,15 @@ onUnmounted(() => {
}
.tabIcon+.tabTitle {
- margin-left: 8px;
+ padding-left: 8px;
}
.tabTitle {
overflow: hidden;
- transition: width 0.15s ease-in-out;
+
+ &.animate {
+ transition: width .15s linear, padding-left .15s linear;
+ }
}
.tabHighlight {
diff --git a/packages/frontend/src/components/global/MkPageHeader.vue b/packages/frontend/src/components/global/MkPageHeader.vue
index d39fcde1b5..803efb1690 100644
--- a/packages/frontend/src/components/global/MkPageHeader.vue
+++ b/packages/frontend/src/components/global/MkPageHeader.vue
@@ -1,10 +1,10 @@
<template>
<div v-if="show" ref="el" :class="[$style.root]" :style="{ background: bg }">
<div :class="[$style.upper, { [$style.slim]: narrow, [$style.thin]: thin_ }]">
- <div v-if="narrow && props.displayMyAvatar && $i" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
+ <div v-if="!thin_ && narrow && props.displayMyAvatar && $i" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
<MkAvatar :class="$style.avatar" :user="$i" />
</div>
- <div v-else-if="narrow && !hideTitle" :class="$style.buttonsLeft" />
+ <div v-else-if="!thin_ && narrow && !hideTitle" :class="$style.buttonsLeft" />
<template v-if="metadata">
<div v-if="!hideTitle" :class="$style.titleContainer" @click="top">
@@ -21,7 +21,7 @@
</div>
<XTabs v-if="!narrow || hideTitle" :class="$style.tabs" :tab="tab" @update:tab="key => emit('update:tab', key)" :tabs="tabs" :root-el="el" @tab-click="onTabClick"/>
</template>
- <div v-if="(narrow && !hideTitle) || (actions && actions.length > 0)" :class="$style.buttonsRight">
+ <div v-if="(!thin_ && narrow && !hideTitle) || (actions && actions.length > 0)" :class="$style.buttonsRight">
<template v-for="action in actions">
<button v-tooltip.noDelay="action.text" class="_button" :class="[$style.button, { [$style.highlighted]: action.highlighted }]" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
</template>
@@ -142,6 +142,7 @@ onUnmounted(() => {
.upper {
--height: 50px;
display: flex;
+ gap: var(--margin);
height: var(--height);
.tabs:first-child {
@@ -151,12 +152,9 @@ onUnmounted(() => {
padding-left: 16px;
mask-image: linear-gradient(90deg, rgba(0,0,0,0), rgb(0,0,0) 16px, rgb(0,0,0) 100%);
}
- .tabs:last-child {
+ .tabs {
margin-right: auto;
}
- .tabs:not(:last-child) {
- margin-right: 0;
- }
&.thin {
--height: 42px;
@@ -170,19 +168,14 @@ onUnmounted(() => {
&.slim {
text-align: center;
+ gap: 0;
+ .tabs:first-child {
+ margin-left: 0;
+ }
> .titleContainer {
- flex: 1;
margin: 0 auto;
max-width: 100%;
-
- > *:first-child {
- margin-left: auto;
- }
-
- > *:last-child {
- margin-right: auto;
- }
}
}
}
@@ -198,8 +191,6 @@ onUnmounted(() => {
align-items: center;
min-width: var(--height);
height: var(--height);
- margin: 0 var(--margin);
-
&:empty {
width: var(--height);
}
@@ -207,12 +198,12 @@ onUnmounted(() => {
.buttonsLeft {
composes: buttons;
- margin-right: auto;
+ margin: 0 var(--margin) 0 0;
}
.buttonsRight {
composes: buttons;
- margin-left: auto;
+ margin: 0 0 0 var(--margin);
}
.avatar {
@@ -257,7 +248,7 @@ onUnmounted(() => {
white-space: nowrap;
text-align: left;
font-weight: bold;
- flex-shrink: 0;
+ flex-shrink: 1;
margin-left: 24px;
}