-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
878 additions
and
258 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import DemoBlock from "./src/index.vue"; | ||
|
||
export default DemoBlock; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import type { ExtractPropTypes } from "vue"; | ||
|
||
export const demoProps = { | ||
github: { | ||
type: String, | ||
default: "https://github.com/chizukicn/hoci" | ||
}, | ||
codeSandBox: { | ||
type: String, | ||
default: "https://codesandbox.io/" | ||
}, | ||
highlightedCode: { | ||
type: String, | ||
default: "" | ||
}, | ||
code: { | ||
type: String, | ||
default: "" | ||
}, | ||
title: { | ||
type: String, | ||
default: "" | ||
}, | ||
desc: { | ||
type: String, | ||
default: "" | ||
}, | ||
lang: { | ||
type: String, | ||
default: "vue" | ||
}, | ||
expand: { | ||
type: Boolean, | ||
default: false | ||
}, | ||
src: { | ||
type: String, | ||
default: "" | ||
} | ||
} as const; | ||
|
||
export type ODemoProps = ExtractPropTypes<typeof demoProps>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<script lang='ts' setup name="demo-block"> | ||
import { computed } from "vue"; | ||
import { isClient, useClipboard, useToggle } from "@vueuse/core"; | ||
import { usePlayground } from "./playground"; | ||
import { demoProps } from "./index"; | ||
const props = defineProps(demoProps); | ||
const decodedHighlightedCode = computed(() => | ||
decodeURIComponent(props.highlightedCode) | ||
); | ||
const { copy, copied } = useClipboard({ source: decodeURIComponent(props.code) }); | ||
const [value, toggle] = useToggle(); | ||
const editOnPlayground = () => { | ||
if (props.code) { | ||
const { link } = usePlayground(props.code); | ||
if (!isClient) { | ||
return; | ||
}; | ||
window.open(link); | ||
} | ||
}; | ||
</script> | ||
|
||
<template> | ||
<ClientOnly> | ||
<div v-bind="$attrs" class="mt-6"> | ||
<div class="p-8 c-#282f38 b-1 border-light-700 b-solid rounded-sm dark:bg-dark-700 dark:border-#4C4D4F flex [&:o-button-base]:!c-context vp-raw bg"> | ||
<slot /> | ||
</div> | ||
<div class="relative"> | ||
<div class="flex justify-end pt-3 gap-2"> | ||
<a class="relative outline-none flex justify-center items-center w-7 h-7 p-0 rounded-full border border-light-900 dark:border-dark-900 bg-white dark:bg-#38383A cursor-pointer hover:bg-#E5E6EB dark:hover:bg-dark:300" group @click="editOnPlayground"> | ||
<div class="o-demo_action_icon i-carbon:chemistry" /> | ||
<div class="o-demo_tooltip" group-hover:opacity-100> | ||
Edit in Playground | ||
</div> | ||
</a> | ||
<a class="relative outline-none flex justify-center items-center w-7 h-7 p-0 rounded-full border border-light-900 dark:border-dark-900 bg-white dark:bg-#38383A cursor-pointer hover:bg-#E5E6EB dark:hover:bg-dark:300" group :href="github" target="_blank"> | ||
<div class="o-demo_action_icon i-carbon-logo-github" /> | ||
<div class="o-demo_tooltip" group-hover:opacity-100> | ||
Edit on GitHub | ||
</div> | ||
</a> | ||
<a class="relative outline-none flex justify-center items-center w-7 h-7 p-0 rounded-full border border-light-900 dark:border-dark-900 bg-white dark:bg-#38383A cursor-pointer hover:bg-#E5E6EB dark:hover:bg-dark:300" group @click="copy()"> | ||
<div class="o-demo_action_icon i-carbon:copy" /> | ||
<div class="o-demo_tooltip" group-hover:opacity-100> | ||
{{ copied ? 'Copied' : 'Copy code' }} | ||
</div> | ||
</a> | ||
<a class="relative outline-none flex justify-center items-center w-7 h-7 p-0 rounded-full border border-light-900 dark:border-dark-900 bg-white dark:bg-#38383A cursor-pointer hover:bg-#E5E6EB dark:hover:bg-dark:300" group @click="toggle()"> | ||
<div class="o-demo_action_icon i-carbon:fit-to-width" /> | ||
<div class="o-demo_tooltip" group-hover:opacity-100> | ||
{{ value ? 'Hidden code' : 'Show code' }} | ||
</div> | ||
</a> | ||
</div> | ||
<div v-show="value" :class="`language-${lang} extra-class`" v-html="decodedHighlightedCode" /> | ||
</div> | ||
</div> | ||
</ClientOnly> | ||
</template> | ||
|
||
<style scoped lang="scss"> | ||
@keyframes fade-in { | ||
from { | ||
opacity: 0; | ||
} | ||
to { | ||
opacity: 1; | ||
} | ||
} | ||
.showcode-enter-active { | ||
animation: fade-in 200ms; | ||
} | ||
.showcode-leave-active { | ||
animation: fade-in reverse 200ms; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const playgroundUrl = (import.meta as any).env.DEV ? "http://localhost:5173/play/" : "https://onu.zyob.top/play/"; | ||
|
||
function utoa(data: string) { | ||
return btoa(unescape(encodeURIComponent(data))); | ||
} | ||
|
||
const MAIN_FILE_NAME = "App.vue"; | ||
|
||
export const usePlayground = (source: string) => { | ||
const code = decodeURIComponent(source); | ||
const originCode = { | ||
[MAIN_FILE_NAME]: code | ||
}; | ||
|
||
const encoded = utoa(JSON.stringify(originCode)); | ||
const link = `${playgroundUrl}#${encoded}`; | ||
return { | ||
encoded, | ||
link | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const FenceDemoTag = "vue:demo"; | ||
export const DemoTag = "demo"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import type { MarkdownRenderer } from "vitepress"; | ||
import { FenceDemoTag } from "./constants"; | ||
import { genDemoByCode } from "./utils"; | ||
|
||
export function fencePlugin(md: MarkdownRenderer) { | ||
const defaultRender = md.renderer.rules.fence; | ||
|
||
md.renderer.rules.fence = (tokens, idx, options, env, self) => { | ||
const token = tokens[idx]; | ||
if (token.info.trim() !== FenceDemoTag) { | ||
return defaultRender!(tokens, idx, options, env, self); | ||
}; | ||
|
||
const content = token.content; | ||
const path = env.path; | ||
|
||
const demoScripts = genDemoByCode(md, env, path, content); | ||
return demoScripts; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { demoBlockPlugin } from "./plugin-demo-block"; | ||
import { fencePlugin } from "./fencePlugin"; | ||
|
||
export function applyPlugins(md: markdownit) { | ||
md.use(fencePlugin); | ||
md.use(demoBlockPlugin); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { dirname, resolve } from "node:path"; | ||
import fsExtra from "fs-extra"; | ||
import { baseParse } from "@vue/compiler-core"; | ||
import type { AttributeNode, ElementNode } from "@vue/compiler-core"; | ||
import type { MarkdownRenderer } from "vitepress"; | ||
import { DemoTag } from "./constants"; | ||
import { getDemoComponent } from "./utils"; | ||
|
||
function getPropsMap(attrs: AttributeNode[]) { | ||
const map: Record<string, string | undefined> = {}; | ||
for (const { name, value } of attrs) { | ||
map[name] = value?.content; | ||
}; | ||
|
||
return map; | ||
} | ||
|
||
export function parseProps(content: string) { | ||
const ast = baseParse(content); | ||
const demoElement = ast.children[0] as ElementNode; | ||
|
||
const props = getPropsMap(demoElement.props as AttributeNode[]); | ||
|
||
return props; | ||
} | ||
|
||
export function demoBlockPlugin(md: MarkdownRenderer) { | ||
const addRenderRule = (type: string) => { | ||
const defaultRender = md.renderer.rules[type]; | ||
|
||
md.renderer.rules[type] = (tokens, idx, options, env, self) => { | ||
const token = tokens[idx]; | ||
const content = token.content.trim(); | ||
|
||
if (!content.startsWith(`<${DemoTag} `)) { | ||
return defaultRender!(tokens, idx, options, env, self); | ||
}; | ||
|
||
const { path } = env; | ||
|
||
const props = parseProps(content); | ||
|
||
if (!props.src) { | ||
return defaultRender!(tokens, idx, options, env, self); | ||
}; | ||
|
||
const frontmatter = env.frontmatter; | ||
|
||
const mdDir = dirname(frontmatter.realPath ?? path); | ||
const srcPath = resolve(mdDir, props.src); | ||
const code = fsExtra.readFileSync(srcPath, "utf-8"); | ||
|
||
const demoScripts = getDemoComponent(md, env, { | ||
title: props.title, | ||
desc: props.desc, | ||
path: srcPath, | ||
code, | ||
...props | ||
}); | ||
|
||
return demoScripts; | ||
}; | ||
}; | ||
|
||
addRenderRule("html_block"); | ||
addRenderRule("html_inline"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export interface DemoInfos { | ||
title?: string | ||
desc?: string | ||
path: string | ||
code: string | ||
lang?: string | ||
} |
Oops, something went wrong.