@slidev/client 52.17.2 → 52.18.1
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/Monaco.vue +5 -2
- package/composables/useNav.test.ts +130 -0
- package/composables/useNav.ts +20 -4
- package/internals/TitleIcon.vue +1 -1
- package/package.json +12 -12
- package/setup/monaco.ts +8 -8
- package/shim.d.ts +15 -1
package/builtin/Monaco.vue
CHANGED
|
@@ -20,6 +20,7 @@ import lz from 'lz-string'
|
|
|
20
20
|
import { computed, defineAsyncComponent, nextTick, onMounted, ref } from 'vue'
|
|
21
21
|
import { useNav } from '../composables/useNav'
|
|
22
22
|
import { useSlideContext } from '../context'
|
|
23
|
+
import { configs } from '../env'
|
|
23
24
|
import { makeId } from '../logic/utils'
|
|
24
25
|
|
|
25
26
|
const props = withDefaults(
|
|
@@ -28,6 +29,7 @@ const props = withDefaults(
|
|
|
28
29
|
diffLz?: string
|
|
29
30
|
lang?: string
|
|
30
31
|
readonly?: boolean
|
|
32
|
+
lines?: boolean
|
|
31
33
|
lineNumbers?: 'on' | 'off' | 'relative' | 'interval'
|
|
32
34
|
height?: number | string // Posible values: 'initial', 'auto', '100%', '200px', etc.
|
|
33
35
|
editorOptions?: monaco.editor.IEditorOptions
|
|
@@ -44,7 +46,7 @@ const props = withDefaults(
|
|
|
44
46
|
codeLz: '',
|
|
45
47
|
lang: 'typescript',
|
|
46
48
|
readonly: false,
|
|
47
|
-
|
|
49
|
+
lines: configs.lineNumbers,
|
|
48
50
|
height: 'initial',
|
|
49
51
|
ata: true,
|
|
50
52
|
runnable: false,
|
|
@@ -58,6 +60,7 @@ const CodeRunner = defineAsyncComponent(() => import('../internals/CodeRunner.vu
|
|
|
58
60
|
const code = ref(lz.decompressFromBase64(props.codeLz).trimEnd())
|
|
59
61
|
const diff = props.diffLz && ref(lz.decompressFromBase64(props.diffLz).trimEnd())
|
|
60
62
|
const isWritable = computed(() => props.writable && !props.readonly && __DEV__)
|
|
63
|
+
const lineNumbers = props.lineNumbers ?? (props.lines ? 'on' : 'off')
|
|
61
64
|
|
|
62
65
|
const langMap: Record<string, string> = {
|
|
63
66
|
ts: 'typescript',
|
|
@@ -106,7 +109,7 @@ onMounted(async () => {
|
|
|
106
109
|
const commonOptions = {
|
|
107
110
|
automaticLayout: true,
|
|
108
111
|
readOnly: props.readonly,
|
|
109
|
-
lineNumbers
|
|
112
|
+
lineNumbers,
|
|
110
113
|
minimap: { enabled: false },
|
|
111
114
|
overviewRulerBorder: false,
|
|
112
115
|
overviewRulerLanes: 0,
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { ClicksContext, SlideRoute } from '@slidev/types'
|
|
2
|
+
import type { SlidevContextNav } from './useNav'
|
|
3
|
+
import { renderToString } from '@vue/server-renderer'
|
|
4
|
+
import { provideLocal } from '@vueuse/core'
|
|
5
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
6
|
+
import { computed, createSSRApp, defineComponent, h, reactive, ref } from 'vue'
|
|
7
|
+
import { injectionSlidevContext } from '../constants'
|
|
8
|
+
import { useNav, useNavBase } from './useNav'
|
|
9
|
+
|
|
10
|
+
vi.mock('#slidev/slides', async () => {
|
|
11
|
+
const { ref } = await import('vue')
|
|
12
|
+
return {
|
|
13
|
+
slides: ref([
|
|
14
|
+
{
|
|
15
|
+
no: 1,
|
|
16
|
+
meta: {
|
|
17
|
+
slide: { frontmatter: { title: 'First' } },
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
no: 2,
|
|
22
|
+
meta: {
|
|
23
|
+
slide: { frontmatter: { title: 'Second' } },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
]),
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
vi.mock('../env', async () => {
|
|
31
|
+
const { ref } = await import('vue')
|
|
32
|
+
return {
|
|
33
|
+
configs: { remote: false },
|
|
34
|
+
slideAspect: ref(16 / 9),
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
vi.mock('../state', async () => {
|
|
39
|
+
const { ref } = await import('vue')
|
|
40
|
+
return { hmrSkipTransition: ref(false) }
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
vi.mock('vue-router', async () => {
|
|
44
|
+
const { reactive, ref } = await import('vue')
|
|
45
|
+
const route = reactive({
|
|
46
|
+
name: 'export',
|
|
47
|
+
params: { no: '1' },
|
|
48
|
+
query: {},
|
|
49
|
+
})
|
|
50
|
+
const router = {
|
|
51
|
+
currentRoute: ref(route),
|
|
52
|
+
push: vi.fn(),
|
|
53
|
+
replace: vi.fn(),
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
useRoute: () => route,
|
|
57
|
+
useRouter: () => router,
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
function route(no: number, frontmatter: Record<string, any>): SlideRoute {
|
|
62
|
+
return {
|
|
63
|
+
no,
|
|
64
|
+
meta: {
|
|
65
|
+
slide: { frontmatter },
|
|
66
|
+
},
|
|
67
|
+
} as unknown as SlideRoute
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
describe('useNavBase', () => {
|
|
71
|
+
it('exposes reactive frontmatter for the current slide', () => {
|
|
72
|
+
const currentRoute = ref(route(1, { title: 'Intro', section: 'start' }))
|
|
73
|
+
const nav = useNavBase(
|
|
74
|
+
computed(() => currentRoute.value),
|
|
75
|
+
computed(() => ({ current: 0, clicksStart: 0, total: 0 }) as ClicksContext),
|
|
76
|
+
ref(0),
|
|
77
|
+
ref(false),
|
|
78
|
+
ref(false),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
expect(nav.currentFrontmatter.value).toEqual({
|
|
82
|
+
title: 'Intro',
|
|
83
|
+
section: 'start',
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
currentRoute.value = route(2, { title: 'Details', section: 'body' })
|
|
87
|
+
|
|
88
|
+
expect(nav.currentFrontmatter.value).toEqual({
|
|
89
|
+
title: 'Details',
|
|
90
|
+
section: 'body',
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('uses the slide-local navigation context while rendering exported slides', async () => {
|
|
95
|
+
vi.stubGlobal('location', { search: '' })
|
|
96
|
+
let observedNav: SlidevContextNav | undefined
|
|
97
|
+
const localNav = {
|
|
98
|
+
currentSlideNo: computed(() => 2),
|
|
99
|
+
currentPage: computed(() => 2),
|
|
100
|
+
currentSlideRoute: computed(() => route(2, { title: 'Second' })),
|
|
101
|
+
tocTree: computed(() => [
|
|
102
|
+
{ no: 1, active: false },
|
|
103
|
+
{ no: 2, active: true },
|
|
104
|
+
]),
|
|
105
|
+
} as unknown as SlidevContextNav
|
|
106
|
+
|
|
107
|
+
const Child = defineComponent({
|
|
108
|
+
setup() {
|
|
109
|
+
observedNav = useNav()
|
|
110
|
+
return () => h('span')
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
const App = defineComponent({
|
|
114
|
+
setup() {
|
|
115
|
+
provideLocal(injectionSlidevContext, reactive({
|
|
116
|
+
nav: localNav,
|
|
117
|
+
configs: {},
|
|
118
|
+
themeConfigs: {},
|
|
119
|
+
}) as any)
|
|
120
|
+
return () => h(Child)
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
await renderToString(createSSRApp(App))
|
|
125
|
+
|
|
126
|
+
expect(observedNav?.currentSlideNo.value).toBe(2)
|
|
127
|
+
expect(observedNav?.currentSlideRoute.value.meta.slide.frontmatter.title).toBe('Second')
|
|
128
|
+
expect(observedNav?.tocTree.value[1].active).toBe(true)
|
|
129
|
+
})
|
|
130
|
+
})
|
package/composables/useNav.ts
CHANGED
|
@@ -3,11 +3,11 @@ import type { ComputedRef, Ref, TransitionGroupProps, WritableComputedRef } from
|
|
|
3
3
|
import type { RouteLocationNormalized, Router } from 'vue-router'
|
|
4
4
|
import { clamp } from '@antfu/utils'
|
|
5
5
|
import { parseRangeString } from '@slidev/parser/utils'
|
|
6
|
-
import { createSharedComposable } from '@vueuse/core'
|
|
7
|
-
import { computed, ref, watch } from 'vue'
|
|
6
|
+
import { createSharedComposable, injectLocal } from '@vueuse/core'
|
|
7
|
+
import { computed, ref, toRaw, watch } from 'vue'
|
|
8
8
|
import { useRoute, useRouter } from 'vue-router'
|
|
9
9
|
import { slides } from '#slidev/slides'
|
|
10
|
-
import { CLICKS_MAX } from '../constants'
|
|
10
|
+
import { CLICKS_MAX, injectionSlidevContext } from '../constants'
|
|
11
11
|
import { configs } from '../env'
|
|
12
12
|
import { useRouteQuery } from '../logic/route'
|
|
13
13
|
import { getSlide, getSlidePath } from '../logic/slides'
|
|
@@ -26,6 +26,7 @@ export interface SlidevContextNav {
|
|
|
26
26
|
currentSlideRoute: ComputedRef<SlideRoute>
|
|
27
27
|
currentTransition: ComputedRef<TransitionGroupProps | undefined>
|
|
28
28
|
currentLayout: ComputedRef<string>
|
|
29
|
+
currentFrontmatter: ComputedRef<Record<string, any>>
|
|
29
30
|
|
|
30
31
|
nextRoute: ComputedRef<SlideRoute>
|
|
31
32
|
prevRoute: ComputedRef<SlideRoute>
|
|
@@ -105,6 +106,7 @@ export function useNavBase(
|
|
|
105
106
|
const currentPath = computed(() => getSlidePath(currentSlideRoute.value, isPresenter.value))
|
|
106
107
|
const currentSlideNo = computed(() => currentSlideRoute.value.no)
|
|
107
108
|
const currentLayout = computed(() => currentSlideRoute.value.meta?.layout || (currentSlideNo.value === 1 ? 'cover' : 'default'))
|
|
109
|
+
const currentFrontmatter = computed(() => currentSlideRoute.value.meta.slide.frontmatter)
|
|
108
110
|
|
|
109
111
|
const clicks = computed(() => clicksContext.value.current)
|
|
110
112
|
const clicksStart = computed(() => clicksContext.value.clicksStart)
|
|
@@ -223,6 +225,7 @@ export function useNavBase(
|
|
|
223
225
|
currentPage: currentSlideNo,
|
|
224
226
|
currentSlideRoute,
|
|
225
227
|
currentLayout,
|
|
228
|
+
currentFrontmatter,
|
|
226
229
|
currentTransition,
|
|
227
230
|
clicksDirection,
|
|
228
231
|
nextRoute,
|
|
@@ -362,7 +365,7 @@ const useNavState = createSharedComposable((): SlidevContextNavState => {
|
|
|
362
365
|
}
|
|
363
366
|
})
|
|
364
367
|
|
|
365
|
-
|
|
368
|
+
const useSharedNav = createSharedComposable((): SlidevContextNavFull => {
|
|
366
369
|
const state = useNavState()
|
|
367
370
|
const router = useRouter()
|
|
368
371
|
|
|
@@ -398,3 +401,16 @@ export const useNav = createSharedComposable((): SlidevContextNavFull => {
|
|
|
398
401
|
...state,
|
|
399
402
|
}
|
|
400
403
|
})
|
|
404
|
+
|
|
405
|
+
export function useNav(): SlidevContextNavFull {
|
|
406
|
+
const nav = useSharedNav()
|
|
407
|
+
const context = injectLocal(injectionSlidevContext, undefined)
|
|
408
|
+
if (!context)
|
|
409
|
+
return nav
|
|
410
|
+
|
|
411
|
+
const localNav = toRaw(context).nav as unknown as SlidevContextNav
|
|
412
|
+
return {
|
|
413
|
+
...nav,
|
|
414
|
+
...localNav,
|
|
415
|
+
}
|
|
416
|
+
}
|
package/internals/TitleIcon.vue
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/client",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "52.
|
|
4
|
+
"version": "52.18.1",
|
|
5
5
|
"description": "Presentation slides for developers",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -39,36 +39,36 @@
|
|
|
39
39
|
"@shikijs/vitepress-twoslash": "^4.3.1",
|
|
40
40
|
"@slidev/rough-notation": "^0.1.0",
|
|
41
41
|
"@typescript/ata": "^0.9.8",
|
|
42
|
-
"@unhead/vue": "^3.
|
|
42
|
+
"@unhead/vue": "^3.2.3",
|
|
43
43
|
"@unocss/extractor-mdc": "^66.7.5",
|
|
44
44
|
"@unocss/preset-mini": "^66.7.5",
|
|
45
45
|
"@unocss/reset": "^66.7.5",
|
|
46
|
-
"@vueuse/core": "^14.
|
|
47
|
-
"@vueuse/math": "^14.
|
|
46
|
+
"@vueuse/core": "^14.4.0",
|
|
47
|
+
"@vueuse/math": "^14.4.0",
|
|
48
48
|
"@vueuse/motion": "^3.0.3",
|
|
49
49
|
"ansis": "^4.3.1",
|
|
50
50
|
"drauu": "^1.0.0",
|
|
51
51
|
"file-saver": "^2.0.5",
|
|
52
52
|
"fitty": "^2.4.2",
|
|
53
53
|
"floating-vue": "^5.2.2",
|
|
54
|
-
"fuse.js": "^7.
|
|
55
|
-
"katex": "^0.
|
|
54
|
+
"fuse.js": "^7.5.0",
|
|
55
|
+
"katex": "^0.18.1",
|
|
56
56
|
"lz-string": "^1.5.0",
|
|
57
57
|
"mermaid": "^11.16.0",
|
|
58
|
-
"monaco-editor": "^0.
|
|
58
|
+
"monaco-editor": "^0.56.0",
|
|
59
59
|
"nanotar": "^0.3.0",
|
|
60
60
|
"pptxgenjs": "^4.0.1",
|
|
61
61
|
"recordrtc": "^5.6.2",
|
|
62
62
|
"shiki": "^4.3.1",
|
|
63
63
|
"typescript": "^6.0.3",
|
|
64
64
|
"unocss": "^66.7.5",
|
|
65
|
-
"vue": "^3.5.
|
|
66
|
-
"vue-router": "^5.
|
|
65
|
+
"vue": "^3.5.40",
|
|
66
|
+
"vue-router": "^5.2.0",
|
|
67
67
|
"yaml": "^2.9.0",
|
|
68
|
-
"@slidev/parser": "52.
|
|
69
|
-
"@slidev/types": "52.
|
|
68
|
+
"@slidev/parser": "52.18.1",
|
|
69
|
+
"@slidev/types": "52.18.1"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"vite": "^8.1.
|
|
72
|
+
"vite": "^8.1.5"
|
|
73
73
|
}
|
|
74
74
|
}
|
package/setup/monaco.ts
CHANGED
|
@@ -3,18 +3,18 @@ import { createSingletonPromise } from '@antfu/utils'
|
|
|
3
3
|
import { shikiToMonaco } from '@shikijs/monaco'
|
|
4
4
|
import { setupTypeAcquisition } from '@typescript/ata'
|
|
5
5
|
import * as monaco from 'monaco-editor'
|
|
6
|
-
import EditorWorker from 'monaco-editor/
|
|
6
|
+
import EditorWorker from 'monaco-editor/editor/editor.worker?worker'
|
|
7
7
|
// @ts-expect-error missing types
|
|
8
|
-
import { StandaloneServices } from 'monaco-editor/
|
|
8
|
+
import { StandaloneServices } from 'monaco-editor/editor/standalone/browser/standaloneServices'
|
|
9
9
|
|
|
10
|
-
import CssWorker from 'monaco-editor/
|
|
11
|
-
import HtmlWorker from 'monaco-editor/
|
|
12
|
-
import JsonWorker from 'monaco-editor/
|
|
13
|
-
import TsWorker from 'monaco-editor/
|
|
10
|
+
import CssWorker from 'monaco-editor/language/css/css.worker?worker'
|
|
11
|
+
import HtmlWorker from 'monaco-editor/language/html/html.worker?worker'
|
|
12
|
+
import JsonWorker from 'monaco-editor/language/json/json.worker?worker'
|
|
13
|
+
import TsWorker from 'monaco-editor/language/typescript/ts.worker?worker'
|
|
14
14
|
// @ts-expect-error missing types
|
|
15
|
-
import { ContextViewService } from 'monaco-editor/
|
|
15
|
+
import { ContextViewService } from 'monaco-editor/platform/contextview/browser/contextViewService'
|
|
16
16
|
// @ts-expect-error missing types
|
|
17
|
-
import { SyncDescriptor } from 'monaco-editor/
|
|
17
|
+
import { SyncDescriptor } from 'monaco-editor/platform/instantiation/common/descriptors'
|
|
18
18
|
import ts from 'typescript'
|
|
19
19
|
import { watchEffect } from 'vue'
|
|
20
20
|
|
package/shim.d.ts
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
// `vite-plugin-pwa` is an optional peer dependency (only needed when the `pwa`
|
|
2
|
+
// option is enabled), so declare the subset of `virtual:pwa-register` we use
|
|
3
|
+
// inline instead of `/// <reference types="vite-plugin-pwa/client" />`. When
|
|
4
|
+
// PWA is off, the CLI serves a no-op stub for this module.
|
|
5
|
+
declare module 'virtual:pwa-register' {
|
|
6
|
+
export interface RegisterSWOptions {
|
|
7
|
+
immediate?: boolean
|
|
8
|
+
onNeedRefresh?: () => void
|
|
9
|
+
onOfflineReady?: () => void
|
|
10
|
+
onRegisteredSW?: (swScriptUrl: string, registration: ServiceWorkerRegistration | undefined) => void
|
|
11
|
+
onRegisterError?: (error: any) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function registerSW(options?: RegisterSWOptions): (reloadPage?: boolean) => Promise<void>
|
|
15
|
+
}
|
|
2
16
|
|
|
3
17
|
declare module '*.md' {
|
|
4
18
|
// with unplugin-vue-markdown, markdowns can be treat as Vue components
|