This commit is contained in:
parent
b774f9cbf4
commit
f4b3104a1b
78
frontend/src/components/TextNode.jsx
Normal file
78
frontend/src/components/TextNode.jsx
Normal file
@ -0,0 +1,78 @@
|
||||
import { useRef, useEffect } from 'react';
|
||||
import { Handle, Position } from 'reactflow';
|
||||
import ReactQuill from 'react-quill-new';
|
||||
import 'react-quill-new/dist/quill.snow.css';
|
||||
import '../styles/quill-dark.css';
|
||||
|
||||
function TextNode({ data }) {
|
||||
const quillRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const editor = quillRef.current?.getEditor?.();
|
||||
const editorRoot = editor?.root;
|
||||
|
||||
if (editorRoot) {
|
||||
const stopKey = (e) => {
|
||||
// fix for spacebar and prevent ReactFlow stealing key
|
||||
if (e.key === ' ' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
editorRoot.addEventListener('keydown', stopKey);
|
||||
return () => {
|
||||
editorRoot.removeEventListener('keydown', stopKey);
|
||||
};
|
||||
}
|
||||
}, [data.editing]); // reapply listener only when editing mode is toggled
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
padding: 10,
|
||||
borderRadius: 6,
|
||||
background: '#1f1f1f',
|
||||
border: '1px solid #1f1f1f',
|
||||
minWidth: 150,
|
||||
maxWidth: 300,
|
||||
overflowWrap: 'break-word',
|
||||
whiteSpace: 'normal',
|
||||
}}
|
||||
>
|
||||
<Handle type="target" position={Position.Top} />
|
||||
|
||||
{data.editing ? (
|
||||
<div
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onDoubleClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<ReactQuill
|
||||
ref={quillRef}
|
||||
value={data.value}
|
||||
onChange={data.onChange}
|
||||
theme="snow"
|
||||
style={{ background: '#1f1f1f', color: 'white', borderRadius: 6 }}
|
||||
/>
|
||||
<button
|
||||
className="btn"
|
||||
style={{ marginTop: 8, padding: '4px 10px', fontSize: 12, borderRadius: 6 }}
|
||||
onClick={data.onSave}
|
||||
>
|
||||
✅ Save
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: data.value || '<i>Double-click to edit...</i>',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Handle type="source" position={Position.Bottom} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TextNode;
|
||||
Loading…
x
Reference in New Issue
Block a user