@slidev/client 0.38.7 → 0.39.0
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/Tweet.vue +8 -1
- package/iframes/monaco/index.ts +2 -2
- package/internals/Play.vue +2 -0
- package/internals/Print.vue +4 -11
- package/internals/PrintContainer.vue +1 -1
- package/internals/PrintSlideClick.vue +1 -1
- package/internals/PrintStyle.vue +16 -0
- package/internals/SlideContainer.vue +3 -2
- package/internals/SlidesShow.vue +8 -26
- package/logic/nav.ts +57 -2
- package/logic/recording.ts +1 -1
- package/package.json +6 -6
- package/routes.ts +3 -1
- package/styles/index.css +4 -0
- package/styles/layouts-base.css +5 -1
- package/styles/transitions.css +56 -0
- package/styles/vars.css +2 -0
- package/utils.ts +6 -3
package/builtin/Tweet.vue
CHANGED
|
@@ -58,7 +58,7 @@ else {
|
|
|
58
58
|
|
|
59
59
|
<template>
|
|
60
60
|
<Transform :scale="scale || 1">
|
|
61
|
-
<div ref="tweet" class="tweet
|
|
61
|
+
<div ref="tweet" class="tweet slidev-tweet">
|
|
62
62
|
<div v-if="!loaded || tweetNotFound" class="w-30 h-30 my-10px bg-gray-400 bg-opacity-10 rounded-lg flex opacity-50">
|
|
63
63
|
<div class="m-auto animate-pulse text-4xl">
|
|
64
64
|
<carbon:logo-twitter />
|
|
@@ -68,3 +68,10 @@ else {
|
|
|
68
68
|
</div>
|
|
69
69
|
</Transform>
|
|
70
70
|
</template>
|
|
71
|
+
|
|
72
|
+
<style>
|
|
73
|
+
.slidev-tweet iframe {
|
|
74
|
+
border-radius: 12px;
|
|
75
|
+
overflow: hidden;
|
|
76
|
+
}
|
|
77
|
+
</style>
|
package/iframes/monaco/index.ts
CHANGED
|
@@ -101,8 +101,8 @@ async function start() {
|
|
|
101
101
|
|
|
102
102
|
update = () => {
|
|
103
103
|
monaco.editor.setTheme(props.dark
|
|
104
|
-
? theme.dark || 'vitesse-dark'
|
|
105
|
-
: theme.light || 'vitesse-light',
|
|
104
|
+
? (theme.dark || 'vitesse-dark')
|
|
105
|
+
: (theme.light || 'vitesse-light'),
|
|
106
106
|
)
|
|
107
107
|
styleObject.innerHTML = `:root { ${props.style} }`
|
|
108
108
|
|
package/internals/Play.vue
CHANGED
|
@@ -9,6 +9,7 @@ import Controls from './Controls.vue'
|
|
|
9
9
|
import SlideContainer from './SlideContainer.vue'
|
|
10
10
|
import NavControls from './NavControls.vue'
|
|
11
11
|
import SlidesShow from './SlidesShow.vue'
|
|
12
|
+
import PrintStyle from './PrintStyle.vue'
|
|
12
13
|
|
|
13
14
|
registerShortcuts()
|
|
14
15
|
|
|
@@ -40,6 +41,7 @@ if (__SLIDEV_FEATURE_DRAWINGS__)
|
|
|
40
41
|
</script>
|
|
41
42
|
|
|
42
43
|
<template>
|
|
44
|
+
<PrintStyle v-if="isPrintMode" />
|
|
43
45
|
<div id="page-root" ref="root" class="grid grid-cols-[1fr_max-content]" :style="themeVars">
|
|
44
46
|
<SlideContainer
|
|
45
47
|
class="w-full h-full"
|
package/internals/Print.vue
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
3
|
-
import { h, watchEffect } from 'vue'
|
|
2
|
+
import { watchEffect } from 'vue'
|
|
4
3
|
import { windowSize } from '../state'
|
|
5
4
|
import { isPrintMode } from '../logic/nav'
|
|
6
|
-
import {
|
|
5
|
+
import { themeVars } from '../env'
|
|
7
6
|
import PrintContainer from './PrintContainer.vue'
|
|
8
|
-
|
|
9
|
-
function vStyle<Props>(props: Props, { slots }: { slots: Slots }) {
|
|
10
|
-
if (slots.default)
|
|
11
|
-
return h('style', slots.default())
|
|
12
|
-
}
|
|
7
|
+
import PrintStyle from './PrintStyle.vue'
|
|
13
8
|
|
|
14
9
|
watchEffect(() => {
|
|
15
10
|
if (isPrintMode)
|
|
@@ -20,9 +15,7 @@ watchEffect(() => {
|
|
|
20
15
|
</script>
|
|
21
16
|
|
|
22
17
|
<template>
|
|
23
|
-
<
|
|
24
|
-
@page { size: {{ slideWidth }}px {{ slideHeight }}px; margin: 0px; }
|
|
25
|
-
</vStyle>
|
|
18
|
+
<PrintStyle v-if="isPrintMode" />
|
|
26
19
|
<div id="page-root" class="grid grid-cols-[1fr_max-content]" :style="themeVars">
|
|
27
20
|
<PrintContainer
|
|
28
21
|
class="w-full h-full"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { Slots } from 'vue'
|
|
3
|
+
import { h } from 'vue'
|
|
4
|
+
import { slideHeight, slideWidth } from '../env'
|
|
5
|
+
|
|
6
|
+
function vStyle<Props>(props: Props, { slots }: { slots: Slots }) {
|
|
7
|
+
if (slots.default)
|
|
8
|
+
return h('style', slots.default())
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<vStyle>
|
|
14
|
+
@page { size: {{ slideWidth }}px {{ slideHeight }}px; margin: 0px; }
|
|
15
|
+
</vStyle>
|
|
16
|
+
</template>
|
|
@@ -3,6 +3,7 @@ import { useElementSize } from '@vueuse/core'
|
|
|
3
3
|
import { computed, provide, ref, watchEffect } from 'vue'
|
|
4
4
|
import { configs, slideAspect, slideHeight, slideWidth } from '../env'
|
|
5
5
|
import { injectionSlideScale } from '../constants'
|
|
6
|
+
import { isPrintMode } from '../logic/nav'
|
|
6
7
|
|
|
7
8
|
const props = defineProps({
|
|
8
9
|
width: {
|
|
@@ -34,7 +35,7 @@ if (props.width) {
|
|
|
34
35
|
const screenAspect = computed(() => width.value / height.value)
|
|
35
36
|
|
|
36
37
|
const scale = computed(() => {
|
|
37
|
-
if (props.scale)
|
|
38
|
+
if (props.scale && !isPrintMode.value)
|
|
38
39
|
return props.scale
|
|
39
40
|
if (screenAspect.value < slideAspect)
|
|
40
41
|
return width.value / slideWidth
|
|
@@ -66,7 +67,7 @@ provide(injectionSlideScale, scale)
|
|
|
66
67
|
|
|
67
68
|
<style lang="postcss">
|
|
68
69
|
#slide-container {
|
|
69
|
-
@apply relative overflow-hidden;
|
|
70
|
+
@apply relative overflow-hidden break-after-page;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
#slide-content {
|
package/internals/SlidesShow.vue
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { clicks, currentRoute, isPresenter, nextRoute, rawRoutes } from '../logic/nav'
|
|
2
|
+
import { TransitionGroup, computed, shallowRef, watch } from 'vue'
|
|
3
|
+
import { clicks, currentRoute, isPresenter, nextRoute, rawRoutes, transition } from '../logic/nav'
|
|
4
4
|
import { getSlideClass } from '../utils'
|
|
5
|
-
import { configs } from '../env'
|
|
6
5
|
import SlideWrapper from './SlideWrapper'
|
|
7
6
|
// @ts-expect-error virtual module
|
|
8
7
|
import GlobalTop from '/@slidev/global-components/top'
|
|
@@ -24,17 +23,7 @@ const DrawingLayer = shallowRef<any>()
|
|
|
24
23
|
if (__SLIDEV_FEATURE_DRAWINGS__ || __SLIDEV_FEATURE_DRAWINGS_PERSIST__)
|
|
25
24
|
import('./DrawingLayer.vue').then(v => DrawingLayer.value = v.default)
|
|
26
25
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
const isLeaving = ref(false)
|
|
30
|
-
function onBeforeLeave() {
|
|
31
|
-
if (configs.pageTransition?.crossfade === false)
|
|
32
|
-
isLeaving.value = true
|
|
33
|
-
}
|
|
34
|
-
function onAfterLeave() {
|
|
35
|
-
if (configs.pageTransition?.crossfade === false)
|
|
36
|
-
isLeaving.value = false
|
|
37
|
-
}
|
|
26
|
+
const loadedRoutes = computed(() => rawRoutes.filter(r => r.meta?.__preloaded || r === currentRoute.value))
|
|
38
27
|
</script>
|
|
39
28
|
|
|
40
29
|
<template>
|
|
@@ -42,18 +31,11 @@ function onAfterLeave() {
|
|
|
42
31
|
<GlobalBottom />
|
|
43
32
|
|
|
44
33
|
<!-- Slides -->
|
|
45
|
-
<
|
|
46
|
-
v-for="route of
|
|
47
|
-
:key="route.path"
|
|
48
|
-
>
|
|
49
|
-
<Transition
|
|
50
|
-
v-bind="configs.pageTransition"
|
|
51
|
-
@before-leave="onBeforeLeave()"
|
|
52
|
-
@after-leave="onAfterLeave()"
|
|
53
|
-
>
|
|
34
|
+
<TransitionGroup v-bind="transition">
|
|
35
|
+
<template v-for="route of loadedRoutes" :key="route.path">
|
|
54
36
|
<SlideWrapper
|
|
55
37
|
:is="route?.component as any"
|
|
56
|
-
v-show="route === currentRoute
|
|
38
|
+
v-show="route === currentRoute"
|
|
57
39
|
:clicks="route === currentRoute ? clicks : 0"
|
|
58
40
|
:clicks-elements="route.meta?.__clicksElements || []"
|
|
59
41
|
:clicks-disabled="false"
|
|
@@ -61,8 +43,8 @@ function onAfterLeave() {
|
|
|
61
43
|
:route="route"
|
|
62
44
|
:context="context"
|
|
63
45
|
/>
|
|
64
|
-
</
|
|
65
|
-
</
|
|
46
|
+
</template>
|
|
47
|
+
</TransitionGroup>
|
|
66
48
|
|
|
67
49
|
<!-- Global Top -->
|
|
68
50
|
<GlobalTop />
|
package/logic/nav.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Ref } from 'vue'
|
|
1
|
+
import type { Ref, TransitionGroupProps } from 'vue'
|
|
2
2
|
import type { RouteRecordRaw } from 'vue-router'
|
|
3
|
-
import { computed, nextTick, ref } from 'vue'
|
|
3
|
+
import { computed, nextTick, ref, watch } from 'vue'
|
|
4
4
|
import type { TocItem } from '@slidev/types'
|
|
5
5
|
import { SwipeDirection, isString, timestamp, usePointerSwipe } from '@vueuse/core'
|
|
6
6
|
import { rawRoutes, router } from '../routes'
|
|
@@ -18,6 +18,7 @@ nextTick(() => {
|
|
|
18
18
|
routeForceRefresh.value += 1
|
|
19
19
|
})
|
|
20
20
|
})
|
|
21
|
+
export const navDirection = ref(0)
|
|
21
22
|
|
|
22
23
|
export const route = computed(() => router.currentRoute.value)
|
|
23
24
|
|
|
@@ -40,6 +41,7 @@ export const currentSlideId = computed(() => currentRoute.value?.meta?.slide?.id
|
|
|
40
41
|
export const currentLayout = computed(() => currentRoute.value?.meta?.layout || (currentPage.value === 1 ? 'cover' : 'default'))
|
|
41
42
|
|
|
42
43
|
export const nextRoute = computed(() => rawRoutes.find(i => i.path === `${Math.min(rawRoutes.length, currentPage.value + 1)}`))
|
|
44
|
+
export const prevRoute = computed(() => rawRoutes.find(i => i.path === `${Math.max(1, currentPage.value - 1)}`))
|
|
43
45
|
|
|
44
46
|
export const clicksElements = computed<HTMLElement[]>(() => {
|
|
45
47
|
// eslint-disable-next-line no-unused-expressions
|
|
@@ -75,6 +77,12 @@ export const rawTree = computed(() => rawRoutes
|
|
|
75
77
|
export const treeWithActiveStatuses = computed(() => getTreeWithActiveStatuses(rawTree.value, currentRoute.value))
|
|
76
78
|
export const tree = computed(() => filterTree(treeWithActiveStatuses.value))
|
|
77
79
|
|
|
80
|
+
export const transition = computed(() => getCurrentTransition(navDirection.value, currentRoute.value, prevRoute.value))
|
|
81
|
+
|
|
82
|
+
watch(currentRoute, (next, prev) => {
|
|
83
|
+
navDirection.value = Number(next?.path) - Number(prev?.path)
|
|
84
|
+
})
|
|
85
|
+
|
|
78
86
|
export function next() {
|
|
79
87
|
if (clicksTotal.value <= clicks.value)
|
|
80
88
|
nextSlide()
|
|
@@ -220,3 +228,50 @@ export function filterTree(tree: TocItem[], level = 1): TocItem[] {
|
|
|
220
228
|
children: filterTree(item.children, level + 1),
|
|
221
229
|
}))
|
|
222
230
|
}
|
|
231
|
+
|
|
232
|
+
const transitionResolveMap: Record<string, string | undefined> = {
|
|
233
|
+
'slide-left': 'slide-left | slide-right',
|
|
234
|
+
'slide-right': 'slide-right | slide-left',
|
|
235
|
+
'slide-up': 'slide-up | slide-down',
|
|
236
|
+
'slide-down': 'slide-down | slide-up',
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function resolveTransition(transition?: string | TransitionGroupProps, isBackward = false): TransitionGroupProps | undefined {
|
|
240
|
+
if (!transition)
|
|
241
|
+
return undefined
|
|
242
|
+
if (typeof transition === 'string') {
|
|
243
|
+
transition = {
|
|
244
|
+
name: transition,
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (!transition.name)
|
|
249
|
+
return undefined
|
|
250
|
+
|
|
251
|
+
let name = transition.name.includes('|')
|
|
252
|
+
? transition.name
|
|
253
|
+
: (transitionResolveMap[transition.name] || transition.name)
|
|
254
|
+
|
|
255
|
+
if (name.includes('|')) {
|
|
256
|
+
const [forward, backward] = name.split('|').map(i => i.trim())
|
|
257
|
+
name = isBackward ? backward : forward
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (!name)
|
|
261
|
+
return undefined
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
...transition,
|
|
265
|
+
name,
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export function getCurrentTransition(direction: number, currentRoute?: RouteRecordRaw, prevRoute?: RouteRecordRaw) {
|
|
270
|
+
let transition = direction > 0
|
|
271
|
+
? prevRoute?.meta?.transition
|
|
272
|
+
: currentRoute?.meta?.transition
|
|
273
|
+
if (!transition)
|
|
274
|
+
transition = configs.transition
|
|
275
|
+
|
|
276
|
+
return resolveTransition(transition, direction < 0)
|
|
277
|
+
}
|
package/logic/recording.ts
CHANGED
|
@@ -107,7 +107,7 @@ export function useRecording() {
|
|
|
107
107
|
return
|
|
108
108
|
|
|
109
109
|
streamCamera.value = await navigator.mediaDevices.getUserMedia({
|
|
110
|
-
video: currentCamera.value === 'none' || recordCamera.value !== true
|
|
110
|
+
video: (currentCamera.value === 'none' || recordCamera.value !== true)
|
|
111
111
|
? false
|
|
112
112
|
: {
|
|
113
113
|
deviceId: currentCamera.value,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
4
4
|
"description": "Presentation slides for developers",
|
|
5
5
|
"author": "antfu <anthonyfu117@hotmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@antfu/utils": "^0.7.2",
|
|
19
|
-
"@unocss/reset": "^0.
|
|
19
|
+
"@unocss/reset": "^0.49.1",
|
|
20
20
|
"@vueuse/core": "^9.11.1",
|
|
21
21
|
"@vueuse/head": "^1.0.23",
|
|
22
22
|
"@vueuse/math": "^9.11.1",
|
|
23
|
-
"@vueuse/motion": "^2.0.0-beta.
|
|
23
|
+
"@vueuse/motion": "^2.0.0-beta.27",
|
|
24
24
|
"codemirror": "^5.65.5",
|
|
25
25
|
"defu": "^6.1.2",
|
|
26
26
|
"drauu": "^0.3.2",
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"prettier": "^2.8.3",
|
|
35
35
|
"recordrtc": "^5.6.2",
|
|
36
36
|
"resolve": "^1.22.1",
|
|
37
|
-
"unocss": "^0.
|
|
37
|
+
"unocss": "^0.49.1",
|
|
38
38
|
"vite-plugin-windicss": "^1.8.10",
|
|
39
39
|
"vue": "^3.2.45",
|
|
40
40
|
"vue-router": "^4.1.6",
|
|
41
41
|
"vue-starport": "^0.3.0",
|
|
42
42
|
"windicss": "^3.5.6",
|
|
43
|
-
"@slidev/parser": "0.
|
|
44
|
-
"@slidev/types": "0.
|
|
43
|
+
"@slidev/parser": "0.39.0",
|
|
44
|
+
"@slidev/types": "0.39.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"vite": "^4.0.4"
|
package/routes.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { RouteRecordRaw } from 'vue-router'
|
|
2
|
+
import type { SlideTransition } from '@slidev/types'
|
|
2
3
|
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
|
3
4
|
import Play from './internals/Play.vue'
|
|
4
5
|
import Print from './internals/Print.vue'
|
|
5
6
|
// @ts-expect-error missing types
|
|
6
7
|
import _rawRoutes from '/@slidev/routes'
|
|
8
|
+
// @ts-expect-error missing types
|
|
7
9
|
import _configs from '/@slidev/configs'
|
|
8
10
|
|
|
9
11
|
export const rawRoutes = _rawRoutes as RouteRecordRaw[]
|
|
@@ -70,7 +72,7 @@ declare module 'vue-router' {
|
|
|
70
72
|
title?: string
|
|
71
73
|
level?: number
|
|
72
74
|
}
|
|
73
|
-
|
|
75
|
+
transition?: string | SlideTransition
|
|
74
76
|
// private fields
|
|
75
77
|
__clicksElements: HTMLElement[]
|
|
76
78
|
__preloaded?: boolean
|
package/styles/index.css
CHANGED
package/styles/layouts-base.css
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/* Sliding */
|
|
2
|
+
.slide-left-enter-active,
|
|
3
|
+
.slide-left-leave-active,
|
|
4
|
+
.slide-right-enter-active,
|
|
5
|
+
.slide-right-leave-active,
|
|
6
|
+
.slide-up-enter-active,
|
|
7
|
+
.slide-up-leave-active,
|
|
8
|
+
.slide-down-enter-active,
|
|
9
|
+
.slide-down-leave-active {
|
|
10
|
+
transition: all var(--slidev-transition-duration) ease;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.slide-left-enter-from,
|
|
14
|
+
.slide-right-leave-to {
|
|
15
|
+
transform: translateX(100%);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.slide-left-leave-to,
|
|
19
|
+
.slide-right-enter-from {
|
|
20
|
+
transform: translateX(-100%);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.slide-up-enter-from,
|
|
24
|
+
.slide-down-leave-to {
|
|
25
|
+
transform: translateY(100%);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.slide-up-leave-to,
|
|
29
|
+
.slide-down-enter-from {
|
|
30
|
+
transform: translateY(-100%);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Fading */
|
|
34
|
+
.fade-enter-active,
|
|
35
|
+
.fade-leave-active {
|
|
36
|
+
transition: opacity var(--slidev-transition-duration) ease;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.fade-enter-from,
|
|
40
|
+
.fade-leave-to {
|
|
41
|
+
opacity: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.fade-out-leave-active {
|
|
45
|
+
transition: opacity calc(var(--slidev-transition-duration) * 0.6) ease-out;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.fade-out-enter-active {
|
|
49
|
+
transition: opacity calc(var(--slidev-transition-duration) * 0.8) ease-in;
|
|
50
|
+
transition-delay: calc(var(--slidev-transition-duration) * 0.6);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.fade-out-enter-from,
|
|
54
|
+
.fade-out-leave-to {
|
|
55
|
+
opacity: 0;
|
|
56
|
+
}
|
package/styles/vars.css
CHANGED
package/utils.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { RouteRecordRaw } from 'vue-router'
|
|
2
2
|
|
|
3
|
-
export function getSlideClass(route?: RouteRecordRaw) {
|
|
3
|
+
export function getSlideClass(route?: RouteRecordRaw, extra = '') {
|
|
4
|
+
const classes = ['slidev-page', extra]
|
|
5
|
+
|
|
4
6
|
const no = route?.meta?.slide?.no
|
|
5
7
|
if (no != null)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
classes.push(`slidev-page-${no}`)
|
|
9
|
+
|
|
10
|
+
return classes.filter(Boolean).join(' ')
|
|
8
11
|
}
|