custom row renderer to allow for clickable links

This commit is contained in:
Lee 2024-04-18 10:56:57 +01:00
parent b4d3e4002d
commit 2040710f05
2 changed files with 51 additions and 1 deletions

@ -14,12 +14,62 @@ type CodeHighlighterProps = {
rounded?: boolean; rounded?: boolean;
}; };
import createElement from "react-syntax-highlighter/dist/esm/create-element";
/**
* 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 { export function CodeHighlighter({ code, rounded = true }: CodeHighlighterProps): ReactElement {
return ( return (
<SyntaxHighlighter <SyntaxHighlighter
language="json" language="json"
style={atomOneDark} style={atomOneDark}
wrapLongLines wrapLongLines
renderer={rowRenderer}
customStyle={{ customStyle={{
maxHeight: "600px", maxHeight: "600px",
backgroundColor: "hsl(var(--popover))", backgroundColor: "hsl(var(--popover))",

@ -49,7 +49,7 @@ export function LookupPlayer({ currentPlayer }: PlayerLookupProps): ReactElement
description: (err as Error).message, description: (err as Error).message,
duration: 5000, duration: 5000,
}); });
return setLoading(false); return;
} }
}; };