spotifyovercastrssapple-podcasts

Color parameters in elm-tailwind-modules with Philipp Krüger

Philipp joins us to talk about color parameters in elm-tailwind-modules and how that brings the tool closer to an ideal expression of a design system in Elm.
March 13, 2023
#78

Transcript

[00:00:00]
Hello, Jeroen.
[00:00:01]
Hello, Dillon.
[00:00:02]
And, well, today we've got another friend of the show joining us, Philip Kruger.
[00:00:08]
Philip, thank you so much for coming back on the show.
[00:00:11]
Hi, thank you for having me again.
[00:00:13]
It's a pleasure.
[00:00:14]
I have been a very happy user of Elm Tailwind Modules and Elm Default Tailwind Modules.
[00:00:21]
So thank you for those tools and thanks for coming back on.
[00:00:25]
Thank you.
[00:00:26]
I'm glad you like them and, yeah, lots of complicated names in all of those tools.
[00:00:32]
Lots of very sensible names, but you got to remember which order they come in.
[00:00:36]
Right.
[00:00:37]
So what are we talking about today, Philip?
[00:00:42]
So Elm Tailwind Modules currently has a new alpha release and in that release there's
[00:00:49]
some nice features that we want to talk about.
[00:00:52]
Actually, Dillon and I both worked on this and I think they're coming up nicely.
[00:00:57]
It's not released yet, at least the NPM package.
[00:01:01]
You can try it out anyway.
[00:01:03]
So yeah, it's an alpha.
[00:01:05]
Yes.
[00:01:06]
And so, okay, so there's the NPM package, Elm Tailwind Modules, and there's the Elm
[00:01:12]
package, Elm Default Tailwind Modules, which is basically the result of running the code
[00:01:18]
generation from the NPM package with the default configuration, right?
[00:01:23]
Yes, exactly.
[00:01:24]
So Elm Tailwind Modules is a code generation tool?
[00:01:29]
Yes.
[00:01:30]
So Elm Tailwind Modules is a code gen tool you install from NPM.
[00:01:36]
You can run it on your NPM config.
[00:01:39]
So if, sorry, on your Tailwind config.
[00:01:42]
So if you have a project with Tailwind CSS installed and you want to use that Tailwind
[00:01:50]
CSS config that you're using in Elm together with Elm CSS, then you can use the NPM package
[00:01:58]
to turn your Tailwind config into Elm Modules that use Elm CSS to have the same effect that,
[00:02:06]
well, all of the CSS classes that Tailwind has have.
[00:02:12]
Is that the right sentence structure?
[00:02:13]
I don't even know.
[00:02:15]
Philip, we did have you on, I guess a couple of years ago now, to talk about the initial
[00:02:21]
release of Elm Tailwind Modules.
[00:02:25]
But why don't we give people a little bit of a refresher?
[00:02:27]
They can go back and listen to that full episode.
[00:02:30]
But like, what problem is Elm Tailwind Modules trying to solve to begin with?
[00:02:34]
And even what is Tailwind?
[00:02:36]
What is that thing that no one has heard about?
[00:02:38]
That's right.
[00:02:39]
Yes, yes.
[00:02:40]
So Tailwind CSS is a way to style your applications using CSS.
[00:02:47]
It is using, I think people call this atomic CSS classes nowadays.
[00:02:52]
Is that still true?
[00:02:53]
I think so.
[00:02:54]
Utilities?
[00:02:55]
Utilities, perhaps.
[00:02:56]
Yeah, utility classes is a term that is used a lot.
[00:03:00]
Oh yeah, utility classes.
[00:03:02]
Right, right, right.
[00:03:03]
So basically the idea is your CSS class definitions are like very, very narrowly scoped.
[00:03:10]
And so for example, to make an element have display flex set, you simply put a class called
[00:03:18]
flex on it.
[00:03:19]
If you want it to be full width, you say w-full as a class on it, if I remember that correctly.
[00:03:29]
And well, so all of these classes in Elm, you'd have to set as strings, right, in your
[00:03:37]
class function from Elm HTML.
[00:03:40]
Or, well, yeah.
[00:03:43]
And since you don't get any type checking with that, that means you might do a typo
[00:03:48]
and wonder why your button doesn't take the full width just because you messed up some
[00:03:54]
dash or something in the name.
[00:03:58]
And so for that, someone else already built a tool which basically takes all of the Tailwind
[00:04:07]
classes that exist and creates small definitions for them, but then relays that to use classes
[00:04:16]
again.
[00:04:17]
So you need to install your or add your CSS file to your Elm application somehow that
[00:04:23]
was generated from Tailwind.
[00:04:25]
And you need to figure out how to do that class elimination, essentially, right?
[00:04:31]
So Tailwind CSS classes that weren't used need to be deleted somehow.
[00:04:36]
And I found that it would be better to just reuse the dead code elimination that Elm the
[00:04:44]
language itself has instead of having to rely on other tools that go through your JS file
[00:04:49]
and try to find certain strings to figure out which classes to remove and to keep.
[00:04:55]
So instead, I built something that was based on Elm CSS.
[00:05:00]
So Elm CSS is a way of describing CSS styles within Elm as code, essentially.
[00:05:07]
And then these automatically get put into your Elm app.
[00:05:10]
You don't have to add any CSS files, some kind of styles.
[00:05:15]
You don't need that.
[00:05:16]
That's all managed by Elm.
[00:05:18]
And similarly, if you just don't use a couple of CSS classes from some module, well, they
[00:05:23]
won't appear in your final code because Elm just eliminates them.
[00:05:28]
Right.
[00:05:29]
So in addition to that, you can, this is one of the kind of really amazing things from
[00:05:34]
this design is you can throw in Elm CSS styles next to Tailwind styles.
[00:05:42]
So if you need to do some really custom CSS, you can even compose them together.
[00:05:47]
You can even, you know, add a media query that's not built into the Tailwind configuration
[00:05:55]
for your breakpoints, you know, like prefers reduced motion or whatever media query you
[00:06:00]
need to add, you can compose that media query together with Tailwind classes because it's
[00:06:05]
just generating Elm CSS.
[00:06:07]
Yeah, exactly.
[00:06:08]
Yeah.
[00:06:09]
There were a couple of nice follow ups from that.
[00:06:13]
Yeah.
[00:06:14]
So if I get it right, usually when you use Tailwind, you just say, hey, I want to use,
[00:06:20]
I want to, usually when you use Tailwind, you say, I want this thing to have full width.
[00:06:26]
So you do W dash full, and then Tailwind sees it and inserts some CSS code, which is going
[00:06:34]
to have the nice properties to make the thing have the full width, right?
[00:06:40]
Yes.
[00:06:41]
And what you're doing with your project is you don't have that real CSS generated by
[00:06:48]
Tailwind, you reimplement it using Elm and Elm CSS, right?
[00:06:54]
Yes.
[00:06:55]
Okay, so there's no, Tailwind doesn't do anything except your defined configuration, and you
[00:07:02]
just piggyback on that one to generate your Elm code.
[00:07:06]
It's almost like that.
[00:07:08]
Yes, we still, we don't bypass Tailwind CSS completely.
[00:07:12]
So essentially, how it works on the inside is it will generate the whole CSS file from
[00:07:21]
Tailwind CSS, and then it will turn that using the Tailwind config, and then it will turn
[00:07:27]
that CSS file into a big Elm module that contains all classes, each with their own definition
[00:07:36]
exposed and then you use that.
[00:07:38]
Right, okay.
[00:07:39]
So you still use it to generate that original CSS file, and then you just generate Elm code
[00:07:44]
and scrap that CSS file.
[00:07:46]
Yes, exactly.
[00:07:47]
Because you don't need it anymore.
[00:07:48]
Okay, interesting.
[00:07:49]
It should all be in memory, so there is no file actually generated.
[00:07:54]
Yeah, so this composability you get with Elm CSS is really interesting.
[00:08:01]
And so when Tailwind v3 came out, there was an interesting challenge that came up because
[00:08:09]
Tailwind v3 introduced this just-in-time JIT compiler that their approach if you're using
[00:08:17]
a project like React, and you can add in these arbitrary colors and CSS properties within
[00:08:24]
Tailwind utility classes, because the JIT compiler would be running in a dev server
[00:08:31]
and automatically generating CSS utility classes for you as needed.
[00:08:37]
So if you use something with an arbitrary color notation that defines a color that's
[00:08:43]
not in your Tailwind configuration, suddenly a CSS utility class would come into existence
[00:08:49]
in this JIT interpreter, and now your CSS file in your dev server would have that.
[00:08:55]
Whereas that became one challenge to support with Elm Tailwind modules.
[00:09:00]
But in addition to that, they just started throwing a whole bunch of different style
[00:09:07]
options and permutations at it.
[00:09:09]
And so the configuration blew up with a huge number of options.
[00:09:13]
So as I recall, there were around like 100,000 generated utilities in the default configuration
[00:09:23]
with v3, which became essentially unusable with a lot of tooling with IntelliSense.
[00:09:30]
And the compiler handles it pretty well, but editor tooling does not like that.
[00:09:35]
Yeah, exactly.
[00:09:36]
I remember it being a problem in the early days of Elm Review, where someone was making
[00:09:41]
this at the same time when there was a 75,000 lines of code Elm file.
[00:09:47]
And like, yeah, that is starting to be quite a big file for any tool like editors and Elm
[00:09:55]
Review.
[00:09:56]
And somehow it stopped being a problem because people stopped using that anyway, or that
[00:10:03]
approach of building a huge file.
[00:10:05]
So I'm glad about that.
[00:10:07]
Yeah, I think part of that is trying to hide it from the tools, trying to hide it in something
[00:10:14]
else.
[00:10:15]
So for example, people do like using, well, the Elm package, Elm default Tailwind modules.
[00:10:22]
So that is just running Elm Tailwind modules, the code generator on the default Tailwind
[00:10:28]
configuration.
[00:10:29]
And so if that's like hidden behind a library, then people still can use it, but their tooling
[00:10:36]
won't have to parse the whole thing all the time while they're working on their project.
[00:10:43]
But yeah, I'm glad I provide stress testing test cases to deal with.
[00:10:50]
I definitely had my fair share of problems with huge Elm files generated from Elm Tailwind
[00:10:57]
modules too.
[00:10:58]
I mean, you really don't have to provide stress tests, honestly.
[00:11:02]
I'd be fine without them at this point.
[00:11:06]
I'm sorry.
[00:11:09]
So when I think about like just this whole Tailwind approach of these utility classes,
[00:11:15]
like in a way, if you really think about it, a single utility class is almost like a notation
[00:11:24]
for parameterizing things.
[00:11:26]
So if you say like, LG colon hover colon text large, or something like that, you're saying
[00:11:37]
on a large screen on hover, make the text large.
[00:11:42]
And really, those are almost like things that you're composing together conceptually.
[00:11:47]
But as far as Tailwind utility classes go, it's giving you an actual class for every
[00:11:53]
possible thing you could do.
[00:11:55]
Which means like, if you do, you know, instead of large, instead of LG, you do SM, you do
[00:12:01]
small, and then hover and then something else, it's generating a class for every single thing
[00:12:08]
you do, which means every permutation of every possible thing gets generated, which is why
[00:12:13]
you have to prune the generated Tailwind CSS file, which is why you can't just like include
[00:12:20]
Tailwind.CSS.
[00:12:21]
I mean, you actually, I'm not sure if with v3 you can because it's so huge now.
[00:12:27]
Back in the day, sometimes people would do that.
[00:12:29]
And it was like a 10 megabyte file with every possible permutation.
[00:12:33]
And that's why you use this sort of, you know, regex scanner to find the classes that you
[00:12:39]
use and don't use.
[00:12:40]
So the Tailwind can prune down to just the ones you use.
[00:12:44]
Elm Tailwind modules addresses that, like the earlier release addressed that problem
[00:12:49]
partially by making things composable with Elm CSS.
[00:12:53]
And then you had things like breakpoints generated a function.
[00:12:59]
So you do like, so you would get a breakpoint.large function, and that takes a list of Elm CSS
[00:13:06]
styles, and you can pass it other Tailwind styles.
[00:13:09]
So you can compose it together.
[00:13:11]
So essentially, it takes these things that just generate a CSS class for every possible
[00:13:18]
permutation of everything you could possibly express.
[00:13:20]
And it turns that into what it really more conceptually is, which is like composing together
[00:13:25]
these different pieces.
[00:13:27]
And so sort of like a good tool for that, right?
[00:13:30]
Absolutely.
[00:13:31]
Now, this latest alpha release and this latest non alpha release of Elm default Tailwind
[00:13:37]
modules, the Elm package, kind of goes a step further with the composability.
[00:13:42]
So not only do you have the breakpoints being a function that more conceptually matches
[00:13:48]
what it's doing, this composable thing, instead of a bajillion permutations of everything
[00:13:52]
you could possibly do.
[00:13:54]
So what's the new development in the latest version, Philip?
[00:13:58]
You want to?
[00:13:59]
Yeah, sure.
[00:14:00]
So basically, before, if you, let's say you wanted to make an elements background blue.
[00:14:07]
So there would be one Tailwind class for that, that would be bg-blue-100, for example.
[00:14:16]
And so that sets the background color to the blue 100 color.
[00:14:19]
The blue 100 color is something that is defined in your Tailwind config, or it is coming from
[00:14:25]
the default Tailwind colors that is in your default Tailwind config.
[00:14:30]
In the new version, you would actually compose a function together with a value.
[00:14:35]
So very simple, you'd have bg underscore color being a function and you apply to it a blue
[00:14:44]
underscore 100 color from the theme module, which is a new module now generated in Tailwind
[00:14:52]
modules in the new alpha.
[00:14:54]
And so that makes it, that reads nicely.
[00:14:57]
You can technically abstract it if you, let's say, wanted to create some kind of view function
[00:15:03]
that is abstract over a bunch of colors.
[00:15:06]
You could do that.
[00:15:07]
You could apply the color later if you have a bunch of themes.
[00:15:11]
There's fun things you can do with it.
[00:15:14]
Previously, it would be really, really hard to create these composable view functions,
[00:15:19]
for example, because you're actually not allowed to, let's say you don't use Elm Tailwind modules,
[00:15:27]
you don't use any other Elm tools, you only compose these strings together in normal Tailwind
[00:15:35]
CSS.
[00:15:36]
But then you wouldn't actually be able to break apart the string and choose the color,
[00:15:43]
essentially, from some computation, from an if expression or something like that.
[00:15:50]
Because then once you break up the string, the regex matcher from Tailwind CSS wouldn't
[00:15:54]
be able to recognize that you're using this utility, the CSS utility.
[00:16:00]
So that's something that is not much nicer, I think.
[00:16:03]
That makes the Elm version of it kind of nicer to use, I would argue.
[00:16:08]
Yeah, I really like that point.
[00:16:10]
I think when you are able to use the same mental model you use for writing Elm code
[00:16:16]
and the way that dead code illumination happens with Elm code, that's huge.
[00:16:23]
Because as you say, you don't have to get superstitious with your code where you say,
[00:16:29]
wait a minute, am I allowed to concatenate strings together or will that break things
[00:16:33]
in mysterious ways?
[00:16:35]
That doesn't feel great to have to think about that with Elm code, which is what happens
[00:16:39]
if you use vanilla Tailwind with a class string in Elm.
[00:16:48]
You have to worry about those spooky side effects at a distance.
[00:16:53]
In addition to that, like you said, you can have a button helper function that takes an
[00:17:01]
on hover color and a regular color for the background.
[00:17:06]
And now those are Elm values that you can pass to Elm functions because these generated
[00:17:13]
Tailwind helper functions that Elm Tailwind modules now generates for you are functions
[00:17:20]
that take color parameters.
[00:17:22]
So this is really nice from a developer experience perspective.
[00:17:27]
It also, I will note, I have a GitHub issue where I sort of explored the, I did my best
[00:17:34]
to remember my combinatorics math stats class.
[00:17:38]
I was never great at stats class.
[00:17:40]
So the number of lines to beat is 75,000.
[00:17:45]
Oh, yes.
[00:17:47]
Oh, I think we did.
[00:17:50]
The number of lines to beat is 75,000 for Tailwind version two.
[00:17:55]
So with Tailwind version three, they added like so many more definitions.
[00:18:00]
Even if you just had a single line for every definition, you would have a thousand lines,
[00:18:05]
a hundred thousand lines of code.
[00:18:07]
Yes, exactly.
[00:18:08]
So for Tailwind version three, I showed my work.
[00:18:15]
So if anybody doubts my stats calculation abilities, which I would not blame you for,
[00:18:21]
you can see I showed my work at least in this GitHub issue.
[00:18:24]
But it goes from a grand total of 88,320 down to 23 when you parameterize the color and
[00:18:34]
opacity variance.
[00:18:36]
So 88,000 to 23?
[00:18:40]
Yeah.
[00:18:41]
Wow.
[00:18:42]
That's not every possible style, but at least that number, like, that's a subset of the
[00:18:53]
total possible styles.
[00:18:54]
But it did reduce by that amount, to put it that way.
[00:18:57]
You can think of it this way.
[00:18:59]
You're like, you actually only have 23 different kinds of small utilities.
[00:19:04]
Like you can change the accent color, you can change the background color, the text
[00:19:09]
color.
[00:19:10]
Those are the 23 different things, and then you multiply that with every main color that
[00:19:15]
Tailwind has, and every variation that Tailwind has for every main color.
[00:19:20]
Then with every opacity that is possible with each of those colors, then you multiply that
[00:19:26]
with breakpoints and more and more, and you will get like huge and huge amounts of combinations.
[00:19:32]
And previously, Tailwind modules would generate all of that for you, thinking, well, it can
[00:19:37]
be deleted later.
[00:19:38]
But of course, that causes issues.
[00:19:40]
At one point, I generated a basically full configuration kind of file with Tailwind modules
[00:19:48]
as a test.
[00:19:49]
Basically, that's always running as a test in the generator code.
[00:19:54]
And so that includes the typography plugin for Tailwind, and I think, yeah, also another
[00:20:01]
plugin, but that may be unrelated.
[00:20:04]
And it clocked out at like 2 million lines of codes or more for like a full configuration
[00:20:12]
as an Elm file.
[00:20:13]
And that's just, well, that's a lot.
[00:20:15]
Tooling won't handle that well at all.
[00:20:18]
So yeah, that needed to change.
[00:20:21]
It's only 33 times more than that file that was already way too big.
[00:20:26]
Yes, exactly.
[00:20:28]
So...
[00:20:30]
Yeah.
[00:20:31]
We can do better.
[00:20:34]
I'm sure we'll wait a couple of Tailwind versions, and we'll roll back to the old Elm Tailwind
[00:20:40]
modules version, and we can generate some massive new files for you.
[00:20:46]
So this changes, is it only for colors or is it also for other things that are somewhat
[00:20:52]
similar?
[00:20:53]
This version actually only abstracts out colors.
[00:20:55]
There are other possible things to abstract out, like spacing, variables, but for now,
[00:21:03]
it's only colors.
[00:21:04]
Okay.
[00:21:05]
Why would you or would you not want to do things like spacing?
[00:21:09]
Well, it is basically something else to figure out exactly how to do it.
[00:21:14]
Spacing...
[00:21:15]
And there's always like a conversation to be had about how configurable do you want
[00:21:20]
your styles to be, because there is some value in restricting the set of possibilities, essentially.
[00:21:28]
So you have fewer things to choose from when you're building a front end, and you usually
[00:21:33]
end up with more consistent styles.
[00:21:36]
And you could pretty quickly argue that, well, if you have this utility that is literally
[00:21:42]
W-3, W-4, W-5, why not just abstract that out?
[00:21:49]
And instead of using these numbers, just literally pass in the integers.
[00:21:53]
At some point, well, that could be argued, and there's more to be figured out exactly.
[00:21:59]
Is that something that you should do?
[00:22:02]
Is that something that will destroy some value of Tailwind CSS, or is it not?
[00:22:07]
So basically, there's more thoughts to be had about that.
[00:22:11]
Yeah.
[00:22:12]
So Tailwind already limits what you can do, because for instance, you have W-3 pixels
[00:22:19]
or something, which says that something is three pixels wide, and you say, think four
[00:22:26]
or four, then you have eight, then 16, that kind of thing.
[00:22:30]
It's actually more abstracted.
[00:22:33]
It's not pixels.
[00:22:36]
They sort of have the configuration gives you these increments, but they're not defined
[00:22:41]
as pixels and they're abstracted away from that.
[00:22:44]
But yeah.
[00:22:45]
Yeah.
[00:22:46]
There's one pixel, I think.
[00:22:47]
And then it's that abstract thing.
[00:22:49]
Is there one pixel one?
[00:22:50]
Oh, nice.
[00:22:51]
I think so.
[00:22:52]
Okay.
[00:22:53]
Yeah.
[00:22:54]
Because that could, I guess, be useful.
[00:22:55]
But yeah, so you already have a pretty restricted set of width that you can set.
[00:23:00]
So one, two, four, eight, 16, something like that.
[00:23:05]
So I could imagine that you could also, just like colors, just say, well, these are the
[00:23:09]
different possible values that you can pass.
[00:23:12]
It's one, some variants, one, variant two, variant 16, variant 32.
[00:23:17]
And I was like, would that make sense as well for Tailwind to parameterize some of these
[00:23:22]
functions the same way?
[00:23:24]
Again, to reduce the size of Tailwind and the number of generated utilities that you
[00:23:30]
have?
[00:23:31]
Yes, I think so.
[00:23:32]
I think that would make sense.
[00:23:33]
There's just some thinking to be had about exactly how, like, perhaps we can put that
[00:23:38]
into a theme.
[00:23:39]
And like, we literally have a to do in the repo, which is do the same that we did with
[00:23:44]
auto abstracting the colors, and just auto abstract the spacing as well.
[00:23:50]
I think the space that we save from doing that is actually a little less than with colors,
[00:24:00]
because colors were just the more extreme case with more and more combinations.
[00:24:04]
I can see that.
[00:24:05]
Yeah, I actually did a few calculations on that in this GitHub issue.
[00:24:10]
And what I wrote is that from the v3 output with a default configuration, using the older
[00:24:18]
release of Elm Tailwind modules, 98% of the output was related to or 98% of the generated
[00:24:28]
definitions had colors in the name.
[00:24:31]
2% did not.
[00:24:33]
So 1600 did not have colors in the name.
[00:24:37]
80,875 did have colors in the name.
[00:24:39]
So that was the biggest one.
[00:24:41]
Because what it is, is it's like, you know, with combinations, when you're like, order
[00:24:47]
independent combining things, every time you add something, you're multiplying the number
[00:24:52]
of possibilities, just like adding a nested for loop, you know, so you go from O of N
[00:24:58]
to O of N squared, to O of N or, you know, O of M times N, if you prefer, you know, however
[00:25:05]
you want to call that, but effectively O of N squared and cubed, these colors were getting
[00:25:11]
into these deeply nested loops where you're multiplying, multiplying, multiplying.
[00:25:16]
And because it was, you know, the accent plus left or right or x or y plus or no, that would
[00:25:27]
be for border has those options.
[00:25:31]
Plus you can have a color strength, plus you can have a color opacity.
[00:25:37]
So it blew up pretty quickly.
[00:25:39]
Yeah, exactly.
[00:25:40]
But now, now the that's, that's all gone.
[00:25:45]
And instead, if you look at, for example, the Tailwind module, the utilities module
[00:25:51]
that is generated from the default Tailwind configuration, that clocks in at around 50,000
[00:25:57]
lines of code.
[00:25:58]
So we're, we're down a little from the 70 to 75,000.
[00:26:03]
However, we also like have a lot more stuff in that module.
[00:26:09]
So there's way, way more things you can, way more colors and combinations and stuff that
[00:26:13]
you can use.
[00:26:14]
Yeah.
[00:26:15]
And you heavily relying on Elms live code inclusion slash dead code elimination to reduce
[00:26:21]
that in practice, right?
[00:26:24]
Yeah, absolutely.
[00:26:25]
Absolutely.
[00:26:26]
And one of these, one of the things that this really makes me kind of step back and think
[00:26:30]
about is, you know, we, we talked about this a little at some point, Philip, like when
[00:26:35]
you think about what, what is the value at that point?
[00:26:40]
And what are we actually doing here with like this library?
[00:26:43]
It makes you think about like, what now you've just got a bunch of functions for basically
[00:26:48]
like saying, this is a text background color, and here's a color that I'm passing into it.
[00:26:54]
And at that point, it almost becomes Elm CSS and except with like a design system.
[00:27:01]
So it, it really makes you think like, how, how does this compare to our platonic ideal
[00:27:08]
of a way of writing kind of a design system in Elm?
[00:27:13]
Like if we just wrote that from scratch, what would that look like?
[00:27:16]
And how does that compare to what Elm tailwind modules is generating for us now?
[00:27:22]
Yeah, that's, that's an interesting question.
[00:27:24]
Elm tailwind modules is definitely still like, most or a lot of its reasons for existence
[00:27:32]
is the whole ecosystem around tailwind.
[00:27:35]
But they're like, if you take all of that away, you quickly start to think about, well,
[00:27:42]
it's probably mostly a bunch of smart folks who've identified a good way to create utilities
[00:27:51]
to style web pages.
[00:27:54]
So they figured out which utilities are useful, and how to, well, how do I say this, basically,
[00:28:03]
they found a good way to factor utilities for styling HTML.
[00:28:10]
And if you take away all of the tailwind CSS stuff, and you start to abstract out these
[00:28:17]
utilities, you could think of like creating a something similar to Elm UI that has similar
[00:28:24]
utilities for setting the background color, and other CSS web API things.
[00:28:32]
And yeah, I think it looks a lot similar, very similar to something like Elm UI.
[00:28:37]
Right.
[00:28:38]
Yeah, if I think about like, let's say, I'm like, maybe even like kind of new to web development,
[00:28:47]
and, you know, familiar with Elm, and I'm like, okay, does Elm give me like a really
[00:28:52]
easy way to like style things like I love the simplicity of Elm, and not having to think
[00:28:57]
about weird mutations and side effects and things happening?
[00:29:01]
Is there something that makes me feel that way with the way you style things in Elm,
[00:29:07]
right?
[00:29:08]
And, you know, Elm UI is one answer to that question that abstracts away all these things
[00:29:12]
that you don't have to think about centering an element and things like that, which is
[00:29:17]
awesome.
[00:29:18]
When I think about the things like that are going to be stressful when you're getting
[00:29:23]
into web development, or like just for me, who's not super strong styling person, it's
[00:29:29]
like, should I use font size in pixels or REM or EM?
[00:29:36]
It's like there's so many, there's like analysis paralysis, where there are so many choices.
[00:29:44]
And you have to sort of navigate those choices.
[00:29:47]
It's not like here are a bunch of reasonable choices that will give you good results for
[00:29:51]
your users, accessibility, maintainable code.
[00:29:54]
It's like, yeah, here are a bunch of choices.
[00:29:56]
But if you use inconsistent options, or the wrong options, you will end up with unmaintainable
[00:30:02]
code and inaccessible code and bad things will happen.
[00:30:06]
And that sucks.
[00:30:07]
So that's one thing like when you do when you use Tailwind, what you're getting is like,
[00:30:14]
they made that choice of whether to use font size in pixels or EM or REM, which I don't
[00:30:21]
even know.
[00:30:22]
And I don't really care.
[00:30:23]
And I don't have to care.
[00:30:24]
And for most people just using like the built in Tailwind, like text large text small is
[00:30:30]
fine.
[00:30:31]
And you don't ever really have to think about that because they're really good at those
[00:30:35]
things.
[00:30:36]
And they've researched them a lot.
[00:30:37]
So that's like a huge part of the value of it.
[00:30:40]
Like another thing that I wouldn't want to have to think about with CSS coming into Elm
[00:30:47]
as a new web developer is like defining my CSS classes and thinking about the cascading,
[00:30:52]
right?
[00:30:53]
Elm UI sort of like addressed that problem in its own way of you don't have to think
[00:30:57]
about cascading because that that is a very stressful part of CSS.
[00:31:02]
And Tailwind utility classes approaches that problem in a different way, but it still solves
[00:31:06]
that problem.
[00:31:07]
You don't have to think about cascading because it's all just adding utility classes.
[00:31:11]
Yes, exactly.
[00:31:13]
You've got like the amazing community, all of these thoughtful design decisions that
[00:31:19]
go into it that you get for free.
[00:31:21]
You have a design system that constrains, like gives you guardrails of well thought
[00:31:26]
out steps for your sizing and margins and padding and things like that.
[00:31:32]
And now you start to be able to compose them together with functions where you can pass
[00:31:37]
in color, you can define a breakpoint and pass in all the things and use them programmatically.
[00:31:43]
And you can think of it just like Elm code.
[00:31:45]
And then the only thing that's left that I'm thinking like as somebody who's like, okay,
[00:31:51]
Elm makes so much sense.
[00:31:52]
What if I rethought CSS from scratch?
[00:31:55]
And now I'm like, well, there still is like margin versus padding, which one should I
[00:31:59]
use?
[00:32:00]
And there still is like all these quirks of like flex, and I need to define flex in the
[00:32:06]
right place for a parent and things like that.
[00:32:08]
So those are the things that come to mind that are left that are like, that's not quite
[00:32:12]
the platonic ideal, but a lot of the things start to get pretty close to that.
[00:32:16]
Yes, exactly.
[00:32:17]
There's a lot of things.
[00:32:18]
I mean, I think that there will I think that a pure Elm solution would look a lot like
[00:32:26]
something like Elm UI.
[00:32:28]
But I think there is real value in just because we're not there today in reusing this huge
[00:32:34]
ecosystem of well, Tailwind CSS is very opinionated.
[00:32:40]
But at the same time, it is also very expressive.
[00:32:42]
And there's a lot of people out there who are writing Tailwind CSS.
[00:32:46]
They kind of share the same opinionated configuration, essentially, because they're all using Tailwind
[00:32:53]
CSS.
[00:32:54]
So when you see something, let's say you're on TailwindUI.com, I think it was right.
[00:33:00]
And you have these prebuilt components, you can take them.
[00:33:03]
And because it's just HTML and uses these utility classes, they're just right in there.
[00:33:10]
You can reuse that you can use that for your stuff.
[00:33:13]
This helps beginners who don't know CSS very well, just taking that into their projects
[00:33:19]
and starting something with it.
[00:33:21]
If you just had a CSS file and an HTML file, then these can get out of sync and weirdly
[00:33:27]
combine and not work exactly correctly.
[00:33:31]
If you have a different kind of HTML structure and stuff like that.
[00:33:34]
So there's, I think there's huge value in that ecosystem.
[00:33:39]
And it's nice bringing that into Elm.
[00:33:41]
Yes.
[00:33:42]
I should say Tailwind UI is the the creators of Tailwind CSS created a sort of component
[00:33:50]
like showcase.
[00:33:52]
It's like a set of components and screens that basically just gives you like the HTML
[00:33:58]
and Tailwind CSS classes for these common screens, a sales page, a blog post selection,
[00:34:06]
testimonials page, and they look really good.
[00:34:09]
And you can copy paste them into HTML2Elm.com and even get Elm Tailwind module style syntax.
[00:34:19]
Yes.
[00:34:20]
And I think from that perhaps, like we can also learn something.
[00:34:24]
I mean, Tailwind CSS is pretty good.
[00:34:28]
And it's nice to be able to take that ecosystem into Elm.
[00:34:31]
But of course, it's not perfect, right?
[00:34:33]
We still have 50,000 lines of code of utilities that could be better composable, we could
[00:34:40]
have spacing abstracted out, we could not have both padding and margin, and you don't
[00:34:45]
know which one to use.
[00:34:47]
We could not have I don't know, nowadays, it's too many ways of centering stuff.
[00:34:53]
Do you use text center?
[00:34:54]
Do you use margin auto?
[00:34:56]
Do you use items, center and flexbox or whatever it is?
[00:35:03]
Because still like it's not perfect.
[00:35:05]
But for something like that to exist in the Elm ecosystem, I would imagine it to be, let's
[00:35:10]
say it uses Elm UI, and it provides a bunch of that the value of the big value I see is
[00:35:18]
people publishing pre built components that you can take and modify to your needs.
[00:35:25]
So somebody has a dashboard kind of structure that you can just copy, and you can adapt
[00:35:32]
for your project.
[00:35:34]
Or there's something built with Elm UI that gives you a sidebar or a login form, those
[00:35:43]
kinds of things.
[00:35:44]
But then also learning from tailwind CSS, we know that likely you want to have a configuration
[00:35:52]
for your theme.
[00:35:54]
So there's going to be your company's CI in there.
[00:35:59]
And actually, what did CI stand for?
[00:36:02]
Corporate identity, right?
[00:36:03]
Okay, sorry, exactly.
[00:36:04]
That's what I wanted to figure out.
[00:36:10]
So the company's corporate identity is what I meant.
[00:36:13]
So the color theme that the company uses or something like that, that would be in your
[00:36:18]
tailwind.
[00:36:19]
And so those kinds of things, right?
[00:36:22]
You would have that with Elm UI.
[00:36:24]
And then I think you get into like a very similar kind of situation, a nice ecosystem
[00:36:31]
where you help juniors who maybe not know how to style stuff very effectively, or anyone
[00:36:38]
who wants to start up something.
[00:36:39]
I think for that, it would be really helpful.
[00:36:41]
Now, when you say Elm UI, do you literally mean Elm UI?
[00:36:47]
Elm UI as it exists now, obviously is not composable with these things that Elm Tailwind
[00:36:53]
modules generates, which are Elm CSS properties.
[00:36:56]
Do you mean exactly Elm UI or something with a similar interface to Elm UI?
[00:37:01]
Yeah, basically, what I'm getting at is you could build something on top of Elm UI that
[00:37:06]
well, because Elm UI improves upon not having both padding and margin and these kinds of
[00:37:14]
things, but it does not have the configuration.
[00:37:17]
I think it would be valuable if you had something like these component libraries that others
[00:37:24]
are building, and but they would be configurable with some kind of configuration.
[00:37:29]
And you essentially build something like Tailwind CSS, but around Elm UI.
[00:37:34]
I can imagine something like that.
[00:37:35]
That's very interesting, although it does become difficult, because you talked about
[00:37:39]
like being able to tap into this giant community, and set of resources for Tailwind.
[00:37:46]
And so if you've got if you go to Tailwind UI.com, and you go copy paste some HTML from
[00:37:53]
there, and it uses margins and padding, yes, you definitely lose that ecosystem.
[00:38:00]
That is true.
[00:38:01]
Basically, I see this as a thought exercise, like what is the what is the perfect version
[00:38:07]
look like?
[00:38:08]
Having learned from what Tailwind CSS has done, right?
[00:38:12]
Yeah.
[00:38:13]
I mean, we should just compile every component to the equivalent to HTML binary or something.
[00:38:19]
And then you can, then you can compile that components that you found on the on the internet,
[00:38:26]
and just keep using your own configuration.
[00:38:28]
Oh, yeah, that would be interesting.
[00:38:32]
This was just a very random idea.
[00:38:36]
Or perhaps, perhaps you don't even need to do the copy pasting thing.
[00:38:40]
And at the end of the day, maybe that's the wrong flow.
[00:38:43]
And you can actually reasonably abstract stuff and just use a function from a package, perhaps,
[00:38:51]
perhaps not, I don't know, maybe the equivalent of Tailwind UI and Tailwind CSS would just
[00:38:57]
be packages and functions.
[00:38:59]
But yeah, nobody's built that yet.
[00:39:01]
Exactly the way I described, I think, I don't know.
[00:39:04]
So I feel like I missed something or unclear about something.
[00:39:07]
Is it possible in Tailwind to say, remove all the classes related to margin or to padding
[00:39:13]
or whatever?
[00:39:14]
No, sorry.
[00:39:15]
I don't know.
[00:39:17]
That's not possible.
[00:39:18]
Or perhaps I'm misunderstanding something.
[00:39:20]
Yeah, I mean, it is interesting, because there is this sort of quality in the Elm community.
[00:39:26]
There's a willingness to think things up from scratch.
[00:39:30]
And sometimes say, like, hey, here's this way of solving problems.
[00:39:36]
And it doesn't support every possible way of solving problems.
[00:39:39]
And that's the point.
[00:39:41]
And we don't give you escape hatches even for that.
[00:39:43]
So if you don't like it, then use another package that lets you do that or drop down
[00:39:49]
to a lower level thing.
[00:39:50]
Like that's kind of, that's an approach that's pretty common in Elm.
[00:39:54]
And it's one of the things we love about it, but it definitely has trade offs.
[00:39:58]
So I mean, it seems Elm Tailwind modules as it stands, is a pretty darn good balance of
[00:40:04]
like, you know, being able to use a well thought out design system and all these great things.
[00:40:10]
But it actually, it doesn't limit what you can do at all.
[00:40:14]
And also you can do semantic HTML and you can, you can use margin if you need to.
[00:40:20]
But at least like, it gives you these things that are easily within reach, where you usually
[00:40:26]
don't have to think about those weird corner cases most of the time.
[00:40:30]
So it's like, it's pretty close.
[00:40:32]
Yeah, I think so too.
[00:40:35]
I mean, yeah, there's still a bunch of things that aren't exactly perfect, but those go
[00:40:40]
deep down into the browser and the platform that we're building on, right?
[00:40:46]
Web API is in CSS.
[00:40:48]
And yeah, those will take a longer time to improve, I guess.
[00:40:54]
Is there anything on your radar that you are keen to explore next?
[00:40:59]
Or are you not thinking about that at this stage?
[00:41:02]
Well, one thing is I would like to, for Elm Tailwind modules, I would like to explore
[00:41:10]
a different way of generating the modules.
[00:41:13]
Essentially, what happens right now is that the Tailwind configuration is fed into Tailwind
[00:41:22]
CSS.
[00:41:23]
And Tailwind CSS will generate a huge CSS file.
[00:41:27]
And that CSS file is processed by Elm Tailwind modules.
[00:41:31]
And that means that this process of creating all of the different variants, this explosion,
[00:41:36]
this combinatorial explosion, that does still happen, but it's in the background, kind of.
[00:41:41]
There's no files generated with it.
[00:41:43]
But it still needs to happen.
[00:41:45]
And we should, or it should actually, or Elm Tailwind modules should just connect to Tailwind
[00:41:51]
CSS at a different level, before Tailwind CSS actually generates all the combinations
[00:41:58]
of the way that utilities can be built.
[00:42:01]
But that's kind of inside Tailwind CSS.
[00:42:04]
So it's a little harder to get to.
[00:42:06]
But I believe that we could do that.
[00:42:08]
And we would get a lot of things for free.
[00:42:11]
So this would mostly be for performance, I'm guessing.
[00:42:14]
But is that a, I'm curious, is that a problem?
[00:42:17]
Because how long does it take for Tailwind to run?
[00:42:20]
And is it a problem for people who have JavaScript projects, which don't use Elm Tailwind modules?
[00:42:26]
So for regular Tailwind, they have optimizations in place to not do all of that work.
[00:42:31]
But we can't use them in Tailwind, Elm Tailwind modules, because basically, these optimizations
[00:42:38]
rely on regex matching, and going into your code where we actually use the Tailwind configurations
[00:42:46]
and figuring out exactly what you need.
[00:42:47]
Use of that.
[00:42:48]
Okay, so usually, the regular Tailwind, it looks at your code and then generates what
[00:42:53]
is necessary.
[00:42:54]
Whereas your approach is we generate everything.
[00:43:00]
And then Elm's data code elimination will remove what is unnecessary.
[00:43:04]
Yes.
[00:43:05]
And we also in between have this abstraction step where all the combinations get compressed
[00:43:10]
down in just a smaller set of combinations.
[00:43:14]
And you can actually compose them using functions and values.
[00:43:17]
And that process takes like, on my machine, I think it's like 20 seconds.
[00:43:21]
So it can be pretty long.
[00:43:23]
And depending on what you do, that is fine.
[00:43:26]
So for example, if you have some Tailwind configuration, and you're just generating
[00:43:30]
it once, then well, 20 seconds isn't too bad.
[00:43:34]
But of course, if you're constantly tweaking your configuration, that will not be fun.
[00:43:39]
And also, we may be imprecise.
[00:43:42]
We don't we haven't tested every possible Tailwind configuration out there.
[00:43:46]
There may be bugs hidden in the code.
[00:43:49]
That's why it's still an alpha.
[00:43:51]
And I think, well, it's going to be hard to squash every possible bug out there.
[00:43:57]
I don't think that people will hit lots of them in practice.
[00:44:00]
But still, it would be a way more resilient kind of way of generating these Elm modules.
[00:44:09]
If they were generated from that part in Tailwind CSS that still knows about, like, these are
[00:44:15]
colors and they get combined with this kind of utility, instead of having to guess what
[00:44:23]
the combinations are afterwards.
[00:44:24]
Yeah, does Tailwind have a plugin system for this kind of thing?
[00:44:29]
I know it has a plugin system, but I don't know what those plugins can do and what they
[00:44:34]
can't do.
[00:44:35]
Yeah.
[00:44:36]
So basically, if you're, I'm not extremely familiar with Tailwind CSS internals.
[00:44:44]
They don't have a out of the box plugin system for something or that Elm Tailwind modules
[00:44:50]
could use their plugin system.
[00:44:53]
It's correct.
[00:44:54]
They have one, you can basically add things that generate more combinatorial stuff.
[00:44:59]
So let's say you wanted to, I don't know, there's a new web API, and suddenly you can
[00:45:04]
define the color of your cursor or something like that.
[00:45:08]
Maybe that even exists, who knows.
[00:45:10]
And then you could go in and add like a Tailwind plugin and say, okay, this Tailwind plugin
[00:45:15]
is some JavaScript function and it generates a CSS definition that says cursor color colon,
[00:45:25]
and then insert here every possible Tailwind configuration color from the theme.
[00:45:32]
And so hooking into that step before these combinations get executed, essentially, would
[00:45:39]
be nice for Elm Tailwind modules.
[00:45:41]
That should reduce the time, that should make it easy for abstracting out spacing to and
[00:45:47]
other things.
[00:45:48]
So yeah, that would be the hope.
[00:45:50]
That would be a next step, I think.
[00:45:52]
I actually wondered, like, if Tailwind adds a new feature, a new utility, do you need
[00:45:58]
to do anything in your project to make that work?
[00:46:02]
Or let's imagine we, Tailwind added that cursor color feature.
[00:46:07]
Would you need to do anything?
[00:46:10]
Luckily not, no.
[00:46:12]
I mean, the version 3 update was something bigger for Elm Tailwind modules to support,
[00:46:18]
but all of the minor updates so far seemed to go pretty smoothly.
[00:46:23]
Cool.
[00:46:24]
Yeah, so basically, there's no manual work involved with that.
[00:46:28]
And I can't, I mean, basically what happens with new Tailwind versions is when they add
[00:46:33]
new utilities, they essentially just change the Tailwind configuration.
[00:46:38]
And I need to, or Elm Tailwind modules needs to support many different kinds of Tailwind
[00:46:42]
configurations out of the box anyway, and combinations of additional plugins that people
[00:46:47]
may want to install.
[00:46:49]
And so yeah, that should work out of the box.
[00:46:52]
So Tailwind v3, one of the curveballs that it threw at your library, among other things,
[00:47:01]
was this way of this arbitrary syntax.
[00:47:05]
So like there is a way now in Tailwind of expressing an arbitrary color.
[00:47:10]
Like an example they give is, you know, if you have your, I guess your CI colors, your
[00:47:16]
corporate identity colors that you use for your color palette in your Tailwind config,
[00:47:24]
you might have a link to Twitter and LinkedIn and whatever.
[00:47:30]
But those aren't part of your design system and you don't want them to be.
[00:47:33]
You just want to say like, I want to drop out of our design system for a moment and
[00:47:38]
just use Twitter blue.
[00:47:40]
And I don't want to pollute my design system with that because I don't want people making
[00:47:44]
buy now button that's Twitter blue because it's not part of our design system.
[00:47:48]
So there's a syntax for doing arbitrary colors in Tailwind CSS.
[00:47:51]
You want to talk a little bit about the like design decisions behind this and maybe the,
[00:47:58]
you've got the Elm Tailwind modules base Elm package, which just gives a couple of color
[00:48:03]
helpers.
[00:48:04]
Yes.
[00:48:05]
So there's, I mean, there's a little bit of a debate around that, I guess, or initially,
[00:48:12]
because well, one response to that Tailwind feature at the beginning could have been,
[00:48:17]
well, why not use inline styles for this if you'd need it sometimes.
[00:48:23]
You could do the same thing with Elm CSS and like add some inline styles, but the thing
[00:48:28]
is once you do that, you're out of Tailwind CSS land.
[00:48:31]
And there's a couple of things that Tailwind CSS does.
[00:48:34]
So everything fits together nicely.
[00:48:36]
Like for example, it passes down opacity into like sub elements, essentially.
[00:48:44]
It handles that nicely.
[00:48:46]
There's basically it does a bunch of additional things sometimes around basic styles, which
[00:48:51]
you would expect would be basic, but turn out have some nice hooks here and there.
[00:48:57]
Another example would be like font size is something that is like you can locally change
[00:49:02]
that and it should work nicely with Tailwind CSS.
[00:49:07]
And it would be nice to hook into that or into Tailwind CSS in a way that doesn't bypass
[00:49:13]
it completely.
[00:49:14]
And so that is possible with this, with these helpers.
[00:49:18]
So you can, instead of just using one of the predefined theme things, you can use your
[00:49:24]
own color if you need to.
[00:49:27]
And there's going to be like arbitrary RBGA, I think it's called in the base library that
[00:49:33]
every generated code depends on.
[00:49:35]
You can use that.
[00:49:36]
So basically, I thought, well, if they decide to do that, let's do this as well.
[00:49:42]
You won't see this in the very beginning.
[00:49:44]
So if you're only depending on default Tailwind modules, you will not see that there is an
[00:49:49]
arbitrary way to do this or to add colors because you should instead just have your
[00:49:55]
config and add colors that you need into your config.
[00:49:59]
But if you really want to or need to go outside of that, there is a way to do that, which
[00:50:05]
doesn't bypass any Tailwind CSS generated things.
[00:50:08]
Right.
[00:50:09]
So it's, it kind of seems like a, you do want to a certain extent to be able to say, okay,
[00:50:16]
we have this design system, so I don't have, and as Elm developers, we really want to be
[00:50:21]
able to say, what are the guarantees I can depend on?
[00:50:23]
And so like design system, it's constraints.
[00:50:27]
You say like, what guarantees do I get from those constraints?
[00:50:30]
Are they like full guarantees or are they like partial guarantees?
[00:50:34]
And, and then, so this arbitrary RGB and arbitrary RGBA, these functions that are provided for
[00:50:42]
the color type in this generated code is an escape patch in a sense.
[00:50:48]
I mean, it's something that now exists in Tailwind.
[00:50:51]
So you could argue it's just following the Tailwind semantics, but it also is an escape
[00:50:55]
patch from the Tailwind design system.
[00:50:57]
But I hear there's a tool that helps you do static analysis to give you additional guarantees
[00:51:03]
around this type of thing.
[00:51:05]
So I think this is the perfect use case for Elm Review to just have this be, if you want
[00:51:11]
to, a forbidden function or forbidden in certain contexts.
[00:51:15]
Oh, that's an interesting idea.
[00:51:17]
Yeah, yeah.
[00:51:18]
But that would be something to turn on per project, for example.
[00:51:21]
So yeah, I haven't actually thought about that.
[00:51:24]
I mean, I guess to some extent, you could just have an Elm Review rule that checks that
[00:51:30]
any class that you're using is a Tailwind class, is an existing Tailwind class.
[00:51:37]
Because the original problem of your project is if you make a typo in a Tailwind class,
[00:51:42]
then it's not going to take effect.
[00:51:45]
And you want to know about that.
[00:51:47]
So that's why we go with the type safe route of creating functions and creating variables
[00:51:51]
so that the compiler helps us.
[00:51:54]
But you could do it using Elm Review.
[00:51:56]
But then you do need restrictions, like you only want to report things that you know are
[00:52:03]
used as classes and not are just arbitrary strings, because we have the same syntax for
[00:52:09]
defining both, right?
[00:52:10]
Just string literals.
[00:52:12]
So you do need to know in which context you are.
[00:52:14]
Yeah, absolutely.
[00:52:16]
And also you re-inherit these problems that the original Tailwind CSS had as well, which
[00:52:21]
you can't break up the literal in the middle.
[00:52:25]
If you have bg-blue100, and you want to combine, instead, like do a string concat of bg- and
[00:52:32]
then color, and color is a variable.
[00:52:36]
And that's like a string passed in or something like that.
[00:52:38]
That won't work.
[00:52:39]
But yeah, you could do an Elm Review rule like that.
[00:52:44]
Yeah, and you lose the ability to get dead code elimination through the Elm compiler.
[00:52:50]
So Tailwind does have something to that effect.
[00:52:53]
I don't know how well it works in practice, if it works as well as the Elm compiler or
[00:53:00]
better or worse.
[00:53:01]
I don't know.
[00:53:02]
But yeah, then you would have to rely again on Tailwind's way of doing things and you
[00:53:07]
might get false.
[00:53:09]
It might not delete as much as you want.
[00:53:12]
But definitely an interesting approach as well, but different.
[00:53:15]
Very different.
[00:53:17]
It does make me think, so you're talking about the vanilla Tailwind CSS approach to using
[00:53:25]
Elm CSS classes that point to Tailwind CSS utilities.
[00:53:29]
And it makes me think, is there a reason for some users not to switch?
[00:53:36]
Or is it mostly at this point, it's a lot of work and I haven't done the upgrade yet?
[00:53:41]
For example, elmradio.com, slightly embarrassingly, I mean, it's three years old, so it predates
[00:53:52]
Elm Tailwind modules, but it uses vanilla Tailwind CSS utility classes.
[00:53:57]
But you kind of don't want to break anything in its CSS, so that's scary.
[00:54:03]
So it's a big upgrade job.
[00:54:05]
But I do have the site html2elm.com, which as we talked about, lets you convert Tailwind
[00:54:14]
classes to Elm Tailwind modules syntax.
[00:54:19]
And there's also the companion Elm Review rule that lets you take a debug.todo string
[00:54:30]
where the string has HTML and it will convert that string to HTML.
[00:54:33]
And it even uses the import context, we talked about this in the previous Elm Tailwind modules
[00:54:38]
episode.
[00:54:39]
But that Elm Review rule provides a fix that converts an HTML string to an Elm Tailwind
[00:54:46]
modules HTML snippet.
[00:54:49]
And now it's striking me that it would actually be really handy to just have an Elm Review
[00:54:54]
version of that rule for class attributes to go in and change those class attributes,
[00:55:04]
not the entire HTML snippet.
[00:55:06]
And I think I could do that.
[00:55:08]
And that would like, for example, for me resisting going in and upgrading from vanilla Tailwind
[00:55:14]
to Elm Tailwind modules in the Elm Radio site, that would...
[00:55:19]
This is like the tooling author's thought process, right?
[00:55:22]
I wouldn't want to manually do it, but what if I built a tool that did it for me?
[00:55:28]
I mean, luckily, this doesn't take extremely long anymore now that we have Elm Review,
[00:55:34]
like going through all of the Elm code or building like a parser or something that would
[00:55:38]
have been extremely hard.
[00:55:40]
But yes, it might actually save time in total.
[00:55:45]
Exactly.
[00:55:46]
That's the goal with tooling authors is that you're like, eventually it's going to pay
[00:55:51]
off.
[00:55:52]
And in my life, I'll have spent less time building tools than I would have manually
[00:55:55]
building on these things.
[00:55:56]
I mean, I don't think it's a lie that even we believe in.
[00:55:59]
It's just like the way that I like to myself is like, oh, well, at least it's going to
[00:56:06]
be useful to other people.
[00:56:08]
Yeah.
[00:56:09]
Right.
[00:56:10]
Yes.
[00:56:11]
Yeah.
[00:56:12]
Because I can't just lie and say, well, this is going to save me some time.
[00:56:16]
Like, no.
[00:56:18]
It's more fun anyway.
[00:56:19]
So yeah.
[00:56:21]
It's the arbitrary condiment passing utility from XKCD.
[00:56:26]
But yeah, it sounds good.
[00:56:29]
Sounds like exactly the thing we described before.
[00:56:33]
But except instead of checking, you just transform it into the Elm Table modules version.
[00:56:41]
Yeah.
[00:56:43]
Is there like a kind of there definitely is a fix all in Elm Review, right?
[00:56:49]
Yeah.
[00:56:50]
Oh, wow.
[00:56:51]
That would be quite amazing if you managed to just fix all and you turn any vanilla Tailwind
[00:57:00]
CSS Elm project into a Elm Table modules project.
[00:57:04]
That would be awesome, right?
[00:57:06]
Pretty amazing.
[00:57:07]
The really cool thing, like, so, you know, because Elm Review gives you access to all
[00:57:12]
these things, you can like look at imports and stuff, right?
[00:57:15]
So the rule I have for the string to HTML snippet one looks at your import context and
[00:57:23]
it uses all of your imports and exposed values.
[00:57:26]
So if you like do import HTML styled, is it?
[00:57:31]
Yeah.
[00:57:32]
Import HTML styled exposing dot dot, then it will use just div and span instead of HTML
[00:57:39]
dot style dot div.
[00:57:40]
So if you do import HTML dot styled as HTML, it will do HTML dot div, for example.
[00:57:48]
Yeah, it's super powerful.
[00:57:50]
Yeah.
[00:57:51]
I was going to ask you, Philip, if you had tips on how to switch from Elm HTML to Elm
[00:57:56]
CSS because to use your project, people need to switch to Elm CSS first.
[00:58:02]
But now I feel like the answer is just going to be, well, we can rise an Elm Review rule
[00:58:06]
for that.
[00:58:08]
So I mean, that would be amazing, right?
[00:58:12]
I mean, also like Elm CSS is basically a superset of Elm HTML anyway.
[00:58:18]
Yeah.
[00:58:19]
So I don't think it's going to be very hard anyway.
[00:58:22]
Just change the imports and that's mostly going to be it, I'm guessing.
[00:58:26]
Yeah.
[00:58:27]
I mean, yeah, I haven't done like an upgrade in that kind recently.
[00:58:32]
But yeah, as far as I know, it should be straightforward.
[00:58:36]
And it seemed to have worked really well for Elm Radio.
[00:58:39]
The other cool thing with like building these kind of Elm Review code mod tools is you can
[00:58:47]
have a folder in the repo with a review configuration.
[00:58:52]
So like, let's say it's Elm HTML to Elm CSS.
[00:58:56]
You can have a configuration that just is an Elm Review config folder that only has
[00:59:02]
that one rule.
[00:59:04]
And then you can run Elm Review with dash dash template and point it to that repo.
[00:59:10]
And you don't need to like, temporarily set up the rule in your config folder.
[00:59:14]
So you can give somebody a single command to run, and it'll just run the code mod.
[00:59:18]
So that's pretty cool, too.
[00:59:19]
Yeah, actually, it's dash dash config dash dash template is if you want to run a configuration
[00:59:24]
that is hosted on GitHub somewhere.
[00:59:26]
So you actually don't even need to have it on your machine, you can do it.
[00:59:31]
If the rule exists somewhere in GitHub, then that will also work.
[00:59:34]
Wait, but you do that.
[00:59:36]
Yeah, but I was talking about if you host it on GitHub.
[00:59:38]
So if you have on GitHub, just a folder that has your code mod review rule, then you can
[00:59:44]
give them a single command, they don't need to download anything or set up a temporary
[00:59:49]
configure anything.
[00:59:50]
Yeah, absolutely.
[00:59:51]
At this point, Elm Review, have you have you thought about a rename of Elm Review?
[00:59:56]
Because like code mod, that sounds, sounds like more than review.
[01:00:01]
And it's like Elm Review is underselling it.
[01:00:04]
I mean, to some extent, this is like a topic for us not really to tell when they're anymore.
[01:00:13]
But I mean, to some extent, like, I don't even know if a code mod is a term that is
[01:00:18]
used elsewhere than in the JavaScript community.
[01:00:21]
Maybe it is.
[01:00:22]
That's where I encountered it, at least.
[01:00:25]
But even just like linters, they do the same thing as Elm Review, they just usually do
[01:00:30]
it worse.
[01:00:31]
And even just a linter is a very bad name.
[01:00:35]
Yeah, I guess linters just have gotten meaning, because they existed and didn't really, I
[01:00:43]
personally didn't know what that would mean before.
[01:00:46]
Yeah, well, yeah, well, actually, lint are those, those tiny pieces of fabric that you
[01:00:51]
find in your clothes.
[01:00:53]
So linting is the process of accumulating those, not of cleaning them.
[01:00:59]
So linter is technically something that adds garbage to your code.
[01:01:04]
Yeah, I guess there are some people who feel like that.
[01:01:09]
Yeah, yeah.
[01:01:10]
Well, if you had all those disabled comments, then yes, I agree.
[01:01:16]
But so only for this reason, for this reason alone, I'm already pretty happy I didn't call
[01:01:21]
it Elm Lint.
[01:01:22]
Actually, that I renamed it.
[01:01:25]
But yeah.
[01:01:26]
So yeah, that's...
[01:01:28]
That's a side topic.
[01:01:31]
Sorry.
[01:01:32]
Always happy to talk about Elm Review.
[01:01:36]
It is a really good pairing.
[01:01:37]
And it could even be cool to, well, maybe it's overboard, but the Elm Tailwind modules
[01:01:44]
base package, I was thinking could even expose an Elm Review rule that helps you avoid the
[01:01:50]
arbitrary RGB.
[01:01:51]
Although at that point, like, there are packages that have forbidden functions and things like
[01:01:56]
that, so it's probably better to use a standard tool for that.
[01:01:59]
So are there any tips we should give people who, let's say somebody is upgrading from
[01:02:05]
the previous release of Elm Tailwind modules to the alpha?
[01:02:10]
First of all, how can they help you through the alpha process?
[01:02:15]
And secondly, what does the upgrade process look like for them?
[01:02:19]
So the upgrade process is upgrade your npm package, and you can do that with npm i dash
[01:02:29]
dash save Elm Tailwind modules at alpha.
[01:02:33]
So no need to remember the version or anything.
[01:02:36]
Once you do that, rerun it to get like all the new Tailwind modules.
[01:02:39]
And you'll basically have to replace bg underscore blue, etc. with bg color.
[01:02:48]
And then another import of the theme module, which is now new, and whatever color you were
[01:02:53]
using from that theme module.
[01:02:55]
I'm guessing you will get compiler errors for all the things that you should do.
[01:02:59]
Absolutely.
[01:03:00]
Nice.
[01:03:01]
And I mean, yeah, that's that's the power of it, right?
[01:03:04]
You can you can change the way it works, and you'll get compiler errors, and you just fix
[01:03:09]
them everywhere.
[01:03:10]
And it should definitely just work.
[01:03:11]
Remember to add your global styles to your style sheet.
[01:03:15]
I've had some people now hit with a new Tailwind.
[01:03:20]
The way the new Tailwind version works, they've had issues with suddenly it working less well
[01:03:29]
with the global style.
[01:03:31]
So there's like one global styles thing that is basically kind of a style reset that Tailwind
[01:03:37]
needs to work.
[01:03:38]
But apparently it worked okay without using this.
[01:03:42]
Previously, it doesn't do that as well anymore.
[01:03:45]
So it's not intended to be used that way.
[01:03:47]
So just just include it.
[01:03:48]
Yeah, that might be a feature, not a bug.
[01:03:51]
Yeah, it definitely was an unintended feature.
[01:03:56]
There's no way I mean, we should have an Elm review rule for that.
[01:04:00]
Right.
[01:04:01]
But yeah, do that.
[01:04:03]
And then just try out the alpha.
[01:04:05]
It should actually be very straightforward.
[01:04:07]
But if you do hit some issues, like contacting me, whatever way feels comfortable for you,
[01:04:13]
DM me on Slack, or write an issue up on the Elm Tailwind modules or Elm default Tailwind
[01:04:19]
modules, GitHub, Issue Tracker, and then yeah, that's the perfect way.
[01:04:24]
Eventually, I'll just announce the at least the alpha or even the finished, finished,
[01:04:31]
I guess, while the final new version on the Elm discourse.
[01:04:35]
Amazing.
[01:04:36]
And for people looking to try it out, like, do you have any guidance on you have this
[01:04:42]
Elm default Tailwind modules package, which as we talked about, it's an Elm package that
[01:04:47]
is basically a packaged up version of the default Tailwind config with the generated
[01:04:52]
code from Elm Tailwind modules.
[01:04:54]
So you don't need to install an npm package to use that one.
[01:04:57]
It's like much easier to get set up if you want to try it out.
[01:05:01]
Do you think that people should eventually outgrow that?
[01:05:05]
Or is it okay if certain people don't outgrow that, for example,
[01:05:11]
I mean, it's up to you.
[01:05:18]
I personally think there's like, I will have a lot of personal projects that I will just
[01:05:23]
do with Elm default Tailwind modules, because I don't feel like creating my own color scheme.
[01:05:32]
And basically, that's what you want to do with your custom config.
[01:05:36]
There's some other things like if you really want to have something very production ready,
[01:05:41]
you can add your custom plugins to Tailwind to for example, what is it auto prefixes one
[01:05:49]
of them, but I think that that is even auto installed with default Tailwind modules.
[01:05:54]
But plugins like that, which make it work on more devices, let's say, that add polyfills
[01:06:00]
for older CSS classes for newer CSS classes that didn't exist previously.
[01:06:08]
So these kinds of things, if you really want to have something polished, then graduate.
[01:06:12]
But honestly, I really like the flow personally of using just default Tailwind modules.
[01:06:19]
Yeah, I'm a big fan of being able to I use Tailwindui.com a lot.
[01:06:26]
It's a paid library of components and styles, but it's like so so worth it.
[01:06:35]
For me, it has been and if you use the default configuration, the things look like they look
[01:06:41]
on the site, and you copy paste the styles and they just work, you don't have to tweak
[01:06:47]
it to use your naming convention for your color, style system and stuff.
[01:06:53]
So I kind of like that, like, maybe I'll change indigo or whatever to whatever color I'm using.
[01:06:59]
But other than that, like, I can just drop things in.
[01:07:02]
So there's, it's kind of like the debate of like, how much customization do you do on
[01:07:06]
your system versus using the default keyboard shortcuts and keyboard layout so you can go
[01:07:12]
to someone else's machine and work with them.
[01:07:15]
I was going to say like, you probably don't need to upgrade from default Tailwind modules.
[01:07:22]
If you don't have a corporate identity.
[01:07:25]
So now you're saying that the Elm reader doesn't have a corporate identity.
[01:07:28]
Yes, I'm sorry.
[01:07:30]
I guess we do have an identity.
[01:07:33]
It's just not a corporation.
[01:07:35]
Makes sense, I guess.
[01:07:40]
I mean, you can you can build your identity on top of tailwind colors.
[01:07:44]
We've learned that version three has like a bazillion more colors than previously.
[01:07:48]
Exactly.
[01:07:50]
Or is it simpler to just build a corporation?
[01:07:52]
I mean, maybe at this point, you know.
[01:07:57]
Well, amazing stuff, Philip.
[01:08:00]
And thanks again for all your work on this awesome project.
[01:08:03]
And thanks for coming on the show.
[01:08:05]
Thank you for helping with it as well.
[01:08:08]
And thank you for having me.
[01:08:09]
It's a pleasure.
[01:08:10]
And Jeroen, until next time.
[01:08:13]
Until next time.