11import React , { useState , useCallback } from 'react' ;
22import Editor from '@monaco-editor/react' ;
3+ import { DEFAULT_JSON } from '../constants' ;
34import './JsonFormatter.less' ;
45
56interface JsonFormatterProps {
@@ -8,23 +9,7 @@ interface JsonFormatterProps {
89}
910
1011const JsonFormatter : React . FC < JsonFormatterProps > = ( { isDarkMode, onThemeChange } ) => {
11- const [ inputJson , setInputJson ] = useState ( `{
12- "name": "JSON Formatter",
13- "version": "1.0.0",
14- "description": "A beautiful JSON formatting tool",
15- "features": ["format", "minify", "validate", "copy", "download"],
16- "author": {
17- "name": "Developer",
18- 19- },
20- "nested": {
21- "level1": {
22- "level2": {
23- "data": "deeply nested value"
24- }
25- }
26- }
27- }` ) ;
12+ const [ inputJson , setInputJson ] = useState ( DEFAULT_JSON ) ;
2813 const [ outputJson , setOutputJson ] = useState ( '' ) ;
2914 const [ error , setError ] = useState ( '' ) ;
3015 const [ success , setSuccess ] = useState ( '' ) ;
@@ -44,6 +29,25 @@ const JsonFormatter: React.FC<JsonFormatterProps> = ({ isDarkMode, onThemeChange
4429 }
4530 } , [ inputJson ] ) ;
4631
32+ const handleInputChange = useCallback ( ( value : string | undefined ) => {
33+ const newValue = value || '' ;
34+ setInputJson ( newValue ) ;
35+
36+ // Auto-format on paste if it's valid JSON
37+ try {
38+ const parsed = JSON . parse ( newValue ) ;
39+ const formatted = JSON . stringify ( parsed , null , 2 ) ;
40+ setOutputJson ( formatted ) ;
41+ setError ( '' ) ;
42+ } catch {
43+ // Don't show error for partial input while typing
44+ if ( newValue . trim ( ) ) {
45+ setError ( '' ) ;
46+ setOutputJson ( '' ) ;
47+ }
48+ }
49+ } , [ ] ) ;
50+
4751 const minifyJson = useCallback ( ( ) => {
4852 try {
4953 const parsed = JSON . parse ( inputJson ) ;
@@ -72,7 +76,7 @@ const JsonFormatter: React.FC<JsonFormatterProps> = ({ isDarkMode, onThemeChange
7276 await navigator . clipboard . writeText ( outputJson ) ;
7377 setSuccess ( 'Copied to clipboard!' ) ;
7478 setTimeout ( ( ) => setSuccess ( '' ) , 3000 ) ;
75- } catch ( err ) {
79+ } catch {
7680 setError ( 'Failed to copy to clipboard' ) ;
7781 }
7882 }
@@ -105,29 +109,29 @@ const JsonFormatter: React.FC<JsonFormatterProps> = ({ isDarkMode, onThemeChange
105109 < div className = { `controls-bar ${ themeClass } ` } >
106110 < div className = "button-group" >
107111 < button className = { `button primary ${ themeClass } ` } onClick = { formatJson } >
108- fmt
112+ format
109113 </ button >
110114 < button className = { `button ${ themeClass } ` } onClick = { minifyJson } >
111- min
115+ minify
112116 </ button >
113117 < button
114118 className = { `button ${ themeClass } ` }
115119 onClick = { copyToClipboard }
116120 disabled = { ! outputJson }
117121 >
118- cp
122+ copy
119123 </ button >
120124 < button
121125 className = { `button ${ themeClass } ` }
122126 onClick = { downloadJson }
123127 disabled = { ! outputJson }
124128 >
125- dl
129+ download
126130 </ button >
127131 </ div >
128132 < div className = "theme-controls" >
129133 < button className = { `button danger ${ themeClass } ` } onClick = { clearAll } >
130- clr
134+ clear
131135 </ button >
132136 < button className = { `button theme-button ${ themeClass } ` } onClick = { toggleTheme } >
133137 { isDarkMode ? '☀️' : '🌙' }
@@ -145,7 +149,7 @@ const JsonFormatter: React.FC<JsonFormatterProps> = ({ isDarkMode, onThemeChange
145149 height = "100%"
146150 defaultLanguage = "json"
147151 value = { inputJson }
148- onChange = { ( value ) => setInputJson ( value || '' ) }
152+ onChange = { handleInputChange }
149153 theme = { isDarkMode ? 'vs-dark' : 'vs' }
150154 options = { {
151155 minimap : { enabled : false } ,
0 commit comments