mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
96 lines
2.7 KiB
Vue
96 lines
2.7 KiB
Vue
<template>
|
|
<div class="[&>div>pre]:!rounded-t-none [&>div>pre]:!mt-0">
|
|
<div
|
|
class="flex border border-gray-200 dark:border-gray-700 relative rounded-t-md"
|
|
:class="[{ 'p-4': padding, 'rounded-b-md': !hasCode, 'border-b-0': hasCode, 'not-prose': !prose }, backgroundClass, extraClass]"
|
|
>
|
|
<template v-if="component">
|
|
<iframe v-if="iframe" :src="`/examples/${component}`" v-bind="iframeProps" :class="backgroundClass" class="w-full" />
|
|
<component :is="camelName" v-else v-bind="componentProps" :class="componentClass" />
|
|
</template>
|
|
|
|
<ContentSlot v-if="$slots.default" :use="$slots.default" />
|
|
</div>
|
|
<template v-if="hasCode">
|
|
<slot v-if="$slots.code" name="code" />
|
|
<ContentRenderer v-else :value="ast" class="[&>div>pre]:!rounded-t-none [&>div>pre]:!mt-0" />
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { camelCase } from 'scule'
|
|
import { fetchContentExampleCode } from '~/composables/useContentExamplesCode'
|
|
import { transformContent } from '@nuxt/content/transformers'
|
|
import { useShikiHighlighter } from '~/composables/useShikiHighlighter'
|
|
|
|
const props = defineProps({
|
|
component: {
|
|
type: String,
|
|
default: null
|
|
},
|
|
componentClass: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
componentProps: {
|
|
type: Object,
|
|
default: () => ({})
|
|
},
|
|
hiddenCode: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
padding: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
prose: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
iframe: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
iframeProps: {
|
|
type: Object,
|
|
default: () => ({})
|
|
},
|
|
backgroundClass: {
|
|
type: String,
|
|
default: 'bg-white dark:bg-gray-900'
|
|
},
|
|
extraClass: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
})
|
|
|
|
let component = props.component
|
|
// TODO: Remove once merged on `main` branch
|
|
if (['command-palette-theme-algolia', 'command-palette-theme-raycast', 'vertical-navigation-theme-tailwind', 'pagination-theme-rounded'].includes(component)) {
|
|
component = component.replace('-theme', '-example-theme')
|
|
}
|
|
|
|
const instance = getCurrentInstance()
|
|
const camelName = camelCase(component)
|
|
const data = await fetchContentExampleCode(camelName)
|
|
const highlighter = useShikiHighlighter()
|
|
|
|
const hasCode = computed(() => !props.hiddenCode && (data?.code || instance.slots.code))
|
|
|
|
const { data: ast } = await useAsyncData(`content-example-${camelName}-ast`, () => transformContent('content:_markdown.md', `\`\`\`vue\n${data?.code ?? ''}\n\`\`\``, {
|
|
markdown: {
|
|
highlight: {
|
|
highlighter,
|
|
theme: {
|
|
light: 'material-theme-lighter',
|
|
default: 'material-theme',
|
|
dark: 'material-theme-palenight'
|
|
}
|
|
}
|
|
}
|
|
}))
|
|
</script>
|