@slidev/client 0.49.0-beta.6 → 0.49.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.
@@ -0,0 +1,56 @@
1
+ import { throttledWatch } from '@vueuse/core'
2
+ import { useNav } from '../composables/useNav'
3
+ import { isDark } from '../logic/dark'
4
+
5
+ export function useEmbeddedControl() {
6
+ const nav = useNav()
7
+ const clientId = `${Date.now()}`
8
+
9
+ window.addEventListener('message', ({ data }) => {
10
+ if (data && data.target === 'slidev') {
11
+ if (data.type === 'navigate') {
12
+ if (data.no || data.clicks) {
13
+ nav.go(+data.no, +data.clicks || 0)
14
+ }
15
+ else if (typeof data.operation === 'string') {
16
+ const fn = nav[data.operation as keyof typeof nav]
17
+ if (typeof fn === 'function')
18
+ (fn as any)(...(data.args ?? []))
19
+ }
20
+ }
21
+ else if (data.type === 'css-vars') {
22
+ const root = document.documentElement
23
+ for (const [key, value] of Object.entries(data.vars || {}))
24
+ root.style.setProperty(key, value as any)
25
+ }
26
+ else if (data.type === 'color-schema') {
27
+ isDark.value = data.color === 'dark'
28
+ }
29
+ }
30
+ })
31
+
32
+ if (nav.isEmbedded.value) {
33
+ throttledWatch(
34
+ [nav.currentSlideNo, nav.clicks, nav.hasNext, nav.hasPrev],
35
+ ([no, clicks, hasNext, hasPrev]) => {
36
+ window.parent.postMessage(
37
+ {
38
+ target: 'slidev',
39
+ clientId,
40
+ navState: {
41
+ no,
42
+ clicks,
43
+ hasNext,
44
+ hasPrev,
45
+ },
46
+ },
47
+ '*',
48
+ )
49
+ },
50
+ {
51
+ throttle: 300,
52
+ immediate: true,
53
+ },
54
+ )
55
+ }
56
+ }
@@ -51,11 +51,11 @@ export interface SlidevContextNav {
51
51
  /** Go to previous click */
52
52
  prev: () => Promise<void>
53
53
  /** Go to next slide */
54
- nextSlide: () => Promise<void>
54
+ nextSlide: (lastClicks?: boolean) => Promise<void>
55
55
  /** Go to previous slide */
56
56
  prevSlide: (lastClicks?: boolean) => Promise<void>
57
57
  /** Go to slide */
58
- go: (page: number | string, clicks?: number, force?: boolean) => Promise<void>
58
+ go: (no: number | string, clicks?: number, force?: boolean) => Promise<void>
59
59
  /** Go to the first slide */
60
60
  goFirst: () => Promise<void>
61
61
  /** Go to the last slide */
@@ -86,7 +86,7 @@ export interface SlidevContextNavState {
86
86
  getPrimaryClicks: (route: SlideRoute) => ClicksContext
87
87
  }
88
88
 
89
- export interface SlidevContextNavFull extends SlidevContextNav, SlidevContextNavState {}
89
+ export interface SlidevContextNavFull extends SlidevContextNav, SlidevContextNavState { }
90
90
 
91
91
  export function useNavBase(
92
92
  currentSlideRoute: ComputedRef<SlideRoute>,
@@ -149,27 +149,24 @@ export function useNavBase(
149
149
  async function prev() {
150
150
  clicksDirection.value = -1
151
151
  if (queryClicks.value <= clicksStart.value)
152
- await prevSlide()
152
+ await prevSlide(true)
153
153
  else
154
154
  queryClicks.value -= 1
155
155
  }
156
156
 
157
- async function nextSlide() {
157
+ async function nextSlide(lastClicks = false) {
158
158
  clicksDirection.value = 1
159
- if (currentSlideNo.value < slides.value.length)
160
- await go(currentSlideNo.value + 1)
159
+ await go(
160
+ Math.min(currentSlideNo.value + 1, slides.value.length),
161
+ lastClicks && !isPrint.value ? CLICKS_MAX : undefined,
162
+ )
161
163
  }
162
164
 
163
- async function prevSlide(lastClicks = true) {
165
+ async function prevSlide(lastClicks = false) {
164
166
  clicksDirection.value = -1
165
- const next = Math.max(1, currentSlideNo.value - 1)
166
167
  await go(
167
- next,
168
- lastClicks
169
- ? isPrint.value
170
- ? undefined
171
- : getSlide(next)?.meta.__clicksContext?.total ?? CLICKS_MAX
172
- : undefined,
168
+ Math.max(1, currentSlideNo.value - 1),
169
+ lastClicks && !isPrint.value ? CLICKS_MAX : undefined,
173
170
  )
174
171
  }
175
172
 
@@ -181,19 +178,20 @@ export function useNavBase(
181
178
  return go(total.value)
182
179
  }
183
180
 
184
- async function go(page: number | string, clicks: number = 0, force = false) {
181
+ async function go(no: number | string, clicks: number = 0, force = false) {
185
182
  skipTransition.value = false
186
- const pageChanged = currentSlideNo.value !== page
183
+ const pageChanged = currentSlideNo.value !== no
187
184
  const clicksChanged = clicks !== queryClicks.value
188
- const meta = getSlide(page)?.meta
185
+ const meta = getSlide(no)?.meta
189
186
  const clicksStart = meta?.slide?.frontmatter.clicksStart ?? 0
190
187
  clicks = clamp(clicks, clicksStart, meta?.__clicksContext?.total ?? CLICKS_MAX)
191
188
  if (force || pageChanged || clicksChanged) {
192
189
  await router?.push({
193
- path: getSlidePath(page, isPresenter.value),
190
+ path: getSlidePath(no, isPresenter.value),
194
191
  query: {
195
192
  ...router.currentRoute.value.query,
196
193
  clicks: clicks === 0 ? undefined : clicks.toString(),
194
+ embedded: location.search.includes('embedded') ? 'true' : undefined,
197
195
  },
198
196
  })
199
197
  }
@@ -30,7 +30,7 @@ onClickOutside(el, () => {
30
30
  <KeepAlive>
31
31
  <div
32
32
  v-if="value"
33
- class="rounded-md bg-main shadow absolute bottom-10 left-0 z-20"
33
+ class="rounded-md bg-main text-main shadow absolute bottom-10 left-0 z-20"
34
34
  dark:border="~ main"
35
35
  >
36
36
  <slot name="menu" />
@@ -3,6 +3,7 @@ import type { ComputedRef } from 'vue'
3
3
  import { shallowRef } from 'vue'
4
4
  import setupContextMenu from '../setup/context-menu'
5
5
  import { configs, mode } from '../env'
6
+ import { useNav } from '../composables/useNav'
6
7
 
7
8
  export const currentContextMenu = shallowRef<null | {
8
9
  x: number
@@ -28,6 +29,10 @@ export function onContextMenu(ev: MouseEvent) {
28
29
  if (ev.shiftKey || ev.defaultPrevented)
29
30
  return
30
31
 
32
+ const { isEmbedded } = useNav()
33
+ if (isEmbedded.value)
34
+ return
35
+
31
36
  openContextMenu(ev.pageX, ev.pageY)
32
37
  ev.preventDefault()
33
38
  ev.stopPropagation()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@slidev/client",
3
3
  "type": "module",
4
- "version": "0.49.0-beta.6",
4
+ "version": "0.49.0",
5
5
  "description": "Presentation slides for developers",
6
6
  "author": "antfu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -28,16 +28,16 @@
28
28
  "node": ">=18.0.0"
29
29
  },
30
30
  "dependencies": {
31
- "@antfu/utils": "^0.7.7",
31
+ "@antfu/utils": "^0.7.8",
32
32
  "@iconify-json/carbon": "^1.1.32",
33
- "@iconify-json/ph": "^1.1.12",
33
+ "@iconify-json/ph": "^1.1.13",
34
34
  "@iconify-json/svg-spinners": "^1.1.2",
35
- "@shikijs/monaco": "^1.4.0",
36
- "@shikijs/vitepress-twoslash": "^1.4.0",
35
+ "@shikijs/monaco": "^1.5.1",
36
+ "@shikijs/vitepress-twoslash": "^1.5.1",
37
37
  "@slidev/rough-notation": "^0.1.0",
38
38
  "@typescript/ata": "^0.9.4",
39
- "@unhead/vue": "^1.9.8",
40
- "@unocss/reset": "^0.59.4",
39
+ "@unhead/vue": "^1.9.10",
40
+ "@unocss/reset": "^0.60.0",
41
41
  "@vueuse/core": "^10.9.0",
42
42
  "@vueuse/math": "^10.9.0",
43
43
  "@vueuse/motion": "^2.1.0",
@@ -52,15 +52,15 @@
52
52
  "monaco-editor": "^0.48.0",
53
53
  "prettier": "^3.2.5",
54
54
  "recordrtc": "^5.6.2",
55
- "shiki": "^1.4.0",
56
- "shiki-magic-move": "^0.3.7",
55
+ "shiki": "^1.5.1",
56
+ "shiki-magic-move": "^0.4.2",
57
57
  "typescript": "^5.4.5",
58
- "unocss": "^0.59.4",
59
- "vue": "^3.4.26",
58
+ "unocss": "^0.60.0",
59
+ "vue": "^3.4.27",
60
60
  "vue-router": "^4.3.2",
61
61
  "yaml": "^2.4.2",
62
- "@slidev/parser": "0.49.0-beta.6",
63
- "@slidev/types": "0.49.0-beta.6"
62
+ "@slidev/parser": "0.49.0",
63
+ "@slidev/types": "0.49.0"
64
64
  },
65
65
  "devDependencies": {
66
66
  "vite": "^5.2.11"
package/setup/root.ts CHANGED
@@ -9,8 +9,8 @@ import { skipTransition } from '../logic/hmr'
9
9
  import { makeId } from '../logic/utils'
10
10
  import { getSlidePath } from '../logic/slides'
11
11
  import { createFixedClicks } from '../composables/useClicks'
12
- import { isDark } from '../logic/dark'
13
12
  import { useNav } from '../composables/useNav'
13
+ import { useEmbeddedControl } from '../composables/useEmbeddedCtrl'
14
14
  import setups from '#slidev/setups/root'
15
15
 
16
16
  export default function setupRoot() {
@@ -30,21 +30,7 @@ export default function setupRoot() {
30
30
  if (__DEV__) {
31
31
  // @ts-expect-error expose global
32
32
  window.__slidev__ = context
33
- window.addEventListener('message', ({ data }) => {
34
- if (data && data.target === 'slidev') {
35
- if (data.type === 'navigate') {
36
- context.nav.go(+data.no, +data.clicks || 0)
37
- }
38
- else if (data.type === 'css-vars') {
39
- const root = document.documentElement
40
- for (const [key, value] of Object.entries(data.vars || {}))
41
- root.style.setProperty(key, value as any)
42
- }
43
- else if (data.type === 'color-schema') {
44
- isDark.value = data.color === 'dark'
45
- }
46
- }
47
- })
33
+ useEmbeddedControl()
48
34
  }
49
35
 
50
36
  // User Setups
@@ -39,9 +39,9 @@ export default function setupShortcuts() {
39
39
  { name: 'next_page_key', key: 'pageDown', fn: next, autoRepeat: true },
40
40
  { name: 'prev_page_key', key: 'pageUp', fn: prev, autoRepeat: true },
41
41
  { name: 'next_down', key: and(down, navViaArrowKeys), fn: nextSlide, autoRepeat: true },
42
- { name: 'prev_up', key: and(up, navViaArrowKeys), fn: () => prevSlide(false), autoRepeat: true },
42
+ { name: 'prev_up', key: and(up, navViaArrowKeys), fn: prevSlide, autoRepeat: true },
43
43
  { name: 'next_shift', key: and(right, shift), fn: nextSlide, autoRepeat: true },
44
- { name: 'prev_shift', key: and(left, shift), fn: () => prevSlide(false), autoRepeat: true },
44
+ { name: 'prev_shift', key: and(left, shift), fn: prevSlide, autoRepeat: true },
45
45
  { name: 'toggle_dark', key: and(d, not(drawingEnabled)), fn: toggleDark },
46
46
  { name: 'toggle_overview', key: and(or(o, backtick), not(drawingEnabled)), fn: toggleOverview },
47
47
  { name: 'hide_overview', key: and(escape, not(drawingEnabled)), fn: () => showOverview.value = false },