@@ -243,6 +243,20 @@ const canonicalUrl = computed(() => {
243243 return url
244244})
245245
246+ // Toggle markdown view mode
247+ const markdownViewModes = [
248+ {
249+ label: $t (' code.markdown_view_mode.preview' ),
250+ icon: ' i-carbon-view' ,
251+ },
252+ {
253+ label: $t (' code.markdown_view_mode.code' ),
254+ icon: ' i-carbon-code' ,
255+ },
256+ ] as const
257+
258+ const markdownViewMode = ref <(typeof markdownViewModes )[number ][' label' ]>(' preview' )
259+
246260useHead ({
247261 link: [{ rel: ' canonical' , href: canonicalUrl }],
248262})
@@ -359,15 +373,38 @@ useSeoMeta({
359373 <!-- File viewer -->
360374 <template v-if =" isViewingFile && fileContent " >
361375 <div
362- class =" sticky top-0 bg-bg border-b border-border px-4 py-2 flex items-center justify-between"
376+ class =" sticky z-10 top-0 bg-bg border-b border-border px-4 py-2 flex items-center justify-between"
363377 >
364- <div class =" flex items-center gap-3 text-sm" >
365- <span class =" text-fg-muted" >{{
366- $t('code.lines', { count: fileContent.lines })
367- }}</span >
368- <span v-if =" currentNode?.size" class =" text-fg-subtle" >{{
369- formatBytes(currentNode.size)
370- }}</span >
378+ <div class =" flex items-center gap-2" >
379+ <div
380+ v-if =" fileContent.markdownHtml"
381+ class =" flex items-center gap-1 p-0.5 bg-bg-subtle border border-border-subtle rounded-md overflow-x-auto"
382+ role =" tablist"
383+ aria-label =" Markdown view mode selector"
384+ >
385+ <button
386+ v-for =" mode in markdownViewModes"
387+ :key =" mode.label"
388+ class =" px-2 py-1.5 font-mono text-xs rounded transition-colors duration-150 border border-solid focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 inline-flex items-center gap-1.5"
389+ :class ="
390+ markdownViewMode === mode.label
391+ ? 'bg-bg shadow text-fg border-border'
392+ : 'text-fg-subtle hover:text-fg border-transparent'
393+ "
394+ @click =" markdownViewMode = mode.label"
395+ >
396+ <span class =" inline-block h-3 w-3" :class =" mode.icon" aria-hidden =" true" />
397+ {{ mode.label }}
398+ </button >
399+ </div >
400+ <div class =" flex items-center gap-3 text-sm" >
401+ <span class =" text-fg-muted" >{{
402+ $t('code.lines', { count: fileContent.lines })
403+ }}</span >
404+ <span v-if =" currentNode?.size" class =" text-fg-subtle" >{{
405+ formatBytes(currentNode.size)
406+ }}</span >
407+ </div >
371408 </div >
372409 <div class =" flex items-center gap-2" >
373410 <button
@@ -389,7 +426,19 @@ useSeoMeta({
389426 </a >
390427 </div >
391428 </div >
429+ <div
430+ v-if =" fileContent.markdownHtml"
431+ v-show =" markdownViewMode === 'preview'"
432+ class =" flex justify-center p-4"
433+ >
434+ <div
435+ class =" readme-content prose prose-invert max-w-[70ch]"
436+ v-html =" fileContent.markdownHtml.html"
437+ ></div >
438+ </div >
439+
392440 <CodeViewer
441+ v-show =" !fileContent.markdownHtml || markdownViewMode === 'code'"
393442 :html =" fileContent.html"
394443 :lines =" fileContent.lines"
395444 :selected-lines =" selectedLines"
0 commit comments