-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathYDBSyntaxHighlighter.tsx
119 lines (103 loc) · 3.48 KB
/
YDBSyntaxHighlighter.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import React from 'react';
import {ClipboardButton} from '@gravity-ui/uikit';
import {nanoid} from '@reduxjs/toolkit';
import {PrismLight as ReactSyntaxHighlighter} from 'react-syntax-highlighter';
import i18n from './i18n';
import {b} from './shared';
import {useSyntaxHighlighterStyle} from './themes';
import type {Language} from './types';
import {yql} from './yql';
import './YDBSyntaxHighlighter.scss';
async function registerLanguage(lang: Language) {
if (lang === 'yql') {
ReactSyntaxHighlighter.registerLanguage('yql', yql);
} else {
const {default: syntax} = await import(
`react-syntax-highlighter/dist/esm/languages/prism/${lang}`
);
ReactSyntaxHighlighter.registerLanguage(lang, syntax);
}
}
interface ClipboardButtonOptions {
alwaysVisible?: boolean;
copyText?: string;
withLabel?: boolean;
}
export type WithClipboardButtonProp = ClipboardButtonOptions | boolean;
type YDBSyntaxHighlighterProps = {
text: string;
language: Language;
className?: string;
transparentBackground?: boolean;
withClipboardButton?: WithClipboardButtonProp;
};
export function YDBSyntaxHighlighter({
text,
language,
className,
transparentBackground = true,
withClipboardButton,
}: YDBSyntaxHighlighterProps) {
const [highlighterKey, setHighlighterKey] = React.useState('');
const style = useSyntaxHighlighterStyle(transparentBackground);
React.useEffect(() => {
async function registerLangAndUpdateKey() {
await registerLanguage(language);
setHighlighterKey(nanoid());
}
registerLangAndUpdateKey();
}, [language]);
const renderCopyButton = () => {
if (withClipboardButton) {
return (
<div className={b('sticky-container')} onClick={(e) => e.stopPropagation()}>
<ClipboardButton
view="flat-secondary"
size="s"
className={b('copy', {
visible:
typeof withClipboardButton === 'object' &&
withClipboardButton.alwaysVisible,
})}
text={
(typeof withClipboardButton === 'object' &&
withClipboardButton.copyText) ||
text
}
>
{typeof withClipboardButton === 'object' &&
withClipboardButton.withLabel === false
? null
: i18n('copy')}
</ClipboardButton>
</div>
);
}
return null;
};
let paddingStyles = {};
if (
withClipboardButton &&
typeof withClipboardButton === 'object' &&
withClipboardButton.alwaysVisible
) {
if (withClipboardButton.withLabel) {
paddingStyles = {paddingRight: 80};
} else {
paddingStyles = {paddingRight: 40};
}
}
return (
<div className={b(null, className)}>
{renderCopyButton()}
<ReactSyntaxHighlighter
key={highlighterKey}
language={language}
style={style}
customStyle={{height: '100%', ...paddingStyles}}
>
{text}
</ReactSyntaxHighlighter>
</div>
);
}