Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import { Button, cnm, IconCheck, IconCopy } from "@humansignal/ui";
import styles from "./code-block.module.scss";
import { useCopyText } from "@humansignal/core/lib/hooks/useCopyText";
 
export function CodeBlock({
  code,
  className,
  variant = "default",
  allowCopy,
}: {
  title?: string;
  description?: string;
  code: string;
  className?: string;
  variant?: "default" | "warning" | "negative";
  allowCopy?: boolean;
}) {
  const variantStyles = {
    default: "bg-neutral-surface border-neutral-border",
    warning: "bg-warning-background border-warning-border-subtle",
    negative: "bg-negative-background border-negative-border-subtle",
  };
 
  const [copyCode, isCopied] = useCopyText();
 
  return (
    <div
      className={cnm(
        "relative p-3 rounded-small border border-neutral-border text-14 text-neutral-content overflow-y-auto",
        "scrollbar-thin scrollbar-thumb-neutral-border-bold scrollbar-track-transparent",
        variantStyles[variant],
        styles["code-block-shadow"],
        className,
      )}
    >
      <pre className="whitespace-pre-wrap">{code.trim()}</pre>
      {allowCopy && (
        <Button size="small" look="string" className="absolute top-1 right-2" onClick={() => copyCode(code)}>
          {isCopied ? <IconCheck /> : <IconCopy />}
        </Button>
      )}
    </div>
  );
}