95 lines
2.6 KiB
TypeScript
95 lines
2.6 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
|
|
interface SimpleCodeEditorProps {
|
|
id: string;
|
|
initialValue?: string;
|
|
language?: 'javascript' | 'python';
|
|
onChange?: (value: string) => void;
|
|
}
|
|
|
|
export function SimpleCodeEditor({
|
|
id,
|
|
initialValue = '',
|
|
language = 'javascript',
|
|
onChange
|
|
}: SimpleCodeEditorProps) {
|
|
const [code, setCode] = useState(initialValue);
|
|
const [copySuccess, setCopySuccess] = useState(false);
|
|
|
|
// 复制代码到剪贴板
|
|
const copyToClipboard = () => {
|
|
navigator.clipboard.writeText(code).then(() => {
|
|
setCopySuccess(true);
|
|
setTimeout(() => setCopySuccess(false), 2000);
|
|
});
|
|
};
|
|
|
|
// 处理代码变化
|
|
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
const value = e.target.value;
|
|
setCode(value);
|
|
if (onChange) {
|
|
onChange(value);
|
|
}
|
|
};
|
|
|
|
// 更新初始值
|
|
useEffect(() => {
|
|
if (initialValue !== undefined) {
|
|
setCode(initialValue);
|
|
}
|
|
}, [initialValue]);
|
|
|
|
return (
|
|
<div>
|
|
<div className="code-editor-wrapper">
|
|
<div className="code-editor-header">
|
|
<div className="code-editor-filename">{language === 'javascript' ? 'script.js' : 'script.py'}</div>
|
|
<div className="code-editor-actions">
|
|
<button
|
|
className="bg-transparent border-0 p-0 cursor-pointer"
|
|
title="复制代码"
|
|
onClick={copyToClipboard}
|
|
onKeyDown={(e) => {
|
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
copyToClipboard();
|
|
}
|
|
}}
|
|
aria-label="复制代码"
|
|
tabIndex={0}
|
|
>
|
|
<i className="ri-file-copy-line"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div className="code-editor-container">
|
|
<textarea
|
|
id={id}
|
|
className="code-editor-textarea"
|
|
value={code}
|
|
onChange={handleChange}
|
|
placeholder="请输入自定义代码"
|
|
style={{
|
|
fontFamily: 'Consolas, Monaco, Courier New, monospace',
|
|
fontSize: '14px',
|
|
lineHeight: '1.5',
|
|
padding: '12px',
|
|
width: '100%',
|
|
height: '400px',
|
|
backgroundColor: '#272822',
|
|
color: '#f8f8f2',
|
|
border: 'none',
|
|
resize: 'vertical',
|
|
tabSize: '4'
|
|
}}
|
|
></textarea>
|
|
</div>
|
|
</div>
|
|
{copySuccess && (
|
|
<div className="code-copy-success show">
|
|
代码已复制到剪贴板
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|