Skip to content
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

Add [method] and [scroll] attributes for Refresh Stream #1208

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

seanpdoyle
Copy link
Contributor

I have a page where I am using Turbo morph. when I submit a form and
redirect I would like to reset the scroll, but if a refresh is triggered
by a broadcast I would like to preserve teh scroll. Is that possible ?

#turbo Discord

This commit expands the set of attributes for <turbo-stream action="refresh"> to include [method] and [scroll] (in addition to [request-id]). These attributes correspond directly to the turbo-refresh-prefixed <meta> element elements that control morphing and scroll preservation.

When present on the <turbo-stream action="refresh">, their values are forward along to the Session.refresh method call, which in turn encodes them into Visit options under the refresh key. Those options are then used during Visit instantiation, and transformed into .refresh properties.

At render time, the PageRenderer attempts to read the refresh method and scroll preservation settings with the following precedence:

  1. read from the corresponding Visit.refresh property (possibly null)
  2. read from the corresponding <meta name="turbo-..."> element (possibly null)

If no value is provided, fallback to the default ({ method: "replace", scroll: "reset" }).

@seanpdoyle
Copy link
Contributor Author

@adrienpoly I've opened this in response to our conversation in Discord.

@seanpdoyle
Copy link
Contributor Author

seanpdoyle commented Feb 28, 2024

I feel that the [method] and [scroll] attributes matching the turbo-refresh-prefixed meta element [name] attributes is appropriate.

I'm less confident about the Visit options key (and resulting property name). The "public API" boundaries of Visit options are currently unclear. If we intend for these keys to be private and for internal use only, the name isn't important to decide upon. If they're intended to be public, I think it's important to workshop and appropriate name and structure.

@jorgemanrubia does this seem like a conservative enough expansion of Morph Refresh support?

@adrienpoly
Copy link
Member

@adrienpoly I've opened this in response to our conversation in Discord.

Thanks, I am trying to understand how I could leverage in my Rails app and it is a bit unclear.

A simplify version of what I have is

class Post 
  broadcast_refreshes
  ...
end

and a view view

<%= turbo_stream_from @post %>
<%= turbo_refreshes_with method: :morph, scroll: :reset %>

<form ....></form>

The form redirect to this page with a scroll reset and I would like to preserve the scroll when the refresh is triggered by a broadcast.

Looking at your proposal I am not sure how I should set the turbo-stream attributes?

Would it be something like this?

<%= turbo_stream_from @post, scroll: :preserve %>

or at the model level?

Thanks

@seanpdoyle
Copy link
Contributor Author

or at the model level?

To support scroll resets from redirects during a form submission, you could continue to render the <meta name="turbo-refresh-scroll" content="reset">, or omit the element entirely.

To support scroll preservation from broadcasts, the idea would be to broadcast the <turbo-stream> element with the configuration encoded directly into the element.

Since this change must be made separate from the Rails code, that support is still unclear and to be determined. One possibility could be to extend broadcast_refreshes to accept HTML attribute options:

broadcast_refreshes scroll: :preserve

Another approach might be to keep broadcast_refreshes generic and simple like it currently is, but change broadcast_refresh_to and broadcast_refresh_later_to to accept the attributes in the same way that the other stream broadcast methods accept :target, :targets, etc.

> I have a page where I am using Turbo morph. when I submit a form and
> redirect I would like to reset the scroll, but if a refresh is triggered
> by a broadcast I would like to preserve teh scroll. Is that possible ?
>
> [#turbo Discord][discord]

This commit expands the set of attributes for `<turbo-stream
action="refresh">` to include `[method]` and `[scroll]` (in addition to
`[request-id]`). These attributes correspond directly to the
[`turbo-refresh`-prefixed `<meta>` element][meta] elements that control
morphing and scroll preservation.

When present on the `<turbo-stream action="refresh">`, their values are
forward along to the `Session.refresh` method call, which in turn
encodes them into Visit options under the `refresh` key. Those options
are then used during `Visit` instantiation, and transformed into
`.refresh` properties.

At render time, the `PageRenderer` attempts to read the refresh method
and scroll preservation settings with the following precedence:

1. read from the corresponding `Visit.refresh` property (possibly null)
2. read from the corresponding `<meta name="turbo-...">` element (possibly null)

If no value is provided, fallback to the default (`{ method: "replace",
scroll: "reset" }`).

[discord]: https://discord.com/channels/988103760050012160/1044659721229054033/1212443786270212167
[meta]: https://turbo.hotwired.dev/handbook/page_refreshes#morphing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants