@slidev/client 0.43.0-beta.4 → 0.43.0-beta.6

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.
@@ -28,6 +28,7 @@ export function useNav(route: ComputedRef<RouteRecordRaw | RouteLocationNormaliz
28
28
  const tree = computed(() => filterTree(treeWithActiveStatuses.value))
29
29
 
30
30
  return {
31
+ rawRoutes,
31
32
  route,
32
33
  path,
33
34
  total,
package/constants.ts CHANGED
@@ -5,12 +5,14 @@ import type { SlidevContext } from './modules/context'
5
5
 
6
6
  export const injectionClicks: InjectionKey<Ref<number>> = Symbol('v-click-clicks')
7
7
  export const injectionClicksElements: InjectionKey<Ref<(Element | string)[]>> = Symbol('v-click-clicks-elements')
8
- export const injectionOrderMap: InjectionKey<Ref<Map<number, HTMLElement[]>>> = Symbol('v-click-clicks-order-map')
9
8
  export const injectionClicksDisabled: InjectionKey<Ref<boolean>> = Symbol('v-click-clicks-disabled')
9
+ export const injectionOrderMap: InjectionKey<Ref<Map<number, HTMLElement[]>>> = Symbol('v-click-clicks-order-map')
10
+ export const injectionCurrentPage: InjectionKey<number> = Symbol('slidev-page')
10
11
  export const injectionSlideScale: InjectionKey<ComputedRef<number>> = Symbol('slidev-slide-scale')
11
12
  export const injectionSlidevContext: InjectionKey<UnwrapNestedRefs<SlidevContext>> = Symbol('slidev-slidev-context')
12
13
  export const injectionRoute: InjectionKey<RouteRecordRaw> = Symbol('slidev-route')
13
14
  export const injectionSlideContext: InjectionKey<RenderContext> = Symbol('slidev-slide-context')
15
+ export const injectionActive: InjectionKey<Ref<boolean>> = Symbol('slidev-active')
14
16
 
15
17
  export const CLASS_VCLICK_TARGET = 'slidev-vclick-target'
16
18
  export const CLASS_VCLICK_HIDDEN = 'slidev-vclick-hidden'
@@ -1,8 +1,8 @@
1
1
  import { useVModel } from '@vueuse/core'
2
2
  import type { Ref } from 'vue'
3
- import { defineComponent, h, provide } from 'vue'
3
+ import { defineComponent, h, provide, toRef } from 'vue'
4
4
  import type { RenderContext } from '@slidev/types'
5
- import { injectionClicks, injectionClicksDisabled, injectionClicksElements, injectionOrderMap, injectionRoute, injectionSlideContext } from '../constants'
5
+ import { injectionActive, injectionClicks, injectionClicksDisabled, injectionClicksElements, injectionCurrentPage, injectionOrderMap, injectionRoute, injectionSlideContext } from '../constants'
6
6
 
7
7
  export default defineComponent({
8
8
  name: 'SlideWrapper',
@@ -27,6 +27,10 @@ export default defineComponent({
27
27
  type: String,
28
28
  default: 'main',
29
29
  },
30
+ active: {
31
+ type: Boolean,
32
+ default: false,
33
+ },
30
34
  is: {
31
35
  type: Object,
32
36
  default: undefined,
@@ -45,7 +49,9 @@ export default defineComponent({
45
49
  clicksElements.value.length = 0
46
50
 
47
51
  provide(injectionRoute, props.route as any)
52
+ provide(injectionCurrentPage, +props.route?.path)
48
53
  provide(injectionSlideContext, props.context as RenderContext)
54
+ provide(injectionActive, toRef(props, 'active'))
49
55
  provide(injectionClicks, clicks as Ref<number>)
50
56
  provide(injectionClicksDisabled, clicksDisabled)
51
57
  provide(injectionClicksElements, clicksElements as any)
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
- import { useVModel } from '@vueuse/core'
3
- import { computed, watchEffect } from 'vue'
2
+ import { useEventListener, useVModel } from '@vueuse/core'
3
+ import { computed, ref, watchEffect } from 'vue'
4
4
  import { themeVars } from '../env'
5
- import { breakpoints, windowSize } from '../state'
5
+ import { breakpoints, showOverview, windowSize } from '../state'
6
6
  import { currentPage, go as goSlide, rawRoutes } from '../logic/nav'
7
7
  import { currentOverviewPage, overviewRowCount } from '../logic/overview'
8
8
  import { getSlideClass } from '../utils'
@@ -47,6 +47,42 @@ const rowCount = computed(() => {
47
47
  return Math.floor((windowSize.width.value - padding) / (cardWidth.value + gap))
48
48
  })
49
49
 
50
+ const keyboardBuffer = ref<string>('')
51
+
52
+ useEventListener('keypress', (e) => {
53
+ if (!showOverview.value) {
54
+ keyboardBuffer.value = ''
55
+ return
56
+ }
57
+ if (e.key === 'Enter' && keyboardBuffer.value) {
58
+ e.preventDefault()
59
+ go(+keyboardBuffer.value)
60
+ keyboardBuffer.value = ''
61
+ return
62
+ }
63
+ const num = Number.parseInt(e.key.replace(/[^0-9]/g, ''))
64
+ if (Number.isNaN(num)) {
65
+ keyboardBuffer.value = ''
66
+ return
67
+ }
68
+ if (!keyboardBuffer.value && num === 0)
69
+ return
70
+
71
+ keyboardBuffer.value += String(num)
72
+
73
+ // beyond the number of slides, reset
74
+ if (+keyboardBuffer.value >= rawRoutes.length) {
75
+ keyboardBuffer.value = ''
76
+ return
77
+ }
78
+
79
+ // When the input number is the largest at the number of digits, we go to that page directly.
80
+ if (+keyboardBuffer.value * 10 > rawRoutes.length) {
81
+ go(+keyboardBuffer.value)
82
+ keyboardBuffer.value = ''
83
+ }
84
+ })
85
+
50
86
  watchEffect(() => {
51
87
  // Watch currentPage, make sure every time we open overview,
52
88
  // we focus on the right page.
@@ -101,10 +137,16 @@ watchEffect(() => {
101
137
  </SlideContainer>
102
138
  </div>
103
139
  <div
104
- class="absolute top-0 opacity-50"
140
+ class="absolute top-0"
105
141
  :style="`left: ${cardWidth + 5}px`"
106
142
  >
107
- {{ idx + 1 }}
143
+ <template v-if="keyboardBuffer && String(idx + 1).startsWith(keyboardBuffer)">
144
+ <span class="text-green font-bold">{{ keyboardBuffer }}</span>
145
+ <span class="opacity-50">{{ String(idx + 1).slice(keyboardBuffer.length) }}</span>
146
+ </template>
147
+ <span v-else class="opacity-50">
148
+ {{ idx + 1 }}
149
+ </span>
108
150
  </div>
109
151
  </div>
110
152
  </div>
@@ -9,7 +9,7 @@ import { isDark } from '../logic/dark'
9
9
  import { injectionSlidevContext } from '../constants'
10
10
  import { useContext } from '../composables/useContext'
11
11
 
12
- export type SlidevContextNavKey = 'path' | 'total' | 'currentPage' | 'currentPath' | 'currentRoute' | 'currentSlideId' | 'currentLayout' | 'nextRoute' | 'rawTree' | 'treeWithActiveStatuses' | 'tree' | 'downloadPDF' | 'next' | 'nextSlide' | 'openInEditor' | 'prev' | 'prevSlide'
12
+ export type SlidevContextNavKey = 'path' | 'total' | 'currentPage' | 'currentPath' | 'currentRoute' | 'currentSlideId' | 'currentLayout' | 'nextRoute' | 'rawTree' | 'treeWithActiveStatuses' | 'tree' | 'downloadPDF' | 'next' | 'nextSlide' | 'openInEditor' | 'prev' | 'prevSlide' | 'rawRoutes'
13
13
  export type SlidevContextNavClicksKey = 'clicks' | 'clicksElements' | 'clicksTotal' | 'hasNext' | 'hasPrev'
14
14
 
15
15
  export interface SlidevContextNav extends Pick<typeof nav, SlidevContextNavKey> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slidev/client",
3
- "version": "0.43.0-beta.4",
3
+ "version": "0.43.0-beta.6",
4
4
  "description": "Presentation slides for developers",
5
5
  "author": "antfu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@antfu/utils": "^0.7.6",
19
- "@unocss/reset": "^0.55.5",
19
+ "@unocss/reset": "^0.55.6",
20
20
  "@vueuse/core": "^10.4.1",
21
21
  "@vueuse/head": "^1.3.1",
22
22
  "@vueuse/math": "^10.4.1",
@@ -35,14 +35,14 @@
35
35
  "prettier": "^3.0.3",
36
36
  "recordrtc": "^5.6.2",
37
37
  "resolve": "^1.22.4",
38
- "unocss": "^0.55.5",
38
+ "unocss": "^0.55.6",
39
39
  "vite-plugin-windicss": "^1.9.1",
40
40
  "vue": "^3.3.4",
41
41
  "vue-router": "^4.2.4",
42
42
  "vue-starport": "^0.3.0",
43
43
  "windicss": "^3.5.6",
44
- "@slidev/parser": "0.43.0-beta.4",
45
- "@slidev/types": "0.43.0-beta.4"
44
+ "@slidev/parser": "0.43.0-beta.6",
45
+ "@slidev/types": "0.43.0-beta.6"
46
46
  },
47
47
  "devDependencies": {
48
48
  "vite": "^4.4.9"
package/routes.ts CHANGED
@@ -67,10 +67,14 @@ export const router = createRouter({
67
67
 
68
68
  declare module 'vue-router' {
69
69
  interface RouteMeta {
70
+ // inherited from frontmatter
70
71
  layout: string
71
72
  name?: string
72
73
  class?: string
73
74
  clicks?: number
75
+ transition?: string | TransitionGroupProps | undefined
76
+
77
+ // slide info
74
78
  slide?: {
75
79
  start: number
76
80
  end: number
@@ -85,7 +89,7 @@ declare module 'vue-router' {
85
89
  content: string
86
90
  frontmatter: Record<string, any>
87
91
  }
88
- transition?: string | TransitionGroupProps | undefined
92
+
89
93
  // private fields
90
94
  __clicksElements: HTMLElement[]
91
95
  __preloaded?: boolean
@@ -1,5 +1,5 @@
1
1
  /* __imports__ */
2
- import { and, not } from '@vueuse/math'
2
+ import { and, not, or } from '@vueuse/math'
3
3
  import type { NavOperations, ShortcutOptions } from '@slidev/types'
4
4
  import { downloadPDF, go, goFirst, goLast, next, nextSlide, prev, prevSlide } from '../logic/nav'
5
5
  import { toggleDark } from '../logic/dark'
@@ -8,7 +8,7 @@ import { drawingEnabled } from '../logic/drawings'
8
8
  import { currentOverviewPage, downOverviewPage, nextOverviewPage, prevOverviewPage, upOverviewPage } from './../logic/overview'
9
9
 
10
10
  export default function setupShortcuts() {
11
- const { escape, space, shift, left, right, up, down, enter, d, g, o } = magicKeys
11
+ const { escape, space, shift, left, right, up, down, enter, d, g, o, '`': backtick } = magicKeys
12
12
 
13
13
  // @ts-expect-error injected in runtime
14
14
  // eslint-disable-next-line unused-imports/no-unused-vars
@@ -41,7 +41,7 @@ export default function setupShortcuts() {
41
41
  { name: 'next_shift', key: and(right, shift), fn: nextSlide, autoRepeat: true },
42
42
  { name: 'prev_shift', key: and(left, shift), fn: () => prevSlide(false), autoRepeat: true },
43
43
  { name: 'toggle_dark', key: and(d, not(drawingEnabled)), fn: toggleDark },
44
- { name: 'toggle_overview', key: and(o, not(drawingEnabled)), fn: toggleOverview },
44
+ { name: 'toggle_overview', key: and(or(o, backtick), not(drawingEnabled)), fn: toggleOverview },
45
45
  { name: 'hide_overview', key: and(escape, not(drawingEnabled)), fn: () => showOverview.value = false },
46
46
  { name: 'goto', key: and(g, not(drawingEnabled)), fn: () => showGotoDialog.value = !showGotoDialog.value },
47
47
  { name: 'next_overview', key: and(right, showOverview), fn: nextOverviewPage },