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

Expose morphing functions for consumer use #1319

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

Conversation

seanpdoyle
Copy link
Contributor

@seanpdoyle seanpdoyle commented Sep 24, 2024

Related to #1177, #1085

Document and export the range of morphing available to Turbo's internals. The continuum spans from morphing elements, to morphing their children, to morphing turbo-frame elements, to morphing body elements.

Instead of exporting Idiomorph directly, this commit exports a mix of the utility functions and the Morphing-prefixed .renderElement class functions. This way, the range of turbo:-prefixed are dispatched regardless of whether the call originated Turbo-side or application-side.

Document and export the range of morphing available to Turbo's
internals. The continuum spans from morphing elements, to morphing their
children, to morphing turbo-frame elements, to morphing body elements.

Instead of exporting Idiomorph directly, this commit exports a mix of
the utility functions and the Morphing-prefixed `.renderElement` class
functions. This way, the range of `turbo:`-prefixed are dispatched
regardless of whether the call originated Turbo-side or
application-side.
@seanpdoyle
Copy link
Contributor Author

@jorgemanrubia this proposal aims to provide clients with the tooling necessary to explore the viability of morphing outside of Turbo-managed Page Refreshes to the same URL.

I've read your comment #1085 (comment) regarding the ways that Morphing is incompatible with Turbo's current snapshot-driven navigation mechanisms.

I'll share them here for context:

the current implementation relies on managing different body elements at rendering time (not the same morphed one)

Agreed. Like you mention, the internals could be changed to account for the difference in expectations

does browser history make sense with morphing?

The main use case I've encountered that would benefit from morphing involves a List-Details view. The idea is that driving the page toward the Details of a selected item from the List would preserve the state of the List while replacing the contents of the Details with Morphing. In that scenario, navigating the browser backwards and forwards for that entry in the history should utilize Morphing, but navigating past the page with the List-Details view should utilize full-page Replace rendering.

Should Turbo create snapshots before each morph so that it can restore those? You wouldn't do that with stream actions, why would you do for page refreshes with morphing?

I think that might be necessary to support the browser history manipulation described above.

this would also be an additional API in the library, more choice for the user

Agreed. Exposing the functions directly (like what is proposed in this diff) promotes exploration in this space, but ultimately it would be nice for Turbo to provide first-party support for this. The most obvious change would involve a [data-turbo-render-method] attribute (proposed in #1145), but I'm also wary of expanding that area of the interface. There are too many edge cases and combinatory explosion of [data-turbo-*] attributes to account for.

Having said that, I'm not sure of an alternative that is more subtle while being declarative, relies on progressive enhancement and graceful degradation, etc.

In the use case I've described above, the navigation graph is fairly limited based on the URLs of the List-Details pattern. You'd want to morph when navigating from /lists/:list_id to /lists/:list_id/details (and maybe even /lists/:list_id/details/:id and /lists/:list_id/details/:id/edit or /lists/:list_id/details/new?). You might even need to support variations on the nouns (if the models are polymorphic) like /lists/:list_id/special_details or /special_lists/:list_id/details.

I wonder if the pattern of URLs is knowable ahead of time. If it is, would a Turbo Native-like Path Configurations JSON file make sense? A callback that provides the source and destination URLs for comparison? A new detail property on a turbo:-prefixed CustomEvent?

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.

1 participant