Skip to content

Commit

Permalink
feat: preview
Browse files Browse the repository at this point in the history
  • Loading branch information
jaskang committed Jan 6, 2023
1 parent f69ec35 commit e1f57cf
Show file tree
Hide file tree
Showing 15 changed files with 415 additions and 89 deletions.
1 change: 0 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
registry=https://registry.npmmirror.com
6 changes: 3 additions & 3 deletions docs/.vitepress/cache/deps/_metadata.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"hash": "1a3561bb",
"browserHash": "5b83d99f",
"hash": "43881e07",
"browserHash": "c1e4d7e0",
"optimized": {
"vue": {
"src": "../../../../node_modules/.pnpm/vue@3.2.45/node_modules/vue/dist/vue.runtime.esm-bundler.js",
"file": "vue.js",
"fileHash": "c7bb3abf",
"fileHash": "37e21a42",
"needsInterop": false
}
},
Expand Down
1 change: 0 additions & 1 deletion docs/.vitepress/components/MdvueDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<template>
<div class="mdvue-demo">
<div class="mdvue-demo__preview">
aaaa
<slot name="preview" />
</div>
<div class="mdvue-demo__code">
Expand Down
6 changes: 5 additions & 1 deletion docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ export default defineConfig({
theme: 'github-dark',
},
vite: {
plugins: [MditVuePreview(), Inspect(), vueJsx()],
plugins: [
MditVuePreview(),
// Inspect(),
vueJsx(),
],
},
themeConfig: {
nav: [
Expand Down
123 changes: 67 additions & 56 deletions docs/.vitepress/md/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { Plugin, PluginOption, Update } from 'vite'
import fs from 'node:fs'
import { remark } from 'remark'
import { visit, type Node } from 'unist-util-visit'
import type { Code, Parent, Root } from 'mdast'
import path from 'node:path'
import { VFile } from 'vfile'
import { fromMarkdown } from 'mdast-util-from-markdown'
import { toMarkdown } from 'mdast-util-to-markdown'
import { frontmatterFromMarkdown, frontmatterToMarkdown } from 'mdast-util-frontmatter'
import { gfmFromMarkdown, gfmToMarkdown } from 'mdast-util-gfm'
import { mathFromMarkdown, mathToMarkdown } from 'mdast-util-math'
import { directiveFromMarkdown, directiveToMarkdown } from 'mdast-util-directive'
import type { Code, Parent } from 'mdast'
import { createHash } from 'node:crypto'

const CODE_VUE_REGEXP = /DemoBlock[a-z0-9]{8}I\d{1,4}\.vue$/
Expand All @@ -15,53 +18,68 @@ function md5(str: string): string {
return createHash('md5').update(str).digest('hex')
}

export default function remarkDemo(options = {}) {
return (tree: Root, file: any) => {
// console.log(JSON.stringify(tree, null, 2))
const id = file.path
// const scriptNode = tree.children.find(n => n.type === 'html' && n.value.startsWith('<script'))
const blocks: string[] = []
FileBlockMap.set(id, blocks)
export default function remarkDemo(id: string, code: string) {
const tree = fromMarkdown(code, {
mdastExtensions: [
frontmatterFromMarkdown(['yaml', 'toml']),
gfmFromMarkdown(),
mathFromMarkdown(),
directiveFromMarkdown,
],
})

visit(tree as Node, 'code', (node: Code, index: number, parent: Parent) => {
const lang = (node.lang || '').split(':')[0]
const meta = (node.meta || '').split(' ')
// const scriptNode = tree.children.find(n => n.type === 'html' && n.value.startsWith('<script'))
const blocks: string[] = []
FileBlockMap.set(id, blocks)

const isDemo = meta.indexOf('demo') !== -1 && lang === 'vue'
if (isDemo) {
// console.log(node)
// node.value
const hash = md5(file.path).substr(0, 8)
const name = `DemoBlock${hash}I${index}`
blocks.push(name)
DemoBlockMap.set(`${name}.vue`, node.value)
visit(tree as Node, 'code', (node: Code, index: number, parent: Parent) => {
const lang = (node.lang || '').split(':')[0]
const meta = (node.meta || '').split(' ')

parent.children.splice(
index,
1,
{
type: 'html',
value: `<MdvueDemo>\n<template #preview><${name}/></template>`,
},
node,
{
type: 'html',
value: '</MdvueDemo>',
}
)
return index + 3
}
})
if (blocks.length > 0) {
tree.children.push({
type: 'html',
value: `<script setup>\n${blocks
.map(b => `import ${b} from "${b}.vue";`)
.join('\n')}\n</script>`,
})
FileBlockMap.set(id, blocks)
const isDemo = meta.indexOf('demo') !== -1 && lang === 'vue'
if (isDemo) {
const hash = md5(id).substr(0, 8)
const name = `DemoBlock${hash}I${index}`
blocks.push(name)
DemoBlockMap.set(`${name}.vue`, node.value)

parent.children.splice(
index,
1,
{
type: 'html',
value: `<MdvueDemo>\n<template #preview><${name}/></template>`,
},
node,
{
type: 'html',
value: '</MdvueDemo>',
}
)
return index + 3
}
})
if (blocks.length > 0) {
tree.children.push({
type: 'html',
value: `<script setup>\n${blocks
.map(b => `import ${b} from "${b}.vue";`)
.join('\n')}\n</script>`,
})
FileBlockMap.set(id, blocks)

const out = toMarkdown(tree, {
extensions: [
frontmatterToMarkdown(['yaml', 'toml']),
gfmToMarkdown(),
mathToMarkdown(),
directiveToMarkdown,
],
})

return out
}
return code
}

let vuePlugin: any = null
Expand All @@ -75,8 +93,6 @@ export function MditVuePreview(): Plugin {
const isVitepress = config.plugins.find(p => p.name === 'vitepress')
const isVuepress = config.plugins.find(p => p.name === 'vuepress')
vuePlugin = config.plugins.find(p => p.name === 'vite:vue')
console.log('vuePlugin', vuePlugin)

envType = isVitepress ? 'vitepress' : isVuepress ? 'vuepress' : 'vite'
},
resolveId(id) {
Expand All @@ -90,27 +106,22 @@ export function MditVuePreview(): Plugin {
return code
}
if (id.endsWith('.md')) {
const file = await remark()
.use(remarkDemo)
.process(new VFile({ value: fs.readFileSync(id, 'utf8'), path: id }))
return file.toString()
const file = remarkDemo(id, fs.readFileSync(id, 'utf8'))
return file
}
},
async handleHotUpdate(ctx) {
const { file, server, timestamp } = ctx
const { moduleGraph } = server
if (file.endsWith('.md')) {
await remark()
.use(remarkDemo)
.process(new VFile({ value: fs.readFileSync(file, 'utf8'), path: file }))
remarkDemo(file, fs.readFileSync(file, 'utf8'))
const blocks = FileBlockMap.get(file) || []
if (blocks && blocks.length > 0) {
const updates: any[] = []
for (const name of blocks) {
const id = `${name}.vue`
const mod = moduleGraph.getModuleById(id)
if (mod) {
console.log('handleHotUpdate', id, DemoBlockMap.get(`${name}.vue`))
const ret = await vuePlugin.handleHotUpdate({
file: id,
timestamp: timestamp,
Expand Down
116 changes: 100 additions & 16 deletions docs/components/button.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,115 @@
# Button

## 颜色

```vue demo
<template>
<div class="space-x-1">
<EButton>你测试好</EButton>
<EButton color="primary">primary</EButton>
<EButton color="success">success</EButton>
<EButton color="warning">warning</EButton>
<EButton color="error">error</EButton>
<EButton disabled>默认</EButton>
<EButton color="primary" disabled>primary</EButton>
</div>
</template>
```

## 大小

```vue demo
<template>
<div class="space-x-1">
<EButton size="xs">button xs</EButton>
<EButton size="sm">button sm</EButton>
<EButton>button</EButton>
<EButton size="lg">button lg</EButton>
<EButton size="xl">button xl</EButton>
</div>
<br />
<div class="space-x-1">
<EButton color="primary" size="xs">primary xs</EButton>
<EButton color="primary" size="sm">primary sm</EButton>
<EButton color="primary">primary</EButton>
<EButton color="primary" size="lg">primary lg</EButton>
<EButton color="primary" size="xl">primary xl</EButton>
</div>
</template>
```

## 圆角

```vue demo
<template>
<div class="space-x-1">
<EButton type="round">默认</EButton>
<EButton color="primary" type="round">primary</EButton>
<EButton color="success" type="round">success</EButton>
<EButton color="warning" type="round">warning</EButton>
<EButton color="error" type="round">error</EButton>
</div>
</template>
```

## 圆形

```vue demo
<template>
<div class="space-x-1">
<EButton type="circle">D</EButton>
<EButton color="primary" type="circle">P</EButton>
<EButton color="success" type="circle">S</EButton>
<EButton color="warning" type="circle">W</EButton>
<EButton color="error" type="circle">E</EButton>
</div>
</template>
```

## 链接

```vue demo
<template>
<button>Get Started</button>
<div class="space-x-1">
<EButton type="link">default</EButton>
<EButton color="primary" type="link">primary</EButton>
<EButton color="success" type="link">success</EButton>
<EButton color="warning" type="link">warning</EButton>
<EButton color="error" type="link">error</EButton>
</div>
</template>
```

```vue demo [config.ts]
## 禁用

```vue demo
<template>
<EButton>你好</EButton>
<EButton color="primary">primary</EButton>
<EButton color="success">success</EButton>
<EButton color="warning">warning</EButton>
<EButton color="error">error</EButton>
<EButton disabled>默认</EButton>
<EButton color="primary" disabled>primary</EButton>
<div class="space-x-1">
<EButton disabled>禁用</EButton>
<EButton color="primary" disabled>primary 禁用</EButton>
<EButton type="round" disabled>默认</EButton>
<EButton type="circle" disabled>D</EButton>
<EButton type="link" disabled>primary</EButton>
</div>
</template>
```

## 按钮组

```vue demo
<template>
<EButton>aaaaaasssssss</EButton>
<EButton color="primary">primary</EButton>
<EButton color="success">success</EButton>
<EButton color="warning">warning</EButton>
<EButton color="error">error</EButton>
<EButton disabled>默认</EButton>
<EButton color="primary" disabled>primary</EButton>
<EButtonGroup>
<EButton>primary</EButton>
<EButton>primary</EButton>
<EButton>primary</EButton>
<EButton>primary</EButton>
</EButtonGroup>
<br /><br />
<EButtonGroup>
<EButton color="primary">primary</EButton>
<EButton color="primary">primary</EButton>
<EButton color="primary">primary</EButton>
<EButton color="primary">primary</EButton>
</EButtonGroup>
</template>
```
10 changes: 10 additions & 0 deletions docs/components/checkbox.md
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
# checkbox

```vue demo
<template>
<div class="space-x-1">
<ECheckbox>ECheckbox</ECheckbox>
<ECheckbox disabled>ECheckbox disabled</ECheckbox>
<ECheckbox checked disabled>ECheckbox disabled</ECheckbox>
</div>
</template>
```
12 changes: 12 additions & 0 deletions docs/components/radio.md
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
# radio

```vue demo
<template>
<div class="space-x-1">
<ERadio name="radio">ERadio</ERadio>
<ERadio name="radio">ERadio</ERadio>
<ERadio name="radio">ERadio</ERadio>
<ERadio name="radio" disabled>ERadio disabled</ERadio>
<ERadio name="radio" checked disabled>ERadio disabled</ERadio>
</div>
</template>
```
16 changes: 12 additions & 4 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,23 @@ layout: home

hero:
name: VitePress
text: Vite & Vue powered static site generator.
text: Vite & Vue Powered Static Site Generator
tagline: Simple, powerful, and performant. Meet the modern SSG framework you've always wanted.
actions:
- theme: brand
text: Get Started
link: /example
link: /guide/getting-started
- theme: alt
text: View on GitHub
link: https://github.com/vuejs/vitepress
---

vue
features:
- title: "Vite: The DX that can't be beat"
details: Feel the speed of Vite. Instant server start and lightning fast HMR that stays fast regardless of the app size.
- title: Designed to be simplicity first
details: With Markdown-centered content, it's built to help you focus on writing and deployed with minimum configuration.
- title: Power of Vue meets Markdown
details: Enhance your content with all the features of Vue in Markdown, while being able to customize your site with Vue.
- title: Fully static yet still dynamic
details: Go wild with true SSG + SPA architecture. Static on page load, but engage users with 100% interactivity from there.
---
Loading

0 comments on commit e1f57cf

Please sign in to comment.