@slidev/client 0.48.6 → 0.48.8
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 +14 -6
- package/composables/useNav.ts +15 -7
- package/constants.ts +1 -0
- package/internals/ClicksSlider.vue +10 -7
- package/internals/Goto.vue +2 -2
- package/internals/PresenterMouse.vue +6 -2
- package/internals/PrintSlide.vue +6 -2
- package/package.json +12 -12
- package/pages/print.vue +1 -1
- package/setup/code-runners.ts +6 -2
package/composables/useClicks.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sum } from '@antfu/utils'
|
|
1
|
+
import { clamp, sum } from '@antfu/utils'
|
|
2
2
|
import type { ClicksContext, SlideRoute } from '@slidev/types'
|
|
3
3
|
import type { Ref } from 'vue'
|
|
4
4
|
import { ref, shallowReactive } from 'vue'
|
|
@@ -7,18 +7,21 @@ import { routeForceRefresh } from '../logic/route'
|
|
|
7
7
|
|
|
8
8
|
export function createClicksContextBase(
|
|
9
9
|
current: Ref<number>,
|
|
10
|
-
|
|
10
|
+
clicksStart = 0,
|
|
11
|
+
clicksTotalOverrides?: number,
|
|
11
12
|
): ClicksContext {
|
|
12
13
|
const relativeOffsets: ClicksContext['relativeOffsets'] = new Map()
|
|
13
14
|
const map: ClicksContext['map'] = shallowReactive(new Map())
|
|
14
15
|
|
|
15
16
|
return {
|
|
16
17
|
get current() {
|
|
17
|
-
|
|
18
|
+
// Here we haven't know clicksTotal yet.
|
|
19
|
+
return clamp(+current.value, clicksStart, this.total)
|
|
18
20
|
},
|
|
19
21
|
set current(value) {
|
|
20
|
-
current.value = +value
|
|
22
|
+
current.value = clamp(+value, clicksStart, this.total)
|
|
21
23
|
},
|
|
24
|
+
clicksStart,
|
|
22
25
|
relativeOffsets,
|
|
23
26
|
map,
|
|
24
27
|
onMounted() { },
|
|
@@ -56,7 +59,7 @@ export function createClicksContextBase(
|
|
|
56
59
|
get total() {
|
|
57
60
|
// eslint-disable-next-line no-unused-expressions
|
|
58
61
|
routeForceRefresh.value
|
|
59
|
-
return
|
|
62
|
+
return clicksTotalOverrides ?? Math.max(0, ...[...map.values()].map(v => v.max || 0))
|
|
60
63
|
},
|
|
61
64
|
}
|
|
62
65
|
}
|
|
@@ -65,5 +68,10 @@ export function createFixedClicks(
|
|
|
65
68
|
route?: SlideRoute | undefined,
|
|
66
69
|
currentInit = 0,
|
|
67
70
|
): ClicksContext {
|
|
68
|
-
|
|
71
|
+
const clicksStart = route?.meta.slide?.frontmatter.clicksStart ?? 0
|
|
72
|
+
return createClicksContextBase(
|
|
73
|
+
ref(Math.max(currentInit, clicksStart)),
|
|
74
|
+
clicksStart,
|
|
75
|
+
route?.meta?.clicks,
|
|
76
|
+
)
|
|
69
77
|
}
|
package/composables/useNav.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { useRouter } from 'vue-router'
|
|
|
5
5
|
import type { RouteLocationNormalized, Router } from 'vue-router'
|
|
6
6
|
import { createSharedComposable } from '@vueuse/core'
|
|
7
7
|
import { logicOr } from '@vueuse/math'
|
|
8
|
+
import { clamp } from '@antfu/utils'
|
|
8
9
|
import { getCurrentTransition } from '../logic/transition'
|
|
9
10
|
import { getSlide, getSlidePath } from '../logic/slides'
|
|
10
11
|
import { CLICKS_MAX } from '../constants'
|
|
@@ -33,6 +34,7 @@ export interface SlidevContextNav {
|
|
|
33
34
|
|
|
34
35
|
clicksContext: ComputedRef<ClicksContext>
|
|
35
36
|
clicks: ComputedRef<number>
|
|
37
|
+
clicksStart: ComputedRef<number>
|
|
36
38
|
clicksTotal: ComputedRef<number>
|
|
37
39
|
|
|
38
40
|
/** The table of content tree */
|
|
@@ -99,6 +101,7 @@ export function useNavBase(
|
|
|
99
101
|
const currentLayout = computed(() => currentSlideRoute.value.meta?.layout || (currentSlideNo.value === 1 ? 'cover' : 'default'))
|
|
100
102
|
|
|
101
103
|
const clicks = computed(() => clicksContext.value.current)
|
|
104
|
+
const clicksStart = computed(() => clicksContext.value.clicksStart)
|
|
102
105
|
const clicksTotal = computed(() => clicksContext.value.total)
|
|
103
106
|
const nextRoute = computed(() => slides.value[Math.min(slides.value.length, currentSlideNo.value + 1) - 1])
|
|
104
107
|
const prevRoute = computed(() => slides.value[Math.max(1, currentSlideNo.value - 1) - 1])
|
|
@@ -140,7 +143,7 @@ export function useNavBase(
|
|
|
140
143
|
|
|
141
144
|
async function prev() {
|
|
142
145
|
clicksDirection.value = -1
|
|
143
|
-
if (queryClicks.value <=
|
|
146
|
+
if (queryClicks.value <= clicksStart.value)
|
|
144
147
|
await prevSlide()
|
|
145
148
|
else
|
|
146
149
|
queryClicks.value -= 1
|
|
@@ -177,6 +180,9 @@ export function useNavBase(
|
|
|
177
180
|
skipTransition.value = false
|
|
178
181
|
const pageChanged = currentSlideNo.value !== page
|
|
179
182
|
const clicksChanged = clicks !== queryClicks.value
|
|
183
|
+
const meta = getSlide(page)?.meta
|
|
184
|
+
const clicksStart = meta?.slide?.frontmatter.clicksStart ?? 0
|
|
185
|
+
clicks = clamp(clicks, clicksStart, meta?.__clicksContext?.total ?? CLICKS_MAX)
|
|
180
186
|
if (pageChanged || clicksChanged) {
|
|
181
187
|
await router?.push({
|
|
182
188
|
path: getSlidePath(page, isPresenter.value),
|
|
@@ -202,6 +208,7 @@ export function useNavBase(
|
|
|
202
208
|
prevRoute,
|
|
203
209
|
clicksContext,
|
|
204
210
|
clicks,
|
|
211
|
+
clicksStart,
|
|
205
212
|
clicksTotal,
|
|
206
213
|
hasNext,
|
|
207
214
|
hasPrev,
|
|
@@ -289,24 +296,25 @@ const useNavState = createSharedComposable((): SlidevContextNavState => {
|
|
|
289
296
|
computed({
|
|
290
297
|
get() {
|
|
291
298
|
if (currentSlideNo.value === thisNo)
|
|
292
|
-
return +(queryClicksRaw.value
|
|
299
|
+
return Math.max(+(queryClicksRaw.value ?? 0), context.clicksStart)
|
|
293
300
|
else if (currentSlideNo.value > thisNo)
|
|
294
301
|
return CLICKS_MAX
|
|
295
302
|
else
|
|
296
|
-
return
|
|
303
|
+
return context.clicksStart
|
|
297
304
|
},
|
|
298
305
|
set(v) {
|
|
299
306
|
if (currentSlideNo.value === thisNo)
|
|
300
|
-
queryClicksRaw.value =
|
|
307
|
+
queryClicksRaw.value = clamp(v, context.clicksStart, context.total).toString()
|
|
301
308
|
},
|
|
302
309
|
}),
|
|
303
|
-
route?.meta?.
|
|
310
|
+
route?.meta.slide?.frontmatter.clicksStart ?? 0,
|
|
311
|
+
route?.meta.clicks,
|
|
304
312
|
)
|
|
305
313
|
|
|
306
314
|
// On slide mounted, make sure the query is not greater than the total
|
|
307
315
|
context.onMounted = () => {
|
|
308
|
-
if (
|
|
309
|
-
queryClicksRaw.value =
|
|
316
|
+
if (currentSlideNo.value === thisNo)
|
|
317
|
+
queryClicksRaw.value = clamp(+queryClicksRaw.value, context.clicksStart, context.total).toString()
|
|
310
318
|
}
|
|
311
319
|
|
|
312
320
|
if (route?.meta)
|
package/constants.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { ClicksContext } from '@slidev/types'
|
|
3
|
+
import { clamp, range } from '@antfu/utils'
|
|
3
4
|
import { computed } from 'vue'
|
|
4
5
|
import { CLICKS_MAX } from '../constants'
|
|
5
6
|
|
|
@@ -8,6 +9,8 @@ const props = defineProps<{
|
|
|
8
9
|
}>()
|
|
9
10
|
|
|
10
11
|
const total = computed(() => props.clicksContext.total)
|
|
12
|
+
const start = computed(() => clamp(0, props.clicksContext.clicksStart, total.value))
|
|
13
|
+
const length = computed(() => total.value - start.value + 1)
|
|
11
14
|
const current = computed({
|
|
12
15
|
get() {
|
|
13
16
|
return props.clicksContext.current > total.value ? -1 : props.clicksContext.current
|
|
@@ -18,7 +21,7 @@ const current = computed({
|
|
|
18
21
|
},
|
|
19
22
|
})
|
|
20
23
|
|
|
21
|
-
const
|
|
24
|
+
const clicksRange = computed(() => range(start.value, total.value + 1))
|
|
22
25
|
|
|
23
26
|
function onMousedown() {
|
|
24
27
|
if (current.value < 0 || current.value > total.value)
|
|
@@ -29,8 +32,8 @@ function onMousedown() {
|
|
|
29
32
|
<template>
|
|
30
33
|
<div
|
|
31
34
|
class="flex gap-1 items-center select-none"
|
|
32
|
-
:title="`Clicks in this slide: ${
|
|
33
|
-
:class="
|
|
35
|
+
:title="`Clicks in this slide: ${length}`"
|
|
36
|
+
:class="length ? '' : 'op50'"
|
|
34
37
|
>
|
|
35
38
|
<div class="flex gap-0.5 items-center min-w-16 font-mono mr1">
|
|
36
39
|
<carbon:cursor-1 text-sm op50 />
|
|
@@ -46,13 +49,13 @@ function onMousedown() {
|
|
|
46
49
|
@dblclick="current = clicksContext.total"
|
|
47
50
|
>
|
|
48
51
|
<div
|
|
49
|
-
v-for="i of
|
|
52
|
+
v-for="i of clicksRange" :key="i"
|
|
50
53
|
border="y main" of-hidden relative
|
|
51
54
|
:class="[
|
|
52
55
|
i === 0 ? 'rounded-l border-l' : '',
|
|
53
56
|
i === total ? 'rounded-r border-r' : '',
|
|
54
57
|
]"
|
|
55
|
-
:style="{ width:
|
|
58
|
+
:style="{ width: length > 0 ? `${1 / length * 100}%` : '100%' }"
|
|
56
59
|
>
|
|
57
60
|
<div absolute inset-0 :class="i <= current ? 'bg-primary op15' : ''" />
|
|
58
61
|
<div
|
|
@@ -69,8 +72,8 @@ function onMousedown() {
|
|
|
69
72
|
<input
|
|
70
73
|
v-model="current"
|
|
71
74
|
class="range" absolute inset-0
|
|
72
|
-
type="range" :min="
|
|
73
|
-
:style="{ '--thumb-width': `${1 / (
|
|
75
|
+
type="range" :min="start" :max="total" :step="1" z-10 op0
|
|
76
|
+
:style="{ '--thumb-width': `${1 / (length + 1) * 100}%` }"
|
|
74
77
|
@mousedown="onMousedown"
|
|
75
78
|
@focus="event => (event.currentTarget as HTMLElement)?.blur()"
|
|
76
79
|
>
|
package/internals/Goto.vue
CHANGED
|
@@ -3,7 +3,7 @@ import { computed, ref, watch } from 'vue'
|
|
|
3
3
|
import Fuse from 'fuse.js'
|
|
4
4
|
import { activeElement, showGotoDialog } from '../state'
|
|
5
5
|
import { useNav } from '../composables/useNav'
|
|
6
|
-
import
|
|
6
|
+
import TitleRenderer from '#slidev/title-renderer'
|
|
7
7
|
|
|
8
8
|
const container = ref<HTMLDivElement>()
|
|
9
9
|
const input = ref<HTMLInputElement>()
|
|
@@ -161,7 +161,7 @@ watch(activeElement, () => {
|
|
|
161
161
|
<div w-4 text-right op50 text-sm>
|
|
162
162
|
{{ item.no }}
|
|
163
163
|
</div>
|
|
164
|
-
<
|
|
164
|
+
<TitleRenderer :no="item.no" />
|
|
165
165
|
</li>
|
|
166
166
|
</ul>
|
|
167
167
|
</div>
|
|
@@ -8,8 +8,12 @@ import { sharedState } from '../state/shared'
|
|
|
8
8
|
class="absolute top-0 left-0 right-0 bottom-0 pointer-events-none text-xl"
|
|
9
9
|
>
|
|
10
10
|
<ph-cursor-fill
|
|
11
|
-
class="absolute"
|
|
12
|
-
:style="{
|
|
11
|
+
class="absolute stroke-white dark:stroke-black"
|
|
12
|
+
:style="{
|
|
13
|
+
left: `${sharedState.cursor.x}%`,
|
|
14
|
+
top: `${sharedState.cursor.y}%`,
|
|
15
|
+
strokeWidth: 16,
|
|
16
|
+
}"
|
|
13
17
|
/>
|
|
14
18
|
</div>
|
|
15
19
|
</template>
|
package/internals/PrintSlide.vue
CHANGED
|
@@ -16,10 +16,14 @@ const clicks0 = createFixedClicks(route, isPrintWithClicks.value ? 0 : CLICKS_MA
|
|
|
16
16
|
:nav="useFixedNav(route, clicks0)"
|
|
17
17
|
/>
|
|
18
18
|
<template v-if="isPrintWithClicks">
|
|
19
|
+
<!--
|
|
20
|
+
clicks0.total can be any number >=0 when rendering.
|
|
21
|
+
So total-clicksStart can be negative in intermediate states.
|
|
22
|
+
-->
|
|
19
23
|
<PrintSlideClick
|
|
20
|
-
v-for="i
|
|
24
|
+
v-for="i in Math.max(0, clicks0.total - clicks0.clicksStart)"
|
|
21
25
|
:key="i"
|
|
22
|
-
:nav="useFixedNav(route, createFixedClicks(route, i))"
|
|
26
|
+
:nav="useFixedNav(route, createFixedClicks(route, i + clicks0.clicksStart))"
|
|
23
27
|
/>
|
|
24
28
|
</template>
|
|
25
29
|
</template>
|
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.8",
|
|
5
5
|
"description": "Presentation slides for developers",
|
|
6
6
|
"author": "antfu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"@iconify-json/carbon": "^1.1.31",
|
|
33
33
|
"@iconify-json/ph": "^1.1.11",
|
|
34
34
|
"@iconify-json/svg-spinners": "^1.1.2",
|
|
35
|
-
"@shikijs/monaco": "^1.1
|
|
36
|
-
"@shikijs/vitepress-twoslash": "^1.1
|
|
35
|
+
"@shikijs/monaco": "^1.2.1",
|
|
36
|
+
"@shikijs/vitepress-twoslash": "^1.2.1",
|
|
37
37
|
"@slidev/rough-notation": "^0.1.0",
|
|
38
38
|
"@typescript/ata": "^0.9.4",
|
|
39
|
-
"@unhead/vue": "^1.
|
|
40
|
-
"@unocss/reset": "^0.58.
|
|
39
|
+
"@unhead/vue": "^1.9.3",
|
|
40
|
+
"@unocss/reset": "^0.58.8",
|
|
41
41
|
"@vueuse/core": "^10.9.0",
|
|
42
42
|
"@vueuse/math": "^10.9.0",
|
|
43
43
|
"@vueuse/motion": "^2.1.0",
|
|
@@ -47,23 +47,23 @@
|
|
|
47
47
|
"floating-vue": "^5.2.2",
|
|
48
48
|
"fuse.js": "^7.0.0",
|
|
49
49
|
"js-yaml": "^4.1.0",
|
|
50
|
-
"katex": "^0.16.
|
|
50
|
+
"katex": "^0.16.10",
|
|
51
51
|
"lz-string": "^1.5.0",
|
|
52
52
|
"mermaid": "^10.9.0",
|
|
53
53
|
"monaco-editor": "^0.47.0",
|
|
54
54
|
"prettier": "^3.2.5",
|
|
55
55
|
"recordrtc": "^5.6.2",
|
|
56
|
-
"shiki": "^1.1
|
|
56
|
+
"shiki": "^1.2.1",
|
|
57
57
|
"shiki-magic-move": "^0.3.4",
|
|
58
|
-
"typescript": "^5.4.
|
|
59
|
-
"unocss": "^0.58.
|
|
58
|
+
"typescript": "^5.4.3",
|
|
59
|
+
"unocss": "^0.58.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.8",
|
|
64
|
+
"@slidev/types": "0.48.8"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"vite": "^5.
|
|
67
|
+
"vite": "^5.2.7"
|
|
68
68
|
}
|
|
69
69
|
}
|
package/pages/print.vue
CHANGED
|
@@ -28,8 +28,8 @@ onMounted(() => {
|
|
|
28
28
|
:style="{ background: 'var(--slidev-slide-container-background, black)' }"
|
|
29
29
|
:width="windowSize.width.value"
|
|
30
30
|
/>
|
|
31
|
+
<div id="twoslash-container" />
|
|
31
32
|
</div>
|
|
32
|
-
<div id="twoslash-container" />
|
|
33
33
|
</template>
|
|
34
34
|
|
|
35
35
|
<style lang="postcss">
|
package/setup/code-runners.ts
CHANGED
|
@@ -144,9 +144,13 @@ export async function runJavaScript(code: string): Promise<CodeRunnerOutputs> {
|
|
|
144
144
|
return textRep
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
// The reflect-metadata runtime is available, so allow that to go through
|
|
148
147
|
function sanitizeJS(code: string) {
|
|
149
|
-
|
|
148
|
+
// The reflect-metadata runtime is available, so allow that to go through
|
|
149
|
+
code = code.replace(`import "reflect-metadata"`, '').replace(`require("reflect-metadata")`, '')
|
|
150
|
+
// Transpiled typescript sometimes contains an empty export, remove it.
|
|
151
|
+
code = code.replace('export {};', '')
|
|
152
|
+
|
|
153
|
+
return code
|
|
150
154
|
}
|
|
151
155
|
|
|
152
156
|
return allLogs
|