@@ -5,6 +5,8 @@ import JsonEditor from "./JsonEditor";
5
5
import { updateValueAtPath } from "@/utils/jsonUtils" ;
6
6
import { generateDefaultValue } from "@/utils/schemaUtils" ;
7
7
import type { JsonValue , JsonSchemaType } from "@/utils/jsonUtils" ;
8
+ import { useToast } from "@/lib/hooks/useToast" ;
9
+ import { CheckCheck , Copy } from "lucide-react" ;
8
10
9
11
interface DynamicJsonFormProps {
10
12
schema : JsonSchemaType ;
@@ -31,6 +33,9 @@ const DynamicJsonForm = ({
31
33
const isOnlyJSON = ! isSimpleObject ( schema ) ;
32
34
const [ isJsonMode , setIsJsonMode ] = useState ( isOnlyJSON ) ;
33
35
const [ jsonError , setJsonError ] = useState < string > ( ) ;
36
+ const [ copiedJson , setCopiedJson ] = useState < boolean > ( false ) ;
37
+ const { toast } = useToast ( ) ;
38
+
34
39
// Store the raw JSON string to allow immediate feedback during typing
35
40
// while deferring parsing until the user stops typing
36
41
const [ rawJsonValue , setRawJsonValue ] = useState < string > (
@@ -246,19 +251,55 @@ const DynamicJsonForm = ({
246
251
}
247
252
} , [ shouldUseJsonMode , isJsonMode ] ) ;
248
253
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
+
249
279
return (
250
280
< div className = "space-y-4" >
251
281
< div className = "flex justify-end space-x-2" >
252
282
{ 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
+ </ >
261
301
) }
302
+
262
303
{ ! isOnlyJSON && (
263
304
< Button variant = "outline" size = "sm" onClick = { handleSwitchToFormMode } >
264
305
{ isJsonMode ? "Switch to Form" : "Switch to JSON" }
0 commit comments