Files
Frontend/src/app/components/code-highlighter.tsx
Liam 777d7bebd3
All checks were successful
Deploy App / docker (ubuntu-latest) (push) Successful in 1m2s
update code formatter background color
2024-04-19 15:51:17 +01:00

83 lines
2.0 KiB
TypeScript

import { ReactElement } from "react";
import SyntaxHighlighter from "react-syntax-highlighter";
import createElement from "react-syntax-highlighter/dist/esm/create-element";
import { atomOneDark } from "react-syntax-highlighter/dist/esm/styles/hljs";
type CodeHighlighterProps = {
/**
* The code to highlight.
*/
code: string;
/**
* Should the element be rounded?
*/
rounded?: boolean;
};
/**
* Render the rows with the ability to render links.
*
* @param rows the rows to render
* @param stylesheet the stylesheet to use
* @param useInlineStyles should inline styles be used
* @returns the rendered rows
*/
function rowRenderer({
rows,
stylesheet,
useInlineStyles,
}: {
rows: any;
stylesheet: { [key: string]: React.CSSProperties };
useInlineStyles: boolean;
}) {
return rows.map((node: any, i: number) => {
node.children = node.children.map((children: any) => {
const text = children?.children?.[0]?.value;
if (typeof text === "string" && text.startsWith('"http')) {
return {
...children,
tagName: "a",
properties: {
...children.properties,
href: text.slice(1, -1), // in JSON strings are enclosed with ", they need to be removed
target: "_blank",
// Tailwind CSS classes
class: "underline !text-primary hover:!text-muted-foreground transition-all",
},
};
}
return children;
});
return createElement({
node,
stylesheet,
useInlineStyles,
key: `code-segement${i}`,
});
});
}
export function CodeHighlighter({ code, rounded = true }: CodeHighlighterProps): ReactElement {
return (
<SyntaxHighlighter
language="json"
style={atomOneDark}
wrapLongLines
renderer={rowRenderer}
customStyle={{
maxHeight: "600px",
backgroundColor: "hsl(var(--background-accent))",
wordBreak: "break-all",
borderRadius: rounded ? "0.75rem" : undefined,
}}
>
{code}
</SyntaxHighlighter>
);
}