@slidev/client 0.43.0-beta.5 → 0.43.0-beta.7

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
@@ -13,6 +13,7 @@ export const injectionSlidevContext: InjectionKey<UnwrapNestedRefs<SlidevContext
13
13
  export const injectionRoute: InjectionKey<RouteRecordRaw> = Symbol('slidev-route')
14
14
  export const injectionSlideContext: InjectionKey<RenderContext> = Symbol('slidev-slide-context')
15
15
  export const injectionActive: InjectionKey<Ref<boolean>> = Symbol('slidev-active')
16
+ export const injectionFrontmatter: InjectionKey<Record<string, any>> = Symbol('slidev-fontmatter')
16
17
 
17
18
  export const CLASS_VCLICK_TARGET = 'slidev-vclick-target'
18
19
  export const CLASS_VCLICK_HIDDEN = 'slidev-vclick-hidden'
@@ -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,46 @@ 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
+ const extactMatch = rawRoutes.findIndex(i => i.path === keyboardBuffer.value)
80
+ if (extactMatch !== -1)
81
+ currentOverviewPage.value = extactMatch + 1
82
+
83
+ // When the input number is the largest at the number of digits, we go to that page directly.
84
+ if (+keyboardBuffer.value * 10 > rawRoutes.length) {
85
+ go(+keyboardBuffer.value)
86
+ keyboardBuffer.value = ''
87
+ }
88
+ })
89
+
50
90
  watchEffect(() => {
51
91
  // Watch currentPage, make sure every time we open overview,
52
92
  // we focus on the right page.
@@ -79,7 +119,7 @@ watchEffect(() => {
79
119
  >
80
120
  <div
81
121
  class="inline-block border rounded border-opacity-50 overflow-hidden bg-main hover:border-$slidev-theme-primary transition"
82
- :class="{ 'border-$slidev-theme-primary': focus(idx + 1), 'border-gray-400': !focus(idx + 1) }"
122
+ :class="(focus(idx + 1) || currentOverviewPage === idx + 1) ? 'border-$slidev-theme-primary' : 'border-gray-400'"
83
123
  :style="themeVars"
84
124
  @click="go(+route.path)"
85
125
  >
@@ -101,10 +141,16 @@ watchEffect(() => {
101
141
  </SlideContainer>
102
142
  </div>
103
143
  <div
104
- class="absolute top-0 opacity-50"
144
+ class="absolute top-0"
105
145
  :style="`left: ${cardWidth + 5}px`"
106
146
  >
107
- {{ idx + 1 }}
147
+ <template v-if="keyboardBuffer && String(idx + 1).startsWith(keyboardBuffer)">
148
+ <span class="text-green font-bold">{{ keyboardBuffer }}</span>
149
+ <span class="opacity-50">{{ String(idx + 1).slice(keyboardBuffer.length) }}</span>
150
+ </template>
151
+ <span v-else class="opacity-50">
152
+ {{ idx + 1 }}
153
+ </span>
108
154
  </div>
109
155
  </div>
110
156
  </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.5",
3
+ "version": "0.43.0-beta.7",
4
4
  "description": "Presentation slides for developers",
5
5
  "author": "antfu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",
@@ -41,8 +41,8 @@
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.5",
45
- "@slidev/types": "0.43.0-beta.5"
44
+ "@slidev/parser": "0.43.0-beta.7",
45
+ "@slidev/types": "0.43.0-beta.7"
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 },