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;