feat: code block language selection (#198)

* code block language selection

* cleanup

* Add copy button
This commit is contained in:
Philip Okugbe
2024-08-24 18:12:19 +01:00
committed by GitHub
parent 4433d5174d
commit 17475bf123
4 changed files with 85 additions and 3 deletions

View File

@ -0,0 +1,62 @@
import { NodeViewContent, NodeViewProps, NodeViewWrapper } from "@tiptap/react";
import { ActionIcon, CopyButton, Group, Select, Tooltip } from "@mantine/core";
import { useState } from "react";
import classes from "./code-block.module.css";
import { IconCheck, IconCopy } from "@tabler/icons-react";
import { useHover } from "@mantine/hooks";
export default function CodeBlockView(props: NodeViewProps) {
const { node, updateAttributes, extension, editor, selected } = props;
const { language } = node.attrs;
const [languageValue, setLanguageValue] = useState<string | null>(
language || null,
);
const { hovered, ref } = useHover();
function changeLanguage(language: string) {
setLanguageValue(language);
updateAttributes({
language: language,
});
}
return (
<NodeViewWrapper className="codeBlock" ref={ref}>
<Group justify="flex-end">
<Select
placeholder="Auto"
checkIconPosition="right"
data={extension.options.lowlight.listLanguages()}
value={languageValue}
onChange={changeLanguage}
searchable
style={{ maxWidth: "130px" }}
classNames={{ input: classes.selectInput }}
disabled={!editor.isEditable}
/>
<CopyButton value={node?.textContent} timeout={2000}>
{({ copied, copy }) => (
<Tooltip
label={copied ? "Copied" : "Copy"}
withArrow
position="right"
>
<ActionIcon
color={copied ? "teal" : "gray"}
variant="subtle"
onClick={copy}
>
{copied ? <IconCheck size={16} /> : <IconCopy size={16} />}
</ActionIcon>
</Tooltip>
)}
</CopyButton>
</Group>
<pre spellCheck="false">
<NodeViewContent as="code" className={`language-${language}`} />
</pre>
</NodeViewWrapper>
);
}

View File

@ -0,0 +1,4 @@
.selectInput {
height: 25px;
min-height: 25px;
}