Hey gang, recently updated my core components and generated live views to fix a big frustration of mine. Wrote up a post here:
Does this bother anyone else? Is there appetite for updating the Phoenix templates to support this better?
Hey gang, recently updated my core components and generated live views to fix a big frustration of mine. Wrote up a post here:
Does this bother anyone else? Is there appetite for updating the Phoenix templates to support this better?
That’s a good article and touches on something which bothers me deeply - the complete disregard for semantic markup. I mean, do it for the visually impaired people who might use assistive technology. You don’t have to use aria-* attributes, proper semantic markup goes a long way. When I see a button that does navigation or if/else in template which renders an anchor or a button, I get goosebumps. There are many other cases, I’m sure everyone has encountered at least one.
I don’t use the built-in components (except for the icon and flash components, which I should probably replace eventually), but I also share this frustration with SPAs in general. I like having all state in the URL, so that it can be linked to externally. Middle-clicking to open in a new tab is also a nice bonus. I don’t like how SPAs throw away all of the built-in conveniences of the web only to be forced to recreate them in more complicated ways.
If you like having links like this in your SPA, you might like this library I made recently for this purpose: Cartograph - E2E Query Param Patching for LiveView
I agree that using the history API to fake a navigation is never going to be as good as the real thing. However, having all state encoded in the URL is impractical; at best you have the essential part of your states in your URL so real navigation works. Your user will still be able to perceive some discontinuity navigating between 2 live views.
Yeah, “all” is a hyperbole I guess.
There’s always going to be a lot of transient or session-related state for any interactive app. Things like the state of form fields in a bulk edit workflow should be preserved so the user doesn’t lose work if they accidentally close the page, but not in the URL. Using the URL for something like that could even present a security/compliance risk since URL params show up in network logs.
I think my frustration with SPAs wrt URL state comes from the fact that a lot of things that could be easily stored in URL state are often not simply because of the patterns that SPA frameworks encourage. The common example is a pagination param like page=2 being sent to the BE apis to load the page data on the “next page” button click, but not exposing that to the browser URL. If the user leaves the page, they have no way to get back to whichever page they were on without clicking through different pages or maybe using the jump-to-page input (if it’s implemented on that page). This is especially bad if the app isn’t set up to handle client-side routing and load components based on the URL path because then the user gets redirected to the homepage, so they have to click all the way through the app to get back to the view they were on, then page through it. This gets worse when we start adding other basics like sorting and filtering to the view. ![]()
Personally, I think the ability to link directly to a particular view of data on a website is one of the superpowers of the web. We lost a lot of things when we moved from primarily native desktop UIs to browser-based UIs (easily implemented undo/redo for example), but the web does make some interaction patterns easier out of the box, and tunneling directly to a specific view with specific state at any arbitrary point in the application is one of the things the web can do easily that native apps need special consideration from the engineer to support.
Cheers!
But this isn’t the same thing.
You can replicate the “click entire row” behaviour while still respecting accessibility. Check out the free tailwind course: Build UIs that don't suck - Tailwind CSS
In this case, the solution is to put some position classes on the table row and then making an <a> element that overlaps the entire row.
I am not sure which of the following scenarios were you referring to:
1 is impractical for many SPA frameworks because real navigation will reboot the SPA and many SPA frameworks are pretty heavy. 2 works as long as the user don’t click back button. Yes, you can save state in the history API but still in non-trivial cases you cannot save everything, There will be edge cases that URL does not match with content, or worse, when your user go back and forth. No wonder people take the easy way out which is not supporting this usage.
In this case, the solution is to put some position classes on the table row and then making an
<a>element that overlaps the entire row.
I’m not sure I get what you’re saying. Use CSS to position an (empty?) <a> tag so that it’s laid out over top of the table row?
It’s actually part of the intro video you see on that tailwind page. You do something like this:
<tr class="relative">
<td>
<a href="#">
test
<span class="absolute inset-0></span> <!-- this absolute inset-0 with the relative on the tr element makes it overlay the whole thing -->
</a>
</td>
<td>foobar</td>
</tr>
This is just from memory so adapt as needed.