Building Forms (and Catalyst) w/ Adam Wathan

00:08.80
Chris Morrell
All right? welcome back to another episode of overengineered the podcast where we ask the very important question. What's the absolute best way to do things. We've already got a perfectly acceptable solution for I am here today with ah Adam Wathan um and we're going to talk about forms or maybe not exactly forms. But we're going to start there. Um Adam I I said this about Aaron last last episode and I'm going to say it again today I can't imagine that the you know. Few hundred people who listen to my podcast don't know who you are but do you want to just ah say a quick high in intro anyway.

00:45.80
Adam Wathan
Yeah, sure. So I'm Adam if you know me for anything at this point. It's probably as the person who created tail and css so that's kind of what I work on full-time I have small team people working on it where we make templates and ui components and and that sort of thing and. Put tons of work into the open source stuff too.

01:07.60
Chris Morrell
Awesome! And yeah I mean part of the reason that I wanted to talk today. Is you just ah, launched the the the pre-release of catalyst which is your new kind of ui kit right? excited to have that kind of off the.

01:17.50
Adam Wathan
Yeah.

01:24.91
Chris Morrell
Off the agenda.

01:26.37
Adam Wathan
I'm excited to have it. Um not just like building up ah behind closed doors forever because um, we started I mean I initially put it on the calendar to start building like an initial prototype of it in like October 2000 22 and then we didn't really have time for that cycle just kind of got busy with other stuff and then kept wanting to get to it and then finally like got into it super seriously more April and 2023 built out.

01:45.55
Chris Morrell
Um, okay.

01:56.97
Chris Morrell
Okay.

02:00.25
Adam Wathan
Some prototypes and export some design ideas and stuff like that then we had this like event in June where I kind of previewed it on stage and then shortly after that we deleted every single line of code and started again and um, then basically. Every two months because we run these two month work cycles here. Ah every set of two months you know we intended to get a release out at that time. So it was like okay we're going to get a release out by Ah yeah, end of August and that didn't happen. Okay, well, we'll definitely get it out by like end of October and then that didn't happen.

02:27.29
Chris Morrell
Um, sure.

02:35.46
Adam Wathan
And was like okay we have to get this out in December no matter what because just as a small company. We just can't afford to spend all of the time of every person at the company on this for years on end. There's other things that got to be done. You know.

02:48.49
Chris Morrell
Right.

02:50.79
Adam Wathan
So we did. We did finally get a version of it out in December as you mentioned it's kind of like we're calling it like a developer preview development preview kind of like an early version it it does have a bunch of stuff in there. We started with a focus on like form elements and stuff sort of things that I think people really needed the most. Um.

03:08.57
Adam Wathan
But we still have a lot of ah lot of other stuff. We'd like to get in there. But right now we're kind of like taking advantage of the fact that we got it out in December um, and sort of of ah you know released a little bit of that pressure and we're kind of circling back to some of the other things that we need to. Need to make some progress on and spend a couple months on those and and then ah get back into just like driving out new components for catalyst. It's going to be so much nicer. It's being a state where it's like we can just do one component and release it one component release it one component. It.

03:27.87
Chris Morrell
Sure.

03:40.15
Chris Morrell
Um, right? yeah that makes sense.

03:41.89
Adam Wathan
Instead of where we were at where it's like okay we got to hit some minimum threshold of like releasability here and I think we are barely even at that point but you know just had to make the tough call to ah to just get something out there and you know have a bit of ah, a clean slate. So.

03:45.22
Chris Morrell
Right.

04:01.20
Adam Wathan
But I'm I'm happy with ah where it's at so far I'm looking forward to putting some some more work into it soon And yeah, happy to chat about any of the things they think are interesting.

04:11.69
Chris Morrell
Yeah, so here, let me let me set the stage a little bit. Um just going back A little little ways you know I've been a Pg p developer for a long time. Um, but I came to sort of the larall world relatively recently you know, ah in the five dot. Era Um, and you know prior prior to Laravell we really you know we were just kind of all In-house. Everything was custom built. Um and you know it was mostly just like Ph P Three P P four code that I had written in the late.

04:30.21
Adam Wathan
Huh.

04:47.75
Chris Morrell
90 S and early two thousand s the lake had ballooned out to to all the different places that it did um but when I first sort of switched to larave um a thing that really surprised me was for all the things that laravell offered there was not a form builder and I was just like what. Is going on here like it just seems like this is such an incredibly all encompassing framework and you know my experience of web development is like it's all database access in forms right? You know like tables and forth. Yeah, yeah, the the age-old saying.

05:09.17
Adam Wathan
Ah.

05:18.89
Adam Wathan
It's basically just forms. Yeah tables of tables and forms right? like yeah yeah.

05:26.69
Chris Morrell
So like it just really surprised me and and I later realized that that had changed right? that there what there had been. The.

05:31.11
Adam Wathan
Yeah, we used to have it I think in it was either might have been layer about four definitely layer about 3 I feel like had forms. Yeah.

05:36.86
Chris Morrell
Um, yeah I think it was dropped in the five five dot zero or 5 for the first 5 release whatever that was um and I for some reason I didn't discover the Lareville collective ah version when we first started but I did find your boot forms package.

05:51.29
Adam Wathan
Um, yep, Hu ah boot forms. That's awesome.

05:56.50
Chris Morrell
Um, and we you know we were using bootstrap and Boot forms is like oh great This is like perfect. This is exactly what I'm looking for. But I think either you had already. Ah, okay yeah, um.

06:07.68
Adam Wathan
I Definitely wouldn't be maintaining it anymore at that point. Yeah.

06:13.94
Chris Morrell
So I was like well this is a great starting point I'm just going to fork it and we're just Goingnna we're just going to go from there and we did a decent amount of ah overhaul of boot forms. Um, you know to kind of bring it up to the the the modern laravell sort of feeling.

06:24.31
Adam Wathan
Um.

06:31.89
Chris Morrell
A api I mean it was already pretty much there but just like you know, updated it to to match the modern framework. Um, and we use boot forms for a year or 2 um, but when tailwin you know really took off. Feel like this would us all before like we switched tailwin because we switched tail when in 202018 sometime in 2018? Um, yeah, yeah, pretty early on um and you know we were. We've been honestly we.

06:47.19
Adam Wathan
Ah.

06:54.23
Adam Wathan
Yep, pretty early.

07:04.52
Chris Morrell
I am I am so relieved we just removed our last bootstrap code from the codebase like three weeks ago so we've been running tail win and and bootstrap in this weird horrible custom configuration of everything for all these years and that's you know it's just.

07:11.40
Adam Wathan
Cool.

07:18.88
Adam Wathan
Sure.

07:24.40
Chris Morrell
When you have a big application. Those are the things that you just have to deal with yeah, but um, you know, Basically when we when we decide that we were really going all in on tailwind. Ah boot forms started to really feel like the wrong solution and that's when um.

07:25.15
Adam Wathan
Takes a long time. Yeah, if you want to just kind of get things in a consistent state for sure.

07:43.74
Chris Morrell
That's when I released the the package air which is you know, essentially like a spiritual successor to boot forms in terms of its like Apis but it's all really um, you know it's like tailwind and alpine focused. You know it. It provides a lot of like.

07:50.80
Adam Wathan
Cool.

08:02.88
Chris Morrell
Conveniences around using um you know, well all the default styling is tailwind and then like it's just it's more focused on you know, sort of like a utility Css mindset and it has a lot of features that just meet our needs nowadays. Um, and it's been great. I mean it's It's ah it seems like it's been.. It's been well received. Although I think that the era of form builders is maybe like a little bit past because there's so much focus on like different approaches to frontend.

08:39.80
Chris Morrell
I still think a lot I mean a lot of people must be doing this. We certainly write just straight up blade and and ah Lairrevelle stuff all the time. Um, and like you know, really don't don't dip into react unless we really need it. Um, and so.

08:39.94
Adam Wathan
Ah.

08:44.90
Adam Wathan
Yeah.

08:59.44
Chris Morrell
You know airs just been going along. We're in 2.0 it's been solid for us for years. But really when when blade components came out ah it was just like okay this is the way to write blade now like the xml style syntax just feels so much better.

09:12.38
Adam Wathan
Sure, Yeah, yep.

09:18.36
Chris Morrell
And I've been I've just been thinking about okay air 3 like at some point in air I just added essentially like a bunch of components that pretty much wrap the the um existing method call. Yeah and just kind of like forward attributes to the to the function of the same name. You know it's it's a.

09:29.51
Adam Wathan
The like function calls. Yeah yeah.

09:38.20
Chris Morrell
Pretty naive approach but it's fine. Um, but it doesn't feel great I still use the the you know just echo approach mostly because that just feels more true to what air is right now. Um, and ah.

09:38.32
Adam Wathan
Um.

09:54.00
Chris Morrell
Yeah, so I've just been I've just been thinking a lot about what is like an xml style form building Api look like and so when you you know when you when I started to hear you talk about catalyst and particularly what really what really caught my attention was when you said. Um, part of that like Teardown and rewrite was deciding to switch to individual components instead of like having a single form input component. That's something that I've been really struggling with because and I wonder if maybe part of it is the difference.

10:18.13
Adam Wathan
Yeah.

10:30.45
Chris Morrell
Between the scope of what air does versus catalyst because we're kind of like wrapping up a bunch of like server-side stuff and client-side stuff into one unit. But um, yeah I'm just really curious about that that particular decision and and the other decisions that you kind of made around.

10:39.11
Adam Wathan
Yeah.

10:50.24
Chris Morrell
The Apis that you landed on and um, you know what? your what you? what? you could see improving on further you know, just that's that's sort of the starting point for me. So can you talk about like that decision to to change that up.

10:53.30
Adam Wathan
Um.

11:00.20
Adam Wathan
Yeah, yeah, yeah, yeah, so when I first demoed it at tailin connect we did have these apis that were a bit more like sort of like 1 component that rendered multiple elements you know so you might have.

11:17.30
Chris Morrell
Um, yeah.

11:18.20
Adam Wathan
Think we had like a text field component and it had like a label prop and like a description prop and those would get rendered as like all the right elements and you just get the whole thing as this one unit and there's tons and tons of advantages to that, especially from like a technical perspective because you do have to like jump through some hoops. Um, to make things work when you break things down a lot of the time. Um I think like I'm trying to think if there was any other real nail in the coffin moments for that for me but the big one was just me and Jonathan were working on.

11:41.77
Chris Morrell
Um.

11:56.80
Adam Wathan
This text field thing trying to come up with different situations where we're going to use it and different designs. We want to be able to implement and I just like ran into this situation. What we were doing actually is um, we went through like to and Jui. And we looked at all the form layouts and form related components and just we're trying to make sure can we build this one. Can we build this one. Can we build this one you know and just like going through the list and I think we found one I'll like see if I can find it quickly right here so make sure I'm not talking out of my ass. But yeah, actually you know what.

12:09.33
Chris Morrell
Um.

12:14.47
Chris Morrell
Um, right.

12:24.92
Adam Wathan
Even like the very first one on the page we have this like username field and the username field is like narrower than like the about field that's underneath it and we just started wondering like okay well how would we build that I guess we could wrap our text field with like a Div and just put a max width.

12:33.80
Chris Morrell
Ah.

12:43.78
Adam Wathan
On that Div and that would like constrain the width of everything but then I said to Jonathan well what if the text field had like a description but would you want the description to also be constrained like I don't think so like all we're really trying to do is like constrain the input as a way to signal to the user like.

12:52.92
Chris Morrell
Right.

13:01.47
Adam Wathan
This is about how long we expect the content in here to be. It's like when you have like a phone number field or like a Cvc code field for a payments form or something you know like that's like an affordance that you can give people. It's just that Width thing.

13:05.14
Chris Morrell
Um, sure.

13:13.72
Chris Morrell
Yeah I have definitely dealt with this that this exact problem in like the air Apis as well.

13:18.72
Adam Wathan
Yeah, yeah, so we're just trying to think like okay well what are the different ways that we could solve that like using the existing Api where everything's 1 big component. It quickly starts to feel like okay well we could add a new prop like. Input classes you know and here's the classes that like you can add to the input or we could just add classes to the class attribute that use like Tillwin's arbitrary variance to basically like target the input inside of it and constrain the width of that you know so that's something that we could do. But then you kind of need to know what the.

13:38.69
Chris Morrell
Um.

13:46.66
Chris Morrell
Oh that's kind of interesting. Yeah.

13:55.37
Adam Wathan
Element is that it's rendering and it's really not intuitive in Catalyst because Inputs aren't inputs. They're spans with an input inside of them and that's because um Inputs can't don't have Pseudo elements. There's no before and after element on on input elements.

14:02.96
Chris Morrell
Um, okay.

14:09.90
Chris Morrell
Um, okay.

14:10.45
Adam Wathan
And we need those to create like all the right shadows and stuff that we're trying to do so instead we have to wrap it with a spin put some shadows on the spin. Add some Pseudo elements to the spin then put the input inside of it. So even if you did try to target like the input. You'd quickly see like okay, the input got smaller but the parent shadow is still full Width you know that's surprising.

14:20.75
Chris Morrell
Um, interesting.

14:29.60
Chris Morrell
Ah, right.

14:30.40
Adam Wathan
Um, so then like the alternative to that was okay. Well what if we did just like give people all the individual components. So There's the input component is just the input. The label component is just a label description component is just the description and yeah, ultimately like. That just ended up feeling like it gave us the flexibility. Um that we wanted like ah another situation that's kind of similar is you have like a select that takes like options as a prop as an array or something instead of like a list of child elements and that totally works. But.

15:01.71
Chris Morrell
Ah.

15:07.17
Adam Wathan
You lose that flexibility of like doing something in 1 option. That's a little bit different than the others like say you're building like a list box and it's got like 5 options to choose from it and you're building it as like a custom list box. You can actually style things custom and 1 of the options is like new. And wasn't there before and you want when someone opens the dropdown to see the list and see like a little new badge next to one of the items now like try try expressing that in like the array options format all of a sudden. It's like okay I guess we have to add like new as a boolean option to like every single one of these options and then like.

15:25.67
Chris Morrell
We have.

15:39.85
Chris Morrell
Ah, right.

15:40.33
Adam Wathan
You know decide whether to render that and and the the Apis just like grow and grow and grow to accommodate all these things whereas if you could have just like did what you wanted to do to that element directly. You wouldn't have needed to do that. You know, um.

15:52.55
Chris Morrell
Um I Love that you bring that one up to because that that was like ah that was an ah outstanding issue that we had like that someone had brought up like how do we do option groups and like styling individual options and honestly I can't remember what. What solution we came up with but it was just like you can't with this with this package right now because yeah, we just accept an array. Yeah.

16:11.60
Adam Wathan
Sure, Yeah, yeah, and you end up with lots of props too for like buttons like left add on right? add on you know when whereas if you just like.

16:23.93
Chris Morrell
Yep yep.

16:28.15
Adam Wathan
Think about things as like a tree structure that you just build up with elements. It's like well if I want to put something at the beginning I just I put it at the beginning if I want to put something at the end I just like put it at the end. Um, so that was kind of like yeah we we committed to going that route. For for those reasons just for like maximum flexibility and at first we are a little hesitant in some ways because it's like is this going to feel verbose is this going to feel like a lot of typing is this going to feel like people have to do a lot of work to just like get something on the screen.

16:57.74
Chris Morrell
Yeah.

17:02.77
Adam Wathan
But when we actually like did a side- by side of like okay this is what I would have to write in vanilla html with all the tamb one classes and all that stuff and this is what it would look like with components. It was still like the same number of lines but it still just was very clear that it was an improvement you know? Um, so yeah, we went We went that route.

17:16.88
Chris Morrell
Um, ah.

17:21.90
Adam Wathan
Um I can stop and answer any questions and there's more stuff I can talk about too but is there. Any do you have any thing I Guess that's like what about this? What about that You know.

17:34.63
Chris Morrell
Um, well okay, here's here's I have a couple of thoughts. Um, you know one is I You know I All that resonates a lot and and it it really does point at some of the places where the existing apis that we have are are.

17:51.93
Chris Morrell
Ah, little hard to work with um I think um I think the 1 thing that I I was thinking about earlier today is like okay so in air you know this is what I was trying to get get at.

17:54.90
Adam Wathan
Um.

18:08.54
Chris Morrell
I Think the scope is or the scope is different right? because we're dealing with the entire request lifecycle right? If you if you submit a if you as you're filling out So a form right with air. It's a like rendering all your.

18:28.56
Adam Wathan
Yeah, so like whatever the name is on the field. It knows to kind of look that up in the session or or whatever to find errors on the stuff.

18:28.63
Chris Morrell
Larall Error Messages Inline client side right.

18:38.30
Chris Morrell
Yeah, it's well it's doing it's it's doing it both in ah sort of in both places right? It's both looking at the like you know session errors if the form is being rendered and and like you know, dealing with old input and all that stuff and then it's also doing client side validation.

18:51.67
Adam Wathan
Yep.

18:54.78
Chris Morrell
With your error messages as well. So like we have We basically have like ah a layer where you can even either pass it a form request or just like an array of rules and excuse me and most of those rules we can actually do client-side validation on um, as well. So we're like rendering we're conditionally rendering error messages on the client. Ah as you fill out the form and then like when you submit the form. Um, if there's like server-side errors we're rendering those errors again on the client right? So There's this.. There's a little bit more of an assumption that. That um, you know you're going to have like this whole grouping of things like a label or like ah you know a whole group of elements that might have like an error state and may conditionally have an error message but you don't know when you're writing the markup.

19:51.62
Chris Morrell
Whether that error message is going to be visible or not like it's It's context dependent. Um, so like at the very least instead of it being like a help block or something like that. It'd be like a you know? ah you know.

19:57.32
Adam Wathan
Um.

20:09.41
Chris Morrell
Error ah placeholder or whatever you know like just just put this like if there are errors you render them here. Um, and so there are things like that where I think when the form builder has more awareness of like.

20:12.33
Adam Wathan
Sure.

20:28.58
Chris Morrell
Broader context and and it's less like really you I focused that changes some of the the considerations I don't know that it changes in an enough. Um.

20:38.91
Adam Wathan
Yeah, yeah, it's tricky I get what you're saying like you have just these things where like obviously you can like hoist those concerns like out to the call site where you're like building the form but now that's like something you have to do every time yourself instead of just having it like magically.

20:51.66
Chris Morrell
Right.

20:57.48
Adam Wathan
Handled for you. Um.

20:58.99
Chris Morrell
Um, did you ever consider just like you know you have the whatever the field and the label and the input elements but you also publish the like apparent element that just does a default.

21:06.46
Adam Wathan
Yeah, yeah, yeah, and that's kind of how we thought about the whole thing like that was kind of like what we told ourselves in our head when we decided. Okay, you know what like I see the value in like the bigger components but it seems like the smaller ones are definitely.

21:24.43
Chris Morrell
Right.

21:25.37
Adam Wathan
Required so let's do those first and think of those as like building blocks for anything bigger if we want to offer anything bigger and I I feel like there were times where there were where some things did kind of coexist I'm trying to think right now if we if we shipped anything like that and. So some things that changed. So for example, like the checkbox component used to accept like the label as the children so you could just render like a checkbox with a label by just doing like checkbox and put the text inside of it and um.

21:55.49
Chris Morrell
Um, sure.

22:03.60
Adam Wathan
But you could also just pass no children and just get like just the checkbox and like connect your own label to it if you needed to do like a custom style or something but ultimately like we ended up just shipping it where like the checkbox just does 1 thing and I feel like there was probably a good technical reason for it. But it also just kind of felt at the end of the day strange that like.

22:12.10
Chris Morrell
Um.

22:23.42
Adam Wathan
Did 2 different things you know? So um, yeah, exactly I just felt like the apis were then kind of inconsistent like how come I don't need to use a label component every time I use a checkbox but I do for for everything else. So I could still see a world where like we.

22:24.91
Chris Morrell
Um, right? Well especially when everything else is so focused.

22:37.15
Chris Morrell
Um, yeah.

22:41.51
Adam Wathan
Did that and maybe we don't in catalyst but I did we did kind of like tell ourselves in our heads every time we ran into like a tricky decision like a lot of the time the answer was like well someone can always like wrap this up into the opinionated component that they reuse a ton of times and and even if that's just like a component that they're just using on one page. They might just like.

22:54.20
Chris Morrell
Um, right right.

23:00.94
Adam Wathan
Make it a little small little function at the top of the file and you know we're talking react land here but then just like reuse it in that context and and and then kind of be be done with it. So for us because it's kind of like a Ui kit I did feel like we had to try and be careful not to be Like. We don't want to be not opinionated enough that it's like not Opinionated. You know the whole point of it is to be opinionated tailwind is the thing. That's not really opinionated when it comes to like what a form input should look like you know, but also didn't want to be like we also wanted to be careful.

23:23.27
Chris Morrell
Right.

23:33.11
Chris Morrell
Um, right.

23:39.34
Adam Wathan
I'd rather someone have to like type it a little bit more than like have to try and sort of like circumvent opinions that were like baked in you know what? I mean.

23:45.75
Chris Morrell
Right? Yeah, no I think that's an an important sort of like distinction.

23:53.93
Adam Wathan
Yeah, because I feel like that type of frustration is like a more hostile type of frustration. You know, um.

23:58.61
Chris Morrell
Ah, absolutely absolutely. Yeah yeah I mean it's It's basically the ah the final debate.

24:05.99
Adam Wathan
Um, yeah, sure. Yeah yeah, like don't make me have to undo things you did you know to ah to do what I want to do everything feels a little bit nicer for if it's always just like additive you know versus like subtractive changes that you have to make to things.

24:12.54
Chris Morrell
Right.

24:23.83
Chris Morrell
Um, yeah, 1 um, because that's I think I think what I'm leaning towards right now is basically what you're talking about like ah there'd there'd be low-level components and you could use them and they would be.

24:24.20
Adam Wathan
Um.

24:39.67
Chris Morrell
Designed to work you know to to kind of like account for the different scenarios that they might be used in. Um, yeah, but I think that I think that what I'm I'm leaning towards is also.

24:46.27
Adam Wathan
But you might have to do a bit more wiring yourself compared to like if you use the big pieces.

24:58.77
Chris Morrell
Um, you know, essentially publishing like an input group component right? like ah and then you know the the Api decision that I'm still kind of like on the fence on is either.

25:01.86
Adam Wathan
Yeah.

25:15.93
Chris Morrell
The input group is just it is what it is and then if you want to change it. You just publish. You know you just publish the views and you modify it. However, you want or you know with Laravelle There's the opportunity to do like name slots. So I'm thinking that there may be a way to essentially have like.

25:28.95
Adam Wathan
M.

25:35.84
Chris Morrell
There's the input group component and if you want to hijack the way the label is rendered right? You could just do Xlot label right.

25:41.11
Adam Wathan
Sure you provide a? yeah yeah, yeah, yeah, that kind of how v works if I remember right too right? There's like named slots but the component can define like the default content of that slot and if you provide something from the outside it'll override it? Okay, yeah, yeah, so if if the layer of our 1 works that way which i.

25:55.97
Chris Morrell
Um, okay yeah, I'm not familiar with view. So I don't know. But.

26:00.93
Adam Wathan
And bet it does because I think it was very inspired by like a lot of the way view does things.

26:05.10
Chris Morrell
Um, it's yeah, it's not um, you you have to kind of hack around it a little bit but it's definitely possible. You know I I explored it a little bit.

26:12.49
Adam Wathan
Yeah I think that's a cool idea like we could do that too really like just like okay the input isn't exactly like what I need in this case. Well let me just pass in the input you know instead.

26:26.42
Chris Morrell
Um, right.

26:27.75
Adam Wathan
Yeah, it's just like a default parameter that happens to be filled in for you by default. Yeah, that's an interesting way to think about it for sure.

26:32.37
Chris Morrell
And then it's like okay if that doesn't get me what I need right? because I in this particular case I need the label to be on the bottom in the like actual structure of the dom right for some for some reason I I need it or I need it to be. You know. They need to be side by side I Need to do some crazy thing that is just outside of the context of what is Configurable. You always can drop down then to that lower level of just okay for this one use case I'm going to render the field and I'm going to render the label and the help block you know. However.

26:53.15
Adam Wathan
Yeah.

27:03.36
Adam Wathan
yeah yeah I think that's the important thing right? like I don't think like there's anything like inherently wrong with the idea of having these like bigger components that group things together I think the the Dis the thing to decide is like.

27:09.77
Chris Morrell
And.

27:22.69
Adam Wathan
Whether you solve customization concerns by just like throwing more props at the problem. You know what I mean or whether you just say like if it's not right like here's what I made it with like do what you want use the pieces that are useful use the pieces that don't use the pieces that aren't like that feels like.

27:28.92
Chris Morrell
Um, right.

27:41.38
Adam Wathan
It's it's kind of like in a lot of ways similar to how Laravell philosophically like how it handles a lot of things internally where it just gives you a callback. You know what? I mean it's like you're trying to configure something should this person be able to access this route or not like I could just have an array with a bunch of rules and a bunch of stuff or it's like why don't you just.

27:48.83
Chris Morrell
Yeah.

27:59.71
Adam Wathan
Tell me whether this person should be able to like access it or I mean um, yeah, it's like a are you a Seinfeld fan. Yeah yeah, the.

28:00.79
Chris Morrell
Um, right? you just decide. Yeah, yeah, yeah, that's a good as much as I mean you can't not be a Seinfeld fan a little bit I guess.

28:13.18
Adam Wathan
I don't know if you remember the episode where Kramer has a new phone number and it's like very, it's like 1 digit off of like the movie hotline that people are always calling to find out what times movies are playing and he answers the phone and he's like if you'd like to see you know death blow.

28:19.76
Chris Morrell
Yes.

28:29.43
Adam Wathan
Press too and here's like some here's on like Dialtonne he's like you selected and he gets it wrong every time because he has no idea what these dilatones are at the end of the college just like why don't you just tell me the name of the movie. You'd like to see you know that's how I got of feel about the la of all Apis you know so.

28:36.93
Chris Morrell
Ah, yes.

28:45.00
Chris Morrell
Right? Yeah, yeah, no I think that that's I think finding that that um that like balance of let me give you some really nice scene defaults and in a lot of cases. You can just you can just use these.

29:00.90
Adam Wathan
Um.

29:03.82
Chris Morrell
Because that's the thing that I that's the thing that I worry about if we go too far down the other path like yes with select inputs right now it really sucks to not be able to customize an individual option. But.

29:18.91
Adam Wathan
Um, yeah.

29:22.30
Chris Morrell
99% of the time I just want to pass an array of options right? and.

29:24.28
Adam Wathan
Yeah, yeah, so do you make everyone suffer 99% of the time to be able to do the thing 1% of the time like that's yeah.

29:32.10
Chris Morrell
Um, right? So it feels like you could You could get the best of both worlds there where there's an options prop on the select input right? and that just if that's there it uses it. But if you have options as children.

29:40.34
Adam Wathan
Yeah.

29:49.33
Adam Wathan
Totally yeah.

29:49.78
Chris Morrell
Just uses them instead right? And yes you deal with the fact that like what what do I do if I get both like you'd have to handle that. Ah, either you know, have to throw an exception or something but um, you know for us even more like we have. There's like an interface that you can add to.

29:56.85
Adam Wathan
Sure yeah.

30:08.75
Chris Morrell
Ah, anything and there's like a trait that you can pull into a model that essentially is just like this is how to render this model as an air option. So then in in my controller I can just pass down a collection of models.

30:19.11
Adam Wathan
Um.

30:26.70
Chris Morrell
And air just knows how to render those models as options for you right? I don't want to like lose that um convenience having to loop over everyone and render an option option component and pass in the like model's key is the the value and then the like label as the label you know like.

30:28.38
Adam Wathan
Nice. Yep yep.

30:46.58
Chris Morrell
Most of the time that just works exactly the way I want it to um and so I think um I think that my hope is that we can still provide those conveniences. But yeah, figure out a way to get those like lower.

30:49.37
Adam Wathan
Um, yeah.

31:02.84
Chris Morrell
That that lower level access if you need it.

31:05.97
Adam Wathan
Um, yeah I think that's totally like a good approach that there's not really any downsides to that you know? Um, yeah.

31:14.71
Chris Morrell
Yeah, yeah, another interesting I was just talking about this kind of when I was thinking about how I wanted to approach this talk like um, another package that we maintain is called Grattl and it's just like ah the.

31:32.50
Adam Wathan
Oh.

31:32.82
Chris Morrell
Breadcrumb package you know like um and you know the nice thing is you define your breadcrumbs in your routes. So just as you're defining the route you define the breadcrumb and then there's just a single blade component that you render that just prints out the breadcrumbs in like. 1 of 1000000 different ui framework styles. Um, and we do provide like the option to publish a view. You know like publish ah vendor Gretel layout that blade peachpeer. Whatever you know whatever it is.

31:52.26
Adam Wathan
Sure, Yeah, yeah.

32:10.50
Chris Morrell
If you want to override that but we also just like accept an argument like a prop on the component that's like use this view to render the breadcrumbs for this particular instance and um I feel like there may be some interesting thing there because.

32:20.95
Adam Wathan
Um, yep.

32:27.95
Chris Morrell
Um, another thing that Gretel does is it exposes a bunch of ah functions to your view for handling like the Aria attributes. Um, and like the active and inactive class names like all that stuff so like. Even if you're rendering your own custom view. You still get access to those functions and so I was kind of thinking. There may be a world and I think this would be easier to do in blade than it would be in react. Um, but I think there's maybe a world where like that form group has a default.

32:46.87
Adam Wathan
Yeah, yeah.

33:02.84
Chris Morrell
Ah, default view. Um, but you could just pass it another. Ah you know view name and then it would just render the form group through that but it would still provide all the like context. Um. And you know expose a bunch of those helper functions so you could still like if you want to deal with really complex error state logic or um, you know, understanding like what's the current bound value for this field and stuff like that like you still have access to that in your custom view. But again, you'd just be able to like for this 1 spot like build a custom partial that renders like the form group for that and you wouldn't have to override the whole form group component I think there's something interesting there but I'm not quite sure yet.

33:58.42
Adam Wathan
Yeah, how would that work in terms of like would you still be responsible for like making sure your template includes that error messages like outlet and stuff like that or whatever.

34:11.22
Chris Morrell
Um, I think that like you would just have full control then but if you use like if you drop in the error message component inside of your view like it should still have the correct context. You know.

34:27.30
Adam Wathan
Gotcha so that it's almost like a way to basically take like a customized thing that you want to use more than once and that Kavin easy way to use it more than once like I I guess you could just make a.

34:38.22
Chris Morrell
Um, yeah.

34:40.00
Adam Wathan
Component for that too right? like just a blade component.

34:41.95
Chris Morrell
Um, you could the advantage would be this would essentially be like we're still taking on the responsibility of all the component level logic right? And you're only responsible for rendering the view right? like.

34:54.62
Adam Wathan
Um, got it.

34:59.13
Chris Morrell
You get all the props um that any form group would get and you can do whatever you want with them. Um I I think that that could be a nice way because then if it's like yeah I just want to render in this 1 place.

35:01.67
Adam Wathan
Sure Yep yep, yeah, that makes sense.

35:15.59
Chris Morrell
This weird horizontal form that I need to render things like inside. Ah you know you know in a really strange layout. Ah I'm just going to grab the default view and just tweak it for this one use case and now I can just do like X form group view equals.

35:29.78
Adam Wathan
Sure. Yeah, yeah, yeah I think that would work.

35:35.37
Chris Morrell
My view you know. So are there any other like when you were when you were playing with these catalyst Apis like were there any other aha moments you had around. Oh I Really want this like this or like. The way that this api feels is not right like we need to rethink this.

35:57.23
Adam Wathan
Yeah let me think the yeah the api stuff I'm looking through like the Docs right now just try and see like there were certain things that we debated like originally button actually I think. This is actually still the case. Yeah, okay, so this is something I didn't even remember like where we landed on but like 1 of the hard decisions was like deciding like can a button component be a button and a link you know because that's like a common thing. You just have a link that looks like a button but it's not actually like a button type button element. So that was something like we wrestled with.

36:28.52
Chris Morrell
Um, sure are.

36:35.67
Adam Wathan
Um, quite a bit. Ultimately, we ended up just having like a button that can take an href prop you know and now it acts as a link I'm trying to remember if there was like a specific thing that like pushed us over that edge I think it was probably to do with.

36:53.91
Adam Wathan
Um, like we we have avatars and we wanted avatars to be able to be used as buttons and also be used as as links and ah, you know we had some some stuff around that where it's like okay well should the avatar just be able to accept like an hf. Prop 2 and now the avatar access a link. Well if an avatar can do that like why can't a button do that? Whatever we decide should be like sort of consistent. You know and I think there was like ah there was no like right or wrong answer for a lot of these things but they they are just like examples of the sort of like Api decisions. You have to make decisions around I think like.

37:15.72
Chris Morrell
Right.

37:27.55
Chris Morrell
Yeah.

37:30.91
Adam Wathan
Have like a pagination component. That's like exact opposite of probably how any blade pagination thing would ever work like to me that's like a classic example of like you probably just want a bunch of options passed into this thing. Whereas ours is just elements. You know so there's like a pagination wrapper then there's like a pagination previous element which is the previous button and you can sort of lay them out. However, you want and a lot of it's kind of weird because it's like well there's only 1 right structure for this, you know and you're letting people technically.

37:45.35
Chris Morrell
Um.

37:48.90
Chris Morrell
I write.

37:57.16
Chris Morrell
Right? Yeah yeah.

38:03.40
Adam Wathan
Make it possible to do the wrong thing because what if they put the next button at the beginning in the previous button at the end you know I mean um and ah.

38:10.69
Chris Morrell
Um, well I mean you might want to have the previous and next buttons next to each other and then the list like I think that's a viable.

38:17.41
Adam Wathan
Yeah, yeah, but then like does our component actually know to like adjust the spacing to make that stuff work and and that's actually maybe an interesting topic. It's just like how we've all the different ways we kind of explored for handling like.

38:23.63
Chris Morrell
Right? right.

38:35.27
Adam Wathan
Kind of ah contextual layouts you know so you have ah an input with a label with a description like how do you make sure that the right margins are there when the components are present but not when they're not present and and stuff like that and if you um.

38:35.70
Chris Morrell
Yeah.

38:50.53
Adam Wathan
Like for example, our input component. You can put the description right? under the label or you can put it like right under the input itself and the paddings or the margins are a little bit different depending on where you put it but can't just be like the that's not the description component can't just have like empty 2 built into it or whatever.

38:59.80
Chris Morrell
Right.

39:05.66
Chris Morrell
Right? Yeah I was curious about that like are you doing that all in Css or are the components talking to each other.

39:08.60
Adam Wathan
Um, so yeah, so we are doing it in Css um, originally our first version of it was using react context. So I don't know like how much react you do.

39:23.91
Chris Morrell
Um, yeah I'm I'm pretty familiar.

39:28.33
Adam Wathan
Sure So you know so basically like I think it'd be like our field component like the wrapper component would basically basically pass down some effectively like readable by any child information that just said okay, the label should have these classes. The input should have these classes. The description should have these classes and.

39:34.22
Chris Morrell
Um, yeah.

39:44.45
Chris Morrell
Um, yeah.

39:47.53
Adam Wathan
Um, you know they would just read from all those Contexts and apply the classes correctly and stuff like that and that did generally work but it just kind of felt like.

39:54.90
Chris Morrell
So were you like looping over the children to determine that like you were just looking at the order of the children.

40:02.66
Adam Wathan
No yeah, so that that didn't handle that problem like Vick the position of things it just like made sure that they actually had um what they needed so that I think was one of the reasons that I like pushed us away from.

40:13.60
Chris Morrell
Okay.

40:19.97
Adam Wathan
From that solution. Ah so what we ended up doing is basically using tail ones like arbitrary variance from the parent to target the children and there's a lot of like crazy ones in there where it basically says like like you know how in Css you have like the um, the sibling ah cominator like the plus right.

40:28.50
Chris Morrell
Okay.

40:38.31
Chris Morrell
Um, yep.

40:39.71
Adam Wathan
So we have like an arbitrary variant. That's like when there's an input plus a description that description should have an Mt of this when it's a description plus an input then the description have a margin bottom of this. Um and we do that for like.

40:49.12
Chris Morrell
Um.

40:53.70
Adam Wathan
For a ton of different stuff even like buttons like if the button has an icon and the icon is on the left. It should have like this negative margin if it's on the right. It should have this negative margin. Um.

41:02.61
Chris Morrell
Um, are you targeting like ah for a lack of better term like semantic class names there or just like at the element names. Okay.

41:09.95
Adam Wathan
We're we're targeting data attributes. So a lot of ah most of the components in catalysts that are like meant to be nested in things have what we call this like data slot attribute.

41:22.10
Chris Morrell
Ok.

41:24.66
Adam Wathan
So this was something that I kind of picked up looking at like react Aria components. Um, they do a similar thing where they just use the native html slot attribute which is meant for like sort of like shadow Dom Web componentee stuff but is a valid attribute on any element and just does nothing outside of the shadow dom.

41:26.67
Chris Morrell
Okay.

41:37.00
Chris Morrell
Okay, oh interesting. Okay.

41:44.15
Adam Wathan
So you could just target something that has like a slot of description or a slot of label or whatever and it would add those styles to it. Um, we went with data slot because we eventually discovered that Svg Elements cannot have the slot attribute. That's not a valid attribute on svgs.

41:50.69
Chris Morrell
Ah.

41:58.20
Chris Morrell
Okay.

42:02.10
Adam Wathan
And was like ah so do we just make the svg one use data slot and everything else use slot might as well just make it all data attributes. So all of our icons have like data slot equals icon and if you download like our herroiccons libraries for react, you'll even see like that's actually like baked in to make it as easy as possible to integrate with catalyst.

42:05.24
Chris Morrell
Right.

42:18.16
Chris Morrell
Um, oh yeah, nice.

42:20.99
Adam Wathan
So that's what we're targeting. We're targeting these like data slot. Um attributes on everything and like yeah using like the the sibling selectors using like even doing things like okay if this is like the first child then it should be this if it's like the last child that should be this. It starts to feel like a lot like more traditional css type of like.

42:35.13
Chris Morrell
Um, right? Yes, yeah.

42:39.56
Adam Wathan
Wizardry you know, but it makes things like very magical and and shockingly effective. Um, the other cool thing. Yeah yeah, like basically if we can dream up a valid reason why someone would put things in 1 order or the other we can like make it look good. Yeah.

42:47.80
Chris Morrell
Um, yeah I can imagine. It's very resilient too. Um.

42:58.34
Chris Morrell
Um, yeah.

42:59.21
Adam Wathan
And um, if you want to like escape out of that for whatever reason. Um I can't remember if actually if this survived or not because there's 2 ways to now at least at 1 point we just made like that slot. Ah a prop. So if you had an input you could just like set the set the slot to null and then it wouldn't inherit any of those styles from the parent and you could just add the styles yourself. Um.

43:17.25
Chris Morrell
Um, okay.

43:22.70
Chris Morrell
Um, okay oh sure right? Well doesn't I was going to ask doesn't targeting data attributes Also give it a lower selector precedence like wouldn't.

43:38.50
Adam Wathan
It's the it's the same as a class but because it's coming from the parent I think it's actually like is it one higher. It's probably yeah it it I think it's actually not even higher.

43:40.26
Chris Morrell
Okay.

43:47.15
Chris Morrell
Um, well yeah, it would be higher specificity right? because it's it's like ah a nested selector. Yeah yeah, right? Okay, okay.

43:52.23
Adam Wathan
It would because it'd be 2 classes. It'd be like the class on the parent then like the direct child then like the attribute selector. So I think that it ends up being like an o o 2 or o 2 o or something. Um, yeah, so you do have like some specificity stuff to deal with there which is why it's nice to be able to like remove that slot or what we actually. Encouraging the docs is every single like top level wrapper component that defines layout styles and catalyst like our field component for input fields and select fields or um, what's like another wrapper component. Ah I don't think that one.

44:24.62
Chris Morrell
Like table.

44:30.83
Adam Wathan
Works that way. So it's more stuff like like list boxes and and stuff like that. Um, all of those components have like a corresponding like component in Headless Ui Um, and Headless Ui is like our react library that does all the crazy accessibility stuff but does no styling.

44:36.21
Chris Morrell
Um.

44:42.64
Chris Morrell
Um, okay.

44:45.86
Chris Morrell
Right.

44:49.16
Adam Wathan
So a lot of the stuff in Catalyst is actually just like a themed version of a headless Ui component and that's ultimately why like we chose to use Headless Ui instead of building it with like an existing well instead of using like someone else's react library because there are other great Headless react Ui libraries that actually.

44:54.99
Chris Morrell
Ah.

45:07.65
Adam Wathan
Have more features than headless who I currently does but by using our own library. It was like we could like change the library to accommodate catalyst and obviously we don't do it in a way where like only works for catalyst but it was just like we want to make it easy to build things like catalyst and we want it to be as thin.

45:14.64
Chris Morrell
Right? You can custom tailor it.

45:25.61
Adam Wathan
A layer on top of it is possible. So um, so yeah, if you're building an input group and you don't want the layout styles at all, you can just import like field from Headless Ui instead of field from Catalyst and you get like the unstyled one and it still has all the behavior. It's still.

45:28.20
Chris Morrell
Um.

45:40.87
Chris Morrell
Right? right.

45:45.16
Adam Wathan
Adds ids to everything and all the right Aria attributes and everything but now all of the components inside of it are just going to be smushed together and you can do like the layout yourself. Um, so that's like where we ultimately landed. It has worked pretty well. It does mean that like the class lists like if you look at some of the catalyst stuff and like.

45:55.13
Chris Morrell
Ah.

46:04.93
Adam Wathan
View source. It is a mouthful of ah of classes for sure, especially when you start thinking about dark mode as well and all the different states like the form controls are by far the craziest because.

46:09.32
Chris Morrell
Ah, sure.

46:20.11
Adam Wathan
You got like disabled states you got focus days. You got hover states you got dark mode versions of all those things you have like forced colors mode which um, most people don't even know what it is but it's like a high contrast mode in windows that most people just don't design for it. But in our case feels like.

46:23.16
Chris Morrell
Um, right.

46:30.86
Chris Morrell
Yeah.

46:37.12
Adam Wathan
Kind of have to design for it because it's um, we're selling code. You know what I mean so I feel like if we know about something then it's sort of like ah negligent for us to not like solve for it. You know.

46:46.97
Chris Morrell
Um, yeah, well and I think that that's the reason like I don't know just for for me personally like obviously there are a ton of like Ui kits out there that use tailwin nowadays but generally.

47:03.86
Adam Wathan
Um.

47:05.53
Chris Morrell
Always go to tail when you eye first at least because I like I just expect that all that stuff has been thought about you know like I think despite whether the fact you know most people are not ever going to be thinking about high contrast mode but just the fact that you have accounted for it. Just.

47:13.13
Adam Wathan
Um, yeah.

47:24.99
Chris Morrell
Is another reason to be like oh well I'm always going to reach for this because I know everything's been thought through.

47:26.55
Adam Wathan
Yeah, yeah, and you'll find bugs I'm sure about but you'll never but there's so many bugs you won't find you know mean that you won't even realize like we had to work around. But yeah, that's kind of like the nice thing about using this sort of thing.

47:35.96
Chris Morrell
Sure.

47:45.92
Adam Wathan
You have people spending like an unreasonable amount of time trying to like work out every dark corner of it. You know there's edge cases that are solved in there that you don't even realize are there to solve. Um like I'm just looking at our like list box right now and it's got like a min height on it and I'm like oh man I.

47:51.10
Chris Morrell
Um, right.

48:04.47
Adam Wathan
Can't remember why that's needed. But I guess it's I guess it's needed. You know what? I mean.

48:07.20
Chris Morrell
Um, there's I just ran into there's like a weird um you know when you're when you're dealing with like flex. Um I don't know if this is if that's using flexbox or grid but like. There's There's a scenario where you need to add a min height to get like the max Width stuff in flex to work I don't know I just bumped into this the other day.

48:29.18
Adam Wathan
Yeah I would be surprised you know? Yeah, there's all sorts of like hairy horrible stuff. Man.

48:37.89
Chris Morrell
Um, so one thing that like you know I I know that there's like an error message component right? But like how do you? How do you go about like if I want to So if I want to render sort of ah, an entire error state.

48:46.33
Adam Wathan
Yep.

48:55.92
Chris Morrell
Right? Like I've got an input. Maybe I want some sort of I want like styling around the component as you know like a red border around the input itself. Maybe like the the label color is different or there's like a star next to it or so you know some sort of styling around the label.

49:11.63
Adam Wathan
Yeah.

49:14.44
Chris Morrell
Maybe even styling around the whole like group or field or whatever you want to call it as well as showing the health text like have you thought through keeping that stuff in sync or is that just something that you just have to deal with.

49:17.28
Adam Wathan
Sure. Yeah, yeah, yeah, yeah, we did think about that right now we don't We just kind of say like okay, well like the input has an invalid prop and you can just set that yourself. You know by just like checking wherever your errors are and seeing if an error is present and then same for like rendering the error message you can just check um does it have an error for this one. Okay, then render the error message. Um, and I've I've.

49:33.59
Chris Morrell
Um.

49:44.55
Chris Morrell
Ah.

49:47.73
Adam Wathan
If our styles were any more complicated than that I think I would have been pushed a lot harder to try and like just be able to set like an invalid on like the whole field and then have that be like red and I think I'm remembering now that that literally did exist at 1 point because that's how our disabled states work.

49:55.41
Chris Morrell
On the field itself.

50:04.79
Chris Morrell
Okay.

50:06.40
Adam Wathan
For sort of the same reason So when you disable like an input in catalyst. We also like reduce the opacity on the label. Um and to have to do that in both places or even on like the description was like ah that's kind of annoying and be nice if you could just set like disabled on the field.

50:13.43
Chris Morrell
Um, right.

50:22.59
Adam Wathan
And there was like some sort of prior art for this too because the html field set element works this way you can like disable a field set and everything inside of it gets disabled So our disabled styles work that way already and we could definitely make the invalid styles work that way too. So on a field you just could have invalid.

50:26.25
Chris Morrell
Right? yeah.

50:42.70
Adam Wathan
And then whatever the condition is that says whether it's invalid or not and that would be like inherited by all the children. The thing that was like a sticking point for us that we couldn't make a decision on was the error message should you just always render the error message permanently but like its visibility is controlled by like whether the parent.

50:58.27
Chris Morrell
Um.

51:01.40
Adam Wathan
Has like invalid true or not. You know.

51:03.81
Chris Morrell
Ah, yeah I mean I feel like yeah, that's it's that's tricky.

51:10.60
Adam Wathan
Yeah, unless you can name it in a way where like you kind of suggested earlier. It's almost like an error an error. Yeah, you know it's like it's like ah a place where it might go if needed you know, but you have to like name it.

51:17.54
Chris Morrell
Um, error slot or something like that are right.

51:25.20
Adam Wathan
In a way that communicates that because if it's just like error message. It feels like it's there. You know what? I mean. Um.

51:27.87
Chris Morrell
Right? Yeah I don't really from like an api perspective I don't I don't really see a problem with saying like field invalid and then like like field invalid equals error. Whatever you know like the valid state.

51:41.34
Adam Wathan
yeah yeah yeah yeah yeah I think it's a cool idea like I'm thinking about some of the details like 1 potential tricky thing is like well if you haven't set invalid on it.

51:44.76
Chris Morrell
And then you just have let you just conditionally render their message if error is set as well.

51:58.63
Adam Wathan
And you have an error message does that mean you want the error message to definitely render I think it probably means you do So it's almost like if invalid is undefined. Well then the error message is rendering unconditionally. But if it's set to false explicitly false then you can hide the error message you know stuff like that. Yeah.

52:00.59
Chris Morrell
Right.

52:12.90
Chris Morrell
Um, oh oh, that's interesting. Yeah, that would be cool. Yeah.

52:18.21
Adam Wathan
So yeah I think that's like a good example of a simplification that could be made to the api that I think would be like fairly safe because it kind of comes back to what we were talking about earlier where it's like you could still that still decomposes into like. Individual invalid stuff if you if you don't want the label to be read in this case for some reason just like don't put it invalid on the field and instead put it on the input in their message and don't put it on the label. You know? Yeah, just go down 1 level you know and like hand a little bit more manually.

52:39.66
Chris Morrell
Right? right? They both have that prop as well. If you want to do it? Yeah yeah, yeah, that's definitely something that I've been I've been trying to think through is just like to what degree.

52:50.94
Adam Wathan
So I think that would be a cool improvement.

52:59.11
Chris Morrell
Because we don't try to think this through um you know, right now there's really only 1 level of like nesting right? There's like the form component and then there's all the elements inside the form and each element ah is aware of the current.

53:12.34
Adam Wathan
Yeah.

53:18.41
Chris Morrell
Like the form that's being rendered in because you know we also do like value binding so I can just like pass in an array of values to the form and now if you have an input that has the same name like that value is bound right? and um, like the same with the alpine stuff like you could just say like as alpine component and then it's going to.

53:30.37
Adam Wathan
Yep.

53:38.40
Chris Morrell
Um, watch all the individual elements that you render inside the form and once the form has closed. It's going to take all those elements and create like a default alpine state for you out of the box right? Some nice convenience stuff like that and so there's like a little bit.

53:50.82
Adam Wathan
Um, yeah.

53:56.18
Chris Morrell
Of cross communication between the the individual inputs and the form and I can see a world where like if you had that like third level of nesting or a third level of like abstraction where um, those form groups for lack of better term. You can go down to the to the individual component level like I can see an argument for just like saying okay well when I'm rendering a form group like each individual component phones home to the parent form group that it's being rendered in.

54:30.88
Adam Wathan
M.

54:32.79
Chris Morrell
And you just like kind of make decisions based on that because then you could just say okay like if I have a field with ah like an error message in it like just implicitly set the the invalid state to true unless I've explicitly said it you know and like I can see how you could argue that that.

54:46.87
Adam Wathan
Yep, yeah.

54:52.65
Chris Morrell
That's like a little too magical in some places but I I don't know my preference is like make it make it good by default.

54:56.40
Adam Wathan
Yeah, yeah, a lot of a lot of stuff works that way in not really in callous itself. But in Headless who I because that's kind of like a pattern that you're sort of forced to do in react a lot a lot of time but the ah the thing that's unfortunate about it. Least in react is the only way to do that means like the component has to render and then the child talks to the parent changes something in the parent and then everything re-rendders again and now now it's in the correct state. So that means like your server side rendered html is like not right ever you know which is.

55:21.11
Chris Morrell
Forces a rerender. Yeah.

55:29.84
Chris Morrell
Um, always wrong. Oh that sucks? yeah.

55:33.50
Adam Wathan
Really annoying. Um, so we try to like avoid that for things that feel like quite important even in that situation. It's probably fine. You know you have like your Aria Invalid states and stuff that need to be on things but by the time a screen reader sees it I'm sure it's right, You know.

55:49.24
Chris Morrell
Right.

55:52.10
Adam Wathan
But it's still like is a little bit just like I Just wish it was just right from the beginning. Yeah, um, yeah, it's like it's like race conditions everywhere is kind of like what react development is when it comes to those sorts of patterns. Yeah.

55:55.88
Chris Morrell
Um, ah right right? Ah, could well well yeah for sure. Oh my god yes I I I was tinkering with a. I haven't written much react in a little while I was tinkering with something in react and it's like because of the nature of of what I'm I'm implementing. It's just like use effects everywhere that are all like dependent like it's the It's all the bad things right? It's a million use Ras and use effects that are all like sort of trying to synchronize with with ah stuff that isn't meant to be used with react you know so it's just like trying to force it to work in that context and it is ah it just.

56:30.69
Adam Wathan
Sure here.

56:47.29
Chris Morrell
The state synchronization and like race condition stuff is a nightmare to deal with but I was going to say like for catalyst if you had let me think about this you if you had like if you own the.

56:51.46
Adam Wathan
Yeah, ah.

57:04.47
Chris Morrell
The form input component right? You could render each child first and then pass all of those children into the parent.

57:06.79
Adam Wathan
Yep.

57:22.94
Chris Morrell
After they've been rendered. Um and I don't know if that would work right? but couldn't she just do like you know let label equals label right? let.

57:40.29
Adam Wathan
Yep.

57:40.93
Chris Morrell
Input equals input and let ah error message Equals Error Message. Um, and then once you have those 3 you know those 3 objects in memory. In your parent component then you pass those 3 into the form group component and somehow like at that moment pull out the data that you need I don't know.

58:03.81
Adam Wathan
Yeah, like this this the specifics of it is like imagine you, you're saying I want the presence of the error message to dictate whether the input component. That's right before it and it's sibling has like Aria invalid equals true on it right.

58:21.88
Chris Morrell
Um, right.

58:22.50
Adam Wathan
So. The way it has to work right now is yeah, you render the whole you render the field which renders its children which has an error message. The air message has a use effect. That's like okay use that some shared contacts to basically say hey parent I exist therefore this is invalid and then the parent's like oh. I better like tell everyone that this whole thing's invalid and then the inputs like oh thanks for telling me I'm invalid I'll update and be invalid. But if like can't know until it's like actually like running on the page. You know, um.

58:57.89
Chris Morrell
Is Well I guess I'm just like I don't know how react renders those if I if I were to create like when I create a component I Guess it's not rendered until even if I. If I like instantiate it. It's just it's It's just like the function that right, right right? So Even then it's the same problem.

59:19.12
Adam Wathan
Yeah, it's not rendered until it's actually like yeah in the tree you know and things are actually talking to each other and then yeah and yeah, it's yeah yeah, it's tricky I think I've heard them talk about.

59:34.40
Chris Morrell
Ah.

59:37.81
Adam Wathan
And different people and sort of like the react team I've seen mention exploring this problem of basically trying to make it more possible for children to talk to parents um sort of in the same like render sort of pass which would be really cool but ah.

59:51.70
Chris Morrell
Um, yeah.

59:57.41
Adam Wathan
Haven't seen any progress on it. But yeah.

59:59.66
Chris Morrell
Um, that's that's something that like there are ways to hack that with Blade Um, and I know ah I know there have been a couple attempts to like figure this out like get a better api into the framework but it's that's something that's that's not.

01:00:12.30
Adam Wathan
And.

01:00:17.44
Chris Morrell
It's it's more doable because you can kind of like the children get rendered first before the parent in blade so like you can set some sort of global state or like hook up some sort of like global global hook to be like when I start rendering a form then I like set a static property on the form to be like. This is the current form that's being rendered and then when a child renders you like call that static method on the form and say hey give me the current form that's being rendered and then I can pass things to it like there are ways to to do it or like just share some sort of global view state. But it's it's awkward. It's.

01:00:54.62
Adam Wathan
Yeah.

01:00:56.19
Chris Morrell
It's a thing that I think especially if you're building like more frameworky type. Um you I you want it all the time and there's not a great way to do it yet, but it's tricky for sure. Um, well I mean that was.

01:01:04.13
Adam Wathan
Yeah, yeah for sure.

01:01:14.91
Chris Morrell
That was really the big thing I'm trying to think if there's anything else that um you know that we that that I've been trying to figure Out. Um. That I know you've been thinking about but I think I think that that was the big one and I I think you've definitely convinced me that at the very least you need those lower lower level components and then like maybe I Yeah I think the abstractions on top feel right to me at least.

01:01:38.89
Adam Wathan
Yeah, you can build abstractions on top of them. Basically.

01:01:47.14
Adam Wathan
Yeah, for sure. Go man. Yeah, it's been fun.

01:01:47.64
Chris Morrell
Least for what we have you know, but yes has been really interesting. Well thank you was There is there anything else you that comes to mind for you.

01:01:59.14
Adam Wathan
Ah, no I think like we talked about a lot of the kind of the most interesting bits so far. Um, you know, always looking for new ideas though and looking forward to seeing what's possible with certain things. You know what 1 thing actually that was a major. Thing we wrestled with was trying to think of the exact situation. There's a lot of situations where I'm trying to I can't even remember what the solution was before we went all in on this but there's this new css pseudo l class called has that lets you basically style a parent based on what contents it has.

01:02:32.30
Chris Morrell
Yep.

01:02:35.39
Adam Wathan
And we kept running into situations where like we felt like this would like make our lives so much easier and um because we're doing things in Javascript instead and I can you remember some of the things that we were doing honestly I'm sure if I just look through the codebase for like uses of it. It'd be.

01:02:39.20
Chris Morrell
Yeah.

01:02:55.23
Adam Wathan
Straightforward but there's a lot of it and.

01:02:56.71
Chris Morrell
Um, well I can imagine I mean all of this like parent child conditional styles like you're going to bump into that all the time.

01:03:00.50
Adam Wathan
Yeah, yeah I think specifically one was like we have like a list of checkboxes and checkboxes can like optionally each have a description under the label.

01:03:10.34
Chris Morrell
Um.

01:03:13.96
Adam Wathan
And when we had like a list of checkboxes and any of them had a description. We wanted a bit more space between them. But if there's no descriptions and it's just like a list of like very simple checkboxes then we wanted the spacing a bit tighter and that was like quite painful to solve with like for just from ah by trying to do it.

01:03:17.39
Chris Morrell
Yes, yeah.

01:03:32.50
Adam Wathan
Pure api decision making and or just trying to do it with Javascript but using has it was just like well if the checkbox list has any descriptions in it then we want to use this spacing. You know it's like so so easy. But at the time like I mean has is extremely new. But.

01:03:41.74
Chris Morrell
Oh my God That's so nice. Yeah.

01:03:51.31
Chris Morrell
Um, yeah.

01:03:52.57
Adam Wathan
The place where it was missing support was in Firefox and it landed in Firefox like the day before we released catalyst. Um, so we just decided to go all in on it and just ah, just sort of under the impression of like okay we know we have a lot more work to do on catalyst we know it's kind of like a development preview. Um, anyone building with them right now is very much like an early adopter and it's just like hacking on side projects with it. It's not like the next gmail is going to be built with this in the next like six months or whatever and be ubiquitously used by everyone by the time anyone builds anything that has like a big user base like.

01:04:18.26
Chris Morrell
Um, sure shark.

01:04:31.33
Adam Wathan
Has support is not going to be something that anyone like is concerned about you know so we just kind of felt like let's just like think in the future a little bit and um, not like write a bunch of code that like six months from now we're going to tell ourselves like none of this stuff matters anymore and now we have all this cruft in here. Why don't we.

01:04:35.58
Chris Morrell
Um, ah.

01:04:50.90
Adam Wathan
Just do it this way in the first place so we very much leaned into like some of that really modern css stuff to solve a lot of those problems has is like life changing. It is so good. Um.

01:05:04.95
Chris Morrell
That's such a nice.. Ah we we have like a dropdown component that has to deal with this and we're dealing I can't remember how we're dealing with it. But it's like you know if any item in the dropdown has a icon. Then any other element even if it doesn't have an icon needs to get like a you know, put the text pushed over to account for the icons right? and I remember this being a nightmare that I can't remember how we solved it but it was a nightmare to deal with just because it's like you just don't know in the parent.

01:05:27.52
Adam Wathan
Yeah, totally.

01:05:41.30
Chris Morrell
Um, or you know getting that awareness into um into the right places was was definitely a challenge and I yeah I mean has just makes that trivial right? ah.

01:05:54.14
Adam Wathan
Yeah, it's crazy how trivial makes that stuff. It's the best.

01:06:00.74
Chris Morrell
The other one so you know I I come from very old school ah web development and I definitely am still ah you know, catching up to things in some in some ways or and and we also are our organization caters to a pretty old audience. So like. We're always dealing with ah browser support issues that other people don't necessarily deal with um, but you know in our like switch from bootstrap to tailwind. We basically had to do a bunch of um like we had to pull out the tailwind reset. And do all of that inside of like a custom class and then anywhere we wanted to use Tailwin you had to wrap that in a Div that was like class tail win. So that um, you know we we weren't fight the 2 different styles resets weren't fighting with each other. Um and there are ah a bunch of other things like that. But we also just had a bunch of you know we had.

01:06:46.28
Adam Wathan
Um.

01:06:57.61
Chris Morrell
Hundreds of thousands of lines of code that we're assuming that like a header had padding on it right? or whatever. Um, so the full reset was really tricky and what we've just started to play with is just like using the not selector.

01:07:02.62
Adam Wathan
Yeah, yeah, yeah.

01:07:15.60
Chris Morrell
To just say if there's no class defined on an element then we give it some default styles. But as soon as you add any class. Um, you just take like basically adding a class is just taking full control. Yep yeah.

01:07:16.15
Adam Wathan
Um.

01:07:19.57
Adam Wathan
Yeah, yeah, it's a cool idea. Just adding even like adding the class attribute like the presence of the class attribute. Basically right? yeah.

01:07:33.58
Chris Morrell
And that has been I'm ah I'm trying to be a little cautious with it because it feels like it's the type of thing that's clever enough that it might bite you you know.

01:07:41.79
Adam Wathan
Yeah, yeah, yeah, yeah, the more like it makes you smile the worse of an idea usually is you know.

01:07:47.39
Chris Morrell
Yes, but it it is really nice to just be like if I have an alert right? We have an alert class and a like alert red right? And it's just that sets the default styling for the Div and I just want anchor tags inside of the alerts to match the color.

01:07:57.50
Adam Wathan
Yeah, oh.

01:08:06.83
Chris Morrell
Of the alert itself right? and even when it was back in bootstrap it was like you'd do Alert Alert red and then you all your links you would do like class alert link or whatever right? and that was and that felt bad to me too. You know, um, and so now we just have if you put a.

01:08:17.63
Adam Wathan
Yep yep.

01:08:25.89
Chris Morrell
Plain anchor tag inside of an alert. It gets the color of the parent alert. But if I add a class I have full control to do whatever the heck I want with it and that feels great. Um, and I can see ah that being useful even in some of the form stuff like you know, essentially just you. Provide those default styles. But like if if they start adding their own if you start adding your own class names to any of the components. You could just take full control over them. Potentially yeah, anyway, yeah, we've been going for an hour I don't want to take up too much more of your time. This has been ah this has been really fun. Um.

01:08:53.10
Adam Wathan
Yeah, cool.

01:09:04.99
Chris Morrell
And I feel like I have a good sense of direction now I Really appreciate it. Um, all right? Well is there ah is there anything that your that tailwind is is coming out with ah soon that you're excited about you. Want to talk talk about before we go.

01:09:06.21
Adam Wathan
Cool man. Yeah I'm glad it was helpful.

01:09:23.30
Chris Morrell
Or tease.

01:09:23.89
Adam Wathan
Ah, yeah I mean right now we're working on tail one four whatever that means so we're exploring an R and D and a bunch of stuff with modern css features that um will simplify a lot of internals and how some things work and ah so that's been.

01:09:28.74
Chris Morrell
Um, sure.

01:09:37.78
Chris Morrell
Um, yeah.

01:09:40.56
Adam Wathan
Kind of a fun experiment but only started on it on Monday you know so very ah, very early, but that's what we're kind of working on right now hopefully have something cool out in the next couple months like an alpha or something um with like a proper release probably more like in the summer but

01:09:44.45
Chris Morrell
Um, sure.

01:09:57.51
Chris Morrell
That's exciting.

01:09:58.79
Adam Wathan
Yeah, yeah, that's kind of like what we're working on right now. So it's it's It's definitely fun to get back into the framework space and out of the Ui component space for a little bit and yeah work some different muscles.

01:10:08.24
Chris Morrell
Um, sure, nice. Well I am looking forward to that all right? Well thanks again I'm going to hit the Altra button and then we'll ah we'll call it.

01:10:19.84
Adam Wathan
Sounds good. Thanks.

Creators and Guests

Chris Morrell
Host
Chris Morrell
Father of two. Mostly talking about PHP/Laravel/React on Twitter. He/him.
Adam Wathan
Guest
Adam Wathan
Creator of @tailwindcss. Listener of Slayer. Austin 3:16.
Building Forms (and Catalyst) w/ Adam Wathan
Broadcast by