@slidev/client 0.48.2 → 0.48.4

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.
@@ -60,17 +60,13 @@ watchEffect(() => {
60
60
  })
61
61
 
62
62
  onMounted(() => {
63
- if (!clicks || clicks.disabled || !props.ranges?.length)
63
+ if (!clicks || !props.ranges?.length)
64
64
  return
65
65
 
66
66
  const { start, end, delta } = clicks.resolve(props.at, props.ranges.length - 1)
67
67
  clicks.register(id, { max: end, delta })
68
68
 
69
- const index = computed(() => {
70
- if (clicks.disabled)
71
- return props.ranges.length - 1
72
- return Math.max(0, clicks.current - start + 1)
73
- })
69
+ const index = computed(() => Math.max(0, clicks.current - start + 1))
74
70
 
75
71
  const finallyRange = computed(() => {
76
72
  return props.finally === 'last' ? props.ranges.at(-1) : props.finally.toString()
@@ -55,17 +55,13 @@ onUnmounted(() => {
55
55
  })
56
56
 
57
57
  onMounted(() => {
58
- if (!clicks || clicks.disabled || !props.ranges?.length)
58
+ if (!clicks || !props.ranges?.length)
59
59
  return
60
60
 
61
61
  const { start, end, delta } = clicks.resolve(props.at, props.ranges.length - 1)
62
62
  clicks.register(id, { max: end, delta })
63
63
 
64
- const index = computed(() => {
65
- if (clicks.disabled)
66
- return props.ranges.length - 1
67
- return Math.max(0, clicks.current - start + 1)
68
- })
64
+ const index = computed(() => Math.max(0, clicks.current - start + 1))
69
65
 
70
66
  const finallyRange = computed(() => {
71
67
  return props.finally === 'last' ? props.ranges.at(-1) : props.finally.toString()
@@ -3,8 +3,9 @@ import type { RenderContext } from '@slidev/types'
3
3
  import { computed, ref } from 'vue'
4
4
  import { useElementVisibility } from '@vueuse/core'
5
5
  import { useSlideContext } from '../context'
6
+ import { useNav } from '../composables/useNav'
6
7
 
7
- type Context = 'main' | 'visible' | RenderContext
8
+ type Context = 'main' | 'visible' | 'print' | RenderContext
8
9
 
9
10
  const props = defineProps<{
10
11
  context: Context | Context[]
@@ -17,6 +18,7 @@ const targetVisible = useElementVisibility(target)
17
18
  const needsDomWrapper = Array.isArray(context) ? context.includes('visible') : context === 'visible'
18
19
 
19
20
  const { $renderContext: currentContext } = useSlideContext()
21
+ const { isPrintMode } = useNav()
20
22
  const shouldRender = computed(() => {
21
23
  const anyContext = Array.isArray(context) ? context.some(contextMatch) : contextMatch(context)
22
24
  const allConditions = Array.isArray(context) ? context.every(conditionsMatch) : conditionsMatch(context)
@@ -30,6 +32,8 @@ function contextMatch(context: Context) {
30
32
  return true
31
33
  if (context === 'visible')
32
34
  return true
35
+ if (context === 'print' && isPrintMode.value)
36
+ return true
33
37
  return false
34
38
  }
35
39
 
@@ -43,6 +47,8 @@ function conditionsMatch(context: Context) {
43
47
  <template>
44
48
  <div v-if="needsDomWrapper" ref="target">
45
49
  <slot v-if="shouldRender" />
50
+ <slot v-else name="fallback" />
46
51
  </div>
47
52
  <slot v-else-if="shouldRender" />
53
+ <slot v-else name="fallback" />
48
54
  </template>
@@ -5,6 +5,7 @@ import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
5
5
  import lz from 'lz-string'
6
6
  import { useSlideContext } from '../context'
7
7
  import { makeId, updateCodeHighlightRange } from '../logic/utils'
8
+ import { useNav } from '../composables/useNav'
8
9
 
9
10
  const props = defineProps<{
10
11
  at?: string | number
@@ -13,7 +14,8 @@ const props = defineProps<{
13
14
  }>()
14
15
 
15
16
  const steps = JSON.parse(lz.decompressFromBase64(props.stepsLz)) as KeyedTokensInfo[]
16
- const { $clicksContext: clicks, $scale: scale } = useSlideContext()
17
+ const { $clicksContext: clicks, $scale: scale, $zoom: zoom } = useSlideContext()
18
+ const { isPrintMode } = useNav()
17
19
  const id = makeId()
18
20
 
19
21
  const stepIndex = ref(0)
@@ -23,11 +25,11 @@ const container = ref<HTMLElement>()
23
25
  const ranges = computed(() => props.stepRanges.map(i => i.length ? i : ['all']))
24
26
 
25
27
  onUnmounted(() => {
26
- clicks!.unregister(id)
28
+ clicks?.unregister(id)
27
29
  })
28
30
 
29
31
  onMounted(() => {
30
- if (!clicks || clicks.disabled)
32
+ if (!clicks)
31
33
  return
32
34
 
33
35
  if (ranges.value.length !== steps.length)
@@ -92,8 +94,9 @@ onMounted(() => {
92
94
  class="slidev-code relative shiki overflow-visible"
93
95
  :steps="steps"
94
96
  :step="stepIndex"
97
+ :animate="!isPrintMode"
95
98
  :options="{
96
- globalScale: scale,
99
+ globalScale: scale * zoom,
97
100
  // TODO: make this configurable later
98
101
  duration: 800,
99
102
  stagger: 1,
@@ -26,7 +26,7 @@ const matchRoute = computed(() => {
26
26
  })
27
27
 
28
28
  const matchClick = computed(() => {
29
- if (!video.value || currentContext?.value !== 'slide' || clicks?.disabled || clicks?.current === undefined)
29
+ if (!video.value || currentContext?.value !== 'slide' || !clicks)
30
30
  return false
31
31
  return clicks.map.get(video.value)?.isShown?.value ?? true
32
32
  })
@@ -14,7 +14,7 @@ const { $clicksContext: clicks } = useSlideContext()
14
14
 
15
15
  onMounted(() => {
16
16
  watchEffect((onCleanup) => {
17
- if (!clicks || clicks.disabled)
17
+ if (!clicks)
18
18
  return
19
19
 
20
20
  let delta = +props.size
@@ -8,15 +8,11 @@ import { routeForceRefresh } from '../logic/route'
8
8
  export function createClicksContextBase(
9
9
  current: Ref<number>,
10
10
  clicksOverrides?: number,
11
- isDisabled?: () => boolean,
12
11
  ): ClicksContext {
13
12
  const relativeOffsets: ClicksContext['relativeOffsets'] = new Map()
14
13
  const map: ClicksContext['map'] = shallowReactive(new Map())
15
14
 
16
15
  return {
17
- get disabled() {
18
- return isDisabled ? isDisabled() : false
19
- },
20
16
  get current() {
21
17
  return +current.value
22
18
  },
@@ -25,7 +21,7 @@ export function createClicksContextBase(
25
21
  },
26
22
  relativeOffsets,
27
23
  map,
28
- onMounted() {},
24
+ onMounted() { },
29
25
  resolve(at, size = 1) {
30
26
  const [isRelative, value] = normalizeAtProp(at)
31
27
  if (isRelative) {
@@ -68,7 +64,6 @@ export function createClicksContextBase(
68
64
  export function createFixedClicks(
69
65
  route?: SlideRoute | undefined,
70
66
  currentInit = 0,
71
- isDisabled?: () => boolean,
72
67
  ): ClicksContext {
73
- return createClicksContextBase(ref(currentInit), route?.meta?.clicks, isDisabled)
68
+ return createClicksContextBase(ref(currentInit), route?.meta?.clicks)
74
69
  }
@@ -259,8 +259,6 @@ const useNavState = createSharedComposable((): SlidevContextNavState => {
259
259
 
260
260
  const queryClicks = computed({
261
261
  get() {
262
- if (clicksContext.value.disabled)
263
- return CLICKS_MAX
264
262
  let v = +(queryClicksRaw.value || 0)
265
263
  if (Number.isNaN(v))
266
264
  v = 0
@@ -281,8 +279,6 @@ const useNavState = createSharedComposable((): SlidevContextNavState => {
281
279
  const context = createClicksContextBase(
282
280
  computed({
283
281
  get() {
284
- if (context.disabled)
285
- return CLICKS_MAX
286
282
  if (currentSlideNo.value === thisNo)
287
283
  return +(queryClicksRaw.value || 0) || 0
288
284
  else if (currentSlideNo.value > thisNo)
@@ -296,7 +292,6 @@ const useNavState = createSharedComposable((): SlidevContextNavState => {
296
292
  },
297
293
  }),
298
294
  route?.meta?.clicks,
299
- () => isPrintMode.value && !isPrintWithClicks.value,
300
295
  )
301
296
 
302
297
  // On slide mounted, make sure the query is not greater than the total
package/constants.ts CHANGED
@@ -12,6 +12,7 @@ export const injectionRoute = '$$slidev-route' as unknown as InjectionKey<SlideR
12
12
  export const injectionRenderContext = '$$slidev-render-context' as unknown as InjectionKey<Ref<RenderContext>>
13
13
  export const injectionActive = '$$slidev-active' as unknown as InjectionKey<Ref<boolean>>
14
14
  export const injectionFrontmatter = '$$slidev-fontmatter' as unknown as InjectionKey<Record<string, any>>
15
+ export const injectionSlideZoom = '$$slidev-slide-zoom' as unknown as InjectionKey<ComputedRef<number>>
15
16
 
16
17
  export const CLASS_VCLICK_TARGET = 'slidev-vclick-target'
17
18
  export const CLASS_VCLICK_HIDDEN = 'slidev-vclick-hidden'
package/context.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ref, toRef } from 'vue'
1
+ import { computed, ref, toRef } from 'vue'
2
2
  import { injectLocal, objectOmit, provideLocal } from '@vueuse/core'
3
3
  import {
4
4
  FRONTMATTER_FIELDS,
@@ -9,6 +9,7 @@ import {
9
9
  injectionRenderContext,
10
10
  injectionRoute,
11
11
  injectionSlideScale,
12
+ injectionSlideZoom,
12
13
  injectionSlidevContext,
13
14
  } from './constants'
14
15
 
@@ -24,7 +25,8 @@ export function useSlideContext() {
24
25
  const $renderContext = injectLocal(injectionRenderContext)!
25
26
  const $frontmatter = injectLocal(injectionFrontmatter, {})
26
27
  const $route = injectLocal(injectionRoute, undefined)
27
- const $scale = injectLocal(injectionSlideScale, ref(1))!
28
+ const $scale = injectLocal(injectionSlideScale, ref(1))
29
+ const $zoom = injectLocal(injectionSlideZoom, computed(() => 1))
28
30
 
29
31
  return {
30
32
  $slidev,
@@ -36,6 +38,7 @@ export function useSlideContext() {
36
38
  $renderContext,
37
39
  $frontmatter,
38
40
  $scale,
41
+ $zoom,
39
42
  }
40
43
  }
41
44
 
@@ -2,11 +2,12 @@
2
2
  import type { SlideRoute } from '@slidev/types'
3
3
  import { useFixedNav, useNav } from '../composables/useNav'
4
4
  import { createFixedClicks } from '../composables/useClicks'
5
+ import { CLICKS_MAX } from '../constants'
5
6
  import PrintSlideClick from './PrintSlideClick.vue'
6
7
 
7
8
  const { route } = defineProps<{ route: SlideRoute }>()
8
9
  const { isPrintWithClicks } = useNav()
9
- const clicks0 = createFixedClicks(route, 0, () => !isPrintWithClicks.value)
10
+ const clicks0 = createFixedClicks(route, isPrintWithClicks.value ? 0 : CLICKS_MAX)
10
11
  </script>
11
12
 
12
13
  <template>
@@ -14,7 +15,7 @@ const clicks0 = createFixedClicks(route, 0, () => !isPrintWithClicks.value)
14
15
  :clicks-context="clicks0"
15
16
  :nav="useFixedNav(route, clicks0)"
16
17
  />
17
- <template v-if="!clicks0.disabled">
18
+ <template v-if="isPrintWithClicks">
18
19
  <PrintSlideClick
19
20
  v-for="i of clicks0.total"
20
21
  :key="i"
@@ -133,7 +133,6 @@ watchEffect(() => {
133
133
  <SlideContainer
134
134
  :key="route.no"
135
135
  :width="cardWidth"
136
- :clicks-disabled="true"
137
136
  class="pointer-events-none"
138
137
  >
139
138
  <SlideWrapper
@@ -3,7 +3,7 @@ import { computed, defineAsyncComponent, defineComponent, h, onMounted, ref, toR
3
3
  import type { PropType } from 'vue'
4
4
  import { provideLocal } from '@vueuse/core'
5
5
  import type { ClicksContext, RenderContext, SlideRoute } from '@slidev/types'
6
- import { injectionActive, injectionClicksContext, injectionCurrentPage, injectionRenderContext, injectionRoute } from '../constants'
6
+ import { injectionActive, injectionClicksContext, injectionCurrentPage, injectionRenderContext, injectionRoute, injectionSlideZoom } from '../constants'
7
7
  import SlideLoading from './SlideLoading.vue'
8
8
 
9
9
  const props = defineProps({
@@ -29,21 +29,23 @@ const props = defineProps({
29
29
  },
30
30
  })
31
31
 
32
+ const zoom = computed(() => props.route.meta?.slide?.frontmatter.zoom ?? 1)
33
+
32
34
  provideLocal(injectionRoute, props.route)
33
35
  provideLocal(injectionCurrentPage, ref(props.route.no))
34
36
  provideLocal(injectionRenderContext, ref(props.renderContext as RenderContext))
35
37
  provideLocal(injectionActive, toRef(props, 'active'))
36
38
  provideLocal(injectionClicksContext, toRef(props, 'clicksContext'))
39
+ provideLocal(injectionSlideZoom, zoom)
37
40
 
38
41
  const style = computed(() => {
39
- const zoom = props.route.meta?.slide?.frontmatter.zoom ?? 1
40
- return zoom === 1
42
+ return zoom.value === 1
41
43
  ? undefined
42
44
  : {
43
- width: `${100 / zoom}%`,
44
- height: `${100 / zoom}%`,
45
+ width: `${100 / zoom.value}%`,
46
+ height: `${100 / zoom.value}%`,
45
47
  transformOrigin: 'top left',
46
- transform: `scale(${zoom})`,
48
+ transform: `scale(${zoom.value})`,
47
49
  }
48
50
  })
49
51
 
@@ -75,6 +75,7 @@ function onAfterLeave() {
75
75
  class="overflow-hidden"
76
76
  />
77
77
  </div>
78
+ <div id="twoslash-container" />
78
79
  </component>
79
80
 
80
81
  <!-- Global Top -->
@@ -132,7 +132,7 @@ function isCurrent(thisClick: number | [number, number], clicks: number) {
132
132
  export function resolveClick(el: Element, dir: DirectiveBinding<any>, value: VClickValue, clickAfter = false, flagHide = false): ResolvedClicksInfo | null {
133
133
  const ctx = dirInject(dir, injectionClicksContext)?.value
134
134
 
135
- if (!el || !ctx || ctx.disabled)
135
+ if (!el || !ctx)
136
136
  return null
137
137
 
138
138
  if (value === false || value === 'false')
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@slidev/client",
3
3
  "type": "module",
4
- "version": "0.48.2",
4
+ "version": "0.48.4",
5
5
  "description": "Presentation slides for developers",
6
6
  "author": "antfu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -36,7 +36,7 @@
36
36
  "@shikijs/vitepress-twoslash": "^1.1.7",
37
37
  "@slidev/rough-notation": "^0.1.0",
38
38
  "@typescript/ata": "^0.9.4",
39
- "@unhead/vue": "^1.8.11",
39
+ "@unhead/vue": "^1.8.18",
40
40
  "@unocss/reset": "^0.58.5",
41
41
  "@vueuse/core": "^10.9.0",
42
42
  "@vueuse/math": "^10.9.0",
@@ -50,7 +50,7 @@
50
50
  "katex": "^0.16.9",
51
51
  "lz-string": "^1.5.0",
52
52
  "mermaid": "^10.9.0",
53
- "monaco-editor": "^0.46.0",
53
+ "monaco-editor": "^0.47.0",
54
54
  "prettier": "^3.2.5",
55
55
  "recordrtc": "^5.6.2",
56
56
  "shiki": "^1.1.7",
@@ -60,10 +60,10 @@
60
60
  "vue": "^3.4.21",
61
61
  "vue-demi": "^0.14.7",
62
62
  "vue-router": "^4.3.0",
63
- "@slidev/parser": "0.48.2",
64
- "@slidev/types": "0.48.2"
63
+ "@slidev/parser": "0.48.4",
64
+ "@slidev/types": "0.48.4"
65
65
  },
66
66
  "devDependencies": {
67
- "vite": "^5.1.5"
67
+ "vite": "^5.1.6"
68
68
  }
69
69
  }
@@ -177,7 +177,6 @@ onMounted(() => {
177
177
  <SlideContainer
178
178
  :key="route.no"
179
179
  :width="cardWidth"
180
- :clicks-disabled="true"
181
180
  class="pointer-events-none important:[&_*]:select-none"
182
181
  >
183
182
  <SlideWrapper
package/pages/print.vue CHANGED
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { watchEffect } from 'vue'
2
+ import { onMounted, watchEffect } from 'vue'
3
+ import { recomputeAllPoppers } from 'floating-vue'
3
4
  import { windowSize } from '../state'
4
5
  import PrintContainer from '../internals/PrintContainer.vue'
5
6
  import PrintStyle from '../internals/PrintStyle.vue'
@@ -13,6 +14,10 @@ watchEffect(() => {
13
14
  else
14
15
  (document.body.parentNode as HTMLElement).classList.remove('print')
15
16
  })
17
+
18
+ onMounted(() => {
19
+ recomputeAllPoppers()
20
+ })
16
21
  </script>
17
22
 
18
23
  <template>
@@ -24,6 +29,7 @@ watchEffect(() => {
24
29
  :width="windowSize.width.value"
25
30
  />
26
31
  </div>
32
+ <div id="twoslash-container" />
27
33
  </template>
28
34
 
29
35
  <style lang="postcss">
package/setup/main.ts CHANGED
@@ -35,7 +35,7 @@ export default async function setupMain(app: App) {
35
35
  app.use(createVClickDirectives())
36
36
  app.use(createVMarkDirective())
37
37
  app.use(MotionPlugin)
38
- app.use(TwoSlashFloatingVue as any, { container: '#slideshow' })
38
+ app.use(TwoSlashFloatingVue as any, { container: '#twoslash-container' })
39
39
 
40
40
  const context: AppContext = {
41
41
  app,