74 lines
2.1 KiB
Vue
Raw Normal View History

2026-05-31 13:21:13 +02:00
<script setup lang="ts">
import type { ClicksContext, RenderContext, SlideRoute } from '@slidev/types'
import type { CSSProperties, PropType } from 'vue'
import { SlideBottom, SlideTop } from '#slidev/global-layers'
import { provideLocal } from '@vueuse/core'
import { computed, ref, toRef } from 'vue'
import { injectionClicksContext, injectionCurrentPage, injectionFrontmatter, injectionRenderContext, injectionRoute, injectionSlideZoom } from '../constants'
import { configs } from '../env'
import { getSlideClass } from '../utils'
const props = defineProps({
clicksContext: {
type: Object as PropType<ClicksContext>,
required: true,
},
renderContext: {
type: String as PropType<RenderContext>,
default: 'slide',
},
route: {
type: Object as PropType<SlideRoute>,
required: true,
},
})
const zoom = computed(() => props.route.meta?.slide?.frontmatter.zoom ?? 1)
provideLocal(injectionRoute, props.route)
provideLocal(injectionFrontmatter, props.route.meta.slide.frontmatter)
provideLocal(injectionCurrentPage, ref(props.route.no))
provideLocal(injectionRenderContext, ref(props.renderContext))
provideLocal(injectionClicksContext, toRef(props, 'clicksContext'))
provideLocal(injectionSlideZoom, zoom)
const zoomStyle = computed(() => {
return zoom.value === 1
? undefined
: {
width: `${100 / zoom.value}%`,
height: `${100 / zoom.value}%`,
transformOrigin: 'top left',
transform: `scale(${zoom.value})`,
}
})
const style = computed<CSSProperties>(() => ({
...zoomStyle.value,
'user-select': configs.selectable ? undefined : 'none',
}))
</script>
<template>
<div
:data-slidev-no="props.route.no"
:class="getSlideClass(route, ['slide', 'presenter'].includes(props.renderContext) ? '' : 'disable-view-transition')"
:style="style"
:lang="props.route.meta.slide.frontmatter.lang"
>
<SlideBottom />
<component :is="props.route.component" />
<SlideTop />
</div>
</template>
<style scoped>
.disable-view-transition:deep(*) {
view-transition-name: none !important;
}
.slidev-page {
position: absolute;
inset: 0;
}
</style>