@slidev/client 0.43.11 → 0.43.13

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.
@@ -2,7 +2,7 @@
2
2
  import { computed, ref, shallowRef } from 'vue'
3
3
  import { isColorSchemaConfigured, isDark, toggleDark } from '../logic/dark'
4
4
  import { currentPage, downloadPDF, hasNext, hasPrev, isEmbedded, isPresenter, next, presenterPassword, prev, showPresenter, total } from '../logic/nav'
5
- import { activeElement, breakpoints, fullscreen, showEditor, showInfoDialog, showPresenterCursor, toggleOverview } from '../state'
5
+ import { activeElement, breakpoints, fullscreen, presenterLayout, showEditor, showInfoDialog, showPresenterCursor, toggleOverview, togglePresenterLayout } from '../state'
6
6
  import { brush, drawingEnabled } from '../logic/drawings'
7
7
  import { configs } from '../env'
8
8
  import Settings from './Settings.vue'
@@ -148,6 +148,11 @@ if (__SLIDEV_FEATURE_DRAWINGS__)
148
148
  <HiddenText :text="showEditor ? 'Hide editor' : 'Show editor'" />
149
149
  <carbon:text-annotation-toggle />
150
150
  </button>
151
+
152
+ <button v-if="isPresenter" class="slidev-icon-btn" title="Toggle Presenter Layout" @click="togglePresenterLayout">
153
+ <carbon:template />
154
+ {{ presenterLayout }}
155
+ </button>
151
156
  </template>
152
157
  <template v-if="!__DEV__">
153
158
  <button v-if="configs.download" class="slidev-icon-btn" @click="downloadPDF">
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { ignorableWatch, onClickOutside } from '@vueuse/core'
3
- import { nextTick, ref, watch } from 'vue'
2
+ import { ignorableWatch, onClickOutside, useVModel } from '@vueuse/core'
3
+ import { ref, watch, watchEffect } from 'vue'
4
4
  import { currentSlideId } from '../logic/nav'
5
5
  import { useDynamicSlideInfo } from '../logic/note'
6
6
  import NoteDisplay from './NoteDisplay.vue'
@@ -9,11 +9,22 @@ const props = defineProps({
9
9
  class: {
10
10
  default: '',
11
11
  },
12
+ editing: {
13
+ default: false,
14
+ },
15
+ style: {
16
+ default: () => ({}),
17
+ },
12
18
  placeholder: {
13
19
  default: 'No notes for this slide',
14
20
  },
15
21
  })
16
22
 
23
+ const emit = defineEmits([
24
+ 'update:editing',
25
+ ])
26
+ const editing = useVModel(props, 'editing', emit, { passive: true })
27
+
17
28
  const { info, update } = useDynamicSlideInfo(currentSlideId)
18
29
 
19
30
  const note = ref('')
@@ -42,17 +53,11 @@ watch(
42
53
  )
43
54
 
44
55
  const input = ref<HTMLTextAreaElement>()
45
- const editing = ref(false)
46
56
 
47
- async function switchNoteEdit(e: MouseEvent) {
48
- if ((e?.target as HTMLElement)?.tagName === 'A')
49
- return
50
-
51
- editing.value = true
52
- input.value?.focus()
53
- await nextTick()
54
- input.value?.focus()
55
- }
57
+ watchEffect(() => {
58
+ if (editing.value)
59
+ input.value?.focus()
60
+ })
56
61
 
57
62
  onClickOutside(input, () => {
58
63
  editing.value = false
@@ -61,20 +66,23 @@ onClickOutside(input, () => {
61
66
 
62
67
  <template>
63
68
  <NoteDisplay
64
- v-if="!editing && note"
65
- :class="props.class"
66
- :note="note"
69
+ v-if="!editing"
70
+ class="my--4 border-transparent border-2"
71
+ :class="[props.class, note ? '' : 'opacity-50']"
72
+ :style="props.style"
73
+ :note="note || placeholder"
67
74
  :note-html="info?.noteHTML"
68
- @click="switchNoteEdit"
69
75
  />
70
76
  <textarea
71
77
  v-else
72
78
  ref="input"
73
79
  v-model="note"
74
- class="prose resize-none overflow-auto outline-none bg-transparent block"
75
- style="line-height: 1.75; margin: 1em 0;"
80
+ class="prose resize-none overflow-auto outline-none bg-transparent block border-green border-2"
81
+ style="line-height: 1.75;"
82
+ :style="props.style"
76
83
  :class="props.class"
77
84
  :placeholder="placeholder"
85
+ @keydown.esc=" editing = false"
78
86
  @focus="editing = true"
79
87
  />
80
88
  </template>
@@ -3,7 +3,7 @@ import { useHead } from '@vueuse/head'
3
3
  import { computed, onMounted, reactive, ref, shallowRef, watch } from 'vue'
4
4
  import { useMouse, useWindowFocus } from '@vueuse/core'
5
5
  import { clicks, clicksTotal, currentPage, currentRoute, hasNext, nextRoute, total, useSwipeControls } from '../logic/nav'
6
- import { showEditor, showOverview, showPresenterCursor } from '../state'
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'
9
9
  import { registerShortcuts } from '../logic/shortcuts'
@@ -30,6 +30,8 @@ useHead({
30
30
  title: `Presenter - ${slideTitle}`,
31
31
  })
32
32
 
33
+ const notesEditing = ref(false)
34
+
33
35
  const { timer, resetTimer } = useTimer()
34
36
 
35
37
  const nextTabElements = ref([])
@@ -86,7 +88,7 @@ onMounted(() => {
86
88
 
87
89
  <template>
88
90
  <div class="bg-main h-full slidev-presenter">
89
- <div class="grid-container">
91
+ <div class="grid-container" :class="`layout${presenterLayout}`">
90
92
  <div class="grid-section top flex">
91
93
  <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">
92
94
  <div class="flex-auto" />
@@ -135,12 +137,39 @@ onMounted(() => {
135
137
  next
136
138
  </div>
137
139
  </div>
138
- <div class="grid-section note overflow-auto">
139
- <template v-if="__DEV__ && __SLIDEV_FEATURE_EDITOR__ && Editor && showEditor">
140
- <Editor />
141
- </template>
142
- <NoteEditor v-else-if="__DEV__" class="w-full max-w-full h-full overflow-auto p-2 lg:p-4" />
143
- <NoteStatic v-else class="w-full max-w-full h-full overflow-auto p-2 lg:p-4" />
140
+ <!-- Notes -->
141
+ <div v-if="__DEV__ && __SLIDEV_FEATURE_EDITOR__ && Editor && showEditor" class="grid-section note of-auto">
142
+ <Editor />
143
+ </div>
144
+ <div v-else class="grid-section note grid grid-rows-[1fr_min-content]">
145
+ <NoteEditor
146
+ v-if="__DEV__"
147
+ class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
148
+ :editing="notesEditing"
149
+ :style="{ fontSize: `${presenterNotesFontSize}em` }"
150
+ />
151
+ <NoteStatic
152
+ v-else
153
+ class="w-full max-w-full h-full overflow-auto p-2 lg:p-4"
154
+ :style="{ fontSize: `${presenterNotesFontSize}em` }"
155
+ />
156
+ <div class="border-t border-main py-1 px-2 text-sm">
157
+ <button class="slidev-icon-btn" @click="increasePresenterFontSize">
158
+ <HiddenText text="Increase font size" />
159
+ <carbon:zoom-in />
160
+ </button>
161
+ <button class="slidev-icon-btn" @click="decreasePresenterFontSize">
162
+ <HiddenText text="Decrease font size" />
163
+ <carbon:zoom-out />
164
+ </button>
165
+ <button
166
+ v-if="__DEV__"
167
+ class="slidev-icon-btn" @click="notesEditing = !notesEditing"
168
+ >
169
+ <HiddenText text="Edit Notes" />
170
+ <carbon:edit />
171
+ </button>
172
+ </div>
144
173
  </div>
145
174
  <div class="grid-section bottom">
146
175
  <NavControls :persist="true" />
@@ -180,6 +209,9 @@ onMounted(() => {
180
209
  @apply h-full w-full bg-gray-400 bg-opacity-15;
181
210
  display: grid;
182
211
  gap: 1px 1px;
212
+ }
213
+
214
+ .grid-container.layout1 {
183
215
  grid-template-columns: 1fr 1fr;
184
216
  grid-template-rows: min-content 2fr 1fr min-content;
185
217
  grid-template-areas:
@@ -189,8 +221,18 @@ onMounted(() => {
189
221
  "bottom bottom";
190
222
  }
191
223
 
224
+ .grid-container.layout2 {
225
+ grid-template-columns: 3fr 2fr;
226
+ grid-template-rows: min-content 2fr 1fr min-content;
227
+ grid-template-areas:
228
+ "top top"
229
+ "note main"
230
+ "note next"
231
+ "bottom bottom";
232
+ }
233
+
192
234
  @media (max-aspect-ratio: 3/5) {
193
- .grid-container {
235
+ .grid-container.layout1 {
194
236
  grid-template-columns: 1fr;
195
237
  grid-template-rows: min-content 1fr 1fr 1fr min-content;
196
238
  grid-template-areas:
@@ -203,7 +245,7 @@ onMounted(() => {
203
245
  }
204
246
 
205
247
  @media (min-aspect-ratio: 1/1) {
206
- .grid-container {
248
+ .grid-container.layout1 {
207
249
  grid-template-columns: 1fr 1.1fr 0.9fr;
208
250
  grid-template-rows: min-content 1fr 2fr min-content;
209
251
  grid-template-areas:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slidev/client",
3
- "version": "0.43.11",
3
+ "version": "0.43.13",
4
4
  "description": "Presentation slides for developers",
5
5
  "author": "antfu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",
@@ -45,8 +45,8 @@
45
45
  "vue-router": "^4.2.5",
46
46
  "vue-starport": "^0.4.0",
47
47
  "windicss": "^3.5.6",
48
- "@slidev/parser": "0.43.11",
49
- "@slidev/types": "0.43.11"
48
+ "@slidev/types": "0.43.13",
49
+ "@slidev/parser": "0.43.13"
50
50
  },
51
51
  "devDependencies": {
52
52
  "vite": "^4.5.0"
package/state/index.ts CHANGED
@@ -29,4 +29,21 @@ export const showPresenterCursor = useLocalStorage('slidev-presenter-cursor', tr
29
29
  export const showEditor = useLocalStorage('slidev-show-editor', false)
30
30
  export const editorWidth = useLocalStorage('slidev-editor-width', isClient ? window.innerWidth * 0.4 : 100)
31
31
 
32
+ export const presenterNotesFontSize = useLocalStorage('slidev-presenter-font-size', 1)
33
+ export const presenterLayout = useLocalStorage('slidev-presenter-layout', 1)
34
+
35
+ export function togglePresenterLayout() {
36
+ presenterLayout.value = presenterLayout.value + 1
37
+ if (presenterLayout.value > 2)
38
+ presenterLayout.value = 1
39
+ }
40
+
41
+ export function increasePresenterFontSize() {
42
+ presenterNotesFontSize.value = Math.min(2, presenterNotesFontSize.value + 0.1)
43
+ }
44
+
45
+ export function decreasePresenterFontSize() {
46
+ presenterNotesFontSize.value = Math.max(0.5, presenterNotesFontSize.value - 0.1)
47
+ }
48
+
32
49
  export const toggleOverview = useToggle(showOverview)