Rooftop Ruby Podcast

19: CSS, Stimulus, PhlexUI?

Collin Donnell Episode 19
  • Joel is coming to RubyConf in San Diego!
  • Collin has been thinking about CSS, Stimulus, and building on top of Phlex.

Collin is available for freelance work. You should hire him! Get in touch via Mastodon.

Follow us on Mastodon:

Show art created by JD Davis.

Collin:

Hey, Joel.

Joel:

hey,

Collin:

Hey. Uh, how, how has your week been?

Joel:

my week has been great. Yeah. How was yours?

Collin:

Uh, interesting. Um, yeah, a few things happened, uh, but I. We will talk about those. The first thing I wanted to tell you, did you see that Johnny, ive, I know you did cause I sent it to you. His first gadget since leaving Apple is a$64,000 record player.

Joel:

Yeah, this is, this is insane. Uh, and, and no, I hadn't seen it until you linked me to it, but, um,

Collin:

Yeah.

Joel:

actually looks amazing. I kind of want one

Collin:

I, um, do, do you listen to vinyl? I, I do.

Joel:

I d I don't, to be honest.

Collin:

Oh, you should. Um, I, I have a project. It was, it was expensive. I mean, it was like$500 or something. Like it wasn't cheap. It wasn't like one of the ones you can get it, you know I don't know what the equivalent of Target is there, but you know what I mean? That kind of thing. Like a big box store. Um, but, you know, it wasn't$64,000 either. So. I guess I'm going to have to read through exactly entire thing because on, on the face of it I'm trying to understand like what would make like, like I could, yeah, like what it could possibly do differently cuz it's a thing that spins that you put a needle to.

Joel:

I mean, it's beautiful. I think

Collin:

It is beautiful. Yeah.

Joel:

Johnny Ive, and, and he can, he can sell it and people are gonna buy it,

Collin:

Yeah, I believe you can make a$10,000 record player that you would somehow be able to explain how you got there by like doing like maximalist component design. Uh, but then I think about$50,000 of this has to be who made it.

Joel:

Right. Yeah. Yeah. This is, this is easily 90, 95% margins.

Collin:

Yeah. It's amazing. I love it. Uh,

Joel:

But they're, they're only making 250,

Collin:

That's why Okay. That's why it's expensive. It's for like crazy rich people who want to be like, I got one of the Johnny I've turntables. Right?

Joel:

There, there's easily 250 crazy rich people who will buy this

Collin:

Absolutely. If I was that rich, I'd buy it. Why not? Uh, man, I think I said last week that if I got rich I'd still be cool. Like I'd give my money a charity and stuff, and immediately the next week I'm like, If I got, if I was rich, I'd buy a$64,000 turntable.

Joel:

Yeah.

Collin:

Um, which is, it's just kind of a funny thing, uh, to say, uh, okay, huge news. Maybe I'll put a sound effect in here. Probably not. Uh, Joel, you're going to be at Ruby Comp in San Diego.

Joel:

Yes. Yeah, I've decided. Well, I've, uh, I've got the time to come, so, uh, I'm gonna try and make it up there.

Collin:

That's. That's incredible. I'm really excited because then we'll, we'll get to hang, um, which will be huge. Uh,

Joel:

Yeah. We've never met in real life, have

Collin:

no, but, but I,

Joel:

we? like, like I don't know if we were at the same conference maybe before.

Collin:

no, definitely not because I'd only been to Rails Comp this year and last year. And you

Joel:

Oh, okay.

Collin:

I was at the one in Portland. Um, Which is what I'm told is called, uh, main Character Energy, which is like the first year that you're like, or like Protagonist Energy, which is that like the first year you would've wanted to do that. Like it would've even been a thing I'd think of. It was like, it's in your town. Um, so I was very lucky then, uh, Yeah. So I'll be there because it's, what was, I wanna hang out with you. Like, I would go if it was, if you were just like, I'm gonna be in San, I'm gonna be anywhere on the West coast and I have time, I'd probably like figure out a way to get there. Uh, but you know, Ruby Comp is also, well, and I think we'll both be submitting talks, uh, which will be exciting. Uh, I have, I have a couple of ideas and I know you do too. We don't have to spoil'em now, but, um, That's, yeah, that's, that's, uh, it's very exciting stuff. Uh, maybe we can talk him into lettings, do a live episode as a talk. Uh,

Joel:

Yeah, that'd be great. I've, I've never given a talk at a conference before. Um, but there are a few things that I think it would be fun to talk about and, um, there's no harm in submitting something.

Collin:

Yeah. I've given several.

Joel:

shot.

Collin:

I've given several and I think, um, What, what would I give, what would I give somebody as a tip? Not that you asked, cuz you didn't, but what would I give somebody as a tip, which would be, uh, don't put too many words on your slides,

Joel:

Yep.

Collin:

Don't put too much on your slides and practice it all the way through a few times, like in your house. Just like, even if it's only like twice, like literally do the whole thing you're gonna say, because I've done that and I've not done that. And the times I did that, it went great and the times I didn't do that, it was variable. And so I would say if you. Try and get your talk done sooner than later and then, uh, and then practice it a couple times. Although I feel like with Rails confidence, I assume Ruby Comp, I don't think they tell you that many weeks before if you got accepted. It's not like months. So you still only have so much time, but I think you'll do.

Joel:

I'm, I'm probably gonna get the talk together anyway, because even if it's not accepted at Ruby Comp, I'll still, I'll still give this talk somewhere. In fact, um, I know what kind of person I am and I know that I'm very likely to be working on my Ruby Comp talk, like on the flight. So to combat that, I'm gonna probably try and make myself give the same talk at like El rug or something

Collin:

Mm-hmm.

Joel:

and then like a couple of months before, that way I know that I'm gonna have got my torque ready and like done it once in advance cuz, because then I can be preparing the torque on the evening, the night like before el r rather than uh, Ruby Comp.

Collin:

Yeah, I, that's funny. Um, I do know people, it was when there were more regional conferences going on where they would give, they basically had a couple of a talk they did, and they would give it at a few conferences because like it's different groups a lot of the time. Um, Yeah, Ruby Comp feels like one where maybe you do sort of need to write your talk for it. I mean, you could have given it before, but maybe not as much after, although maybe after, I don't know. You can do whatever you want. Um, I just meant that it's one that like a lot of people will go to, but also, you know, rails Comp wasn't that big. There's a lot of people who weren't at Rails Comp who probably would be at some regional conference in, you know,

Joel:

Sure. Yeah.

Collin:

So,

Joel:

Yeah. I'm not, I'm not really sure what I want to talk about. There's, I've, I've got a few different ideas, but, um, I think I'm gonna submit a few different things and then see what they think.

Collin:

Yeah, that's a no, that's a great idea. And I, I agree that I also am that kind of person, which I'd like to imagine I'd be the kind of person who would just be like, I'm just gonna write a couple of talks and then like, they'll be ready for whenever something comes up. I've never done that. Um,

Joel:

Yeah,

Collin:

that's all very exciting. I think you're gonna do great cuz you have a lot to say. You're very smart. And people like you. So I think you'll do great no matter what. Uh, so I, this I've been thinking about, so I've been thinking about a couple of things this week and I don't know what we want to get into too much. I did have an idea that sort of relates to Phlex. I think that's an interesting one we should talk about. Um, but I've also been thinking about, I don't know, I was. I know you're a very big fan of vanilla, CSS and different things, and I was thinking about CSS a lot in the last couple days. For some reason I decided, I'm like, this is gonna be the time. You're gonna get really good at it. And I'm like, fine. Right. Uh, and I was thinking, so I was, I was looking at stuff like, like bem, block element modifier and how people do things like that. And then you know, also things like tailwind and those sorts of things. And it seems to me like on one end of the spectrum, if your page was simple enough, I'm not saying I would do this, but you could. You could just put everything as style attributes and it would probably be fine cuz your page is so simple.

Joel:

Yeah, you could.

Collin:

That doesn't scale very far. Like once you have like two pages, it's probably not even one complex page not gonna scale. And so then I think you move up to where you could do most everything with just semantic, you know, like, this is, I'm defining, this is a pretty small scope and I'm just defining, you know, how the semantic elements in my HTML will be layered and. Doing that very closely in my css, and I think if you had a limited number of kinds of things, that probably works pretty well. But that at some point, sort of the next phase of that would be you need to start introducing some kind of classes or whatever to get some specificity and you know, be able to, To find things a little bit differently because the elements are not always going to nest in exactly the same way.

Joel:

Right.

Collin:

Uh, and then my question is this, is that as far as you go, which is like CSS and nesting and just using it kind of in that way? Or do you think there's any value to these things like bem and then I almost sort of thought tailwind or something like it? I'm. Don't think this is where I'm going, but I almost wondered is that almost kind of like an extension beyond that in a way, not like in a hierarchy sort of way is like it's better for more advanced, but in a way of if somebody was like, I need to put more direct levels of like specificity into my html, when you get to Tailwind, it's all in hd. It's all just there

Joel:

Right.

Collin:

and that kind of seems like another step. I don't know. What do you think about any of that? Is there anything there?

Joel:

Yeah, I've gone back and forth on Tailwind and, um, I am pretty convinced at this point that it is not good.

Collin:

Mm-hmm.

Joel:

Um, I can see its advantages, uh, in doing very simple stuff, but, um, it tends to, in my experience, introduce a lot of technical debt and. Like, it's very difficult to, like, if you have something that begins to get more complex,

Collin:

Mm-hmm.

Joel:

you can't like refactor it to make it simpler very easily. Like for example, there's no way to have all of your styles like one on each line very easily.

Collin:

Correct.

Joel:

Um, they have to be in this like either very long line or you have to enable like soft wrapping on your editor.

Collin:

used to have like a brick

Joel:

Um, and you have a wall of text,

Collin:

Correct.

Joel:

uh, and you have to kind of scan that, and there's not really any hierarchy. Um, so, you know, tailwind can be nice

Collin:

could probably do some things. You could probably do some things to like sort'em or something.

Joel:

you could, you could probably do that. But again, it's not easy. Editors have, um, in my experience, good support for sorting lines. Not very good support for, for, uh, for sorting. Words. So maybe, maybe your editors can do that.

Collin:

I think you have to write a script for it, is how I

Joel:

might. Yeah.

Collin:

Um,

Joel:

But, but even so, like, like Tailwind is like, it's quite nice when you, when your elements have maybe three or four, maybe five classes on them at most.

Collin:

Yeah.

Joel:

Uh, but then when it comes to, you know, like 20.

Collin:

Yeah.

Joel:

And some of them are working on pseudo selectors, um, like after and before tags and applying things to those, you know, and they're not grouped really. They're just, you could try to keep them all together, but they're not really grouped. Uh, some of them are, are applying to hover effects, right? Maybe you've got five different styles that you apply on hover. Again, they're not grouped hierarchically under hover. Um, They're just there and they all, every single one of them has to select hover again. Um, you know, when, when it comes to that kind of thing, it's just like, this is just not as good as css. Um, or, or like abstractions on top of css, like SAS post css. Um,

Collin:

Yeah.

Joel:

I'm a big fan of keeping it as vanilla and simple as possible until, Until you need to do something more. Like I would try on a new project, I would try to avoid SaaS to be honest. Um, and maybe use something like CSS Next. Um, I think that's the name of the project that basically gives you, uh, I think it's a post CSS plugin that gives you the ability to use like new and upcoming CSS features, but compile them to. To support older browsers. So for example, CSS now has native support for nesting. Um, so you can do a selector and then inside that selector you can do another selector, uh, that is quite recently supported in, and I think it's supported in some newer browsers. But, but that's been available I think in, in CSS next for a while.

Collin:

Yeah.

Joel:

just like compiling to normal css.

Collin:

Yeah, I've, I've heard of that as well. I, I think the nice thing with vanilla, for me, one thing is that not even going to like post CSS is that it keeps your build system like extremely simple, which I really like. And things like nesting. I guess the thing with Nest, with using those features, they're getting pretty high support. I looked at the other day, it's like 80% now for nesting.

Joel:

Mm-hmm.

Collin:

But that does mean it's not the kind of thing though, where like it's gonna fail gracefully. So, so for 20% that means your website just won't work at all. So I guess that it really needs to be like in the mid nineties, at least probably before you wanna support it. Um, cuz like, yeah, even if, I don't know, losing five or 10% even seems like a lot if it's gonna completely break your entire website. Um, Yeah, I, I do think those are all good ideas. I would, the only way I can see Tailwind for me is I would not put Tailwind into like an e r B template, although I know people do that cuz it just seems like you're gonna have, like you said, just all these like walls of text is all gonna be right there.

Joel:

Right, so.

Collin:

I think I. If you are highly, highly componentized with something like Phlex, maybe there's a way to, I mean, there's obviously a way you can hide a lot of that, uh, tailwind, grossness and kind of make it resemble more like what you do in. Uh, like a native app where, you know, like you've got similar, it's not as gross as tailwind, but like, you know, you're setting all that view stuff like in the component, in the view, um

Joel:

You could even like define a hash on your component that had all of your tail, like your tailwind classes on it kind of grouped, and then have a, a very simple ruby script in your application component that is able to find the method that pretends that hash and then like compile it into a list of, of, uh, of, of, of class tokens or something like that. That, that would be pretty simple.

Collin:

Yeah, I was, and I, I was thinking about that as well. Um, it didn't seem, seem like you could do it pretty, pretty easily. However, it does make your build system more complex, which I guess, I don't know, maybe. Maybe other people don't care about that as much as I do. It does feel to me though, like Tailwind is because most front ends are in like React or something, and it feels like kind of made with that in mind. Like it feels like a good fit for that. Where I haven't seen a Rails project yet where it seems like that clean of a wind, um, Yeah, I also was, yeah.

Joel:

get, I do get why people use it. Um, and I, I think if you are gonna use Tailwind, then what you really want don't wanna be doing is copying and pasting a bunch of the same sets of classes. For the same components again and again in ERB views. Like actually extract a component for everything that you put a list of tailwind tokens on and like name it and then reuse it in your views

Collin:

Yeah,

Joel:

that. is so important because that like, that can kind of replace what we would've, uh, perhaps traditionally used a semantic CSS class four, right?

Collin:

Correct. But what, so what I, but then as we were talking, I was thinking. If you were going to go so hard on components just to like make tailwinds like livable, right? Is that really different than going super hard on. Making a bunch of classes with good names. Just like for css, you're kind of doing the same thing at that point, except like now you have literally like 10,000 files, what, not that many, but yourself. All these files and, uh, I'm a fan of less files, although, you know, it's not, you know, like if breaking things out's good, but less unnecessary files. So I'm thinking at that point, like, is having like button primary,

Joel:

Mm-hmm.

Collin:

whatever class. I mean, it probably wouldn't be that exactly, but like is that, I don't know how that's really different at that point. Cause it feels like you've kind of gotten to the same place except, you know, now it's all just defined as components, but it's kind of doing the same thing. Um,

Joel:

Yeah. And it kind of, it does limit you to using only a subset of CSS and to not using the latest CSS features.

Collin:

yeah.

Joel:

Uh, and I, whereas like if you just use css and especially if you use CSS with CSS Next, something like that. You get to use all the latest features and all of css, there's, there's not really anything you can't do. You're not gonna like find a solution online to some problem and then realize, oh, but I can't do that cuz there's no tailwind class for it.

Collin:

Yeah.

Joel:

then I still have to go and like have this, this, uh, kind of, uh, closet full of. The bits of css, like with that, that you had to write manually on top of all your tailwind stuff? I don't know. I, for me, I would, I would really just try to keep it as simple as possible. Um, you mentioned, you mentioned b e M. Um, I think this is a really, um, like traditionally BM was a really interesting and compelling idea. I used it a lot, um, number of years ago, and. One of its, uh, big advantages was it was a way of naming things so that you'd had a kind of sense of hierarchy, but without hierarchy. So you weren't doing like, selector for the outer component and then selector for the inner part of that component, um, and making the browser do all the work to, to run those through those selectors because,

Collin:

to be, um,

Joel:

Right. Everything you were selecting was just one class,

Collin:

Mm-hmm.

Joel:

um, and you just had like, name spacing built into the class name. I think that that made a lot of sense for like, for the time, but I think that now that like, that kind of b browser, uh, support is isn't a big deal. Um, sorry, what I'm trying to say is, um, browsers, browsers are really, really fast. Um, and I think that now, It's totally fine to just have like nested CSS selectors. So I would typically just have a CSS selector for the outer component. And then I would have like use normal element selectors if I can. Uh, if there's no conflicts within that component, like maybe I have a nav component and there's a nav element which has the class of like main nav. Then inside that there's a UL and Li and an A. Right? I can just select the ul, the li and the A directly like Nav space li, nav space A. I don't have to put classes on each of those things because they're the only things of that type inside nav, if that makes sense. And um, M was kind of a way to avoid doing that for performance. I just don't think that we need to worry about that anymore. Like maybe still like that style and that's fine. But, um, I don't think that performance consideration is really, really valid anymore. Um, however, modifiers, um, I think we actually have an even better way of doing them now, which is to use, uh, kind of like data attribute selectors. So instead of adding a class for a modifier, like say you have, um, you might have, um, nav, nav link, active nav link inactive

Collin:

You could give that as a data attribute,

Joel:

Yeah, you could

Collin:

data active,

Joel:

data dash status equals active data, dash status equals inactive, or something like that. And then you can use, um, you know, square brackets, uh, attribute selectors, uh, instead.

Collin:

You know, I hadn't actually thought of that and I think that will probably keep me away from trying, uh, bm cuz it, yeah, I did kind of get the impression that it was maybe something that was popular like a decade ago that has potentially like, sort of lost relevance over time, uh, as more features of coming to CSS or whatever. So that that makes sense. Um, oh, I did something so I. I did something cool this week, which was, uh, which very briefly is I, um, I was messing around with a couple of things. One was, uh, well, what I wanted to do was create those like pop-up menus like they have in hay, like in the email client. Um, and there's a couple of tutorials for this. So I looked at those and I was just experimenting with it. A couple of things I thought were neat, which is that if you use the new, uh, HTML dialogue, Element and you say, and you have a lazy, loaded turbo frame within it. Um, it will lazy load correctly when you just say like, dialogue show,

Joel:

Oh wow. That's awesome.

Collin:

seemed very simple. Uh, and so like you're, you just have like a stimulus controller that's like toggles that on and off. And that's even simpler than what other people I think had been. I don't know if like semantically that's bad or something, but I don't think so. Cause I think that's what it's meant for. Because it has a mode, it has a mode where it like, is a modal, you know, where it like blocks the page. Uh, and then it has a mode where with like a backdrop even. And then it has a mode where it's like a, just like a popup and you just put anywhere you want.

Joel:

Mm-hmm.

Collin:

was thinking, um, so that was very cool. Maybe I should write a blog post or something about that cuz it was, uh, if I can get it working in a, you know, make a nice, clean example of it. But, um, yeah, so that's, I don't know. That's what, uh, and then, uh, I don't know anything new in literal, literal world this week, I feel like we have a literal check-in.

Joel:

Yeah, yeah, we can have a literal check-in. Um, yeah, so I actually have added a new feature to literal this week. Um, which is actually turning into one of my favorite features in the entire library. Um, and the, it's called literal variant and basically, uh, literal vari variant compliments. Uh, a another object, uh, called a literal switch, uh, which is, uh, a literal switch is basically a way of having an exhaustive case statement. So you could create a literal switch with an enumeration, sorry, um, in enumerable. And then you can pass a block and it will make sure that you handle every item in that enumerable. And then when you try to evaluate something against it, it's gonna select the correct, uh, item, kind of just like a case statement. Um, but so literal variance, basically. A variant is one of a kind. So, um, so a variant knows what it is and it knows what it could have been, essentially. So I could have an operation that says, um, I'm gonna return one of either a successful object or one of, or error a, error B or error c. Uh, and then you do your block. You can either rescue those errors and return them as values, or you can have it like actually just return error values. And then in the handling code, when you call that method, you have to pass a block. And say for the response, I'm gonna handle this case and this case and this case. If, if you miss a case, it's gonna raise immediately and tell you like, you didn't handle this case. Or if you, if you handle too many cases, it's gonna say, Hey, you're handling, you know, an extra case that you shouldn't be. Um, and so it's kind of a way of, uh, kind of just having a nice like interface around, uh, anything that could be. Of multiple types. It, it's kind of similar to what you might use a result mon a for except a result. Mon ad is basically a success case and a failure case. And this is more useful for situations where it's, it's gonna be one of like a union of types as opposed to, um, you know, binary successful or not successful. Does that make sense?

Collin:

Yes, that does make sense. Yeah, that sounds extremely useful.

Joel:

So it's kind of like flattening. If you had a, if you had a result object and your failure could be one of certain number of failures, you had a union of failures or any number of failures, it's kinda like flattening that and saying, let's just have one list of all the things that could come back. I don't kind of really care whether they're successful or failures. It doesn't really matter. Um, In terms of the way that they're handled, it's just, they're just one valid response. Um, yeah.

Collin:

Right.

Joel:

I've, uh, been working on that, uh, integrating it at work, uh, and it's, it's like really nice to use, so I'm quite happy.

Collin:

No, that's amazing. That sounds, uh, extremely, extremely useful. Um, oh, I did have one more thing I wanted to mention to you this week, which was, so I had this idea of something to build and I don't exactly know what it's gonna look like yet, but the basic idea so far, the name is Phlex ui, is. Pretty much to build some basic abstractions on top of Phlex

Joel:

Mm-hmm.

Collin:

in a way that is similar to but not a clone of mean. Cause you couldn't make it a clone Exactly. But of Swift ui. Um, I might look into that. I think it would be much simpler. I think it'd be a lot of things like, like in

Joel:

I, I thought you were gonna say Tailwind UI for a second,

Collin:

No,

Joel:

but, so now I'm really interested. So I don't know anything about Swift ui.

Collin:

Yeah, so in Swift ui, when you're laying out, um, when you're laying things out, it has a, uh, what is it? It has a system that I find like pretty easy to get my head around, which is that it's a grid. And essentially what you have, and maybe you could use literal for some of this too, but essentially what you have is a, uh, like a view protocol. And within that, uh, it returns. It has a single method called, um, uh, what is it called? View, I don't know. Um, I'm blanking at the moment. For some reason it's really weird. But, you know, it has a single method that basically sets everything up in the view and it can call other views. And, you know,

Joel:

Sure.

Collin:

this may sound very familiar to you. like in Phlex you have a single method, it's called template. Um, and you have a couple of, but like, that's the primary one.

Joel:

Oh, I should have gone with View. I didn't think of that

Collin:

Never too late. Um, never

Joel:

might actually go back and rename that because,

Collin:

It's a

Joel:

uh, as we discussed a few minutes ago, um, before we started this call, uh, there is a, there is a problem in Phlex, which is that, uh, you define the template method to put your template in, but HTML has an element called template. So there's like a name conflict, um, where normally you would expect cooling template within the template would render a template tag instead, it just creates an infinite loop. Uh, and I wrote a post about all the different techniques I used to try to get around this and ultimately failed and wasn't able to. And so I had to rename the method template tag. Uh, but view is actually a really good name for that template method that you define. That I, I don't think there's a html element called view.

Collin:

I don't think so. I mean, unless you, like defined, yeah. You can define whatever you want now, but built in, I don't think there isn't like a built in semantic, uh, method for that.

Joel:

huh. I'm gonna, I'm gonna take that away and think about it. Um, sorry, I, I totally interrupted you, but, um,

Collin:

No, no, no. Um, but that's, that's fine. Yeah. I was just thinking like when I saw Phlex, I'm like, oh, this is kind of similar. There's a few things that are different. Um, And maybe you could, I don't know, maybe if you tied it to like hot wire kinda stuff or something else. Maybe you could do some of this, but I, I, I have no idea. Um, but uh, you know,

Joel:

Oh, like are you talking about like behavior and

Collin:

I'm talking about like, yeah, like two-way data binding is kind of what I'm thinking about, uh, which. You know, some of the abstraction, pretty much a lot of the abstractions in, um, in Swift UI have to do with, you have thing called like state variables, which sort of manage like the, the way things look. And I, you could imagine having some kind of like JavaScript tie in that like somehow like. Updates parts of the page when the state variable changes, right? Like in line, which as I'm saying it, that sounds very cool to me. Um, and it'd be sort of automatic. And then you also have things where you can tie, for example, to like a model is you can be like, this ties to the name of this and it's a two-way data binding. Um, I don't exactly know how you would get that, but I do think get, the first thing was the state variables, so that might be worth exploring. Um, yeah. So.

Joel:

that that might be worth exploring as a separate gem to the, the other stuff

Collin:

To the UI thing, it would be like a dependency of the UI thing maybe. Um, that's, that's a,

Joel:

I would check out. Um, is it LiveView, is that the PHP one or the elixir one

Collin:

uh, the elixir one is Live view.

Joel:

Yeah, Phoenix LiveView. I would check that out.

Collin:

Yeah. I think I will.

Joel:

I've often wondered whether there might be a way to take Phoenix LiveView, frontend JavaScript

Collin:

Uhhuh

Joel:

and just build a completely ruby backend for it. Like behaving the same way as the elixir server would.

Collin:

Yeah,

Joel:

Um, and just having like a, a live view compliant Ruby server,

Collin:

yeah,

Joel:

uh, that was able to do everything and like base it off of Phlex. I've, I've thought about that a lot, but, um, I haven't dug in and like actually found out how to do it or if it's even possible.

Collin:

yeah. I don't know.

Joel:

but I imagine it must be right. There's, there's a front end code that talks to backend code through an interface. And as long as Ruby is able to.

Collin:

Respond.

Joel:

Respond. in the same way In theory it should

Collin:

could do it through a socket. You could, I mean, I feel like there's a, I feel like there is a, uh, a turbo streams thing here to make that work. But then you're tied to turbo streams. I don't know if you want that.

Joel:

A action cable, uh, it's, it's all, it's all web sockets, so I, I expect you could do it with action cable,

Collin:

Yeah, that's, that's pretty interesting. Um, I do like the idea cuz they introduce Phlex data or no. Lemme see where this is going. Uh, they introduced swift data, which is like a model there. It's, yeah, it's, it's like your, um, version of like active record now in Swift. Uh, but I could do Phlex data, which would be the data binding thing, and I could do Phlex ui and I just keep stealing their names as like, they have swift charts, so I could make Phlex charts just, just to like, have done them all. Um, which would be fun.

Joel:

Yeah. Phlex has, um, SVG support. I, I think that's very, uh, not very, Often used, but um, yeah, just like it has, uh, Phlex html, you can have a Phlex s VG component.

Collin:

Oh

Joel:

And even if you create an S VG tag in Phlex HTML component, then it yields a new Phlex s s VG object. So if you say S vg do, and then you pick up s right? You can then say S dot path, s.circle, whatever it is.

Collin:

You could just, you could just have a component to be like, generate a chart and have all the chart. You'd give it, like the chart type, you'd give it like whatever. And then you have to write a lot of stuff to do the svg, but

Joel:

Sure.

Collin:

doable. Um,

Joel:

Yeah,

Collin:

that's really fun.

Joel:

do that using SVGs.

Collin:

Then I could have a whole, we could, you know, it'd be a whole, uh, a whole family of Phlex.dot dot, uh, Phlex Ask Chris, uh, things. I think that's why. So, so that's why, I mean, that's what's exciting about using something like that. And it, it's the thing I haven't done very much yet, you know, which is where, to me, if you do a direct translation of your e r B to Phlex and you like do that. There's like, there's benefits there, right? Um, versus something where you're writing in a different language, like even like view component or whatever, I guess. Um, like there are benefits, but essentially you're just writing HTML in, in Ruby. So it's like, it seems like the big win would come from building abstraction, like using that to build the abstractions that are now easier to do because underlying you have all the benefits of it being a real ruby object.

Joel:

Yes. Yes, absolutely. Um, and, and we, we actually talked, um, again before, before we started recording about, um, about kind of simplifying what it's like to call, like to render other components from components and how it would be nicer to be able to do them to render a component just by calling a method instead of calling render and passing in. An instance of a component that you had to set up. Um, I could totally see that. Like a library that provided a bunch of like standard components, just making a module available that you can include into your Phlex html objects that just gives you these methods that you can call.

Collin:

Yeah, yeah. Yeah.

Joel:

and, and, like, yeah, that's absolutely where like Phlex is very low level. It's, you're not really meant to use Phlex. On its own, like just the HTML tags to build your app. You're meant to build components first and then compose those components together, um, to build, to build your app. You, you basically, yeah, that's, that, like, that's, that's the, the strategy that I always imagine people, people using it

Collin:

Which is a very natural way for me cause I've done that so much in other, uh, worlds. Sorry, I got sidetracked though. We got talking about the view slash template method. Um, and I didn't finish what I was gonna say, which was that basically the way you lay it out is you nest things. You don't, you know, you're not using CSS cuz you don't have css. You're basically, it's all composed of nesting. Uh, What you call like V stacks, H stacks lists, you have all these different kind of types,

Joel:

right.

Collin:

and that is, that is how you compose your, um, your views. And then there are ways to say like, this is above, you can also have a Z stack. And so that is how you say, like, these things will appear above each other or below. Um, and then if you need very, I don't actually know how you would do this, uh, with Phlex, but maybe there's a way where if you need like very specific like pixel. Specific layout. Uh, there's a fallback called a geometry reader, which then you wrap and then it basically passes you an object or a type which has all the information about like the geometry of its parent. And you can then use that to say like, this needs to be 30% from the left side or whatever. Um, which, yeah. So I don't know if I would build all of that, but I think. I think at least like the basic grid stuff though, with the VS stack, the H stack and the lists and things like that. I think that would be maybe cool. Um, you know, and it all, it could all be built on top of like Phlexbox or CSS grid I guess, or whatever. Um, just

Joel:

components. Components like that. Yeah, I, I would. Rather than make it, so you say like Render vs. Stack render H Stack,

Collin:

just be vs stack.

Joel:

define the VS. Stack method on a module and include and like make that available for to be included. Um, yeah, it's building this kind of thing with Phlex is great because you don't need to like do any kind of setup. You don't need to have like a rails engine or like a views folder. You can just define classes.

Collin:

Mm-hmm.

Joel:

And make them available. Once they're required, then they, they just work in, in rails or in anything. Like, you don't have to make your view library like Rails specific either. If you never touch rails, then it will work anywhere that Phlex works.

Collin:

You know, we were talking about before the call, um, which maybe meant we should have started

Joel:

should have just recorded,

Collin:

Yeah.

Joel:

we should hit record when we, when we get on the call and then we can cut in whatever we want from that.

Collin:

that's a good point. Um,

Joel:

the pre-talk.

Collin:

yeah. Uh, so what did that get me thinking of though? Um, crap. Oh, with that, uh, We were talking before the call about how if you, um, defining like those method names or whatever to like represent, like if you had VS. Stack that it's hard to get without a compiler, right? Which is a way to solve this for Phlex. hard to get away from having something like a render method or whatever and just like taking away or maybe not needing. Some other things, um, hard to get away from that, uh, because like the modules aren't gonna work properly, but if you had it where you had like Phlex ui, colon, colon stacks, right. Phlex ui, colon, colon, whatever, or you could include that.

Joel:

Mm-hmm.

Collin:

all of those methods are just a, they're in this, they're part of this class.

Joel:

on self.

Collin:

Yeah. So you completely get around.

Joel:

Yeah, absolutely.

Collin:

for things that, I mean, for your custom things, you still need to do it, but for the things that are in this library, I mean, you could apply that method to your custom things as well. But for the things that are in this library, you could just include Phlex UI in your top level Phlex component, you know, Phlex view component, which at both whichever super class, and then have'em right.

Joel:

Yeah. Yeah, that would, that would work.

Collin:

just be available

Joel:

to, to, to explain this problem. It, um, for listeners, um, I've often wanted to avoid having to call. So, so right now in Phlex you have to say render, and then you have to give it an instance of a component. So where that's usually, um, a constant, like my component new, um, and what I, what I would rather it was is instead of saying render, you just say the name of your constant, like my component. Then in brackets the, the parameters that you wanna pass to it, um, or like open a block. My component do, um, and it's, and it would work like a method call just with a capital letter so it matches the name of the, the class name that it corresponds to. Um, I think that that makes the most beautiful looking templates. The problem is, while it works for like rendering components, Um, like that because you can just define a method on the component that you're in that is able to render the component that you're referencing. If you are referencing another component that is name spaced, um, so it's like, um, maybe it's like nav, colon, colon item, then that is no longer a method call on self. It is a method. It's the item method call on the constant nav. And the content nav doesn't know which component is being rendered because it's completely separate, right? It doesn't know self. There's no way in Ruby to implicitly pass the self of the cooler when you're calling a method. And so there's basically no way to get this to work. There is one way to get it to work, as we discussed before we started the cool, um, which is gross. You can basically, before you start rendering a template, You get the current thread, you set a, a thread local variable on the thread to point to the buffer that you're rendering to. You then render the template. The template calls, methods on various constants all over the place, and they use the current thread, uh, local variable to find that buffer and just push things into it. Um, and then hopefully at the end of the template you clean it up and, uh, Remove, remove the buffer from the thread. It's really gross.

Collin:

sounds to me too insane to be worth doing. Uh, I think a compiler is if you're kind of thinking you want to do that anyway, I think building that into the compiler is like the way to go.

Joel:

yeah. I think, I think so too.

Collin:

Yeah. Well, I think that's great. I think it is a great episode. Uh, talked about a lot of stuff. Um, I dunno, anything else you

Joel:

speaking. Well, we, we spoke about css.

Collin:

Oh yeah.

Joel:

Uh, I don't have any answers to this, but, um, you're talking about Phlex ui. Can you think of a, a way that you could, like, so let's say you built Phlex ui, right? You've got Phlex components, but you also need to expose css that these Phlex components depend on. How, how would you go about doing that? I guess the simplest way would be like, like the first idea you mentioned, which is like just have style attributes everywhere.

Collin:

Yes. Uh, yeah.

Joel:

or, or even I guess, style elements, right? You could, you could haves style elements that allow you to access more css. Um,

Collin:

Yeah. Um, Not totally clear. I haven't figured that out in my head yet. Uh, I think in my, I think one solution would be to really take inspiration from swift ey and the way that they do this. Is, uh, there are some things that you call that, like for setup. So like for an H stack or VS stack, you might say, like Gap or whatever, like how far things, whatever it's called. Uh, how far things are away from each other in the stack. But then for things like style, you set, you have, um, you actually append those to the end as, as, uh, as call as method calls. And those are called modifier methods. Uh, and so those, so then those would be. Receiving the Phlex component before it's rendered and then doing something,

Joel:

Mm-hmm.

Collin:

uh, Obviously have not thought that all the way through yet, but that's just a different way I could see doing it. Um, so one of them could be like.style and you would just literally give or dot class and you would just like literally give it to class names you want from your css, but you could also have things like dot board radius, dot whatever. Like you could expose some of that stuff through there. Um, or maybe like, you know, you could have a system for different kinds of, it depends, you know. I think you could definitely go all the way if I took the Swift ui, like, uh, inspiration all the way,

Joel:

Yeah.

Collin:

um, and really do that. Uh, so I think it'd be a matter of figuring out how much of that inspira, you know, how far in that direction I want to go to where it's gonna start to look weird to Ruby programmers would be my concern because I don't feel like modifier methods are like a ruby thing that much. I don't see it a lot. Uh, Things like that, although it's not that weird. I mean, I think it makes sense as soon as you see it so that,

Joel:

sense as soon as you see it in Ruby, then that, I think that's fine. Like

Collin:

it's less weird than like our spec, basically, like it would make, as soon as you saw it and understood the concept, you're like, I get it. Versus like,

Joel:

a big fan

Collin:

or a whatever? Yeah,

Joel:

I'm a big fan of taking. Great ideas from other languages and trying to put them in Ruby and expose ISTs to them. So I'm, I'm all for that. Um, I was thinking, I, I, I know this is technically possible, I don't know if it's like exposed and available through public APIs. Just trying to think whether it might be, um, but there is like a, a rendering state, like a global rendering state for any given Phlex render. Um, that, so you can. Um, the, the way that that Phlex renders, uh, is you hit the first outmost outer component and then when it renders a component, it passes through a buffer. Um, and that's how like, and then that one passes the buffer down and down and down, uh, and eventually comes back to the outer component, which can render its closing tab. Yep.

Collin:

apply your modifier methods

Joel:

Well, so it doesn't just, it doesn't just pass a buffer. It also passes, uh, a context object, which is able to store state about that render no matter like which component you're on. So I was thinking there is a way that you could detect if, if a given component is the first of its type on a page. And if it's the first of its type, it could render additionally some style, a style tag that knows how to style it so that. Then if you ever render that component again, you don't need to render the styles again. They've already been rendered once, but you can, you can render the HTML and they'll already be styled because the first time that component was rendered, it came out with style tags. Um, so that, that might be something that, that would be possible. I don't know if that's very performant, if, if browsers may probably do better. Having all the styles up front in the head. Um, I don't know. Um, but it might be something that's like, just worth it for the simplicity that you'd get in terms of you could just install this Ruby library and use it and the styles would just work. Um, you wouldn't have to worry about, okay, and I also need to MPM install this thing and get it through my asset pipeline and make sure that's all working. Otherwise, it's gonna look like crap and nothing's gonna work.

Collin:

Yeah. I like the idea of it being pretty highly. Here's the thing, if you don't want it to be abstracted, Phlex exists and you can just use Phlex. Right. But, so I think if I was gonna build it, having it be like fairly highly abstracted, cuz you could still just like, it's still gonna be a Phlex component so you could just fall back to that at any time. So I think, yeah, I think having it kind of, I may experiment. I don't know if I'm gonna do how much of that I'm gonna do. I think I'm just gonna see like, could I get like a couple of components that would be useful that you could include and call that way? Uh, Maybe I'll just see if I can get that going and make a little gem for it. And, uh, you can comment on it or other people can comment on it, um, if it's interesting at all. But, uh, you know, if the, if the gem name's available, it's, it's a great gem name. So I think I got that going for me. Um, I mean, no Phlex Wise definitely available. I was thinking of swift ey available. I'm like, I don't think Swifty Wise

Joel:

You could, you could make a swifty i

Collin:

that'd be very

Joel:

I bet it's available.

Collin:

I definitely almost, it's almost certainly is be a very silly name for

Joel:

almost definitely not

Collin:

doesn't Yeah. It'd be

Joel:

no gem names are available.

Collin:

yeah, you, you know what, calling a Ruby gems Swift, I makes me think of is, I forget who the quote is from, but it's the one where it's like the Holy Roman Empire is neither holy nor Roman, nor an Empire I mean, I guess it would be ui. Um, but that's what made me think of, uh,

Joel:

Okay. Swift UI is not taken.

Collin:

Yeah, I'm then trying it with uh, Phlex ui, but um, cuz it makes any sense. Uh, which

Joel:

wonder if the Gem UI is taken. Uh, it is. It's a, it's a 0.0 0.0. Just someone reserving the gem name,

Collin:

'em. Yeah. I

Joel:

you can sometimes get hold of those things.

Collin:

Yeah, that's a good idea.

Joel:

had success. So you could have Ruby Ruby gems.org/uh/gem/ui.

Collin:

That's pretty

Joel:

That would be pretty

Collin:

that's like, that's like right up there. Literal for like, for seo. Uh, yeah.

Joel:

Oh, yeah. Yeah. The Li Literal is such a great s e o gem name.

Collin:

I think UI is just about as good though. I think that's right up there.

Joel:

Yeah.

Collin:

Um, oh one.

Joel:

I was literally like people searching like literal array, like How, how do I define a literal string Like

Collin:

That's

Joel:

ever in Ruby? Yeah,

Collin:

It's all the, um, it's all the developers from other languages or like, how do I, how do I get a property Newman Ruby or whatever.

Joel:

What's the Enum

Collin:

Yeah.

Joel:

Enum literal.

Collin:

yeah. Uh, oh. One thing I wanna mention before we take off is, uh, if anybody's looking for freelance help with iOS or Mac or Ruby, you know what I do. If you listen to the show, you're familiar, uh, get in touch, you can find me a mastodon. That's probably the easiest way. Uh, and then I think besides that, uh, know, if you like the show, do all the stuff I'd say every week. Star it, favorite it, like it, tell your friends and uh, we will see you next week.

People on this episode

Podcasts we love

Check out these other fine podcasts recommended by us, not an algorithm.

Fresh Fusion Artwork

Fresh Fusion

Jared White
Ruby for All Artwork

Ruby for All

Andrew Mason & Julie J
Code with Jason Artwork

Code with Jason

Jason Swett
IndieRails Artwork

IndieRails

Jess Brown & Jeremy Smith
Remote Ruby Artwork

Remote Ruby

Jason Charnes, Chris Oliver, Andrew Mason
YAGNI Artwork

YAGNI

Matt Swanson
The Bike Shed Artwork

The Bike Shed

thoughtbot
Rubber Duck Dev Show Artwork

Rubber Duck Dev Show

Chris & Creston
Dead Code Artwork

Dead Code

Jared Norman
Developer Voices Artwork

Developer Voices

Kris Jenkins
FounderQuest Artwork

FounderQuest

The Honeybadger Crew
Friendly Show Artwork

Friendly Show

Adrian Marin & Yaroslav Shmarov
Mostly Technical Artwork

Mostly Technical

Ian Landsman and Aaron Francis