-
Notifications
You must be signed in to change notification settings - Fork 429
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
Turbo Streams: Manage element focus #686
Conversation
52bc93d
to
cba0f0a
Compare
3498c61
to
9cf77e7
Compare
9cf77e7
to
3fe69a1
Compare
3fe69a1
to
5df5038
Compare
@kevinmcconnell if you're available, this is ready for review. |
8cb3446
to
fe4a77f
Compare
@manuelpuyol @marcoroth if you're available and interested in this feature, I'd really appreciate some review! |
fe4a77f
to
a68606d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 from me for this change.
The only thing to consider, which I think is currently not supported, is something like.
<input class="input" value="a value"> <!-- this element has focus -->
and a Turbo Stream like:
<turbo-stream action="replace" targets=".input">
<template>
<input class="input" value="a new value">
</template>
</turbo-stream>
Unless I'm missing something.
I think this accounts for that with the timestamp |
Re-reading the code, those time stamps only mark autofocus elements. Without some kind of css path matching, tracking focus across anonymous elements isn't supported. |
Doesn't the timestamp generation just account for the case in Turbo Streams where you have the |
Okay yeah, that makes sense. I guess it's fine to have the requirement for an id attribute to be present. |
👍 Just to clarify, tracking focus for anonymous elements isn't currently supported either. |
76c30e1
to
0d88d96
Compare
Hi, why are you making this exception?
I imagine a case like the following. A user presses a button, and the focus stays on that button. In that case, as the document has a focused element, the autofocus attribute of the element coming from the Turbo stream would not be respected. Is this the case? In my opinion, if there is an autofocus attribute, it should be focused even if another element has the current focus. |
0d88d96
to
1ae0824
Compare
1ae0824
to
b6cdb77
Compare
b6cdb77
to
82621b1
Compare
b9cc563
to
5921ae6
Compare
5921ae6
to
0e84543
Compare
@afcapel @kevinmcconnell I've rebased this changeset to account for the migration from TypeScript. It's ready for re-review. |
a2dea62
to
aaccb97
Compare
aaccb97
to
bb3ef8b
Compare
When a `<turbo-stream>` modifies the document, it has the potential to affect which element has focus. For example, consider an element with an `[id]` that has focus: ```html <label for="an-input"> <input id="an-input" value="an invalid value"> <!-- this element has focus --> ``` Next, consider a `<turbo-stream>` element to replace it: ```html <turbo-stream action="replace" target="an-input"> <template> <input id="an-input" value="an invalid value" class="invalid-input"> </template> </turbo-stream> ``` Prior to this commit, rendering that `<turbo-stream>` would remove the element with focus, and never restore it. After this commit, the `Session` will capture the `[id]` value of the element with focus (if there is any), then "restore" focus to an element in the document with a matching `[id]` attribute _after_ the render. Similarly, consider a `<turbo-stream>` that appends an element with `[autofocus]`: ```html <turbo-stream action="append" targets="body"> <template> <input autofocus> </template> </turbo-stream> ``` Prior to this commit, inserting an `[autofocus]` into the document with a `<turbo-stream>` had no effect. After this commit, the `Session` will scan any `<turbo-stream>` elements its about to render, extracting the first focusable element that declares an `[autofocus]` attribute. Once the rendering is complete, it will attempt to autofocus that element. Several scenarios will prevent that, including: * there aren't any `[autofocus]` elements in the collection of `<turbo-stream>` elements * the `[autofocus]` element does not exist in the document after the rendering is complete * the document already has an element with focus
bb3ef8b
to
675f636
Compare
Nice one, thanks @seanpdoyle 🙏 |
Hi @seanpdoyle could happen that the processing of new messages is blocked by this addition? pd: I've replaced all the nextAnimationFrame functions for nextMicroTask() and it works! |
When a
<turbo-stream>
modifies the document, it has the potential toaffect which element has focus.
For example, consider an element with an
[id]
that has focus:Next, consider a
<turbo-stream>
element to replace it:Prior to this commit, rendering that
<turbo-stream>
would remove theelement with focus, and never restore it.
After this commit, the
Session
will capture the[id]
value of theelement with focus (if there is any), then "restore" focus to an element
in the document with a matching
[id]
attribute after the render.Similarly, consider a
<turbo-stream>
that appends an element with[autofocus]
:Prior to this commit, inserting an
[autofocus]
into the document witha
<turbo-stream>
had no effect.After this commit, the
Session
will scan any<turbo-stream>
elementsits about to render, extracting the first focusable element that
declares an
[autofocus]
attribute.Once the rendering is complete, it will attempt to autofocus that
element. Several scenarios will prevent that, including:
[autofocus]
elements in the collection of<turbo-stream>
elements[autofocus]
element does not exist in the document after therendering is complete