feat: generate code dynamically

This commit is contained in:
zernonia 2024-03-13 23:42:14 +08:00
parent 4d08adc81e
commit 3832ea3043
6 changed files with 44 additions and 18 deletions

View File

@ -3,17 +3,12 @@ import { defineConfig } from 'vitepress'
import Icons from 'unplugin-icons/vite'
import tailwind from 'tailwindcss'
import autoprefixer from 'autoprefixer'
import { createCssVariablesTheme } from 'shiki'
import { cssVariables } from './theme/config/shiki'
// import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers'
import { siteConfig } from './theme/config/site'
import ComponentPreviewPlugin from './theme/plugins/previewer'
const cssVariables = createCssVariablesTheme({
variablePrefix: '--shiki-',
variableDefaults: {},
})
// https://vitepress.dev/reference/site-config
export default defineConfig({
title: siteConfig.name,

View File

@ -1,10 +1,10 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { onMounted, ref, toRefs, watch } from 'vue'
import { Icon } from '@iconify/vue'
import { makeCodeSandboxParams } from '../utils/codeeditor'
import Tooltip from './Tooltip.vue'
import { Button } from '@/lib/registry/new-york/ui/button'
import { type Style } from '@/lib/registry/styles'
import type { Style } from '@/lib/registry/styles'
const props = defineProps<{
name: string
@ -12,11 +12,12 @@ const props = defineProps<{
style: Style
}>()
const { code } = toRefs(props)
const sources = ref<Record<string, string>>({})
onMounted(() => {
sources.value['App.vue'] = props.code
})
watch(code, () => {
sources.value['App.vue'] = code.value
}, { immediate: true })
</script>
<template>

View File

@ -1,4 +1,7 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import { codeToHtml } from 'shiki'
import { cssVariables } from '../config/shiki'
import StyleSwitcher from './StyleSwitcher.vue'
import ComponentLoader from './ComponentLoader.vue'
import Stackblitz from './Stackblitz.vue'
@ -11,7 +14,7 @@ defineOptions({
inheritAttrs: false,
})
withDefaults(defineProps<{
const props = withDefaults(defineProps<{
name: string
align?: 'center' | 'start' | 'end'
sfcTsCode?: string
@ -19,6 +22,22 @@ withDefaults(defineProps<{
}>(), { align: 'center' })
const { style } = useConfigStore()
const codeString = ref('')
const codeHtml = ref('')
watch(style, async () => {
try {
codeString.value = await import(`../../../src/lib/registry/${style.value}/example/${props.name}.vue?raw`).then(res => res.default.trim())
codeHtml.value = await codeToHtml(codeString.value, {
lang: 'vue',
theme: cssVariables,
})
}
catch (err) {
console.error(err)
}
}, { immediate: true })
</script>
<template>
@ -47,8 +66,8 @@ const { style } = useConfigStore()
<StyleSwitcher />
<div class="flex items-center gap-x-1">
<Stackblitz :key="style" :style="style" :name="name" :code="decodeURIComponent(sfcTsCode ?? '')" />
<CodeSandbox :key="style" :style="style" :name="name" :code="decodeURIComponent(sfcTsCode ?? '')" />
<Stackblitz :key="style" :style="style" :name="name" :code="codeString" />
<CodeSandbox :key="style" :style="style" :name="name" :code="codeString" />
</div>
</div>
<div
@ -62,7 +81,7 @@ const { style } = useConfigStore()
</div>
</TabsContent>
<TabsContent value="code">
<div v-if="sfcTsHtml" class="language-vue" style="flex: 1;" v-html="decodeURIComponent(sfcTsHtml)" />
<div v-if="codeHtml" class="language-vue" style="flex: 1;" v-html="codeHtml" />
<slot v-else />
</TabsContent>
</Tabs>

View File

@ -1,10 +1,10 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { onMounted, ref, toRefs, watch } from 'vue'
import { Icon } from '@iconify/vue'
import { makeStackblitzParams } from '../utils/codeeditor'
import Tooltip from './Tooltip.vue'
import { Button } from '@/lib/registry/new-york/ui/button'
import { type Style } from '@/lib/registry/styles'
import type { Style } from '@/lib/registry/styles'
const props = defineProps<{
name: string
@ -12,10 +12,14 @@ const props = defineProps<{
style: Style
}>()
const { code } = toRefs(props)
const sources = ref<Record<string, string>>({})
onMounted(() => {
sources.value['App.vue'] = props.code
})
watch(code, () => {
sources.value['App.vue'] = code.value
})
function handleClick() {

View File

@ -0,0 +1,6 @@
import { createCssVariablesTheme } from 'shiki'
export const cssVariables = createCssVariablesTheme({
variablePrefix: '--shiki-',
variableDefaults: {},
})

View File

@ -18,6 +18,7 @@ export function makeCodeSandboxParams(componentName: string, style: Style, sourc
export function makeStackblitzParams(componentName: string, style: Style, sources: Record<string, string>) {
const files: Record<string, string> = {}
Object.entries(constructFiles(componentName, style, sources)).forEach(([k, v]) => (files[`${k}`] = typeof v.content === 'object' ? JSON.stringify(v.content, null, 2) : v.content))
console.log({ files, componentName, style, sources })
return sdk.openProject({
title: `${componentName} - Radix Vue`,
files,