Skip to content

Commit e0db8a3

Browse files
committed
chore(playground): init demo
1 parent f2a4841 commit e0db8a3

20 files changed

+1431
-112
lines changed

.vscode/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
"cSpell.words": [
33
"antfu",
44
"bumpp",
5+
"catppuccin",
56
"changelogithub",
67
"commitlint",
78
"mdast",
89
"preid",
10+
"shiki",
911
"unplugin"
1012
],
1113
// Disable the default formatter, use eslint instead

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import antfu from '@antfu/eslint-config'
33
export default antfu({
44
formatters: true,
55
vue: true,
6-
ignores: ['./pnpm-lock.yaml', 'playground'],
6+
ignores: ['./pnpm-lock.yaml'],
77
})

playground/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
"preview": "vite preview"
1010
},
1111
"dependencies": {
12+
"@vueuse/core": "^13.0.0",
1213
"naive-ui": "^2.41.0",
1314
"vue": "^3.5.13"
1415
},
1516
"devDependencies": {
1617
"@vitejs/plugin-vue": "^5.2.1",
1718
"@vue/tsconfig": "^0.7.0",
19+
"autoprefixer": "^10.4.21",
20+
"postcss": "^8.5.3",
21+
"tailwindcss": "3",
1822
"typescript": "~5.7.2",
1923
"vite": "^6.2.0",
2024
"vue-tsc": "^2.2.4"

playground/pnpm-lock.yaml

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

playground/postcss.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}

playground/src/App.vue

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,25 @@
11
<script setup lang="ts">
2-
import Header from './Header.vue';
2+
import { useDark, useToggle } from '@vueuse/core'
3+
import { darkTheme, NConfigProvider } from 'naive-ui'
4+
import { computed, provide } from 'vue'
35
import Container from './Container.vue'
4-
import { NConfigProvider } from 'naive-ui'
6+
import Header from './Header.vue'
7+
8+
const isDark = useDark()
9+
const toggleTheme = useToggle(isDark)
10+
provide('context', {
11+
isDark,
12+
toggleTheme,
13+
})
14+
15+
const theme = computed(() => isDark.value ? darkTheme : null)
516
</script>
617

718
<template>
8-
<NConfigProvider>
9-
<div class="playground">
19+
<NConfigProvider :theme="theme">
20+
<div class="w-screen h-screen p-4 flex flex-col gap-4 bg-white dark:bg-black text-neutral-800 dark:text-neutral-200">
1021
<Header />
11-
<Container />
22+
<Container class="h-[calc(100vh-32px-52px-16px)]" />
1223
</div>
1324
</NConfigProvider>
1425
</template>
15-
16-
<style lang="scss">
17-
body {
18-
margin: 0;
19-
}
20-
21-
* {
22-
box-sizing: border-box;
23-
}
24-
</style>
25-
26-
<style lang="scss">
27-
.playground {
28-
width: 100vw;
29-
height: 100vh;
30-
padding: 16px;
31-
32-
display: flex;
33-
flex-direction: column;
34-
}
35-
</style>

playground/src/Container.vue

Lines changed: 129 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,82 @@
1-
<template>
2-
<div class="container">
3-
<div class="actions">
4-
<NSlider v-model:value="ms"
5-
:min="10" :max="300" :step="10" :disabled="loading"
6-
:format-tooltip="number => `Stream speed: ${number} ms per letter`" />
7-
<NButton :loading="loading" :disabled="!mdStr?.trim().length" @click="rerun">Rerun</NButton>
8-
</div>
9-
<div class="render">
10-
<NInput v-model:value="mdStr" type="textarea" :disabled="loading" />
11-
<VueMarkdown :md="mdStr" />
12-
</div>
13-
</div>
14-
</template>
15-
161
<script setup lang="ts">
17-
import { computed, ref } from 'vue';
18-
import { VueMarkdown } from '../../src';
19-
import { NButton, NSlider, NInput } from 'naive-ui'
2+
import { watchThrottled } from '@vueuse/core'
3+
import { NButton, NIcon, NInput, NScrollbar, NSelect, NSlider } from 'naive-ui'
4+
import { computed, inject, nextTick, ref, type Ref } from 'vue'
5+
import { VueMarkdown } from '../../src'
6+
import IconGithub from './icons/github.vue'
7+
import IconMoon from './icons/moon.vue'
8+
import IconSun from './icons/sun.vue'
9+
import codeLanguages from './templates/code-languages.md?raw'
10+
import fullMarkdown from './templates/full-markdown.md?raw'
2011
2112
defineOptions({
22-
name: 'PlaygroundContainer'
13+
name: 'PlaygroundContainer',
2314
})
2415
16+
const leftRef = ref()
17+
const rightRef = ref()
18+
2519
const mdStr = ref('')
20+
watchThrottled(mdStr, () => {
21+
nextTick(() => {
22+
requestAnimationFrame(() => {
23+
leftRef.value?.scrollBy({
24+
top: Number.MAX_SAFE_INTEGER,
25+
behavior: 'smooth',
26+
})
27+
rightRef.value?.scrollBy({
28+
top: Number.MAX_SAFE_INTEGER,
29+
behavior: 'smooth',
30+
})
31+
})
32+
})
33+
})
34+
35+
const templates = [
36+
{
37+
label: 'Full markdown',
38+
value: 'full-markdown',
39+
},
40+
{
41+
label: 'Code languages',
42+
value: 'code-languages',
43+
},
44+
]
45+
function onSelectTemplate(value: string) {
46+
switch (value) {
47+
case 'full-markdown': {
48+
mdStr.value = fullMarkdown
49+
rerun()
50+
break
51+
}
52+
case 'code-languages': {
53+
mdStr.value = codeLanguages
54+
rerun()
55+
break
56+
}
57+
default: {
58+
mdStr.value = ''
59+
break
60+
}
61+
}
62+
}
2663
27-
const timeId = ref<NodeJS.Timeout>()
28-
const ms = ref(100)
29-
const rerun = () => {
64+
const timeId = ref<ReturnType<typeof setInterval>>()
65+
const ms = ref(10)
66+
function rerun() {
3067
if (timeId.value) {
3168
clearInterval(timeId.value)
3269
3370
timeId.value = undefined
71+
72+
return
3473
}
3574
3675
const str = mdStr.value
3776
let index = 0
3877
3978
mdStr.value = ''
4079
timeId.value = setInterval(() => {
41-
console.log('setInterval')
4280
if (index >= str.length) {
4381
clearInterval(timeId.value)
4482
timeId.value = undefined
@@ -51,32 +89,73 @@ const rerun = () => {
5189
}
5290
5391
const loading = computed(() => !!timeId.value)
54-
</script>
55-
56-
<style lang="scss" scoped>
57-
.container {
58-
flex: 1;
59-
padding: 16px;
60-
display: flex;
61-
flex-direction: column;
62-
gap: 16px;
63-
}
6492
65-
.actions {
66-
display: flex;
67-
gap: 16px;
68-
69-
.n-slider {
70-
max-width: 200px;
71-
display: flex;
72-
align-items: center;
73-
}
74-
}
93+
const { isDark, toggleTheme } = inject<{
94+
isDark: Ref<boolean>
95+
toggleTheme: () => void
96+
}>('context')!
97+
</script>
7598

76-
.render {
77-
flex: 1;
78-
display: grid;
79-
grid-template-columns: repeat(2, 1fr);
80-
gap: 24px;
81-
}
82-
</style>
99+
<template>
100+
<div class=" flex-1 flex flex-col gap-4">
101+
<div class="flex justify-between items-center">
102+
<div class="flex gap-4">
103+
<NButton type="primary" :quaternary="loading" :disabled="!mdStr.trim()" @click="rerun">
104+
{{ loading ? 'Stop' : 'Rerun' }}
105+
</NButton>
106+
<NSelect class="w-52" :disabled="loading" :options="templates" :consistent-menu-width="false" placeholder="Select markdown template" clearable @update:value="onSelectTemplate" />
107+
<div>
108+
<div class="flex items-center justify-between gap-2">
109+
<label class="text-sm text-neutral-600 dark:text-neutral-400">Stream speed</label>
110+
<div class="text-xs text-neutral-500">
111+
{{ Math.round(1000 / ms) }} characters / min
112+
</div>
113+
</div>
114+
<NSlider
115+
v-model:value="ms"
116+
class="w-56"
117+
:min="1"
118+
:max="50"
119+
:step="1"
120+
:disabled="loading"
121+
:tooltip="false"
122+
/>
123+
</div>
124+
</div>
125+
<div class="flex items-center">
126+
<NButton quaternary circle @click="toggleTheme()">
127+
<template #icon>
128+
<NIcon>
129+
<IconMoon v-if="isDark" />
130+
<IconSun v-else />
131+
</NIcon>
132+
</template>
133+
</NButton>
134+
<a href="https://github.com/litingyes/vue-markdown.git" target="_blank">
135+
<NButton quaternary circle>
136+
<template #icon>
137+
<NIcon>
138+
<IconGithub />
139+
</NIcon>
140+
</template>
141+
</NButton>
142+
</a>
143+
</div>
144+
</div>
145+
<div class="flex-1 grid grid-cols-2 gap-6 h-[calc(100%-38px-16px)]">
146+
<NScrollbar ref="leftRef" class="h-full pr-3">
147+
<NInput
148+
v-model:value="mdStr"
149+
type="textarea"
150+
placeholder="MarkDown content to render"
151+
:disabled="loading"
152+
:autosize="{ minRows: 20 }"
153+
autofocus
154+
/>
155+
</NScrollbar>
156+
<NScrollbar ref="rightRef" class="h-full pr-3">
157+
<VueMarkdown :md="mdStr" />
158+
</NScrollbar>
159+
</div>
160+
</div>
161+
</template>

playground/src/Header.vue

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,18 @@
1-
<template>
2-
<header>
3-
<h1>Vue Markdown</h1>
4-
<p>{{ pkgInfo.description }}</p>
5-
</header>
6-
</template>
7-
81
<script setup lang="ts">
92
import pkgInfo from '../../package.json'
103
114
defineOptions({
12-
name:'PlaygroundHeader'
5+
name: 'PlaygroundHeader',
136
})
147
</script>
158

16-
<style scoped>
17-
header {
18-
display: flex;
19-
flex-direction: column;
20-
align-items: center;
21-
}
22-
23-
h1 {
24-
margin: 0;
25-
font-size: 24px;
26-
line-height: 32px;
27-
font-weight: 600;
28-
color: #0a0a0a;
29-
}
30-
31-
p {
32-
margin: 0;
33-
font-size: 14;
34-
line-height: 20px;
35-
color: #171717;
36-
}
37-
</style>
9+
<template>
10+
<header class="flex flex-col items-center">
11+
<h1 class="text-2xl font-semibold bg-clip-text text-transparent bg-gradient-to-r from-pink-500 to-violet-500">
12+
Vue Markdown
13+
</h1>
14+
<p class="text-sm text-neutral-600 dark:text-neutral-400">
15+
{{ pkgInfo.description }}
16+
</p>
17+
</header>
18+
</template>

playground/src/icons/github.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
3+
<path fill="currentColor" d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2" />
4+
</svg>
5+
</template>

playground/src/icons/moon.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
3+
<path fill="currentColor" fill-rule="evenodd" d="M12.226 2.003a9.97 9.97 0 0 0-7.297 2.926c-3.905 3.905-3.905 10.237 0 14.142s10.237 3.905 14.142 0a9.97 9.97 0 0 0 2.926-7.297a10 10 0 0 0-.337-2.368a15 15 0 0 1-1.744 1.436c-1.351.949-2.733 1.563-3.986 1.842c-1.906.423-3.214.032-3.93-.684s-1.107-2.024-.684-3.93c.279-1.253.893-2.635 1.842-3.986c.414-.592.893-1.177 1.436-1.744a10 10 0 0 0-2.368-.337m5.43 15.654a7.96 7.96 0 0 0 2.251-4.438c-3.546 2.045-7.269 2.247-9.321.195s-1.85-5.775.195-9.321a8 8 0 1 0 6.876 13.564" clip-rule="evenodd" />
4+
</svg>
5+
</template>

0 commit comments

Comments
 (0)