Skip to content

Commit 87a3a48

Browse files
committed
feat: 添加 HeaderBar 组件并优化 Playground 组件的布局和样式
1 parent dcb6d37 commit 87a3a48

File tree

5 files changed

+147
-7
lines changed

5 files changed

+147
-7
lines changed

index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>Slidev-Parser Playground</title>
7+
<title>SlidevParser Playground</title>
88
<style>
99
body {
1010
margin: 0;
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<script lang='ts' setup>
2+
import { useClipboard } from '@vueuse/core'
3+
import { toggleDark } from '../composables/dark'
4+
import { inputMDC } from '../composables/url'
5+
6+
// 接收 paneSize 的 props,并定义切换事件
7+
defineProps({
8+
paneSize: {
9+
type: Number,
10+
required: true,
11+
},
12+
})
13+
14+
const emit = defineEmits(['toggleSize'])
15+
16+
const { copy, copied } = useClipboard()
17+
18+
function handleShare() {
19+
const url = new URL(window.location.href)
20+
copy(url.toString())
21+
}
22+
23+
function handleReset() {
24+
// eslint-disable-next-line no-alert
25+
if (confirm('Reset all settings? It can NOT be undone.')) {
26+
inputMDC.value = ''
27+
}
28+
}
29+
</script>
30+
31+
<template>
32+
<div
33+
class="p2 z-10 bg-gray/10"
34+
flex="~ items-center wrap gap-3" w-full
35+
>
36+
<div flex="~ items-center" cursor-pointer @click="emit('toggleSize')">
37+
<div flex items-center gap-2>
38+
<div :class="paneSize === 0 ? 'i-logos-slidev rotate-90' : 'i-logos-slidev'" />
39+
<div text-lg font-bold>
40+
SlidevParser
41+
</div>
42+
</div>
43+
</div>
44+
<div class="text-sm md:text-base flex flex-auto items-center justify-end flex-nowrap gap-1">
45+
<button
46+
:class="copied ? 'i-ri-checkbox-circle-line text-green' : 'i-ri-share-line'"
47+
icon-btn
48+
title="Share Link"
49+
@click="handleShare"
50+
/>
51+
<button
52+
i-ri-eraser-line
53+
icon-btn
54+
title="Reset To Default"
55+
@click="handleReset"
56+
/>
57+
<a
58+
i-ri-github-line icon-btn
59+
href="https://github.com/unocss/unocss"
60+
target="_blank"
61+
title="GitHub"
62+
/>
63+
<button
64+
i-ri-sun-line
65+
dark:i-ri-moon-line
66+
icon-btn
67+
title="Toggle Color Mode"
68+
@click="toggleDark"
69+
/>
70+
</div>
71+
</div>
72+
</template>

playground/src/components/Playground.vue

+25-5
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,47 @@ import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'
33
import { Pane, Splitpanes } from 'splitpanes'
44
import { ref } from 'vue'
55
import Editor from './Edit.vue'
6+
import HeaderBar from './HeaderBar.vue'
67
import Preview from './Preview.vue'
78
89
const bp = useBreakpoints(breakpointsTailwind)
9-
1010
const isMobile = bp.smaller('sm')
1111
const isResizing = ref(false)
12+
13+
const paneSize = ref(50)
14+
const savedSize = ref(50)
15+
16+
function toggleSize() {
17+
if (paneSize.value > 0) {
18+
savedSize.value = paneSize.value
19+
paneSize.value = 0
20+
}
21+
else {
22+
paneSize.value = savedSize.value || 50
23+
}
24+
}
25+
function onResize($event) {
26+
isResizing.value = true
27+
paneSize.value = $event[0].size
28+
}
1229
</script>
1330

1431
<template>
1532
<Splitpanes
1633
h-screen
1734
w-screen
1835
:horizontal="isMobile"
36+
@resize="onResize"
1937
@resized="isResizing = false"
20-
@resize="isResizing = true"
2138
>
22-
<Pane>
39+
<Pane :size="paneSize">
2340
<Editor border="r t main solid" />
2441
</Pane>
25-
<Pane>
26-
<Preview :resizing="isResizing" />
42+
<Pane flex="~ col" h-full :size="100 - paneSize">
43+
<HeaderBar :pane-size="paneSize" @toggle-size="toggleSize" />
44+
<div flex-1 of-hidden>
45+
<Preview />
46+
</div>
2747
</Pane>
2848
</Splitpanes>
2949
</template>

playground/src/composables/dark.ts

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useDark } from '@vueuse/core'
2+
import { nextTick } from 'vue'
3+
4+
export const isDark = useDark()
5+
6+
// @ts-expect-error: Transition API
7+
const isAppearanceTransition = document.startViewTransition
8+
&& !window.matchMedia('(prefers-reduced-motion: reduce)').matches
9+
/**
10+
* Credit to [@hooray](https://github.com/hooray)
11+
* @see https://github.com/vuejs/vitepress/pull/2347
12+
*/
13+
export function toggleDark(event?: MouseEvent) {
14+
if (!isAppearanceTransition || !event) {
15+
isDark.value = !isDark.value
16+
return
17+
}
18+
const x = event.clientX
19+
const y = event.clientY
20+
const endRadius = Math.hypot(
21+
Math.max(x, innerWidth - x),
22+
Math.max(y, innerHeight - y),
23+
)
24+
const transition = document.startViewTransition(async () => {
25+
isDark.value = !isDark.value
26+
await nextTick()
27+
})
28+
transition.ready.then(() => {
29+
const clipPath = [
30+
`circle(0px at ${x}px ${y}px)`,
31+
`circle(${endRadius}px at ${x}px ${y}px)`,
32+
]
33+
document.documentElement.animate(
34+
{
35+
clipPath: isDark.value
36+
? [...clipPath].reverse()
37+
: clipPath,
38+
},
39+
{
40+
duration: 400,
41+
easing: 'ease-in',
42+
pseudoElement: isDark.value
43+
? '::view-transition-old(root)'
44+
: '::view-transition-new(root)',
45+
},
46+
)
47+
})
48+
}

playground/src/composables/url.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const inputMDC = ref(decode(params.get('mdc') || '') || defaultMDC)
1919
export const options: Ref<RendererOptions> = ref(JSON.parse(decode(params.get('options') || '') || defaultOptions))
2020

2121
export function updateUrl() {
22-
const url = new URL('/play/', window.location.origin)
22+
const url = new URL('/', window.location.origin)
2323
params.set('mdc', encode(inputMDC.value))
2424
// params.set('options', encode(JSON.stringify(options.value)))
2525
localStorage.setItem(STORAGE_KEY, url.search)

0 commit comments

Comments
 (0)