Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

julianrubisch
julianrubisch

Posted on • Originally published atblog.minthesize.com on

     

Tooltips with Futurism

As I read the excellent post abouthow to implement lazy loaded tooltips with Hotwire by Sean P. Doyle and Steve Polito, I couldn’t help but think that this is actually a very distinct example of how hard it is to draw the line between anall-in REST approach (i.e., controllers and routes forallthethings) and a more nuanced take on things that tries tobalance REST and RPC ways of implementing Reactive Rails.

So I decided to write up a quick reply usingfuturism, the lazy loading solution of the CableReady ecosystem, just to serve as an example of an alternative which maybe aligns better with existing legacy codebases (because it relies on plain Rails partials - that might even already exist in your application!).

Let’s get started!

1. Install futurism

First, let’s install futurism. Sean’s repository uses importmaps, so we’ll have to do a bit of manual installation inapp/javascript/controllers/index.js as long as the Futurism installer hasn’t been fully ported.

$ bundle add futurism -v 1.2.0.pre9$ bin/importmap pin @stimulus_reflex/futurism@1.2.0-pre9// app/javascript/controllers/index.jsimport { Application } from "@hotwired/stimulus";// NEW: import cable from turbo-rails and futurismimport { cable } from "@hotwired/turbo-rails";import * as Futurism from "@stimulus_reflex/futurism";const application = Application.start();// Configure Stimulus development experienceapplication.debug = false;window.Stimulus = application;export { application };// NEW: initialize futurismconst consumer = await cable.getConsumer();Futurism.initializeElements();Futurism.createSubscription(consumer);
Enter fullscreen modeExit fullscreen mode

Essentially, this initializes Futurism with the default ActionCable consumer, and intializes the custom elements used under the hood.

2. Implement Lazy Loading

Sean and Steve use a Turbo frame in the show view, as well as in theuser partial to load the tooltip. To quote the original article/source code:

<!-- app/views/tooltips/show.html.erb --><turbo-frame> <div> <div><%= render partial: "users/user", object: @user, formats: :svg %> <strong>Name:</strong><%= link_to @user.name, @user, class: "text-white" %> </div> <div></div> </div></turbo-frame><!-- app/views/users/_user.html.erb --><turbo-frame role="tooltip" src="<%= user_tooltip_path(user, turbo_frame: dom_id(user, :tooltip)) %>">
Enter fullscreen modeExit fullscreen mode

Now, among other things, this leads to a bit of confusion for the first-time reader regarding the addressing of the frame: To have Turbo swap out the correct frame, we need to pass the identifier as a parameter down to theTooltipsController usinguser_tooltip_path(user, turbo_frame: dom_id(user, :tooltip)).

Using futurism, I’m going to take a slightly different approach. First I’m going to move the contents from the tooltipsshow.html.erb to a_tooltip.html.erb partial (note that the content can stay exactly the same, we’re just dumping the surrounding<turbo-frame>):

<!-- app/views/tooltips/_tooltip.html.erb --><div> <div><%= render partial: "users/user", object: user, formats: :svg %> <strong>Name:</strong><%= link_to user.name, user, class: "text-white" %> </div> <div></div></div>
Enter fullscreen modeExit fullscreen mode

In_user.html.erb, I exchange the Turbo frame for a futurize call and restructure the markup a bit (to make the peer-hover work, I wrapped it in an enclosing<span>).

All you have to know at this moment is that it obeys the API ofrender partial: and you can pass a placeholder to the block (which I omitted here):

<!-- app/views/users/_user.html.erb --><div> <p> <strong>name:</strong><%= user.name %> </p> <p><%= link_to "show this user", user, class: "peer", aria: { describedby: dom_id(user, :tooltip) } %> <span><%= futurize partial: "tooltips/tooltip",                   locals: {user: user},                   extends: :div do %><% end %> </span> </p></div>
Enter fullscreen modeExit fullscreen mode

The result is an equivalent functionality, albeit with a full RESTful route including all the boilerplate less. This time, we’re using a<futurism-element> to communicate with ActionCable and CableReady does the heavy lifting in the background. Observe:../assets/images/posts/2022/2022-01-31-tooltips-futurism.gif

3. Conclusion

I hope you enjoyed this comparison. It’s important to me to spell out that there’s no right or wrong here. I wrote futurism prior to Turbo frames even being a thing, and find myself using the latter in a majority of cases these days. But sometimes, a less intrusive approach is preferable, especially when dealing with legacy codebases, or really small DOM fragments, where a full-fledged ActionDispatch route would be an overdo.

The interested reader might want to take a look at thefuturism README for further information on the library.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Joined

More fromjulianrubisch

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp