Skip to content

Commit fbe1a71

Browse files
committed
chore: update DEFAULT JSON
1 parent 3ed493b commit fbe1a71

File tree

4 files changed

+66
-36
lines changed

4 files changed

+66
-36
lines changed

eslint.config.mjs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ export default [
55
{
66
rules: {
77
// 将空行限制为一行
8-
'no-multiple-empty-lines': ['error', { 'max': 1, 'maxEOF': 0, 'maxBOF': 0 }],
8+
'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0, maxBOF: 0 }],
99
// --- 新增或修改以下规则来处理 JSX 标签内的空格 ---
1010
'react/jsx-tag-spacing': [
1111
'error',
1212
{
13-
'closingSlash': 'never', // 不允许在自闭合标签的斜杠前有空格 (<img /> 而不是 <img /> )
14-
'beforeSelfClosing': 'always', // 自闭合标签的斜杠前必须有空格 (<img /> 而不是 <img/>)
15-
'afterOpening': 'never', // 开标签 > 之前不允许有空格 (<p> 而不是 <p >)
16-
'beforeClosing': 'never' // 闭合标签 < 之前不允许有空格 (</p> 而不是 < /p>)
17-
}
18-
]
19-
}
20-
}
13+
closingSlash: 'never', // 不允许在自闭合标签的斜杠前有空格 (<img /> 而不是 <img /> )
14+
beforeSelfClosing: 'always', // 自闭合标签的斜杠前必须有空格 (<img /> 而不是 <img/>)
15+
afterOpening: 'never', // 开标签 > 之前不允许有空格 (<p> 而不是 <p >)
16+
beforeClosing: 'never', // 闭合标签 < 之前不允许有空格 (</p> 而不是 < /p>)
17+
},
18+
],
19+
},
20+
},
2121
];

src/components/JsonFormatter.tsx

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useState, useCallback } from 'react';
22
import Editor from '@monaco-editor/react';
3+
import { DEFAULT_JSON } from '../constants';
34
import './JsonFormatter.less';
45

56
interface JsonFormatterProps {
@@ -8,23 +9,7 @@ interface JsonFormatterProps {
89
}
910

1011
const 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-
"email": "[email protected]"
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 },

src/constants/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export const DEFAULT_JSON = `{
2+
"name": "JSON Formatter",
3+
"version": "1.0.0",
4+
"description": "A beautiful JSON formatting tool",
5+
"author": "const",
6+
"site": "https://json.const.site",
7+
"blog": "https://blog.luckfunc.com",
8+
"features": [
9+
"format",
10+
"minify",
11+
"validate",
12+
"copy",
13+
"download",
14+
"auto-format"
15+
],
16+
"config": {
17+
"theme": "auto",
18+
"autoFormat": true,
19+
"lineNumbers": true
20+
},
21+
"meta": {
22+
"created": "2025",
23+
"license": "MIT",
24+
"repository": "https://github.com/luckfunc/json-formatter"
25+
}
26+
}`;

vite.config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { defineConfig } from 'vite'
2-
import react from '@vitejs/plugin-react'
1+
import { defineConfig } from 'vite';
2+
import react from '@vitejs/plugin-react';
33

44
// https://vitejs.dev/config/
55
export default defineConfig({
66
plugins: [react()],
7-
})
7+
});

0 commit comments

Comments
 (0)