@slidev/client 0.48.0-beta.1 → 0.48.0-beta.11

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 (61) hide show
  1. package/builtin/CodeBlockWrapper.vue +4 -3
  2. package/builtin/KaTexBlockWrapper.vue +4 -3
  3. package/builtin/RenderWhen.vue +3 -3
  4. package/builtin/SlideCurrentNo.vue +2 -3
  5. package/builtin/SlidesTotal.vue +3 -4
  6. package/builtin/SlidevVideo.vue +8 -6
  7. package/builtin/Toc.vue +3 -3
  8. package/builtin/TocList.vue +3 -2
  9. package/builtin/Tweet.vue +4 -15
  10. package/builtin/VClickGap.vue +3 -5
  11. package/builtin/VClicks.ts +1 -1
  12. package/composables/useClicks.ts +19 -13
  13. package/composables/useTweetScript.ts +17 -0
  14. package/constants.ts +56 -8
  15. package/context.ts +70 -0
  16. package/env.ts +3 -12
  17. package/internals/DrawingControls.vue +39 -9
  18. package/internals/DrawingLayer.vue +3 -2
  19. package/internals/Editor.vue +7 -3
  20. package/internals/Goto.vue +5 -4
  21. package/internals/IconButton.vue +4 -3
  22. package/internals/InfoDialog.vue +1 -1
  23. package/internals/Modal.vue +1 -1
  24. package/internals/NavControls.vue +2 -3
  25. package/internals/NoteDisplay.vue +1 -1
  26. package/internals/NoteEditor.vue +36 -8
  27. package/internals/NoteStatic.vue +5 -6
  28. package/internals/PrintContainer.vue +3 -2
  29. package/internals/PrintSlideClick.vue +5 -7
  30. package/internals/RecordingDialog.vue +5 -6
  31. package/internals/SlideContainer.vue +12 -9
  32. package/internals/SlideWrapper.ts +28 -12
  33. package/internals/SlidesOverview.vue +18 -7
  34. package/internals/SlidesShow.vue +7 -8
  35. package/layouts/two-cols-header.vue +9 -3
  36. package/logic/drawings.ts +6 -3
  37. package/logic/nav.ts +6 -1
  38. package/logic/note.ts +7 -7
  39. package/main.ts +8 -4
  40. package/modules/context.ts +4 -3
  41. package/modules/{directives.ts → v-click.ts} +15 -15
  42. package/modules/v-mark.ts +159 -0
  43. package/package.json +21 -13
  44. package/{internals/EntrySelect.vue → pages/entry.vue} +7 -0
  45. package/{internals/NotesView.vue → pages/notes.vue} +3 -3
  46. package/pages/overview.vue +201 -0
  47. package/{internals/Play.vue → pages/play.vue} +7 -7
  48. package/{internals/PresenterPrint.vue → pages/presenter/print.vue} +7 -5
  49. package/{internals/Presenter.vue → pages/presenter.vue} +64 -58
  50. package/{internals/Print.vue → pages/print.vue} +2 -2
  51. package/routes.ts +27 -51
  52. package/setup/codemirror.ts +7 -0
  53. package/shim-vue.d.ts +35 -0
  54. package/shim.d.ts +0 -12
  55. package/state/index.ts +10 -10
  56. package/styles/code.css +7 -3
  57. package/styles/index.css +18 -6
  58. package/styles/katex.css +1 -1
  59. package/styles/layouts-base.css +17 -12
  60. package/styles/vars.css +1 -0
  61. package/uno.config.ts +14 -2
@@ -2,7 +2,7 @@
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 { clicksContext, currentPage, currentRoute, currentSlideId, hasNext, nextRoute, queryClicks, rawRoutes, total, useSwipeControls } from '../logic/nav'
6
6
  import { decreasePresenterFontSize, increasePresenterFontSize, presenterLayout, presenterNotesFontSize, showEditor, showOverview, showPresenterCursor } from '../state'
7
7
  import { configs, themeVars } from '../env'
8
8
  import { sharedState } from '../state/shared'
@@ -11,16 +11,16 @@ import { getSlideClass } from '../utils'
11
11
  import { useTimer } from '../logic/utils'
12
12
  import { isDrawing } from '../logic/drawings'
13
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'
14
+ import SlideWrapper from '../internals/SlideWrapper'
15
+ import SlideContainer from '../internals/SlideContainer.vue'
16
+ import NavControls from '../internals/NavControls.vue'
17
+ import SlidesOverview from '../internals/SlidesOverview.vue'
18
+ import NoteEditor from '../internals/NoteEditor.vue'
19
+ import NoteStatic from '../internals/NoteStatic.vue'
20
+ import Goto from '../internals/Goto.vue'
21
+ import SlidesShow from '../internals/SlidesShow.vue'
22
+ import DrawingControls from '../internals/DrawingControls.vue'
23
+ import IconButton from '../internals/IconButton.vue'
24
24
 
25
25
  const main = ref<HTMLDivElement>()
26
26
 
@@ -54,7 +54,7 @@ watch([currentRoute, queryClicks], () => {
54
54
 
55
55
  const Editor = shallowRef<any>()
56
56
  if (__DEV__ && __SLIDEV_FEATURE_EDITOR__)
57
- import('./Editor.vue').then(v => Editor.value = v.default)
57
+ import('../internals/Editor.vue').then(v => Editor.value = v.default)
58
58
 
59
59
  // sync presenter cursor
60
60
  onMounted(() => {
@@ -140,12 +140,16 @@ onMounted(() => {
140
140
  <div v-else class="grid-section note grid grid-rows-[1fr_min-content] overflow-hidden">
141
141
  <NoteEditor
142
142
  v-if="__DEV__"
143
+ :key="`edit-${currentSlideId}`"
144
+ :no="currentSlideId"
143
145
  class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
144
146
  :editing="notesEditing"
145
147
  :style="{ fontSize: `${presenterNotesFontSize}em` }"
146
148
  />
147
149
  <NoteStatic
148
150
  v-else
151
+ :key="`static-${currentSlideId}`"
152
+ :no="currentSlideId"
149
153
  class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
150
154
  :style="{ fontSize: `${presenterNotesFontSize}em` }"
151
155
  />
@@ -181,26 +185,26 @@ onMounted(() => {
181
185
  <SlidesOverview v-model="showOverview" />
182
186
  </template>
183
187
 
184
- <style lang="postcss" scoped>
188
+ <style scoped>
185
189
  .slidev-presenter {
186
190
  --slidev-controls-foreground: current;
187
191
  }
188
192
 
189
- .timer-btn:hover {
190
- & > :first-child {
191
- @apply opacity-0;
192
- }
193
- & > :last-child {
194
- @apply opacity-100;
195
- }
193
+ .timer-btn:hover > :first-child {
194
+ opacity: 0;
195
+ }
196
+ .timer-btn:hover > :last-child {
197
+ opacity: 1;
196
198
  }
197
199
 
198
200
  .section-title {
199
- @apply px-4 py-2 text-xl;
201
+ --uno: px-4 py-2 text-xl;
200
202
  }
201
203
 
202
204
  .grid-container {
203
- @apply h-full w-full bg-gray-400 bg-opacity-15;
205
+ --uno: bg-active;
206
+ height: 100%;
207
+ width: 100%;
204
208
  display: grid;
205
209
  gap: 1px 1px;
206
210
  }
@@ -209,20 +213,20 @@ onMounted(() => {
209
213
  grid-template-columns: 1fr 1fr;
210
214
  grid-template-rows: min-content 2fr 1fr min-content;
211
215
  grid-template-areas:
212
- "top top"
213
- "main main"
214
- "note next"
215
- "bottom bottom";
216
+ 'top top'
217
+ 'main main'
218
+ 'note next'
219
+ 'bottom bottom';
216
220
  }
217
221
 
218
222
  .grid-container.layout2 {
219
223
  grid-template-columns: 3fr 2fr;
220
224
  grid-template-rows: min-content 2fr 1fr min-content;
221
225
  grid-template-areas:
222
- "top top"
223
- "note main"
224
- "note next"
225
- "bottom bottom";
226
+ 'top top'
227
+ 'note main'
228
+ 'note next'
229
+ 'bottom bottom';
226
230
  }
227
231
 
228
232
  @media (max-aspect-ratio: 3/5) {
@@ -230,11 +234,11 @@ onMounted(() => {
230
234
  grid-template-columns: 1fr;
231
235
  grid-template-rows: min-content 1fr 1fr 1fr min-content;
232
236
  grid-template-areas:
233
- "top"
234
- "main"
235
- "note"
236
- "next"
237
- "bottom";
237
+ 'top'
238
+ 'main'
239
+ 'note'
240
+ 'next'
241
+ 'bottom';
238
242
  }
239
243
  }
240
244
 
@@ -243,38 +247,40 @@ onMounted(() => {
243
247
  grid-template-columns: 1fr 1.1fr 0.9fr;
244
248
  grid-template-rows: min-content 1fr 2fr min-content;
245
249
  grid-template-areas:
246
- "top top top"
247
- "main main next"
248
- "main main note"
249
- "bottom bottom bottom";
250
+ 'top top top'
251
+ 'main main next'
252
+ 'main main note'
253
+ 'bottom bottom bottom';
250
254
  }
251
255
  }
252
256
 
253
257
  .progress-bar {
254
- @apply fixed left-0 right-0 bottom-0;
258
+ --uno: fixed left-0 right-0 bottom-0;
255
259
  }
256
260
 
257
261
  .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
- }
262
+ --uno: bg-main;
275
263
  }
276
264
 
265
+ .grid-section.top {
266
+ grid-area: top;
267
+ }
268
+ .grid-section.main {
269
+ grid-area: main;
270
+ }
271
+ .grid-section.next {
272
+ grid-area: next;
273
+ }
274
+ .grid-section.note {
275
+ grid-area: note;
276
+ }
277
+ .grid-section.bottom {
278
+ grid-area: bottom;
279
+ }
277
280
  .context {
278
- @apply absolute top-0 left-0 px-1 text-xs bg-gray-400 bg-opacity-50 opacity-75 rounded-br-md;
281
+ position: absolute;
282
+ top: 0;
283
+ left: 0;
284
+ --uno: px-1 text-xs bg-gray-400 bg-opacity-50 opacity-75 rounded-br-md;
279
285
  }
280
286
  </style>
@@ -3,8 +3,8 @@ import { watchEffect } from 'vue'
3
3
  import { windowSize } from '../state'
4
4
  import { isPrintMode } from '../logic/nav'
5
5
  import { themeVars } from '../env'
6
- import PrintContainer from './PrintContainer.vue'
7
- import PrintStyle from './PrintStyle.vue'
6
+ import PrintContainer from '../internals/PrintContainer.vue'
7
+ import PrintStyle from '../internals/PrintStyle.vue'
8
8
 
9
9
  watchEffect(() => {
10
10
  if (isPrintMode)
package/routes.ts CHANGED
@@ -1,65 +1,73 @@
1
1
  import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
2
2
  import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
3
- import type { TransitionGroupProps } from 'vue'
4
- import type { ClicksContext } from '@slidev/types'
5
- import Play from './internals/Play.vue'
6
- import Print from './internals/Print.vue'
7
3
 
8
- // @ts-expect-error missing types
9
- import _rawRoutes, { redirects } from '/@slidev/routes'
4
+ import { rawRoutes, redirects } from '#slidev/routes'
5
+ import configs from '#slidev/configs'
10
6
 
11
- // @ts-expect-error missing types
12
- import _configs from '/@slidev/configs'
13
-
14
- export const rawRoutes = _rawRoutes as RouteRecordRaw[]
7
+ export { rawRoutes }
15
8
 
16
9
  export const routes: RouteRecordRaw[] = [
17
10
  {
18
11
  name: 'play',
19
12
  path: '/',
20
- component: Play,
13
+ component: () => import('./pages/play.vue'),
21
14
  children: [
22
15
  ...rawRoutes,
23
16
  ...redirects,
24
17
  ],
25
18
  },
26
- { name: 'print', path: '/print', component: Print },
19
+ {
20
+ name: 'print',
21
+ path: '/print',
22
+ component: () => import('./pages/print.vue'),
23
+ },
24
+
25
+ // Redirects
27
26
  { path: '', redirect: { path: '/1' } },
28
27
  { path: '/:pathMatch(.*)', redirect: { path: '/1' } },
29
28
  ]
30
29
 
31
30
  if (__SLIDEV_FEATURE_PRESENTER__) {
32
31
  function passwordGuard(to: RouteLocationNormalized) {
33
- if (!_configs.remote || _configs.remote === to.query.password)
32
+ if (!configs.remote || configs.remote === to.query.password)
34
33
  return true
35
- if (_configs.remote && to.query.password === undefined) {
34
+ if (configs.remote && to.query.password === undefined) {
36
35
  // eslint-disable-next-line no-alert
37
36
  const password = prompt('Enter password')
38
- if (_configs.remote === password)
37
+ if (configs.remote === password)
39
38
  return true
40
39
  }
41
40
  if (to.params.no)
42
41
  return { path: `/${to.params.no}` }
43
42
  return { path: '' }
44
43
  }
45
- routes.push({ path: '/presenter/print', component: () => import('./internals/PresenterPrint.vue') })
44
+
45
+ routes.push({
46
+ path: '/presenter/print',
47
+ component: () => import('./pages/presenter/print.vue'),
48
+ })
46
49
  if (__SLIDEV_HAS_SERVER__) {
47
50
  routes.push({
48
51
  name: 'entry',
49
52
  path: '/entry',
50
- component: () => import('./internals/EntrySelect.vue'),
53
+ component: () => import('./pages/entry.vue'),
54
+ })
55
+ routes.push({
56
+ name: 'overview',
57
+ path: '/overview',
58
+ component: () => import('./pages/overview.vue'),
51
59
  })
52
60
  routes.push({
53
61
  name: 'notes',
54
62
  path: '/notes',
55
- component: () => import('./internals/NotesView.vue'),
63
+ component: () => import('./pages/notes.vue'),
56
64
  beforeEnter: passwordGuard,
57
65
  })
58
66
  }
59
67
  routes.push({
60
68
  name: 'presenter',
61
69
  path: '/presenter/:no',
62
- component: () => import('./internals/Presenter.vue'),
70
+ component: () => import('./pages/presenter.vue'),
63
71
  beforeEnter: passwordGuard,
64
72
  })
65
73
  routes.push({
@@ -74,35 +82,3 @@ export const router = createRouter({
74
82
  : createWebHistory(import.meta.env.BASE_URL),
75
83
  routes,
76
84
  })
77
-
78
- declare module 'vue-router' {
79
- interface RouteMeta {
80
- // inherited from frontmatter
81
- layout: string
82
- name?: string
83
- class?: string
84
- clicks?: number
85
- transition?: string | TransitionGroupProps | undefined
86
- preload?: boolean
87
-
88
- // slide info
89
- slide?: {
90
- start: number
91
- end: number
92
- note?: string
93
- noteHTML?: string
94
- id: number
95
- no: number
96
- filepath: string
97
- title?: string
98
- level?: number
99
- raw: string
100
- content: string
101
- frontmatter: Record<string, any>
102
- }
103
-
104
- // private fields
105
- __clicksContext: null | ClicksContext
106
- __preloaded?: boolean
107
- }
108
- }
@@ -1,4 +1,5 @@
1
1
  import type { Ref, WritableComputedRef } from 'vue'
2
+ import { onClickOutside } from '@vueuse/core'
2
3
  import { watch } from 'vue'
3
4
  import * as _CodeMirror from 'codemirror'
4
5
  import 'codemirror/mode/javascript/javascript'
@@ -47,5 +48,11 @@ export async function useCodeMirror(
47
48
  { immediate: true },
48
49
  )
49
50
 
51
+ onClickOutside(cm.getWrapperElement(), () => {
52
+ const el = cm.getInputField()
53
+ if (document.activeElement === el)
54
+ el.blur()
55
+ })
56
+
50
57
  return cm
51
58
  }
package/shim-vue.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ declare module 'vue' {
2
+ import type { UnwrapNestedRefs } from 'vue'
3
+ import type { SlidevContext } from './modules/context'
4
+
5
+ interface ComponentCustomProperties {
6
+ $slidev: UnwrapNestedRefs<SlidevContext>
7
+ }
8
+ }
9
+
10
+ declare module 'vue-router' {
11
+ interface RouteMeta {
12
+ // inherited from frontmatter
13
+ layout: string
14
+ name?: string
15
+ class?: string
16
+ clicks?: number
17
+ transition?: string | TransitionGroupProps | undefined
18
+ preload?: boolean
19
+
20
+ // slide info
21
+ slide?: Omit<SlideInfo, 'source'> & {
22
+ noteHTML: string
23
+ filepath: string
24
+ start: number
25
+ id: number
26
+ no: number
27
+ }
28
+
29
+ // private fields
30
+ __clicksContext: null | ClicksContext
31
+ __preloaded?: boolean
32
+ }
33
+ }
34
+
35
+ export {}
package/shim.d.ts CHANGED
@@ -1,9 +1,3 @@
1
- declare interface Window {
2
- // extend the window
3
- }
4
-
5
- declare module '*.vue';
6
-
7
1
  // with unplugin-vue-markdown, markdowns can be treat as Vue components
8
2
  declare module '*.md' {
9
3
  import type { ComponentOptions } from 'vue'
@@ -12,12 +6,6 @@ declare module '*.md' {
12
6
  export default component
13
7
  }
14
8
 
15
- declare module '/@slidev/configs' {
16
- import { SlidevConfig } from '@slidev/types'
17
-
18
- export default SlidevConfig
19
- }
20
-
21
9
  declare module 'mermaid/dist/mermaid.esm.mjs' {
22
10
  import Mermaid from 'mermaid/dist/mermaid.d.ts'
23
11
 
package/state/index.ts CHANGED
@@ -20,19 +20,19 @@ export const activeElement = useActiveElement()
20
20
  export const isInputting = computed(() => ['INPUT', 'TEXTAREA'].includes(activeElement.value?.tagName || '') || activeElement.value?.classList.contains('CodeMirror-code'))
21
21
  export const isOnFocus = computed(() => ['BUTTON', 'A'].includes(activeElement.value?.tagName || ''))
22
22
 
23
- export const currentCamera = useLocalStorage<string>('slidev-camera', 'default')
24
- export const currentMic = useLocalStorage<string>('slidev-mic', 'default')
23
+ export const currentCamera = useLocalStorage<string>('slidev-camera', 'default', { listenToStorageChanges: false })
24
+ export const currentMic = useLocalStorage<string>('slidev-mic', 'default', { listenToStorageChanges: false })
25
25
  export const slideScale = useLocalStorage<number>('slidev-scale', 0)
26
26
 
27
- export const showOverview = useLocalStorage('slidev-show-overview', false)
28
- export const showPresenterCursor = useLocalStorage('slidev-presenter-cursor', true)
29
- export const showEditor = useLocalStorage('slidev-show-editor', false)
30
- export const isEditorVertical = useLocalStorage('slidev-editor-vertical', false)
31
- export const editorWidth = useLocalStorage('slidev-editor-width', isClient ? window.innerWidth * 0.4 : 318)
32
- export const editorHeight = useLocalStorage('slidev-editor-height', isClient ? window.innerHeight * 0.4 : 300)
27
+ export const showOverview = useLocalStorage('slidev-show-overview', false, { listenToStorageChanges: false })
28
+ export const showPresenterCursor = useLocalStorage('slidev-presenter-cursor', true, { listenToStorageChanges: false })
29
+ export const showEditor = useLocalStorage('slidev-show-editor', false, { listenToStorageChanges: false })
30
+ export const isEditorVertical = useLocalStorage('slidev-editor-vertical', false, { listenToStorageChanges: false })
31
+ export const editorWidth = useLocalStorage('slidev-editor-width', isClient ? window.innerWidth * 0.4 : 318, { listenToStorageChanges: false })
32
+ export const editorHeight = useLocalStorage('slidev-editor-height', isClient ? window.innerHeight * 0.4 : 300, { listenToStorageChanges: false })
33
33
 
34
- export const presenterNotesFontSize = useLocalStorage('slidev-presenter-font-size', 1)
35
- export const presenterLayout = useLocalStorage('slidev-presenter-layout', 1)
34
+ export const presenterNotesFontSize = useLocalStorage('slidev-presenter-font-size', 1, { listenToStorageChanges: false })
35
+ export const presenterLayout = useLocalStorage('slidev-presenter-layout', 1, { listenToStorageChanges: false })
36
36
 
37
37
  export function togglePresenterLayout() {
38
38
  presenterLayout.value = presenterLayout.value + 1
package/styles/code.css CHANGED
@@ -59,7 +59,9 @@ html:not(.dark) .shiki span {
59
59
  .slidev-code-line-numbers .slidev-code code .line::before {
60
60
  content: counter(step);
61
61
  counter-increment: step;
62
- @apply w-4 mr-6 inline-block text-right text-gray-400 dark:text-gray-600;
62
+ display: inline-block;
63
+ text-align: right;
64
+ --uno: w-4 mr-6 text-gray-400 dark:text-gray-600;
63
65
  }
64
66
 
65
67
  /* Inline Code */
@@ -67,7 +69,7 @@ html:not(.dark) .shiki span {
67
69
  font-size: 0.9em;
68
70
  background: var(--slidev-code-background);
69
71
  border-radius: var(--slidev-code-radius);
70
- @apply font-light py-0.5 px-1.5;
72
+ --uno: font-light py-0.5 px-1.5;
71
73
  }
72
74
 
73
75
  .slidev-layout :not(pre) > code:before {
@@ -82,4 +84,6 @@ html:not(.dark) .shiki span {
82
84
  }
83
85
 
84
86
  /* CodeMirror */
85
- .CodeMirror pre.CodeMirror-placeholder { opacity: 0.4; }
87
+ .CodeMirror pre.CodeMirror-placeholder {
88
+ opacity: 0.4;
89
+ }
package/styles/index.css CHANGED
@@ -23,15 +23,16 @@ html {
23
23
  }
24
24
 
25
25
  .slidev-icon-btn.shallow {
26
- @apply opacity-30
26
+ opacity: 0.3;
27
27
  }
28
28
 
29
29
  .slidev-icon-btn.active {
30
- @apply opacity-100
30
+ opacity: 1;
31
31
  }
32
32
 
33
33
  .slidev-icon-btn.disabled {
34
- @apply opacity-25 pointer-events-none;
34
+ opacity: 0.25;
35
+ pointer-events: none;
35
36
  }
36
37
 
37
38
  .slidev-vclick-target {
@@ -39,11 +40,13 @@ html {
39
40
  }
40
41
 
41
42
  .slidev-vclick-hidden {
42
- @apply !opacity-0 !pointer-events-none;
43
+ opacity: 0 !important;
44
+ pointer-events: none !important;
45
+ user-select: none !important;
43
46
  }
44
47
 
45
48
  .slidev-vclick-fade {
46
- @apply opacity-50;
49
+ opacity: 0.5;
47
50
  }
48
51
 
49
52
  .slidev-icon {
@@ -53,5 +56,14 @@ html {
53
56
  }
54
57
 
55
58
  .slidev-page {
56
- @apply absolute top-0 left-0 right-0 w-full relative;
59
+ position: relative;
60
+ top: 0;
61
+ left: 0;
62
+ right: 0;
63
+ width: 100%;
64
+ }
65
+
66
+ /* Transform the position back for Rough Notation (v-mark) */
67
+ .rough-annotation {
68
+ transform: scale(calc(1 / var(--slidev-slide-scale)));
57
69
  }
package/styles/katex.css CHANGED
@@ -2,4 +2,4 @@
2
2
  }
3
3
  .slidev-katex-wrapper .mord.dishonored {
4
4
  opacity: 0.3;
5
- }
5
+ }
@@ -1,7 +1,8 @@
1
1
  .slidev-layout {
2
2
  @apply px-14 py-10 text-[1.1rem] h-full;
3
3
 
4
- pre, code {
4
+ pre,
5
+ code {
5
6
  @apply select-text;
6
7
  }
7
8
 
@@ -54,7 +55,9 @@
54
55
  }
55
56
 
56
57
  blockquote {
57
- @apply text-sm px-2 py-1 bg-$prism-background text-$prism-foreground border-$slidev-theme-primary border-l rounded;
58
+ background: var(--slidev-code-background);
59
+ color: var(--slidev-code-foreground);
60
+ @apply text-sm px-2 py-1 border-primary border-l rounded;
58
61
  }
59
62
 
60
63
  blockquote > * {
@@ -66,7 +69,7 @@
66
69
  }
67
70
 
68
71
  tr {
69
- @apply border-b border-gray-400 border-opacity-20;
72
+ @apply border-b border-main;
70
73
  }
71
74
 
72
75
  th {
@@ -74,26 +77,28 @@
74
77
  }
75
78
 
76
79
  a {
77
- @apply border-current border-b border-dashed hover:text-$slidev-theme-primary hover:border-solid;
80
+ @apply border-current border-b border-dashed hover:text-primary hover:border-solid;
78
81
  }
79
82
 
80
- td, th {
83
+ td,
84
+ th {
81
85
  @apply p-2 py-3;
82
86
  }
83
87
 
84
- b, strong {
88
+ b,
89
+ strong {
85
90
  @apply font-600;
86
91
  }
87
92
 
88
93
  kbd {
89
- @apply border border-gray-400 border-b-2 border-opacity-20 rounded;
94
+ @apply border border-main border-b-2 rounded;
90
95
  @apply bg-gray-400 bg-opacity-5 py-0.5 px-1 text-xs font-mono;
91
96
  }
92
97
  }
93
98
 
94
99
  .slidev-layout,
95
- [dir=ltr],
96
- .slidev-layout [dir=ltr] {
100
+ [dir='ltr'],
101
+ .slidev-layout [dir='ltr'] {
97
102
  h1 {
98
103
  @apply -ml-[0.05em] mr-0;
99
104
  }
@@ -107,10 +112,10 @@
107
112
  }
108
113
  }
109
114
 
110
- [dir=rtl],
111
- .slidev-layout [dir=rtl] {
115
+ [dir='rtl'],
116
+ .slidev-layout [dir='rtl'] {
112
117
  h1 {
113
- @apply -mr-[0.05em] ml-0;
118
+ @apply -mr-[0.05em] ml-0;
114
119
  }
115
120
 
116
121
  h6 {
package/styles/vars.css CHANGED
@@ -7,6 +7,7 @@
7
7
  --slidev-code-line-height: 18px;
8
8
  --slidev-code-radius: 4px;
9
9
  --slidev-code-margin: 4px 0;
10
+ --slidev-theme-primary: #3ab9d5;
10
11
 
11
12
  --slidev-transition-duration: 0.5s;
12
13
  --slidev-slide-container-background: black;
package/uno.config.ts CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  transformerDirectives,
9
9
  transformerVariantGroup,
10
10
  } from 'unocss'
11
+ import { variantMatcher } from '@unocss/preset-mini/utils'
11
12
 
12
13
  export default defineConfig({
13
14
  safelist: [
@@ -15,15 +16,26 @@ export default defineConfig({
15
16
  'prose',
16
17
  ],
17
18
  shortcuts: {
18
- 'bg-main': 'bg-white text-[#181818] dark:(bg-[#121212] text-[#ddd])',
19
+ 'bg-main': 'bg-white dark:bg-[#121212]',
19
20
  'bg-active': 'bg-gray-400/10',
20
- 'border-main': 'border-gray-400/20',
21
+ 'border-main': 'border-gray/20',
22
+ 'text-main': 'text-[#181818] dark:text-[#ddd]',
23
+ 'text-primary': 'color-$slidev-theme-primary',
24
+ 'bg-primary': 'bg-$slidev-theme-primary',
25
+ 'border-primary': 'border-$slidev-theme-primary',
21
26
  'abs-tl': 'absolute top-0 left-0',
22
27
  'abs-tr': 'absolute top-0 right-0',
23
28
  'abs-b': 'absolute bottom-0 left-0 right-0',
24
29
  'abs-bl': 'absolute bottom-0 left-0',
25
30
  'abs-br': 'absolute bottom-0 right-0',
26
31
  },
32
+ // Slidev Specific Variants, probably extrat to a preset later
33
+ variants: [
34
+ // `forward:` and `backward:` variant to selectively apply styles based on the direction of the slide
35
+ // For example, `forward:text-red` will only apply to the slides that are navigated forward
36
+ variantMatcher('forward', input => ({ prefix: `.slidev-nav-go-forward ${input.prefix}` })),
37
+ variantMatcher('backward', input => ({ prefix: `.slidev-nav-go-backward ${input.prefix}` })),
38
+ ],
27
39
  presets: [
28
40
  presetUno(),
29
41
  presetAttributify(),