@rtdui/code-highlight
Version:
React code highlight component based on refractor
77 lines (74 loc) • 2.83 kB
JavaScript
'use client';
import { Fragment, jsx, jsxs } from 'react/jsx-runtime';
import { forwardRef } from 'react';
import clsx from 'clsx';
import { refractor } from 'refractor/lib/all.js';
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
import { IconClipboardCheck, IconCopy } from '@tabler/icons-react';
import { CopyButton, Tooltip, Button } from '@rtdui/core';
import { decorator } from './decorator.mjs';
const CodeHighlight = forwardRef(
(props, ref) => {
const {
code,
language = "tsx",
withCopyButton = true,
copyLabel = "Copy code",
copiedLabel = "Copied",
diff = false,
showLineNumbers = false,
highlingtLines = "",
bad = false
} = props;
const ast = refractor.highlight(code.trim(), language);
if (diff || showLineNumbers || highlingtLines) {
const meta = `${highlingtLines} ${showLineNumbers ? "showLineNumbers" : ""}`;
decorator(ast, diff, meta);
}
const elements = toJsxRuntime(ast, { Fragment, jsx: jsx, jsxs: jsxs });
return /* @__PURE__ */ jsxs("div", { ref, children: [
/* @__PURE__ */ jsxs("div", { className: "flex items-start w-full bg-(--prism-color-2)", children: [
/* @__PURE__ */ jsx("small", { className: "bg-base-300 uppercase font-bold text-xs rounded-br-md px-2 py-1", children: language }),
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
withCopyButton && bad === false && /* @__PURE__ */ jsx(CopyButton, { value: code.trim(), children: ({ copied, copy }) => /* @__PURE__ */ jsx(
Tooltip,
{
tip: copied ? copiedLabel : copyLabel,
position: "left",
color: copied ? "success" : "info",
children: /* @__PURE__ */ jsx(Button, { size: "xs", ghost: true, shape: "square", onClick: copy, children: copied ? /* @__PURE__ */ jsx(
IconClipboardCheck,
{
size: 20,
className: "stroke-success"
}
) : /* @__PURE__ */ jsx(IconCopy, { size: 20 }) })
}
) })
] }),
/* @__PURE__ */ jsx(
"pre",
{
className: clsx(`language-${language}`, "mt-0!", {
"bg-red-100!": bad === true,
"dark:bg-red-950!": bad === true
}),
"data-no-lang-indicator": language,
children: /* @__PURE__ */ jsx(
"code",
{
className: clsx(`language-${language}`, "code-highlight", {
"bg-red-100!": bad === true,
"dark:bg-red-950!": bad === true
}),
children: elements
}
)
}
)
] });
}
);
CodeHighlight.displayName = "@rtdui/CodeHighlight";
export { CodeHighlight };
//# sourceMappingURL=CodeHighlight.mjs.map