import { Transition } from "@headlessui/react";
import { ClipboardDocumentIcon, CheckIcon } from "@heroicons/react/24/outline";
import clsx from "clsx";
import { useMemo, useCallback, type HTMLAttributes } from "react";
import { useEffect, useState } from "react";
import type { OffsetOrPosition } from "shiki";
import style from "./style.module.css";
import type { SupportedLanguage } from "./supported-language";
import { useHighlightedCode } from "./use-highlighted-code";
import { getLogger } from "../../browser-logger";
import { Button } from "../Button";
export * from "./supported-language";
type CodeProps = {
language?: SupportedLanguage | undefined;
children: string;
dimRange?: readonly [OffsetOrPosition, OffsetOrPosition] | undefined;
};
export const Code = ({ language, children, dimRange }: CodeProps) => {
const chompedCode = useMemo(() => chomp(children), [children]);
return (
{chompedCode}
{chompedCode}
);
};
const chomp = (text: string) => {
const splitText = text.split("\n");
const firstNonemptyLine = splitText.findIndex((line) => line.trim() !== "");
const lastNonemptyLine = splitText.findLastIndex(
(line) => line.trim() !== "",
);
return splitText.slice(firstNonemptyLine, lastNonemptyLine + 1).join("\n");
};
type CopyButtonProps = Omit, "children"> & {
children: string;
};
const CopyButton = ({ children, className, ...props }: CopyButtonProps) => {
const [isCopied, setIsCopied] = useState(false);
const copy = useCallback(() => {
navigator.clipboard
.writeText(children)
.then(() => {
setIsCopied(true);
})
.catch((error: unknown) => {
/* TODO do something here? */
getLogger().error(error);
});
}, [children]);
useEffect(() => {
setIsCopied(false);
}, [children]);
useEffect(() => {
if (isCopied) {
const timeout = setTimeout(() => {
setIsCopied(false);
}, 2000);
return () => {
clearTimeout(timeout);
};
} else {
return;
}
}, [isCopied]);
return (
);
};
type HighlightedCodeProps = Omit, "children"> & {
language?: SupportedLanguage | undefined;
children: string;
dimRange?: readonly [OffsetOrPosition, OffsetOrPosition] | undefined;
};
const HighlightedCode = ({
language,
children,
dimRange,
className,
...props
}: HighlightedCodeProps) => {
const highlightedCode = useHighlightedCode(language, children, dimRange);
return (
{children.split("\n").map((line, i) => (
{line}
))}
),
})}
/>
);
};