@slidev/client 53.0.0 → 53.1.0

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 (46) hide show
  1. package/builtin/CodeBlockWrapper.vue +6 -2
  2. package/builtin/KaTexBlockWrapper.test.ts +6 -2
  3. package/builtin/KaTexBlockWrapper.vue +6 -2
  4. package/builtin/Mermaid.vue +3 -1
  5. package/builtin/RenderWhen.vue +9 -3
  6. package/builtin/ShikiMagicMove.vue +6 -2
  7. package/builtin/Toc.vue +3 -1
  8. package/builtin/VAfter.ts +3 -1
  9. package/builtin/VClicks.ts +31 -14
  10. package/builtin/VSwitch.ts +10 -3
  11. package/composables/useClicks.ts +6 -2
  12. package/composables/useDragElements.ts +16 -6
  13. package/composables/useDrawings.ts +3 -1
  14. package/composables/useEmbeddedCtrl.ts +7 -1
  15. package/composables/useNav.test.ts +9 -3
  16. package/composables/useNav.ts +21 -7
  17. package/composables/usePreloadImages.ts +6 -2
  18. package/composables/useSlideInfo.ts +6 -2
  19. package/composables/useViewTransition.ts +7 -1
  20. package/context.ts +3 -1
  21. package/env.ts +3 -1
  22. package/internals/ClicksSlider.vue +6 -2
  23. package/internals/DragControl.vue +34 -9
  24. package/internals/Goto.vue +6 -2
  25. package/internals/NoteDisplay.vue +5 -2
  26. package/internals/NoteStatic.vue +2 -0
  27. package/internals/ShadowRoot.vue +3 -1
  28. package/internals/SideEditor.vue +3 -1
  29. package/internals/SlideContainer.vue +3 -1
  30. package/internals/SlideWrapper.vue +3 -1
  31. package/logic/route.ts +3 -1
  32. package/logic/screenshot.ts +3 -1
  33. package/logic/slidePath.ts +5 -1
  34. package/logic/snapshot.ts +3 -1
  35. package/modules/v-click.ts +10 -4
  36. package/modules/v-mark.ts +20 -10
  37. package/modules/v-motion.ts +34 -9
  38. package/package.json +23 -23
  39. package/pages/overview.vue +17 -5
  40. package/pages/presenter.vue +2 -5
  41. package/setup/code-runners.ts +18 -6
  42. package/setup/context-menu.ts +2 -0
  43. package/setup/shiki-options.ts +11 -2
  44. package/setup/shortcuts.ts +100 -18
  45. package/state/storage.ts +6 -2
  46. package/state/syncState.ts +7 -1
@@ -26,7 +26,9 @@ watch(
26
26
  (v) => {
27
27
  if (!isInputting.value) {
28
28
  note.value = (v?.note || '').trim()
29
- const frontmatterPart = v?.frontmatterRaw?.trim() ? `---\n${v.frontmatterRaw.trim()}\n---\n\n` : ''
29
+ const frontmatterPart = v?.frontmatterRaw?.trim()
30
+ ? `---\n${v.frontmatterRaw.trim()}\n---\n\n`
31
+ : ''
30
32
  content.value = frontmatterPart + (v?.source.contentRaw || '').trim()
31
33
  dirty.value = false
32
34
  }
@@ -41,7 +41,9 @@ const containerSize = useElementSize(container)
41
41
  const slideElement = ref<HTMLElement | null>(null)
42
42
 
43
43
  const width = computed(() => props.width ?? containerSize.width.value)
44
- const height = computed(() => props.width ? props.width / slideAspect.value : containerSize.height.value)
44
+ const height = computed(() => props.width
45
+ ? props.width / slideAspect.value
46
+ : containerSize.height.value)
45
47
 
46
48
  const scale = computed(() => {
47
49
  if (slideScale.value && !isPrintMode.value)
@@ -34,7 +34,9 @@ provideLocal(injectionSlideZoom, zoom)
34
34
 
35
35
  const style = computed<CSSProperties>(() => ({
36
36
  'user-select': configs.selectable ? undefined : 'none',
37
- '--slidev-slide-zoom-scale': zoom.value === 1 ? undefined : zoom.value,
37
+ '--slidev-slide-zoom-scale': zoom.value === 1
38
+ ? undefined
39
+ : zoom.value,
38
40
  }))
39
41
  </script>
40
42
 
package/logic/route.ts CHANGED
@@ -28,7 +28,9 @@ export function useRouteQuery<T extends string | string[]>(
28
28
  router[unref(mode) as 'replace' | 'push']({
29
29
  query: {
30
30
  ...router.currentRoute.value.query,
31
- [name]: `${v}` === defaultValue ? undefined : v,
31
+ [name]: `${v}` === defaultValue
32
+ ? undefined
33
+ : v,
32
34
  },
33
35
  })
34
36
  })
@@ -58,4 +58,6 @@ export async function startScreenshotSession(width: number, height: number) {
58
58
  export type ScreenshotSession = Awaited<ReturnType<typeof startScreenshotSession>>
59
59
 
60
60
  const chromeVersion = window.navigator.userAgent.match(/Chrome\/(\d+)/)?.[1]
61
- export const isScreenshotSupported = chromeVersion ? Number(chromeVersion) >= 94 : false
61
+ export const isScreenshotSupported = chromeVersion
62
+ ? Number(chromeVersion) >= 94
63
+ : false
@@ -6,5 +6,9 @@ export function getSlideRoutePath(
6
6
  exporting: boolean = false,
7
7
  ) {
8
8
  const no = route.meta.slide?.frontmatter.routeAlias ?? route.no
9
- return exporting ? `/export/${no}` : presenter ? `/presenter/${no}` : `/${no}`
9
+ return exporting
10
+ ? `/export/${no}`
11
+ : presenter
12
+ ? `/presenter/${no}`
13
+ : `/${no}`
10
14
  }
package/logic/snapshot.ts CHANGED
@@ -9,7 +9,9 @@ import { startScreenshotSession } from './screenshot'
9
9
  import { getSlide } from './slides'
10
10
 
11
11
  const chromeVersion = window.navigator.userAgent.match(/Chrome\/(\d+)/)?.[1]
12
- export const isScreenshotSupported = chromeVersion ? Number(chromeVersion) >= 94 : false
12
+ export const isScreenshotSupported = chromeVersion
13
+ ? Number(chromeVersion) >= 94
14
+ : false
13
15
 
14
16
  const initialWait = 100
15
17
 
@@ -165,14 +165,20 @@ export function resolveClick(el: Element | string, dir: DirectiveBinding<any>, v
165
165
 
166
166
  ctx.register(el, info)
167
167
 
168
- const isShown = computed(() => flagHide ? !info.isActive.value : info.isActive.value)
168
+ const isShown = computed(() => flagHide
169
+ ? !info.isActive.value
170
+ : info.isActive.value)
169
171
  const visibilityState = computed(() => {
170
172
  if (isShown.value)
171
173
  return 'shown'
172
- if (Number.isFinite(info.end))
173
- return ctx.current < info.start ? 'before' : 'after'
174
- else
174
+ if (Number.isFinite(info.end)) {
175
+ return ctx.current < info.start
176
+ ? 'before'
177
+ : 'after'
178
+ }
179
+ else {
175
180
  return flagHide ? 'after' : 'before'
181
+ }
176
182
  })
177
183
 
178
184
  const resolved = {
package/modules/v-mark.ts CHANGED
@@ -55,17 +55,27 @@ const vMarkModifiers: Record<string, (options: RoughDirectiveOptions, value?: an
55
55
 
56
56
  const vMarkModifiersDynamic: [RegExp, (match: RegExpMatchArray, options: RoughDirectiveOptions, value?: any) => RoughDirectiveOptions][] = [
57
57
  // Support setting delay like `v-mark.delay300="1"`
58
- [/^delay-?(\d+)?$/, (match, options, value) => {
59
- const ms = (match[1] ? Number.parseInt(match[1]) : value) || 300
60
- options.delay = ms
61
- return options
62
- }],
58
+ [
59
+ /^delay-?(\d+)?$/,
60
+ (match, options, value) => {
61
+ const ms = (match[1]
62
+ ? Number.parseInt(match[1])
63
+ : value) || 300
64
+ options.delay = ms
65
+ return options
66
+ },
67
+ ],
63
68
  // Support setting opacity like `v-mark.op50="1"`
64
- [/^(?:op|opacity)-?(\d+)?$/, (match, options, value) => {
65
- const opacity = (match[1] ? Number.parseInt(match[1]) : value) || 100
66
- options.opacity = opacity / 100
67
- return options
68
- }],
69
+ [
70
+ /^(?:op|opacity)-?(\d+)?$/,
71
+ (match, options, value) => {
72
+ const opacity = (match[1]
73
+ ? Number.parseInt(match[1])
74
+ : value) || 100
75
+ options.opacity = opacity / 100
76
+ return options
77
+ },
78
+ ],
69
79
  ]
70
80
 
71
81
  /**
@@ -23,9 +23,18 @@ export function createVMotionDirectives() {
23
23
 
24
24
  const props = node.props = { ...node.props }
25
25
 
26
- const variantInitial = { ...props.initial, ...props.variants?.['slidev-initial'] }
27
- const variantEnter = { ...props.enter, ...props.variants?.['slidev-enter'] }
28
- const variantLeave = { ...props.leave, ...props.variants?.['slidev-leave'] }
26
+ const variantInitial = {
27
+ ...props.initial,
28
+ ...props.variants?.['slidev-initial'],
29
+ }
30
+ const variantEnter = {
31
+ ...props.enter,
32
+ ...props.variants?.['slidev-enter'],
33
+ }
34
+ const variantLeave = {
35
+ ...props.leave,
36
+ ...props.variants?.['slidev-leave'],
37
+ }
29
38
  delete props.initial
30
39
  delete props.enter
31
40
  delete props.leave
@@ -41,7 +50,9 @@ export function createVMotionDirectives() {
41
50
  for (const k of Object.keys(props)) {
42
51
  if (k.startsWith('click-')) {
43
52
  const s = k.slice(6)
44
- const at = s.includes('-') ? s.split('-').map(Number) as [number, number] : +s
53
+ const at = s.includes('-')
54
+ ? s.split('-').map(Number) as [number, number]
55
+ : +s
45
56
  const id = idPrefix + s
46
57
  clicks.push({
47
58
  id,
@@ -53,7 +64,11 @@ export function createVMotionDirectives() {
53
64
  }
54
65
  }
55
66
 
56
- clicks.sort((a, b) => (Array.isArray(a.at) ? a.at[0] : a.at) - (Array.isArray(b.at) ? b.at[0] : b.at))
67
+ clicks.sort((a, b) => (Array.isArray(a.at)
68
+ ? a.at[0]
69
+ : a.at) - (Array.isArray(b.at)
70
+ ? b.at[0]
71
+ : b.at))
57
72
 
58
73
  original.created!(el, binding, node, prevNode)
59
74
  original.mounted!(el, binding, node, prevNode)
@@ -67,7 +82,10 @@ export function createVMotionDirectives() {
67
82
  () => {
68
83
  const visibility = resolvedClickMap.get(el)?.visibilityState.value ?? 'shown'
69
84
  if (!clicksContext?.value || !['slide', 'presenter'].includes(renderContext?.value ?? '')) {
70
- const mixedVariant: Record<string, unknown> = { ...variantInitial, ...variantEnter }
85
+ const mixedVariant: Record<string, unknown> = {
86
+ ...variantInitial,
87
+ ...variantEnter,
88
+ }
71
89
  for (const { variant } of clicks)
72
90
  Object.assign(mixedVariant, variant)
73
91
 
@@ -75,7 +93,10 @@ export function createVMotionDirectives() {
75
93
  }
76
94
  else if (isPrintMode.value || thisPage?.value === currentPage.value) {
77
95
  if (visibility === 'shown') {
78
- const mixedVariant: Record<string, unknown> = { ...variantInitial, ...variantEnter }
96
+ const mixedVariant: Record<string, unknown> = {
97
+ ...variantInitial,
98
+ ...variantEnter,
99
+ }
79
100
  for (const { variant, info } of clicks) {
80
101
  if (!info || info.isActive.value)
81
102
  Object.assign(mixedVariant, variant)
@@ -86,11 +107,15 @@ export function createVMotionDirectives() {
86
107
  motion.apply(mixedVariant)
87
108
  }
88
109
  else {
89
- motion.apply(visibility === 'before' ? variantInitial : variantLeave)
110
+ motion.apply(visibility === 'before'
111
+ ? variantInitial
112
+ : variantLeave)
90
113
  }
91
114
  }
92
115
  else {
93
- motion.apply((thisPage?.value ?? -1) > currentPage.value ? variantInitial : variantLeave)
116
+ motion.apply((thisPage?.value ?? -1) > currentPage.value
117
+ ? variantInitial
118
+ : variantLeave)
94
119
  }
95
120
  },
96
121
  {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@slidev/client",
3
3
  "type": "module",
4
- "version": "53.0.0",
4
+ "version": "53.1.0",
5
5
  "description": "Presentation slides for developers",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -30,46 +30,46 @@
30
30
  "dependencies": {
31
31
  "@antfu/utils": "^9.3.0",
32
32
  "@fix-webm-duration/fix": "^1.0.1",
33
- "@iconify-json/carbon": "^1.2.27",
33
+ "@iconify-json/carbon": "^1.2.29",
34
34
  "@iconify-json/ph": "^1.2.2",
35
35
  "@iconify-json/svg-spinners": "^1.2.4",
36
- "@shikijs/engine-javascript": "^4.4.3",
37
- "@shikijs/magic-move": "^4.4.3",
38
- "@shikijs/monaco": "^4.4.3",
39
- "@shikijs/vitepress-twoslash": "^4.4.3",
40
- "@slidev/parser": "53.0.0",
36
+ "@shikijs/engine-javascript": "^4.6.0",
37
+ "@shikijs/magic-move": "^4.6.0",
38
+ "@shikijs/monaco": "^4.6.0",
39
+ "@shikijs/vitepress-twoslash": "^4.6.0",
40
+ "@slidev/parser": "53.1.0",
41
41
  "@slidev/rough-notation": "^0.1.0",
42
- "@slidev/types": "53.0.0",
42
+ "@slidev/types": "53.1.0",
43
43
  "@typescript/ata": "^0.9.8",
44
- "@unhead/vue": "^3.4.1",
45
- "@unocss/extractor-mdc": "^66.10.4",
46
- "@unocss/preset-mini": "^66.10.4",
47
- "@unocss/reset": "^66.10.4",
48
- "@vueuse/core": "^14.4.0",
49
- "@vueuse/math": "^14.4.0",
44
+ "@unhead/vue": "^3.4.3",
45
+ "@unocss/extractor-mdc": "^66.12.0",
46
+ "@unocss/preset-mini": "^66.12.0",
47
+ "@unocss/reset": "^66.12.0",
48
+ "@vueuse/core": "^15.0.0",
49
+ "@vueuse/math": "^15.0.0",
50
50
  "@vueuse/motion": "^3.0.3",
51
- "ansis": "^4.4.0",
51
+ "ansis": "^4.5.0",
52
52
  "drauu": "^1.0.0",
53
53
  "file-saver": "^2.0.5",
54
54
  "fitty": "^2.4.2",
55
55
  "floating-vue": "^5.4.0",
56
56
  "fuse.js": "^7.5.0",
57
- "katex": "^0.18.7",
57
+ "katex": "^0.19.1",
58
58
  "lz-string": "^1.5.0",
59
59
  "markdown-it-github-alerts": "^1.0.1",
60
- "mermaid": "^12.0.0",
61
- "monaco-editor": "^0.56.0",
60
+ "mermaid": "^12.3.0",
61
+ "monaco-editor": "^0.57.0",
62
62
  "nanotar": "^0.3.0",
63
63
  "pptxgenjs": "^4.0.1",
64
64
  "recordrtc": "^5.6.2",
65
- "shiki": "^4.4.3",
65
+ "shiki": "^4.6.0",
66
66
  "typescript": "^6.0.3",
67
- "unocss": "^66.10.4",
68
- "vue": "^3.5.42",
69
- "vue-router": "^5.3.1",
67
+ "unocss": "^66.12.0",
68
+ "vue": "^3.5.44",
69
+ "vue-router": "^5.4.0",
70
70
  "yaml": "^2.9.1"
71
71
  },
72
72
  "devDependencies": {
73
- "vite": "^8.3.0"
73
+ "vite": "^8.3.6"
74
74
  }
75
75
  }
@@ -101,7 +101,11 @@ function checkActiveBlocks() {
101
101
  active = { idx, visibleHeight }
102
102
  }
103
103
 
104
- activeBlocks.value = fullyVisible.length ? fullyVisible : active ? [active.idx] : []
104
+ activeBlocks.value = fullyVisible.length
105
+ ? fullyVisible
106
+ : active
107
+ ? [active.idx]
108
+ : []
105
109
  }
106
110
 
107
111
  function openSlideInNewTab(path: string) {
@@ -151,7 +155,9 @@ function scrollSlideNoIntoCenter(no: number) {
151
155
  if (start == null)
152
156
  return
153
157
  const top = start
154
- + (end == null ? 0 : (end - start) * progress)
158
+ + (end == null
159
+ ? 0
160
+ : (end - start) * progress)
155
161
  - scroller.value.clientHeight * 0.5
156
162
  if (Math.abs(scroller.value.scrollTop - top) < 1)
157
163
  return
@@ -160,8 +166,12 @@ function scrollSlideNoIntoCenter(no: number) {
160
166
 
161
167
  function getInitialSlideNo() {
162
168
  const value = currentRoute.query.slideNo
163
- const no = Number(Array.isArray(value) ? value[0] : value)
164
- return Number.isFinite(no) && no > 0 ? no : undefined
169
+ const no = Number(Array.isArray(value)
170
+ ? value[0]
171
+ : value)
172
+ return Number.isFinite(no) && no > 0
173
+ ? no
174
+ : undefined
165
175
  }
166
176
 
167
177
  function updateSlideNoQuery(no: number) {
@@ -275,7 +285,9 @@ function openOverviewSlideSource(e: MouseEvent, route: SlideRoute) {
275
285
 
276
286
  onMounted(() => {
277
287
  window.addEventListener('message', onOverviewMessage)
278
- const initialSlideNo = isEmbeddedPreviewMode.value ? getInitialSlideNo() : undefined
288
+ const initialSlideNo = isEmbeddedPreviewMode.value
289
+ ? getInitialSlideNo()
290
+ : undefined
279
291
  if (initialSlideNo != null) {
280
292
  ignoreOverviewScrollUntil = Date.now() + 300
281
293
  scrollSlideNoIntoCenter(initialSlideNo)
@@ -102,7 +102,6 @@ const resizeStartRowSize = ref(280)
102
102
 
103
103
  const RESIZER_LIMITS = {
104
104
  minNotesWidth: 240,
105
- maxNotesWidth: 720,
106
105
  minNotesRowSize: 160,
107
106
  maxNotesWidthRatio: 0.7,
108
107
  maxNotesRowHeightRatio: 0.75,
@@ -120,10 +119,7 @@ const isNotesOnBottom = computed(() => presenterLayout.value === 1 && !isLayout1
120
119
  function clampNotesWidth(width: number) {
121
120
  if (!Number.isFinite(width))
122
121
  return RESIZER_LIMITS.minNotesWidth
123
- return Math.max(
124
- RESIZER_LIMITS.minNotesWidth,
125
- Math.min(RESIZER_LIMITS.maxNotesWidth, Math.round(width)),
126
- )
122
+ return Math.max(RESIZER_LIMITS.minNotesWidth, Math.round(width))
127
123
  }
128
124
 
129
125
  function updateNotesWidthFromPointer(clientX: number) {
@@ -395,6 +391,7 @@ onMounted(() => {
395
391
  class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
396
392
  :style="{ fontSize: `${presenterNotesFontSize}em` }"
397
393
  :clicks-context="clicksContext"
394
+ auto-scroll
398
395
  />
399
396
  <div border-t border-main />
400
397
  <div class="py-1 px-2 text-sm transition" :class="inFocus ? '' : 'op25'">
@@ -65,14 +65,18 @@ export default createSingletonPromise(async () => {
65
65
  function runJavaScript(code: string): CodeRunnerOutputs {
66
66
  const result = ref<CodeRunnerOutput[]>([])
67
67
 
68
- const onError = (error: any) => result.value.push({ error: String(error) })
68
+ const onError = (error: any) => result.value.push({
69
+ error: String(error),
70
+ })
69
71
  const logger = (...objs: any[]) => result.value.push(objs.map(printObject))
70
72
  const vmConsole = Object.assign({}, console)
71
73
  vmConsole.info = vmConsole.log = vmConsole.debug = vmConsole.warn = vmConsole.error = logger
72
74
  vmConsole.clear = () => result.value.length = 0
73
75
  try {
74
76
  const wrappedCode = `return async (console, __slidev_import, __slidev_on_error) => {
75
- ${configs.monacoRunUseStrict ? `"use strict";` : ''}
77
+ ${configs.monacoRunUseStrict
78
+ ? `"use strict";`
79
+ : ''}
76
80
  try {
77
81
  ${fixupCode(code)}
78
82
  } catch (e) {
@@ -119,7 +123,9 @@ function runJavaScript(code: string): CodeRunnerOutputs {
119
123
  textRep = `Set (${arg.size}) {${setIter.map(objectToText).join(', ')}}`
120
124
  }
121
125
  else if (arg instanceof Map) {
122
- const mapIter = [...arg.entries()]
126
+ const mapIter = [
127
+ ...arg.entries(),
128
+ ]
123
129
  textRep
124
130
  = `Map (${arg.size}) {${mapIter
125
131
  .map(([k, v]) => `${objectToText(k)} => ${objectToText(v)}`)
@@ -135,13 +141,19 @@ function runJavaScript(code: string): CodeRunnerOutputs {
135
141
  else if (typeof arg === 'object') {
136
142
  const name = arg.constructor?.name ?? ''
137
143
  // No one needs to know an obj is an obj
138
- const nameWithoutObject = name && name === 'Object' ? '' : name
139
- const prefix = nameWithoutObject ? `${nameWithoutObject}: ` : ''
144
+ const nameWithoutObject = name && name === 'Object'
145
+ ? ''
146
+ : name
147
+ const prefix = nameWithoutObject
148
+ ? `${nameWithoutObject}: `
149
+ : ''
140
150
 
141
151
  // JSON.stringify omits any keys with a value of undefined. To get around this, we replace undefined with the text __undefined__ and then do a global replace using regex back to keyword undefined
142
152
  textRep
143
153
  = prefix
144
- + JSON.stringify(arg, (_, value) => (value === undefined ? '__undefined__' : value), 2).replace(
154
+ + JSON.stringify(arg, (_, value) => (value === undefined
155
+ ? '__undefined__'
156
+ : value), 2).replace(
145
157
  /"__undefined__"/g,
146
158
  'undefined',
147
159
  )
@@ -6,6 +6,7 @@ import { computed } from 'vue'
6
6
  import setups from '#slidev/setups/context-menu'
7
7
  import { useDrawings } from '../composables/useDrawings'
8
8
  import { useNav } from '../composables/useNav'
9
+ import { configs } from '../env'
9
10
  import { fullscreen, showEditor, toggleOverview } from '../state'
10
11
 
11
12
  // @unocss-include
@@ -79,6 +80,7 @@ export default () => {
79
80
  icon: 'i-carbon:pen',
80
81
  label: drawingEnabled.value ? 'Hide drawing toolbar' : 'Show drawing toolbar',
81
82
  action: () => (drawingEnabled.value = !drawingEnabled.value),
83
+ show: __SLIDEV_FEATURE_DRAWINGS__ && (!configs.drawings.presenterOnly || isPresenter.value),
82
84
  },
83
85
  {
84
86
  icon: 'i-carbon:apps',
@@ -37,7 +37,9 @@ export function resolveShikiOptions(options: (ShikiSetupReturn | void)[]) {
37
37
  mergedOptions.defaultColor = false
38
38
 
39
39
  const themeOption = extractThemeName(mergedOptions.theme) || extractThemeNames(mergedOptions.themes || {})
40
- const themeNames = typeof themeOption === 'string' ? [themeOption] : Object.values(themeOption)
40
+ const themeNames = typeof themeOption === 'string'
41
+ ? [themeOption]
42
+ : Object.values(themeOption)
41
43
 
42
44
  const themeInput: Record<string, ThemeInput> = Object.assign({}, bundledThemes)
43
45
  if (typeof mergedOptions.theme === 'object' && mergedOptions.theme?.name) {
@@ -51,7 +53,14 @@ export function resolveShikiOptions(options: (ShikiSetupReturn | void)[]) {
51
53
  }
52
54
  }
53
55
 
54
- const languageNames = new Set<string>(['markdown', 'vue', 'javascript', 'typescript', 'html', 'css'])
56
+ const languageNames = new Set<string>([
57
+ 'markdown',
58
+ 'vue',
59
+ 'javascript',
60
+ 'typescript',
61
+ 'html',
62
+ 'css',
63
+ ])
55
64
  const languageInput: Record<string, LanguageInput> = Object.assign({}, bundledLanguages)
56
65
  for (const option of options) {
57
66
  const langs = option?.langs
@@ -32,24 +32,106 @@ export default function setupShortcuts() {
32
32
  const navViaArrowKeys = and(not(showOverview), not(activeDragElement))
33
33
 
34
34
  let shortcuts: ShortcutOptions[] = [
35
- { name: 'next_space', key: and(space, not(shift)), fn: next, autoRepeat: true },
36
- { name: 'prev_space', key: and(space, shift), fn: prev, autoRepeat: true },
37
- { name: 'next_right', key: and(right, not(shift), navViaArrowKeys), fn: next, autoRepeat: true },
38
- { name: 'prev_left', key: and(left, not(shift), navViaArrowKeys), fn: prev, autoRepeat: true },
39
- { name: 'next_page_key', key: 'pageDown', fn: next, autoRepeat: true },
40
- { name: 'prev_page_key', key: 'pageUp', fn: prev, autoRepeat: true },
41
- { name: 'next_down', key: and(down, navViaArrowKeys), fn: nextSlide, autoRepeat: true },
42
- { name: 'prev_up', key: and(up, navViaArrowKeys), fn: prevSlide, autoRepeat: true },
43
- { name: 'next_shift', key: and(right, shift), fn: nextSlide, autoRepeat: true },
44
- { name: 'prev_shift', key: and(left, shift), fn: prevSlide, autoRepeat: true },
45
- { name: 'toggle_dark', key: and(d, not(drawingEnabled)), fn: toggleDark },
46
- { name: 'toggle_overview', key: and(or(o, backtick), not(drawingEnabled)), fn: toggleOverview },
47
- { name: 'hide_overview', key: and(escape, not(drawingEnabled)), fn: () => showOverview.value = false },
48
- { name: 'goto', key: and(g, not(drawingEnabled)), fn: () => showGotoDialog.value = !showGotoDialog.value },
49
- { name: 'next_overview', key: and(right, showOverview), fn: nextOverviewPage },
50
- { name: 'prev_overview', key: and(left, showOverview), fn: prevOverviewPage },
51
- { name: 'up_overview', key: and(up, showOverview), fn: upOverviewPage },
52
- { name: 'down_overview', key: and(down, showOverview), fn: downOverviewPage },
35
+ {
36
+ name: 'next_space',
37
+ key: and(space, not(shift)),
38
+ fn: next,
39
+ autoRepeat: true,
40
+ },
41
+ {
42
+ name: 'prev_space',
43
+ key: and(space, shift),
44
+ fn: prev,
45
+ autoRepeat: true,
46
+ },
47
+ {
48
+ name: 'next_right',
49
+ key: and(right, not(shift), navViaArrowKeys),
50
+ fn: next,
51
+ autoRepeat: true,
52
+ },
53
+ {
54
+ name: 'prev_left',
55
+ key: and(left, not(shift), navViaArrowKeys),
56
+ fn: prev,
57
+ autoRepeat: true,
58
+ },
59
+ {
60
+ name: 'next_page_key',
61
+ key: 'pageDown',
62
+ fn: next,
63
+ autoRepeat: true,
64
+ },
65
+ {
66
+ name: 'prev_page_key',
67
+ key: 'pageUp',
68
+ fn: prev,
69
+ autoRepeat: true,
70
+ },
71
+ {
72
+ name: 'next_down',
73
+ key: and(down, navViaArrowKeys),
74
+ fn: nextSlide,
75
+ autoRepeat: true,
76
+ },
77
+ {
78
+ name: 'prev_up',
79
+ key: and(up, navViaArrowKeys),
80
+ fn: prevSlide,
81
+ autoRepeat: true,
82
+ },
83
+ {
84
+ name: 'next_shift',
85
+ key: and(right, shift),
86
+ fn: nextSlide,
87
+ autoRepeat: true,
88
+ },
89
+ {
90
+ name: 'prev_shift',
91
+ key: and(left, shift),
92
+ fn: prevSlide,
93
+ autoRepeat: true,
94
+ },
95
+ {
96
+ name: 'toggle_dark',
97
+ key: and(d, not(drawingEnabled)),
98
+ fn: toggleDark,
99
+ },
100
+ {
101
+ name: 'toggle_overview',
102
+ key: and(or(o, backtick), not(drawingEnabled)),
103
+ fn: toggleOverview,
104
+ },
105
+ {
106
+ name: 'hide_overview',
107
+ key: and(escape, not(drawingEnabled)),
108
+ fn: () => showOverview.value = false,
109
+ },
110
+ {
111
+ name: 'goto',
112
+ key: and(g, not(drawingEnabled)),
113
+ fn: () => showGotoDialog.value = !showGotoDialog.value,
114
+ },
115
+ {
116
+ name: 'next_overview',
117
+ key: and(right, showOverview),
118
+ fn: nextOverviewPage,
119
+ },
120
+ {
121
+ name: 'prev_overview',
122
+ key: and(left, showOverview),
123
+ fn: prevOverviewPage,
124
+ },
125
+ {
126
+ name: 'up_overview',
127
+ key: and(up, showOverview),
128
+ fn: upOverviewPage,
129
+ },
130
+ {
131
+ name: 'down_overview',
132
+ key: and(down, showOverview),
133
+ fn: downOverviewPage,
134
+ },
53
135
  {
54
136
  name: 'goto_from_overview',
55
137
  key: and(enter, showOverview),
package/state/storage.ts CHANGED
@@ -64,8 +64,12 @@ export function togglePresenterCursor() {
64
64
 
65
65
  export const showEditor = useLocalStorage('slidev-show-editor', false, { listenToStorageChanges: false })
66
66
  export const isEditorVertical = useLocalStorage('slidev-editor-vertical', false, { listenToStorageChanges: false })
67
- export const editorWidth = useLocalStorage('slidev-editor-width', isClient ? window.innerWidth * 0.4 : 318, { listenToStorageChanges: false })
68
- export const editorHeight = useLocalStorage('slidev-editor-height', isClient ? window.innerHeight * 0.4 : 300, { listenToStorageChanges: false })
67
+ export const editorWidth = useLocalStorage('slidev-editor-width', isClient
68
+ ? window.innerWidth * 0.4
69
+ : 318, { listenToStorageChanges: false })
70
+ export const editorHeight = useLocalStorage('slidev-editor-height', isClient
71
+ ? window.innerHeight * 0.4
72
+ : 300, { listenToStorageChanges: false })
69
73
 
70
74
  export const activeDragElement = shallowRef<DragElementState | null>(null)
71
75
 
@@ -118,5 +118,11 @@ export function createSyncState<State extends object>(serverState: State, defaul
118
118
  watch(state, onStateChanged, { deep: true })
119
119
  }
120
120
 
121
- return { init, onPatch, onUpdate, patch, state }
121
+ return {
122
+ init,
123
+ onPatch,
124
+ onUpdate,
125
+ patch,
126
+ state,
127
+ }
122
128
  }