@@ -5,6 +5,8 @@ import JsonEditor from "./JsonEditor";
55import { updateValueAtPath } from "@/utils/jsonUtils" ;
66import { generateDefaultValue } from "@/utils/schemaUtils" ;
77import type { JsonValue , JsonSchemaType } from "@/utils/jsonUtils" ;
8+ import { useToast } from "@/lib/hooks/useToast" ;
9+ import { CheckCheck , Copy } from "lucide-react" ;
810
911interface DynamicJsonFormProps {
1012 schema : JsonSchemaType ;
@@ -31,6 +33,9 @@ const DynamicJsonForm = ({
3133 const isOnlyJSON = ! isSimpleObject ( schema ) ;
3234 const [ isJsonMode , setIsJsonMode ] = useState ( isOnlyJSON ) ;
3335 const [ jsonError , setJsonError ] = useState < string > ( ) ;
36+ const [ copiedJson , setCopiedJson ] = useState < boolean > ( false ) ;
37+ const { toast } = useToast ( ) ;
38+
3439 // Store the raw JSON string to allow immediate feedback during typing
3540 // while deferring parsing until the user stops typing
3641 const [ rawJsonValue , setRawJsonValue ] = useState < string > (
@@ -246,19 +251,55 @@ const DynamicJsonForm = ({
246251 }
247252 } , [ shouldUseJsonMode , isJsonMode ] ) ;
248253
254+ const handleCopyJson = useCallback ( ( ) => {
255+ try {
256+ navigator . clipboard
257+ . writeText ( JSON . stringify ( value , null , 2 ) ?? "[]" )
258+ . then ( ( ) => {
259+ setCopiedJson ( true ) ;
260+
261+ toast ( {
262+ title : "JSON copied" ,
263+ description :
264+ "The JSON data has been successfully copied to your clipboard." ,
265+ } ) ;
266+
267+ setTimeout ( ( ) => {
268+ setCopiedJson ( false ) ;
269+ } , 2000 ) ;
270+ } )
271+ . catch ( ( error ) => {
272+ reportError ( error ) ;
273+ } ) ;
274+ } catch ( error ) {
275+ reportError ( error ) ;
276+ }
277+ } , [ toast , value ] ) ;
278+
249279 return (
250280 < div className = "space-y-4" >
251281 < div className = "flex justify-end space-x-2" >
252282 { isJsonMode && (
253- < Button
254- type = "button"
255- variant = "outline"
256- size = "sm"
257- onClick = { formatJson }
258- >
259- Format JSON
260- </ Button >
283+ < >
284+ < Button variant = "outline" size = "sm" onClick = { handleCopyJson } >
285+ { copiedJson ? (
286+ < CheckCheck className = "h-4 w-4 mr-2" />
287+ ) : (
288+ < Copy className = "h-4 w-4 mr-2" />
289+ ) }
290+ Copy JSON
291+ </ Button >
292+ < Button
293+ type = "button"
294+ variant = "outline"
295+ size = "sm"
296+ onClick = { formatJson }
297+ >
298+ Format JSON
299+ </ Button >
300+ </ >
261301 ) }
302+
262303 { ! isOnlyJSON && (
263304 < Button variant = "outline" size = "sm" onClick = { handleSwitchToFormMode } >
264305 { isJsonMode ? "Switch to Form" : "Switch to JSON" }
0 commit comments