From a6ee301d5b3c30d5d86b49bff15be82fce4e9250 Mon Sep 17 00:00:00 2001 From: HoshinoSuzumi Date: Tue, 19 Nov 2024 20:53:54 +0800 Subject: [PATCH] docs framework: tocs, contents, highlighter --- docs/app.vue | 11 ++- ...cExampleBlock.vue => ComponentPreview.vue} | 93 ++++++++++--------- docs/components/TitleBar.vue | 7 +- docs/components/Toc.vue | 91 ++++++++++++++++++ docs/composables/useShikiHighlighter.ts | 8 +- docs/content/2.components/button.md | 38 ++++---- docs/content/index.md | 19 +--- docs/layouts/default.vue | 8 +- docs/nuxt.config.ts | 13 ++- docs/package.json | 1 + docs/pages/[...slug].vue | 46 +++++++-- docs/utils/index.ts | 17 ++++ pnpm-lock.yaml | 17 ++++ 13 files changed, 271 insertions(+), 98 deletions(-) rename docs/components/{DocExampleBlock.vue => ComponentPreview.vue} (51%) create mode 100644 docs/components/Toc.vue create mode 100644 docs/utils/index.ts diff --git a/docs/app.vue b/docs/app.vue index 4441c11..f4bec5e 100644 --- a/docs/app.vue +++ b/docs/app.vue @@ -1,4 +1,7 @@ - + + diff --git a/docs/components/DocExampleBlock.vue b/docs/components/ComponentPreview.vue similarity index 51% rename from docs/components/DocExampleBlock.vue rename to docs/components/ComponentPreview.vue index 42aef56..df429e9 100644 --- a/docs/components/DocExampleBlock.vue +++ b/docs/components/ComponentPreview.vue @@ -3,12 +3,13 @@ import FileTypeVue from "./icon/VscodeIconsFileTypeVue.vue" import FileTypeTypescript from "./icon/VscodeIconsFileTypeTypescriptOfficial.vue" import FileTypeJavascript from "./icon/VscodeIconsFileTypeJsOfficial.vue" import TablerTerminal from "./icon/TablerTerminal.vue"; +import { camelCase, kebabCase, upperFirst } from "scule"; -const hightlighter = useShikiHighlighter(); +const route = useRoute(); +const highlighter = useShikiHighlighter(); const slots = defineSlots<{ default?: () => VNode[]; - code?: () => VNode[]; }>(); const IconComponents = { @@ -19,33 +20,19 @@ const IconComponents = { 'js': FileTypeJavascript, } -const codeSlotContent = computed(() => { - if (slots.code) { - const slotContent = slots.code(); - let contentLines = slotContent - .map(vnode => vnode.children || '') - .join('') - .replace('\n', '') // remove first line break - .split('\n'); - - // calculate the minimum indent - const minIndent = contentLines.reduce((min, line) => { - const match = line.match(/^(\s*)\S/); - if (match) { - return Math.min(min, match[1].length); - } - return min; - }, Infinity); - - // remove the minimum indent from each line - const stringContent = contentLines.map(line => line.slice(minIndent)).join('\n'); - - return stringContent; - } - return ''; -}) - const props = defineProps({ + slug: { + type: String, + default: '', + }, + props: { + type: Object, + default: () => ({}), + }, + slots: { + type: Object, + default: () => ({}), + }, filename: { type: String, default: '', @@ -54,13 +41,27 @@ const props = defineProps({ type: String as PropType, default: '', }, - code: { - type: String, - default: '', - } }) -const { data: ast } = await useAsyncData(`${'name'}-ast-${JSON.stringify({ slots: props.slots, code: props.code })}`, async () => { +const componentName = props.slug || `Ray${upperFirst(camelCase(route.params.slug[route.params.slug.length - 1]))}` +const componentProps = reactive({ ...props.props }) + +const code = computed(() => { + let code = `\`\`\`html + +\`\`\` + ` + return code; +}) + +const { data: codeRender } = await useAsyncData(`${componentName}-renderer-${JSON.stringify({ slots: slots, code: code.value })}`, async () => { let formatted = '' try { // @ts-ignore @@ -70,24 +71,25 @@ const { data: ast } = await useAsyncData(`${'name'}-ast-${JSON.stringify({ slots singleQuote: true }) } catch { - formatted = props.code + formatted = code.value } return parseMarkdown(formatted, { highlight: { highlighter, theme: { - light: 'material-theme-lighter', - default: 'material-theme', - dark: 'material-theme-palenight' + light: 'light-plus', + dark: 'dark-plus' } } }) +}, { + watch: [code] })