docs: add theme to highlight code block (#831)
This commit is contained in:
parent
e0d4980e31
commit
52b9b20b3c
|
|
@ -4,7 +4,6 @@ import autoprefixer from 'autoprefixer'
|
||||||
import tailwind from 'tailwindcss'
|
import tailwind from 'tailwindcss'
|
||||||
import Icons from 'unplugin-icons/vite'
|
import Icons from 'unplugin-icons/vite'
|
||||||
import { defineConfig } from 'vitepress'
|
import { defineConfig } from 'vitepress'
|
||||||
import { cssVariables } from './theme/config/shiki'
|
|
||||||
|
|
||||||
import { siteConfig } from './theme/config/site'
|
import { siteConfig } from './theme/config/site'
|
||||||
import CodeWrapperPlugin from './theme/plugins/codewrapper'
|
import CodeWrapperPlugin from './theme/plugins/codewrapper'
|
||||||
|
|
@ -31,7 +30,6 @@ export default defineConfig({
|
||||||
['meta', { name: 'og:site_name', content: siteConfig.name }],
|
['meta', { name: 'og:site_name', content: siteConfig.name }],
|
||||||
['meta', { name: 'og:image', content: siteConfig.ogImage }],
|
['meta', { name: 'og:image', content: siteConfig.ogImage }],
|
||||||
['meta', { name: 'twitter:image', content: siteConfig.ogImage }],
|
['meta', { name: 'twitter:image', content: siteConfig.ogImage }],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
sitemap: {
|
sitemap: {
|
||||||
|
|
@ -58,7 +56,6 @@ export default defineConfig({
|
||||||
|
|
||||||
srcDir: path.resolve(__dirname, '../src'),
|
srcDir: path.resolve(__dirname, '../src'),
|
||||||
markdown: {
|
markdown: {
|
||||||
theme: cssVariables,
|
|
||||||
codeTransformers: [
|
codeTransformers: [
|
||||||
transformerMetaWordHighlight(),
|
transformerMetaWordHighlight(),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,8 @@ import { cn } from '@/lib/utils'
|
||||||
import { useConfigStore } from '@/stores/config'
|
import { useConfigStore } from '@/stores/config'
|
||||||
import { useClipboard } from '@vueuse/core'
|
import { useClipboard } from '@vueuse/core'
|
||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import { codeToHtml } from 'shiki'
|
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import { cssVariables } from '../config/shiki'
|
import { highlight } from '../config/shiki'
|
||||||
import CodeSandbox from './CodeSandbox.vue'
|
import CodeSandbox from './CodeSandbox.vue'
|
||||||
import ComponentLoader from './ComponentLoader.vue'
|
import ComponentLoader from './ComponentLoader.vue'
|
||||||
import Stackblitz from './Stackblitz.vue'
|
import Stackblitz from './Stackblitz.vue'
|
||||||
|
|
@ -37,10 +36,7 @@ function transformImportPath(code: string) {
|
||||||
watch([style, codeConfig], async () => {
|
watch([style, codeConfig], async () => {
|
||||||
try {
|
try {
|
||||||
rawString.value = await import(`../../../src/lib/registry/${style.value}/example/${props.name}.vue?raw`).then(res => res.default.trim())
|
rawString.value = await import(`../../../src/lib/registry/${style.value}/example/${props.name}.vue?raw`).then(res => res.default.trim())
|
||||||
codeHtml.value = await codeToHtml(transformedRawString.value, {
|
codeHtml.value = highlight(transformedRawString.value, 'vue')
|
||||||
lang: 'vue',
|
|
||||||
theme: cssVariables,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,41 @@
|
||||||
import { createCssVariablesTheme } from 'shiki'
|
import type { HighlighterCore } from 'shiki/core'
|
||||||
|
import type { ThemeOptions } from 'vitepress'
|
||||||
|
import { computedAsync } from '@vueuse/core'
|
||||||
|
import { createHighlighterCore } from 'shiki/core'
|
||||||
|
import { createJavaScriptRegexEngine } from 'shiki/engine/javascript'
|
||||||
|
|
||||||
export const cssVariables = createCssVariablesTheme({
|
export const shikiThemes: ThemeOptions = {
|
||||||
variablePrefix: '--shiki-',
|
light: 'github-light-default',
|
||||||
variableDefaults: {},
|
dark: 'github-dark-default',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const highlighter = computedAsync<HighlighterCore>(async (onCancel) => {
|
||||||
|
const shiki = await createHighlighterCore({
|
||||||
|
engine: createJavaScriptRegexEngine(),
|
||||||
|
themes: [
|
||||||
|
() => import('shiki/themes/github-dark-default.mjs'),
|
||||||
|
() => import('shiki/themes/github-light-default.mjs'),
|
||||||
|
],
|
||||||
|
langs: [
|
||||||
|
() => import('shiki/langs/javascript.mjs'),
|
||||||
|
() => import('shiki/langs/vue.mjs'),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
onCancel(() => shiki?.dispose())
|
||||||
|
return shiki
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export function highlight(code: string, lang: string) {
|
||||||
|
if (!highlighter.value)
|
||||||
|
return code
|
||||||
|
|
||||||
|
return highlighter.value.codeToHtml(code, {
|
||||||
|
lang,
|
||||||
|
defaultColor: false,
|
||||||
|
themes: {
|
||||||
|
dark: 'github-dark-default',
|
||||||
|
light: 'github-light-default',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,15 @@
|
||||||
scrollbar-color: hsl(215.4 16.3% 56.9% / 0.3);
|
scrollbar-color: hsl(215.4 16.3% 56.9% / 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.dark .shiki,
|
||||||
|
html.dark .shiki span {
|
||||||
|
color: var(--shiki-dark);
|
||||||
|
}
|
||||||
|
html:not(.dark) .shiki,
|
||||||
|
html:not(.dark) .shiki span {
|
||||||
|
color: var(--shiki-light);
|
||||||
|
}
|
||||||
|
|
||||||
.antialised {
|
.antialised {
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
@ -154,7 +163,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
div[class^="language-"] {
|
div[class^="language-"] {
|
||||||
@apply mb-4 mt-6 max-h-[650px] overflow-x-auto md:rounded-lg border !bg-secondary-foreground dark:!bg-secondary
|
@apply mb-4 mt-6 max-h-[650px] overflow-x-auto md:rounded-lg border
|
||||||
}
|
}
|
||||||
pre {
|
pre {
|
||||||
@apply py-4;
|
@apply py-4;
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^1.1.2",
|
||||||
"rimraf": "^6.0.1",
|
"rimraf": "^6.0.1",
|
||||||
"shiki": "^1.17.7",
|
"shiki": "^1.22.1",
|
||||||
"tailwind-merge": "^2.5.2",
|
"tailwind-merge": "^2.5.2",
|
||||||
"tailwindcss": "^3.4.12",
|
"tailwindcss": "^3.4.12",
|
||||||
"tsx": "^4.19.1",
|
"tsx": "^4.19.1",
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,10 @@ import { Switch } from '@/components/ui/switch'
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<Switch :checked="isDark" @update:checked="toggleTheme">
|
<Switch :checked="isDark" @update:checked="toggleTheme">
|
||||||
<template #thumb>
|
<template #thumb>
|
||||||
<Icon v-if="isDark" icon="lucide:moon" class="size-3"></Icon>
|
<Icon v-if="isDark" icon="lucide:moon" class="size-3" />
|
||||||
<Icon v-else icon="lucide:sun" class="size-3"></Icon>
|
<Icon v-else icon="lucide:sun" class="size-3" />
|
||||||
</template>
|
</template>
|
||||||
</Switch>
|
</Switch>
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,20 @@ import {
|
||||||
useForwardPropsEmits,
|
useForwardPropsEmits,
|
||||||
} from 'radix-vue'
|
} from 'radix-vue'
|
||||||
import { computed, type HTMLAttributes } from 'vue'
|
import { computed, type HTMLAttributes } from 'vue'
|
||||||
|
|
||||||
const props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()
|
const props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()
|
||||||
|
|
||||||
const emits = defineEmits<SwitchRootEmits>()
|
const emits = defineEmits<SwitchRootEmits>()
|
||||||
|
|
||||||
const delegatedProps = computed(() => {
|
const delegatedProps = computed(() => {
|
||||||
const { class: _, ...delegated } = props
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
return delegated
|
return delegated
|
||||||
})
|
})
|
||||||
|
|
||||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<SwitchRoot
|
<SwitchRoot
|
||||||
v-bind="forwarded"
|
v-bind="forwarded"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"files": [
|
"files": [
|
||||||
{
|
{
|
||||||
"name": "Switch.vue",
|
"name": "Switch.vue",
|
||||||
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n SwitchRoot,\n type SwitchRootEmits,\n type SwitchRootProps,\n SwitchThumb,\n useForwardPropsEmits,\n} from 'radix-vue'\nimport { computed, type HTMLAttributes } from 'vue'\nconst props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()\nconst emits = defineEmits<SwitchRootEmits>()\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n return delegated\n})\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n<template>\n <SwitchRoot\n v-bind=\"forwarded\"\n :class=\"cn(\n 'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',\n props.class,\n )\"\n >\n <SwitchThumb\n :class=\"cn('pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5')\"\n >\n <slot name=\"thumb\" />\n </SwitchThumb>\n </SwitchRoot>\n</template>\n"
|
"content": "<script setup lang=\"ts\">\nimport { cn } from '@/lib/utils'\nimport {\n SwitchRoot,\n type SwitchRootEmits,\n type SwitchRootProps,\n SwitchThumb,\n useForwardPropsEmits,\n} from 'radix-vue'\nimport { computed, type HTMLAttributes } from 'vue'\n\nconst props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()\n\nconst emits = defineEmits<SwitchRootEmits>()\n\nconst delegatedProps = computed(() => {\n const { class: _, ...delegated } = props\n\n return delegated\n})\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n <SwitchRoot\n v-bind=\"forwarded\"\n :class=\"cn(\n 'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',\n props.class,\n )\"\n >\n <SwitchThumb\n :class=\"cn('pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5')\"\n >\n <slot name=\"thumb\" />\n </SwitchThumb>\n </SwitchRoot>\n</template>\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "index.ts",
|
"name": "index.ts",
|
||||||
|
|
|
||||||
2772
pnpm-lock.yaml
2772
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user