spotifyovercastrssapple-podcasts

Plug and Play Design Systems with Georges Boris

Georges Boris joins us to share two new packages for theming and stateless widgets with minimal boilerplate.
January 16, 2023
#74

Transcript

[00:00:00]
Hello Jeroen. Hello Dillon. And what are we talking about today? Today we have a guest
[00:00:06]
with us and that is George, George Borys. Welcome. Hey folks, I'm glad to be back. And
[00:00:13]
we're going to talk about what you released recently which is called Elm Widgets. Can
[00:00:18]
you explain to us what Elm Widgets is? Sure, Elm Widgets is a collection of widgets that
[00:00:26]
you can use in your Elm applications. It's similar to what you would expect from something
[00:00:32]
like Bootstrap or maybe Material components, things like that. But it's aiming at focusing
[00:00:41]
on the things that make Elm, right? Like doing a good set of APIs that are still type safe
[00:00:49]
and doing that in a way that you need the least boilerplate code possible. So focusing
[00:00:56]
on stateless components and how can I say it? Well, using kind of like what you get
[00:01:03]
with the platform like by itself so that your Elm side of things is as clean as possible.
[00:01:11]
Make sense? Yeah. So you released this package and the full name is uncover-co slash Elm
[00:01:20]
Widgets just if people are trying to find it. Yep. Yes. Uncover is the company. So this
[00:01:28]
package is like one of the open source initiative ones. Yeah, that's great. Is Bootstrap still
[00:01:36]
cool George? Or is it becoming cool again? What inspired you to create something in this
[00:01:44]
sort of philosophy of like a set of plug and play widgets? What motivated you to do that?
[00:01:50]
Were you solving a problem for yourself and your team or for the community? Yeah. It's
[00:01:57]
a good question. I would say no, but at the same time, maybe yes, because so many people
[00:02:05]
use it and I know that it's constantly getting updated and using kind of like the new cool
[00:02:11]
things. So the new, I believe that there is like a pretty recent version of Bootstrap
[00:02:19]
that is more like tailwind or something like that. Maybe I'm saying completely like a wrong
[00:02:25]
thing here, but at least like the look and feel is a lot more modern. But yeah, like
[00:02:32]
for my own company, we wanted to create like a set of UI elements for us to use in our
[00:02:37]
design system. And there is a lot of work when you are first doing that in a new project.
[00:02:47]
And most of the time you're not actually getting the value of like spending all of the time
[00:02:53]
building the same kind of like so reusable components, like a date picker or a way of
[00:03:01]
like validating some input text in a really, I don't know, predictable way of like accessifying
[00:03:09]
a mask for an input or anything like that. So I started browsing in Elm packages and
[00:03:16]
there are some stuff there, but most of them are kind of wrappers around XG scene, non-Elm
[00:03:25]
libraries like Bootstrap, like Booma. And most of them are not even the modern ones.
[00:03:32]
So like it's an old Bootstrap, it's Booma, which is not like, I believe that this is
[00:03:39]
not like the thing that people are using the most right now. There is like a material one,
[00:03:45]
but then like you get into this mess of like, I need to import JavaScript and the JavaScript
[00:03:50]
will interact with Elm in some way. And there's like, I don't know, it gets a bit complex,
[00:03:57]
I would say. So I thought that maybe providing something more simple for the community would
[00:04:05]
be good for people to just get more, get productive faster, you know, because I noticed that the
[00:04:11]
Elm community is really tech savvy in a lot of ways. I constantly see people talking about
[00:04:17]
like this new data structures or new ways of dealing with, well, data basically and
[00:04:23]
types, but the UI, it's not forefront, in the forefront a lot of the times. So if you
[00:04:31]
could just like plug and play something that looks nice and feels nice, and maybe it's
[00:04:36]
like, it's accessible, that could make the like Elm apps feel better as a whole. And
[00:04:42]
that would make Elm look better. And that for me is like a complete win.
[00:04:47]
Right. So do you view this as a package to, excuse the word, but bootstrap Elm projects?
[00:04:55]
Sure. Yeah, I hope so. Like the whole idea is that Elm widgets focus on kind of like
[00:05:02]
units, right? So you can just like use Elm widgets for this one thing that you're trying
[00:05:08]
to just like throw it out there really fast. So if you have an existing app and you just
[00:05:14]
want to use like a slider, please just like use Elm widgets. And there's like a customizable
[00:05:19]
slider that you can use there. There's like some validation, but if you are bootstrapping
[00:05:24]
something new, maybe you use Elm widgets for most of the, like this common UI elements,
[00:05:31]
right? And in that subject, I tried to make Elm widgets be, well, at first I didn't try
[00:05:42]
to make Elm widgets be a competing strategy with anything that already existed, like Elm
[00:05:48]
UI or Elm CSS, or like there are a lot of different like really quality things in the
[00:05:54]
Elm ecosystem. So I just wanted Elm widgets to be something that can live alongside them.
[00:06:02]
But if you are starting a new application and you like imported Elm widgets and you
[00:06:07]
are, I don't know, like you want to just like do a small layout thing, which is something
[00:06:12]
that is not like the focus of the library. We also included a few helpers that like there's
[00:06:17]
this container widget, which is kind of like this small subset of what you would get with
[00:06:24]
Elm UI that maybe it will get you farther using just Elm widgets and without you having
[00:06:34]
to like, I don't know, like pull in something else just to do like the layout or something
[00:06:39]
like that, right?
[00:06:40]
It feels a lot like the Tailwind philosophy of like providing a constrained sort of system,
[00:06:47]
right? A few utilities that let you have layout utilities and a standard for the sizing units
[00:06:55]
and some baked in opinions.
[00:06:57]
Exactly. It's definitely an opinionated set of widgets. And this also plugs into the way
[00:07:06]
that we do teaming using Elm widgets because we also released this another library called
[00:07:14]
Elm Team, which you need to use if you want to create your custom team for Elm widgets.
[00:07:19]
So once again, it's uncover co slash Elm theme, right?
[00:07:25]
Exactly. Yeah. So we bake in a default team with Elm widgets, but if you want to create
[00:07:31]
your own, you will probably import Elm team and create a custom team there. And the thing
[00:07:38]
is that Elm team is a really constraint based team setup. So there are like this small number
[00:07:45]
of variables that you need to define and everything will follow that pattern. So yeah. So Elm
[00:07:51]
widgets is just like an application, not an application, but view functions on top of
[00:07:55]
Elm team.
[00:07:56]
Right. So that would be similar to in Tailwind defining your, your palette. And in fact,
[00:08:04]
you have a little NPM helper package to help you build a theme using your palette from
[00:08:10]
Tailwind, right?
[00:08:11]
Exactly. Yeah. The NPM package. So Elm team, the way that it works is it provides a set
[00:08:21]
of CSS variables inside the scope of your application in every single value of like
[00:08:29]
colors or like the, the phone families, they are using those variables just like you would
[00:08:36]
do with Tailwind, right? Like when you create your Tailwind config, you're actually defining
[00:08:43]
a bunch of like CSS variables that Tailwind uses underneath each of its classes.
[00:08:49]
So what I did is that I created an NPM package, which is a Tailwind plugin that you can use
[00:08:58]
so that you can define your values using Elm team, but they are also available in your
[00:09:03]
Tailwind. So you can just like mix and match. Oh, I, maybe you use like the component from
[00:09:09]
Elm widgets, but you are pretty used to doing layout with Tailwind or you're not, you don't
[00:09:15]
want to do like create all of your components using Elm widgets. You can create like just
[00:09:20]
reuse the buttons, the, the, the, the form stuff, maybe a tag or something like that,
[00:09:26]
a pop up pop over, sorry, but everything else you can just use Tailwind and that's fine
[00:09:31]
because it will get access to your, to your values.
[00:09:34]
So do you define the same number of variables as Tailwind?
[00:09:39]
No. So Elm team focuses on color and font families only. So it, it doesn't focus on,
[00:09:47]
I don't know, like spacing or in like Tailwind, there's a lot of stuff. Yeah. So it's, it's
[00:09:55]
kind of confusing a bit because well, Elm widgets is using Tailwind underneath. So if
[00:10:02]
you actually go to Elm widget source code, you see that Elm widget styling is done using
[00:10:09]
Tailwind using like Elm teams Tailwind plugin. So it's kind of like this whole ecosystem
[00:10:17]
of packages that are intertwined in a bit. And I did this just because I really wanted
[00:10:23]
Elm widgets to be a community package and Tailwind is something that once you know how
[00:10:28]
to use it, you do like my Tailwind TSS declaration will be the same as Dillon's. So if Dillon's
[00:10:35]
wants to, if Dillon wants to create a new widget, he can just go there. He will follow kind
[00:10:40]
of like this really fixed pattern of defining a few things and it's fine. It will look the
[00:10:47]
same. The API, it's really, every component has the same API basically, or at least like
[00:10:53]
the same structure. So, so yeah, I felt like Tailwind would be like the right choice for
[00:11:00]
the package itself to be more approachable for contributors.
[00:11:05]
That's very interesting. So I, I remember back in the day I made my fair share of apps
[00:11:12]
with Bootstrap, Twitter Bootstrap and, and it was, it was great, you know, it was great
[00:11:18]
like throwing together some widgets and you make an app and you can get really comfortable
[00:11:25]
building things with that and move quickly. And, and then in more recent years, I've really
[00:11:32]
started to love the Tailwind workflow because first of all, there's so much love that the
[00:11:39]
creators of Tailwind have put into the small details of getting the design system right.
[00:11:45]
And the, the basic defaults for the spacing and the rounding and the different units that
[00:11:52]
like the, you know, how quickly the units grow for P2 to P4. And there are so many details
[00:12:01]
they put into all these little details about fonts and all these things that most people
[00:12:05]
aren't going to think about. And then you can build a site that looks great, but it's
[00:12:11]
easy to build because you don't have to have an opinion about a lot of things that they've
[00:12:15]
put into it, but you can if you, if you really want to. So that's been an interesting progression
[00:12:21]
for me, styling things to go from Twitter Bootstrap, because I think one of the things
[00:12:27]
with Twitter Bootstrap, one of the reasons that it's fallen out of popularity is that
[00:12:31]
people could start to recognize a Bootstrap site and then they would stop having that
[00:12:38]
branding differentiation and people want to build their brand. They want things to look
[00:12:43]
professional rather than a cookie cutter site that looks like anything else. And they want
[00:12:48]
to have their unique brand. And of course you can theme Twitter Bootstrap pages with,
[00:12:55]
you know, custom variants and things, but, but you're limited in, in how you can theme
[00:12:59]
it. So this is an interesting twist with, with Elm Widgets and Elm Theme with how you're
[00:13:04]
kind of like using some pieces of Elm Tailwind, some of the Tailwind philosophy, and then
[00:13:09]
some of this more Bootstrap philosophy where you're like, here's a button. But do you,
[00:13:14]
do you think that that hybrid approach, does that like avoid some of the pitfalls of getting
[00:13:21]
stuck with a cookie cutter site that you can't build with your, your brand's custom styles?
[00:13:29]
Or does that, does that allow you to, or do you eventually outgrow it and need to do something
[00:13:34]
more custom?
[00:13:35]
Well, here's the, the, the strategy, at least for now, I'd say that like becoming something
[00:13:42]
that is easy to recognize. First, if that's the case, then like props to Elm Widgets because
[00:13:50]
it's a success, you know, but sometimes you just want to get things done and there's just
[00:13:57]
so much opportunity to get lost in like this small decisions of something that is not your
[00:14:02]
main thing to do when you are not trying to, to look like a, like the cookie cutter that
[00:14:08]
you said, like, like this, this standard way of doing things. But at the same time, I,
[00:14:14]
I definitely have been someone that, that like didn't want to look the same and like
[00:14:20]
created my own thing like over and over again. So
[00:14:23]
Congratulations. You have done it again.
[00:14:28]
Yeah. The thing is that for Elm Widgets is not just look and feel. There is like this,
[00:14:36]
this whole thing about creating this nice API for, for Elm, right? And I feel like these
[00:14:45]
APIs are valuable despite the styling. So my, my idea is that Elm Widgets can eventually,
[00:14:55]
and I actually started doing that, but I kind of like roll it back before release and I'll
[00:15:00]
try to make it better before actually releasing it, but make Elm Widgets possibly be a, how
[00:15:07]
can I say it? Like, like headless UI. So an un-styled UI that you can still use the API
[00:15:13]
for validations, for all of the, the, the nice Elm APIs that use the browser itself,
[00:15:21]
but you can still style it as you see fit because in the end, those are just like view
[00:15:27]
functions that are receiving classes and you could pass in your own tailwind classes, or
[00:15:32]
you can pass in your own, like, I don't know, just like normal style tag or like style attributes
[00:15:37]
or anything like that and make it your own. I don't know. I feel like there's a, a, a,
[00:15:42]
a, how can I say this? Like a gradation? I don't know. Like a, a, a possibilities here.
[00:15:49]
Like you can just like do the really easy way. Maybe we can get so far by using Elm
[00:15:56]
team and making the, the colors and the fonts, something that looks like your brand. So that
[00:16:01]
might be sufficient for a lot of the, the, the use cases for different companies because
[00:16:06]
of a few things like Elm is not that used. Elm Widgets is not like that used. So people
[00:16:11]
won't recognize it like from the get go. But even if it was, if you are doing like the
[00:16:17]
admin of your own company and you just want to get like, make things like appear in the
[00:16:21]
screen, hopefully you just want to get stuff done, you know? And then like the, the, the
[00:16:27]
last final step, maybe you want to go that extra step, not for every single pieces of
[00:16:32]
your UI, but maybe your bottom, you want to use like your bottom in a way that like the
[00:16:37]
API is the same, but you want to make it really customizable. That's fine. Just go the headless
[00:16:42]
UI route, you know?
[00:16:44]
Right. So maybe in a, in a context where you have like a large company with a very particular
[00:16:51]
brand and they have designers trying to curate the full experience of what the UI looks like,
[00:16:58]
it's not the tool for that because it takes certain opinions. But if you're, if you're
[00:17:04]
able to not make, you know, not need to micromanage every detail of the UI and just say, I want
[00:17:10]
a button and I don't need to control exactly how the button looks, then it might be a really
[00:17:14]
good tool.
[00:17:15]
Yeah. And I hope to not just by myself, but like as a community to kind of do the same
[00:17:24]
thing that you mentioned about Tailwind, which is kind of like grouped together this set
[00:17:30]
of nice, nice, I don't know, like community knowledge about good design patterns, accessibility
[00:17:39]
patterns, and maybe even like, I don't know, a few styling decisions. I'm already piggybacking
[00:17:46]
on Tailwind for most of that. So if you are using the containers and the text and the
[00:17:51]
title, like those things that are really basic, those are, those elements are part of Elm
[00:17:59]
Widgets because they are kind of like a way for you to be consistent with your, with your
[00:18:05]
team, whenever you are using it.
[00:18:08]
But if you were using Elm Team with Tailwind CSS, you would get the same thing because
[00:18:15]
it's using Tailwind underneath as well. So yeah.
[00:18:18]
Right. So you can, you can use this with an app that's styled with Tailwind, which is
[00:18:24]
really interesting because then you can, you can sort of opt out of a certain widget style
[00:18:30]
and just drop into Tailwind and say, I'm going to use this one Elm Widget widget, and then
[00:18:36]
I'm not going to use this other one. I'm just going to do straight up Tailwind. And that's
[00:18:40]
also true for if you're using Elm CSS, if you're using Elm UI, right? So there's, talk
[00:18:47]
a little bit about that and how, how did you build it to enable using it with all these
[00:18:52]
different tools? Because there's often a problem in the Elm ecosystem that like the composition
[00:18:59]
problem. You have like Elm UI and you have Elm CSS, and then you have Elm, like accessible
[00:19:06]
HTML, but then you need like Elm accessible CSS, HTML, and then you have Elm CSS with
[00:19:13]
context and Elm UI with context. But then how do you use that with Elm accessible CSS
[00:19:19]
with context? So how did you avoid that like composition problem with, with your design
[00:19:25]
here?
[00:19:26]
I have to say, like, I'm just starting to dabble into like using Linux and what you
[00:19:31]
described to me, like, it seems kind of like the same hell, but, but yeah, like the, the,
[00:19:40]
the thing that I, I tried to do was just go the, the most compatible way possible, which
[00:19:47]
is just like go the, the pure HTML. Like eventually every, everything needs to talk to an HTML
[00:19:55]
and like convert to and from HTML, right? So Elm widgets, all of the functions, they
[00:20:01]
return like pure Elm slash HTML. So, so yeah, like Elm UI, you can use, I believe it's like
[00:20:11]
the, like HTML function or from HTML or something like that. Yeah. Elm CSS is like from unstyled.
[00:20:20]
So every one of them, they, they, they are able to, to talk with Elm HTML in some way.
[00:20:27]
The only tricky thing, especially for Elm UI is that I'm not like a huge Elm UI user.
[00:20:34]
I really liked the approach, but I have, I don't have the experience using it. So for
[00:20:39]
Elmbook it has been like a challenge sometimes because there are some unexpected things that
[00:20:45]
happen because I believe that Elm UI uses a flex box for most of its like parent elements.
[00:20:53]
So I don't know if like CSS, you know, right? Like it's, it's a funny way of doing things.
[00:21:00]
So maybe a parent changes how things are like the rules underneath it in some ways. So there
[00:21:07]
might be some, some cases where you get unexpected results because you are placing an element
[00:21:13]
inside a parent that kind of like changes the rules. But most of the time, Elm widgets
[00:21:18]
provide, well, all of the time, Elm widgets provides you with like a single Elm element
[00:21:24]
and the rules underneath it are pretty well defined. So at most you get something that
[00:21:31]
should be, I don't know, like full width, be scratched to the left and you just like
[00:21:35]
fix it and that should be fine.
[00:21:38]
Right. I've experienced that before as well with like Elm UI where if you try to put an
[00:21:45]
HTML element within, you know, an Elm UI row or column, it might not do what you expect
[00:21:52]
or like vice versa. If you try to put Elm UI things inside of like a flex box, row or
[00:22:00]
column. So things like that might, might have some unexpected results, but otherwise it
[00:22:04]
generally is interoperable. So, so you, yeah, like what, what is your philosophy? Like you've
[00:22:10]
talked about stateless view components and you've talked about how your theme sort of
[00:22:17]
is trying to reduce boilerplate and you hinted at that it's using CSS variables. So like
[00:22:23]
how does all that work and how does that like reduce boilerplate for the, for the developer?
[00:22:29]
You know, yeah. And I would also like to ask why do you focus so much on stateless? Maybe
[00:22:34]
let's start with that.
[00:22:36]
Sure. So for beginners using Elm, I'd say that the whole plugin messages and trying
[00:22:44]
to compose like pages and like sub parts of the page and making like this, this, I dunno,
[00:22:51]
like this many work across different pages. Those things sometimes get, get to be unusually
[00:22:58]
hard problem to solve at first. And that can be frustrating. Right? So it's, it's kind
[00:23:05]
of funny to say stateless because the components, they like the DOM, it's stateful sometimes.
[00:23:13]
So if you are using input, so the inputs by itself, it's kind of like holding its internal
[00:23:18]
state and Elm is just like doing this IO to the DOM. Right? So it's communicating with
[00:23:27]
the DOM. When I, when I mentioned stateless, I mostly mentioned there are no messages,
[00:23:33]
like there are no, there is no internal state of a component that the component itself is
[00:23:38]
managing. So all of the components, they are just like receiving some message from the
[00:23:43]
DOM itself and then giving it to you so that you can like retrieve some, something, and
[00:23:50]
then you like return the same value to the DOM and that's it. But the, the thing is that
[00:23:55]
I wanted to still, to, to still be able to, to plug into that, that pipeline of communication
[00:24:02]
and a really useful way of doing that is by using custom decoders. So not just decoders,
[00:24:09]
but basically plugging into the decoder pipeline. For instance, the HTML input elements, they
[00:24:16]
provide you with a lot of like nice native validation methods. So you can define like,
[00:24:23]
a max length or a min length. So for your input, but you can also define a pattern using
[00:24:29]
regex. And so, and the, the browser actually gives you what, what validation actually failed
[00:24:38]
and sometimes even for what reason. So if we can plug into that API of the browser,
[00:24:44]
then we can give that to the user and it can just show you that, that output, right? It
[00:24:50]
can kind of like do this native validation of the, of the, the, the input without you
[00:24:56]
to, to do that inside your update cycle.
[00:24:59]
Yeah. When you say that the browser gives you that information, it gives you the validation
[00:25:04]
error. Do you mean that it gives you, do you mean that it gives you that inside the custom
[00:25:10]
events or the, the events?
[00:25:12]
Yeah. So each element, like if you, if you have the like input element, for instance,
[00:25:20]
it has this valid validity property and inside validity it has like all of this possible
[00:25:28]
errors that you can receive, like that, that can be true or false based on the attributes
[00:25:34]
that you're giving to the DOM. And it's you, it will show you, well, like what is the reason
[00:25:39]
that input is not, it's valid or not. And not only that, it even gives you this validation
[00:25:44]
message, but like, even though it was kind of like interesting, I ended up not using
[00:25:49]
it because the validation message, it, it was kind, it was kind of hard to, to make
[00:25:57]
sure that it was talking about the same error that you wanted to display. Like there is
[00:26:03]
like this priority that the, that each browser can decide, like you are wrong. Like your
[00:26:10]
input is wrong because of like three different reasons at the same time. The, but the validation
[00:26:15]
message you can, we can't actually control like which message will pop up. And sometimes
[00:26:20]
you just want to, to show like the, the, the most important error or something like that.
[00:26:26]
And, and yeah, like for, for cross browser, like compatibility, I decided to not go that
[00:26:33]
route, you know?
[00:26:34]
Yeah. Do you use the, I believe there are some like CSS pseudo classes for validity
[00:26:40]
of input elements too. Did you opt to use that or not?
[00:26:44]
I, I opt to not use that because, yeah, because I dunno, like I felt like this should be a,
[00:26:52]
since you have the errors at your hand and it's pretty easy to just like use them, it
[00:26:57]
would be awesome if the user could like choose if they wanted to, to show something to, to
[00:27:02]
be really intrusive or not intrusive. That's right.
[00:27:06]
I think so having done a deep dive myself on form API design for Elm with this stateless
[00:27:14]
mindset and looking at, you know, decoding events and things, I, I think you arrived
[00:27:21]
at a good decision there because essentially like, so this is an interesting approach you've
[00:27:27]
taken because you're, you're using these events coming from the platforms validation API,
[00:27:36]
but you're not using the CSS piece to determine if it's valid.
[00:27:40]
I think that probably gives you more control over when to show validation errors because
[00:27:46]
the problem with using like the CSS pseudo classes for validity is that you have to use
[00:27:54]
the exact platforms behavior on deciding when to check validity. So do you, so do you want
[00:28:00]
to show something as having an error before the user is even focused to that input element
[00:28:07]
because it's invalid because it must not be blank. And so suddenly you open a new form
[00:28:12]
and everything on there is red because it's not valid yet because it must not be blank.
[00:28:17]
That's frustrating. And you, you want to have fine grained control over when you present
[00:28:22]
validity errors or do you do that the second they focus it or do you do it after they've
[00:28:29]
typed something that can also be frustrating in certain cases or do you do it after they've
[00:28:34]
blurred it or do you do it after they've tried to submit it? So you want to have fine grained
[00:28:40]
control over these things and there's no one size fits all answer to that. So I think that
[00:28:46]
what you've arrived at is an interesting happy medium where you're using the platform there,
[00:28:50]
but also like, Hey, we can't use the platform for this part of it because it doesn't give
[00:28:55]
us the fine grained control that we need to have different possible behaviors here. So
[00:29:00]
do you use for stateless, you've talked about a few different pieces of stateless. So there's
[00:29:05]
the one piece of you're trying to avoid having view components that own their own state,
[00:29:12]
which you know, I think is a great philosophy. I'm a hundred percent behind that. I think
[00:29:18]
that's, is that influenced by Evan's Elm sortable table sort of mini writeup that he had in
[00:29:25]
that package?
[00:29:26]
To be honest, no, but that was a, a posthumous influence. Like when I started talking, talking
[00:29:35]
about this package with a few people, they mentioned this package and then I went to
[00:29:40]
it. It's like a really valuable, like learning resource. But to be honest, it's, it's more
[00:29:46]
like I've, I'm not like a really old Elm user. Like, well, it's been two years now, so it's
[00:29:54]
not like I'm not that new as well, but I, I definitely bit the bullet of trying to do
[00:30:02]
the whole like deeply nested Elm architecture and like do the, I dunno, like reinvent the
[00:30:08]
wheel like a few times. So I just wanted to, to be able to not do that right here. And
[00:30:16]
at the same time, I feel like in the Elm package registry, we have quite a few different like
[00:30:23]
complex packages. And most of the time the complexity comes because like you have to
[00:30:31]
understand this, like they're exposed API. Sometimes that these API is kind of like exactly
[00:30:38]
what you want. Sometimes it's, you have to kind of like understand the meta model. And
[00:30:42]
I just wanted to focus on the, like the, the most basic thing that you, you, you could
[00:30:47]
need and like, and that, that constraint it's, it's kind of useful because it, it makes me
[00:30:54]
clearly decide in one direction or the other. For instance, like for the outcomplete widget,
[00:31:01]
I, I just like took a look, like can I do an outcomplete using like just a HTML right
[00:31:08]
now and I can't, it's not that great, but like you can do it using lists and like input
[00:31:16]
lists. And, but then again, like we have this pretty great package in the, the package registry,
[00:31:23]
which is called the user is confidence men zero two, I believe like old too. And the
[00:31:30]
package is called select. So I'll select is actually also an outcomplete thing. And it's
[00:31:38]
like a bit more stateful than, than widgets. And I'm glad that both exists, you know, like
[00:31:43]
you can use widgets thing because it's sometimes simpler, but if you want more control and
[00:31:49]
you want to, well, just go use this other package. And I'm glad that both both exists.
[00:31:55]
And I actually, I really want to, to maybe, well, this is another ambition, but like since
[00:32:01]
own widgets is kind of like a big, biggish, like a largest concentration of different
[00:32:10]
things that you can use for your own application. Why not like in the documentation website,
[00:32:16]
the own book thing, why not even create pages there for something that it doesn't do? So
[00:32:22]
like shards, maybe you want to do a chart or maybe you want to do the, like this fancy,
[00:32:27]
like sortable table. It would be awesome if people could use it as a central place that
[00:32:33]
they would look to just like figure out how to do these things, you know? And I would
[00:32:37]
put them like, I would link them to like the best package or like the, the most widely
[00:32:43]
used options for each of them. Right? Like, so you'd get like Elm visualization, Elm charts
[00:32:49]
and like Elm select from Confidence Man and et cetera.
[00:32:53]
I can already imagine a lot of disappointed people like checking into Elm, which is like,
[00:32:59]
Oh, does it have charts? Yes. It has a reference to charts. No.
[00:33:06]
Well, I can make it like a different section, like community stuff.
[00:33:12]
Yeah. That's, that's a cool idea. I like that process of saying, you know, almost from first
[00:33:20]
principles, like this is my design goal. This is the outcome I want. I want somebody to
[00:33:25]
be able to like basically Elm install this Elm widgets package and then add the global
[00:33:33]
styles thing and then build stuff and, and, and not limit yourself to like, yes, it's
[00:33:40]
not a charting library, but I want that user who maybe they're building their first Elm
[00:33:45]
app or maybe they've just never used charts before and you want them to have a good experience.
[00:33:50]
That's, that's really cool. Yeah. We, a while back, we, some of the people
[00:33:56]
in the Elm community discussed about this hive knowledge that we have, like we eventually
[00:34:02]
everyone has it, which is like the patterns that we use or the packages that we go, that
[00:34:08]
we go for. And I dunno, maybe sharing that hive knowledge in this small niches is a good
[00:34:15]
way to go as well. Right? Like, so even if you're not using Elm widgets, maybe the documentation
[00:34:20]
it's, it's it's valid for you because you can go there and just like browse to different
[00:34:26]
stuff. Yeah. I found the accessible HTML package,
[00:34:29]
a reuse one that's in that sense, not in the hive mind sense, but like you just go through
[00:34:36]
the, the API and it tells you about all these accessibility problems and how you can solve
[00:34:41]
them even if you're not using the package. Like it's really useful just to go through
[00:34:45]
those documentations. Yeah. I, I was super inspired about Elm accessible
[00:34:52]
HTML and the accessibility part of Elm widgets is something that I really want to focus on
[00:34:56]
next because like everything should be accessible because like I'm not doing anything crazy,
[00:35:02]
like I'm not doing anything that the DOM doesn't do, but I want to go like the extra mile and
[00:35:07]
I dunno, make it the best that it can be by itself. And I just want to give a public thanks
[00:35:14]
to Tessa because like not only Elm accessible HTML, but I'm using another package of hers
[00:35:22]
called Elm palette that, that for the Elm team thing there is this team generator thing
[00:35:31]
in the documentation that I'm showing all of the contrast ratios and how accessible
[00:35:36]
is your, is your team. And that package offers were, was super useful for doing that.
[00:35:43]
So when somebody's adding this in, I've been thinking a little bit about like performance
[00:35:49]
with CSS and JS type things. And so this is something that's on my mind. So like I know
[00:35:56]
that this is a pretty vanilla CSS approach in many ways, except that you do, you add
[00:36:04]
the global styles. And so it's, it is kind of CSS in JS in the sense that you use the
[00:36:12]
Elm code to insert the style sheet that it uses for all the CSS. Is there a way to just
[00:36:18]
include the global CSS as a style sheet? Have you considered that or is that not a priority
[00:36:25]
for you? You mean having it available somewhere that people can just like insert it in, in
[00:36:30]
a different way, like just the header element or something like that. It should be pretty
[00:36:35]
easy to do and like plug into the CI. It was just not like a priority for getting the library
[00:36:44]
out there, but it should definitely be something that is doable.
[00:36:46]
I'm curious, what would be the benefits of doing that?
[00:36:49]
Well, there's an article I'll link to and at some point, actually Jeroen, I would love
[00:36:54]
to do a deep dive episode on this topic and explore more, but there's a, there's a blog
[00:37:00]
post by a maintainer of a popular CSS and JS package in the JS ecosystem about why we're
[00:37:09]
breaking up with CSS and JS. And it talks about the performance burden and the performance
[00:37:14]
optimizations you can get from using raw CSS and how the browser is really optimized for
[00:37:19]
that. Now, I mean, that said, like, I'm sure you can just do like a, a lazy style element
[00:37:26]
and maybe, maybe that's not a performance issue. So, cause CSS and JS is different because
[00:37:32]
you're constantly changing the style nodes and re-computing things as the styles change
[00:37:39]
in the children layouts. Whereas if you're just inserting a global style, it might be
[00:37:44]
very different cause you can just have a single lazy style node that doesn't, the elm virtual
[00:37:49]
DOM doesn't ever have to touch again. So maybe that's not an issue, just thinking out loud
[00:37:54]
here. Yeah. So, you know, another thing that comes to mind with it is like the bundle size,
[00:38:00]
but maybe it's, maybe it's pretty modest because I can definitely imagine like your loading
[00:38:05]
widgets are really nice and I've definitely copy pasted some really ugly CSS animations
[00:38:13]
and like had a lot of trouble, like maintaining these little bits of animation code just to
[00:38:20]
have like a loading widget. I can imagine like just, Hey, just install elm widgets and
[00:38:25]
then use the loading widget there. Cause they look really nice and you don't have to think
[00:38:29]
about it. So yeah, I'd be curious to look at the bundle size implications for just using
[00:38:34]
one widget, if that would be worth the trade off there.
[00:38:37]
Yeah, no, this is definitely something that I've considered. The size of the CSS, since
[00:38:42]
I'm using tailwind and tailwind is so optimized for a lot like reusing code and like it's,
[00:38:48]
it's really small. I believe like the, the whole, like the whole thing is like, it's
[00:38:54]
kind of like six K like a six K something like that.
[00:38:59]
You mean all of widgets, all of elm widgets?
[00:39:03]
No, no, no. Just like the, the CSS needed for all of elm widgets. And I could do the,
[00:39:09]
the whole like splitting up components in different styles, but then it might get like
[00:39:15]
easily it will get larger if you like import like three components maybe. Right. Yeah.
[00:39:22]
So this is why I haven't focused that on that so far, but like for something like the, the
[00:39:28]
loading stuff, it makes sense. But at the same time it it's, it's such like, I don't
[00:39:35]
know, maybe if someone wants to use just like the loading and it, it makes sense to access
[00:39:39]
by itself, maybe there should be another package that is just like pretty loaders. And so that's
[00:39:45]
it.
[00:39:46]
Yeah. That sounds very much like what the, the problem they had with lodash in JavaScripts.
[00:39:52]
Lodash is too big. Okay, well let's split up every function into a separate package.
[00:39:57]
Yeah, right. Exactly. Fortunately, it sounds like it's not too big, but yeah, with, cause
[00:40:03]
there's definitely a burden on the user too for splitting everything up. So you have to
[00:40:06]
add the global styles for everything you include. And at that point you, you've broken that
[00:40:11]
philosophy of like minimizing boilerplate. So there's, it seems like you've made a reasonable
[00:40:16]
trade off there.
[00:40:17]
Okay. I want to, I want to geek out a little bit, not with my knowledge, but, but I want
[00:40:23]
to, to know more. So Elmwitches is full of stateless elements and some of them, I was
[00:40:29]
very surprised that they could be stateless. The one that I have in mind, but maybe you
[00:40:34]
have others is the modal where you can show a modal when you click something or when you
[00:40:42]
do an action and then it suddenly shows up. And I, I had a lot, a lot of trouble understanding
[00:40:48]
how you can do that without state. So maybe could you explain how that works? And if you
[00:40:54]
have other funny or interesting elements like this, I would love to hear about those.
[00:40:59]
Sure. Well, it's kind of HML plus CSS trickery the way that I'm doing that. And it would
[00:41:08]
be fine. Definitely. It would be fine for non applications. And I'm just hoping that
[00:41:14]
it's fine for applications as well. So the way that I'm doing it is just by using a checkbox
[00:41:22]
with a label being somewhere in the DOM and the default behavior of when you click a label,
[00:41:29]
is that you, at the same time, you kind of toggle the checkbox that the label is for.
[00:41:36]
So it's the same thing as clicking the element. So the checkboxes is hidden, but the label
[00:41:41]
is the toggle button. So when you click the toggle button, you are actually toggling the
[00:41:47]
checkbox and I'm using the state of the checkbox to display or hide the model. So for the model,
[00:41:55]
this is pretty useful. Well, you definitely want to control if your model is open or not.
[00:42:03]
If the model is maybe it's heavy, maybe it's loading extra stuff when it appears, maybe
[00:42:12]
for accessibility reasons, you don't want to render the content or something like that
[00:42:18]
when it's not actually on the screen. But if the model is something that it's, if you
[00:42:23]
don't kind of like don't care, if it's more of a visual thing of it being shown or hidden,
[00:42:32]
but it makes sense for the content to always be there, it's just like an extra information
[00:42:37]
or something like that, then maybe you can just leave it up to the view and that's fine.
[00:42:42]
It's kind of like using the, not the dialogue, but the how, I forgot the name of the accordion
[00:42:48]
element, like the native one where you can just like detail. So the detail open and closed
[00:42:54]
state, if you are using now, you don't control that as well. Right. So, so it's kind of the
[00:42:59]
same, but with the model, there are other elements that, that use that similar approach.
[00:43:05]
Well, one of the things that's the, sorry. Yeah.
[00:43:08]
Actually you didn't describe how you display the model depending on the state of the select.
[00:43:13]
Sure. Oh, I got the checkbox. Sorry. Yeah. So it's a, it's a CSS thing. I just use the
[00:43:22]
sibling checkbox with the actual model element. And I use that checkbox, checkbox checked
[00:43:31]
state to determine if the model is selected or not. I'm not only using Tailwind here.
[00:43:37]
I also have like this, this small CSS that I do more manual stuff. And one of them is
[00:43:45]
just using that model selection state to display the sibling model and make it like appear
[00:43:51]
with an animation, et cetera. One of the things that, that, that you lose, if you, if you
[00:43:57]
have like a model that only appears when you click something and it like it appears in
[00:44:02]
the DOM itself, just in that, that moment is it's really easy to animate the entry,
[00:44:08]
but the exit, you can't animate that unless you are keeping up like the, you are kind
[00:44:13]
of like tracking the state of the animation that those are all of those things.
[00:44:17]
There's always a good excuse of, Oh, well the user doesn't want to waste his time seeing
[00:44:23]
that model disappear. Right?
[00:44:26]
Exactly. So when you're only the DOM there, you can actually like do pretty easily that
[00:44:33]
fade out state.
[00:44:35]
Yeah. Nice.
[00:44:36]
Yeah. And well, yeah, I, I, I feel like Elm widgets and maybe my libraries as a whole,
[00:44:43]
they have a philosophy that is slightly different from one that is really common in Elm applications,
[00:44:49]
which is I try to make it easy for you to do the right thing. But if you want to do
[00:44:56]
something different, I prefer that you have the freedom and not try to lock you into the
[00:45:02]
perfect, the perfect state, you know? So for the model one, there is like the toggleable
[00:45:08]
model that follows this strategy that I just said to you. But there is also like the, the
[00:45:13]
usual model that, that we'll just like display and you can like track the state and you can
[00:45:17]
control if it's open or not. You can just like, I dunno, show it like at once when it's
[00:45:23]
rendered in the DOM and that's it.
[00:45:26]
And does that one also use the CSS trickery?
[00:45:28]
No, actually no. If you're not using the toggleable model, you, you not get the whole like hidden
[00:45:35]
checkbox and et cetera, because then you, you don't want people to, to be able to like
[00:45:40]
close it in any way other than like receiving the, the Boolean of is it open or not. Right?
[00:45:47]
Yeah. Something I noticed and we've also, we already talked about this. If you use that
[00:45:52]
toggleable or toggle button plus model, meaning you don't have any state for your model, then
[00:45:57]
you can't test that the model shows up in an Elm test because you're relying on the
[00:46:02]
web platform and we don't have any tools except end to end tests like Cypress or Playwright
[00:46:08]
to simulate that. We can't do that with Elm tests or with Elm program tests. So that's
[00:46:14]
unfortunate.
[00:46:15]
Yeah. I'll just say that like, this is probably going to be true for anything that is done.
[00:46:22]
Maybe I don't know, like I don't know if just done, but like done plus CSS. Yeah. Scoped
[00:46:27]
right. Because like if you are using like, like Dillon said, like the detail thing, you
[00:46:32]
are also not owning that state of it. Is it open or not? So maybe you should use that
[00:46:37]
when you kind of like don't care. But yeah, if you want to control the flow, you better
[00:46:42]
use the one that you actually control the state.
[00:46:45]
I was also wondering, usually at least on the product that I work on at work, we have
[00:46:50]
our dialogues, they all have a close button in the corner and they also need to respond
[00:46:55]
to the escape key if you want to. If you press the escape key, then it closes. Can you do
[00:47:01]
that with the toggle button?
[00:47:03]
Sadly, sadly no.
[00:47:06]
Okay. Yeah.
[00:47:07]
Sadly, no. I don't know, like the ideal world, it would be if instead of using like, I don't
[00:47:15]
know, like regular HTML, we were actually using the new dialogue, like HTML dialogue,
[00:47:23]
because that actually gives you everything that you need to, to like, well, control those
[00:47:28]
states that the accessibility is handled by the browser. And hopefully widgets can evolve
[00:47:35]
into using those things as they become more available. But I don't remember.
[00:47:39]
Why are they not?
[00:47:40]
Sorry?
[00:47:41]
Why are they not using the dialogue?
[00:47:44]
Yeah. So, so I don't remember the exact reason, but the thing is that like dialogue right
[00:47:51]
now, it's sadly not as declarative as it, as it should be. You need to JavaScript to
[00:47:58]
be able to, to like display it in a way that actually it handles all of the events in the
[00:48:04]
way that you were expecting. If you're, if you're showing the dialogue, I'm not, I can't
[00:48:09]
describe you exactly what happens, but if I feel like there is a way that you can show
[00:48:15]
a dialogue in a declarative way, but then it kind of like, it, it, it doesn't work the
[00:48:21]
same as it would. I believe that it will, it will not respond to like this escapes things
[00:48:27]
and maybe it won't focus trap your, your inputs as well. All of the, so I don't know. I hope
[00:48:34]
that our widgets can like evolve, like keeping an eye on all of these like dumb possibilities
[00:48:39]
and just like use it more and more.
[00:48:41]
I'm guessing that you would then wait for multiple browsers to support that or you would
[00:48:45]
add a warning saying, don't use this if you don't support this version of this browser.
[00:48:51]
Sure. Yeah. Yeah. I'll just go and say that most, if not all of widgets is built using
[00:48:57]
like really established like browser APIs. So I'm not doing any like experimental stuff.
[00:49:04]
Right. So do you have any other fun CSS trickery in your bag and in Elm widgets?
[00:49:12]
Sure. Well, I feel like the pop over element is something that is also kind of tricky to
[00:49:20]
do sometimes and pop over and to tip are things that are like you could use just like a title
[00:49:28]
attribute instead of a two tip. But sometimes you don't want to do that. You want to control
[00:49:33]
like how it displays. You want to control, like you want to play some, some at like HML
[00:49:39]
thing there you want to, I don't know. And pop over it, it gets a lot harder, right?
[00:49:46]
Like pop overs. I don't know if you, if it's everyone knows what's a pop over because like
[00:49:51]
the, the way that you like the naming, it's, it's a bit different all of the time, but
[00:49:58]
it's like sometimes people call it just drop down or something like that. But it's the
[00:50:03]
element that pops up once you either hover or click another element. Right. So for, we
[00:50:11]
are using this, this idea of not just like hovering using CMS, but just like also using
[00:50:19]
the focus within a selector. So for the pop over one it shows up once you focus on the
[00:50:27]
element that you are using as the anchor and it gets positioned related to that element.
[00:50:34]
But then again, it also keeps appearing if you're interacting with the displayed element.
[00:50:40]
So it's sometimes it's a bit tricky to just like do that because I don't know, you're
[00:50:46]
interacting with the, the, the, the anchor thing. And then once you get outside of the
[00:50:51]
anchor thing, you lose focus, you lose the, the, the thing that you were trying to interact.
[00:50:56]
I don't know. So it's, it's another thing that it's really useful to just do it and
[00:51:01]
just like add a drop down menu or something like that. And not worry about like plugging
[00:51:07]
the messages to do that. I feel like this is another thing that can be frustrating for
[00:51:12]
beginners to, I don't know, like it should be so easy to do this. Why is it hard? Like,
[00:51:17]
you know, and this frustration it's, it's not that productive, you know? So if you want
[00:51:22]
to do that in a more controlled way, that's fine. Like the Elm it's exactly for that.
[00:51:28]
But I just wanted to, to give the like beginners, especially a more frictionless experience
[00:51:34]
at first, and then you can like evolve and control wherever you want.
[00:51:38]
Yeah. Are there trade-offs there with, cause like tooltips are notoriously difficult to
[00:51:45]
do only using CSS. For example, like if a tooltip is only using CSS, can you know if
[00:51:53]
it's going out of the bounds of the screen? I actually wonder if some of the new like
[00:51:59]
has selectors or things like that could allow for something like that in pure CSS that wasn't
[00:52:04]
possible before. But as far as I know with traditional CSS, you can't do that.
[00:52:09]
Yeah. Well, definitely not in a stateless way because yeah, I would need to kind of
[00:52:14]
get bounding, like the bounding box, et cetera. But, but no, like the way that I'm doing right
[00:52:21]
now, it's more, it's more simple. Like it's more focusing on like, do you know where this
[00:52:27]
will show up? Like it's easier for you to just say to me like, okay, position this to
[00:52:32]
the left side or to the right side, et cetera.
[00:52:36]
Right. So something is at the very top of the screen, then you're going to say, put
[00:52:40]
it on the bottom and.
[00:52:41]
Yeah, exactly. Yeah.
[00:52:43]
Okay, cool. Yeah.
[00:52:44]
Those things here that like rely on relative positioning can get a bit tricky because those
[00:52:50]
are one of the things that, that might get screwed up if you, if you are using a non-standard
[00:52:57]
parent styling, you know? So if you are placing an element that is using kind of like this,
[00:53:04]
this popover thing, now I have to, to have this wrapper of that element. And then if
[00:53:13]
you want to style the anchor itself and not the disparate element that I've included in
[00:53:20]
the DOM, then you're kind of stuck. I don't know, like so there are a few places where
[00:53:26]
sadly I, at least so far, I couldn't find a way for me to bypass like this DOM restrictions,
[00:53:34]
you know?
[00:53:35]
I'll be very curious to see what, what kinds of like CSS wizardry become possible for kind
[00:53:42]
of this stateless Elm philosophy with, with the has and is selectors in CSS. Because yeah,
[00:53:48]
like I'm, I'm also a big fan of this approach of like, like for example, a hamburger menu
[00:53:54]
that you, you just have a global menu and it's visible or hidden based on a click on
[00:54:01]
mobile, for example, then like, it's really nice to just not have to manage that state
[00:54:07]
in Elm. And even to be able to share code between internal projects at a company or
[00:54:14]
in an Elm package that just is, here's the CSS, here's the view code, put it in there
[00:54:20]
and it just does the right thing because it uses a checkbox for the, for the visible state
[00:54:25]
because you don't really, it's a, it's a DOM concern that state and you really, you don't
[00:54:31]
care. You don't, you don't need that in the time traveling debugger to be able to go back
[00:54:36]
and track certain weird view states you get into. It's just you, you manage your state.
[00:54:41]
I don't care.
[00:54:42]
Yeah. Like maybe someone could argue that, Oh, I need to be able to debug that state
[00:54:49]
as well. And, and if you're doing something that's really complex, I would get that. But
[00:54:55]
I feel like there's a trade off there, right? Like there is some complexity line that we
[00:55:00]
want to cross before getting into the whole state management thing. And I don't know,
[00:55:05]
it's fun to think about Elm widgets being this repository of, of strategies for doing
[00:55:10]
all of that. After using, starting to work on Elm widgets, I started to, to just, I don't
[00:55:16]
know, you just search, right? Like how can you do this with pure HTML and CSS? And there
[00:55:22]
are like tons of knowledge out there of people already doing that, those things. And it's
[00:55:28]
just like really spread apart, like in Stack Overflow and this like weird tutorial that
[00:55:34]
it's hidden in a block somewhere. And if we can just like place everything in the same
[00:55:39]
place might be fun. And I feel like it's especially useful for Elm applications since for us dealing
[00:55:45]
with all of this plumbing sometimes gets painful.
[00:55:48]
Yeah. I know that this might go against your philosophy of like simple low boiler plate
[00:55:54]
wiring, but have you thought at all about bundling certain things with web components
[00:56:00]
where, you know, this kind of power where you can put the state into some internal thing
[00:56:05]
that Elm doesn't have to care about that can be really declarative. Sometimes web components
[00:56:10]
can be a really nice way to abstract that. But of course you then need to include JavaScript
[00:56:16]
code in order for those web components to be renderable from your Elm code.
[00:56:20]
Sure. Yeah. Like I love web components and like at work we use them. So these strategies
[00:56:27]
definitely something that I, I vouch for. At the same time, I feel like it's similar
[00:56:32]
to the Elm select thing that I mentioned. Like it's, it's good for us to define that
[00:56:38]
we won't have that in Elm widgets, but at the same time, if there are some like really
[00:56:44]
useful tools, maybe we could point them out. Like, okay, if you want to do this, like,
[00:56:49]
I don't know. One of the things that is not really a like element, it's like, it's not
[00:56:54]
really a UI element itself, but it's super common. It's how to, to deal with like translations
[00:57:02]
and like, because it's still like a way of, of you handling texts. Right. And there's
[00:57:08]
tons of different strategies. There is like, I won't go into all of them here in any way,
[00:57:15]
but at the same time, knowing that web components is a particularly useful one might be helpful.
[00:57:23]
Right. So if you're looking for an element and there's like, okay, internationalization
[00:57:29]
or something like that, maybe we can point out to some packages that are more focused
[00:57:34]
on stateless UI, but it's still a stateless UI that is aimed towards that goal. I don't
[00:57:41]
know, because thinking about another, like really good stateless, stateless package,
[00:57:47]
stateless UI package in the Elm repository, Teresa's Elm charts, right? There is no state
[00:57:55]
there, but maybe there could be like a lot of optimizations if there was state, because
[00:58:02]
there's like a lot of work going on in each render, but at the same time, like it makes
[00:58:07]
the API so good. It's so simple to just like copy and paste some code and that's it. There's
[00:58:12]
no boilerplate. And if you think about it, the stateful parts, because there is state
[00:58:20]
actually, sorry. But if you are using like the two tips and those things, then there's
[00:58:25]
state, because like it gets handwritten like in the proper places, et cetera. But it's
[00:58:30]
by far the most difficult part of Elm charts. Like if you want to use events and just like
[00:58:37]
figure out how things line up together, it's the place where people get kind of like, they
[00:58:44]
get trapped. One thing that Jeroen mentioned to me a while back is that you said, Jeroen,
[00:58:52]
that, oh, I thought that Elm was not able to work with CSS variables.
[00:58:57]
Yeah. I was going to ask that about that.
[00:59:01]
So this is one thing that, I don't know, all of these things that are kind of like living
[00:59:06]
in the gray area between Elm and the DOM, I sometimes fear that I'm kind of like using
[00:59:13]
a skate hatch in some way, something that might get fixed in the future or something
[00:59:18]
like that. CSS variables, I hope that's not the case because like the Elm, I feel like
[00:59:23]
Elm style, it does some sort of parsing of what you're giving it. Because I actually,
[00:59:30]
I was able to declaratively call messages from the DOM using some hacks.
[00:59:37]
Using the style function?
[00:59:41]
Not the style, but I actually got, I was able to do that using the image tag because the
[00:59:48]
image tag, if you throw it in the DOM and it doesn't load properly, it throws an error
[00:59:54]
event. So you can just like use the image, like a non-existing image and bind the error
[01:00:02]
event to whatever you want. And since it can be like a hidden image or something like that,
[01:00:09]
you can declaratively call messages from the DOM. I'm not using that. I'm just saying that
[01:00:18]
those things are available. But if you use that, you are treading dangerous paths. But
[01:00:27]
for the CSS variables, I discovered that Elm disregards a few style keys. So if you're
[01:00:34]
using a style or values, I don't know, but it kind of like tries to validate it and it
[01:00:39]
just like ignores if you do something wrong. This can be frustrating. And I believe that
[01:00:44]
style, you can only place one style in the element. Maybe I'm saying something wrong
[01:00:49]
here, but there is like also the, sometimes if you are using a style and you like place
[01:00:55]
another style, it only uses the last one, right? Because it's not like a class that
[01:01:01]
concatenates all values. Like for styles, I believe that it's just like, it's just using
[01:01:07]
the last. But if you are using the, well, first it should be valid to use CSS variables
[01:01:14]
in like anywhere that you are using CSS values. I feel like this is just like something that
[01:01:19]
Elm is wrongfully validating against. But to bypass that, I'm just using the node attribute,
[01:01:28]
like the attribute function directly, then it bypasses that and it can use CSS variables.
[01:01:35]
Oh, cool. Yeah. So there is no, there is no like hidden image with like a hidden on error.
[01:01:42]
Yeah.
[01:01:43]
Yeah. I was going to say that would definitely put you on Santa's naughty list for this year.
[01:01:47]
Good thing you didn't.
[01:01:54]
So the issue with CSS variables is, is only the fact that Elm sometimes ignores them,
[01:01:59]
right?
[01:02:00]
Yes. Yeah. At least from what I could tell. And it's not all the time, like for a few
[01:02:06]
styles it accepts them, but for other ones, like it doesn't, I don't know.
[01:02:12]
And so if I'm understanding correctly, the main purpose of CSS variables for this tool
[01:02:19]
is that low boilerplate goal of being able to basically say, here's my theme, here's
[01:02:27]
the base CSS, and then you just use widgets and it pieces them together and you don't
[01:02:32]
have to wire through your theme and base styles everywhere. You just declare it up front and
[01:02:39]
then it using CSS variables, it's able to basically, you declare your theme, it sets
[01:02:45]
some CSS variables, you declare the base style, it's referencing those CSS variables, and
[01:02:51]
then you use your widgets and it's using those styles with the CSS variables.
[01:02:55]
Yeah. But not only that, and here I'm going to do the pitch for Elm team itself, because
[01:03:02]
like it's pretty useful even if you're not using widgets. The whole idea of Elm team
[01:03:06]
is first, the team itself is this constraint based declaration of like, there are this
[01:03:13]
five colors. I spent a lot of time just trying to do the minimum necessary, like amount of
[01:03:19]
colors and variations of colors to give you flexibility at the same time that gives you
[01:03:24]
like constraints. And the thing is that Elm team is not only declaring that, but it's
[01:03:31]
also creating team scopes in your application. For instance, in a website, sometimes like
[01:03:39]
a marketing website, it's really useful to have the same section. You might use it in
[01:03:47]
a white background and then you want to create some visual diversity and you want to use
[01:03:53]
a dark background later. And you want to change what is the primary color depending on which
[01:03:59]
is the background itself. So you can actually create a number of teams and use them in the
[01:04:07]
same page. So you're not restricted to using like one team per page in any way. So we use
[01:04:14]
that for our website. So each section, we have like, I don't know, like five different
[01:04:19]
teams because our company uses gray as the main background color. So we have like five
[01:04:28]
lightness of gray, like a gray, how do I say that? Shades of gray. And we can just like
[01:04:36]
mix and match whatever you want. And if someone, okay, so this one here should be actually
[01:04:40]
a bit darker and we can just like change this one team variable and that's it. So Elm teams
[01:04:46]
handle that. But not only that, it also handles dark team. Like if you want to declare for
[01:04:54]
each one of those scopes, different teams for different dark modes, you can. And once
[01:04:59]
you go to the dark mode, every single team container will change. So it's super flexible.
[01:05:07]
So even in our main application, we have like two or three kind of like similar teams, but
[01:05:14]
maybe we want to give this element a highlight and it's using the same kinds of like components
[01:05:22]
inside, but we give it like a slightly different team and that's it. Everything still fits
[01:05:28]
together. We can decide into changing what team we want based on any kind of like variables
[01:05:37]
and play that. And that's it. So Elm team gives you all of that. And CSS variables are
[01:05:41]
an ideal way of doing that, right? So all of the elements styles are only using the
[01:05:47]
same values and we are just like providing these scopes that will change the actual values
[01:05:54]
that you are using. That's it.
[01:05:56]
That sounds very nice. I think it'd be the same thing in React at some point with providers.
[01:06:03]
Is that?
[01:06:04]
Providers? Yeah. There are a few teaming libraries in React that you can, well, not just React.
[01:06:11]
Flutter uses the same thing where you can kind of override the provider that you are
[01:06:18]
consuming. So you can have like a global provider and then like in your handler tree, you can
[01:06:23]
have another provider that kind of like overrides the previous one or just changes a value.
[01:06:28]
It's really useful for teaming as a whole.
[01:06:31]
So you mentioned that you selected a number of properties of the theme or a number of
[01:06:38]
things that you could set up so that you're constrained. So I'm looking at the package
[01:06:43]
right now. So for instance, you can set a theme color for primary, for secondary, for
[01:06:50]
success, warning, danger, right? Maybe you can't do it for tertiary or another one. So
[01:06:58]
you're very limited in what you can do. And I found that to be a bit scary, actually.
[01:07:04]
But you say that you did that on purpose. So I would love to hear more about that.
[01:07:08]
Sure. Since Elm theme aims to be used in the same page, like with multiple themes, then
[01:07:14]
you can get around that having multiple themes having like slightly different colors if you
[01:07:18]
want. But at the same time, the thing that is most difficult is not actually deciding
[01:07:23]
the number of base colors. Like for instance, we have like a base, a neutral, primary, secondary,
[01:07:31]
and then the status ones like success, warning, and danger. But the thing that is really difficult
[01:07:37]
is actually defining these three variations of the same color, which I decided on background,
[01:07:44]
foreground, and auxiliary. And the thing is that I want to be able to use some colors
[01:07:51]
as a foreground of the main background. Sometimes I want to use a color to be like a button.
[01:07:57]
Sometimes I want the color to be used in an icon that is like overlaying another color.
[01:08:02]
And this can get quite difficult, right? So if we have like this matrix of possibilities,
[01:08:09]
it's still, I don't know, possible to not go crazy and make sure that everything's working
[01:08:16]
well.
[01:08:17]
So if you go to the Elm widgets, Elm book, in the theme page, there is a theme generator.
[01:08:25]
I'm going to make that more useful so that you can like just throw your own theme there
[01:08:30]
and you can export the theme there that you are using. But it's pretty simple to see how
[01:08:35]
you can just like slightly change a color and see how it breaks compatibility with everything
[01:08:41]
else. Like, okay, so I'm changing this color, so I'm breaking contrast with all of these
[01:08:46]
other possible matches.
[01:08:49]
But once you have everything lined up and everything is accessible, then you are making
[01:08:55]
sure that all of your components that are following these same combinations, they are
[01:08:58]
also accessible. So I know that my button can be like a success button with like a success
[01:09:06]
background and a success auxiliary color as a foreground. I know that I have like a auxiliary
[01:09:13]
base color as the kind of like light color of text on the main background. It can get
[01:09:19]
a bit hard to talk about in like in a podcast like this. But it's not that complex when
[01:09:27]
you are seeing it. And I don't know, I feel like, how can I say this? When building a
[01:09:35]
design system, it can get a bit hard to talk about themes.
[01:09:39]
People are used to talk about defining or color palette. But once you talk about themes,
[01:09:49]
you're not talking about the color palette itself, you're talking about the color variable
[01:09:53]
palette. You are creating a layer of abstraction between your actual color value and the thing
[01:09:59]
that you are using on your code. So it can get tricky for designers to actually think
[01:10:07]
about a component in a way that is not specifically tied to a color, but it is tied to a color
[01:10:15]
variable.
[01:10:16]
So when I'm creating a button, I'm not thinking about, I'm going to use the color red here
[01:10:21]
and this like white on top of it. No, I'm using this background color because semantically,
[01:10:30]
it's what makes sense. And I'm using this foreground color on top of it. And I don't
[01:10:35]
care what it is. It's kind of like I'm always working on grayscale and everything is still
[01:10:42]
visible. But if someone wants to change all of the colors, that's fine because we are
[01:10:47]
talking about the contract is in this layer in between this abstraction layer of the team
[01:10:53]
variables.
[01:10:57]
And I feel like this is not the common place yet. I forgot the name of the thing, but there
[01:11:04]
is this JS styling framework that is getting a bit of a buzz right now. I'll try to remember
[01:11:12]
the name and I'll send you so you can add it to the show notes or something like that.
[01:11:16]
Put it in the show notes.
[01:11:17]
But it does exactly that. The whole thing is that it creates this team layer where people
[01:11:24]
can just define different teams and everything will look, it will work in all the teams.
[01:11:29]
And just by doing that, people are kind of like, oh, this is really great, et cetera.
[01:11:35]
So yeah, it's not that common.
[01:11:37]
Yeah. Well, great. Jorge, where should we point people if they want to follow you or
[01:11:43]
get started with Elm theme and Elm widgets?
[01:11:47]
Sure. I'm Jorge Borges in every single like, I don't know, like Twitter, Elm Slack, discourse
[01:11:56]
and everything basically. So you can find me there, please. And for Elm widgets, it's
[01:12:03]
on the Elm packages as Elm widgets, uncover slash CO Elm widgets. And there is also the
[01:12:11]
Elm book that you can find through the docs, but it's called Elm slash widgets dot netlify
[01:12:17]
dot app. And there you can just like have a run through of the different components
[01:12:23]
and how you would set up. I plan to really evolve it bit by bit. I'm kind of like hoping
[01:12:29]
this is not my Dwarf Fortress project, you know, like something that I'm working on for
[01:12:33]
20 years.
[01:12:34]
There is nothing wrong with that.
[01:12:39]
Trigger warning.
[01:12:41]
But, but, but yeah, like I, maybe this can be a, I really hope that this, this becomes
[01:12:53]
more of a community thing than Elm book. Like Elm book, I'm super grateful because there's,
[01:12:59]
there's a lot of issues open right now, which I'm excited about because most of the issues
[01:13:05]
are not actually bugs, it's just like people asking about stuff. And I hoped for Elm widgets
[01:13:11]
since it's more of a well-scoped set of things, like each module it's, it lives in isolation
[01:13:19]
from the others. So I hope that people can be more like contributors, like in the code
[01:13:25]
itself, right? Like just go there and make your CSS trickery available to the whole Elm
[01:13:30]
community. Yeah.
[01:13:31]
Cool. Amazing. Well, thanks again, George, for, for coming back on. It was a pleasure
[01:13:36]
to have you again.
[01:13:37]
It's always a pleasure. And I hope to one day open this podcast with, hello, Jeroen.
[01:13:47]
And Jeroen, until next time.
[01:13:49]
Until next time.