feat: generate code dynamically
This commit is contained in:
parent
4d08adc81e
commit
3832ea3043
|
|
@ -3,17 +3,12 @@ import { defineConfig } from 'vitepress'
|
||||||
import Icons from 'unplugin-icons/vite'
|
import Icons from 'unplugin-icons/vite'
|
||||||
import tailwind from 'tailwindcss'
|
import tailwind from 'tailwindcss'
|
||||||
import autoprefixer from 'autoprefixer'
|
import autoprefixer from 'autoprefixer'
|
||||||
import { createCssVariablesTheme } from 'shiki'
|
import { cssVariables } from './theme/config/shiki'
|
||||||
|
|
||||||
// import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers'
|
// import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers'
|
||||||
import { siteConfig } from './theme/config/site'
|
import { siteConfig } from './theme/config/site'
|
||||||
import ComponentPreviewPlugin from './theme/plugins/previewer'
|
import ComponentPreviewPlugin from './theme/plugins/previewer'
|
||||||
|
|
||||||
const cssVariables = createCssVariablesTheme({
|
|
||||||
variablePrefix: '--shiki-',
|
|
||||||
variableDefaults: {},
|
|
||||||
})
|
|
||||||
|
|
||||||
// https://vitepress.dev/reference/site-config
|
// https://vitepress.dev/reference/site-config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
title: siteConfig.name,
|
title: siteConfig.name,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref, toRefs, watch } from 'vue'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
import { makeCodeSandboxParams } from '../utils/codeeditor'
|
import { makeCodeSandboxParams } from '../utils/codeeditor'
|
||||||
import Tooltip from './Tooltip.vue'
|
import Tooltip from './Tooltip.vue'
|
||||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
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<{
|
const props = defineProps<{
|
||||||
name: string
|
name: string
|
||||||
|
|
@ -12,11 +12,12 @@ const props = defineProps<{
|
||||||
style: Style
|
style: Style
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const { code } = toRefs(props)
|
||||||
const sources = ref<Record<string, string>>({})
|
const sources = ref<Record<string, string>>({})
|
||||||
|
|
||||||
onMounted(() => {
|
watch(code, () => {
|
||||||
sources.value['App.vue'] = props.code
|
sources.value['App.vue'] = code.value
|
||||||
})
|
}, { immediate: true })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { codeToHtml } from 'shiki'
|
||||||
|
import { cssVariables } from '../config/shiki'
|
||||||
import StyleSwitcher from './StyleSwitcher.vue'
|
import StyleSwitcher from './StyleSwitcher.vue'
|
||||||
import ComponentLoader from './ComponentLoader.vue'
|
import ComponentLoader from './ComponentLoader.vue'
|
||||||
import Stackblitz from './Stackblitz.vue'
|
import Stackblitz from './Stackblitz.vue'
|
||||||
|
|
@ -11,7 +14,7 @@ defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
name: string
|
name: string
|
||||||
align?: 'center' | 'start' | 'end'
|
align?: 'center' | 'start' | 'end'
|
||||||
sfcTsCode?: string
|
sfcTsCode?: string
|
||||||
|
|
@ -19,6 +22,22 @@ withDefaults(defineProps<{
|
||||||
}>(), { align: 'center' })
|
}>(), { align: 'center' })
|
||||||
|
|
||||||
const { style } = useConfigStore()
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -47,8 +66,8 @@ const { style } = useConfigStore()
|
||||||
<StyleSwitcher />
|
<StyleSwitcher />
|
||||||
|
|
||||||
<div class="flex items-center gap-x-1">
|
<div class="flex items-center gap-x-1">
|
||||||
<Stackblitz :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="decodeURIComponent(sfcTsCode ?? '')" />
|
<CodeSandbox :key="style" :style="style" :name="name" :code="codeString" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
@ -62,7 +81,7 @@ const { style } = useConfigStore()
|
||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="code">
|
<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 />
|
<slot v-else />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref, toRefs, watch } from 'vue'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
import { makeStackblitzParams } from '../utils/codeeditor'
|
import { makeStackblitzParams } from '../utils/codeeditor'
|
||||||
import Tooltip from './Tooltip.vue'
|
import Tooltip from './Tooltip.vue'
|
||||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
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<{
|
const props = defineProps<{
|
||||||
name: string
|
name: string
|
||||||
|
|
@ -12,10 +12,14 @@ const props = defineProps<{
|
||||||
style: Style
|
style: Style
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const { code } = toRefs(props)
|
||||||
const sources = ref<Record<string, string>>({})
|
const sources = ref<Record<string, string>>({})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
sources.value['App.vue'] = props.code
|
})
|
||||||
|
|
||||||
|
watch(code, () => {
|
||||||
|
sources.value['App.vue'] = code.value
|
||||||
})
|
})
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
|
|
|
||||||
6
apps/www/.vitepress/theme/config/shiki.ts
Normal file
6
apps/www/.vitepress/theme/config/shiki.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { createCssVariablesTheme } from 'shiki'
|
||||||
|
|
||||||
|
export const cssVariables = createCssVariablesTheme({
|
||||||
|
variablePrefix: '--shiki-',
|
||||||
|
variableDefaults: {},
|
||||||
|
})
|
||||||
|
|
@ -18,6 +18,7 @@ export function makeCodeSandboxParams(componentName: string, style: Style, sourc
|
||||||
export function makeStackblitzParams(componentName: string, style: Style, sources: Record<string, string>) {
|
export function makeStackblitzParams(componentName: string, style: Style, sources: Record<string, string>) {
|
||||||
const files: 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))
|
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({
|
return sdk.openProject({
|
||||||
title: `${componentName} - Radix Vue`,
|
title: `${componentName} - Radix Vue`,
|
||||||
files,
|
files,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user