This commit is contained in:
syuilo 2022-12-30 15:40:29 +09:00
parent 43fafc8d57
commit d147181a82
5 changed files with 83 additions and 22 deletions

View file

@ -131,7 +131,7 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.container-toggle-enter-active, .container-toggle-leave-active { .container-toggle-enter-active, .container-toggle-leave-active {
overflow-y: hidden; overflow-y: clip;
transition: opacity 0.5s, height 0.5s !important; transition: opacity 0.5s, height 0.5s !important;
} }
.container-toggle-enter-from { .container-toggle-enter-from {

View file

@ -98,7 +98,7 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.folder-toggle-enter-active, .folder-toggle-leave-active { .folder-toggle-enter-active, .folder-toggle-leave-active {
overflow-y: hidden; overflow-y: clip;
transition: opacity 0.5s, height 0.5s !important; transition: opacity 0.5s, height 0.5s !important;
} }
.folder-toggle-enter-from { .folder-toggle-enter-from {

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="dwzlatin" :class="{ opened }"> <div class="dwzlatin" :class="{ opened }" ref="root">
<div class="header _button" @click="toggle"> <div class="header _button" @click="toggle">
<span class="icon"><slot name="icon"></slot></span> <span class="icon"><slot name="icon"></slot></span>
<span class="text"><slot name="label"></slot></span> <span class="text"><slot name="label"></slot></span>
@ -9,17 +9,29 @@
<i v-else class="ti ti-chevron-down icon"></i> <i v-else class="ti ti-chevron-down icon"></i>
</span> </span>
</div> </div>
<KeepAlive> <div v-if="openedAtLeastOnce" class="body">
<div v-if="openedAtLeastOnce" v-show="opened" class="body"> <Transition
<MkSpacer :margin-min="14" :margin-max="22"> :name="$store.state.animation ? 'folder-toggle' : ''"
<slot></slot> @enter="enter"
</MkSpacer> @after-enter="afterEnter"
</div> @leave="leave"
</KeepAlive> @after-leave="afterLeave"
>
<KeepAlive>
<div v-show="opened">
<MkSpacer :margin-min="14" :margin-max="22" :container="root">
<slot></slot>
</MkSpacer>
</div>
</KeepAlive>
</Transition>
</div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { nextTick } from 'vue';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
defaultOpen: boolean; defaultOpen: boolean;
}>(), { }>(), {
@ -28,16 +40,50 @@ const props = withDefaults(defineProps<{
let opened = $ref(props.defaultOpen); let opened = $ref(props.defaultOpen);
let openedAtLeastOnce = $ref(props.defaultOpen); let openedAtLeastOnce = $ref(props.defaultOpen);
let root = $ref<HTMLElement>();
const toggle = () => { function enter(el) {
opened = !opened; const elementHeight = el.getBoundingClientRect().height;
if (opened) { el.style.height = 0;
el.offsetHeight; // reflow
el.style.height = elementHeight + 'px';
}
function afterEnter(el) {
el.style.height = null;
}
function leave(el) {
const elementHeight = el.getBoundingClientRect().height;
el.style.height = elementHeight + 'px';
el.offsetHeight; // reflow
el.style.height = 0;
}
function afterLeave(el) {
el.style.height = null;
}
function toggle() {
if (!opened) {
openedAtLeastOnce = true; openedAtLeastOnce = true;
} }
};
nextTick(() => {
opened = !opened;
});
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.folder-toggle-enter-active, .folder-toggle-leave-active {
overflow-y: clip;
transition: opacity 0.3s, height 0.3s, transform 0.3s !important;
}
.folder-toggle-enter-from, .folder-toggle-leave-to {
opacity: 0;
}
.dwzlatin { .dwzlatin {
display: block; display: block;

View file

@ -59,16 +59,17 @@ const finalValue = computed(() => {
} }
}); });
const thumbWidth = computed(() => { const getThumbWidth = () => {
if (thumbEl.value == null) return 0; if (thumbEl.value == null) return 0;
return thumbEl.value!.offsetWidth; return thumbEl.value!.offsetWidth;
}); };
const thumbPosition = ref(0); const thumbPosition = ref(0);
const calcThumbPosition = () => { const calcThumbPosition = () => {
if (containerEl.value == null) { if (containerEl.value == null) {
thumbPosition.value = 0; thumbPosition.value = 0;
} else { } else {
thumbPosition.value = (containerEl.value.offsetWidth - thumbWidth.value) * steppedRawValue.value; thumbPosition.value = (containerEl.value.offsetWidth - getThumbWidth()) * steppedRawValue.value;
console.log(containerEl.value.offsetWidth, getThumbWidth());
} }
}; };
watch([steppedRawValue, containerEl], calcThumbPosition); watch([steppedRawValue, containerEl], calcThumbPosition);
@ -110,12 +111,14 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
style.appendChild(document.createTextNode('* { cursor: grabbing !important; } body * { pointer-events: none !important; }')); style.appendChild(document.createTextNode('* { cursor: grabbing !important; } body * { pointer-events: none !important; }'));
document.head.appendChild(style); document.head.appendChild(style);
const thumbWidth = getThumbWidth();
const onDrag = (ev: MouseEvent | TouchEvent) => { const onDrag = (ev: MouseEvent | TouchEvent) => {
ev.preventDefault(); ev.preventDefault();
const containerRect = containerEl.value!.getBoundingClientRect(); const containerRect = containerEl.value!.getBoundingClientRect();
const pointerX = ev.touches && ev.touches.length > 0 ? ev.touches[0].clientX : ev.clientX; const pointerX = ev.touches && ev.touches.length > 0 ? ev.touches[0].clientX : ev.clientX;
const pointerPositionOnContainer = pointerX - (containerRect.left + (thumbWidth.value / 2)); const pointerPositionOnContainer = pointerX - (containerRect.left + (thumbWidth / 2));
rawValue.value = Math.min(1, Math.max(0, pointerPositionOnContainer / (containerEl.value!.offsetWidth - thumbWidth.value))); rawValue.value = Math.min(1, Math.max(0, pointerPositionOnContainer / (containerEl.value!.offsetWidth - thumbWidth)));
}; };
let beforeValue = finalValue.value; let beforeValue = finalValue.value;

View file

@ -14,6 +14,9 @@ const props = withDefaults(defineProps<{
contentMax?: number | null; contentMax?: number | null;
marginMin?: number; marginMin?: number;
marginMax?: number; marginMax?: number;
// MkFolderheight
container?: HTMLElement,
}>(), { }>(), {
contentMax: null, contentMax: null,
marginMin: 12, marginMin: 12,
@ -23,7 +26,7 @@ const props = withDefaults(defineProps<{
let ro: ResizeObserver; let ro: ResizeObserver;
let root = $ref<HTMLElement>(); let root = $ref<HTMLElement>();
let content = $ref<HTMLElement>(); let content = $ref<HTMLElement>();
let margin = $ref(0); let margin = $ref(props.marginMin);
const widthHistory = [null, null] as [number | null, number | null]; const widthHistory = [null, null] as [number | null, number | null];
const heightHistory = [null, null] as [number | null, number | null]; const heightHistory = [null, null] as [number | null, number | null];
const shouldSpacerMin = inject('shouldSpacerMin', false); const shouldSpacerMin = inject('shouldSpacerMin', false);
@ -41,6 +44,15 @@ const adjust = (rect: { width: number; height: number; }) => {
} }
}; };
if (props.container) {
const width = props.container.offsetWidth;
const height = props.container.offsetHeight;
adjust({
width,
height,
});
}
onMounted(() => { onMounted(() => {
ro = new ResizeObserver((entries) => { ro = new ResizeObserver((entries) => {
/* iOS /* iOS
@ -50,8 +62,8 @@ onMounted(() => {
}); });
*/ */
const width = root!.offsetWidth; const width = props.container ? props.container.offsetWidth : root!.offsetWidth;
const height = root!.offsetHeight; const height = props.container ? props.container.offsetHeight : root!.offsetHeight;
//#region Prevent infinite resizing //#region Prevent infinite resizing
// https://github.com/misskey-dev/misskey/issues/9076 // https://github.com/misskey-dev/misskey/issues/9076