@slidev/client 0.48.0-beta.2 → 0.48.0-beta.21

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.
Files changed (91) hide show
  1. package/App.vue +7 -0
  2. package/builtin/Arrow.vue +2 -4
  3. package/builtin/CodeBlockWrapper.vue +14 -6
  4. package/builtin/KaTexBlockWrapper.vue +5 -4
  5. package/builtin/Mermaid.vue +4 -3
  6. package/builtin/Monaco.vue +109 -92
  7. package/builtin/RenderWhen.vue +3 -3
  8. package/builtin/ShikiMagicMove.vue +50 -0
  9. package/builtin/SlideCurrentNo.vue +2 -3
  10. package/builtin/SlidesTotal.vue +3 -4
  11. package/builtin/SlidevVideo.vue +9 -7
  12. package/builtin/Toc.vue +4 -4
  13. package/builtin/TocList.vue +4 -3
  14. package/builtin/Tweet.vue +3 -22
  15. package/builtin/VClick.ts +2 -1
  16. package/builtin/VClickGap.vue +3 -5
  17. package/builtin/VClicks.ts +1 -1
  18. package/composables/useClicks.ts +39 -20
  19. package/composables/useContext.ts +4 -9
  20. package/composables/useNav.ts +182 -44
  21. package/composables/useSwipeControls.ts +40 -0
  22. package/composables/useTocTree.ts +63 -0
  23. package/constants.ts +59 -10
  24. package/context.ts +73 -0
  25. package/env.ts +3 -12
  26. package/internals/ClicksSlider.vue +93 -0
  27. package/internals/Controls.vue +2 -2
  28. package/internals/DrawingControls.vue +39 -9
  29. package/internals/DrawingLayer.vue +3 -3
  30. package/internals/Goto.vue +7 -6
  31. package/internals/IconButton.vue +7 -3
  32. package/internals/InfoDialog.vue +1 -1
  33. package/internals/Modal.vue +1 -1
  34. package/internals/NavControls.vue +11 -10
  35. package/internals/NoteDisplay.vue +131 -8
  36. package/internals/NoteEditable.vue +128 -0
  37. package/internals/NoteStatic.vue +8 -6
  38. package/internals/PrintContainer.vue +8 -6
  39. package/internals/PrintSlide.vue +10 -11
  40. package/internals/PrintSlideClick.vue +14 -18
  41. package/internals/{SlidesOverview.vue → QuickOverview.vue} +31 -20
  42. package/internals/RecordingControls.vue +1 -1
  43. package/internals/RecordingDialog.vue +5 -6
  44. package/internals/{Editor.vue → SideEditor.vue} +9 -5
  45. package/internals/SlideContainer.vue +12 -9
  46. package/internals/SlideLoading.vue +19 -0
  47. package/internals/SlideWrapper.ts +32 -16
  48. package/internals/SlidesShow.vue +20 -18
  49. package/layouts/error.vue +5 -0
  50. package/layouts/two-cols-header.vue +9 -3
  51. package/logic/drawings.ts +13 -10
  52. package/logic/nav-state.ts +20 -0
  53. package/logic/nav.ts +51 -258
  54. package/logic/note.ts +9 -9
  55. package/logic/overview.ts +2 -2
  56. package/logic/route.ts +10 -1
  57. package/logic/slides.ts +19 -0
  58. package/logic/transition.ts +50 -0
  59. package/main.ts +8 -4
  60. package/modules/context.ts +7 -13
  61. package/modules/mermaid.ts +6 -7
  62. package/modules/{directives.ts → v-click.ts} +15 -15
  63. package/modules/v-mark.ts +159 -0
  64. package/package.json +27 -16
  65. package/{internals/EntrySelect.vue → pages/entry.vue} +7 -0
  66. package/{internals/NotesView.vue → pages/notes.vue} +7 -6
  67. package/pages/overview.vue +227 -0
  68. package/{internals/Play.vue → pages/play.vue} +17 -13
  69. package/{internals/PresenterPrint.vue → pages/presenter/print.vue} +13 -8
  70. package/{internals/Presenter.vue → pages/presenter.vue} +114 -105
  71. package/{internals/Print.vue → pages/print.vue} +3 -4
  72. package/routes.ts +28 -60
  73. package/setup/codemirror.ts +8 -3
  74. package/setup/monaco.ts +108 -44
  75. package/setup/root.ts +8 -9
  76. package/setup/shortcuts.ts +2 -1
  77. package/shim-vue.d.ts +38 -0
  78. package/shim.d.ts +1 -13
  79. package/state/index.ts +10 -10
  80. package/styles/code.css +7 -3
  81. package/styles/index.css +68 -7
  82. package/styles/katex.css +1 -1
  83. package/styles/layouts-base.css +17 -12
  84. package/styles/monaco.css +27 -0
  85. package/styles/vars.css +1 -0
  86. package/uno.config.ts +14 -2
  87. package/utils.ts +15 -2
  88. package/iframes/monaco/index.css +0 -28
  89. package/iframes/monaco/index.html +0 -7
  90. package/iframes/monaco/index.ts +0 -260
  91. package/internals/NoteEditor.vue +0 -88
@@ -1,28 +0,0 @@
1
- html,
2
- body,
3
- #container {
4
- padding: 0;
5
- margin: 0;
6
- background: var(--slidev-code-background);
7
- width: 100%;
8
- height: 200%;
9
- }
10
-
11
- #container {
12
- padding: var(--slidev-code-padding);
13
- margin: var(--slidev-code-margin);
14
- border-radius: var(--slidev-code-radius);
15
- }
16
-
17
- .monaco-editor .monaco-hover {
18
- border-radius: var(--slidev-code-radius);
19
- overflow: hidden;
20
- border: none;
21
- outline: none;
22
- }
23
-
24
- .monaco-editor .lines-content,
25
- .monaco-editor .view-line,
26
- .monaco-editor .view-lines {
27
- user-select: none;
28
- }
@@ -1,7 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <body>
4
- <div id="container"></div>
5
- <script type="module" src="./index.ts"></script>
6
- </body>
7
- </html>
@@ -1,260 +0,0 @@
1
- import '/@slidev/styles'
2
- import './index.css'
3
-
4
- import type * as monaco from 'monaco-editor'
5
- import { formatCode } from '../../setup/prettier'
6
- import setupMonaco from '../../setup/monaco'
7
- import '/@slidev/monaco-types'
8
-
9
- const url = new URL(location.href)
10
- const props = {
11
- id: url.searchParams.get('id'),
12
- code: '',
13
- diff: '',
14
- lang: url.searchParams.get('lang') ?? 'typescript',
15
- readonly: false,
16
- lineNumbers: url.searchParams.get('lineNumbers') ?? 'off',
17
- dark: false,
18
- style: '',
19
- editorOptions: {},
20
- }
21
-
22
- const styleObject = document.createElement('style')
23
- let originalEditor: monaco.editor.IStandaloneCodeEditor
24
- let modifiedEditor: monaco.editor.IStandaloneCodeEditor
25
- let format: () => void = () => { }
26
- let update: () => void = () => { }
27
-
28
- document.body.appendChild(styleObject)
29
-
30
- function lang() {
31
- switch (props.lang) {
32
- case 'ts':
33
- case 'tsx':
34
- return 'typescript'
35
- case 'jsx':
36
- case 'js':
37
- return 'javascript'
38
- default:
39
- return props.lang
40
- }
41
- }
42
-
43
- function ext() {
44
- switch (lang()) {
45
- case 'typescript':
46
- return 'ts'
47
- case 'javascript':
48
- return 'js'
49
- default:
50
- return lang()
51
- }
52
- }
53
-
54
- function post(data: any, type = 'slidev-monaco') {
55
- if (window.parent === window)
56
- return
57
-
58
- window.parent.postMessage(
59
- {
60
- type,
61
- id: props.id,
62
- data,
63
- },
64
- location.origin,
65
- )
66
- }
67
-
68
- async function start() {
69
- const { monaco, theme = {}, editorOptions = {} } = await setupMonaco()
70
-
71
- const style = getComputedStyle(document.documentElement)
72
- const container = document.getElementById('container')!
73
-
74
- const model = monaco.editor.createModel(
75
- props.code,
76
- lang(),
77
- monaco.Uri.parse(`file:///root/${Date.now()}.${ext()}`),
78
- )
79
-
80
- if (url.searchParams.get('diff')) {
81
- // Diff editor
82
- const diffModel = monaco.editor.createModel(
83
- props.diff,
84
- lang(),
85
- monaco.Uri.parse(`file:///root/${Date.now()}.${ext()}`),
86
- )
87
- const monacoEditor = monaco.editor.createDiffEditor(container, {
88
- fontSize: +style.getPropertyValue('--slidev-code-font-size').replace(/px/g, ''),
89
- fontFamily: style.getPropertyValue('--slidev-code-font-family'),
90
- lineHeight: +style.getPropertyValue('--slidev-code-line-height').replace(/px/g, ''),
91
- lineDecorationsWidth: 0,
92
- lineNumbersMinChars: 0,
93
- scrollBeyondLastLine: false,
94
- scrollBeyondLastColumn: 0,
95
- automaticLayout: true,
96
- readOnly: props.readonly,
97
- theme: 'vitesse-dark',
98
- lineNumbers: props.lineNumbers as any,
99
- glyphMargin: false,
100
- scrollbar: {
101
- useShadows: false,
102
- vertical: 'hidden',
103
- horizontal: 'hidden',
104
- },
105
- overviewRulerLanes: 0,
106
- minimap: { enabled: false },
107
- enableSplitViewResizing: false,
108
- renderOverviewRuler: false,
109
- // renderSideBySide: false,
110
- ...editorOptions,
111
- })
112
- monacoEditor.setModel({
113
- original: model,
114
- modified: diffModel,
115
- })
116
- originalEditor = monacoEditor.getOriginalEditor()
117
- modifiedEditor = monacoEditor.getModifiedEditor()
118
-
119
- format = async () => {
120
- model.setValue((await formatCode(props.code, lang())).trim())
121
- diffModel.setValue((await formatCode(props.diff, lang())).trim())
122
- }
123
-
124
- // ctrl+s to format
125
- originalEditor.onKeyDown((e) => {
126
- if ((e.ctrlKey || e.metaKey) && e.code === 'KeyS') {
127
- e.preventDefault()
128
- format()
129
- }
130
- })
131
- modifiedEditor.onKeyDown((e) => {
132
- if ((e.ctrlKey || e.metaKey) && e.code === 'KeyS') {
133
- e.preventDefault()
134
- format()
135
- }
136
- })
137
-
138
- update = () => {
139
- monaco.editor.setTheme(props.dark
140
- ? (theme.dark || 'vitesse-dark')
141
- : (theme.light || 'vitesse-light'))
142
- styleObject.innerHTML = `:root { ${props.style} }`
143
-
144
- if (originalEditor.getValue().toString() !== props.code) {
145
- const selection = originalEditor.getSelection()
146
- originalEditor.setValue(props.code)
147
- if (selection)
148
- originalEditor.setSelection(selection)
149
- }
150
- originalEditor.updateOptions(props.editorOptions)
151
-
152
- if (modifiedEditor.getValue().toString() !== props.diff) {
153
- const selection = modifiedEditor.getSelection()
154
- modifiedEditor.setValue(props.diff)
155
- if (selection)
156
- modifiedEditor.setSelection(selection)
157
- }
158
- modifiedEditor.updateOptions(props.editorOptions)
159
- }
160
-
161
- diffModel.onDidChangeContent(() => {
162
- onCodeChange(diffModel.getValue().toString())
163
- })
164
-
165
- function onCodeChange(diff: string) {
166
- props.diff = diff
167
- post({ diff })
168
- }
169
- }
170
- else {
171
- // Normal editor
172
- originalEditor = monaco.editor.create(container, {
173
- model,
174
- tabSize: 2,
175
- insertSpaces: true,
176
- detectIndentation: false,
177
- folding: false,
178
- fontSize: +style.getPropertyValue('--slidev-code-font-size').replace(/px/g, ''),
179
- fontFamily: style.getPropertyValue('--slidev-code-font-family'),
180
- lineHeight: +style.getPropertyValue('--slidev-code-line-height').replace(/px/g, ''),
181
- lineDecorationsWidth: 0,
182
- lineNumbersMinChars: 0,
183
- scrollBeyondLastLine: false,
184
- scrollBeyondLastColumn: 0,
185
- automaticLayout: true,
186
- readOnly: props.readonly,
187
- theme: 'vitesse-dark',
188
- lineNumbers: props.lineNumbers as any,
189
- glyphMargin: false,
190
- scrollbar: {
191
- useShadows: false,
192
- vertical: 'hidden',
193
- horizontal: 'hidden',
194
- },
195
- overviewRulerLanes: 0,
196
- minimap: { enabled: false },
197
- ...editorOptions,
198
- })
199
-
200
- format = async () => {
201
- model.setValue((await formatCode(props.code, lang())).trim())
202
- }
203
-
204
- // ctrl+s to format
205
- originalEditor.onKeyDown((e) => {
206
- if ((e.ctrlKey || e.metaKey) && e.code === 'KeyS') {
207
- e.preventDefault()
208
- format()
209
- }
210
- })
211
-
212
- update = () => {
213
- monaco.editor.setTheme(props.dark
214
- ? (theme.dark || 'vitesse-dark')
215
- : (theme.light || 'vitesse-light'))
216
- styleObject.innerHTML = `:root { ${props.style} }`
217
-
218
- if (originalEditor.getValue().toString() !== props.code) {
219
- const selection = originalEditor.getSelection()
220
- originalEditor.setValue(props.code)
221
- if (selection)
222
- originalEditor.setSelection(selection)
223
- }
224
- originalEditor.updateOptions(props.editorOptions)
225
- }
226
- }
227
-
228
- originalEditor.onDidContentSizeChange(() => {
229
- post({ height: Math.max(originalEditor.getContentHeight(), modifiedEditor?.getContentHeight() ?? 0) })
230
- })
231
-
232
- model.onDidChangeContent(() => {
233
- onCodeChange(model.getValue().toString())
234
- })
235
-
236
- function onCodeChange(code: string) {
237
- props.code = code
238
- post({ code })
239
- }
240
-
241
- update()
242
-
243
- post({}, 'slidev-monaco-loaded')
244
- }
245
-
246
- window.addEventListener('message', (payload) => {
247
- if (payload.source === window)
248
- return
249
- if (payload.origin !== location.origin)
250
- return
251
- if (typeof payload.data !== 'string')
252
- return
253
- const { type, data, id } = JSON.parse(payload.data)
254
- if (type === 'slidev-monaco' && id === props.id) {
255
- Object.assign(props, data)
256
- update()
257
- }
258
- })
259
-
260
- start()
@@ -1,88 +0,0 @@
1
- <script setup lang="ts">
2
- import { ignorableWatch, onClickOutside, useVModel } from '@vueuse/core'
3
- import { ref, watch, watchEffect } from 'vue'
4
- import { currentSlideId } from '../logic/nav'
5
- import { useDynamicSlideInfo } from '../logic/note'
6
- import NoteDisplay from './NoteDisplay.vue'
7
-
8
- const props = defineProps({
9
- class: {
10
- default: '',
11
- },
12
- editing: {
13
- default: false,
14
- },
15
- style: {
16
- default: () => ({}),
17
- },
18
- placeholder: {
19
- default: 'No notes for this slide',
20
- },
21
- })
22
-
23
- const emit = defineEmits([
24
- 'update:editing',
25
- ])
26
- const editing = useVModel(props, 'editing', emit, { passive: true })
27
-
28
- const { info, update } = useDynamicSlideInfo(currentSlideId)
29
-
30
- const note = ref('')
31
- let timer: any
32
-
33
- const { ignoreUpdates } = ignorableWatch(
34
- note,
35
- (v) => {
36
- const id = currentSlideId.value
37
- clearTimeout(timer)
38
- timer = setTimeout(() => {
39
- update({ raw: null!, note: v }, id)
40
- }, 500)
41
- },
42
- )
43
-
44
- watch(
45
- info,
46
- (v) => {
47
- clearTimeout(timer)
48
- ignoreUpdates(() => {
49
- note.value = v?.note || ''
50
- })
51
- },
52
- { immediate: true, flush: 'sync' },
53
- )
54
-
55
- const input = ref<HTMLTextAreaElement>()
56
-
57
- watchEffect(() => {
58
- if (editing.value)
59
- input.value?.focus()
60
- })
61
-
62
- onClickOutside(input, () => {
63
- editing.value = false
64
- })
65
- </script>
66
-
67
- <template>
68
- <NoteDisplay
69
- v-if="!editing"
70
- class="my--4 border-transparent border-2"
71
- :class="[props.class, note ? '' : 'opacity-50']"
72
- :style="props.style"
73
- :note="note || placeholder"
74
- :note-html="info?.noteHTML"
75
- />
76
- <textarea
77
- v-else
78
- ref="input"
79
- v-model="note"
80
- class="prose resize-none overflow-auto outline-none bg-transparent block border-green border-2"
81
- style="line-height: 1.75;"
82
- :style="props.style"
83
- :class="props.class"
84
- :placeholder="placeholder"
85
- @keydown.esc=" editing = false"
86
- @focus="editing = true"
87
- />
88
- </template>