@dodlhuat/basix 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -1
- package/css/accordion.scss +86 -87
- package/css/alert.scss +137 -137
- package/css/button.scss +48 -0
- package/css/calendar.scss +957 -0
- package/css/card.scss +65 -65
- package/css/chart.scss +270 -157
- package/css/chat-bubbles.scss +134 -68
- package/css/chips.scss +109 -19
- package/css/colors.scss +32 -32
- package/css/datepicker.scss +336 -336
- package/css/defaults.scss +90 -90
- package/css/docs.scss +529 -0
- package/css/editor.scss +36 -0
- package/css/file-uploader.scss +1 -1
- package/css/flyout-menu.scss +361 -361
- package/css/form.scss +0 -15
- package/css/gallery.scss +65 -6
- package/css/grid.scss +41 -40
- package/css/group-picker.scss +345 -0
- package/css/guitar-chords.css +250 -250
- package/css/icons.scss +330 -330
- package/css/parameters.scss +3 -3
- package/css/placeholder.scss +33 -33
- package/css/popover.scss +206 -0
- package/css/progress.scss +76 -32
- package/css/properties.scss +51 -36
- package/css/push-menu.scss +302 -174
- package/css/reset.scss +39 -39
- package/css/scrollbar.scss +62 -5
- package/css/sidebar-nav.scss +92 -0
- package/css/spinner.scss +65 -65
- package/css/stepper.scss +48 -12
- package/css/style.css +3159 -254
- package/css/style.css.map +1 -1
- package/css/style.min.css +1 -1
- package/css/style.scss +51 -45
- package/css/table.scss +199 -199
- package/css/tabs.scss +154 -123
- package/css/timeline.scss +83 -38
- package/css/timepicker.scss +100 -5
- package/css/toast.scss +81 -81
- package/css/virtual-dropdown.scss +35 -29
- package/js/calendar.js +532 -0
- package/js/calendar.ts +706 -0
- package/js/chart.js +573 -257
- package/js/chart.ts +692 -0
- package/js/code-viewer.js +10 -10
- package/js/code-viewer.ts +188 -188
- package/js/datepicker.ts +627 -627
- package/js/docs-nav.js +204 -0
- package/js/dropdown.ts +179 -179
- package/js/editor.js +50 -6
- package/js/editor.ts +483 -444
- package/js/file-uploader.js +1 -0
- package/js/file-uploader.ts +1 -0
- package/js/flyout-menu.js +14 -14
- package/js/flyout-menu.ts +249 -249
- package/js/form-builder.js +106 -106
- package/js/gallery.js +14 -8
- package/js/gallery.ts +245 -236
- package/js/group-picker.js +342 -0
- package/js/group-picker.ts +447 -0
- package/js/guitar-chords.js +268 -268
- package/js/lazy-loader.js +121 -121
- package/js/modal.ts +166 -166
- package/js/popover.js +163 -0
- package/js/popover.ts +219 -0
- package/js/position.js +108 -0
- package/js/position.ts +111 -0
- package/js/push-menu.js +113 -0
- package/js/push-menu.ts +284 -145
- package/js/request.js +50 -50
- package/js/scroll.ts +47 -47
- package/js/scrollbar.js +13 -0
- package/js/scrollbar.ts +324 -307
- package/js/select.ts +216 -216
- package/js/sidebar-nav.js +41 -0
- package/js/sidebar-nav.ts +66 -0
- package/js/table.ts +452 -452
- package/js/tabs.ts +279 -279
- package/js/theme.js +17 -6
- package/js/theme.ts +234 -224
- package/js/toast.ts +137 -137
- package/js/tooltip.js +6 -60
- package/js/tooltip.ts +184 -251
- package/js/tsconfig.json +18 -18
- package/js/utils.ts +83 -83
- package/js/virtual-dropdown.js +25 -25
- package/js/virtual-dropdown.ts +365 -365
- package/package.json +39 -39
- package/js/index.js +0 -816
- package/js/index.ts +0 -987
package/js/code-viewer.js
CHANGED
|
@@ -128,16 +128,16 @@ class CodeViewer {
|
|
|
128
128
|
}
|
|
129
129
|
render() {
|
|
130
130
|
const highlighted = this.highlight(this.code);
|
|
131
|
-
this.container.innerHTML = `
|
|
132
|
-
<div class="code-display">
|
|
133
|
-
<div class="code-header">
|
|
134
|
-
<span class="code-language">${this.language}</span>
|
|
135
|
-
<button class="copy-button">Copy</button>
|
|
136
|
-
</div>
|
|
137
|
-
<div class="code-content">
|
|
138
|
-
<pre>${highlighted}</pre>
|
|
139
|
-
</div>
|
|
140
|
-
</div>
|
|
131
|
+
this.container.innerHTML = `
|
|
132
|
+
<div class="code-display">
|
|
133
|
+
<div class="code-header">
|
|
134
|
+
<span class="code-language">${this.language}</span>
|
|
135
|
+
<button class="copy-button">Copy</button>
|
|
136
|
+
</div>
|
|
137
|
+
<div class="code-content">
|
|
138
|
+
<pre>${highlighted}</pre>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
141
|
`;
|
|
142
142
|
const copyButton = this.container.querySelector('.copy-button');
|
|
143
143
|
if (copyButton) {
|
package/js/code-viewer.ts
CHANGED
|
@@ -1,188 +1,188 @@
|
|
|
1
|
-
type SupportedLanguage = 'javascript' | 'js' | 'html' | 'css';
|
|
2
|
-
|
|
3
|
-
class CodeViewer {
|
|
4
|
-
private container: HTMLElement;
|
|
5
|
-
private code: string;
|
|
6
|
-
private language: string;
|
|
7
|
-
|
|
8
|
-
constructor(elementOrSelector: string | HTMLElement, code: string, language: SupportedLanguage = 'javascript') {
|
|
9
|
-
const element = typeof elementOrSelector === 'string'
|
|
10
|
-
? document.querySelector<HTMLElement>(elementOrSelector)
|
|
11
|
-
: elementOrSelector;
|
|
12
|
-
|
|
13
|
-
if (!element) {
|
|
14
|
-
throw new Error(`CodeViewer: Element not found for selector "${elementOrSelector}"`);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
this.container = element;
|
|
18
|
-
this.code = code;
|
|
19
|
-
this.language = language.toLowerCase();
|
|
20
|
-
this.render();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
private highlight(code: string): string {
|
|
24
|
-
switch(this.language) {
|
|
25
|
-
case 'javascript':
|
|
26
|
-
case 'js':
|
|
27
|
-
return this.highlightJavaScript(code);
|
|
28
|
-
case 'html':
|
|
29
|
-
return this.highlightHTML(code);
|
|
30
|
-
case 'css':
|
|
31
|
-
return this.highlightCSS(code);
|
|
32
|
-
default:
|
|
33
|
-
return this.escape(code);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private escape(str: string): string {
|
|
38
|
-
return str
|
|
39
|
-
.replace(/&/g, '&')
|
|
40
|
-
.replace(/</g, '<')
|
|
41
|
-
.replace(/>/g, '>')
|
|
42
|
-
.replace(/"/g, '"')
|
|
43
|
-
.replace(/'/g, ''');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private highlightJavaScript(code: string): string {
|
|
47
|
-
const strings: string[] = [];
|
|
48
|
-
|
|
49
|
-
code = code.replace(/`(?:[^`\\]|\\[\s\S])*`/g, (match) => {
|
|
50
|
-
strings.push(match);
|
|
51
|
-
return `###STRING${strings.length - 1}###`;
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
code = code.replace(/"(?:[^"\\]|\\[\s\S])*"/g, (match) => {
|
|
55
|
-
strings.push(match);
|
|
56
|
-
return `###STRING${strings.length - 1}###`;
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
code = code.replace(/'(?:[^'\\]|\\[\s\S])*'/g, (match) => {
|
|
60
|
-
strings.push(match);
|
|
61
|
-
return `###STRING${strings.length - 1}###`;
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const comments: string[] = [];
|
|
65
|
-
code = code.replace(/(\/\/.*$)/gm, (match) => {
|
|
66
|
-
comments.push(match);
|
|
67
|
-
return `###COMMENT${comments.length - 1}###`;
|
|
68
|
-
});
|
|
69
|
-
code = code.replace(/(\/\*[\s\S]*?\*\/)/g, (match) => {
|
|
70
|
-
comments.push(match);
|
|
71
|
-
return `###COMMENT${comments.length - 1}###`;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
code = this.escape(code);
|
|
75
|
-
|
|
76
|
-
const keywords = 'const|let|var|function|class|if|else|for|while|return|new|this|super|extends|import|export|from|default|async|await|try|catch|throw|switch|case|break|continue';
|
|
77
|
-
code = code.replace(new RegExp(`\\b(${keywords})\\b`, 'g'), '<span class="keyword">$1</span>');
|
|
78
|
-
|
|
79
|
-
code = code.replace(/\b(\d+(?:\.\d+)?)\b/g, '<span class="number">$1</span>');
|
|
80
|
-
|
|
81
|
-
strings.forEach((str, i) => {
|
|
82
|
-
code = code.replace(`###STRING${i}###`, '<span class="string">' + this.escape(str) + '</span>');
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
comments.forEach((comment, i) => {
|
|
86
|
-
code = code.replace(`###COMMENT${i}###`, '<span class="comment">' + this.escape(comment) + '</span>');
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
return code;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private highlightHTML(code: string): string {
|
|
93
|
-
code = this.escape(code);
|
|
94
|
-
|
|
95
|
-
code = code.replace(/(<!--[\s\S]*?-->)/g, '###COMMENT_START###$1###COMMENT_END###');
|
|
96
|
-
|
|
97
|
-
code = code.replace(/(<\/?)([a-zA-Z0-9]+)([^&]*?)(>)/g, (match, open, tagName, attrs, close) => {
|
|
98
|
-
attrs = attrs.replace(/\s+([a-zA-Z-]+)(=?)("[^&]*?"|'[^&]*?')?/g, (m: string, attrName: string, eq: string, attrValue?: string) => {
|
|
99
|
-
let result = ' <span class="attribute">' + attrName + '</span>';
|
|
100
|
-
if (eq) result += eq;
|
|
101
|
-
if (attrValue) result += '<span class="string">' + attrValue + '</span>';
|
|
102
|
-
return result;
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
return open + '<span class="tag">' + tagName + '</span>' + attrs + '<span class="punctuation">' + close + '</span>';
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
code = code.replace(/###COMMENT_START###(.*?)###COMMENT_END###/g, '<span class="comment">$1</span>');
|
|
109
|
-
|
|
110
|
-
return code;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private highlightCSS(code: string): string {
|
|
114
|
-
code = this.escape(code);
|
|
115
|
-
|
|
116
|
-
const comments: string[] = [];
|
|
117
|
-
code = code.replace(/(\/\*[\s\S]*?\*\/)/g, (match) => {
|
|
118
|
-
comments.push(match);
|
|
119
|
-
return `###COMMENT${comments.length - 1}###`;
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const strings: string[] = [];
|
|
123
|
-
code = code.replace(/("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/g, (match) => {
|
|
124
|
-
strings.push(match);
|
|
125
|
-
return `###STRING${strings.length - 1}###`;
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
code = code.replace(/^([^{]+)(?={)/gm, (match) => {
|
|
129
|
-
return '<span class="selector">' + match.trim() + '</span>';
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
code = code.replace(/([a-z-]+)(\s*):/gi, '<span class="property">$1</span>$2:');
|
|
133
|
-
|
|
134
|
-
code = code.replace(/:\s*([0-9.]+(?:px|em|rem|%|vh|vw|s|ms)?)/g, ': <span class="number">$1</span>');
|
|
135
|
-
|
|
136
|
-
strings.forEach((str, i) => {
|
|
137
|
-
code = code.replace(`###STRING${i}###`, '<span class="string">' + str + '</span>');
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
comments.forEach((comment, i) => {
|
|
141
|
-
code = code.replace(`###COMMENT${i}###`, '<span class="comment">' + comment + '</span>');
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
return code;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private async copyCode(): Promise<void> {
|
|
148
|
-
try {
|
|
149
|
-
await navigator.clipboard.writeText(this.code);
|
|
150
|
-
const btn = this.container.querySelector<HTMLButtonElement>('.copy-button');
|
|
151
|
-
|
|
152
|
-
if (!btn) return;
|
|
153
|
-
|
|
154
|
-
btn.textContent = 'copied!';
|
|
155
|
-
btn.classList.add('copied');
|
|
156
|
-
|
|
157
|
-
setTimeout(() => {
|
|
158
|
-
btn.textContent = 'Copy';
|
|
159
|
-
btn.classList.remove('copied');
|
|
160
|
-
}, 2000);
|
|
161
|
-
} catch (err) {
|
|
162
|
-
console.error('Error:', err);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
private render(): void {
|
|
167
|
-
const highlighted = this.highlight(this.code);
|
|
168
|
-
|
|
169
|
-
this.container.innerHTML = `
|
|
170
|
-
<div class="code-display">
|
|
171
|
-
<div class="code-header">
|
|
172
|
-
<span class="code-language">${this.language}</span>
|
|
173
|
-
<button class="copy-button">Copy</button>
|
|
174
|
-
</div>
|
|
175
|
-
<div class="code-content">
|
|
176
|
-
<pre>${highlighted}</pre>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
`;
|
|
180
|
-
|
|
181
|
-
const copyButton = this.container.querySelector<HTMLButtonElement>('.copy-button');
|
|
182
|
-
if (copyButton) {
|
|
183
|
-
copyButton.addEventListener('click', () => this.copyCode());
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
export { CodeViewer };
|
|
188
|
-
export type { SupportedLanguage };
|
|
1
|
+
type SupportedLanguage = 'javascript' | 'js' | 'html' | 'css';
|
|
2
|
+
|
|
3
|
+
class CodeViewer {
|
|
4
|
+
private container: HTMLElement;
|
|
5
|
+
private code: string;
|
|
6
|
+
private language: string;
|
|
7
|
+
|
|
8
|
+
constructor(elementOrSelector: string | HTMLElement, code: string, language: SupportedLanguage = 'javascript') {
|
|
9
|
+
const element = typeof elementOrSelector === 'string'
|
|
10
|
+
? document.querySelector<HTMLElement>(elementOrSelector)
|
|
11
|
+
: elementOrSelector;
|
|
12
|
+
|
|
13
|
+
if (!element) {
|
|
14
|
+
throw new Error(`CodeViewer: Element not found for selector "${elementOrSelector}"`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
this.container = element;
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.language = language.toLowerCase();
|
|
20
|
+
this.render();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private highlight(code: string): string {
|
|
24
|
+
switch(this.language) {
|
|
25
|
+
case 'javascript':
|
|
26
|
+
case 'js':
|
|
27
|
+
return this.highlightJavaScript(code);
|
|
28
|
+
case 'html':
|
|
29
|
+
return this.highlightHTML(code);
|
|
30
|
+
case 'css':
|
|
31
|
+
return this.highlightCSS(code);
|
|
32
|
+
default:
|
|
33
|
+
return this.escape(code);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private escape(str: string): string {
|
|
38
|
+
return str
|
|
39
|
+
.replace(/&/g, '&')
|
|
40
|
+
.replace(/</g, '<')
|
|
41
|
+
.replace(/>/g, '>')
|
|
42
|
+
.replace(/"/g, '"')
|
|
43
|
+
.replace(/'/g, ''');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private highlightJavaScript(code: string): string {
|
|
47
|
+
const strings: string[] = [];
|
|
48
|
+
|
|
49
|
+
code = code.replace(/`(?:[^`\\]|\\[\s\S])*`/g, (match) => {
|
|
50
|
+
strings.push(match);
|
|
51
|
+
return `###STRING${strings.length - 1}###`;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
code = code.replace(/"(?:[^"\\]|\\[\s\S])*"/g, (match) => {
|
|
55
|
+
strings.push(match);
|
|
56
|
+
return `###STRING${strings.length - 1}###`;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
code = code.replace(/'(?:[^'\\]|\\[\s\S])*'/g, (match) => {
|
|
60
|
+
strings.push(match);
|
|
61
|
+
return `###STRING${strings.length - 1}###`;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const comments: string[] = [];
|
|
65
|
+
code = code.replace(/(\/\/.*$)/gm, (match) => {
|
|
66
|
+
comments.push(match);
|
|
67
|
+
return `###COMMENT${comments.length - 1}###`;
|
|
68
|
+
});
|
|
69
|
+
code = code.replace(/(\/\*[\s\S]*?\*\/)/g, (match) => {
|
|
70
|
+
comments.push(match);
|
|
71
|
+
return `###COMMENT${comments.length - 1}###`;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
code = this.escape(code);
|
|
75
|
+
|
|
76
|
+
const keywords = 'const|let|var|function|class|if|else|for|while|return|new|this|super|extends|import|export|from|default|async|await|try|catch|throw|switch|case|break|continue';
|
|
77
|
+
code = code.replace(new RegExp(`\\b(${keywords})\\b`, 'g'), '<span class="keyword">$1</span>');
|
|
78
|
+
|
|
79
|
+
code = code.replace(/\b(\d+(?:\.\d+)?)\b/g, '<span class="number">$1</span>');
|
|
80
|
+
|
|
81
|
+
strings.forEach((str, i) => {
|
|
82
|
+
code = code.replace(`###STRING${i}###`, '<span class="string">' + this.escape(str) + '</span>');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
comments.forEach((comment, i) => {
|
|
86
|
+
code = code.replace(`###COMMENT${i}###`, '<span class="comment">' + this.escape(comment) + '</span>');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return code;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private highlightHTML(code: string): string {
|
|
93
|
+
code = this.escape(code);
|
|
94
|
+
|
|
95
|
+
code = code.replace(/(<!--[\s\S]*?-->)/g, '###COMMENT_START###$1###COMMENT_END###');
|
|
96
|
+
|
|
97
|
+
code = code.replace(/(<\/?)([a-zA-Z0-9]+)([^&]*?)(>)/g, (match, open, tagName, attrs, close) => {
|
|
98
|
+
attrs = attrs.replace(/\s+([a-zA-Z-]+)(=?)("[^&]*?"|'[^&]*?')?/g, (m: string, attrName: string, eq: string, attrValue?: string) => {
|
|
99
|
+
let result = ' <span class="attribute">' + attrName + '</span>';
|
|
100
|
+
if (eq) result += eq;
|
|
101
|
+
if (attrValue) result += '<span class="string">' + attrValue + '</span>';
|
|
102
|
+
return result;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return open + '<span class="tag">' + tagName + '</span>' + attrs + '<span class="punctuation">' + close + '</span>';
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
code = code.replace(/###COMMENT_START###(.*?)###COMMENT_END###/g, '<span class="comment">$1</span>');
|
|
109
|
+
|
|
110
|
+
return code;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private highlightCSS(code: string): string {
|
|
114
|
+
code = this.escape(code);
|
|
115
|
+
|
|
116
|
+
const comments: string[] = [];
|
|
117
|
+
code = code.replace(/(\/\*[\s\S]*?\*\/)/g, (match) => {
|
|
118
|
+
comments.push(match);
|
|
119
|
+
return `###COMMENT${comments.length - 1}###`;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const strings: string[] = [];
|
|
123
|
+
code = code.replace(/("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/g, (match) => {
|
|
124
|
+
strings.push(match);
|
|
125
|
+
return `###STRING${strings.length - 1}###`;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
code = code.replace(/^([^{]+)(?={)/gm, (match) => {
|
|
129
|
+
return '<span class="selector">' + match.trim() + '</span>';
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
code = code.replace(/([a-z-]+)(\s*):/gi, '<span class="property">$1</span>$2:');
|
|
133
|
+
|
|
134
|
+
code = code.replace(/:\s*([0-9.]+(?:px|em|rem|%|vh|vw|s|ms)?)/g, ': <span class="number">$1</span>');
|
|
135
|
+
|
|
136
|
+
strings.forEach((str, i) => {
|
|
137
|
+
code = code.replace(`###STRING${i}###`, '<span class="string">' + str + '</span>');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
comments.forEach((comment, i) => {
|
|
141
|
+
code = code.replace(`###COMMENT${i}###`, '<span class="comment">' + comment + '</span>');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return code;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private async copyCode(): Promise<void> {
|
|
148
|
+
try {
|
|
149
|
+
await navigator.clipboard.writeText(this.code);
|
|
150
|
+
const btn = this.container.querySelector<HTMLButtonElement>('.copy-button');
|
|
151
|
+
|
|
152
|
+
if (!btn) return;
|
|
153
|
+
|
|
154
|
+
btn.textContent = 'copied!';
|
|
155
|
+
btn.classList.add('copied');
|
|
156
|
+
|
|
157
|
+
setTimeout(() => {
|
|
158
|
+
btn.textContent = 'Copy';
|
|
159
|
+
btn.classList.remove('copied');
|
|
160
|
+
}, 2000);
|
|
161
|
+
} catch (err) {
|
|
162
|
+
console.error('Error:', err);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private render(): void {
|
|
167
|
+
const highlighted = this.highlight(this.code);
|
|
168
|
+
|
|
169
|
+
this.container.innerHTML = `
|
|
170
|
+
<div class="code-display">
|
|
171
|
+
<div class="code-header">
|
|
172
|
+
<span class="code-language">${this.language}</span>
|
|
173
|
+
<button class="copy-button">Copy</button>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="code-content">
|
|
176
|
+
<pre>${highlighted}</pre>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
`;
|
|
180
|
+
|
|
181
|
+
const copyButton = this.container.querySelector<HTMLButtonElement>('.copy-button');
|
|
182
|
+
if (copyButton) {
|
|
183
|
+
copyButton.addEventListener('click', () => this.copyCode());
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
export { CodeViewer };
|
|
188
|
+
export type { SupportedLanguage };
|