import { cva } from "class-variance-authority";
import React, { Suspense } from "react";
import { violet } from "tailwindcss/colors";
import { customColors } from "@sparkle/lib/colors";
const SyntaxHighlighter = React.lazy(
() => import("react-syntax-highlighter/dist/esm/default-highlight")
);
export const codeInlineVariants = cva(
[
"s-mx-0.5 s-my-0.5 s-cursor-text s-rounded-md s-border s-px-1 s-py-0.5",
"s-border-border dark:s-border-border-night",
"s-text-[0.90em]",
"s-text-golden-600 dark:s-text-golden-600-night",
],
{
variants: {
variant: {
surface: ["s-bg-muted/70 dark:s-bg-muted-night/70"],
},
},
defaultVariants: {
variant: "surface",
},
}
);
export const codeBlockVariants = cva(
[
"s-mx-0.5 s-my-0.5 s-cursor-text s-rounded-md s-border s-p-2",
"s-border-border dark:s-border-border-night",
"s-text-[0.90em]",
],
{
variants: {
variant: {
surface: ["s-bg-muted/70 dark:s-bg-muted-night/70"],
},
},
defaultVariants: {
variant: "surface",
},
}
);
type CodeBlockProps = {
children?: React.ReactNode;
className?: string;
inline?: boolean;
variant?: "surface";
wrapLongLines?: boolean;
showLineNumber?: boolean;
};
export function CodeBlock({
children,
className,
inline,
variant = "surface",
wrapLongLines = false,
showLineNumber = false,
}: CodeBlockProps): JSX.Element {
const match = /language-(\w+)/.exec(className || "");
const language = match ? match[1] : "text";
const languageOverrides: { [key: string]: string } = {
jsx: "javascript",
tsx: "typescript",
py: "python",
};
const languageToUse = languageOverrides[language] || language;
const codeStyle = {
hljs: {
display: "block",
overflowX: "auto",
padding: "1em",
color: "var(--s-foreground)",
backgroundColor: "transparent",
fontSize: "0.875rem",
},
"hljs-ln": {
color: "var(--s-muted-foreground)",
fontSize: "0.75rem",
paddingRight: "1em",
textAlign: "right",
userSelect: "none",
},
"hljs-keyword": {
// function, const, let, if, return
color: violet[500],
},
"hljs-function": {
color: customColors.blue[600],
},
"hljs-title": {
// Function names
color: customColors.blue[600],
},
"hljs-built_in": {
// document, console, Date
color: customColors.golden[500],
},
"hljs-string": {
// Regular strings
color: customColors.green[500],
},
"hljs-variable": {
// Regular variables
color: "var(--s-foreground)",
},
"hljs-literal": {
// true, false, null
color: customColors.golden[500],
},
"hljs-number": {
// Numeric values
color: customColors.golden[500],
},
"hljs-comment": {
// Comments
color: customColors.golden[700],
},
"hljs-template-variable": {
// Template literal variables ${...}
color: customColors.rose[500],
},
"hljs-property": {
// Object properties
color: "var(--s-foreground)",
},
"hljs-punctuation": {
// Brackets, dots, etc
color: "var(--s-foreground)",
},
"hljs-operator": {
// =, +, -, etc
color: violet[500],
},
"hljs-method": {
// Method calls
color: customColors.blue[600],
},
"hljs-tag": {
// HTML tags
color: customColors.rose[500],
},
"hljs-name": {
// Tag names
color: customColors.rose[500],
},
"hljs-attr": {
// HTML attributes
color: customColors.golden[500],
},
"hljs-params": {
// Function parameters
color: "var(--s-foreground)",
},
// Typography styles
"hljs-emphasis": {
fontStyle: "italic",
},
"hljs-strong": {
fontWeight: "bold",
},
};
return !inline ? (
{children}
);
}