@slidev/client 0.48.0-beta.8 → 0.48.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.
Files changed (98) hide show
  1. package/App.vue +7 -0
  2. package/builtin/Arrow.vue +2 -4
  3. package/builtin/CodeBlockWrapper.vue +33 -28
  4. package/builtin/KaTexBlockWrapper.vue +1 -1
  5. package/builtin/Link.vue +3 -1
  6. package/builtin/Mermaid.vue +4 -3
  7. package/builtin/Monaco.vue +166 -93
  8. package/builtin/ShikiMagicMove.vue +103 -0
  9. package/builtin/SlidevVideo.vue +1 -1
  10. package/builtin/Toc.vue +1 -1
  11. package/builtin/TocList.vue +4 -3
  12. package/builtin/Tweet.vue +12 -9
  13. package/builtin/VClick.ts +2 -1
  14. package/composables/useClicks.ts +19 -32
  15. package/composables/useDarkMode.ts +9 -0
  16. package/composables/useDrawings.ts +181 -0
  17. package/composables/useNav.ts +346 -44
  18. package/{logic/note.ts → composables/useSlideInfo.ts} +13 -16
  19. package/composables/useSwipeControls.ts +43 -0
  20. package/composables/useTocTree.ts +81 -0
  21. package/composables/useViewTransition.ts +7 -4
  22. package/constants.ts +4 -3
  23. package/context.ts +13 -6
  24. package/env.ts +7 -16
  25. package/index.html +1 -0
  26. package/index.ts +12 -0
  27. package/internals/ClicksSlider.vue +93 -0
  28. package/internals/CodeRunner.vue +142 -0
  29. package/internals/Controls.vue +2 -2
  30. package/internals/DomElement.vue +18 -0
  31. package/internals/DrawingControls.vue +15 -17
  32. package/internals/DrawingLayer.vue +6 -5
  33. package/internals/DrawingPreview.vue +4 -2
  34. package/internals/Goto.vue +9 -6
  35. package/internals/IconButton.vue +7 -3
  36. package/internals/NavControls.vue +31 -12
  37. package/internals/NoteDisplay.vue +131 -8
  38. package/internals/NoteEditable.vue +129 -0
  39. package/internals/NoteStatic.vue +8 -6
  40. package/internals/PrintContainer.vue +11 -8
  41. package/internals/PrintSlide.vue +11 -12
  42. package/internals/PrintSlideClick.vue +14 -19
  43. package/internals/{SlidesOverview.vue → QuickOverview.vue} +35 -22
  44. package/internals/RecordingControls.vue +1 -1
  45. package/internals/RecordingDialog.vue +5 -6
  46. package/internals/{Editor.vue → SideEditor.vue} +26 -17
  47. package/internals/SlideContainer.vue +13 -9
  48. package/internals/SlideLoading.vue +19 -0
  49. package/internals/SlideWrapper.vue +79 -0
  50. package/internals/SlidesShow.vue +36 -22
  51. package/layouts/error.vue +5 -0
  52. package/layouts/two-cols-header.vue +9 -3
  53. package/logic/overview.ts +2 -2
  54. package/logic/route.ts +16 -5
  55. package/logic/slides.ts +20 -0
  56. package/logic/transition.ts +50 -0
  57. package/logic/utils.ts +24 -1
  58. package/main.ts +3 -15
  59. package/{setup → modules}/codemirror.ts +1 -3
  60. package/modules/context.ts +1 -46
  61. package/modules/mermaid.ts +9 -8
  62. package/package.json +21 -15
  63. package/{internals/EntrySelect.vue → pages/entry.vue} +7 -0
  64. package/{internals/NotesView.vue → pages/notes.vue} +9 -6
  65. package/pages/overview.vue +231 -0
  66. package/{internals/Play.vue → pages/play.vue} +22 -15
  67. package/{internals/PresenterPrint.vue → pages/presenter/print.vue} +15 -8
  68. package/{internals/Presenter.vue → pages/presenter.vue} +129 -107
  69. package/{internals/Print.vue → pages/print.vue} +6 -5
  70. package/routes.ts +26 -57
  71. package/setup/code-runners.ts +164 -0
  72. package/setup/main.ts +39 -9
  73. package/setup/mermaid.ts +5 -6
  74. package/setup/monaco.ts +114 -51
  75. package/setup/root.ts +62 -18
  76. package/setup/shortcuts.ts +15 -12
  77. package/shim-vue.d.ts +34 -0
  78. package/shim.d.ts +1 -13
  79. package/state/index.ts +2 -2
  80. package/styles/code.css +9 -5
  81. package/styles/index.css +63 -7
  82. package/styles/katex.css +1 -1
  83. package/styles/layouts-base.css +17 -12
  84. package/styles/shiki-twoslash.css +1 -1
  85. package/styles/vars.css +1 -0
  86. package/uno.config.ts +14 -2
  87. package/utils.ts +15 -2
  88. package/composables/useContext.ts +0 -17
  89. package/composables/useTweetScript.ts +0 -17
  90. package/iframes/monaco/index.css +0 -28
  91. package/iframes/monaco/index.html +0 -7
  92. package/iframes/monaco/index.ts +0 -260
  93. package/internals/NoteEditor.vue +0 -88
  94. package/internals/SlideWrapper.ts +0 -58
  95. package/logic/drawings.ts +0 -161
  96. package/logic/nav.ts +0 -278
  97. package/setup/prettier.ts +0 -43
  98. /package/{composables → logic}/hmr.ts +0 -0
@@ -1,18 +1,22 @@
1
1
  <script setup lang="ts">
2
2
  import { computed, ref, shallowRef } from 'vue'
3
3
  import { isEditorVertical, isScreenVertical, showEditor, slideScale, windowSize } from '../state'
4
- import { isEmbedded, isPrintMode, next, prev, useSwipeControls } from '../logic/nav'
5
- import { isDrawing } from '../logic/drawings'
4
+ import { useSwipeControls } from '../composables/useSwipeControls'
6
5
  import { registerShortcuts } from '../logic/shortcuts'
7
- import { configs, themeVars } from '../env'
8
- import Controls from './Controls.vue'
9
- import SlideContainer from './SlideContainer.vue'
10
- import NavControls from './NavControls.vue'
11
- import SlidesShow from './SlidesShow.vue'
12
- import PrintStyle from './PrintStyle.vue'
6
+ import { configs } from '../env'
7
+ import Controls from '../internals/Controls.vue'
8
+ import SlideContainer from '../internals/SlideContainer.vue'
9
+ import NavControls from '../internals/NavControls.vue'
10
+ import SlidesShow from '../internals/SlidesShow.vue'
11
+ import PrintStyle from '../internals/PrintStyle.vue'
12
+ import { useNav } from '../composables/useNav'
13
+ import { useDrawings } from '../composables/useDrawings'
13
14
 
14
15
  registerShortcuts()
15
16
 
17
+ const { next, prev, isEmbedded, isPrintMode } = useNav()
18
+ const { isDrawing } = useDrawings()
19
+
16
20
  const root = ref<HTMLDivElement>()
17
21
  function onClick(e: MouseEvent) {
18
22
  if (showEditor.value)
@@ -31,18 +35,21 @@ useSwipeControls(root)
31
35
 
32
36
  const persistNav = computed(() => isScreenVertical.value || showEditor.value)
33
37
 
34
- const Editor = shallowRef<any>()
38
+ const SideEditor = shallowRef<any>()
35
39
  if (__DEV__ && __SLIDEV_FEATURE_EDITOR__)
36
- import('./Editor.vue').then(v => Editor.value = v.default)
40
+ import('../internals/SideEditor.vue').then(v => SideEditor.value = v.default)
37
41
 
38
42
  const DrawingControls = shallowRef<any>()
39
43
  if (__SLIDEV_FEATURE_DRAWINGS__)
40
- import('./DrawingControls.vue').then(v => DrawingControls.value = v.default)
44
+ import('../internals/DrawingControls.vue').then(v => DrawingControls.value = v.default)
41
45
  </script>
42
46
 
43
47
  <template>
44
48
  <PrintStyle v-if="isPrintMode" />
45
- <div id="page-root" ref="root" class="grid" :class="isEditorVertical ? 'grid-rows-[1fr_max-content]' : 'grid-cols-[1fr_max-content]'" :style="themeVars">
49
+ <div
50
+ id="page-root" ref="root" class="grid"
51
+ :class="isEditorVertical ? 'grid-rows-[1fr_max-content]' : 'grid-cols-[1fr_max-content]'"
52
+ >
46
53
  <SlideContainer
47
54
  class="w-full h-full"
48
55
  :style="{ background: 'var(--slidev-slide-container-background, black)' }"
@@ -70,9 +77,9 @@ if (__SLIDEV_FEATURE_DRAWINGS__)
70
77
  </template>
71
78
  </SlideContainer>
72
79
 
73
- <template v-if="__DEV__ && __SLIDEV_FEATURE_EDITOR__ && Editor && showEditor">
74
- <Editor :resize="true" />
80
+ <template v-if="__DEV__ && __SLIDEV_FEATURE_EDITOR__ && SideEditor && showEditor">
81
+ <SideEditor :resize="true" />
75
82
  </template>
76
83
  </div>
77
84
  <Controls />
78
- </template>
85
+ </template>../composables/drawings
@@ -2,9 +2,11 @@
2
2
  import { computed } from 'vue'
3
3
  import { useStyleTag } from '@vueuse/core'
4
4
  import { useHead } from '@unhead/vue'
5
- import { configs, themeVars } from '../env'
6
- import { rawRoutes, total } from '../logic/nav'
7
- import NoteDisplay from './NoteDisplay.vue'
5
+ import { useNav } from '../../composables/useNav'
6
+ import { configs } from '../../env'
7
+ import NoteDisplay from '../../internals/NoteDisplay.vue'
8
+
9
+ const { slides, total } = useNav()
8
10
 
9
11
  useStyleTag(`
10
12
  @page {
@@ -24,15 +26,17 @@ html #page-root {
24
26
  }
25
27
  `)
26
28
 
27
- useHead({ title: `Notes - ${configs.title}` })
29
+ useHead({
30
+ title: `Notes - ${configs.title}`,
31
+ })
28
32
 
29
- const slidesWithNote = computed(() => rawRoutes
33
+ const slidesWithNote = computed(() => slides.value
30
34
  .map(route => route.meta?.slide)
31
35
  .filter(slide => slide !== undefined && slide.noteHTML !== ''))
32
36
  </script>
33
37
 
34
38
  <template>
35
- <div id="page-root" :style="themeVars">
39
+ <div id="page-root">
36
40
  <div class="m-4">
37
41
  <div class="mb-10">
38
42
  <h1 class="text-4xl font-bold mt-2">
@@ -54,9 +58,12 @@ const slidesWithNote = computed(() => rawRoutes
54
58
  <div class="flex-auto" />
55
59
  </div>
56
60
  </h2>
57
- <NoteDisplay :note-html="slide!.noteHTML" class="max-w-full" />
61
+ <NoteDisplay
62
+ :note-html="slide!.noteHTML"
63
+ class="max-w-full"
64
+ />
58
65
  </div>
59
- <hr v-if="index < slidesWithNote.length - 1" class="border-gray-400/50 mb-8">
66
+ <hr v-if="index < slidesWithNote.length - 1" class="border-main mb-8">
60
67
  </div>
61
68
  </div>
62
69
  </div>
@@ -2,31 +2,46 @@
2
2
  import { useHead } from '@unhead/vue'
3
3
  import { computed, onMounted, reactive, ref, shallowRef, watch } from 'vue'
4
4
  import { useMouse, useWindowFocus } from '@vueuse/core'
5
- import { clicksContext, currentPage, currentRoute, hasNext, nextRoute, queryClicks, rawRoutes, total, useSwipeControls } from '../logic/nav'
5
+ import { useSwipeControls } from '../composables/useSwipeControls'
6
6
  import { decreasePresenterFontSize, increasePresenterFontSize, presenterLayout, presenterNotesFontSize, showEditor, showOverview, showPresenterCursor } from '../state'
7
- import { configs, themeVars } from '../env'
7
+ import { configs } from '../env'
8
8
  import { sharedState } from '../state/shared'
9
9
  import { registerShortcuts } from '../logic/shortcuts'
10
10
  import { getSlideClass } from '../utils'
11
11
  import { useTimer } from '../logic/utils'
12
- import { isDrawing } from '../logic/drawings'
13
- import { useFixedClicks } from '../composables/useClicks'
14
- import SlideContainer from './SlideContainer.vue'
15
- import NavControls from './NavControls.vue'
16
- import SlidesOverview from './SlidesOverview.vue'
17
- import NoteEditor from './NoteEditor.vue'
18
- import NoteStatic from './NoteStatic.vue'
19
- import Goto from './Goto.vue'
20
- import SlidesShow from './SlidesShow.vue'
21
- import SlideWrapper from './SlideWrapper'
22
- import DrawingControls from './DrawingControls.vue'
23
- import IconButton from './IconButton.vue'
12
+ import { createFixedClicks } from '../composables/useClicks'
13
+ import SlideWrapper from '../internals/SlideWrapper.vue'
14
+ import SlideContainer from '../internals/SlideContainer.vue'
15
+ import NavControls from '../internals/NavControls.vue'
16
+ import QuickOverview from '../internals/QuickOverview.vue'
17
+ import NoteEditable from '../internals/NoteEditable.vue'
18
+ import NoteStatic from '../internals/NoteStatic.vue'
19
+ import Goto from '../internals/Goto.vue'
20
+ import SlidesShow from '../internals/SlidesShow.vue'
21
+ import DrawingControls from '../internals/DrawingControls.vue'
22
+ import IconButton from '../internals/IconButton.vue'
23
+ import ClicksSlider from '../internals/ClicksSlider.vue'
24
+ import { useNav } from '../composables/useNav'
25
+ import { useDrawings } from '../composables/useDrawings'
24
26
 
25
27
  const main = ref<HTMLDivElement>()
26
28
 
27
29
  registerShortcuts()
28
30
  useSwipeControls(main)
29
31
 
32
+ const {
33
+ clicksContext,
34
+ currentSlideNo,
35
+ currentSlideRoute,
36
+ hasNext,
37
+ nextRoute,
38
+ slides,
39
+ queryClicks,
40
+ getPrimaryClicks,
41
+ total,
42
+ } = useNav()
43
+ const { isDrawing } = useDrawings()
44
+
30
45
  const slideTitle = configs.titleTemplate.replace('%s', configs.title || 'Slidev')
31
46
  useHead({
32
47
  title: `Presenter - ${slideTitle}`,
@@ -36,25 +51,32 @@ const notesEditing = ref(false)
36
51
 
37
52
  const { timer, resetTimer } = useTimer()
38
53
 
39
- const clicksCtxMap = rawRoutes.map(route => useFixedClicks(route))
54
+ const clicksCtxMap = computed(() => slides.value.map(route => createFixedClicks(route)))
40
55
  const nextFrame = computed(() => {
41
56
  if (clicksContext.value.current < clicksContext.value.total)
42
- return [currentRoute.value!, clicksContext.value.current + 1] as const
57
+ return [currentSlideRoute.value!, clicksContext.value.current + 1] as const
43
58
  else if (hasNext.value)
44
59
  return [nextRoute.value!, 0] as const
45
60
  else
46
61
  return null
47
62
  })
63
+
48
64
  const nextFrameClicksCtx = computed(() => {
49
- return nextFrame.value && clicksCtxMap[+nextFrame.value[0].path - 1]
65
+ return nextFrame.value && clicksCtxMap.value[nextFrame.value[0].no - 1]
50
66
  })
51
- watch([currentRoute, queryClicks], () => {
52
- nextFrameClicksCtx.value && (nextFrameClicksCtx.value[0].value = nextFrame.value![1])
53
- }, { immediate: true })
54
67
 
55
- const Editor = shallowRef<any>()
68
+ watch(
69
+ [currentSlideRoute, queryClicks],
70
+ () => {
71
+ if (nextFrameClicksCtx.value)
72
+ nextFrameClicksCtx.value.current = nextFrame.value![1]
73
+ },
74
+ { immediate: true },
75
+ )
76
+
77
+ const SideEditor = shallowRef<any>()
56
78
  if (__DEV__ && __SLIDEV_FEATURE_EDITOR__)
57
- import('./Editor.vue').then(v => Editor.value = v.default)
79
+ import('../internals/SideEditor.vue').then(v => SideEditor.value = v.default)
58
80
 
59
81
  // sync presenter cursor
60
82
  onMounted(() => {
@@ -86,68 +108,64 @@ onMounted(() => {
86
108
  <template>
87
109
  <div class="bg-main h-full slidev-presenter">
88
110
  <div class="grid-container" :class="`layout${presenterLayout}`">
89
- <div class="grid-section top flex">
90
- <img src="../assets/logo-title-horizontal.png" class="ml-2 my-auto h-10 py-1 lg:h-14 lg:py-2" style="height: 3.5rem;" alt="Slidev logo">
91
- <div class="flex-auto" />
92
- <div
93
- class="timer-btn my-auto relative w-22px h-22px cursor-pointer text-lg"
94
- opacity="50 hover:100"
95
- @click="resetTimer"
96
- >
97
- <carbon:time class="absolute" />
98
- <carbon:renew class="absolute opacity-0" />
99
- </div>
100
- <div class="text-2xl pl-2 pr-6 my-auto tabular-nums">
101
- {{ timer }}
102
- </div>
103
- </div>
104
- <div ref="main" class="relative grid-section main flex flex-col p-2 lg:p-4" :style="themeVars">
111
+ <div ref="main" class="relative grid-section main flex flex-col">
105
112
  <SlideContainer
106
113
  key="main"
107
- class="h-full w-full"
114
+ class="h-full w-full p-2 lg:p-4 flex-auto"
108
115
  >
109
116
  <template #default>
110
117
  <SlidesShow render-context="presenter" />
111
118
  </template>
112
119
  </SlideContainer>
113
- <div class="context">
114
- current
120
+ <ClicksSlider
121
+ :key="currentSlideRoute?.no"
122
+ :clicks-context="getPrimaryClicks(currentSlideRoute)"
123
+ class="w-full pb2 px4 flex-none"
124
+ />
125
+ <div class="absolute left-0 top-0 bg-main border-b border-r border-main px2 py1 op50 text-sm">
126
+ Current
115
127
  </div>
116
128
  </div>
117
- <div class="relative grid-section next flex flex-col p-2 lg:p-4" :style="themeVars">
129
+ <div class="relative grid-section next flex flex-col p-2 lg:p-4">
118
130
  <SlideContainer
119
131
  v-if="nextFrame && nextFrameClicksCtx"
120
132
  key="next"
121
133
  class="h-full w-full"
122
134
  >
123
135
  <SlideWrapper
124
- :is="nextFrame[0].component as any"
125
- :key="nextFrame[0].path"
126
- :clicks-context="nextFrameClicksCtx[1]"
136
+ :is="nextFrame[0].component!"
137
+ :key="nextFrame[0].no"
138
+ :clicks-context="nextFrameClicksCtx"
127
139
  :class="getSlideClass(nextFrame[0])"
128
140
  :route="nextFrame[0]"
129
141
  render-context="previewNext"
130
142
  />
131
143
  </SlideContainer>
132
- <div class="context">
133
- next
144
+ <div class="absolute left-0 top-0 bg-main border-b border-r border-main px2 py1 op50 text-sm">
145
+ Next
134
146
  </div>
135
147
  </div>
136
148
  <!-- Notes -->
137
- <div v-if="__DEV__ && __SLIDEV_FEATURE_EDITOR__ && Editor && showEditor" class="grid-section note of-auto">
138
- <Editor />
149
+ <div v-if="__DEV__ && __SLIDEV_FEATURE_EDITOR__ && SideEditor && showEditor" class="grid-section note of-auto">
150
+ <SideEditor />
139
151
  </div>
140
152
  <div v-else class="grid-section note grid grid-rows-[1fr_min-content] overflow-hidden">
141
- <NoteEditor
153
+ <NoteEditable
142
154
  v-if="__DEV__"
155
+ :key="`edit-${currentSlideNo}`"
156
+ v-model:editing="notesEditing"
157
+ :no="currentSlideNo"
143
158
  class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
144
- :editing="notesEditing"
159
+ :clicks-context="clicksContext"
145
160
  :style="{ fontSize: `${presenterNotesFontSize}em` }"
146
161
  />
147
162
  <NoteStatic
148
163
  v-else
164
+ :key="`static-${currentSlideNo}`"
165
+ :no="currentSlideNo"
149
166
  class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
150
167
  :style="{ fontSize: `${presenterNotesFontSize}em` }"
168
+ :clicks-context="clicksContext"
151
169
  />
152
170
  <div class="border-t border-main py-1 px-2 text-sm">
153
171
  <IconButton title="Increase font size" @click="increasePresenterFontSize">
@@ -165,116 +183,120 @@ onMounted(() => {
165
183
  </IconButton>
166
184
  </div>
167
185
  </div>
168
- <div class="grid-section bottom">
186
+ <div class="grid-section bottom flex">
169
187
  <NavControls :persist="true" />
188
+ <div flex-auto />
189
+ <div
190
+ class="timer-btn my-auto relative w-22px h-22px cursor-pointer text-lg"
191
+ opacity="50 hover:100"
192
+ @click="resetTimer"
193
+ >
194
+ <carbon:time class="absolute" />
195
+ <carbon:renew class="absolute opacity-0" />
196
+ </div>
197
+ <div class="text-2xl pl-2 pr-6 my-auto tabular-nums">
198
+ {{ timer }}
199
+ </div>
170
200
  </div>
171
201
  <DrawingControls v-if="__SLIDEV_FEATURE_DRAWINGS__" />
172
202
  </div>
173
203
  <div class="progress-bar">
174
204
  <div
175
- class="progress h-2px bg-primary transition-all"
176
- :style="{ width: `${(currentPage - 1) / (total - 1) * 100}%` }"
205
+ class="progress h-3px bg-primary transition-all"
206
+ :style="{ width: `${(currentSlideNo - 1) / (total - 1) * 100}%` }"
177
207
  />
178
208
  </div>
179
209
  </div>
180
210
  <Goto />
181
- <SlidesOverview v-model="showOverview" />
211
+ <QuickOverview v-model="showOverview" />
182
212
  </template>
183
213
 
184
- <style lang="postcss" scoped>
214
+ <style scoped>
185
215
  .slidev-presenter {
186
216
  --slidev-controls-foreground: current;
187
217
  }
188
218
 
189
- .timer-btn:hover {
190
- & > :first-child {
191
- @apply opacity-0;
192
- }
193
- & > :last-child {
194
- @apply opacity-100;
195
- }
219
+ .timer-btn:hover > :first-child {
220
+ opacity: 0;
221
+ }
222
+ .timer-btn:hover > :last-child {
223
+ opacity: 1;
196
224
  }
197
225
 
198
226
  .section-title {
199
- @apply px-4 py-2 text-xl;
227
+ --uno: px-4 py-2 text-xl;
200
228
  }
201
229
 
202
230
  .grid-container {
203
- @apply h-full w-full bg-gray-400 bg-opacity-15;
231
+ --uno: bg-gray/20;
232
+ height: 100%;
233
+ width: 100%;
204
234
  display: grid;
205
235
  gap: 1px 1px;
206
236
  }
207
237
 
208
238
  .grid-container.layout1 {
209
239
  grid-template-columns: 1fr 1fr;
210
- grid-template-rows: min-content 2fr 1fr min-content;
240
+ grid-template-rows: 2fr 1fr min-content;
211
241
  grid-template-areas:
212
- "top top"
213
- "main main"
214
- "note next"
215
- "bottom bottom";
242
+ 'main main'
243
+ 'note next'
244
+ 'bottom bottom';
216
245
  }
217
246
 
218
247
  .grid-container.layout2 {
219
248
  grid-template-columns: 3fr 2fr;
220
- grid-template-rows: min-content 2fr 1fr min-content;
249
+ grid-template-rows: 2fr 1fr min-content;
221
250
  grid-template-areas:
222
- "top top"
223
- "note main"
224
- "note next"
225
- "bottom bottom";
251
+ 'note main'
252
+ 'note next'
253
+ 'bottom bottom';
226
254
  }
227
255
 
228
256
  @media (max-aspect-ratio: 3/5) {
229
257
  .grid-container.layout1 {
230
258
  grid-template-columns: 1fr;
231
- grid-template-rows: min-content 1fr 1fr 1fr min-content;
259
+ grid-template-rows: 1fr 1fr 1fr min-content;
232
260
  grid-template-areas:
233
- "top"
234
- "main"
235
- "note"
236
- "next"
237
- "bottom";
261
+ 'main'
262
+ 'note'
263
+ 'next'
264
+ 'bottom';
238
265
  }
239
266
  }
240
267
 
241
268
  @media (min-aspect-ratio: 1/1) {
242
269
  .grid-container.layout1 {
243
270
  grid-template-columns: 1fr 1.1fr 0.9fr;
244
- grid-template-rows: min-content 1fr 2fr min-content;
271
+ grid-template-rows: 1fr 2fr min-content;
245
272
  grid-template-areas:
246
- "top top top"
247
- "main main next"
248
- "main main note"
249
- "bottom bottom bottom";
273
+ 'main main next'
274
+ 'main main note'
275
+ 'bottom bottom bottom';
250
276
  }
251
277
  }
252
278
 
253
279
  .progress-bar {
254
- @apply fixed left-0 right-0 bottom-0;
280
+ --uno: fixed left-0 right-0 top-0;
255
281
  }
256
282
 
257
283
  .grid-section {
258
- @apply bg-main;
259
-
260
- &.top {
261
- grid-area: top;
262
- }
263
- &.main {
264
- grid-area: main;
265
- }
266
- &.next {
267
- grid-area: next;
268
- }
269
- &.note {
270
- grid-area: note;
271
- }
272
- &.bottom {
273
- grid-area: bottom;
274
- }
284
+ --uno: bg-main;
275
285
  }
276
286
 
277
- .context {
278
- @apply absolute top-0 left-0 px-1 text-xs bg-gray-400 bg-opacity-50 opacity-75 rounded-br-md;
287
+ .grid-section.top {
288
+ grid-area: top;
289
+ }
290
+ .grid-section.main {
291
+ grid-area: main;
292
+ }
293
+ .grid-section.next {
294
+ grid-area: next;
295
+ }
296
+ .grid-section.note {
297
+ grid-area: note;
298
+ }
299
+ .grid-section.bottom {
300
+ grid-area: bottom;
279
301
  }
280
- </style>
302
+ </style>../composables/drawings
@@ -1,10 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import { watchEffect } from 'vue'
3
3
  import { windowSize } from '../state'
4
- import { isPrintMode } from '../logic/nav'
5
- import { themeVars } from '../env'
6
- import PrintContainer from './PrintContainer.vue'
7
- import PrintStyle from './PrintStyle.vue'
4
+ import PrintContainer from '../internals/PrintContainer.vue'
5
+ import PrintStyle from '../internals/PrintStyle.vue'
6
+ import { useNav } from '../composables/useNav'
7
+
8
+ const { isPrintMode } = useNav()
8
9
 
9
10
  watchEffect(() => {
10
11
  if (isPrintMode)
@@ -16,7 +17,7 @@ watchEffect(() => {
16
17
 
17
18
  <template>
18
19
  <PrintStyle v-if="isPrintMode" />
19
- <div id="page-root" class="grid grid-cols-[1fr_max-content]" :style="themeVars">
20
+ <div id="page-root" class="grid grid-cols-[1fr_max-content]">
20
21
  <PrintContainer
21
22
  class="w-full h-full"
22
23
  :style="{ background: 'var(--slidev-slide-container-background, black)' }"
package/routes.ts CHANGED
@@ -1,63 +1,58 @@
1
1
  import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
2
- import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
3
- import type { TransitionGroupProps } from 'vue'
4
- import type { ClicksContext, SlideInfo } from '@slidev/types'
5
-
6
- // @ts-expect-error missing types
7
- import _rawRoutes, { redirects } from '/@slidev/routes'
8
-
9
- // @ts-expect-error missing types
10
- import _configs from '/@slidev/configs'
11
-
12
- export const rawRoutes = _rawRoutes as RouteRecordRaw[]
2
+ import configs from '#slidev/configs'
13
3
 
14
4
  export const routes: RouteRecordRaw[] = [
15
5
  {
16
- name: 'play',
17
- path: '/',
18
- component: () => import('./internals/Play.vue'),
19
- children: [
20
- ...rawRoutes,
21
- ...redirects,
22
- ],
6
+ name: 'print',
7
+ path: '/print',
8
+ component: () => import('./pages/print.vue'),
23
9
  },
24
- { name: 'print', path: '/print', component: () => import('./internals/Print.vue') },
10
+
11
+ // Redirects
25
12
  { path: '', redirect: { path: '/1' } },
26
- { path: '/:pathMatch(.*)', redirect: { path: '/1' } },
27
13
  ]
28
14
 
29
15
  if (__SLIDEV_FEATURE_PRESENTER__) {
30
16
  function passwordGuard(to: RouteLocationNormalized) {
31
- if (!_configs.remote || _configs.remote === to.query.password)
17
+ if (!configs.remote || configs.remote === to.query.password)
32
18
  return true
33
- if (_configs.remote && to.query.password === undefined) {
19
+ if (configs.remote && to.query.password === undefined) {
34
20
  // eslint-disable-next-line no-alert
35
21
  const password = prompt('Enter password')
36
- if (_configs.remote === password)
22
+ if (configs.remote === password)
37
23
  return true
38
24
  }
39
25
  if (to.params.no)
40
26
  return { path: `/${to.params.no}` }
41
27
  return { path: '' }
42
28
  }
43
- routes.push({ path: '/presenter/print', component: () => import('./internals/PresenterPrint.vue') })
29
+
30
+ routes.push({
31
+ path: '/presenter/print',
32
+ component: () => import('./pages/presenter/print.vue'),
33
+ })
44
34
  if (__SLIDEV_HAS_SERVER__) {
45
35
  routes.push({
46
36
  name: 'entry',
47
37
  path: '/entry',
48
- component: () => import('./internals/EntrySelect.vue'),
38
+ component: () => import('./pages/entry.vue'),
39
+ })
40
+ routes.push({
41
+ name: 'overview',
42
+ path: '/overview',
43
+ component: () => import('./pages/overview.vue'),
49
44
  })
50
45
  routes.push({
51
46
  name: 'notes',
52
47
  path: '/notes',
53
- component: () => import('./internals/NotesView.vue'),
48
+ component: () => import('./pages/notes.vue'),
54
49
  beforeEnter: passwordGuard,
55
50
  })
56
51
  }
57
52
  routes.push({
58
53
  name: 'presenter',
59
54
  path: '/presenter/:no',
60
- component: () => import('./internals/Presenter.vue'),
55
+ component: () => import('./pages/presenter.vue'),
61
56
  beforeEnter: passwordGuard,
62
57
  })
63
58
  routes.push({
@@ -66,34 +61,8 @@ if (__SLIDEV_FEATURE_PRESENTER__) {
66
61
  })
67
62
  }
68
63
 
69
- export const router = createRouter({
70
- history: __SLIDEV_HASH_ROUTE__
71
- ? createWebHashHistory(import.meta.env.BASE_URL)
72
- : createWebHistory(import.meta.env.BASE_URL),
73
- routes,
64
+ routes.push({
65
+ name: 'play',
66
+ path: '/:no',
67
+ component: () => import('./pages/play.vue'),
74
68
  })
75
-
76
- declare module 'vue-router' {
77
- interface RouteMeta {
78
- // inherited from frontmatter
79
- layout: string
80
- name?: string
81
- class?: string
82
- clicks?: number
83
- transition?: string | TransitionGroupProps | undefined
84
- preload?: boolean
85
-
86
- // slide info
87
- slide?: Omit<SlideInfo, 'source'> & {
88
- noteHTML: string
89
- filepath: string
90
- start: number
91
- id: number
92
- no: number
93
- }
94
-
95
- // private fields
96
- __clicksContext: null | ClicksContext
97
- __preloaded?: boolean
98
- }
99
- }