@slidev/client 0.48.1 → 0.48.2

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.
@@ -68,6 +68,7 @@ export function createClicksContextBase(
68
68
  export function createFixedClicks(
69
69
  route?: SlideRoute | undefined,
70
70
  currentInit = 0,
71
+ isDisabled?: () => boolean,
71
72
  ): ClicksContext {
72
- return createClicksContextBase(ref(currentInit), route?.meta?.clicks)
73
+ return createClicksContextBase(ref(currentInit), route?.meta?.clicks, isDisabled)
73
74
  }
@@ -170,15 +170,19 @@ export function useNavBase(
170
170
  return go(total.value)
171
171
  }
172
172
 
173
- async function go(page: number | string, clicks?: number) {
173
+ async function go(page: number | string, clicks: number = 0) {
174
174
  skipTransition.value = false
175
- await router?.push({
176
- path: getSlidePath(page, isPresenter.value),
177
- query: {
178
- ...router.currentRoute.value.query,
179
- clicks: clicks || undefined,
180
- },
181
- })
175
+ const pageChanged = currentSlideNo.value !== page
176
+ const clicksChanged = clicks !== queryClicks.value
177
+ if (pageChanged || clicksChanged) {
178
+ await router?.push({
179
+ path: getSlidePath(page, isPresenter.value),
180
+ query: {
181
+ ...router.currentRoute.value.query,
182
+ clicks: clicks === 0 ? undefined : clicks.toString(),
183
+ },
184
+ })
185
+ }
182
186
  }
183
187
 
184
188
  return {
@@ -1,6 +1,7 @@
1
1
  import { ref } from 'vue'
2
2
  import { useRouter } from 'vue-router'
3
3
  import { getSlide } from '../logic/slides'
4
+ import { configs } from '../env'
4
5
 
5
6
  export function useViewTransition() {
6
7
  const router = useRouter()
@@ -16,14 +17,9 @@ export function useViewTransition() {
16
17
  const toMeta = getSlide(to.params.no as string)?.meta
17
18
  const fromNo = fromMeta?.slide?.no
18
19
  const toNo = toMeta?.slide?.no
19
- if (
20
- !(
21
- fromNo !== undefined && toNo !== undefined && (
22
- (fromMeta?.transition === 'view-transition' && fromNo < toNo)
23
- || (toMeta?.transition === 'view-transition' && toNo < fromNo)
24
- )
25
- )
26
- ) {
20
+ const transitionType = fromNo != null && toNo != null
21
+ && ((fromNo < toNo ? fromMeta?.transition : toMeta?.transition) ?? configs.transition)
22
+ if (transitionType !== 'view-transition') {
27
23
  isViewTransition.value = false
28
24
  return
29
25
  }
@@ -43,17 +39,15 @@ export function useViewTransition() {
43
39
  let changeRoute: () => void
44
40
  const ready = new Promise<void>(resolve => (changeRoute = resolve))
45
41
 
46
- // eslint-disable-next-line ts/ban-ts-comment
47
- // @ts-expect-error
48
- const transition = document.startViewTransition(() => {
49
- changeRoute()
50
- return promise
51
- })
42
+ // Wait for `TransitionGroup` to become normal `div`
43
+ setTimeout(() => {
44
+ // @ts-expect-error missing types
45
+ document.startViewTransition(() => {
46
+ changeRoute()
47
+ return promise
48
+ })
49
+ }, 50)
52
50
 
53
- transition.finished.then(() => {
54
- viewTransitionAbort = undefined
55
- viewTransitionFinish = undefined
56
- })
57
51
  return ready
58
52
  })
59
53
 
@@ -28,21 +28,21 @@ function onMousedown() {
28
28
 
29
29
  <template>
30
30
  <div
31
- class="flex gap-0.5 items-center select-none"
31
+ class="flex gap-1 items-center select-none"
32
32
  :title="`Clicks in this slide: ${total}`"
33
33
  :class="total ? '' : 'op50'"
34
34
  >
35
- <div class="flex gap-1 items-center min-w-16 tabular-nums">
35
+ <div class="flex gap-0.5 items-center min-w-16 font-mono mr1">
36
36
  <carbon:cursor-1 text-sm op50 />
37
+ <div flex-auto />
37
38
  <template v-if="current >= 0 && current !== CLICKS_MAX">
38
- <div flex-auto />
39
39
  <span text-primary>{{ current }}</span>
40
40
  <span op25>/</span>
41
41
  </template>
42
42
  <span op50>{{ total }}</span>
43
43
  </div>
44
44
  <div
45
- relative flex-auto h5 flex="~"
45
+ relative flex-auto h5 font-mono flex="~"
46
46
  @dblclick="current = clicksContext.total"
47
47
  >
48
48
  <div
@@ -54,7 +54,7 @@ function onMousedown() {
54
54
  ]"
55
55
  :style="{ width: total > 0 ? `${1 / total * 100}%` : '100%' }"
56
56
  >
57
- <div absolute inset-0 :class="i <= current ? 'bg-primary op20' : ''" />
57
+ <div absolute inset-0 :class="i <= current ? 'bg-primary op15' : ''" />
58
58
  <div
59
59
  :class="[
60
60
  +i === +current ? 'text-primary font-bold op100 border-primary' : 'op30 border-main',
@@ -1,11 +1,12 @@
1
1
  <script setup lang="ts">
2
2
  import type { SlideRoute } from '@slidev/types'
3
- import { useFixedNav } from '../composables/useNav'
3
+ import { useFixedNav, useNav } from '../composables/useNav'
4
4
  import { createFixedClicks } from '../composables/useClicks'
5
5
  import PrintSlideClick from './PrintSlideClick.vue'
6
6
 
7
7
  const { route } = defineProps<{ route: SlideRoute }>()
8
- const clicks0 = createFixedClicks(route, 0)
8
+ const { isPrintWithClicks } = useNav()
9
+ const clicks0 = createFixedClicks(route, 0, () => !isPrintWithClicks.value)
9
10
  </script>
10
11
 
11
12
  <template>
package/logic/route.ts CHANGED
@@ -22,6 +22,9 @@ export function useRouteQuery<T extends string | string[]>(
22
22
  },
23
23
  set(v) {
24
24
  nextTick(() => {
25
+ const oldValue = router.currentRoute.value.query[name]
26
+ if ((oldValue ?? defaultValue?.toString()) === v.toString())
27
+ return
25
28
  router[unref(mode) as 'replace' | 'push']({
26
29
  query: {
27
30
  ...router.currentRoute.value.query,
@@ -30,7 +33,7 @@ export function useRouteQuery<T extends string | string[]>(
30
33
  })
31
34
  })
32
35
  },
33
- }) as any
36
+ })
34
37
  }
35
38
 
36
39
  // force update collected elements when the route is fully resolved
@@ -9,7 +9,7 @@ const transitionResolveMap: Record<string, string | undefined> = {
9
9
  'slide-down': 'slide-down | slide-up',
10
10
  }
11
11
 
12
- export function resolveTransition(transition?: string | TransitionGroupProps, isBackward = false): TransitionGroupProps | undefined {
12
+ function resolveTransition(transition?: string | TransitionGroupProps, isBackward = false): TransitionGroupProps | undefined {
13
13
  if (!transition)
14
14
  return undefined
15
15
  if (typeof transition === 'string') {
package/modules/v-mark.ts CHANGED
@@ -116,7 +116,8 @@ export function createVMarkDirective() {
116
116
 
117
117
  const resolvedClick = resolveClick(el, binding, options.value.at)
118
118
  if (!resolvedClick) {
119
- console.error('[Slidev] Invalid value for v-mark:', options.value.at)
119
+ // No click animation, just show the mark
120
+ annotation.show()
120
121
  return
121
122
  }
122
123
 
@@ -130,19 +131,12 @@ export function createVMarkDirective() {
130
131
 
131
132
  const at = options.value.at
132
133
 
133
- if (at === true) {
134
+ if (at === true)
134
135
  shouldShow = true
135
- }
136
- else if (at === false) {
136
+ else if (at === false)
137
137
  shouldShow = false
138
- }
139
- else if (resolvedClick) {
138
+ else
140
139
  shouldShow = resolvedClick.isActive.value
141
- }
142
- else {
143
- console.error('[Slidev] Invalid value for v-mark:', at)
144
- return
145
- }
146
140
 
147
141
  if (shouldShow == null)
148
142
  return
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@slidev/client",
3
3
  "type": "module",
4
- "version": "0.48.1",
4
+ "version": "0.48.2",
5
5
  "description": "Presentation slides for developers",
6
6
  "author": "antfu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -60,8 +60,8 @@
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.1",
64
- "@slidev/types": "0.48.1"
63
+ "@slidev/parser": "0.48.2",
64
+ "@slidev/types": "0.48.2"
65
65
  },
66
66
  "devDependencies": {
67
67
  "vite": "^5.1.5"
@@ -100,37 +100,42 @@ onMounted(() => {
100
100
 
101
101
  <template>
102
102
  <div class="h-screen w-screen of-hidden flex">
103
- <nav class="h-full flex flex-col border-r border-main p2 select-none">
104
- <div class="flex flex-col flex-auto items-center justify-center group gap-1">
105
- <div
106
- v-for="(route, idx) of slides"
107
- :key="route.no"
108
- class="relative"
109
- >
110
- <button
111
- class="relative transition duration-300 w-8 h-8 rounded hover:bg-active hover:op100"
112
- :class="activeBlocks.includes(idx) ? 'op100 text-primary bg-gray:5' : 'op20'"
113
- @click="scrollToSlide(idx)"
114
- >
115
- <div>{{ idx + 1 }}</div>
116
- </button>
103
+ <nav class="grid grid-rows-[auto_max-content] border-r border-main select-none max-h-full h-full">
104
+ <div class="relative">
105
+ <div class="absolute left-0 top-0 bottom-0 w-200 flex flex-col flex-auto items-end group p2 gap-1 max-h-full of-scroll" style="direction:rtl">
117
106
  <div
118
- v-if="route.meta?.slide?.title"
119
- class="pointer-events-none select-none absolute left-110% bg-main top-50% translate-y--50% ws-nowrap z-10 px2 shadow-xl rounded border border-main transition duration-400 op0 group-hover:op100"
120
- :class="activeBlocks.includes(idx) ? 'text-primary' : 'text-main important-text-op-50'"
107
+ v-for="(route, idx) of slides"
108
+ :key="route.no"
109
+ class="relative"
110
+ style="direction:ltr"
121
111
  >
122
- {{ route.meta?.slide?.title }}
112
+ <button
113
+ class="relative transition duration-300 w-8 h-8 rounded hover:bg-active hover:op100"
114
+ :class="activeBlocks.includes(idx) ? 'op100 text-primary bg-gray:5' : 'op20'"
115
+ @click="scrollToSlide(idx)"
116
+ >
117
+ <div>{{ idx + 1 }}</div>
118
+ </button>
119
+ <div
120
+ v-if="route.meta?.slide?.title"
121
+ class="pointer-events-none select-none absolute left-110% backdrop-blur-8 top-50% translate-y--50% ws-nowrap z-10 px2 shadow-xl rounded border border-main transition duration-400 op0 group-hover:op100"
122
+ :class="activeBlocks.includes(idx) ? 'text-primary' : 'text-main important-text-op-50'"
123
+ >
124
+ {{ route.meta?.slide?.title }}
125
+ </div>
123
126
  </div>
124
127
  </div>
125
128
  </div>
126
- <IconButton
127
- v-if="!isColorSchemaConfigured"
128
- :title="isDark ? 'Switch to light mode theme' : 'Switch to dark mode theme'"
129
- @click="toggleDark()"
130
- >
131
- <carbon-moon v-if="isDark" />
132
- <carbon-sun v-else />
133
- </IconButton>
129
+ <div p2 border="t main">
130
+ <IconButton
131
+ v-if="!isColorSchemaConfigured"
132
+ :title="isDark ? 'Switch to light mode theme' : 'Switch to dark mode theme'"
133
+ @click="toggleDark()"
134
+ >
135
+ <carbon-moon v-if="isDark" />
136
+ <carbon-sun v-else />
137
+ </IconButton>
138
+ </div>
134
139
  </nav>
135
140
  <main
136
141
  class="flex-1 h-full of-auto"