Skip to content

Commit

Permalink
feat: add visible to RenderWhen component (#1260)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
openscript and antfu committed Feb 6, 2024
1 parent 42c570f commit fc6769f
Showing 1 changed file with 25 additions and 6 deletions.
31 changes: 25 additions & 6 deletions packages/client/builtin/RenderWhen.vue
@@ -1,29 +1,48 @@
<script setup lang="ts">
import { computed, inject } from 'vue'
import type { RenderContext } from '@slidev/types'
import { computed, inject, ref } from 'vue'
import { useElementVisibility } from '@vueuse/core'
import { injectionRenderContext } from '../constants'
type Context = 'main' | RenderContext
type Context = 'main' | 'visible' | RenderContext
const props = defineProps<{
context: Context | Context[]
}>()
const { context } = props
const target = ref(null)
const targetVisible = useElementVisibility(target)
const currentContext = inject(injectionRenderContext)
// When context has `visible`, we need to wrap the content with a div to track the visibility
const needsDomWrapper = Array.isArray(context) ? context.includes('visible') : context === 'visible'
const shouldRender = computed(() => Array.isArray(context) ? context.some(contextMatch) : contextMatch(context))
const currentContext = inject(injectionRenderContext)
const shouldRender = computed(() => {
const anyContext = Array.isArray(context) ? context.some(contextMatch) : contextMatch(context)
const allConditions = Array.isArray(context) ? context.every(conditionsMatch) : conditionsMatch(context)
return anyContext && allConditions
})
function contextMatch(context: Context) {
if (context === currentContext?.value)
return true
if (context === 'main' && (currentContext?.value === 'slide' || currentContext?.value === 'presenter'))
return true
if (context === 'visible')
return true
return false
}
function conditionsMatch(context: Context) {
if (context === 'visible')
return targetVisible.value
return true
}
</script>

<template>
<slot v-if="shouldRender" />
<div v-if="needsDomWrapper" ref="target">
<slot v-if="shouldRender" />
</div>
<slot v-else-if="shouldRender" />
</template>

0 comments on commit fc6769f

Please sign in to comment.