diff --git a/packages/frontend/src/components/MkContainer.vue b/packages/frontend/src/components/MkContainer.vue index b4b67198306df950952ca268229e7e8254413f68..962bcaf7e9bf937a4230ffdd0ea86d9092f8be10 100644 --- a/packages/frontend/src/components/MkContainer.vue +++ b/packages/frontend/src/components/MkContainer.vue @@ -131,7 +131,7 @@ export default defineComponent({ <style lang="scss" scoped> .container-toggle-enter-active, .container-toggle-leave-active { - overflow-y: hidden; + overflow-y: clip; transition: opacity 0.5s, height 0.5s !important; } .container-toggle-enter-from { diff --git a/packages/frontend/src/components/MkFolder.vue b/packages/frontend/src/components/MkFolder.vue index d76ea43888fc8ee4bf650959cf3127bfe6418d4e..5a406c8635f85fc3163d32322ca4da8e5560bbcd 100644 --- a/packages/frontend/src/components/MkFolder.vue +++ b/packages/frontend/src/components/MkFolder.vue @@ -98,7 +98,7 @@ export default defineComponent({ <style lang="scss" scoped> .folder-toggle-enter-active, .folder-toggle-leave-active { - overflow-y: hidden; + overflow-y: clip; transition: opacity 0.5s, height 0.5s !important; } .folder-toggle-enter-from { diff --git a/packages/frontend/src/components/form/folder.vue b/packages/frontend/src/components/form/folder.vue index 1256dfcbb460d7696c8dcd7e726cfbb56d7a73cd..d7603e58d1a746771ad4e3cf5df209d135d5777f 100644 --- a/packages/frontend/src/components/form/folder.vue +++ b/packages/frontend/src/components/form/folder.vue @@ -1,5 +1,5 @@ <template> -<div class="dwzlatin" :class="{ opened }"> +<div class="dwzlatin" :class="{ opened }" ref="root"> <div class="header _button" @click="toggle"> <span class="icon"><slot name="icon"></slot></span> <span class="text"><slot name="label"></slot></span> @@ -9,17 +9,29 @@ <i v-else class="ti ti-chevron-down icon"></i> </span> </div> - <KeepAlive> - <div v-if="openedAtLeastOnce" v-show="opened" class="body"> - <MkSpacer :margin-min="14" :margin-max="22"> - <slot></slot> - </MkSpacer> - </div> - </KeepAlive> + <div v-if="openedAtLeastOnce" class="body"> + <Transition + :name="$store.state.animation ? 'folder-toggle' : ''" + @enter="enter" + @after-enter="afterEnter" + @leave="leave" + @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> </template> <script lang="ts" setup> +import { nextTick } from 'vue'; + const props = withDefaults(defineProps<{ defaultOpen: boolean; }>(), { @@ -28,16 +40,50 @@ const props = withDefaults(defineProps<{ let opened = $ref(props.defaultOpen); let openedAtLeastOnce = $ref(props.defaultOpen); +let root = $ref<HTMLElement>(); + +function enter(el) { + const elementHeight = el.getBoundingClientRect().height; + 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; +} -const toggle = () => { - opened = !opened; - if (opened) { +function afterLeave(el) { + el.style.height = null; +} + +function toggle() { + if (!opened) { openedAtLeastOnce = true; } -}; + + nextTick(() => { + opened = !opened; + }); +} </script> <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 { display: block; diff --git a/packages/frontend/src/components/form/range.vue b/packages/frontend/src/components/form/range.vue index db21c35717f76ad9ef8319966b24172d6c3432d1..cdaecb84c8a24d2bb191111338d7a895938f116b 100644 --- a/packages/frontend/src/components/form/range.vue +++ b/packages/frontend/src/components/form/range.vue @@ -59,16 +59,17 @@ const finalValue = computed(() => { } }); -const thumbWidth = computed(() => { +const getThumbWidth = () => { if (thumbEl.value == null) return 0; return thumbEl.value!.offsetWidth; -}); +}; const thumbPosition = ref(0); const calcThumbPosition = () => { if (containerEl.value == null) { thumbPosition.value = 0; } 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); @@ -110,12 +111,14 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => { style.appendChild(document.createTextNode('* { cursor: grabbing !important; } body * { pointer-events: none !important; }')); document.head.appendChild(style); + const thumbWidth = getThumbWidth(); + const onDrag = (ev: MouseEvent | TouchEvent) => { ev.preventDefault(); const containerRect = containerEl.value!.getBoundingClientRect(); const pointerX = ev.touches && ev.touches.length > 0 ? ev.touches[0].clientX : ev.clientX; - const pointerPositionOnContainer = pointerX - (containerRect.left + (thumbWidth.value / 2)); - rawValue.value = Math.min(1, Math.max(0, pointerPositionOnContainer / (containerEl.value!.offsetWidth - thumbWidth.value))); + const pointerPositionOnContainer = pointerX - (containerRect.left + (thumbWidth / 2)); + rawValue.value = Math.min(1, Math.max(0, pointerPositionOnContainer / (containerEl.value!.offsetWidth - thumbWidth))); }; let beforeValue = finalValue.value; diff --git a/packages/frontend/src/components/global/MkSpacer.vue b/packages/frontend/src/components/global/MkSpacer.vue index b3a42d77e7c75f8c89b3b9fea77d3f5417a16c5f..01e7409801aa769cedaa2e1e102f47ac58dd80d0 100644 --- a/packages/frontend/src/components/global/MkSpacer.vue +++ b/packages/frontend/src/components/global/MkSpacer.vue @@ -14,6 +14,9 @@ const props = withDefaults(defineProps<{ contentMax?: number | null; marginMin?: number; marginMax?: number; + + // MkFolderã¨ã‹ã§é–‹é–‰ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®éš›ã«heightã‚’æ£ã—ãä¼ãˆã‚‹ãŸã‚ + container?: HTMLElement, }>(), { contentMax: null, marginMin: 12, @@ -23,7 +26,7 @@ const props = withDefaults(defineProps<{ let ro: ResizeObserver; let root = $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 heightHistory = [null, null] as [number | null, number | null]; 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(() => { ro = new ResizeObserver((entries) => { /* iOSãŒå¯¾å¿œã—ã¦ã„ãªã„ @@ -50,8 +62,8 @@ onMounted(() => { }); */ - const width = root!.offsetWidth; - const height = root!.offsetHeight; + const width = props.container ? props.container.offsetWidth : root!.offsetWidth; + const height = props.container ? props.container.offsetHeight : root!.offsetHeight; //#region Prevent infinite resizing // https://github.com/misskey-dev/misskey/issues/9076