The view stack in Rails is one of the creakiest part of the stack. A lot of people don't realize it, but the way partials in Rails leaks the state of the parent renderer is the source of a lot of bugs and code organization issues.
It's great to see more attention coming to it. Some other libraries worth keeping an eye on:
https://www.phlex.fun - Joel shipped this a few months ago ... it's very similar to Rux except it uses Ruby classes to achieve a similar effect. What's particularly interesting about Joel's efforts is that he is very worried about speed and performance, so it's a very fast templating framework.
https://youtu.be/9-rqBLjr5Eo?t=560 - This is the best overview of what Phoenix is shipping for their HTML framework, which is called HeeX (most of the docs already assume you're "in the know" with Elixir). HeeX is nice (like Rux) in that you can use HTML tags to embed server-side rendered components in markup with tags like `<.icon/>`. Not sure about Rux, but HeeX can reason about HTML from within itself, which means it can validate the DOM and make technologies like LiveView possible (https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html).
I'm hoping at some point in the future a "de facto" (or actual) standard for Rails view components come into being so we can have an HTML-aware templating layer in Rails and improve the ecosystem through more standard UI components.
+1 , I came to that conclusion on the view stack being one of the leakiest if not the leakiest part of the Rails stack after developing saas with heavy SPA-like tendencies. Good to see I am not alone, thanks for sharing the links too
This is pretty cool, I like the idea of using inline templates in ViewComponent. I wonder how this would look using something like Markaby[1], so the templating stayed pure ruby, instead of having to be passed through a transpiler...
I maintain a collection of view components[0] and lots are built without a template, just using the Rails tag helpers directly[1]. They're easy to write, familiar to any Rails dev and very fast.
I do this as well. Our design system in-progress has 32 components and only 3 are rendered with templates.
They are fast and easy to write and easy to modify for sure. I wouldn't mind having the code look more like the output (without a template) but it's not something I've been missing...
Am I understanding correctly that there’s a significant difference in performance between using a ViewComponent + a partial vs. a ViewComponent which renders html via a tag - from inside the component?
Don’t partials get compiled when used from a ViewComponent?
> Am I understanding correctly that there’s a significant difference in performance between using a ViewComponent + a partial vs. a ViewComponent which renders html via a tag - from inside the component?
I don't think there will be much difference at all in everyday use, but some libraries that value performance don't avoid templates for that reason, Pagy for example.
I didn't know about ViewComponent until now, it looks more appealing to me than Rux. Dealing with transpilers is a necessary evil in JS land, I really don't want to bring that headache into my Ruby code.
You can avoid transpiling if you write views in pure Ruby instead. Ruby syntax has everything you need to concisely represent all valid HTML — method calls are tags, keyword arguments are attributes and blocks are content.
I'm surprised no one has yet done React SSR in Rails using Graal (using the polyglot bridge between Rails running on Truffleruby and React on Graal.js).
Does this support HAML-style syntax? We're 100% HAML-only for templating, whether normal Rails views or ViewComponent... https://github.com/haml/hamlhttps://haml.info/ so going back to writing HTML or ERB feels like a huge downgrade.
No, rux doesn't support HAML, since HAML is an entirely different "language" than rux. You'd have to figure out how to identify HAML embedded in Ruby and parse it with the HAML parser. Entirely possible, but not something rux will (probably) ever do.
Surely rux would cover more edge cases than your function? A lot of people would see this function and struggle to understand what it is doing, but if you explicitly use something like rux it's much more obvious. I guess rux would have more overhead than this though.
even simpler, I have always wished that JSX/JSX-alikes would serialize to something like a tuple like `(tag: string | Component, attributes: Record, children: List)`, so your example would start looking something like this:
<div class="example">
<h1 id="heading">This is an example</h1>
<h2>creating React markup</h2>
<AnotherComponent foo="bar">
<li>
<a href="http://whatever.com">One list item</a>
</li>
<li>
Another list item <hr />
</li>
</AnotherComponent>
</div>
Ruby has blocks, so in Phlex, you’d write it like this using methods and keyword arguments.
div(class: "example") do
h1(id: "heading") { "This is an example" }
h2 { "creating React markup" }
AnotherComponent(foo: "bar") do
li { a(href: "http://whatever.com") { "One list item" } }
li do
text " Another list item"
hr
end
end
end
"JSX-inspired" caught me off gaurd, the only thing JSX could inspire me to do was build something so I never had to touch it again, I landed on something similar to what you have here, I call it "Elementary"
I've been building a Javascript server that implements Hotwire/Turbo lately powered by JSX templating (not React!) and minimal client-side JS. Its a wonderful dev experience but this might make me port those ideas back to Ruby. The rest of Rails is just too good to pass up.
The html inside the call method looks cool but I have hard time understanding to how the syntax highlighting would react to seeing html inside the ruby code? Would it highlight it correctly?
From the README:
Write your Python interfaces in a declarative manner with plain render functions, component classes or even single-file components using Vue-like syntax, but with Python!
- Reactivity (made possible by leveraging observ)
- Function components
- Class components with local state and life-cycle methods/hooks
- Single-file components with Vue-like syntax (.cgx files)
- Custom renderers
It's great to see more attention coming to it. Some other libraries worth keeping an eye on:
https://www.phlex.fun - Joel shipped this a few months ago ... it's very similar to Rux except it uses Ruby classes to achieve a similar effect. What's particularly interesting about Joel's efforts is that he is very worried about speed and performance, so it's a very fast templating framework.
https://youtu.be/9-rqBLjr5Eo?t=560 - This is the best overview of what Phoenix is shipping for their HTML framework, which is called HeeX (most of the docs already assume you're "in the know" with Elixir). HeeX is nice (like Rux) in that you can use HTML tags to embed server-side rendered components in markup with tags like `<.icon/>`. Not sure about Rux, but HeeX can reason about HTML from within itself, which means it can validate the DOM and make technologies like LiveView possible (https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html).
I'm hoping at some point in the future a "de facto" (or actual) standard for Rails view components come into being so we can have an HTML-aware templating layer in Rails and improve the ecosystem through more standard UI components.