Issue
<div contentEditable>
<svg viewBox='0 0 300 300'>
<text x=2 y=40>
Can this be a text input field?
</text>
<text y=80>
But not this
</text>
<text y=110>
And not this
</text>
</svg>
</div>
The text in the above SVG is editable because it is wrapped in <div contentEditable>
, however for our use case this is not ideal as is:
- most importantly, we are using React and we'd like the editable text to be controlled in state.
- all text in the above SVG is editable, not just the first text field as is desired
- it is a big buggy, with the cursor going way far to the right
It is possible to create an individually controlled (with React useState
) SVG text field?
EDIT: something along these lines does appear to work:
const [test, setTest] = useState('here is some text');
// And Return
return (<>
<svg>
<foreignObject x="40" y="40" width="300" height="150">
<div xmlns="http://www.w3.org/1999/xhtml">
<FormControl
className='modal-input'
type='text'
value={test}
onChange={(e) => setTest(e.target.value)}
name='firstname'
placeholder='First Name'
/>
</div>
</foreignObject>
...
Where FormElement
is from react-bootstrap. We are going to keep working with this and see if it fits our use case fully, but so far, so good!
Solution
You can embed HTML fragments (including React portals for example) in SVG using the <foreignObject>
tag (which is specifically designed to allow HTML in SVG). BTW I think if you just want to embed some inputs into SVG, doing it using contenteditable
does not seem to make any sense. Just use normal <inputs>
<svg viewBox='0 0 300 300'>
<foreignObject x='0' y='0' width='100' height='100'>
<div contenteditable>
Can this be a text input field?
</div>
</foreignObject>
<text y='80'>
But not this
</text>
<text y='110'>
And not this
</text>
</svg>
Answered By - Nikolay
Answer Checked By - - Pedro (ReactFix Volunteer)