11import MIME from 'mime' ;
22import { computed , observable } from 'mobx' ;
3- import { codeToHtml } from 'shiki ' ;
3+ import { highlight , languages } from 'prismjs ' ;
44import {
55 attribute ,
66 component ,
77 observer ,
8- reaction ,
98 WebCell ,
109 WebCellProps
1110} from 'web-cell' ;
11+ import { stringifyCSS } from 'web-utility' ;
1212
1313import { IconButton } from '../Form' ;
14- import * as styles from './CodeBlock.module.less' ;
1514
1615export interface CodeBlockProps extends WebCellProps < HTMLPreElement > {
1716 name ?: string ;
@@ -22,7 +21,7 @@ export interface CodeBlockProps extends WebCellProps<HTMLPreElement> {
2221
2322export interface CodeBlock extends WebCell < CodeBlockProps > { }
2423
25- @component ( { tagName : 'code-block' } )
24+ @component ( { tagName : 'code-block' , mode : 'open' } )
2625@observer
2726export class CodeBlock extends HTMLElement implements WebCell < CodeBlockProps > {
2827 @attribute
@@ -38,44 +37,61 @@ export class CodeBlock extends HTMLElement implements WebCell<CodeBlockProps> {
3837
3938 @attribute
4039 @observable
41- accessor theme = '' ;
40+ accessor theme = 'okaidia ' ;
4241
43- @observable
44- accessor markup = '' ;
42+ @computed
43+ get markup ( ) {
44+ const { value, language } = this ;
45+
46+ return (
47+ value && language && highlight ( value , languages [ language ] , language )
48+ ) ;
49+ }
4550
4651 @computed
4752 get dataURI ( ) {
4853 return `data:${ MIME . getType ( this . name ) } ;base64,${ btoa ( this . value ) } ` ;
4954 }
5055
51- @reaction ( ( { value, language, theme } ) => value + language + theme )
52- async connectedCallback ( ) {
53- if ( this . value )
54- this . markup = await codeToHtml ( this . value , {
55- lang : this . language ,
56- theme : this . theme
57- } ) ;
56+ connectedCallback ( ) {
57+ this . classList . add (
58+ 'd-block' ,
59+ 'bg-dark' ,
60+ 'rounded' ,
61+ 'overflow-hidden' ,
62+ 'p-3' ,
63+ 'position-relative'
64+ ) ;
5865 }
5966
6067 render ( ) {
61- const { name, dataURI, markup } = this ;
68+ const { name, dataURI, theme , markup } = this ;
6269
6370 return (
6471 < >
72+ < link
73+ rel = "stylesheet"
74+ href = "https://unpkg.com/bootstrap@5.3.3/dist/css/bootstrap.min.css"
75+ />
76+ < link
77+ rel = "stylesheet"
78+ href = "https://unpkg.com/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
79+ />
80+ < link
81+ rel = "stylesheet"
82+ href = { `https://unpkg.com/prismjs@1.29.0/themes/prism-${ theme } .min.css` }
83+ />
84+ < style > { stringifyCSS ( { pre : { margin : 0 } } ) } </ style >
6585 { name && (
66- < div className = "text-end mb-2" >
67- < IconButton
68- name = "download"
69- variant = "warning"
70- download = { name }
71- href = { dataURI }
72- />
73- </ div >
86+ < IconButton
87+ className = "position-absolute top-0 end-0"
88+ variant = "warning"
89+ name = "download"
90+ download = { name }
91+ href = { dataURI }
92+ />
7493 ) }
75- < div
76- className = { `rounded overflow-hidden ${ styles . code } ` }
77- innerHTML = { markup }
78- />
94+ < div innerHTML = { markup } />
7995 </ >
8096 ) ;
8197 }
0 commit comments