85 lines
2.5 KiB
Vue

<script setup lang="ts">
import { FadeInExpandTransition } from '@vuepress/helper/client'
import { useResizeObserver } from '@vueuse/core'
import { useTemplateRef, watch } from 'vue'
import { ClientOnly, onContentUpdated } from 'vuepress/client'
import { useExpand } from '../composables/demo.js'
import '@vuepress/helper/transition/fade-in-height-expand.css'
import '../styles/demo.css'
const { type, title, desc, expanded } = defineProps<{
type?: 'vue' | 'markdown'
title?: string
desc?: string
expanded?: boolean
}>()
const [showCode, toggleCode] = useExpand(expanded)
const draw = useTemplateRef<HTMLIFrameElement>('draw')
const vueDraw = useTemplateRef<HTMLIFrameElement>('draw-vue')
function resizeAndPositionVueDraw() {
if (!draw.value || !vueDraw.value)
return
const rect = draw.value.getBoundingClientRect()
const { scrollLeft, scrollTop } = document.documentElement
vueDraw.value.style.width = `${draw.value.offsetWidth - 48}px`
vueDraw.value.style.top = `${rect.top + scrollTop}px`
vueDraw.value.style.left = `${rect.x + scrollLeft}px`
}
if (type === 'vue' && !__VUEPRESS_SSR__) {
watch([draw, vueDraw], () => {
resizeAndPositionVueDraw()
if (draw.value && vueDraw.value) {
requestAnimationFrame(() => {
draw.value!.style.height = `${vueDraw.value!.offsetHeight}px`
})
}
}, { immediate: true })
useResizeObserver(draw, resizeAndPositionVueDraw)
useResizeObserver(() => document.body, resizeAndPositionVueDraw)
onContentUpdated(resizeAndPositionVueDraw)
useResizeObserver(vueDraw, () => {
if (draw.value && vueDraw.value)
draw.value.style.height = `${vueDraw.value.offsetHeight}px`
})
}
</script>
<template>
<div class="vp-demo-wrapper" :class="{ type }">
<div ref="draw" class="demo-draw">
<slot v-if="type !== 'vue'" />
<ClientOnly v-else>
<Teleport to="body">
<div ref="draw-vue" class="demo-draw-vue">
<slot />
</div>
</Teleport>
</ClientOnly>
</div>
<div v-if="title || desc" class="demo-info">
<p v-if="title" class="title">
{{ title }}
</p>
<p v-if="desc" class="desc">
{{ desc }}
</p>
</div>
<div class="demo-ctrl">
<button type="button" aria-label="Toggle Code" @click="toggleCode">
<span class="vpi-demo-code" />
</button>
</div>
<FadeInExpandTransition>
<div v-show="showCode" class="demo-code">
<slot name="code" />
</div>
</FadeInExpandTransition>
</div>
</template>