-
-
Notifications
You must be signed in to change notification settings - Fork 927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sibling Shows unexpectedly trigger blur on sibling #1734
Comments
This is interesting. Yeah the udomdiff algorithm we moved to in march 2020, will produce the blur event. WebReflection/udomdiff#7 I will need to see which ones don't. Keeping track of focus and focus restoration seems way more brittle than looking at the reconciliation algorithm. I don't see us ever doing that because the library is not really DOM aware and focus state isn't really represented declaratively. But I will need to audit solutions. It is quite likely that they all have edge cases in this regard. Because there are performance implications this might take a while. |
I have run into this issue. When an Element is moved (that be append, insertBefore, or any other moving operation) it loses focus, there's no way around that. This is visualizable by defining a custom element, focus it and logging the For the diffing algorithm to keep the focused element focused. The focused element should become the center of gravity. Everything moves around this focused element. This is not workable, I mean, it will be too expensive that is not worthy. For example: If element 1 is focused and you move it to the bottom of a list with 10 items, then you will have to keep 1 on its place and move the other 9 items, to be able to not "touch" the focused element. There's also the issue that when you move stuff around you could be moving parents, so you will have to check the subtree Then, there's the problem if you move the focused element out of its parent (instead of changing position on the same parent). Then it will lose focus no matter what. I'm saying this because looking for a different algorithm won't be the solution and wanted to document my findings. Comes to mind const active = document.activeElement
doDiff()
active && active.focus() I don't know if this has some performance issues, but I know of some situations on where this is not as simple. Wanting to throttle that snippet, If you have a table with 10 rows, with 10 inputs and 10 select elements with options, you will have at least 11 Maybe that snippet could be used if doesnt impact performance, A wrapper for the function createMemoKeepFocus(source) {
return createMemo(() => {
const active = document.activeElement;
active && queueMicrotask(() => active.focus());
return source();
});
}
const elementsKeepFocus = createMemoKeepFocus(elements)
<For each={elementsKeepFocus()}>{props.children}</For> Browsers would probably add new APIs that consider this problem among others (frames reloading, animations restarting also affected by the same issue) whatwg/dom#1255 if someone has other ideas welcome |
Thanks for the input @titoBouzout. Yeah I remember not checking all of them but most diffing algorithms will fall down in some scenario. It isn't avoidable, and as you said focus resetting is imperfect and has other side effects. I can just picture unrelated changes on inputs suddenly moving the cursor position. I don't think there is winning here. I don't think any framework as remotely solved this unfortunately. So yeah I don't know. |
Describe the bug
When a (focusable) element is flanked by a Show component on either side, a signal triggering both Show components to true will cause the focusable element to lose focus.
Proximally this is caused by the reconcileArray logic using
replaceChild
rather than an insertion method (replacing the focusable element with one of the newly visible Shows, before putting the focusable element back in the DOM). This results in ablur
event being fired at the focusable element (and no subsequent.focus
event for it to regain focus).Your Example Website or App
https://playground.solidjs.com/anonymous/6a550f0d-b8bd-41cd-840f-491c94b2ec36
Steps to Reproduce the Bug or Issue
Expected behavior
I expect that causing (seemingly) unrelated divs to Show will not result in a blur event being fired on the element that has focus. If that is not possible, I expect the element to at least regain focus after the reconciliation is complete
Screenshots or Videos
No response
Platform
Reproduces on multiple browsers, but mine is
macOS, Chrome Version 113.0.5672.92 (Official Build) (x86_64)
, using latest SolidAdditional context
No response
The text was updated successfully, but these errors were encountered: