Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.

Commit 7925ab2

Browse files
committed
add copy buttons to editor
1 parent 6f76cab commit 7925ab2

File tree

4 files changed

+33
-34
lines changed

4 files changed

+33
-34
lines changed

packages/react-databrowser/src/components/databrowser/components/display/display-list-edit.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ const FormItem = ({ name, label }: { name: string; label: string; isNumber?: boo
126126
name,
127127
form,
128128
isEditorDynamic: true,
129+
showCopyButton: true,
129130
})
130131

131132
return (

packages/react-databrowser/src/components/databrowser/components/display/input/custom-editor.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ import { useEffect, useRef } from "react"
22
import { Editor, useMonaco } from "@monaco-editor/react"
33

44
import { cn } from "@/lib/utils"
5+
import { CopyButton } from "@/components/databrowser/copy-button"
56

67
export const CustomEditor = ({
78
language,
89
value,
910
onChange,
1011
maxDynamicHeight,
12+
showCopyButton,
1113
}: {
1214
language: string
1315
value: string
1416
onChange: (value: string) => void
1517
maxDynamicHeight?: number
18+
showCopyButton?: boolean
1619
}) => {
1720
const monaco = useMonaco()
1821
const editorRef = useRef()
@@ -28,7 +31,7 @@ export const CustomEditor = ({
2831

2932
return (
3033
<div
31-
className={cn(maxDynamicHeight === undefined && "h-full p-2")}
34+
className={cn("relative", maxDynamicHeight === undefined && "h-full p-2")}
3235
style={{
3336
height: maxDynamicHeight,
3437
}}
@@ -68,6 +71,11 @@ export const CustomEditor = ({
6871
renderLineHighlight: "none",
6972
}}
7073
/>
74+
{showCopyButton && (
75+
<div className="absolute right-0 top-0">
76+
<CopyButton value={value} />
77+
</div>
78+
)}
7179
</div>
7280
)
7381
}

packages/react-databrowser/src/components/databrowser/components/display/input/use-field.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ export const useField = ({
88
name,
99
form,
1010
isEditorDynamic = false,
11+
showCopyButton,
1112
}: {
1213
name: string
1314
form: UseFormReturn<any>
1415
isEditorDynamic?: boolean
16+
showCopyButton?: boolean
1517
}) => {
1618
const { field, fieldState } = useController<Record<string, string>>({
1719
name,
@@ -57,6 +59,7 @@ export const useField = ({
5759
value={field.value}
5860
onChange={field.onChange}
5961
maxDynamicHeight={isEditorDynamic ? 100 : undefined}
62+
showCopyButton={showCopyButton}
6063
/>
6164
</>
6265
),

packages/react-databrowser/src/components/databrowser/copy-button.tsx

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,41 @@
11
import { useState } from "react"
2-
import { CheckIcon } from "@radix-ui/react-icons"
2+
import { IconCheck, IconCopy } from "@tabler/icons-react"
33

4+
import { cn } from "@/lib/utils"
45
import { Button } from "@/components/ui/button"
56

67
interface Props extends React.HTMLAttributes<HTMLButtonElement> {
7-
onCopy: () => void
88
sizeVariant?: "icon-sm" | "icon-xs"
99
svgSize?: { w: number; h: number }
1010
variant?: "outline" | "default" | "ghost"
11+
value: string
1112
}
1213

1314
export function CopyButton({
14-
onCopy,
15+
value,
1516
sizeVariant = "icon-sm",
1617
variant = "outline",
17-
svgSize,
1818
className,
1919
}: Props) {
2020
const [copied, setCopied] = useState(false)
2121

22-
const handleCopy = () => {
23-
setCopied(true)
24-
onCopy()
25-
setTimeout(() => {
26-
setCopied(false)
27-
}, 1500)
28-
}
29-
3022
return (
31-
<Button size={sizeVariant} variant={variant} onClick={handleCopy} className={className}>
32-
{copied ? (
33-
<CheckIcon className="size-4" />
34-
) : (
35-
<svg
36-
width={svgSize?.w ?? 15}
37-
height={svgSize?.h ?? 15}
38-
viewBox="0 0 22 22"
39-
fill="none"
40-
xmlns="http://www.w3.org/2000/svg"
41-
>
42-
<path
43-
d="M14.3333 7.66683V6.00016C14.3333 5.55814 14.1577 5.13421 13.8451 4.82165C13.5325 4.50909 13.1086 4.3335 12.6666 4.3335H5.99992C5.55789 4.3335 5.13397 4.50909 4.82141 4.82165C4.50885 5.13421 4.33325 5.55814 4.33325 6.00016V12.6668C4.33325 13.1089 4.50885 13.5328 4.82141 13.8453C5.13397 14.1579 5.55789 14.3335 5.99992 14.3335H7.66659M7.66659 9.3335C7.66659 8.89147 7.84218 8.46755 8.15474 8.15499C8.4673 7.84242 8.89122 7.66683 9.33325 7.66683H15.9999C16.4419 7.66683 16.8659 7.84242 17.1784 8.15499C17.491 8.46755 17.6666 8.89147 17.6666 9.3335V16.0002C17.6666 16.4422 17.491 16.8661 17.1784 17.1787C16.8659 17.4912 16.4419 17.6668 15.9999 17.6668H9.33325C8.89122 17.6668 8.4673 17.4912 8.15474 17.1787C7.84218 16.8661 7.66659 16.4422 7.66659 16.0002V9.3335Z"
44-
strokeOpacity="0.4"
45-
stroke="currentColor"
46-
strokeWidth="1.5"
47-
strokeLinecap="round"
48-
strokeLinejoin="round"
49-
/>
50-
</svg>
51-
)}
23+
<Button
24+
size={sizeVariant}
25+
variant={variant}
26+
onClick={(e) => {
27+
setCopied(true)
28+
handleCopyClick(value)
29+
setTimeout(() => {
30+
setCopied(false)
31+
}, 1500)
32+
navigator.clipboard.writeText(value)
33+
e.stopPropagation()
34+
e.preventDefault()
35+
}}
36+
className={cn("text-zinc-500", className)}
37+
>
38+
{copied ? <IconCheck size={14} /> : <IconCopy size={14} />}
5239
</Button>
5340
)
5441
}

0 commit comments

Comments
 (0)