@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
package/App.vue
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { watchEffect } from 'vue'
|
|
3
|
+
import { themeVars } from './env'
|
|
2
4
|
import setupRoot from './setup/root'
|
|
3
5
|
|
|
4
6
|
setupRoot()
|
|
7
|
+
|
|
8
|
+
watchEffect(() => {
|
|
9
|
+
for (const [key, value] of Object.entries(themeVars.value))
|
|
10
|
+
document.body.style.setProperty(key, value.toString())
|
|
11
|
+
})
|
|
5
12
|
</script>
|
|
6
13
|
|
|
7
14
|
<template>
|
package/builtin/Arrow.vue
CHANGED
|
@@ -9,7 +9,7 @@ Simple Arrow
|
|
|
9
9
|
-->
|
|
10
10
|
|
|
11
11
|
<script setup lang="ts">
|
|
12
|
-
import {
|
|
12
|
+
import { makeId } from '../logic/utils'
|
|
13
13
|
|
|
14
14
|
defineProps<{
|
|
15
15
|
x1: number | string
|
|
@@ -20,9 +20,7 @@ defineProps<{
|
|
|
20
20
|
color?: string
|
|
21
21
|
}>()
|
|
22
22
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const id = nanoid()
|
|
23
|
+
const id = makeId()
|
|
26
24
|
</script>
|
|
27
25
|
|
|
28
26
|
<template>
|
|
@@ -14,11 +14,12 @@ Learn more: https://sli.dev/guide/syntax.html#line-highlighting
|
|
|
14
14
|
<script setup lang="ts">
|
|
15
15
|
import { parseRangeString } from '@slidev/parser/core'
|
|
16
16
|
import { useClipboard } from '@vueuse/core'
|
|
17
|
-
import { computed,
|
|
17
|
+
import { computed, onMounted, onUnmounted, ref, watchEffect } from 'vue'
|
|
18
18
|
import type { PropType } from 'vue'
|
|
19
19
|
import { configs } from '../env'
|
|
20
20
|
import { makeId } from '../logic/utils'
|
|
21
|
-
import { CLASS_VCLICK_HIDDEN, CLASS_VCLICK_TARGET
|
|
21
|
+
import { CLASS_VCLICK_HIDDEN, CLASS_VCLICK_TARGET } from '../constants'
|
|
22
|
+
import { useSlideContext } from '../context'
|
|
22
23
|
|
|
23
24
|
const props = defineProps({
|
|
24
25
|
ranges: {
|
|
@@ -47,7 +48,7 @@ const props = defineProps({
|
|
|
47
48
|
},
|
|
48
49
|
})
|
|
49
50
|
|
|
50
|
-
const clicks =
|
|
51
|
+
const { $clicksContext: clicks } = useSlideContext()
|
|
51
52
|
const el = ref<HTMLDivElement>()
|
|
52
53
|
const id = makeId()
|
|
53
54
|
|
|
@@ -55,8 +56,12 @@ onUnmounted(() => {
|
|
|
55
56
|
clicks!.unregister(id)
|
|
56
57
|
})
|
|
57
58
|
|
|
59
|
+
watchEffect(() => {
|
|
60
|
+
el.value?.classList.toggle('slidev-code-line-numbers', props.lines)
|
|
61
|
+
})
|
|
62
|
+
|
|
58
63
|
onMounted(() => {
|
|
59
|
-
if (!clicks || clicks.disabled)
|
|
64
|
+
if (!clicks || clicks.disabled || !props.ranges?.length)
|
|
60
65
|
return
|
|
61
66
|
|
|
62
67
|
const { start, end, delta } = clicks.resolve(props.at, props.ranges.length - 1)
|
|
@@ -120,9 +125,12 @@ function copyCode() {
|
|
|
120
125
|
|
|
121
126
|
<template>
|
|
122
127
|
<div
|
|
123
|
-
ref="el"
|
|
128
|
+
ref="el"
|
|
129
|
+
class="slidev-code-wrapper relative group"
|
|
130
|
+
:class="{
|
|
124
131
|
'slidev-code-line-numbers': props.lines,
|
|
125
|
-
}"
|
|
132
|
+
}"
|
|
133
|
+
:style="{
|
|
126
134
|
'max-height': props.maxHeight,
|
|
127
135
|
'overflow-y': props.maxHeight ? 'scroll' : undefined,
|
|
128
136
|
'--start': props.startLine,
|
|
@@ -20,11 +20,12 @@ Learn more: https://sli.dev/guide/syntax.html#latex-line-highlighting
|
|
|
20
20
|
-->
|
|
21
21
|
|
|
22
22
|
<script setup lang="ts">
|
|
23
|
-
import { computed,
|
|
23
|
+
import { computed, onMounted, onUnmounted, ref, watchEffect } from 'vue'
|
|
24
24
|
import type { PropType } from 'vue'
|
|
25
25
|
import { parseRangeString } from '@slidev/parser'
|
|
26
|
-
import { CLASS_VCLICK_HIDDEN, CLASS_VCLICK_TARGET
|
|
26
|
+
import { CLASS_VCLICK_HIDDEN, CLASS_VCLICK_TARGET } from '../constants'
|
|
27
27
|
import { makeId } from '../logic/utils'
|
|
28
|
+
import { useSlideContext } from '../context'
|
|
28
29
|
|
|
29
30
|
const props = defineProps({
|
|
30
31
|
ranges: {
|
|
@@ -45,7 +46,7 @@ const props = defineProps({
|
|
|
45
46
|
},
|
|
46
47
|
})
|
|
47
48
|
|
|
48
|
-
const clicks =
|
|
49
|
+
const { $clicksContext: clicks } = useSlideContext()
|
|
49
50
|
const el = ref<HTMLDivElement>()
|
|
50
51
|
const id = makeId()
|
|
51
52
|
|
|
@@ -54,7 +55,7 @@ onUnmounted(() => {
|
|
|
54
55
|
})
|
|
55
56
|
|
|
56
57
|
onMounted(() => {
|
|
57
|
-
if (!clicks || clicks.disabled)
|
|
58
|
+
if (!clicks || clicks.disabled || !props.ranges?.length)
|
|
58
59
|
return
|
|
59
60
|
|
|
60
61
|
const { start, end, delta } = clicks.resolve(props.at, props.ranges.length - 1)
|
package/builtin/Mermaid.vue
CHANGED
|
@@ -19,7 +19,7 @@ import ShadowRoot from '../internals/ShadowRoot.vue'
|
|
|
19
19
|
import { isDark } from '../logic/dark'
|
|
20
20
|
|
|
21
21
|
const props = defineProps<{
|
|
22
|
-
|
|
22
|
+
codeLz: string
|
|
23
23
|
scale?: number
|
|
24
24
|
theme?: string
|
|
25
25
|
}>()
|
|
@@ -37,7 +37,7 @@ watchEffect(async (onCleanup) => {
|
|
|
37
37
|
error.value = null
|
|
38
38
|
try {
|
|
39
39
|
const svg = await renderMermaid(
|
|
40
|
-
props.
|
|
40
|
+
props.codeLz || '',
|
|
41
41
|
{
|
|
42
42
|
theme: props.theme || (isDark.value ? 'dark' : undefined),
|
|
43
43
|
...vm!.attrs,
|
|
@@ -48,6 +48,7 @@ watchEffect(async (onCleanup) => {
|
|
|
48
48
|
}
|
|
49
49
|
catch (e) {
|
|
50
50
|
error.value = `${e}`
|
|
51
|
+
console.warn(e)
|
|
51
52
|
}
|
|
52
53
|
})
|
|
53
54
|
|
|
@@ -76,6 +77,6 @@ watchEffect(() => {
|
|
|
76
77
|
</script>
|
|
77
78
|
|
|
78
79
|
<template>
|
|
79
|
-
<pre v-if="error" border="1 red rounded" class="pa-3">{{ error }}</pre>
|
|
80
|
+
<pre v-if="error" border="1 red rounded" class="pa-3 text-wrap">{{ error }}</pre>
|
|
80
81
|
<ShadowRoot v-else class="mermaid" :inner-html="html" @shadow="el = $event" />
|
|
81
82
|
</template>
|
package/builtin/Monaco.vue
CHANGED
|
@@ -12,122 +12,139 @@ Learn more: https://sli.dev/guide/syntax.html#monaco-editor
|
|
|
12
12
|
-->
|
|
13
13
|
|
|
14
14
|
<script setup lang="ts">
|
|
15
|
-
import { computed, onMounted, ref } from 'vue'
|
|
16
|
-
import { useEventListener } from '@vueuse/core'
|
|
17
|
-
import { decode } from 'js-base64'
|
|
18
|
-
import { nanoid } from 'nanoid'
|
|
19
15
|
import type * as monaco from 'monaco-editor'
|
|
20
|
-
import {
|
|
16
|
+
import { computed, nextTick, onMounted, ref } from 'vue'
|
|
17
|
+
import { debounce } from '@antfu/utils'
|
|
18
|
+
import lz from 'lz-string'
|
|
19
|
+
import { makeId } from '../logic/utils'
|
|
21
20
|
|
|
22
21
|
const props = withDefaults(defineProps<{
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
codeLz: string
|
|
23
|
+
diffLz?: string
|
|
25
24
|
lang?: string
|
|
26
25
|
readonly?: boolean
|
|
27
26
|
lineNumbers?: 'on' | 'off' | 'relative' | 'interval'
|
|
28
|
-
height?: number | string
|
|
27
|
+
height?: number | string // Posible values: 'initial', 'auto', '100%', '200px', etc.
|
|
29
28
|
editorOptions?: monaco.editor.IEditorOptions
|
|
29
|
+
ata?: boolean
|
|
30
30
|
}>(), {
|
|
31
|
-
|
|
31
|
+
codeLz: '',
|
|
32
32
|
lang: 'typescript',
|
|
33
33
|
readonly: false,
|
|
34
34
|
lineNumbers: 'off',
|
|
35
|
-
height: '
|
|
35
|
+
height: 'initial',
|
|
36
|
+
ata: true,
|
|
36
37
|
})
|
|
37
38
|
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const diff = ref(props.diff ? decode(props.diff).trimEnd() : null)
|
|
41
|
-
const lineHeight = +(getComputedStyle(document.body).getPropertyValue('--slidev-code-line-height') || '18').replace('px', '') || 18
|
|
42
|
-
const editorHeight = ref(0)
|
|
43
|
-
const calculatedHeight = computed(() => code.value.split(/\r?\n/g).length * lineHeight)
|
|
44
|
-
const height = computed(() => {
|
|
45
|
-
return props.height === 'auto' ? `${Math.max(calculatedHeight.value, editorHeight.value) + 20}px` : props.height
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
const iframe = ref<HTMLIFrameElement>()
|
|
39
|
+
const code = lz.decompressFromBase64(props.codeLz).trimEnd()
|
|
40
|
+
const diff = props.diffLz && lz.decompressFromBase64(props.diffLz).trimEnd()
|
|
49
41
|
|
|
50
|
-
const
|
|
51
|
-
'
|
|
52
|
-
'
|
|
53
|
-
'--slidev-code-background',
|
|
54
|
-
'--slidev-code-line-height',
|
|
55
|
-
'--slidev-code-padding',
|
|
56
|
-
'--slidev-code-margin',
|
|
57
|
-
'--slidev-code-radius',
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
function getStyleObject(el: Element) {
|
|
61
|
-
const object: Record<string, string> = {}
|
|
62
|
-
const style = getComputedStyle(el)
|
|
63
|
-
for (const v of cssVars)
|
|
64
|
-
object[v] = style.getPropertyValue(v)
|
|
65
|
-
return object
|
|
42
|
+
const langMap: Record<string, string> = {
|
|
43
|
+
ts: 'typescript',
|
|
44
|
+
js: 'javascript',
|
|
66
45
|
}
|
|
46
|
+
const lang = langMap[props.lang] ?? props.lang
|
|
47
|
+
const extMap: Record<string, string> = {
|
|
48
|
+
typescript: 'mts',
|
|
49
|
+
javascript: 'mjs',
|
|
50
|
+
ts: 'mts',
|
|
51
|
+
js: 'mjs',
|
|
52
|
+
}
|
|
53
|
+
const ext = extMap[props.lang] ?? props.lang
|
|
67
54
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
frame.setAttribute('sandbox', [
|
|
71
|
-
'allow-forms',
|
|
72
|
-
'allow-modals',
|
|
73
|
-
'allow-pointer-lock',
|
|
74
|
-
'allow-popups',
|
|
75
|
-
'allow-same-origin',
|
|
76
|
-
'allow-scripts',
|
|
77
|
-
'allow-top-navigation-by-user-activation',
|
|
78
|
-
].join(' '))
|
|
79
|
-
|
|
80
|
-
let src = __DEV__
|
|
81
|
-
? `${location.origin}${__SLIDEV_CLIENT_ROOT__}/`
|
|
82
|
-
: import.meta.env.BASE_URL
|
|
83
|
-
src += `iframes/monaco/index.html?id=${id}&lineNumbers=${props.lineNumbers}&lang=${props.lang}`
|
|
84
|
-
if (diff.value)
|
|
85
|
-
src += '&diff=1'
|
|
86
|
-
frame.src = src
|
|
55
|
+
const outer = ref<HTMLDivElement>()
|
|
56
|
+
const container = ref<HTMLDivElement>()
|
|
87
57
|
|
|
88
|
-
|
|
58
|
+
const contentHeight = ref(0)
|
|
59
|
+
const initialHeight = ref<number>()
|
|
60
|
+
const height = computed(() => {
|
|
61
|
+
if (props.height === 'auto')
|
|
62
|
+
return `${contentHeight.value}px`
|
|
63
|
+
if (props.height === 'initial')
|
|
64
|
+
return `${initialHeight.value}px`
|
|
65
|
+
return props.height
|
|
89
66
|
})
|
|
90
67
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
68
|
+
onMounted(async () => {
|
|
69
|
+
// Lazy load monaco, so it will be bundled in async chunk
|
|
70
|
+
const { default: setup } = await import('../setup/monaco')
|
|
71
|
+
const { ata, monaco } = await setup()
|
|
72
|
+
const model = monaco.editor.createModel(code, lang, monaco.Uri.parse(`file:///${makeId()}.${ext}`))
|
|
73
|
+
const commonOptions = {
|
|
74
|
+
automaticLayout: true,
|
|
75
|
+
readOnly: props.readonly,
|
|
76
|
+
lineNumbers: props.lineNumbers,
|
|
77
|
+
minimap: { enabled: false },
|
|
78
|
+
overviewRulerBorder: false,
|
|
79
|
+
overviewRulerLanes: 0,
|
|
80
|
+
padding: { top: 10, bottom: 10 },
|
|
81
|
+
lineNumbersMinChars: 3,
|
|
82
|
+
bracketPairColorization: { enabled: false },
|
|
83
|
+
tabSize: 2,
|
|
84
|
+
fontSize: 11.5,
|
|
85
|
+
fontFamily: 'var(--slidev-code-font-family)',
|
|
86
|
+
scrollBeyondLastLine: false,
|
|
87
|
+
...props.editorOptions,
|
|
88
|
+
} satisfies monaco.editor.IStandaloneEditorConstructionOptions & monaco.editor.IDiffEditorConstructionOptions
|
|
101
89
|
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
90
|
+
let editableEditor: monaco.editor.IStandaloneCodeEditor
|
|
91
|
+
if (diff) {
|
|
92
|
+
const diffModel = monaco.editor.createModel(diff, lang, monaco.Uri.parse(`file:///${makeId()}.${ext}`))
|
|
93
|
+
const editor = monaco.editor.createDiffEditor(container.value!, {
|
|
94
|
+
renderOverviewRuler: false,
|
|
95
|
+
...commonOptions,
|
|
96
|
+
})
|
|
97
|
+
editor.setModel({
|
|
98
|
+
original: model,
|
|
99
|
+
modified: diffModel,
|
|
100
|
+
})
|
|
101
|
+
const originalEditor = editor.getOriginalEditor()
|
|
102
|
+
const modifiedEditor = editor.getModifiedEditor()
|
|
103
|
+
const onContentSizeChange = () => {
|
|
104
|
+
const newHeight = Math.max(originalEditor.getContentHeight(), modifiedEditor.getContentHeight()) + 4
|
|
105
|
+
initialHeight.value ??= newHeight
|
|
106
|
+
contentHeight.value = newHeight
|
|
107
|
+
nextTick(() => editor.layout())
|
|
108
|
+
}
|
|
109
|
+
originalEditor.onDidContentSizeChange(onContentSizeChange)
|
|
110
|
+
modifiedEditor.onDidContentSizeChange(onContentSizeChange)
|
|
111
|
+
editableEditor = modifiedEditor
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
const editor = monaco.editor.create(container.value!, {
|
|
115
|
+
model,
|
|
116
|
+
lineDecorationsWidth: 0,
|
|
117
|
+
...commonOptions,
|
|
118
|
+
})
|
|
119
|
+
editor.onDidContentSizeChange((e) => {
|
|
120
|
+
const newHeight = e.contentHeight + 4
|
|
121
|
+
initialHeight.value ??= newHeight
|
|
122
|
+
contentHeight.value = newHeight
|
|
123
|
+
nextTick(() => editableEditor.layout())
|
|
124
|
+
})
|
|
125
|
+
editableEditor = editor
|
|
126
|
+
}
|
|
127
|
+
if (props.ata) {
|
|
128
|
+
ata(editableEditor.getValue())
|
|
129
|
+
editableEditor.onDidChangeModelContent(debounce(1000, () => {
|
|
130
|
+
ata(editableEditor.getValue())
|
|
131
|
+
}))
|
|
132
|
+
}
|
|
133
|
+
const originalLayoutContentWidget = editableEditor.layoutContentWidget.bind(editableEditor)
|
|
134
|
+
editableEditor.layoutContentWidget = (widget: any) => {
|
|
135
|
+
originalLayoutContentWidget(widget)
|
|
136
|
+
const id = widget.getId()
|
|
137
|
+
if (id === 'editor.contrib.resizableContentHoverWidget') {
|
|
138
|
+
widget._resizableNode.domNode.style.transform = widget._positionPreference === 1
|
|
139
|
+
? /* ABOVE */ `translateY(calc(100% * (var(--slidev-slide-scale) - 1)))`
|
|
140
|
+
: /* BELOW */ `` // reset
|
|
117
141
|
}
|
|
118
|
-
return
|
|
119
142
|
}
|
|
120
|
-
if (payload.type !== 'slidev-monaco')
|
|
121
|
-
return
|
|
122
|
-
if (payload.data?.height)
|
|
123
|
-
editorHeight.value = payload.data?.height
|
|
124
|
-
if (payload?.data?.code && code.value !== payload.data.code)
|
|
125
|
-
code.value = payload.data.code
|
|
126
|
-
if (payload?.data?.diff && diff.value !== payload.data.diff)
|
|
127
|
-
diff.value = payload.data.diff
|
|
128
143
|
})
|
|
129
144
|
</script>
|
|
130
145
|
|
|
131
146
|
<template>
|
|
132
|
-
<
|
|
147
|
+
<div ref="outer" class="slidev-monaco-container" :style="{ height }">
|
|
148
|
+
<div ref="container" class="absolute inset-0.5" />
|
|
149
|
+
</div>
|
|
133
150
|
</template>
|
package/builtin/RenderWhen.vue
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { RenderContext } from '@slidev/types'
|
|
3
|
-
import { computed,
|
|
3
|
+
import { computed, ref } from 'vue'
|
|
4
4
|
import { useElementVisibility } from '@vueuse/core'
|
|
5
|
-
import {
|
|
5
|
+
import { useSlideContext } from '../context'
|
|
6
6
|
|
|
7
7
|
type Context = 'main' | 'visible' | RenderContext
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ const targetVisible = useElementVisibility(target)
|
|
|
16
16
|
// When context has `visible`, we need to wrap the content with a div to track the visibility
|
|
17
17
|
const needsDomWrapper = Array.isArray(context) ? context.includes('visible') : context === 'visible'
|
|
18
18
|
|
|
19
|
-
const currentContext =
|
|
19
|
+
const { $renderContext: currentContext } = useSlideContext()
|
|
20
20
|
const shouldRender = computed(() => {
|
|
21
21
|
const anyContext = Array.isArray(context) ? context.some(contextMatch) : contextMatch(context)
|
|
22
22
|
const allConditions = Array.isArray(context) ? context.every(conditionsMatch) : conditionsMatch(context)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ShikiMagicMovePrecompiled } from 'shiki-magic-move/vue'
|
|
3
|
+
import type { KeyedTokensInfo } from 'shiki-magic-move/types'
|
|
4
|
+
import { onMounted, onUnmounted, ref, watchEffect } from 'vue'
|
|
5
|
+
import lz from 'lz-string'
|
|
6
|
+
import { useSlideContext } from '../context'
|
|
7
|
+
import { makeId } from '../logic/utils'
|
|
8
|
+
|
|
9
|
+
import 'shiki-magic-move/style.css'
|
|
10
|
+
|
|
11
|
+
const props = defineProps<{
|
|
12
|
+
stepsLz: string
|
|
13
|
+
at?: string | number
|
|
14
|
+
}>()
|
|
15
|
+
|
|
16
|
+
const steps = JSON.parse(lz.decompressFromBase64(props.stepsLz)) as KeyedTokensInfo[]
|
|
17
|
+
const { $clicksContext: clicks, $scale: scale } = useSlideContext()
|
|
18
|
+
const id = makeId()
|
|
19
|
+
const index = ref(0)
|
|
20
|
+
|
|
21
|
+
onUnmounted(() => {
|
|
22
|
+
clicks!.unregister(id)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
onMounted(() => {
|
|
26
|
+
if (!clicks || clicks.disabled)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
const { start, end, delta } = clicks.resolve(props.at || '+1', steps.length - 1)
|
|
30
|
+
clicks.register(id, { max: end, delta })
|
|
31
|
+
|
|
32
|
+
watchEffect(() => {
|
|
33
|
+
if (clicks.disabled)
|
|
34
|
+
index.value = steps.length - 1
|
|
35
|
+
else
|
|
36
|
+
index.value = Math.min(Math.max(0, clicks.current - start + 1), steps.length - 1)
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<div class="slidev-code-wrapper slidev-code-magic-move">
|
|
43
|
+
<ShikiMagicMovePrecompiled
|
|
44
|
+
class="slidev-code relative shiki overflow-visible"
|
|
45
|
+
:steps="steps"
|
|
46
|
+
:step="index"
|
|
47
|
+
:options="{ globalScale: scale }"
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
</template>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { injectionCurrentPage } from '../constants'
|
|
2
|
+
import { useSlideContext } from '../context'
|
|
4
3
|
|
|
5
|
-
const $page =
|
|
4
|
+
const { $page } = useSlideContext()
|
|
6
5
|
</script>
|
|
7
6
|
|
|
8
7
|
<template>
|
package/builtin/SlidesTotal.vue
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { injectionSlidevContext } from '../constants'
|
|
2
|
+
import { useSlideContext } from '../context'
|
|
4
3
|
|
|
5
|
-
const $
|
|
4
|
+
const { $nav } = useSlideContext()
|
|
6
5
|
</script>
|
|
7
6
|
|
|
8
7
|
<template>
|
|
9
|
-
<span>{{ $
|
|
8
|
+
<span>{{ $nav.total }}</span>
|
|
10
9
|
</template>
|
package/builtin/SlidevVideo.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed,
|
|
3
|
-
import {
|
|
2
|
+
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
|
3
|
+
import { useSlideContext } from '../context'
|
|
4
4
|
|
|
5
5
|
const props = defineProps<{
|
|
6
6
|
autoPlay?: boolean | 'once' | 'resume' | 'resumeOnce'
|
|
@@ -8,10 +8,12 @@ const props = defineProps<{
|
|
|
8
8
|
autoReset?: 'slide' | 'click'
|
|
9
9
|
}>()
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const {
|
|
12
|
+
$slidev,
|
|
13
|
+
$clicksContext: clicks,
|
|
14
|
+
$renderContext: currentContext,
|
|
15
|
+
$route: route,
|
|
16
|
+
} = useSlideContext()
|
|
15
17
|
|
|
16
18
|
const video = ref<HTMLMediaElement>()
|
|
17
19
|
const played = ref(false)
|
package/builtin/Toc.vue
CHANGED
|
@@ -8,9 +8,9 @@ Usage:
|
|
|
8
8
|
<Toc columns='2' maxDepth='3' mode='onlySiblings'/>
|
|
9
9
|
-->
|
|
10
10
|
<script setup lang='ts'>
|
|
11
|
-
import { computed
|
|
11
|
+
import { computed } from 'vue'
|
|
12
12
|
import type { TocItem } from '@slidev/types'
|
|
13
|
-
import {
|
|
13
|
+
import { useSlideContext } from '../context'
|
|
14
14
|
|
|
15
15
|
const props = withDefaults(
|
|
16
16
|
defineProps<{
|
|
@@ -33,7 +33,7 @@ const props = withDefaults(
|
|
|
33
33
|
},
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
-
const $slidev =
|
|
36
|
+
const { $slidev } = useSlideContext()
|
|
37
37
|
|
|
38
38
|
function filterTreeDepth(tree: TocItem[], level = 1): TocItem[] {
|
|
39
39
|
if (level > Number(props.maxDepth)) {
|
package/builtin/TocList.vue
CHANGED
|
@@ -10,7 +10,7 @@ Usage:
|
|
|
10
10
|
import { computed } from 'vue'
|
|
11
11
|
import { toArray } from '@antfu/utils'
|
|
12
12
|
import type { TocItem } from '@slidev/types'
|
|
13
|
-
import Titles from '
|
|
13
|
+
import Titles from '#slidev/titles.md'
|
|
14
14
|
|
|
15
15
|
const props = withDefaults(defineProps<{
|
|
16
16
|
level: number
|
|
@@ -65,7 +65,8 @@ const styles = computed(() => {
|
|
|
65
65
|
.slidev-layout .slidev-toc-item p {
|
|
66
66
|
margin: 0;
|
|
67
67
|
}
|
|
68
|
-
.slidev-layout .slidev-toc-item div,
|
|
68
|
+
.slidev-layout .slidev-toc-item div,
|
|
69
|
+
.slidev-layout .slidev-toc-item div p {
|
|
69
70
|
display: initial;
|
|
70
71
|
}
|
|
71
72
|
</style>
|
package/builtin/Tweet.vue
CHANGED
|
@@ -7,8 +7,7 @@ Usage:
|
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
<script setup lang="ts">
|
|
10
|
-
import {
|
|
11
|
-
import { getCurrentInstance, onMounted, ref } from 'vue'
|
|
10
|
+
import { onMounted, ref } from 'vue'
|
|
12
11
|
import { isDark } from '../logic/dark'
|
|
13
12
|
|
|
14
13
|
const props = defineProps<{
|
|
@@ -20,11 +19,10 @@ const props = defineProps<{
|
|
|
20
19
|
|
|
21
20
|
const tweet = ref<HTMLElement | null>()
|
|
22
21
|
|
|
23
|
-
const vm = getCurrentInstance()!
|
|
24
22
|
const loaded = ref(false)
|
|
25
23
|
const tweetNotFound = ref(false)
|
|
26
24
|
|
|
27
|
-
async
|
|
25
|
+
onMounted(async () => {
|
|
28
26
|
// @ts-expect-error global
|
|
29
27
|
const element = await window.twttr.widgets.createTweet(
|
|
30
28
|
props.id.toString(),
|
|
@@ -38,24 +36,7 @@ async function create() {
|
|
|
38
36
|
loaded.value = true
|
|
39
37
|
if (element === undefined)
|
|
40
38
|
tweetNotFound.value = true
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// @ts-expect-error global
|
|
44
|
-
if (window?.twttr?.widgets) {
|
|
45
|
-
onMounted(create)
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
useScriptTag(
|
|
49
|
-
'https://platform.twitter.com/widgets.js',
|
|
50
|
-
() => {
|
|
51
|
-
if (vm.isMounted)
|
|
52
|
-
create()
|
|
53
|
-
else
|
|
54
|
-
onMounted(create, vm)
|
|
55
|
-
},
|
|
56
|
-
{ async: true },
|
|
57
|
-
)
|
|
58
|
-
}
|
|
39
|
+
})
|
|
59
40
|
</script>
|
|
60
41
|
|
|
61
42
|
<template>
|
package/builtin/VClick.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { PropType, VNode } from 'vue'
|
|
8
8
|
import { Text, defineComponent, h } from 'vue'
|
|
9
|
+
import { CLICKS_MAX } from '../constants'
|
|
9
10
|
import VClicks from './VClicks'
|
|
10
11
|
|
|
11
12
|
export default defineComponent({
|
|
@@ -31,7 +32,7 @@ export default defineComponent({
|
|
|
31
32
|
return h(
|
|
32
33
|
VClicks,
|
|
33
34
|
{
|
|
34
|
-
every:
|
|
35
|
+
every: CLICKS_MAX,
|
|
35
36
|
at: this.at,
|
|
36
37
|
hide: this.hide,
|
|
37
38
|
fade: this.fade,
|
package/builtin/VClickGap.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { Fragment,
|
|
3
|
-
import { injectionClicksContext } from '../constants'
|
|
2
|
+
import { Fragment, onMounted, watchEffect } from 'vue'
|
|
4
3
|
import { makeId } from '../logic/utils'
|
|
4
|
+
import { useSlideContext } from '../context'
|
|
5
5
|
|
|
6
6
|
const props = defineProps({
|
|
7
7
|
size: {
|
|
@@ -10,12 +10,10 @@ const props = defineProps({
|
|
|
10
10
|
},
|
|
11
11
|
})
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const { $clicksContext: clicks } = useSlideContext()
|
|
14
14
|
|
|
15
15
|
onMounted(() => {
|
|
16
16
|
watchEffect((onCleanup) => {
|
|
17
|
-
const clicks = clicksRef?.value
|
|
18
|
-
|
|
19
17
|
if (!clicks || clicks.disabled)
|
|
20
18
|
return
|
|
21
19
|
|
package/builtin/VClicks.ts
CHANGED