Skip to content

Commit

Permalink
Add codeblock copy button
Browse files Browse the repository at this point in the history
  • Loading branch information
slhmy committed Aug 4, 2024
1 parent 4511e9f commit a3a44f1
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 18 deletions.
49 changes: 49 additions & 0 deletions src/components/markdown/MarkdownRender.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import ReactMarkdown from "react-markdown";
import rehypeKatex from "rehype-katex";
import rehypeMathjax from "rehype-mathjax";
import remarkMath from "remark-math";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { coy } from "react-syntax-highlighter/dist/esm/styles/prism";
import copy from "copy-to-clipboard";

interface MarkdownRenderProps {
content: string;
Expand All @@ -23,8 +26,54 @@ const MarkdownRender: React.FC<MarkdownRenderProps> = (props) => {
children={props.content}
remarkPlugins={[remarkMath]}
rehypePlugins={getRehypePlugins()}
components={{
code({ node, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || "");
const language = match ? match[1] : "text";

return match ? (
<CodeBlock
language={language}
value={String(children)}
className={className}
/>
) : (
<code className={className} {...props}>
{children}
</code>
);
},
}}
/>
);
};

interface CodeBlockProps {
language: string;
value: string;
className?: string;
}

const CodeBlock: React.FC<CodeBlockProps> = ({
language,
value,
className,
}) => {
const handleCopy = () => {
copy(value);
};

return (
<div className="relative">
<button
onClick={handleCopy}
className="btn btn-xs absolute right-0 rounded"
>
Copy
</button>
<code className="w-full">{value}</code>
</div>
);
};

export default MarkdownRender;
30 changes: 17 additions & 13 deletions src/components/problem/ProblemTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ const ProblemTable: React.FC<ProblemTableProps> = (props) => {
<thead>
<tr className="border-base-content/10">
{columns.map((column) => {
if (column.uid === "actions" && !props.showActions) {
return null;
}
if (column.uid === "actions" && !props.showActions) return null;
return <th key={column.uid}>{column.name}</th>;
})}
</tr>
Expand All @@ -51,16 +49,7 @@ const ProblemTable: React.FC<ProblemTableProps> = (props) => {
>
<th className="w-1/3">{problemInfo.title}</th>
<td className="w-1/3">
<div className="space-x-2">
{problemInfo.tags.map((tag) => (
<div
key={tag.name}
className="badge border-0 bg-base-300 font-semibold text-base-content/80"
>
{tag.name}
</div>
))}
</div>
<ProblemTags tags={problemInfo.tags} />
</td>
{props.showActions && (
<td className="w-1/3 p-2">
Expand Down Expand Up @@ -106,6 +95,21 @@ const ProblemTable: React.FC<ProblemTableProps> = (props) => {
);
};

const ProblemTags: React.FC<{ tags: { name: string }[] }> = (props) => {
return (
<div className="space-x-2">
{props.tags.map((tag) => (
<div
key={tag.name}
className="badge border-0 bg-base-300 font-semibold text-base-content/80"
>
{tag.name}
</div>
))}
</div>
);
};

interface ActionsProps {
onClickDelete: () => void;
}
Expand Down
11 changes: 7 additions & 4 deletions src/mocks/rest/problem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,26 @@ Output a string with format: \`Hello! %s\`.
## Input
- The first line contains a string \`s\`.
The first line contains a string \`s\`.
- The length of string \`s\` is at most 100.
- The string contains only lowercase and uppercase letters.
## Output
- Output a string \`Hello! %s\`.
Output a string \`Hello! %s\`.
## Example
### Input:
\`\`\`
\`\`\`text
world!
\`\`\`
### Output:
\`\`\`
\`\`\`text
Hello! world!
\`\`\`
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Problem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const Problem: React.FC = () => {
)}

<div className="flex flex-1 flex-col gap-6 sm:flex-row">
<div className="bo w-full flex-1 rounded border border-base-content/10 bg-base-100 p-4">
<div className="bo w-full flex-1 rounded border border-base-content/10 bg-base-100 p-6">
<h1 className="mb-8 text-4xl font-bold">{getProblem()?.title}</h1>
<MarkdownRender
content={getProblem()?.description || ""}
Expand Down

0 comments on commit a3a44f1

Please sign in to comment.