@@ -11,7 +11,6 @@ const props = defineProps<{
1111
1212const code = ref (' ' )
1313const highlightedCode = ref (' ' )
14- const copied = ref (false )
1514
1615// Extract filename from path for display
1716const filename = computed (() => {
@@ -22,112 +21,119 @@ const filename = computed(() => {
2221const language = computed (() => {
2322 const extension = props .path .split (' .' ).pop () || ' text'
2423 const languageMap: Record <string , string > = {
25- ' ts ' : ' typescript' ,
26- ' js ' : ' javascript' ,
27- ' vue' : ' vue' ,
28- ' svelte' : ' svelte' , // Add this line
29- ' html' : ' html' ,
30- ' css' : ' css' ,
31- ' json' : ' json' ,
32- ' md ' : ' markdown' ,
33- ' tsx' : ' tsx' ,
34- ' jsx' : ' jsx'
24+ ts : ' typescript' ,
25+ js : ' javascript' ,
26+ vue: ' vue' ,
27+ svelte: ' svelte' , // Add this line
28+ html: ' html' ,
29+ css: ' css' ,
30+ json: ' json' ,
31+ md : ' markdown' ,
32+ tsx: ' tsx' ,
33+ jsx: ' jsx'
3534 }
3635 return languageMap [extension ] || ' text'
3736})
3837
3938async function loadCodeAndComponent() {
4039 try {
4140 // Look in the app/.cache/examples directory
42- const files = import .meta .glob ([
43- ' ../code/examples/**/*.ts' ,
44- ' ../code/examples/**/*.tsx' ,
45- ' ../code/examples/**/*.js' ,
46- ' ../code/examples/**/*.jsx' ,
47- ' ../code/examples/**/*.vue' ,
48- ' ../code/examples/**/*.svelte' ,
49- ' ../code/examples/**/*.md'
50- ], {
51- as: ' raw' ,
52- eager: false
53- })
41+ const files = import .meta .glob (
42+ [
43+ ' ../code/examples/**/*.ts' ,
44+ ' ../code/examples/**/*.tsx' ,
45+ ' ../code/examples/**/*.js' ,
46+ ' ../code/examples/**/*.jsx' ,
47+ ' ../code/examples/**/*.vue' ,
48+ ' ../code/examples/**/*.svelte' ,
49+ ' ../code/examples/**/*.md'
50+ ],
51+ {
52+ as: ' raw' ,
53+ eager: false
54+ }
55+ )
5456
5557 // Normalize the path by removing prefixes and cleaning up
5658 let normalizedPath = props .path
5759 .replace (/ ^ @\/ examples\/ / , ' ' ) // Remove @/examples/ prefix
5860 .replace (/ ^ \.\.\/\.\.\/\.\.\/\.\.\/ examples\/ / , ' ' ) // Remove ../../../../examples/ prefix
5961 .replace (/ ^ examples\/ / , ' ' ) // Remove examples/ prefix if present
6062 .replace (/ ^ \/ * | \/ * $ / g , ' ' ) // Remove leading/trailing slashes
61-
63+
6264 // Try to find the file with the normalized path
63- let fileKey = Object .keys (files ).find (key =>
64- key .includes (` /${normalizedPath } ` )
65- )
66-
65+ let fileKey = Object .keys (files ).find ((key ) => key .includes (` /${normalizedPath } ` ))
66+
6767 // If not found, try to find it by just the filename
6868 if (! fileKey ) {
6969 const filename = normalizedPath .split (' /' ).pop ()
70- fileKey = Object .keys (files ).find (key => key .endsWith (` /${filename } ` ))
70+ fileKey = Object .keys (files ).find (( key ) => key .endsWith (` /${filename } ` ))
7171 }
72-
72+
7373 if (! fileKey ) {
74- throw new Error (` File not found: ${normalizedPath }. Make sure the file exists in the examples directory and has been copied to the cache. ` )
74+ throw new Error (
75+ ` File not found: ${normalizedPath }. Make sure the file exists in the examples directory and has been copied to the cache. `
76+ )
7577 }
7678
7779 const loadRaw = files [fileKey ]
7880 if (! loadRaw ) {
79- throw new Error (` File not found: ${normalizedPath }. Make sure the file exists in the examples directory and has been copied to the cache. ` )
81+ throw new Error (
82+ ` File not found: ${normalizedPath }. Make sure the file exists in the examples directory and has been copied to the cache. `
83+ )
8084 }
8185 code .value = await loadRaw ()
82-
86+
8387 highlightedCode .value = await codeToHtml (code .value , {
8488 lang: language .value ,
85- theme: ' github-dark' ,
89+ theme: ' github-dark'
8690 })
8791 } catch (error ) {
8892 console .error (` Error loading file: ${props .path } ` , error )
8993 code .value = ` // Error loading file: ${props .path }\n // ${error instanceof Error ? error .message : String (error )} `
9094 highlightedCode .value = await codeToHtml (code .value , {
9195 lang: ' javascript' ,
92- theme: ' github-dark' ,
96+ theme: ' github-dark'
9397 })
9498 }
9599}
96100
97- async function copyCode() {
98- await navigator .clipboard .writeText (code .value )
99- copied .value = true
100- setTimeout (() => (copied .value = false ), 1500 )
101- }
102-
103101onMounted (loadCodeAndComponent )
104102
105- watch (() => props .path , () => {
106- loadCodeAndComponent ()
107- })
103+ watch (
104+ () => props .path ,
105+ () => {
106+ loadCodeAndComponent ()
107+ }
108+ )
108109 </script >
109110
110111<template >
111- <div class =" code-preview my-6" >
112- <div class =" relative" >
113- <Badge sm neutral class =" absolute top-2 left-2 font-mono text-base-content/50" >
114- {{ filename }}
115- </Badge >
116- <Button xs neutral class =" absolute top-2 right-4 cursor-pointer" @click =" copyCode" >
117- {{ copied ? 'Copied!' : 'Copy' }}
118- </Button >
119- <pre class =" overflow-x-auto rounded-lg p-4" v-html =" highlightedCode" />
120- </div >
121- </div >
112+ <ProsePre :code =" code" :filename =" filename" class =" code-preview" >
113+ <div v-html =" highlightedCode" />
114+ </ProsePre >
122115</template >
123116
124117<style >
118+ .code-preview > div > pre {
119+ padding-left : 0 ;
120+ }
121+ .code-preview {
122+ margin-top : 0 ;
123+ padding-top : 0 ;
124+ padding-bottom : 0 ;
125+ }
126+ .code-preview pre code span .line :not (:last-of-type ):empty {
127+ display : block ;
128+ margin-bottom : 1.5rem ;
129+ }
125130pre .shiki {
126131 background-color : var (--tw-prose-pre-bg ) !important ;
127132 color : var (--tw-prose-pre-code ) !important ;
133+ font-size : 16px ;
128134}
129135pre .shiki code {
130136 display : flex ;
131137 flex-direction : column ;
132138}
133- </style >
139+ </style >
0 commit comments