Skip to content

Commit eb0da0a

Browse files
committed
feat: slides overview
1 parent 42ff547 commit eb0da0a

11 files changed

Lines changed: 194 additions & 38 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ npx vite-slides export talk.pdf
3939
- [ ] Shiki + TwoSlash
4040
- [ ] Export PDF
4141
- [x] Monaco as markdown
42-
- [ ] Slides Overview
42+
- [x] Slides Overview
4343
- [ ] Foot notes
4444
- [x] `v-click` directive
4545
- [ ] Standalone package

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"@antfu/utils": "^0.0.8",
2121
"@iconify/json": "^1.1.329",
2222
"@types/fs-extra": "^9.0.11",
23-
"@types/node": "^14.14.40",
23+
"@types/node": "^14.14.41",
2424
"@types/prettier": "^2.2.3",
2525
"@typescript-eslint/eslint-plugin": "^4.22.0",
2626
"@vitejs/plugin-vue": "^1.2.1",
@@ -31,7 +31,7 @@
3131
"js-base64": "^3.6.0",
3232
"markdown-it-prism": "^2.1.6",
3333
"monaco-editor": "^0.23.0",
34-
"pnpm": "^6.0.2",
34+
"pnpm": "^6.1.0",
3535
"prettier": "^2.2.1",
3636
"theme-vitesse": "^0.1.9",
3737
"typescript": "^4.2.4",

pnpm-lock.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

slides.md

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ mouse.x === x.value // true
490490

491491
The `watch` and `computed` will stop themselves on components unmounted. <br>We'd recommend following the same pattern for your custom composable functions.
492492

493-
<div>
493+
<div v-click>
494494

495495
```ts{monaco}
496496
import { onUnmounted } from 'vue'
@@ -508,7 +508,7 @@ export function useEventListener(target: EventTarget, name: string, fn: any) {
508508

509509
</div>
510510

511-
<div class="abs-b mx-14 my-12">
511+
<div v-click class="abs-b mx-14 my-12">
512512
<VueUse name="useEventListener"/>
513513
</div>
514514

@@ -539,12 +539,6 @@ const scope = effectScope(() => {
539539
stop(scope)
540540
```
541541

542-
---
543-
layout: center
544-
---
545-
546-
# Tips
547-
548542
------
549543

550544
# Template Ref <MarkerTips />
@@ -594,6 +588,7 @@ watch(element, (el) => {
594588
------
595589

596590
# Typed Provide / Inject <MarkerCore/>
591+
597592
Use the `InjectionKey<T>` helper from Vue to share types across context.
598593

599594
<div>
@@ -615,6 +610,7 @@ export const injectKeyUser: InjectionKey<UserInfo> = Symbol()
615610
------
616611

617612
# Typed Provide / Inject <MarkerCore/>
613+
618614
Import the key from the same module for `provide` and `inject`.
619615

620616
<div class="grid grid-cols-2 gap-4">
@@ -667,39 +663,100 @@ export const injectKeyUser: InjectionKey<UserInfo> = Symbol()
667663

668664
------
669665

670-
# App Level Singleton
666+
# Shared State <MarkerPattern />
667+
668+
By the nature of Composition API, states can be created and used independently.
671669

672670
<div class="grid grid-cols-2 gap-4">
673671

672+
<v-click>
673+
674+
```ts
675+
// shared.ts
676+
import { reactive } from 'vue'
677+
678+
export const state = reactive({
679+
foo: 1,
680+
bar: 'Hello'
681+
})
682+
```
683+
684+
</v-click>
685+
686+
<div>
687+
<v-clicks>
688+
689+
```ts
690+
// A.vue
691+
import { state } from './shared.ts'
692+
693+
state.foo += 1
694+
```
695+
674696
```ts
675-
export const keyMyTool: InjectionKey<MyTool> = Symbol()
697+
// B.vue
698+
import { state } from './shared.ts'
699+
700+
console.log(state.foo) // 2
701+
```
702+
703+
</v-clicks>
704+
</div>
705+
</div>
706+
707+
<h3 v-click class="opacity-100">⚠️ But it's not SSR compatible!</h3>
708+
709+
------
710+
711+
# Shared State (SSR friendly) <MarkerPattern />
712+
713+
<div class="grid grid-cols-[max-content,1fr] gap-4">
714+
715+
<v-click>
676716

677-
export function createMyTool() {
717+
```ts
718+
export const myStateKey: InjectionKey<MyState> = Symbol()
719+
720+
export function createMyState() {
678721
const state = {
679722
/* ... */
680723
}
681724

682725
return {
683726
install(app: App) {
684-
app.provide(keyMyTool, state)
727+
app.provide(myStateKey, state)
685728
}
686729
}
687730
}
688731

689-
export function useMyTool(): MyTool {
690-
return inject(keyMyTool)!
732+
export function useMyState(): MyState {
733+
return inject(myStateKey)!
691734
}
692735
```
693736

737+
</v-click>
738+
739+
<div>
740+
<v-clicks>
741+
694742
```ts
743+
// main.ts
695744
const App = createApp(App)
696745

697-
app.use(createMyTool())
746+
app.use(createMyState())
698747
```
699748

749+
```ts
750+
// A.vue
751+
752+
// use everywhere in your app
753+
const state = useMyState()
754+
```
755+
756+
</v-clicks>
700757
</div>
701758

702-
> TODO:
759+
</div>
703760

704761
------
705762

src/builtin/MonacoEnv.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ self.MonacoEnvironment = {
3232
},
3333
}
3434

35-
console.log(monaco.languages.typescript.typescriptDefaults.getCompilerOptions())
35+
// console.log(monaco.languages.typescript.typescriptDefaults.getCompilerOptions())
3636

3737
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
3838
...monaco.languages.typescript.typescriptDefaults.getCompilerOptions(),

src/builtin/SlideControls.vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
<script setup lang="ts">
22
import { useFullscreen } from '@vueuse/core'
3+
import { ref } from 'vue'
34
import { isDark, toggleDark, useNavigateControls } from '~/logic'
45
56
const { isFullscreen, toggle: toggleFullscreen } = useFullscreen(document.body)
67
const { hasNext, hasPrev, prev, next } = useNavigateControls()
8+
9+
const showOverview = ref(false)
710
</script>
811

912
<template>
13+
<SlidesOverview v-model="showOverview" />
1014
<nav class="opacity-0 pb-4 pt-5 pl-6 pr-4 transition right-0 bottom-0 rounded-tl text-xl flex gap-4 text-gray-400 bg-transparent duration-300 fixed hover:(shadow bg-main opacity-100)">
15+
<button class="icon-btn" @click="showOverview = !showOverview">
16+
<carbon:apps />
17+
</button>
18+
1119
<button class="icon-btn" :class="{ disabled: !hasPrev }" @click="prev">
1220
<carbon:arrow-left />
1321
</button>

src/builtin/SlidesOverview.vue

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<script setup lang="ts">
2+
import { useVModel } from '@vueuse/core'
3+
import { computed, defineEmit, defineProps } from 'vue'
4+
import { useNavigateControls } from '~/logic/controls'
5+
import { targetWidth, targetHeight } from '~/logic/scale'
6+
7+
const emit = defineEmit()
8+
const props = defineProps<{ modelValue: boolean }>()
9+
10+
const value = useVModel(props, 'modelValue', emit)
11+
12+
const { routes } = useNavigateControls()
13+
14+
const scale = 0.25
15+
const innerStyle = computed(() => ({
16+
height: `${targetHeight}px`,
17+
width: `${targetWidth}px`,
18+
transformOrigin: 'top left',
19+
transform: `scale(${scale})`,
20+
}))
21+
const style = computed(() => ({
22+
height: `${targetHeight * scale}px`,
23+
width: `${targetWidth * scale}px`,
24+
}))
25+
</script>
26+
27+
<template>
28+
<div
29+
v-if="value"
30+
class="bg-main !bg-opacity-75 p-20 fixed left-0 right-0 top-0 bottom-0 overflow-y-auto"
31+
style="backdrop-filter: blur(5px);"
32+
>
33+
<div
34+
class="grid gap-y-4 gap-x-8 w-full"
35+
style="grid-template-columns: repeat(auto-fit,minmax(220px,1fr));"
36+
>
37+
<div
38+
v-for="(route, idx) of routes.slice(0, -1)"
39+
:key="route.path"
40+
:style="style"
41+
class="relative"
42+
>
43+
<RouterLink
44+
:to="route.path"
45+
:style="style"
46+
class="block border border-gray-400 rounded border-opacity-50 overflow-hidden bg-main hover:(border-primary)"
47+
@click="value = false"
48+
>
49+
<div :style="innerStyle" class="pointer-events-none">
50+
<KeepAlive>
51+
<component :is="route.component" v-click-disabled />
52+
</KeepAlive>
53+
</div>
54+
</RouterLink>
55+
<div class="absolute top-0 left-225px opacity-50">
56+
{{ idx }}
57+
</div>
58+
</div>
59+
</div>
60+
</div>
61+
</template>

src/layouts/default.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
}
2626
2727
h3 {
28-
@apply text-sm pt-2 opacity-40 uppercase tracking-widest font-500 -ml-[0.05em];
28+
@apply text-sm pt-2 uppercase tracking-widest font-500 -ml-[0.05em];
29+
}
30+
31+
h3:not(.opacity-100) {
32+
@apply opacity-40;
2933
}
3034
3135
p {

src/logic/controls.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { computed, App, InjectionKey, inject, ref, ComputedRef, Ref } from 'vue'
22
import { Fn, useMagicKeys, whenever } from '@vueuse/core'
3-
import { Router } from 'vue-router'
3+
import { Router, RouteRecordRaw } from 'vue-router'
44
import { clickCurrent, clickElements } from '~/modules/directives'
55

66
export interface NavigateControls {
77
next: Fn
88
prev: Fn
99
nextSlide: Fn
1010
prevSlide: Fn
11+
routes: RouteRecordRaw[]
1112
paused: Ref<boolean>
1213
hasNext: ComputedRef<boolean>
1314
hasPrev: ComputedRef<boolean>
@@ -73,6 +74,7 @@ export function createNavigateControls(router: Router) {
7374
paused,
7475
hasNext,
7576
hasPrev,
77+
routes,
7678
install(app: App) {
7779
app.provide(NavigateControlsInjection, navigateControls)
7880
},

0 commit comments

Comments
 (0)