Files
gpustack-ui/src/components/highlight-code/code-viewer.tsx
T
2024-09-25 16:17:25 +08:00

93 lines
2.1 KiB
TypeScript

import classNames from 'classnames';
import hljs from 'highlight.js';
import { memo, useMemo } from 'react';
import CopyButton from '../copy-button';
import { escapeHtml } from './utils';
interface CodeViewerProps {
code: string;
lang: string;
autodetect?: boolean;
ignoreIllegals?: boolean;
copyable?: boolean;
height?: string | number;
theme?: 'light' | 'dark';
}
const CodeViewer: React.FC<CodeViewerProps> = (props) => {
const {
code,
lang,
autodetect = true,
ignoreIllegals = true,
copyable = true,
height = 'auto'
} = props || {};
const highlightedCode = useMemo(() => {
const autodetectLang = autodetect && !lang;
const cannotDetectLanguage = !autodetectLang && !hljs.getLanguage(lang);
let className = '';
if (!cannotDetectLanguage) {
className = `hljs ${lang}`;
}
// No idea what language to use, return raw code
if (cannotDetectLanguage) {
console.warn(`The language "${lang}" you specified could not be found.`);
return {
value: escapeHtml(code),
className: className
};
}
if (autodetectLang) {
const result = hljs.highlightAuto(code);
return {
value: result.value,
className: className
};
}
const result = hljs.highlight(code, {
language: lang,
ignoreIllegals: ignoreIllegals
});
return {
value: result.value,
className: className
};
}, [code, lang, autodetect, ignoreIllegals]);
return (
<pre
className={classNames(
'code-pre custome-scrollbar custom-scrollbar-horizontal ',
{
dark: props.theme === 'dark',
light: props.theme === 'light',
copyable: copyable
}
)}
style={{
height: height
}}
>
<code
className={highlightedCode.className}
dangerouslySetInnerHTML={{
__html: highlightedCode.value
}}
></code>
{copyable && (
<CopyButton
text={code}
size="small"
style={{ color: '#abb2bf' }}
></CopyButton>
)}
</pre>
);
};
export default memo(CodeViewer);