-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathCodeSnippet.tsx
103 lines (93 loc) · 2.79 KB
/
CodeSnippet.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
'use client';
import { Button, Tooltip } from '@digdir/designsystemet-react';
import { FilesIcon } from '@navikt/aksel-icons';
import * as prettierBabel from 'prettier/parser-babel';
import * as prettierEstree from 'prettier/plugins/estree';
import * as prettierHtml from 'prettier/plugins/html.js';
import * as prettierMarkdown from 'prettier/plugins/markdown.js';
import * as prettierCSS from 'prettier/plugins/postcss.js';
import * as prettierTypescript from 'prettier/plugins/typescript.js';
import { format } from 'prettier/standalone.js';
import { useEffect, useState } from 'react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { nightOwl } from 'react-syntax-highlighter/dist/esm/styles/prism';
import classes from './CodeSnippet.module.css';
const plugins = [
prettierTypescript,
prettierEstree,
prettierCSS,
prettierMarkdown,
prettierHtml,
prettierBabel,
];
type CodeSnippetProps = {
language?: 'css' | 'html' | 'ts' | 'markdown' | 'js' | 'json';
children?: string;
};
const CodeSnippet = ({
language = 'markdown',
children = '',
}: CodeSnippetProps) => {
const [toolTipText, setToolTipText] = useState('Kopier');
const [snippet, setSnippet] = useState('');
useEffect(() => {
async function formatSnippet(
children: string,
language: CodeSnippetProps['language'],
) {
try {
const formatted = await format(children, {
parser: language === 'ts' ? 'typescript' : language,
plugins,
});
setSnippet(formatted);
} catch (error) {
console.error('Failed formatting code snippet:', error);
setSnippet(children);
}
}
void formatSnippet(children, language);
return () => {
setSnippet(children);
};
}, [children, language]);
const onButtonClick = () => {
setToolTipText('Kopiert!');
navigator.clipboard.writeText(children).catch((reason) => {
throw Error(String(reason));
});
};
return (
<div className={classes.codeSnippet} data-ds-color-mode='dark'>
{snippet && (
<>
<Tooltip content={toolTipText}>
<Button
onMouseEnter={() => setToolTipText('Kopier')}
onClick={() => onButtonClick()}
className={classes.copyButton}
title='Kopier'
icon
color='neutral'
size='sm'
>
<FilesIcon fontSize='1.5rem' />
</Button>
</Tooltip>
<SyntaxHighlighter
style={nightOwl}
language='jsx'
customStyle={{
fontSize: '15px',
margin: 0,
padding: '18px',
}}
>
{snippet}
</SyntaxHighlighter>
</>
)}
</div>
);
};
export { CodeSnippet };