tcoopman

tcoopman

Mix tailwind - 4.0.0-beta.1 support

I thought I’d try to install tailwind 4.0.0-beta.1 (Release v4.0.0-beta.1 · tailwindlabs/tailwindcss · GitHub) that was released today and see how far I got.
Tailwind 4 has some big changes so I don’t expect this to work out-of-the box without any work, but I thought I’d try and see how far I get.

so, I changed the config to

config :tailwind,
  version: "4.0.0-beta.1",

and did a mix tailwind.install, changed the css file according to Installing Tailwind CSS with Vite - Tailwind CSS
and everything seems to run fine, but I don’t get my classes detected.

If I run _build/tailwind-linux-x64 -i assets/css/app.css -o test.css directly, the css file is correct, so it must be something with the arguments that’s different (I think).

Will play a little bit more around and see if I can get it working completely.

Most Liked

frankdugan3

frankdugan3

I’ve been using the alpha for a few months, and I prefer using the new configuration in the app.css file and deleting the js config. I did not change the config.exs, so it still does the cd into the assets directory.

config :tailwind,
  version: "4.0.0-beta.1",
  my_app: [
    args: ~w(
      --input=css/app.css
      --output=../priv/static/assets/app.css
    ),
    cd: Path.expand("../assets", __DIR__)
  ]
/* if you want dark mode via class */
/* default is to use prefers-color-scheme */
@variant dark (&:where(.dark, .dark *));

@variant phx-click-loading (.phx-click-loading&, .phx-click-loading &);
@variant phx-submit-loading (.phx-submit-loading&, .phx-submit-loading &);
@variant phx-change-loading (.phx-change-loading&, .phx-change-loading &);

@plugin "./heroicons.tailwind.plugin.js";

@source "../js/**/*.js";
@source "../../lib/my_app_web.ex";
@source "../../lib/my_app_web/**/*.*ex";

@import "tailwindcss";

And create a heroicons.tailwind.plugin.js if you use heroicons:

const fs = require("fs");
const path = require("path");

module.exports = function ({ matchComponents, theme }) {
  let iconsDir = path.join(process.cwd(), "../deps/heroicons/optimized");
  let values = {};
  let icons = [
    ["", "/24/outline"],
    ["-solid", "/24/solid"],
    ["-mini", "/20/solid"],
    ["-micro", "/16/solid"],
  ];
  icons.forEach(([suffix, dir]) => {
    fs.readdirSync(path.join(iconsDir, dir)).forEach((file) => {
      let name = path.basename(file, ".svg") + suffix;
      values[name] = { name, fullPath: path.join(iconsDir, dir, file) };
    });
  });
  matchComponents(
    {
      hero: ({ name, fullPath }) => {
        let content = fs
          .readFileSync(fullPath)
          .toString()
          .replace(/\r?\n|\r/g, "");
        let size = theme("spacing.6");
        if (name.endsWith("-mini")) {
          size = theme("spacing.5");
        } else if (name.endsWith("-micro")) {
          size = theme("spacing.4");
        }
        return {
          [`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`,
          "-webkit-mask": `var(--hero-${name})`,
          mask: `var(--hero-${name})`,
          "mask-repeat": "no-repeat",
          "background-color": "currentColor",
          "vertical-align": "middle",
          display: "inline-block",
          width: size,
          height: size,
        };
      },
    },
    { values },
  );
};

I think v4 is a fantastic advancement. It uses native CSS layers, which I find solves all problems I have with using selectors for the base style of components, while still allowing the use of utility classes for overrides.

26
Post #5
tcoopman

tcoopman

Got it working:

This is a working config:

  version: "4.0.0-beta.1",
  default: [
    args: ~w(
      --input=assets/css/app.css
      --output=./priv/static/assets/app.css
    ),
    cd: Path.expand("../", __DIR__)
  ]

diff:

As you can see, the difference is to not cd into assets. Tailwind 4 does source detection differently, but you can still configure it: Installing Tailwind CSS with Vite - Tailwind CSS, so the old configuration can probably be kept with correct source detection, but I didn’t bother with that.

11
Post #2
frankdugan3

frankdugan3

As a follow-up, here’s a gist with a simple & robust implementation of dark mode toggling. It contains the config to add to app.css, and button and JS components to add to your core_components.ex file.

Where Next?

Popular in Discussions Top

Rustixir
Hi everyone, im working on find best language/framework/system for high concurrency, high performance and stable performance after wor...
New
cvkmohan
The upcoming Phoenix 1.6 release looks very interesting. Became a habit to watch the commits - and - what they are bringing in. phx.gen...
New
fireproofsocks
This is more of a general question, but I’m wondering how other people in the community think about the pattern matching in function sign...
New
AstonJ
If a newbie asked you about Phoenix Contexts, how would you explain the basics to them? Feel free to be as concise or in-depth as you li...
New
Crowdhailer
I’ve been hearing much about the new formatter and it’s something I have been keen to try. I find examples buy far the most illuminating...
248 19204 150
New
Ankhers
Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in...
New
sergio
There’s a new TIOBE index report that came out that shows Elixir is still not in the top 50 used languages. It also goes on to call Elix...
New
joeerl
I’m playing with Elixir - It’s fun. I think @rvirding does give Elixir courses these days. Re: files and database - when I given Erlang ...
New
griffinbyatt
Sobelow Sobelow is a security-focused static analysis tool for the Phoenix framework. For security researchers, it is a useful tool for g...
New
paulanthonywilson
I like Umbrella projects and pretty much always use them for personal Elixir stuff, especially Nerves things. But I don’t think this is ...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement