@slidev/client 0.48.0-beta.2 → 0.48.0-beta.20
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/App.vue +7 -0
- package/builtin/Arrow.vue +2 -4
- package/builtin/CodeBlockWrapper.vue +14 -6
- package/builtin/KaTexBlockWrapper.vue +5 -4
- package/builtin/Mermaid.vue +4 -3
- package/builtin/Monaco.vue +109 -92
- package/builtin/RenderWhen.vue +3 -3
- package/builtin/ShikiMagicMove.vue +50 -0
- package/builtin/SlideCurrentNo.vue +2 -3
- package/builtin/SlidesTotal.vue +3 -4
- package/builtin/SlidevVideo.vue +8 -6
- package/builtin/Toc.vue +3 -3
- package/builtin/TocList.vue +3 -2
- package/builtin/Tweet.vue +3 -22
- package/builtin/VClick.ts +2 -1
- package/builtin/VClickGap.vue +3 -5
- package/builtin/VClicks.ts +1 -1
- package/composables/useClicks.ts +34 -16
- package/constants.ts +58 -8
- package/context.ts +73 -0
- package/env.ts +3 -12
- package/internals/ClicksSlider.vue +93 -0
- package/internals/Controls.vue +2 -2
- package/internals/DrawingControls.vue +39 -9
- package/internals/DrawingLayer.vue +3 -3
- package/internals/Goto.vue +5 -4
- package/internals/IconButton.vue +7 -3
- package/internals/InfoDialog.vue +1 -1
- package/internals/Modal.vue +1 -1
- package/internals/NavControls.vue +4 -5
- package/internals/NoteDisplay.vue +131 -8
- package/internals/NoteEditable.vue +128 -0
- package/internals/NoteStatic.vue +8 -6
- package/internals/PrintContainer.vue +4 -3
- package/internals/PrintSlide.vue +8 -2
- package/internals/PrintSlideClick.vue +5 -7
- package/internals/{SlidesOverview.vue → QuickOverview.vue} +21 -10
- package/internals/RecordingControls.vue +1 -1
- package/internals/RecordingDialog.vue +5 -6
- package/internals/{Editor.vue → SideEditor.vue} +7 -3
- package/internals/SlideContainer.vue +12 -9
- package/internals/SlideWrapper.ts +28 -12
- package/internals/SlidesShow.vue +7 -8
- package/layouts/two-cols-header.vue +9 -3
- package/logic/drawings.ts +6 -3
- package/logic/nav.ts +11 -8
- package/logic/note.ts +7 -7
- package/main.ts +8 -4
- package/modules/context.ts +4 -3
- package/modules/mermaid.ts +6 -7
- package/modules/{directives.ts → v-click.ts} +15 -15
- package/modules/v-mark.ts +159 -0
- package/package.json +26 -16
- package/{internals/EntrySelect.vue → pages/entry.vue} +7 -0
- package/{internals/NotesView.vue → pages/notes.vue} +5 -3
- package/pages/overview.vue +229 -0
- package/{internals/Play.vue → pages/play.vue} +15 -12
- package/{internals/PresenterPrint.vue → pages/presenter/print.vue} +12 -7
- package/{internals/Presenter.vue → pages/presenter.vue} +108 -100
- package/{internals/Print.vue → pages/print.vue} +3 -4
- package/routes.ts +27 -51
- package/setup/codemirror.ts +8 -3
- package/setup/monaco.ts +108 -44
- package/setup/root.ts +2 -2
- package/shim-vue.d.ts +35 -0
- package/shim.d.ts +1 -13
- package/state/index.ts +10 -10
- package/styles/code.css +7 -3
- package/styles/index.css +68 -7
- package/styles/katex.css +1 -1
- package/styles/layouts-base.css +17 -12
- package/styles/monaco.css +27 -0
- package/styles/vars.css +1 -0
- package/uno.config.ts +14 -2
- package/iframes/monaco/index.css +0 -28
- package/iframes/monaco/index.html +0 -7
- package/iframes/monaco/index.ts +0 -260
- package/internals/NoteEditor.vue +0 -88
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
import { watchEffect } from 'vue'
|
|
3
3
|
import { windowSize } from '../state'
|
|
4
4
|
import { isPrintMode } from '../logic/nav'
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import PrintStyle from './PrintStyle.vue'
|
|
5
|
+
import PrintContainer from '../internals/PrintContainer.vue'
|
|
6
|
+
import PrintStyle from '../internals/PrintStyle.vue'
|
|
8
7
|
|
|
9
8
|
watchEffect(() => {
|
|
10
9
|
if (isPrintMode)
|
|
@@ -16,7 +15,7 @@ watchEffect(() => {
|
|
|
16
15
|
|
|
17
16
|
<template>
|
|
18
17
|
<PrintStyle v-if="isPrintMode" />
|
|
19
|
-
<div id="page-root" class="grid grid-cols-[1fr_max-content]"
|
|
18
|
+
<div id="page-root" class="grid grid-cols-[1fr_max-content]">
|
|
20
19
|
<PrintContainer
|
|
21
20
|
class="w-full h-full"
|
|
22
21
|
:style="{ background: 'var(--slidev-slide-container-background, black)' }"
|
package/routes.ts
CHANGED
|
@@ -1,65 +1,73 @@
|
|
|
1
1
|
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
|
|
2
2
|
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
|
3
|
-
import type { TransitionGroupProps } from 'vue'
|
|
4
|
-
import type { ClicksContext } from '@slidev/types'
|
|
5
|
-
import Play from './internals/Play.vue'
|
|
6
|
-
import Print from './internals/Print.vue'
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
import
|
|
4
|
+
import { rawRoutes, redirects } from '#slidev/routes'
|
|
5
|
+
import configs from '#slidev/configs'
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
import _configs from '/@slidev/configs'
|
|
13
|
-
|
|
14
|
-
export const rawRoutes = _rawRoutes as RouteRecordRaw[]
|
|
7
|
+
export { rawRoutes }
|
|
15
8
|
|
|
16
9
|
export const routes: RouteRecordRaw[] = [
|
|
17
10
|
{
|
|
18
11
|
name: 'play',
|
|
19
12
|
path: '/',
|
|
20
|
-
component:
|
|
13
|
+
component: () => import('./pages/play.vue'),
|
|
21
14
|
children: [
|
|
22
15
|
...rawRoutes,
|
|
23
16
|
...redirects,
|
|
24
17
|
],
|
|
25
18
|
},
|
|
26
|
-
{
|
|
19
|
+
{
|
|
20
|
+
name: 'print',
|
|
21
|
+
path: '/print',
|
|
22
|
+
component: () => import('./pages/print.vue'),
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// Redirects
|
|
27
26
|
{ path: '', redirect: { path: '/1' } },
|
|
28
27
|
{ path: '/:pathMatch(.*)', redirect: { path: '/1' } },
|
|
29
28
|
]
|
|
30
29
|
|
|
31
30
|
if (__SLIDEV_FEATURE_PRESENTER__) {
|
|
32
31
|
function passwordGuard(to: RouteLocationNormalized) {
|
|
33
|
-
if (!
|
|
32
|
+
if (!configs.remote || configs.remote === to.query.password)
|
|
34
33
|
return true
|
|
35
|
-
if (
|
|
34
|
+
if (configs.remote && to.query.password === undefined) {
|
|
36
35
|
// eslint-disable-next-line no-alert
|
|
37
36
|
const password = prompt('Enter password')
|
|
38
|
-
if (
|
|
37
|
+
if (configs.remote === password)
|
|
39
38
|
return true
|
|
40
39
|
}
|
|
41
40
|
if (to.params.no)
|
|
42
41
|
return { path: `/${to.params.no}` }
|
|
43
42
|
return { path: '' }
|
|
44
43
|
}
|
|
45
|
-
|
|
44
|
+
|
|
45
|
+
routes.push({
|
|
46
|
+
path: '/presenter/print',
|
|
47
|
+
component: () => import('./pages/presenter/print.vue'),
|
|
48
|
+
})
|
|
46
49
|
if (__SLIDEV_HAS_SERVER__) {
|
|
47
50
|
routes.push({
|
|
48
51
|
name: 'entry',
|
|
49
52
|
path: '/entry',
|
|
50
|
-
component: () => import('./
|
|
53
|
+
component: () => import('./pages/entry.vue'),
|
|
54
|
+
})
|
|
55
|
+
routes.push({
|
|
56
|
+
name: 'overview',
|
|
57
|
+
path: '/overview',
|
|
58
|
+
component: () => import('./pages/overview.vue'),
|
|
51
59
|
})
|
|
52
60
|
routes.push({
|
|
53
61
|
name: 'notes',
|
|
54
62
|
path: '/notes',
|
|
55
|
-
component: () => import('./
|
|
63
|
+
component: () => import('./pages/notes.vue'),
|
|
56
64
|
beforeEnter: passwordGuard,
|
|
57
65
|
})
|
|
58
66
|
}
|
|
59
67
|
routes.push({
|
|
60
68
|
name: 'presenter',
|
|
61
69
|
path: '/presenter/:no',
|
|
62
|
-
component: () => import('./
|
|
70
|
+
component: () => import('./pages/presenter.vue'),
|
|
63
71
|
beforeEnter: passwordGuard,
|
|
64
72
|
})
|
|
65
73
|
routes.push({
|
|
@@ -74,35 +82,3 @@ export const router = createRouter({
|
|
|
74
82
|
: createWebHistory(import.meta.env.BASE_URL),
|
|
75
83
|
routes,
|
|
76
84
|
})
|
|
77
|
-
|
|
78
|
-
declare module 'vue-router' {
|
|
79
|
-
interface RouteMeta {
|
|
80
|
-
// inherited from frontmatter
|
|
81
|
-
layout: string
|
|
82
|
-
name?: string
|
|
83
|
-
class?: string
|
|
84
|
-
clicks?: number
|
|
85
|
-
transition?: string | TransitionGroupProps | undefined
|
|
86
|
-
preload?: boolean
|
|
87
|
-
|
|
88
|
-
// slide info
|
|
89
|
-
slide?: {
|
|
90
|
-
start: number
|
|
91
|
-
end: number
|
|
92
|
-
note?: string
|
|
93
|
-
noteHTML?: string
|
|
94
|
-
id: number
|
|
95
|
-
no: number
|
|
96
|
-
filepath: string
|
|
97
|
-
title?: string
|
|
98
|
-
level?: number
|
|
99
|
-
raw: string
|
|
100
|
-
content: string
|
|
101
|
-
frontmatter: Record<string, any>
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// private fields
|
|
105
|
-
__clicksContext: null | ClicksContext
|
|
106
|
-
__preloaded?: boolean
|
|
107
|
-
}
|
|
108
|
-
}
|
package/setup/codemirror.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Ref, WritableComputedRef } from 'vue'
|
|
2
|
+
import { onClickOutside } from '@vueuse/core'
|
|
2
3
|
import { watch } from 'vue'
|
|
3
|
-
import
|
|
4
|
+
import CodeMirror from 'codemirror'
|
|
4
5
|
import 'codemirror/mode/javascript/javascript'
|
|
5
6
|
import 'codemirror/mode/css/css'
|
|
6
7
|
import 'codemirror/mode/markdown/markdown'
|
|
@@ -9,8 +10,6 @@ import 'codemirror/mode/htmlmixed/htmlmixed'
|
|
|
9
10
|
import 'codemirror/addon/display/placeholder'
|
|
10
11
|
import 'codemirror/lib/codemirror.css'
|
|
11
12
|
|
|
12
|
-
const CodeMirror = _CodeMirror.default ?? ('fromTextArea' in _CodeMirror ? _CodeMirror : globalThis.CodeMirror)
|
|
13
|
-
|
|
14
13
|
export async function useCodeMirror(
|
|
15
14
|
textarea: Ref<HTMLTextAreaElement | null | undefined>,
|
|
16
15
|
input: Ref<string> | WritableComputedRef<string>,
|
|
@@ -47,5 +46,11 @@ export async function useCodeMirror(
|
|
|
47
46
|
{ immediate: true },
|
|
48
47
|
)
|
|
49
48
|
|
|
49
|
+
onClickOutside(cm.getWrapperElement(), () => {
|
|
50
|
+
const el = cm.getInputField()
|
|
51
|
+
if (document.activeElement === el)
|
|
52
|
+
el.blur()
|
|
53
|
+
})
|
|
54
|
+
|
|
50
55
|
return cm
|
|
51
56
|
}
|
package/setup/monaco.ts
CHANGED
|
@@ -1,52 +1,114 @@
|
|
|
1
|
-
import { getCurrentInstance, onMounted } from 'vue'
|
|
2
|
-
import * as monaco from 'monaco-editor'
|
|
3
1
|
import { createSingletonPromise } from '@antfu/utils'
|
|
4
2
|
import type { MonacoSetupReturn } from '@slidev/types'
|
|
3
|
+
import * as monaco from 'monaco-editor'
|
|
4
|
+
import { watchEffect } from 'vue'
|
|
5
|
+
import { setupTypeAcquisition } from '@typescript/ata'
|
|
6
|
+
import ts from 'typescript'
|
|
7
|
+
|
|
8
|
+
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
|
|
9
|
+
import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
|
|
10
|
+
import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
|
|
11
|
+
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
|
|
12
|
+
import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
|
|
13
|
+
|
|
14
|
+
// @ts-expect-error missing types
|
|
15
|
+
import { ContextViewService } from 'monaco-editor/esm/vs/platform/contextview/browser/contextViewService'
|
|
16
|
+
|
|
17
|
+
// @ts-expect-error missing types
|
|
18
|
+
import { SyncDescriptor } from 'monaco-editor/esm/vs/platform/instantiation/common/descriptors'
|
|
19
|
+
|
|
20
|
+
// @ts-expect-error missing types
|
|
21
|
+
import { StandaloneServices } from 'monaco-editor/esm/vs/editor/standalone/browser/standaloneServices'
|
|
22
|
+
|
|
23
|
+
import { isDark } from '../logic/dark'
|
|
24
|
+
import configs from '#slidev/configs'
|
|
5
25
|
|
|
6
26
|
/* __imports__ */
|
|
27
|
+
window.MonacoEnvironment = {
|
|
28
|
+
getWorker(_, label) {
|
|
29
|
+
if (label === 'json')
|
|
30
|
+
return new JsonWorker()
|
|
31
|
+
if (label === 'css' || label === 'scss' || label === 'less')
|
|
32
|
+
return new CssWorker()
|
|
33
|
+
if (label === 'html' || label === 'handlebars' || label === 'razor')
|
|
34
|
+
return new HtmlWorker()
|
|
35
|
+
if (label === 'typescript' || label === 'javascript')
|
|
36
|
+
return new TsWorker()
|
|
37
|
+
return new EditorWorker()
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class ContextViewService2 extends ContextViewService {
|
|
42
|
+
showContextView(...args: any) {
|
|
43
|
+
super.showContextView(...args)
|
|
44
|
+
// @ts-expect-error missing types
|
|
45
|
+
const contextView = this.contextView.view as HTMLElement
|
|
46
|
+
contextView.style.left = `calc(${contextView.style.left} / var(--slidev-slide-scale))`
|
|
47
|
+
contextView.style.top = `calc(${contextView.style.top} / var(--slidev-slide-scale))`
|
|
48
|
+
// Reset the scale to 1. Otherwise, the sub-menu will be in the wrong position.
|
|
49
|
+
contextView.style.transform = `scale(calc(1 / var(--slidev-slide-scale)))`
|
|
50
|
+
contextView.style.transformOrigin = '0 0'
|
|
51
|
+
}
|
|
52
|
+
}
|
|
7
53
|
|
|
8
54
|
const setup = createSingletonPromise(async () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
55
|
+
// Initialize services first, otherwise we can't override them.
|
|
56
|
+
StandaloneServices.initialize({
|
|
57
|
+
contextViewService: new SyncDescriptor(ContextViewService2, [], true),
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const defaults = monaco.languages.typescript.typescriptDefaults
|
|
61
|
+
|
|
62
|
+
defaults.setCompilerOptions({
|
|
63
|
+
...defaults.getCompilerOptions(),
|
|
15
64
|
strict: true,
|
|
65
|
+
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
|
66
|
+
module: monaco.languages.typescript.ModuleKind.ESNext,
|
|
16
67
|
})
|
|
17
68
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
getWorker(_: any, label: string) {
|
|
37
|
-
if (label === 'json')
|
|
38
|
-
return new JsonWorker()
|
|
39
|
-
if (label === 'css' || label === 'scss' || label === 'less')
|
|
40
|
-
return new CssWorker()
|
|
41
|
-
if (label === 'html' || label === 'handlebars' || label === 'razor')
|
|
42
|
-
return new HtmlWorker()
|
|
43
|
-
if (label === 'typescript' || label === 'javascript')
|
|
44
|
-
return new TsWorker()
|
|
45
|
-
return new EditorWorker()
|
|
69
|
+
// Load types from server
|
|
70
|
+
import('#slidev/monaco-types')
|
|
71
|
+
|
|
72
|
+
const ata = configs.monacoTypesSource === 'cdn'
|
|
73
|
+
? setupTypeAcquisition({
|
|
74
|
+
projectName: 'TypeScript Playground',
|
|
75
|
+
typescript: ts as any, // Version mismatch. No problem found so far.
|
|
76
|
+
logger: console,
|
|
77
|
+
delegate: {
|
|
78
|
+
receivedFile: (code: string, path: string) => {
|
|
79
|
+
defaults.addExtraLib(code, `file://${path}`)
|
|
80
|
+
const uri = monaco.Uri.file(path)
|
|
81
|
+
if (monaco.editor.getModel(uri) === null)
|
|
82
|
+
monaco.editor.createModel(code, 'javascript', uri)
|
|
83
|
+
},
|
|
84
|
+
progress: (downloaded: number, total: number) => {
|
|
85
|
+
// eslint-disable-next-line no-console
|
|
86
|
+
console.debug(`[Typescript ATA] ${downloaded} / ${total}`)
|
|
46
87
|
},
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
: () => { }
|
|
91
|
+
|
|
92
|
+
// monaco.languages.register({ id: 'vue' })
|
|
93
|
+
monaco.languages.register({ id: 'typescript' })
|
|
94
|
+
monaco.languages.register({ id: 'javascript' })
|
|
95
|
+
|
|
96
|
+
const { shiki, themes, shikiToMonaco } = await import('#slidev/shiki')
|
|
97
|
+
const highlighter = await shiki
|
|
98
|
+
|
|
99
|
+
// Use Shiki to highlight Monaco
|
|
100
|
+
shikiToMonaco(highlighter, monaco)
|
|
101
|
+
|
|
102
|
+
if (typeof themes === 'string') {
|
|
103
|
+
monaco.editor.setTheme(themes)
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
watchEffect(() => {
|
|
107
|
+
monaco.editor.setTheme(isDark.value
|
|
108
|
+
? themes.dark || 'vitesse-dark'
|
|
109
|
+
: themes.light || 'vitesse-light')
|
|
110
|
+
})
|
|
111
|
+
}
|
|
50
112
|
|
|
51
113
|
// @ts-expect-error injected in runtime
|
|
52
114
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
@@ -56,15 +118,17 @@ const setup = createSingletonPromise(async () => {
|
|
|
56
118
|
|
|
57
119
|
/* __async_injections__ */
|
|
58
120
|
|
|
59
|
-
if (getCurrentInstance())
|
|
60
|
-
await new Promise<void>(resolve => onMounted(resolve))
|
|
61
|
-
|
|
62
121
|
return {
|
|
63
122
|
monaco,
|
|
123
|
+
ata,
|
|
64
124
|
...injection_return,
|
|
65
125
|
}
|
|
66
126
|
})
|
|
67
127
|
|
|
68
|
-
export default
|
|
128
|
+
export async function addFile(raw: Promise<{ default: string }>, path: string) {
|
|
129
|
+
const code = (await raw).default
|
|
130
|
+
monaco.languages.typescript.typescriptDefaults.addExtraLib(code, `file:///${path}`)
|
|
131
|
+
monaco.editor.createModel(code, 'javascript', monaco.Uri.file(path))
|
|
132
|
+
}
|
|
69
133
|
|
|
70
|
-
setup
|
|
134
|
+
export default setup
|
package/setup/root.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* __imports__ */
|
|
2
2
|
import { watch } from 'vue'
|
|
3
3
|
import { useHead } from '@unhead/vue'
|
|
4
|
-
import { nanoid } from 'nanoid'
|
|
5
4
|
import { configs } from '../env'
|
|
6
5
|
import { initSharedState, onPatch, patch } from '../state/shared'
|
|
7
6
|
import { initDrawingState } from '../state/drawings'
|
|
@@ -9,6 +8,7 @@ import { clicksContext, currentPage, getPath, isNotesViewer, isPresenter } from
|
|
|
9
8
|
import { router } from '../routes'
|
|
10
9
|
import { TRUST_ORIGINS } from '../constants'
|
|
11
10
|
import { skipTransition } from '../composables/hmr'
|
|
11
|
+
import { makeId } from '../logic/utils'
|
|
12
12
|
|
|
13
13
|
export default function setupRoot() {
|
|
14
14
|
// @ts-expect-error injected in runtime
|
|
@@ -25,7 +25,7 @@ export default function setupRoot() {
|
|
|
25
25
|
initSharedState(`${title} - shared`)
|
|
26
26
|
initDrawingState(`${title} - drawings`)
|
|
27
27
|
|
|
28
|
-
const id = `${location.origin}_${
|
|
28
|
+
const id = `${location.origin}_${makeId()}`
|
|
29
29
|
|
|
30
30
|
// update shared state
|
|
31
31
|
function updateSharedState() {
|
package/shim-vue.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
declare module 'vue' {
|
|
2
|
+
import type { UnwrapNestedRefs } from 'vue'
|
|
3
|
+
import type { SlidevContext } from './modules/context'
|
|
4
|
+
|
|
5
|
+
interface ComponentCustomProperties {
|
|
6
|
+
$slidev: UnwrapNestedRefs<SlidevContext>
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare module 'vue-router' {
|
|
11
|
+
interface RouteMeta {
|
|
12
|
+
// inherited from frontmatter
|
|
13
|
+
layout: string
|
|
14
|
+
name?: string
|
|
15
|
+
class?: string
|
|
16
|
+
clicks?: number
|
|
17
|
+
transition?: string | TransitionGroupProps | undefined
|
|
18
|
+
preload?: boolean
|
|
19
|
+
|
|
20
|
+
// slide info
|
|
21
|
+
slide?: Omit<SlideInfo, 'source'> & {
|
|
22
|
+
noteHTML: string
|
|
23
|
+
filepath: string
|
|
24
|
+
start: number
|
|
25
|
+
id: number
|
|
26
|
+
no: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// private fields
|
|
30
|
+
__clicksContext: null | ClicksContext
|
|
31
|
+
__preloaded?: boolean
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {}
|
package/shim.d.ts
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
declare interface Window {
|
|
2
|
-
// extend the window
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
declare module '*.vue';
|
|
6
|
-
|
|
7
|
-
// with unplugin-vue-markdown, markdowns can be treat as Vue components
|
|
8
1
|
declare module '*.md' {
|
|
2
|
+
// with unplugin-vue-markdown, markdowns can be treat as Vue components
|
|
9
3
|
import type { ComponentOptions } from 'vue'
|
|
10
4
|
|
|
11
5
|
const component: ComponentOptions
|
|
12
6
|
export default component
|
|
13
7
|
}
|
|
14
8
|
|
|
15
|
-
declare module '/@slidev/configs' {
|
|
16
|
-
import { SlidevConfig } from '@slidev/types'
|
|
17
|
-
|
|
18
|
-
export default SlidevConfig
|
|
19
|
-
}
|
|
20
|
-
|
|
21
9
|
declare module 'mermaid/dist/mermaid.esm.mjs' {
|
|
22
10
|
import Mermaid from 'mermaid/dist/mermaid.d.ts'
|
|
23
11
|
|
package/state/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { slideAspect } from '../env'
|
|
|
5
5
|
export const showRecordingDialog = ref(false)
|
|
6
6
|
export const showInfoDialog = ref(false)
|
|
7
7
|
export const showGotoDialog = ref(false)
|
|
8
|
+
export const showOverview = ref(false)
|
|
8
9
|
|
|
9
10
|
export const shortcutsEnabled = ref(true)
|
|
10
11
|
export const breakpoints = useBreakpoints({
|
|
@@ -20,19 +21,18 @@ export const activeElement = useActiveElement()
|
|
|
20
21
|
export const isInputting = computed(() => ['INPUT', 'TEXTAREA'].includes(activeElement.value?.tagName || '') || activeElement.value?.classList.contains('CodeMirror-code'))
|
|
21
22
|
export const isOnFocus = computed(() => ['BUTTON', 'A'].includes(activeElement.value?.tagName || ''))
|
|
22
23
|
|
|
23
|
-
export const currentCamera = useLocalStorage<string>('slidev-camera', 'default')
|
|
24
|
-
export const currentMic = useLocalStorage<string>('slidev-mic', 'default')
|
|
24
|
+
export const currentCamera = useLocalStorage<string>('slidev-camera', 'default', { listenToStorageChanges: false })
|
|
25
|
+
export const currentMic = useLocalStorage<string>('slidev-mic', 'default', { listenToStorageChanges: false })
|
|
25
26
|
export const slideScale = useLocalStorage<number>('slidev-scale', 0)
|
|
26
27
|
|
|
27
|
-
export const
|
|
28
|
-
export const
|
|
29
|
-
export const
|
|
30
|
-
export const
|
|
31
|
-
export const
|
|
32
|
-
export const editorHeight = useLocalStorage('slidev-editor-height', isClient ? window.innerHeight * 0.4 : 300)
|
|
28
|
+
export const showPresenterCursor = useLocalStorage('slidev-presenter-cursor', true, { listenToStorageChanges: false })
|
|
29
|
+
export const showEditor = useLocalStorage('slidev-show-editor', false, { listenToStorageChanges: false })
|
|
30
|
+
export const isEditorVertical = useLocalStorage('slidev-editor-vertical', false, { listenToStorageChanges: false })
|
|
31
|
+
export const editorWidth = useLocalStorage('slidev-editor-width', isClient ? window.innerWidth * 0.4 : 318, { listenToStorageChanges: false })
|
|
32
|
+
export const editorHeight = useLocalStorage('slidev-editor-height', isClient ? window.innerHeight * 0.4 : 300, { listenToStorageChanges: false })
|
|
33
33
|
|
|
34
|
-
export const presenterNotesFontSize = useLocalStorage('slidev-presenter-font-size', 1)
|
|
35
|
-
export const presenterLayout = useLocalStorage('slidev-presenter-layout', 1)
|
|
34
|
+
export const presenterNotesFontSize = useLocalStorage('slidev-presenter-font-size', 1, { listenToStorageChanges: false })
|
|
35
|
+
export const presenterLayout = useLocalStorage('slidev-presenter-layout', 1, { listenToStorageChanges: false })
|
|
36
36
|
|
|
37
37
|
export function togglePresenterLayout() {
|
|
38
38
|
presenterLayout.value = presenterLayout.value + 1
|
package/styles/code.css
CHANGED
|
@@ -59,7 +59,9 @@ html:not(.dark) .shiki span {
|
|
|
59
59
|
.slidev-code-line-numbers .slidev-code code .line::before {
|
|
60
60
|
content: counter(step);
|
|
61
61
|
counter-increment: step;
|
|
62
|
-
|
|
62
|
+
display: inline-block;
|
|
63
|
+
text-align: right;
|
|
64
|
+
--uno: w-4 mr-6 text-gray-400 dark-text-gray-600;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
/* Inline Code */
|
|
@@ -67,7 +69,7 @@ html:not(.dark) .shiki span {
|
|
|
67
69
|
font-size: 0.9em;
|
|
68
70
|
background: var(--slidev-code-background);
|
|
69
71
|
border-radius: var(--slidev-code-radius);
|
|
70
|
-
|
|
72
|
+
--uno: font-light py-0.5 px-1.5;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
.slidev-layout :not(pre) > code:before {
|
|
@@ -82,4 +84,6 @@ html:not(.dark) .shiki span {
|
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
/* CodeMirror */
|
|
85
|
-
.CodeMirror pre.CodeMirror-placeholder {
|
|
87
|
+
.CodeMirror pre.CodeMirror-placeholder {
|
|
88
|
+
opacity: 0.4;
|
|
89
|
+
}
|
package/styles/index.css
CHANGED
|
@@ -16,22 +16,27 @@ html {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
.slidev-icon-btn {
|
|
19
|
-
|
|
19
|
+
aspect-ratio: 1;
|
|
20
|
+
display: inline-block;
|
|
21
|
+
user-select: none;
|
|
22
|
+
outline: none;
|
|
23
|
+
cursor: pointer;
|
|
20
24
|
@apply opacity-75 transition duration-200 ease-in-out align-middle rounded p-1;
|
|
21
25
|
@apply hover:(opacity-100 bg-gray-400 bg-opacity-10);
|
|
22
26
|
@apply md:p-2;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
.slidev-icon-btn.shallow {
|
|
26
|
-
|
|
30
|
+
opacity: 0.3;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
.slidev-icon-btn.active {
|
|
30
|
-
|
|
34
|
+
opacity: 1;
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
.slidev-icon-btn.disabled {
|
|
34
|
-
|
|
38
|
+
opacity: 0.25;
|
|
39
|
+
pointer-events: none;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
.slidev-vclick-target {
|
|
@@ -39,11 +44,13 @@ html {
|
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
.slidev-vclick-hidden {
|
|
42
|
-
|
|
47
|
+
opacity: 0 !important;
|
|
48
|
+
pointer-events: none !important;
|
|
49
|
+
user-select: none !important;
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
.slidev-vclick-fade {
|
|
46
|
-
|
|
53
|
+
opacity: 0.5;
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
.slidev-icon {
|
|
@@ -53,5 +60,59 @@ html {
|
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
.slidev-page {
|
|
56
|
-
|
|
63
|
+
position: relative;
|
|
64
|
+
top: 0;
|
|
65
|
+
left: 0;
|
|
66
|
+
right: 0;
|
|
67
|
+
width: 100%;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* Note Clicks */
|
|
71
|
+
|
|
72
|
+
.slidev-note-with-clicks .slidev-note-fade {
|
|
73
|
+
color: #888888ab;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.slidev-note-click-mark {
|
|
77
|
+
user-select: none;
|
|
78
|
+
font-size: 0.7em;
|
|
79
|
+
display: inline-flex;
|
|
80
|
+
--uno: text-violet bg-violet/10 px1 font-mono rounded items-center border
|
|
81
|
+
border-transparent;
|
|
82
|
+
}
|
|
83
|
+
.slidev-note-click-mark.slidev-note-click-mark-active {
|
|
84
|
+
--uno: border border-violet;
|
|
85
|
+
}
|
|
86
|
+
.slidev-note-click-mark.slidev-note-click-mark-past {
|
|
87
|
+
filter: saturate(0);
|
|
88
|
+
opacity: 0.5;
|
|
89
|
+
}
|
|
90
|
+
.slidev-note-click-mark.slidev-note-click-mark-future {
|
|
91
|
+
opacity: 0.5;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.slidev-note-click-mark::before {
|
|
95
|
+
content: '';
|
|
96
|
+
display: inline-block;
|
|
97
|
+
--un-icon: url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 32 32' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M23 28a1 1 0 0 1-.71-.29l-6.13-6.14l-3.33 5a1 1 0 0 1-1 .44a1 1 0 0 1-.81-.7l-6-20A1 1 0 0 1 6.29 5l20 6a1 1 0 0 1 .7.81a1 1 0 0 1-.44 1l-5 3.33l6.14 6.13a1 1 0 0 1 0 1.42l-4 4A1 1 0 0 1 23 28m0-2.41L25.59 23l-7.16-7.15l5.25-3.5L7.49 7.49l4.86 16.19l3.5-5.25Z'/%3E%3C/svg%3E");
|
|
98
|
+
-webkit-mask: var(--un-icon) no-repeat;
|
|
99
|
+
mask: var(--un-icon) no-repeat;
|
|
100
|
+
-webkit-mask-size: 100% 100%;
|
|
101
|
+
mask-size: 100% 100%;
|
|
102
|
+
background-color: currentColor;
|
|
103
|
+
color: inherit;
|
|
104
|
+
width: 1.2em;
|
|
105
|
+
height: 1.2em;
|
|
106
|
+
opacity: 0.8;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.slidev-note-click-mark::after {
|
|
110
|
+
content: attr(data-clicks);
|
|
111
|
+
display: inline-block;
|
|
112
|
+
transform: translateY(0.1em);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Transform the position back for Rough Notation (v-mark) */
|
|
116
|
+
.rough-annotation {
|
|
117
|
+
transform: scale(calc(1 / var(--slidev-slide-scale)));
|
|
57
118
|
}
|
package/styles/katex.css
CHANGED