/*! Strand UI | MIT License | dillingerstaffing.com */ import type { JSX } from "preact"; import { forwardRef } from "preact/compat"; import { useEffect, useState } from "preact/hooks"; import { cx } from "../../internal/index.js"; export interface CodeBlockProps extends Omit, "label"> { code: string; /** Language label, e.g. "html". */ language?: string; /** Render the copy control. */ copyable?: boolean; } const COPIED_DURATION_MS = 1500; /** * Code display with a language label and copy-to-clipboard. * * @example * */ export const CodeBlock = forwardRef(({ code, language, copyable = true, className = "", ...rest }, ref) => { const [copies, setCopies] = useState(0); const copied = copies > 0; useEffect(() => { if (!copies) return; const timer = setTimeout(() => setCopies(0), COPIED_DURATION_MS); return () => clearTimeout(timer); }, [copies]); const copy = async () => { try { await navigator.clipboard.writeText(code); setCopies((n) => n + 1); } catch { // A refused clipboard is not an error the caller can act on. } }; return (
{language && {language}}
        {code}
      
{copyable && ( )}
); }); CodeBlock.displayName = "CodeBlock";