@slidev/client 0.48.0-beta.20 → 0.48.0-beta.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builtin/CodeBlockWrapper.vue +23 -25
- package/builtin/ShikiMagicMove.vue +63 -13
- package/builtin/SlidevVideo.vue +1 -1
- package/builtin/Toc.vue +1 -1
- package/builtin/TocList.vue +1 -1
- package/composables/useClicks.ts +16 -15
- package/composables/useContext.ts +4 -9
- package/composables/useNav.ts +182 -44
- package/composables/useSwipeControls.ts +40 -0
- package/composables/useTocTree.ts +63 -0
- package/constants.ts +2 -3
- package/context.ts +3 -6
- package/env.ts +4 -4
- package/internals/Goto.vue +2 -2
- package/internals/NavControls.vue +7 -5
- package/internals/NoteStatic.vue +1 -1
- package/internals/PrintContainer.vue +8 -7
- package/internals/PrintSlide.vue +6 -13
- package/internals/PrintSlideClick.vue +11 -13
- package/internals/QuickOverview.vue +10 -10
- package/internals/SideEditor.vue +3 -3
- package/internals/SlideContainer.vue +6 -6
- package/internals/SlideLoading.vue +19 -0
- package/internals/SlideWrapper.ts +12 -12
- package/internals/SlidesShow.vue +13 -10
- package/layouts/error.vue +5 -0
- package/logic/drawings.ts +7 -7
- package/logic/nav-state.ts +20 -0
- package/logic/nav.ts +49 -259
- package/logic/note.ts +2 -2
- package/logic/overview.ts +2 -2
- package/logic/route.ts +10 -1
- package/logic/slides.ts +19 -0
- package/logic/transition.ts +50 -0
- package/logic/utils.ts +24 -0
- package/modules/context.ts +7 -12
- package/package.json +8 -7
- package/pages/notes.vue +2 -3
- package/pages/overview.vue +19 -21
- package/pages/play.vue +2 -1
- package/pages/presenter/print.vue +2 -2
- package/pages/presenter.vue +15 -14
- package/routes.ts +6 -14
- package/setup/root.ts +6 -7
- package/setup/shortcuts.ts +2 -1
- package/shim-vue.d.ts +3 -0
- package/state/index.ts +1 -1
- package/styles/code.css +2 -2
- package/utils.ts +15 -2
package/pages/overview.vue
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
|
3
3
|
import { useHead } from '@unhead/vue'
|
|
4
|
-
import type {
|
|
5
|
-
import type { ClicksContext } from 'packages/types'
|
|
4
|
+
import type { ClicksContext, SlideRoute } from '@slidev/types'
|
|
6
5
|
import { configs } from '../env'
|
|
7
|
-
import { openInEditor,
|
|
6
|
+
import { getSlidePath, openInEditor, slides } from '../logic/nav'
|
|
8
7
|
import { useFixedClicks } from '../composables/useClicks'
|
|
9
8
|
import { isColorSchemaConfigured, isDark, toggleDark } from '../logic/dark'
|
|
10
9
|
import { getSlideClass } from '../utils'
|
|
@@ -26,19 +25,19 @@ useHead({
|
|
|
26
25
|
const blocks: Map<number, HTMLElement> = reactive(new Map())
|
|
27
26
|
const activeBlocks = ref<number[]>([])
|
|
28
27
|
const edittingNote = ref<number | null>(null)
|
|
29
|
-
const wordCounts = computed(() =>
|
|
28
|
+
const wordCounts = computed(() => slides.value.map(route => wordCount(route.meta?.slide?.note || '')))
|
|
30
29
|
const totalWords = computed(() => wordCounts.value.reduce((a, b) => a + b, 0))
|
|
31
|
-
const totalClicks = computed(() =>
|
|
30
|
+
const totalClicks = computed(() => slides.value.map(route => getSlideClicks(route)).reduce((a, b) => a + b, 0))
|
|
32
31
|
|
|
33
|
-
const clicksContextMap = new WeakMap<
|
|
34
|
-
function getClicksContext(route:
|
|
32
|
+
const clicksContextMap = new WeakMap<SlideRoute, ClicksContext>()
|
|
33
|
+
function getClicksContext(route: SlideRoute) {
|
|
35
34
|
// We create a local clicks context to calculate the total clicks of the slide
|
|
36
35
|
if (!clicksContextMap.has(route))
|
|
37
36
|
clicksContextMap.set(route, useFixedClicks(route, CLICKS_MAX))
|
|
38
37
|
return clicksContextMap.get(route)!
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
function getSlideClicks(route:
|
|
40
|
+
function getSlideClicks(route: SlideRoute) {
|
|
42
41
|
return route.meta?.clicks || getClicksContext(route)?.total
|
|
43
42
|
}
|
|
44
43
|
|
|
@@ -80,7 +79,7 @@ function scrollToSlide(idx: number) {
|
|
|
80
79
|
el.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
function onMarkerClick(e: MouseEvent, clicks: number, route:
|
|
82
|
+
function onMarkerClick(e: MouseEvent, clicks: number, route: SlideRoute) {
|
|
84
83
|
const ctx = getClicksContext(route)
|
|
85
84
|
if (ctx.current === clicks)
|
|
86
85
|
ctx.current = CLICKS_MAX
|
|
@@ -101,8 +100,8 @@ onMounted(() => {
|
|
|
101
100
|
<nav class="h-full flex flex-col border-r border-main p2 select-none">
|
|
102
101
|
<div class="flex flex-col flex-auto items-center justify-center group gap-1">
|
|
103
102
|
<div
|
|
104
|
-
v-for="(route, idx) of
|
|
105
|
-
:key="route.
|
|
103
|
+
v-for="(route, idx) of slides"
|
|
104
|
+
:key="route.no"
|
|
106
105
|
class="relative"
|
|
107
106
|
>
|
|
108
107
|
<button
|
|
@@ -136,8 +135,8 @@ onMounted(() => {
|
|
|
136
135
|
@scroll="checkActiveBlocks"
|
|
137
136
|
>
|
|
138
137
|
<div
|
|
139
|
-
v-for="(route, idx) of
|
|
140
|
-
:key="route.
|
|
138
|
+
v-for="(route, idx) of slides"
|
|
139
|
+
:key="route.no"
|
|
141
140
|
:ref="el => blocks.set(idx, el as any)"
|
|
142
141
|
class="relative border-t border-main of-hidden flex gap-4 min-h-50 group"
|
|
143
142
|
>
|
|
@@ -148,7 +147,7 @@ onMounted(() => {
|
|
|
148
147
|
<IconButton
|
|
149
148
|
class="mr--3 op0 group-hover:op80"
|
|
150
149
|
title="Play in new tab"
|
|
151
|
-
@click="openSlideInNewTab(route
|
|
150
|
+
@click="openSlideInNewTab(getSlidePath(route, false))"
|
|
152
151
|
>
|
|
153
152
|
<carbon:presentation-file />
|
|
154
153
|
</IconButton>
|
|
@@ -164,23 +163,22 @@ onMounted(() => {
|
|
|
164
163
|
<div class="flex flex-col gap-2 my5">
|
|
165
164
|
<div
|
|
166
165
|
class="border rounded border-main overflow-hidden bg-main select-none h-max"
|
|
167
|
-
@dblclick="openSlideInNewTab(route
|
|
166
|
+
@dblclick="openSlideInNewTab(getSlidePath(route, false))"
|
|
168
167
|
>
|
|
169
168
|
<SlideContainer
|
|
170
|
-
:key="route.
|
|
169
|
+
:key="route.no"
|
|
171
170
|
:width="cardWidth"
|
|
172
171
|
:clicks-disabled="true"
|
|
173
172
|
class="pointer-events-none important:[&_*]:select-none"
|
|
174
173
|
>
|
|
175
174
|
<SlideWrapper
|
|
176
|
-
:is="route.component"
|
|
177
|
-
v-if="route?.component"
|
|
175
|
+
:is="route.component!"
|
|
178
176
|
:clicks-context="getClicksContext(route)"
|
|
179
177
|
:class="getSlideClass(route)"
|
|
180
178
|
:route="route"
|
|
181
179
|
render-context="overview"
|
|
182
180
|
/>
|
|
183
|
-
<DrawingPreview :page="
|
|
181
|
+
<DrawingPreview :page="route.no" />
|
|
184
182
|
</SlideContainer>
|
|
185
183
|
</div>
|
|
186
184
|
<ClicksSlider
|
|
@@ -220,8 +218,8 @@ onMounted(() => {
|
|
|
220
218
|
</main>
|
|
221
219
|
<div class="absolute top-0 right-0 px3 py1.5 border-b border-l rounded-lb bg-main border-main select-none">
|
|
222
220
|
<div class="text-xs op50">
|
|
223
|
-
{{
|
|
224
|
-
{{ totalClicks +
|
|
221
|
+
{{ slides.length }} slides ·
|
|
222
|
+
{{ totalClicks + slides.length - 1 }} clicks ·
|
|
225
223
|
{{ totalWords }} words
|
|
226
224
|
</div>
|
|
227
225
|
</div>
|
package/pages/play.vue
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, ref, shallowRef } from 'vue'
|
|
3
3
|
import { isEditorVertical, isScreenVertical, showEditor, slideScale, windowSize } from '../state'
|
|
4
|
-
import { isEmbedded, isPrintMode, next, prev
|
|
4
|
+
import { isEmbedded, isPrintMode, next, prev } from '../logic/nav'
|
|
5
|
+
import { useSwipeControls } from '../composables/useSwipeControls'
|
|
5
6
|
import { isDrawing } from '../logic/drawings'
|
|
6
7
|
import { registerShortcuts } from '../logic/shortcuts'
|
|
7
8
|
import { configs } from '../env'
|
|
@@ -3,7 +3,7 @@ import { computed } from 'vue'
|
|
|
3
3
|
import { useStyleTag } from '@vueuse/core'
|
|
4
4
|
import { useHead } from '@unhead/vue'
|
|
5
5
|
import { configs } from '../../env'
|
|
6
|
-
import {
|
|
6
|
+
import { slides, total } from '../../logic/nav'
|
|
7
7
|
import NoteDisplay from '../../internals/NoteDisplay.vue'
|
|
8
8
|
|
|
9
9
|
useStyleTag(`
|
|
@@ -28,7 +28,7 @@ useHead({
|
|
|
28
28
|
title: `Notes - ${configs.title}`,
|
|
29
29
|
})
|
|
30
30
|
|
|
31
|
-
const slidesWithNote = computed(() =>
|
|
31
|
+
const slidesWithNote = computed(() => slides.value
|
|
32
32
|
.map(route => route.meta?.slide)
|
|
33
33
|
.filter(slide => slide !== undefined && slide.noteHTML !== ''))
|
|
34
34
|
</script>
|
package/pages/presenter.vue
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { useHead } from '@unhead/vue'
|
|
3
3
|
import { computed, onMounted, reactive, ref, shallowRef, watch } from 'vue'
|
|
4
4
|
import { useMouse, useWindowFocus } from '@vueuse/core'
|
|
5
|
-
import { clicksContext,
|
|
5
|
+
import { clicksContext, currentSlideNo, currentSlideRoute, hasNext, nextRoute, queryClicks, slides, total } from '../logic/nav'
|
|
6
|
+
import { useSwipeControls } from '../composables/useSwipeControls'
|
|
6
7
|
import { decreasePresenterFontSize, increasePresenterFontSize, presenterLayout, presenterNotesFontSize, showEditor, showOverview, showPresenterCursor } from '../state'
|
|
7
8
|
import { configs } from '../env'
|
|
8
9
|
import { sharedState } from '../state/shared'
|
|
@@ -37,10 +38,10 @@ const notesEditing = ref(false)
|
|
|
37
38
|
|
|
38
39
|
const { timer, resetTimer } = useTimer()
|
|
39
40
|
|
|
40
|
-
const clicksCtxMap =
|
|
41
|
+
const clicksCtxMap = computed(() => slides.value.map(route => useFixedClicks(route)))
|
|
41
42
|
const nextFrame = computed(() => {
|
|
42
43
|
if (clicksContext.value.current < clicksContext.value.total)
|
|
43
|
-
return [
|
|
44
|
+
return [currentSlideRoute.value!, clicksContext.value.current + 1] as const
|
|
44
45
|
else if (hasNext.value)
|
|
45
46
|
return [nextRoute.value!, 0] as const
|
|
46
47
|
else
|
|
@@ -48,11 +49,11 @@ const nextFrame = computed(() => {
|
|
|
48
49
|
})
|
|
49
50
|
|
|
50
51
|
const nextFrameClicksCtx = computed(() => {
|
|
51
|
-
return nextFrame.value && clicksCtxMap[
|
|
52
|
+
return nextFrame.value && clicksCtxMap.value[nextFrame.value[0].no - 1]
|
|
52
53
|
})
|
|
53
54
|
|
|
54
55
|
watch(
|
|
55
|
-
[
|
|
56
|
+
[currentSlideRoute, queryClicks],
|
|
56
57
|
() => {
|
|
57
58
|
if (nextFrameClicksCtx.value)
|
|
58
59
|
nextFrameClicksCtx.value.current = nextFrame.value![1]
|
|
@@ -104,8 +105,8 @@ onMounted(() => {
|
|
|
104
105
|
</template>
|
|
105
106
|
</SlideContainer>
|
|
106
107
|
<ClicksSlider
|
|
107
|
-
:key="
|
|
108
|
-
:clicks-context="usePrimaryClicks(
|
|
108
|
+
:key="currentSlideRoute?.no"
|
|
109
|
+
:clicks-context="usePrimaryClicks(currentSlideRoute)"
|
|
109
110
|
class="w-full pb2 px4 flex-none"
|
|
110
111
|
/>
|
|
111
112
|
<div class="absolute left-0 top-0 bg-main border-b border-r border-main px2 py1 op50 text-sm">
|
|
@@ -119,8 +120,8 @@ onMounted(() => {
|
|
|
119
120
|
class="h-full w-full"
|
|
120
121
|
>
|
|
121
122
|
<SlideWrapper
|
|
122
|
-
:is="
|
|
123
|
-
:key="nextFrame[0].
|
|
123
|
+
:is="nextFrame[0].component!"
|
|
124
|
+
:key="nextFrame[0].no"
|
|
124
125
|
:clicks-context="nextFrameClicksCtx"
|
|
125
126
|
:class="getSlideClass(nextFrame[0])"
|
|
126
127
|
:route="nextFrame[0]"
|
|
@@ -138,17 +139,17 @@ onMounted(() => {
|
|
|
138
139
|
<div v-else class="grid-section note grid grid-rows-[1fr_min-content] overflow-hidden">
|
|
139
140
|
<NoteEditable
|
|
140
141
|
v-if="__DEV__"
|
|
141
|
-
:key="`edit-${
|
|
142
|
+
:key="`edit-${currentSlideNo}`"
|
|
142
143
|
v-model:editing="notesEditing"
|
|
143
|
-
:no="
|
|
144
|
+
:no="currentSlideNo"
|
|
144
145
|
class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
|
|
145
146
|
:clicks-context="clicksContext"
|
|
146
147
|
:style="{ fontSize: `${presenterNotesFontSize}em` }"
|
|
147
148
|
/>
|
|
148
149
|
<NoteStatic
|
|
149
150
|
v-else
|
|
150
|
-
:key="`static-${
|
|
151
|
-
:no="
|
|
151
|
+
:key="`static-${currentSlideNo}`"
|
|
152
|
+
:no="currentSlideNo"
|
|
152
153
|
class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
|
|
153
154
|
:style="{ fontSize: `${presenterNotesFontSize}em` }"
|
|
154
155
|
:clicks-context="clicksContext"
|
|
@@ -189,7 +190,7 @@ onMounted(() => {
|
|
|
189
190
|
<div class="progress-bar">
|
|
190
191
|
<div
|
|
191
192
|
class="progress h-3px bg-primary transition-all"
|
|
192
|
-
:style="{ width: `${(
|
|
193
|
+
:style="{ width: `${(currentSlideNo - 1) / (total - 1) * 100}%` }"
|
|
193
194
|
/>
|
|
194
195
|
</div>
|
|
195
196
|
</div>
|
package/routes.ts
CHANGED
|
@@ -1,21 +1,8 @@
|
|
|
1
1
|
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
|
|
2
2
|
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
|
3
|
-
|
|
4
|
-
import { rawRoutes, redirects } from '#slidev/routes'
|
|
5
3
|
import configs from '#slidev/configs'
|
|
6
4
|
|
|
7
|
-
export { rawRoutes }
|
|
8
|
-
|
|
9
5
|
export const routes: RouteRecordRaw[] = [
|
|
10
|
-
{
|
|
11
|
-
name: 'play',
|
|
12
|
-
path: '/',
|
|
13
|
-
component: () => import('./pages/play.vue'),
|
|
14
|
-
children: [
|
|
15
|
-
...rawRoutes,
|
|
16
|
-
...redirects,
|
|
17
|
-
],
|
|
18
|
-
},
|
|
19
6
|
{
|
|
20
7
|
name: 'print',
|
|
21
8
|
path: '/print',
|
|
@@ -24,7 +11,6 @@ export const routes: RouteRecordRaw[] = [
|
|
|
24
11
|
|
|
25
12
|
// Redirects
|
|
26
13
|
{ path: '', redirect: { path: '/1' } },
|
|
27
|
-
{ path: '/:pathMatch(.*)', redirect: { path: '/1' } },
|
|
28
14
|
]
|
|
29
15
|
|
|
30
16
|
if (__SLIDEV_FEATURE_PRESENTER__) {
|
|
@@ -76,6 +62,12 @@ if (__SLIDEV_FEATURE_PRESENTER__) {
|
|
|
76
62
|
})
|
|
77
63
|
}
|
|
78
64
|
|
|
65
|
+
routes.push({
|
|
66
|
+
name: 'play',
|
|
67
|
+
path: '/:no',
|
|
68
|
+
component: () => import('./pages/play.vue'),
|
|
69
|
+
})
|
|
70
|
+
|
|
79
71
|
export const router = createRouter({
|
|
80
72
|
history: __SLIDEV_HASH_ROUTE__
|
|
81
73
|
? createWebHashHistory(import.meta.env.BASE_URL)
|
package/setup/root.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { useHead } from '@unhead/vue'
|
|
|
4
4
|
import { configs } from '../env'
|
|
5
5
|
import { initSharedState, onPatch, patch } from '../state/shared'
|
|
6
6
|
import { initDrawingState } from '../state/drawings'
|
|
7
|
-
import { clicksContext,
|
|
7
|
+
import { clicksContext, currentSlideNo, getSlidePath, hasPrimarySlide, isNotesViewer, isPresenter } from '../logic/nav'
|
|
8
8
|
import { router } from '../routes'
|
|
9
9
|
import { TRUST_ORIGINS } from '../constants'
|
|
10
10
|
import { skipTransition } from '../composables/hmr'
|
|
@@ -37,11 +37,11 @@ export default function setupRoot() {
|
|
|
37
37
|
return
|
|
38
38
|
|
|
39
39
|
if (isPresenter.value) {
|
|
40
|
-
patch('page', +
|
|
40
|
+
patch('page', +currentSlideNo.value)
|
|
41
41
|
patch('clicks', clicksContext.value.current)
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
44
|
-
patch('viewerPage', +
|
|
44
|
+
patch('viewerPage', +currentSlideNo.value)
|
|
45
45
|
patch('viewerClicks', clicksContext.value.current)
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -55,13 +55,12 @@ export default function setupRoot() {
|
|
|
55
55
|
watch(clicksContext, updateSharedState)
|
|
56
56
|
|
|
57
57
|
onPatch((state) => {
|
|
58
|
-
|
|
59
|
-
if (!routePath.match(/^\/(\d+|presenter)\/?/))
|
|
58
|
+
if (!hasPrimarySlide.value)
|
|
60
59
|
return
|
|
61
|
-
if (state.lastUpdate?.type === 'presenter' && (+state.page !== +
|
|
60
|
+
if (state.lastUpdate?.type === 'presenter' && (+state.page !== +currentSlideNo.value || +clicksContext.value.current !== +state.clicks)) {
|
|
62
61
|
skipTransition.value = false
|
|
63
62
|
router.replace({
|
|
64
|
-
path:
|
|
63
|
+
path: getSlidePath(state.page),
|
|
65
64
|
query: {
|
|
66
65
|
...router.currentRoute.value.query,
|
|
67
66
|
clicks: state.clicks || 0,
|
package/setup/shortcuts.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/* __imports__ */
|
|
2
2
|
import { and, not, or } from '@vueuse/math'
|
|
3
3
|
import type { NavOperations, ShortcutOptions } from '@slidev/types'
|
|
4
|
-
import { downloadPDF
|
|
4
|
+
import { downloadPDF } from '../utils'
|
|
5
|
+
import { go, goFirst, goLast, next, nextSlide, prev, prevSlide } from '../logic/nav'
|
|
5
6
|
import { toggleDark } from '../logic/dark'
|
|
6
7
|
import { magicKeys, showGotoDialog, showOverview, toggleOverview } from '../state'
|
|
7
8
|
import { drawingEnabled } from '../logic/drawings'
|
package/shim-vue.d.ts
CHANGED
package/state/index.ts
CHANGED
|
@@ -14,7 +14,7 @@ export const breakpoints = useBreakpoints({
|
|
|
14
14
|
})
|
|
15
15
|
export const windowSize = useWindowSize()
|
|
16
16
|
export const magicKeys = useMagicKeys()
|
|
17
|
-
export const isScreenVertical = computed(() => windowSize.height.value - windowSize.width.value / slideAspect > 120)
|
|
17
|
+
export const isScreenVertical = computed(() => windowSize.height.value - windowSize.width.value / slideAspect.value > 120)
|
|
18
18
|
export const fullscreen = useFullscreen(isClient ? document.body : null)
|
|
19
19
|
|
|
20
20
|
export const activeElement = useActiveElement()
|
package/styles/code.css
CHANGED
|
@@ -44,9 +44,9 @@ html:not(.dark) .shiki span {
|
|
|
44
44
|
overflow: auto;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
.slidev-code .
|
|
47
|
+
.slidev-code .slidev-code-highlighted {
|
|
48
48
|
}
|
|
49
|
-
.slidev-code .
|
|
49
|
+
.slidev-code .slidev-code-dishonored {
|
|
50
50
|
opacity: 0.3;
|
|
51
51
|
pointer-events: none;
|
|
52
52
|
}
|
package/utils.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SlideRoute } from '@slidev/types'
|
|
2
|
+
import { configs } from './env'
|
|
2
3
|
|
|
3
|
-
export function getSlideClass(route?:
|
|
4
|
+
export function getSlideClass(route?: SlideRoute, extra = '') {
|
|
4
5
|
const classes = ['slidev-page', extra]
|
|
5
6
|
|
|
6
7
|
const no = route?.meta?.slide?.no
|
|
@@ -9,3 +10,15 @@ export function getSlideClass(route?: RouteRecordRaw, extra = '') {
|
|
|
9
10
|
|
|
10
11
|
return classes.filter(Boolean).join(' ')
|
|
11
12
|
}
|
|
13
|
+
|
|
14
|
+
export async function downloadPDF() {
|
|
15
|
+
const { saveAs } = await import('file-saver')
|
|
16
|
+
saveAs(
|
|
17
|
+
typeof configs.download === 'string'
|
|
18
|
+
? configs.download
|
|
19
|
+
: configs.exportFilename
|
|
20
|
+
? `${configs.exportFilename}.pdf`
|
|
21
|
+
: `${import.meta.env.BASE_URL}slidev-exported.pdf`,
|
|
22
|
+
`${configs.title}.pdf`,
|
|
23
|
+
)
|
|
24
|
+
}
|