🎨
This commit is contained in:
		
							parent
							
								
									43fafc8d57
								
							
						
					
					
						commit
						d147181a82
					
				
					 5 changed files with 83 additions and 22 deletions
				
			
		|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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> | ||||
| 	<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-if="openedAtLeastOnce" v-show="opened" class="body"> | ||||
| 			<MkSpacer :margin-min="14" :margin-max="22"> | ||||
| 				<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>(); | ||||
| 
 | ||||
| const toggle = () => { | ||||
| 	opened = !opened; | ||||
| 	if (opened) { | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue