Skip to content
Draft
16 changes: 13 additions & 3 deletions src/runtime/components/prose/Img.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const props = withDefaults(defineProps<ProseImgProps>(), {
const appConfig = useAppConfig() as ProseImg['AppConfig']

const [DefineImageTemplate, ReuseImageTemplate] = createReusableTemplate()
const [DefineZoomedImageTemplate, ReuseZoomedImageTemplate] = createReusableTemplate()

const open = ref(false)

Expand Down Expand Up @@ -78,10 +79,19 @@ if (props.zoom) {
:class="ui.base({ class: [props.ui?.base, props.class] })"
/>
</DefineImageTemplate>
<DefineZoomedImageTemplate>
<component
:is="ImageComponent"
:src="refinedSrc"
:alt="alt"
v-bind="$attrs"
:class="ui.zoomedImage({ class: [props.ui?.zoomedImage] })"
/>
</DefineZoomedImageTemplate>

<DialogRoot v-if="zoom" v-slot="{ close }" v-model:open="open" :modal="false">
<DialogTrigger as-child>
<Motion :layout-id="layoutId" as-child :transition="{ type: 'spring', bounce: 0.2, duration: 0.4 }">
<Motion :layout-id="layoutId" as-child :transition="{ type: 'spring', bounce: 0.15, duration: 0.5, ease: 'easeInOut' }">
<ReuseImageTemplate />
</Motion>
</DialogTrigger>
Expand All @@ -91,8 +101,8 @@ if (props.zoom) {
<Motion v-if="open" :initial="{ opacity: 0 }" :animate="{ opacity: 1 }" :exit="{ opacity: 0 }" :class="ui.overlay({ class: [props.ui?.overlay] })" />

<div v-if="open" :class="ui.content({ class: [props.ui?.content] })" @click="close">
<Motion as-child :layout-id="layoutId" :transition="{ type: 'spring', bounce: 0.2, duration: 0.4 }">
<ReuseImageTemplate />
<Motion as-child :layout-id="layoutId" :transition="{ type: 'spring', bounce: 0.15, duration: 0.5, ease: 'easeInOut' }">
<ReuseZoomedImageTemplate />
</Motion>
</div>
</AnimatePresence>
Expand Down
3 changes: 2 additions & 1 deletion src/theme/prose/img.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ export default {
slots: {
base: 'rounded-md w-full',
overlay: 'fixed inset-0 bg-default/75 backdrop-blur-sm will-change-opacity',
content: 'fixed inset-0 flex items-center justify-center cursor-zoom-out focus:outline-none p-4 sm:p-8'
content: 'fixed inset-0 flex items-center justify-center cursor-zoom-out focus:outline-none',
zoomedImage: 'w-full h-auto max-w-[95vw] max-h-[95vh] object-contain rounded-md'
},
variants: {
zoom: {
Expand Down
Loading