Files
2025-04-10 02:06:56 +08:00

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>
);
}