基于 @uiw/react-codemirror 封装的 json 编辑器,支持格式化和 json 语法校验
import React, { useEffect, useState } from 'react';
import { intl } from '@sc/intl';
import CodeMirror from '@uiw/react-codemirror';
import { Button } from 'antd';
import { ErrorFilled } from '@antd/icons';
import { javascript } from '@codemirror/lang-javascript';
import styles from './index.less';
interface IProps {
value: string;
/** onChange 回调, 输出 json */
onChange?: (json: string) => void;
/**占位符 */
placeholder?: string;
/**编辑器高度 */
height?: string;
/**只读模式 */
readonly?: boolean;
}
export default function JsonInput({
value = '',
placeholder,
height,
readonly,
onChange,
}: IProps) {
const [jsonString, setJsonString] = useState(value);
const [errorTips, setErrorTips] = useState('');
const verifyJson = () => {
if (jsonString === '') return;
try {
const result = JSON.stringify(JSON.parse(jsonString), null, '\t');
setErrorTips('');
return result;
} catch (error) {
setErrorTips(intl('json语法有错误,请修改'));
}
};
return (
<div className={styles['json-container']}>
<div className={styles['json-input']}>
<CodeMirror
className={styles.json}
value={jsonString}
height={height}
theme={'light'}
placeholder={placeholder}
readOnly={readonly}
extensions={[javascript({ jsx: true })]}
onChange={(value) => {
setJsonString(value);
onChange?.(value);
}}
onBlur={() => {
verifyJson();
}}
/>
{errorTips && (
<div className={styles['error-tips']}>
<ErrorFilled style={{ marginRight: '4px' }} />
{errorTips}
</div>
)}
</div>
<Button
className={styles.format}
onClick={() => {
if (typeof verifyJson() === 'string') {
setJsonString(verifyJson() as 'string');
}
}}
>
{intl('格式化')}
</Button>
</div>
);
}
.json-container {
display: flex;
width: calc(~'100% - 75px');
.json-input {
display: flex;
width: 100%;
flex-direction: column;
.json {
border: 1px solid rgba(0, 21, 64, 0.12);
border-radius: 4px;
}
.error-tips {
margin-top: 8px;
font-size: 12px;
color: #e54545;
}
}
.format {
display: inline-flex;
margin-left: 12px;
}
}