@slidev/client 0.48.0-beta.6 → 0.48.0-beta.7
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.
- package/internals/SlideContainer.vue +4 -3
- package/main.ts +5 -3
- package/modules/context.ts +1 -1
- package/modules/{directives.ts → v-click.ts} +15 -15
- package/modules/v-mark.ts +159 -0
- package/package.json +9 -8
- package/styles/index.css +5 -0
|
@@ -47,9 +47,10 @@ const scale = computed(() => {
|
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
const style = computed(() => ({
|
|
50
|
-
height: `${slideHeight}px`,
|
|
51
|
-
width: `${slideWidth}px`,
|
|
52
|
-
transform: `translate(-50%, -50%) scale(${scale.value})`,
|
|
50
|
+
'height': `${slideHeight}px`,
|
|
51
|
+
'width': `${slideWidth}px`,
|
|
52
|
+
'transform': `translate(-50%, -50%) scale(${scale.value})`,
|
|
53
|
+
'--slidev-slide-scale': scale.value,
|
|
53
54
|
}))
|
|
54
55
|
|
|
55
56
|
const className = computed(() => ({
|
package/main.ts
CHANGED
|
@@ -3,15 +3,17 @@ import { createHead } from '@unhead/vue'
|
|
|
3
3
|
import App from './App.vue'
|
|
4
4
|
import setupMain from './setup/main'
|
|
5
5
|
import { router } from './routes'
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import { createVClickDirectives } from './modules/v-click'
|
|
7
|
+
import { createVMarkDirective } from './modules/v-mark'
|
|
8
|
+
import { createSlidevContext } from './modules/context'
|
|
8
9
|
|
|
9
10
|
import '/@slidev/styles'
|
|
10
11
|
|
|
11
12
|
const app = createApp(App)
|
|
12
13
|
app.use(router)
|
|
13
14
|
app.use(createHead())
|
|
14
|
-
app.use(
|
|
15
|
+
app.use(createVClickDirectives())
|
|
16
|
+
app.use(createVMarkDirective())
|
|
15
17
|
app.use(createSlidevContext())
|
|
16
18
|
|
|
17
19
|
setupMain({ app, router })
|
package/modules/context.ts
CHANGED
|
@@ -21,7 +21,7 @@ export interface SlidevContext {
|
|
|
21
21
|
themeConfigs: ComputedRef<typeof configs['themeConfig']>
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export
|
|
24
|
+
export function createSlidevContext() {
|
|
25
25
|
return {
|
|
26
26
|
install(app: App) {
|
|
27
27
|
const context = reactive(useContext(route))
|
|
@@ -11,19 +11,21 @@ import {
|
|
|
11
11
|
injectionClicksContext,
|
|
12
12
|
} from '../constants'
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
export type VClickValue = string | [string | number, string | number] | boolean
|
|
15
|
+
|
|
16
|
+
export function dirInject<T = unknown>(dir: DirectiveBinding<any>, key: InjectionKey<T> | string, defaultValue?: T): T | undefined {
|
|
15
17
|
return (dir.instance?.$ as any).provides[key as any] ?? defaultValue
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
export
|
|
20
|
+
export function createVClickDirectives() {
|
|
19
21
|
return {
|
|
20
22
|
install(app: App) {
|
|
21
|
-
app.directive('click', {
|
|
23
|
+
app.directive<HTMLElement, VClickValue>('click', {
|
|
22
24
|
// @ts-expect-error extra prop
|
|
23
25
|
name: 'v-click',
|
|
24
26
|
|
|
25
|
-
mounted(el
|
|
26
|
-
const resolved = resolveClick(el, dir)
|
|
27
|
+
mounted(el, dir) {
|
|
28
|
+
const resolved = resolveClick(el, dir, dir.value)
|
|
27
29
|
if (resolved == null)
|
|
28
30
|
return
|
|
29
31
|
|
|
@@ -55,12 +57,12 @@ export default function createDirectives() {
|
|
|
55
57
|
unmounted,
|
|
56
58
|
})
|
|
57
59
|
|
|
58
|
-
app.directive('after', {
|
|
60
|
+
app.directive<HTMLElement, VClickValue>('after', {
|
|
59
61
|
// @ts-expect-error extra prop
|
|
60
62
|
name: 'v-after',
|
|
61
63
|
|
|
62
|
-
mounted(el
|
|
63
|
-
const resolved = resolveClick(el, dir, true)
|
|
64
|
+
mounted(el, dir) {
|
|
65
|
+
const resolved = resolveClick(el, dir, dir.value, true)
|
|
64
66
|
if (resolved == null)
|
|
65
67
|
return
|
|
66
68
|
|
|
@@ -86,12 +88,12 @@ export default function createDirectives() {
|
|
|
86
88
|
unmounted,
|
|
87
89
|
})
|
|
88
90
|
|
|
89
|
-
app.directive('click-hide', {
|
|
91
|
+
app.directive<HTMLElement, VClickValue>('click-hide', {
|
|
90
92
|
// @ts-expect-error extra prop
|
|
91
93
|
name: 'v-click-hide',
|
|
92
94
|
|
|
93
|
-
mounted(el
|
|
94
|
-
const resolved = resolveClick(el, dir, false, true)
|
|
95
|
+
mounted(el, dir) {
|
|
96
|
+
const resolved = resolveClick(el, dir, dir.value, false, true)
|
|
95
97
|
if (resolved == null)
|
|
96
98
|
return
|
|
97
99
|
|
|
@@ -127,14 +129,12 @@ function isCurrent(thisClick: number | [number, number], clicks: number) {
|
|
|
127
129
|
: thisClick === clicks
|
|
128
130
|
}
|
|
129
131
|
|
|
130
|
-
function resolveClick(el: Element, dir: DirectiveBinding<any>, clickAfter = false, flagHide = false): ResolvedClicksInfo | null {
|
|
132
|
+
export function resolveClick(el: Element, dir: DirectiveBinding<any>, value: VClickValue, clickAfter = false, flagHide = false): ResolvedClicksInfo | null {
|
|
131
133
|
const ctx = dirInject(dir, injectionClicksContext)?.value
|
|
132
134
|
|
|
133
135
|
if (!el || !ctx || ctx.disabled)
|
|
134
136
|
return null
|
|
135
137
|
|
|
136
|
-
let value = dir.value
|
|
137
|
-
|
|
138
138
|
if (value === false || value === 'false')
|
|
139
139
|
return null
|
|
140
140
|
|
|
@@ -153,7 +153,7 @@ function resolveClick(el: Element, dir: DirectiveBinding<any>, clickAfter = fals
|
|
|
153
153
|
// range (absolute)
|
|
154
154
|
delta = 0
|
|
155
155
|
thisClick = value as [number, number]
|
|
156
|
-
maxClick = value[1]
|
|
156
|
+
maxClick = +value[1]
|
|
157
157
|
}
|
|
158
158
|
else {
|
|
159
159
|
({ start: thisClick, end: maxClick, delta } = ctx.resolve(value))
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type { RoughAnnotationConfig } from '@slidev/rough-notation'
|
|
2
|
+
import { annotate } from '@slidev/rough-notation'
|
|
3
|
+
import type { App } from 'vue'
|
|
4
|
+
import { computed, watchEffect } from 'vue'
|
|
5
|
+
import type { VClickValue } from './v-click'
|
|
6
|
+
import { resolveClick } from './v-click'
|
|
7
|
+
|
|
8
|
+
export interface RoughDirectiveOptions extends Partial<RoughAnnotationConfig> {
|
|
9
|
+
at: VClickValue
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type RoughDirectiveValue = VClickValue | RoughDirectiveOptions
|
|
13
|
+
|
|
14
|
+
function addClass(options: RoughDirectiveOptions, cls: string) {
|
|
15
|
+
options.class = [options.class, cls].filter(Boolean).join(' ')
|
|
16
|
+
return options
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Definitions of supported modifiers
|
|
20
|
+
const vMarkModifiers: Record<string, (options: RoughDirectiveOptions, value?: any) => RoughDirectiveOptions> = {
|
|
21
|
+
// Types
|
|
22
|
+
'box': options => Object.assign(options, { type: 'box' }),
|
|
23
|
+
'circle': options => Object.assign(options, { type: 'circle' }),
|
|
24
|
+
'underline': options => Object.assign(options, { type: 'underline' }),
|
|
25
|
+
'highlight': options => Object.assign(options, { type: 'highlight' }),
|
|
26
|
+
'strike-through': options => Object.assign(options, { type: 'strike-through' }),
|
|
27
|
+
'crossed-off': options => Object.assign(options, { type: 'crossed-off' }),
|
|
28
|
+
'bracket': options => Object.assign(options, { type: 'bracket' }),
|
|
29
|
+
|
|
30
|
+
// Type Aliases
|
|
31
|
+
'strike': options => Object.assign(options, { type: 'strike-through' }),
|
|
32
|
+
'cross': options => Object.assign(options, { type: 'crossed-off' }),
|
|
33
|
+
'crossed': options => Object.assign(options, { type: 'crossed-off' }),
|
|
34
|
+
'linethrough': options => Object.assign(options, { type: 'strike-through' }),
|
|
35
|
+
'line-through': options => Object.assign(options, { type: 'strike-through' }),
|
|
36
|
+
|
|
37
|
+
// Colors
|
|
38
|
+
// @unocss-include
|
|
39
|
+
'black': options => addClass(options, 'text-black'),
|
|
40
|
+
'blue': options => addClass(options, 'text-blue'),
|
|
41
|
+
'cyan': options => addClass(options, 'text-cyan'),
|
|
42
|
+
'gray': options => addClass(options, 'text-gray'),
|
|
43
|
+
'green': options => addClass(options, 'text-green'),
|
|
44
|
+
'indigo': options => addClass(options, 'text-indigo'),
|
|
45
|
+
'lime': options => addClass(options, 'text-lime'),
|
|
46
|
+
'orange': options => addClass(options, 'text-orange'),
|
|
47
|
+
'pink': options => addClass(options, 'text-pink'),
|
|
48
|
+
'purple': options => addClass(options, 'text-purple'),
|
|
49
|
+
'red': options => addClass(options, 'text-red'),
|
|
50
|
+
'teal': options => addClass(options, 'text-teal'),
|
|
51
|
+
'white': options => addClass(options, 'text-white'),
|
|
52
|
+
'yellow': options => addClass(options, 'text-yellow'),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const vMarkModifiersDynamic: [RegExp, (match: RegExpMatchArray, options: RoughDirectiveOptions, value?: any) => RoughDirectiveOptions][] = [
|
|
56
|
+
// Support setting delay like `v-mark.delay300="1"`
|
|
57
|
+
[/^delay-?(\d+)?$/, (match, options, value) => {
|
|
58
|
+
const ms = (match[1] ? Number.parseInt(match[1]) : value) || 300
|
|
59
|
+
options.delay = ms
|
|
60
|
+
return options
|
|
61
|
+
}],
|
|
62
|
+
// Support setting opacity like `v-mark.op50="1"`
|
|
63
|
+
[/^(?:op|opacity)-?(\d+)?$/, (match, options, value) => {
|
|
64
|
+
const opacity = (match[1] ? Number.parseInt(match[1]) : value) || 100
|
|
65
|
+
options.opacity = opacity / 100
|
|
66
|
+
return options
|
|
67
|
+
}],
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* This supports v-mark directive to add notations to elements, powered by `rough-notation`.
|
|
72
|
+
*/
|
|
73
|
+
export function createVMarkDirective() {
|
|
74
|
+
return {
|
|
75
|
+
install(app: App) {
|
|
76
|
+
app.directive<HTMLElement, RoughDirectiveValue>('mark', {
|
|
77
|
+
// @ts-expect-error extra prop
|
|
78
|
+
name: 'v-mark',
|
|
79
|
+
|
|
80
|
+
mounted: (el, binding) => {
|
|
81
|
+
const options = computed(() => {
|
|
82
|
+
const bindingOptions = (typeof binding.value === 'object' && !Array.isArray(binding.value))
|
|
83
|
+
? { ...binding.value }
|
|
84
|
+
: { at: binding.value }
|
|
85
|
+
|
|
86
|
+
let modifierOptions: RoughDirectiveOptions = { at: bindingOptions.at }
|
|
87
|
+
const unknownModifiers = Object.entries(binding.modifiers)
|
|
88
|
+
.filter(([k, v]) => {
|
|
89
|
+
if (vMarkModifiers[k]) {
|
|
90
|
+
modifierOptions = vMarkModifiers[k](modifierOptions, v)
|
|
91
|
+
return false
|
|
92
|
+
}
|
|
93
|
+
for (const [re, fn] of vMarkModifiersDynamic) {
|
|
94
|
+
const match = k.match(re)
|
|
95
|
+
if (match) {
|
|
96
|
+
modifierOptions = fn(match, modifierOptions, v)
|
|
97
|
+
return false
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return true
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
if (unknownModifiers.length)
|
|
104
|
+
console.warn('[Slidev] Invalid modifiers for v-mark:', unknownModifiers)
|
|
105
|
+
|
|
106
|
+
const options = {
|
|
107
|
+
...modifierOptions,
|
|
108
|
+
...bindingOptions,
|
|
109
|
+
}
|
|
110
|
+
options.type ||= 'underline'
|
|
111
|
+
|
|
112
|
+
return options
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const annotation = annotate(el, options.value as RoughAnnotationConfig)
|
|
116
|
+
|
|
117
|
+
const resolvedClick = resolveClick(el, binding, options.value.at)
|
|
118
|
+
if (!resolvedClick) {
|
|
119
|
+
console.error('[Slidev] Invalid value for v-mark:', options.value.at)
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
watchEffect(() => {
|
|
124
|
+
let shouldShow: boolean | undefined
|
|
125
|
+
|
|
126
|
+
if (options.value.class)
|
|
127
|
+
annotation.class = options.value.class
|
|
128
|
+
if (options.value.color)
|
|
129
|
+
annotation.color = options.value.color
|
|
130
|
+
|
|
131
|
+
const at = options.value.at
|
|
132
|
+
|
|
133
|
+
if (at === true) {
|
|
134
|
+
shouldShow = true
|
|
135
|
+
}
|
|
136
|
+
else if (at === false) {
|
|
137
|
+
shouldShow = false
|
|
138
|
+
}
|
|
139
|
+
else if (resolvedClick) {
|
|
140
|
+
shouldShow = resolvedClick.isActive.value
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.error('[Slidev] Invalid value for v-mark:', at)
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (shouldShow == null)
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
if (shouldShow)
|
|
151
|
+
annotation.show()
|
|
152
|
+
else
|
|
153
|
+
annotation.hide()
|
|
154
|
+
})
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/client",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.48.0-beta.
|
|
4
|
+
"version": "0.48.0-beta.7",
|
|
5
5
|
"description": "Presentation slides for developers",
|
|
6
6
|
"author": "antfu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -29,19 +29,20 @@
|
|
|
29
29
|
"@antfu/utils": "^0.7.7",
|
|
30
30
|
"@iconify-json/carbon": "^1.1.30",
|
|
31
31
|
"@iconify-json/ph": "^1.1.11",
|
|
32
|
-
"@shikijs/vitepress-twoslash": "^1.1.
|
|
32
|
+
"@shikijs/vitepress-twoslash": "^1.1.7",
|
|
33
|
+
"@slidev/rough-notation": "^0.0.4",
|
|
33
34
|
"@unhead/vue": "^1.8.10",
|
|
34
35
|
"@unocss/reset": "^0.58.5",
|
|
35
36
|
"@vueuse/core": "^10.8.0",
|
|
36
37
|
"@vueuse/math": "^10.8.0",
|
|
37
|
-
"@vueuse/motion": "^2.
|
|
38
|
+
"@vueuse/motion": "^2.1.0",
|
|
38
39
|
"codemirror": "^5.65.16",
|
|
39
40
|
"defu": "^6.1.4",
|
|
40
41
|
"drauu": "^0.4.0",
|
|
41
42
|
"file-saver": "^2.0.5",
|
|
42
43
|
"floating-vue": "^5.2.2",
|
|
43
44
|
"fuse.js": "^7.0.0",
|
|
44
|
-
"js-base64": "^3.7.
|
|
45
|
+
"js-base64": "^3.7.7",
|
|
45
46
|
"js-yaml": "^4.1.0",
|
|
46
47
|
"katex": "^0.16.9",
|
|
47
48
|
"mermaid": "^10.8.0",
|
|
@@ -52,11 +53,11 @@
|
|
|
52
53
|
"resolve": "^1.22.8",
|
|
53
54
|
"unocss": "^0.58.5",
|
|
54
55
|
"vue": "^3.4.19",
|
|
55
|
-
"vue-router": "^4.
|
|
56
|
-
"@slidev/parser": "0.48.0-beta.
|
|
57
|
-
"@slidev/types": "0.48.0-beta.
|
|
56
|
+
"vue-router": "^4.3.0",
|
|
57
|
+
"@slidev/parser": "0.48.0-beta.7",
|
|
58
|
+
"@slidev/types": "0.48.0-beta.7"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
|
-
"vite": "^5.1.
|
|
61
|
+
"vite": "^5.1.4"
|
|
61
62
|
}
|
|
62
63
|
}
|
package/styles/index.css
CHANGED