github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/components/CodeBlock/index.tsx (about) 1 import CopyToClipboard, { CopyToClipboardProvider } from "../CopyToClipboard"; 2 import hcl from "react-syntax-highlighter/dist/esm/languages/prism/hcl"; 3 import json from "react-syntax-highlighter/dist/esm/languages/prism/json"; 4 import sql from "react-syntax-highlighter/dist/esm/languages/prism/sql"; 5 import { classNames } from "../../utils/styles"; 6 import { PrismLight as SyntaxHighlighter } from "react-syntax-highlighter"; 7 import { ThemeNames } from "../../hooks/useTheme"; 8 import { useDashboard } from "../../hooks/useDashboard"; 9 import { useMemo, useState } from "react"; 10 import { 11 vs, 12 vscDarkPlus, 13 } from "react-syntax-highlighter/dist/esm/styles/prism"; 14 15 SyntaxHighlighter.registerLanguage("hcl", hcl); 16 SyntaxHighlighter.registerLanguage("json", json); 17 SyntaxHighlighter.registerLanguage("sql", sql); 18 19 type CodeBlockProps = { 20 children: string; 21 copyToClipboard?: boolean; 22 language?: "hcl" | "json" | "sql"; 23 style?: any; 24 }; 25 26 const CodeBlock = ({ 27 children, 28 copyToClipboard = true, 29 language = "sql", 30 style = {}, 31 }: CodeBlockProps) => { 32 const [showCopyIcon, setShowCopyIcon] = useState(false); 33 const { 34 themeContext: { theme }, 35 } = useDashboard(); 36 37 const styles = useMemo(() => { 38 const commonStyles = { 39 fontFamily: 40 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace', 41 fontSize: "13px", 42 lineHeight: 1.5, 43 margin: 0, 44 }; 45 if (theme.name === ThemeNames.STEAMPIPE_DARK) { 46 return { 47 ...vscDarkPlus, 48 'code[class*="language-"]': { 49 ...vscDarkPlus['code[class*="language-"]'], 50 ...commonStyles, 51 }, 52 'pre[class*="language-"]': { 53 ...vscDarkPlus['pre[class*="language-"]'], 54 ...commonStyles, 55 }, 56 }; 57 } else { 58 return { 59 ...vs, 60 'code[class*="language-"]': { 61 ...vs['code[class*="language-"]'], 62 ...commonStyles, 63 }, 64 'pre > code[class*="language-"]': { 65 ...vs['pre > code[class*="language-"]'], 66 ...commonStyles, 67 }, 68 'pre[class*="language-"]': { 69 ...vs['pre[class*="language-"]'], 70 border: "none", 71 ...commonStyles, 72 }, 73 }; 74 } 75 }, [theme.name]); 76 77 return ( 78 <CopyToClipboardProvider> 79 {({ setDoCopy }) => ( 80 <div 81 className={classNames( 82 "relative p-1", 83 copyToClipboard ? "cursor-pointer" : null, 84 copyToClipboard && showCopyIcon ? "bg-black-scale-1" : null 85 )} 86 onMouseEnter={ 87 copyToClipboard 88 ? () => { 89 setShowCopyIcon(true); 90 } 91 : undefined 92 } 93 onMouseLeave={ 94 copyToClipboard 95 ? () => { 96 setShowCopyIcon(false); 97 } 98 : undefined 99 } 100 onClick={() => setDoCopy(true)} 101 > 102 {/*@ts-ignore*/} 103 <SyntaxHighlighter 104 language={language} 105 style={styles} 106 customStyle={{ 107 padding: 0, 108 wordBreak: "break-keep", 109 background: "transparent", 110 borderRadius: "4px", 111 ...style, 112 }} 113 wrapLongLines 114 > 115 {children || ""} 116 </SyntaxHighlighter> 117 {showCopyIcon && ( 118 <div 119 className={classNames( 120 "absolute cursor-pointer z-50 right-1 top-1" 121 )} 122 > 123 <CopyToClipboard data={children} /> 124 </div> 125 )} 126 </div> 127 )} 128 </CopyToClipboardProvider> 129 ); 130 }; 131 132 export default CodeBlock;