Open alivingspirit opened 2 years ago
Hmm this is a tricky issue. There aren't any solutions that don't involve reading the DOM on set, which is terrible for performance. So it's hard to have that the default behavior for any text.
I checked, Svelte does do this check. (set_data looks at wholeText
)
Vue appears to as well: https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgaW5wdXQgPSByZWYoJ0hlbGxvIFdvcmxkIScpXG5cbmZ1bmN0aW9uIGluY3JlbWVudChlKSB7XG4gIGlucHV0LnZhbHVlID0gZS50YXJnZXQudGV4dENvbnRlbnQ7XG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8ZGl2IGNvbnRlbnRlZGl0YWJsZSBAaW5wdXQ9XCJpbmNyZW1lbnRcIj57e2lucHV0fX08L2Rpdj5cbiAgICA8ZGl2PlxuICAgICAge3tpbnB1dH19XG4gICAgPC9kaXY+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==
Preact doesn't do the check for children, but does for dangerouslySetInnerHTML
: https://github.com/preactjs/preact/issues/2691
Inferno doesn't do the check for children, but does for dangerouslySetInnerHTML
or if you set a special flag on the element.
React doesn't do the check with children or dangerouslySetInnerHTML
Solid doesn't do the check with children or innerHTML
All the VDOM libraries suggest doing some form of uncontrolled as it is the most performant. The simplest version with Solid is: https://playground.solidjs.com/?hash=-1000230651&version=1.3.9
It wouldn't be too hard.. to check innerHTML
, and using that is already a de-opt so maybe it's fine. It also might be just worth documenting and leaving as is.
That's actually the normal browser behavior. You can use the getSelectionRange/setSelectionRange API to fix the cursor position after input manually (be sure to calculate the correct position if you added something before the cursor).
@atk @ryansolid Thank you for the detailed response. I think one of or a combination of these options will work for my use case.
Ok not sure what we do with this. But I think no action for now. This probably is worth documenting if there is a logical place. But it is really specific to contenteditable. Maybe this issue issue is enough until we find a home. @Jutanium any thoughts?
I think a selection primitive might be a solution. It's on my todo list, but not too far up.
Yeah, I ran into this problem as a Solid beginner, and I think this is something we can add to the FAQ section, or into a guide on the new docs site.
It might interest you that a PR for a selection primitive just landed in @solid-primitives, soon to be released. You'll be able to use it like this:
const [selection, setSelection] = createSelection();
createEffect(() => {
// store selection
const selected = selection();
// writing html will break the selection
div.innerHTML = html();
// restore the selection
setSelection(selected);
});
@solid-primitives/selection
is now published, so you can use it.
Amazing! Thank you.
Do the solidJS selection primitives work around when a component resides within a Shadow Root? In the research/prototyping I did, browsers behave differently using the Selection API in these cases. Does SolidJS get around this somehow?
I don't have a specific workaround. Can you provide a test case to make sure I'm not missing something?
When you try to update the content of a contentEditable div or other element the cursor position resets to 0. This makes it impossible to type anything using signals. I'm pretty sure this is not the correct behavior although all my searching does not produce a workaround.
Here is the example. Try to type in the box. https://playground.solidjs.com/?hash=-1236695707&version=1.1.1