import { useCallback, useMemo } from 'react' import reactSyntaxHighlighter, { Light as SyntaxHighlighter } from 'react-syntax-highlighter' import monokaiCustomTheme from 'data/CodeEditorTheme' import CodeBlockStyles from './CodeBlock.module.css' import { Button, IconCopy } from '@supabase/ui' import CopyToClipboard from 'react-copy-to-clipboard' import rangeParser from 'parse-numeric-range' import classNames from 'classnames' import js from 'react-syntax-highlighter/dist/cjs/languages/hljs/javascript' import ts from 'react-syntax-highlighter/dist/cjs/languages/hljs/typescript' import py from 'react-syntax-highlighter/dist/cjs/languages/hljs/python' import sql from 'react-syntax-highlighter/dist/cjs/languages/hljs/sql' export interface CodeBlockProps { lang: 'js' | 'ts' | 'sql' | 'py' startingLineNumber?: number hideCopy?: boolean className?: string children?: string size?: 'small' | 'medium' | 'large' /** * Inline styling * Supports CSS Properties in camelcase */ style?: React.CSSProperties | undefined /** * Lines to be highlighted. * Supports individual lines: '14', multiple lines: '14,15', or a range of lines '14..19' */ highlightLines?: string hideBorder?: boolean } function CodeBlock(props: CodeBlockProps) { let lang = props.lang ? props.lang : props.className ? props.className.replace('language-', '') : 'js' // force jsx to be js highlighted if (lang === 'jsx') lang = 'js' if (lang === 'tsx') lang = 'ts' SyntaxHighlighter.registerLanguage('js', js) SyntaxHighlighter.registerLanguage('ts', ts) SyntaxHighlighter.registerLanguage('py', py) SyntaxHighlighter.registerLanguage('sql', sql) // const large = props.size === 'large' ? true : false const large = false const shouldHighlightLines = props.highlightLines !== undefined const highlightLines = useMemo( () => new Set(rangeParser(props.highlightLines ?? '')), [props.highlightLines] ) const lineProps = useCallback( (lineNumber: number) => { const shouldHighlightLine = !shouldHighlightLines || highlightLines.has(lineNumber) const style = shouldHighlightLine ? {} : { filter: 'grayscale(75%)', opacity: 0.5 } return { className: classNames( CodeBlockStyles['code-line'], shouldHighlightLines && shouldHighlightLine && CodeBlockStyles['code-line--flash'] ), style, } }, [highlightLines] ) return (