Skip to content

Commit 7a715f9

Browse files
committed
added coppy button
1 parent c21a1be commit 7a715f9

File tree

6 files changed

+72
-91
lines changed

6 files changed

+72
-91
lines changed

components/CodeBlock.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"use client";
2+
3+
import * as React from "react";
4+
import { cn } from "@/lib/utils";
5+
import { Button } from "@/packages/ui";
6+
7+
interface ICodeBlock extends React.HTMLAttributes<HTMLPreElement> {}
8+
9+
export async function copyToClipboardWithMeta(value: string, event?: Event) {
10+
navigator.clipboard.writeText(value);
11+
if (event) {
12+
// trackEvent(event);
13+
}
14+
}
15+
16+
export function CodeBlock({ className, children, ...props }: ICodeBlock) {
17+
const [hasCopied, setHasCopied] = React.useState(false);
18+
const preRef = React.useRef<HTMLPreElement>(null);
19+
20+
const handleClickCopy = async () => {
21+
const code = preRef.current?.textContent;
22+
if (code) {
23+
setHasCopied(true);
24+
await navigator.clipboard.writeText(code);
25+
26+
setTimeout(() => {
27+
setHasCopied(false);
28+
}, 3000);
29+
}
30+
};
31+
return (
32+
<pre
33+
className={cn(
34+
"relative overflow-x-auto rounded bg-[#282A36] mt-3 mb-6 p-4",
35+
className
36+
)}
37+
{...props}
38+
>
39+
<Button
40+
disabled={hasCopied}
41+
className="absolute top-4 right-4 z-10"
42+
size="sm"
43+
onClick={handleClickCopy}
44+
>
45+
{hasCopied ? "Copied" : "Copy"}
46+
</Button>
47+
<span ref={preRef}>{children}</span>
48+
</pre>
49+
);
50+
}

components/ComponentShowcase.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { componentConfig } from "@/config";
2-
import { H5 } from "@/packages/ui";
32
import { TabGroup, TabList, TabPanels, TabPanel, Tab } from "@headlessui/react";
43
import React, { HTMLAttributes } from "react";
5-
import { CopyButton } from "./CopyButton";
64

75
interface IComponentShowcase extends HTMLAttributes<HTMLDivElement> {
86
name: keyof typeof componentConfig.examples;
@@ -29,10 +27,7 @@ export function ComponentShowcase({ name, children }: IComponentShowcase) {
2927
</div>
3028
</TabPanel>
3129
<TabPanel>
32-
<div className="relative rounded overflow-auto">
33-
<CopyButton value={Code.toString()} />
34-
{Code}
35-
</div>
30+
<div className="relative rounded overflow-auto">{Code}</div>
3631
</TabPanel>
3732
</TabPanels>
3833
</TabGroup>

components/CopyButton.tsx

Lines changed: 0 additions & 49 deletions
This file was deleted.

components/MDX.tsx

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
"use client";
2+
13
import { H1, H2, H3, H4, H5, H6 } from "@/packages/ui";
24
import { useMDXComponent } from "next-contentlayer/hooks";
35
import React, { HTMLAttributes } from "react";
46
import { ComponentShowcase } from "./ComponentShowcase";
57
import { cn } from "@/lib/utils";
68
import { ComponentSource } from "./ComponentSource";
9+
import { CodeBlock } from "./CodeBlock";
710

811
const components = {
912
h1: H1,
@@ -18,21 +21,7 @@ const components = {
1821
),
1922
h5: H5,
2023
h6: H6,
21-
pre: ({
22-
className,
23-
children,
24-
...props
25-
}: React.HTMLAttributes<HTMLElement>) => (
26-
<pre
27-
className={cn(
28-
"overflow-x-auto rounded bg-[#282A36] mt-3 mb-6 p-4",
29-
className
30-
)}
31-
{...props}
32-
>
33-
{children}
34-
</pre>
35-
),
24+
pre: CodeBlock,
3625
code: ({
3726
className,
3827
children,

contentlayer.config.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default makeSource({
4747
u("element", {
4848
tagName: "pre",
4949
properties: {
50-
__src__: source,
50+
__src__: filePath,
5151
},
5252
children: [
5353
u("element", {
@@ -65,6 +65,8 @@ export default makeSource({
6565
],
6666
})
6767
);
68+
69+
return;
6870
}
6971

7072
if (node.name === "ComponentShowcase" && node.attributes) {
@@ -78,21 +80,13 @@ export default makeSource({
7880
const component = componentConfig.examples[name];
7981
const filePath = path.join(process.cwd(), component.filePath);
8082
const source = fs.readFileSync(filePath, "utf8");
81-
// const cleanedJSX = source
82-
// .replace(/export default function \w+\(\) \{\n?/g, "") // removes function wrapper
83-
// .replace(/return\s*\(\s*/g, "") // removes return statement
84-
// .replace(/\n\s*\);?\s*\}\s*$/g, "") // Removes closing parenthesis, semicolon, and closing brace at the end of the function
85-
// .replace(/\n\s*\n/g, "\n") // removes extra new lines
86-
// .trim()
87-
// .split("\n")
88-
// .map((line) => line.replace(/^ {4}/gm, ""))
89-
// .join("\n");
9083

9184
node.children?.push(
9285
u("element", {
9386
tagName: "pre",
9487
properties: {
9588
__src__: component.filePath,
89+
__rawString__: source,
9690
},
9791
children: [
9892
u("element", {
@@ -110,6 +104,8 @@ export default makeSource({
110104
],
111105
})
112106
);
107+
108+
return;
113109
}
114110
});
115111
return null;

types/unist.d.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { Node } from "unist-builder"
1+
import { Node } from "unist-builder";
22

33
export interface UnistNode extends Node {
4-
type: string
5-
name?: string
6-
tagName?: string
7-
value?: string
4+
type: string;
5+
name?: string;
6+
tagName?: string;
7+
value?: string;
88
attributes?: {
9-
name: string
10-
value: unknown
11-
type?: string
12-
}[]
13-
children?: UnistNode[]
14-
}
9+
name: string;
10+
value: unknown;
11+
type?: string;
12+
}[];
13+
children?: UnistNode[];
14+
}

0 commit comments

Comments
 (0)