@slidev/client 0.48.1 → 0.48.2
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/composables/useClicks.ts +2 -1
- package/composables/useNav.ts +12 -8
- package/composables/useViewTransition.ts +12 -18
- package/internals/ClicksSlider.vue +5 -5
- package/internals/PrintSlide.vue +3 -2
- package/logic/route.ts +4 -1
- package/logic/transition.ts +1 -1
- package/modules/v-mark.ts +5 -11
- package/package.json +3 -3
- package/pages/overview.vue +31 -26
package/composables/useClicks.ts
CHANGED
|
@@ -68,6 +68,7 @@ export function createClicksContextBase(
|
|
|
68
68
|
export function createFixedClicks(
|
|
69
69
|
route?: SlideRoute | undefined,
|
|
70
70
|
currentInit = 0,
|
|
71
|
+
isDisabled?: () => boolean,
|
|
71
72
|
): ClicksContext {
|
|
72
|
-
return createClicksContextBase(ref(currentInit), route?.meta?.clicks)
|
|
73
|
+
return createClicksContextBase(ref(currentInit), route?.meta?.clicks, isDisabled)
|
|
73
74
|
}
|
package/composables/useNav.ts
CHANGED
|
@@ -170,15 +170,19 @@ export function useNavBase(
|
|
|
170
170
|
return go(total.value)
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
async function go(page: number | string, clicks
|
|
173
|
+
async function go(page: number | string, clicks: number = 0) {
|
|
174
174
|
skipTransition.value = false
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
175
|
+
const pageChanged = currentSlideNo.value !== page
|
|
176
|
+
const clicksChanged = clicks !== queryClicks.value
|
|
177
|
+
if (pageChanged || clicksChanged) {
|
|
178
|
+
await router?.push({
|
|
179
|
+
path: getSlidePath(page, isPresenter.value),
|
|
180
|
+
query: {
|
|
181
|
+
...router.currentRoute.value.query,
|
|
182
|
+
clicks: clicks === 0 ? undefined : clicks.toString(),
|
|
183
|
+
},
|
|
184
|
+
})
|
|
185
|
+
}
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ref } from 'vue'
|
|
2
2
|
import { useRouter } from 'vue-router'
|
|
3
3
|
import { getSlide } from '../logic/slides'
|
|
4
|
+
import { configs } from '../env'
|
|
4
5
|
|
|
5
6
|
export function useViewTransition() {
|
|
6
7
|
const router = useRouter()
|
|
@@ -16,14 +17,9 @@ export function useViewTransition() {
|
|
|
16
17
|
const toMeta = getSlide(to.params.no as string)?.meta
|
|
17
18
|
const fromNo = fromMeta?.slide?.no
|
|
18
19
|
const toNo = toMeta?.slide?.no
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
(fromMeta?.transition === 'view-transition' && fromNo < toNo)
|
|
23
|
-
|| (toMeta?.transition === 'view-transition' && toNo < fromNo)
|
|
24
|
-
)
|
|
25
|
-
)
|
|
26
|
-
) {
|
|
20
|
+
const transitionType = fromNo != null && toNo != null
|
|
21
|
+
&& ((fromNo < toNo ? fromMeta?.transition : toMeta?.transition) ?? configs.transition)
|
|
22
|
+
if (transitionType !== 'view-transition') {
|
|
27
23
|
isViewTransition.value = false
|
|
28
24
|
return
|
|
29
25
|
}
|
|
@@ -43,17 +39,15 @@ export function useViewTransition() {
|
|
|
43
39
|
let changeRoute: () => void
|
|
44
40
|
const ready = new Promise<void>(resolve => (changeRoute = resolve))
|
|
45
41
|
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
// Wait for `TransitionGroup` to become normal `div`
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
// @ts-expect-error missing types
|
|
45
|
+
document.startViewTransition(() => {
|
|
46
|
+
changeRoute()
|
|
47
|
+
return promise
|
|
48
|
+
})
|
|
49
|
+
}, 50)
|
|
52
50
|
|
|
53
|
-
transition.finished.then(() => {
|
|
54
|
-
viewTransitionAbort = undefined
|
|
55
|
-
viewTransitionFinish = undefined
|
|
56
|
-
})
|
|
57
51
|
return ready
|
|
58
52
|
})
|
|
59
53
|
|
|
@@ -28,21 +28,21 @@ function onMousedown() {
|
|
|
28
28
|
|
|
29
29
|
<template>
|
|
30
30
|
<div
|
|
31
|
-
class="flex gap-
|
|
31
|
+
class="flex gap-1 items-center select-none"
|
|
32
32
|
:title="`Clicks in this slide: ${total}`"
|
|
33
33
|
:class="total ? '' : 'op50'"
|
|
34
34
|
>
|
|
35
|
-
<div class="flex gap-
|
|
35
|
+
<div class="flex gap-0.5 items-center min-w-16 font-mono mr1">
|
|
36
36
|
<carbon:cursor-1 text-sm op50 />
|
|
37
|
+
<div flex-auto />
|
|
37
38
|
<template v-if="current >= 0 && current !== CLICKS_MAX">
|
|
38
|
-
<div flex-auto />
|
|
39
39
|
<span text-primary>{{ current }}</span>
|
|
40
40
|
<span op25>/</span>
|
|
41
41
|
</template>
|
|
42
42
|
<span op50>{{ total }}</span>
|
|
43
43
|
</div>
|
|
44
44
|
<div
|
|
45
|
-
relative flex-auto h5 flex="~"
|
|
45
|
+
relative flex-auto h5 font-mono flex="~"
|
|
46
46
|
@dblclick="current = clicksContext.total"
|
|
47
47
|
>
|
|
48
48
|
<div
|
|
@@ -54,7 +54,7 @@ function onMousedown() {
|
|
|
54
54
|
]"
|
|
55
55
|
:style="{ width: total > 0 ? `${1 / total * 100}%` : '100%' }"
|
|
56
56
|
>
|
|
57
|
-
<div absolute inset-0 :class="i <= current ? 'bg-primary
|
|
57
|
+
<div absolute inset-0 :class="i <= current ? 'bg-primary op15' : ''" />
|
|
58
58
|
<div
|
|
59
59
|
:class="[
|
|
60
60
|
+i === +current ? 'text-primary font-bold op100 border-primary' : 'op30 border-main',
|
package/internals/PrintSlide.vue
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { SlideRoute } from '@slidev/types'
|
|
3
|
-
import { useFixedNav } from '../composables/useNav'
|
|
3
|
+
import { useFixedNav, useNav } from '../composables/useNav'
|
|
4
4
|
import { createFixedClicks } from '../composables/useClicks'
|
|
5
5
|
import PrintSlideClick from './PrintSlideClick.vue'
|
|
6
6
|
|
|
7
7
|
const { route } = defineProps<{ route: SlideRoute }>()
|
|
8
|
-
const
|
|
8
|
+
const { isPrintWithClicks } = useNav()
|
|
9
|
+
const clicks0 = createFixedClicks(route, 0, () => !isPrintWithClicks.value)
|
|
9
10
|
</script>
|
|
10
11
|
|
|
11
12
|
<template>
|
package/logic/route.ts
CHANGED
|
@@ -22,6 +22,9 @@ export function useRouteQuery<T extends string | string[]>(
|
|
|
22
22
|
},
|
|
23
23
|
set(v) {
|
|
24
24
|
nextTick(() => {
|
|
25
|
+
const oldValue = router.currentRoute.value.query[name]
|
|
26
|
+
if ((oldValue ?? defaultValue?.toString()) === v.toString())
|
|
27
|
+
return
|
|
25
28
|
router[unref(mode) as 'replace' | 'push']({
|
|
26
29
|
query: {
|
|
27
30
|
...router.currentRoute.value.query,
|
|
@@ -30,7 +33,7 @@ export function useRouteQuery<T extends string | string[]>(
|
|
|
30
33
|
})
|
|
31
34
|
})
|
|
32
35
|
},
|
|
33
|
-
})
|
|
36
|
+
})
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
// force update collected elements when the route is fully resolved
|
package/logic/transition.ts
CHANGED
|
@@ -9,7 +9,7 @@ const transitionResolveMap: Record<string, string | undefined> = {
|
|
|
9
9
|
'slide-down': 'slide-down | slide-up',
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
function resolveTransition(transition?: string | TransitionGroupProps, isBackward = false): TransitionGroupProps | undefined {
|
|
13
13
|
if (!transition)
|
|
14
14
|
return undefined
|
|
15
15
|
if (typeof transition === 'string') {
|
package/modules/v-mark.ts
CHANGED
|
@@ -116,7 +116,8 @@ export function createVMarkDirective() {
|
|
|
116
116
|
|
|
117
117
|
const resolvedClick = resolveClick(el, binding, options.value.at)
|
|
118
118
|
if (!resolvedClick) {
|
|
119
|
-
|
|
119
|
+
// No click animation, just show the mark
|
|
120
|
+
annotation.show()
|
|
120
121
|
return
|
|
121
122
|
}
|
|
122
123
|
|
|
@@ -130,19 +131,12 @@ export function createVMarkDirective() {
|
|
|
130
131
|
|
|
131
132
|
const at = options.value.at
|
|
132
133
|
|
|
133
|
-
if (at === true)
|
|
134
|
+
if (at === true)
|
|
134
135
|
shouldShow = true
|
|
135
|
-
|
|
136
|
-
else if (at === false) {
|
|
136
|
+
else if (at === false)
|
|
137
137
|
shouldShow = false
|
|
138
|
-
|
|
139
|
-
else if (resolvedClick) {
|
|
138
|
+
else
|
|
140
139
|
shouldShow = resolvedClick.isActive.value
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
console.error('[Slidev] Invalid value for v-mark:', at)
|
|
144
|
-
return
|
|
145
|
-
}
|
|
146
140
|
|
|
147
141
|
if (shouldShow == null)
|
|
148
142
|
return
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/client",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.48.
|
|
4
|
+
"version": "0.48.2",
|
|
5
5
|
"description": "Presentation slides for developers",
|
|
6
6
|
"author": "antfu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"vue": "^3.4.21",
|
|
61
61
|
"vue-demi": "^0.14.7",
|
|
62
62
|
"vue-router": "^4.3.0",
|
|
63
|
-
"@slidev/parser": "0.48.
|
|
64
|
-
"@slidev/types": "0.48.
|
|
63
|
+
"@slidev/parser": "0.48.2",
|
|
64
|
+
"@slidev/types": "0.48.2"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"vite": "^5.1.5"
|
package/pages/overview.vue
CHANGED
|
@@ -100,37 +100,42 @@ onMounted(() => {
|
|
|
100
100
|
|
|
101
101
|
<template>
|
|
102
102
|
<div class="h-screen w-screen of-hidden flex">
|
|
103
|
-
<nav class="
|
|
104
|
-
<div class="
|
|
105
|
-
<div
|
|
106
|
-
v-for="(route, idx) of slides"
|
|
107
|
-
:key="route.no"
|
|
108
|
-
class="relative"
|
|
109
|
-
>
|
|
110
|
-
<button
|
|
111
|
-
class="relative transition duration-300 w-8 h-8 rounded hover:bg-active hover:op100"
|
|
112
|
-
:class="activeBlocks.includes(idx) ? 'op100 text-primary bg-gray:5' : 'op20'"
|
|
113
|
-
@click="scrollToSlide(idx)"
|
|
114
|
-
>
|
|
115
|
-
<div>{{ idx + 1 }}</div>
|
|
116
|
-
</button>
|
|
103
|
+
<nav class="grid grid-rows-[auto_max-content] border-r border-main select-none max-h-full h-full">
|
|
104
|
+
<div class="relative">
|
|
105
|
+
<div class="absolute left-0 top-0 bottom-0 w-200 flex flex-col flex-auto items-end group p2 gap-1 max-h-full of-scroll" style="direction:rtl">
|
|
117
106
|
<div
|
|
118
|
-
v-
|
|
119
|
-
|
|
120
|
-
|
|
107
|
+
v-for="(route, idx) of slides"
|
|
108
|
+
:key="route.no"
|
|
109
|
+
class="relative"
|
|
110
|
+
style="direction:ltr"
|
|
121
111
|
>
|
|
122
|
-
|
|
112
|
+
<button
|
|
113
|
+
class="relative transition duration-300 w-8 h-8 rounded hover:bg-active hover:op100"
|
|
114
|
+
:class="activeBlocks.includes(idx) ? 'op100 text-primary bg-gray:5' : 'op20'"
|
|
115
|
+
@click="scrollToSlide(idx)"
|
|
116
|
+
>
|
|
117
|
+
<div>{{ idx + 1 }}</div>
|
|
118
|
+
</button>
|
|
119
|
+
<div
|
|
120
|
+
v-if="route.meta?.slide?.title"
|
|
121
|
+
class="pointer-events-none select-none absolute left-110% backdrop-blur-8 top-50% translate-y--50% ws-nowrap z-10 px2 shadow-xl rounded border border-main transition duration-400 op0 group-hover:op100"
|
|
122
|
+
:class="activeBlocks.includes(idx) ? 'text-primary' : 'text-main important-text-op-50'"
|
|
123
|
+
>
|
|
124
|
+
{{ route.meta?.slide?.title }}
|
|
125
|
+
</div>
|
|
123
126
|
</div>
|
|
124
127
|
</div>
|
|
125
128
|
</div>
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
<div p2 border="t main">
|
|
130
|
+
<IconButton
|
|
131
|
+
v-if="!isColorSchemaConfigured"
|
|
132
|
+
:title="isDark ? 'Switch to light mode theme' : 'Switch to dark mode theme'"
|
|
133
|
+
@click="toggleDark()"
|
|
134
|
+
>
|
|
135
|
+
<carbon-moon v-if="isDark" />
|
|
136
|
+
<carbon-sun v-else />
|
|
137
|
+
</IconButton>
|
|
138
|
+
</div>
|
|
134
139
|
</nav>
|
|
135
140
|
<main
|
|
136
141
|
class="flex-1 h-full of-auto"
|