Skip to content

Commit a544def

Browse files
feat(YDBSyntaxHighlighter): separate component, load languages on demand (#2004)
1 parent 6d53518 commit a544def

File tree

19 files changed

+267
-225
lines changed

19 files changed

+267
-225
lines changed

src/components/ConnectToDB/ConnectToDBDialog.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {Dialog, Tabs} from '@gravity-ui/uikit';
55

66
import {cn} from '../../utils/cn';
77
import {LinkWithIcon} from '../LinkWithIcon/LinkWithIcon';
8+
import {YDBSyntaxHighlighterLazy} from '../SyntaxHighlighter/lazy';
89

9-
import {ConnectToDBSyntaxHighlighterLazy} from './ConnectToDBSyntaxHighlighter/lazy';
1010
import {getDocsLink} from './getDocsLink';
1111
import i18n from './i18n';
1212
import {getSnippetCode} from './snippets';
@@ -52,7 +52,12 @@ function ConnectToDBDialog({open, onClose, database, endpoint}: ConnectToDBDialo
5252
className={b('dialog-tabs')}
5353
/>
5454
<div className={b('snippet-container')}>
55-
<ConnectToDBSyntaxHighlighterLazy language={activeTab} text={snippet} />
55+
<YDBSyntaxHighlighterLazy
56+
language={activeTab}
57+
text={snippet}
58+
transparentBackground={false}
59+
withCopy
60+
/>
5661
</div>
5762
{docsLink ? (
5863
<LinkWithIcon

src/components/ConnectToDB/ConnectToDBSyntaxHighlighter/ConnectToDBSyntaxHighlighter.tsx

-82
This file was deleted.

src/components/ConnectToDB/ConnectToDBSyntaxHighlighter/lazy.ts

-6
This file was deleted.

src/components/ConnectToDB/i18n/en.json

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"documentation": "Documentation",
66

77
"close": "Close",
8-
"copy": "Copy",
98

109
"docs_bash": "https://ydb.tech/docs/en/concepts/connect",
1110
"docs_cpp": "https://ydb.tech/docs/en/dev/example-app/example-cpp",

src/components/ConnectToDB/ConnectToDBSyntaxHighlighter/ConnectToDBSyntaxHighlighter.scss src/components/SyntaxHighlighter/YDBSyntaxHighlighter.scss

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
@use '../../../styles/mixins.scss';
1+
@use '../../styles/mixins.scss';
22

3-
.ydb-connect-to-db-syntax-highlighter {
4-
&__wrapper {
5-
position: relative;
6-
z-index: 0;
3+
.ydb-syntax-highlighter {
4+
position: relative;
5+
z-index: 0;
76

8-
height: 100%;
9-
}
7+
height: 100%;
108

119
&__sticky-container {
1210
z-index: 1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import React from 'react';
2+
3+
import {ClipboardButton} from '@gravity-ui/uikit';
4+
import {nanoid} from '@reduxjs/toolkit';
5+
import {PrismLight as ReactSyntaxHighlighter} from 'react-syntax-highlighter';
6+
7+
import i18n from './i18n';
8+
import {b} from './shared';
9+
import {useSyntaxHighlighterStyle} from './themes';
10+
import type {Language} from './types';
11+
import {yql} from './yql';
12+
13+
import './YDBSyntaxHighlighter.scss';
14+
15+
async function registerLanguage(lang: Language) {
16+
if (lang === 'yql') {
17+
ReactSyntaxHighlighter.registerLanguage('yql', yql);
18+
} else {
19+
const {default: syntax} = await import(
20+
`react-syntax-highlighter/dist/esm/languages/prism/${lang}`
21+
);
22+
ReactSyntaxHighlighter.registerLanguage(lang, syntax);
23+
}
24+
}
25+
26+
type YDBSyntaxHighlighterProps = {
27+
text: string;
28+
language: Language;
29+
className?: string;
30+
transparentBackground?: boolean;
31+
withCopy?: boolean;
32+
};
33+
34+
export function YDBSyntaxHighlighter({
35+
text,
36+
language,
37+
className,
38+
transparentBackground = true,
39+
withCopy,
40+
}: YDBSyntaxHighlighterProps) {
41+
const [highlighterKey, setHighlighterKey] = React.useState('');
42+
43+
const style = useSyntaxHighlighterStyle(transparentBackground);
44+
45+
React.useEffect(() => {
46+
async function registerLangAndUpdateKey() {
47+
await registerLanguage(language);
48+
setHighlighterKey(nanoid());
49+
}
50+
registerLangAndUpdateKey();
51+
}, [language]);
52+
53+
const renderCopyButton = () => {
54+
if (withCopy) {
55+
return (
56+
<div className={b('sticky-container')}>
57+
<ClipboardButton
58+
view="flat-secondary"
59+
size="s"
60+
className={b('copy')}
61+
text={text}
62+
>
63+
{i18n('copy')}
64+
</ClipboardButton>
65+
</div>
66+
);
67+
}
68+
69+
return null;
70+
};
71+
72+
return (
73+
<div className={b(null, className)}>
74+
{renderCopyButton()}
75+
76+
<ReactSyntaxHighlighter
77+
key={highlighterKey}
78+
language={language}
79+
style={style}
80+
customStyle={{height: '100%'}}
81+
>
82+
{text}
83+
</ReactSyntaxHighlighter>
84+
</div>
85+
);
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"copy": "Copy"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {registerKeysets} from '../../../utils/i18n';
2+
3+
import en from './en.json';
4+
5+
const COMPONENT = 'ydb-syntax-highlighter';
6+
7+
export default registerKeysets(COMPONENT, {en});
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import {lazyComponent} from '../../utils/lazyComponent';
2+
3+
export const YDBSyntaxHighlighterLazy = lazyComponent(
4+
() => import('./YDBSyntaxHighlighter'),
5+
'YDBSyntaxHighlighter',
6+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import {cn} from '../../utils/cn';
2+
3+
export const b = cn('ydb-syntax-highlighter');
+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import {useThemeValue} from '@gravity-ui/uikit';
2+
import {materialLight, vscDarkPlus} from 'react-syntax-highlighter/dist/esm/styles/prism';
3+
4+
export const lightTransparent = {
5+
...materialLight,
6+
'pre[class*="language-"]': {
7+
...materialLight['pre[class*="language-"]'],
8+
background: 'transparent',
9+
margin: 0,
10+
},
11+
'code[class*="language-"]': {
12+
...materialLight['code[class*="language-"]'],
13+
background: 'transparent',
14+
color: 'var(--g-color-text-primary)',
15+
whiteSpace: 'pre-wrap' as const,
16+
},
17+
comment: {
18+
color: '#969896',
19+
},
20+
string: {
21+
color: '#a31515',
22+
},
23+
tablepath: {
24+
color: '#338186',
25+
},
26+
function: {
27+
color: '#7a3e9d',
28+
},
29+
udf: {
30+
color: '#7a3e9d',
31+
},
32+
type: {
33+
color: '#4d932d',
34+
},
35+
boolean: {
36+
color: '#608b4e',
37+
},
38+
constant: {
39+
color: '#608b4e',
40+
},
41+
variable: {
42+
color: '#001188',
43+
},
44+
};
45+
46+
export const darkTransparent = {
47+
...vscDarkPlus,
48+
'pre[class*="language-"]': {
49+
...vscDarkPlus['pre[class*="language-"]'],
50+
background: 'transparent',
51+
margin: 0,
52+
},
53+
'code[class*="language-"]': {
54+
...vscDarkPlus['code[class*="language-"]'],
55+
background: 'transparent',
56+
color: 'var(--g-color-text-primary)',
57+
whiteSpace: 'pre-wrap' as const,
58+
},
59+
comment: {
60+
color: '#969896',
61+
},
62+
string: {
63+
color: '#ce9178',
64+
},
65+
tablepath: {
66+
color: '#338186',
67+
},
68+
function: {
69+
color: '#9e7bb0',
70+
},
71+
udf: {
72+
color: '#9e7bb0',
73+
},
74+
type: {
75+
color: '#6A8759',
76+
},
77+
boolean: {
78+
color: '#608b4e',
79+
},
80+
constant: {
81+
color: '#608b4e',
82+
},
83+
variable: {
84+
color: '#74b0df',
85+
},
86+
};
87+
88+
const dark: Record<string, React.CSSProperties> = {
89+
...darkTransparent,
90+
'pre[class*="language-"]': {
91+
...darkTransparent['pre[class*="language-"]'],
92+
background: vscDarkPlus['pre[class*="language-"]'].background,
93+
scrollbarColor: `var(--g-color-scroll-handle) transparent`,
94+
},
95+
'code[class*="language-"]': {
96+
...darkTransparent['code[class*="language-"]'],
97+
whiteSpace: 'pre',
98+
},
99+
};
100+
101+
const light: Record<string, React.CSSProperties> = {
102+
...lightTransparent,
103+
'pre[class*="language-"]': {
104+
...lightTransparent['pre[class*="language-"]'],
105+
background: 'var(--g-color-base-misc-light)',
106+
scrollbarColor: `var(--g-color-scroll-handle) transparent`,
107+
},
108+
'code[class*="language-"]': {
109+
...lightTransparent['code[class*="language-"]'],
110+
whiteSpace: 'pre',
111+
},
112+
};
113+
114+
export function useSyntaxHighlighterStyle(transparentBackground?: boolean) {
115+
const themeValue = useThemeValue();
116+
const isDark = themeValue === 'dark' || themeValue === 'dark-hc';
117+
118+
if (transparentBackground) {
119+
return isDark ? darkTransparent : lightTransparent;
120+
}
121+
122+
return isDark ? dark : light;
123+
}
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export type Language =
2+
| 'bash'
3+
| 'cpp'
4+
| 'csharp'
5+
| 'go'
6+
| 'java'
7+
| 'javascript'
8+
| 'php'
9+
| 'python'
10+
| 'yql';

0 commit comments

Comments
 (0)