Rails 7 + ImportMaps/whatever + TailwindCSS + JS = Boggled
Asked Answered
R

3

6

First, I'm much more of a Rails back end person. The JS world today scares me. I know this is a super basic question, but I've racked my brain for a solid couple days trying to figure, this out. I don't know why I can't put a CDN link somewhere in my HTML and get all the JS I need. Those were the good ol' days...

Anyway, I have a nearly fresh Rails 7 app that uses import-maps (do they all?) and I'm trying to get a dropdown "component" from https://tailwindui.com/preview (the first navbar from that page) working. It starts popped open, no hover effects, and is unable to close. My goal is to use more of those components, but all the docs I read seem to leave me thinking there's a missing piece I'm not understanding.

Gemfile contains gem "tailwindcss-rails", "~> 2.0" # github: "rails/tailwindcss-rails"

app/assets/stylesheets/application.tailwind.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

app/assets/javascript/application.js

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails

// what else needs to go here???

config/tailwind.config.js

// const defaultTheme = require('tailwindcss/defaultTheme')

// module.exports = {
//   content: [
//     './app/helpers/**/*.rb',
//     './app/javascript/**/*.js',
//     './app/views/**/*'
//   ],
//   theme: {
//     extend: {
//       fontFamily: {
//         sans: ['Inter var', ...defaultTheme.fontFamily.sans],
//       },
//     },
//   },
//   plugins: [
//     require('@tailwindcss/forms'),
//     require('@tailwindcss/aspect-ratio'),
//     require('@tailwindcss/typography'),
//   ]
// }

What else do I need to put where to get this working? Thank you kindly for filling in the missing pieces in my brain.

Residual answered 24/2, 2022 at 15:16 Comment(1)
In our app, which uses web packer still, we have this in application.js: import "stylesheets/application.scss" and our application.scss includes, among other things, the contents of your application.tailwind.cssThrottle
I
1

There is no JavaScript in their HTML code. On TailwindUI homepage, they explain:

Accessible, interactive examples for React and Vue powered by Headless UI, plus vanilla HTML if you’d rather write any necessary JS yourself.

So I guess in this case you have to write the necessary JS yourself.

Interspace answered 28/2, 2022 at 9:43 Comment(0)
C
1

I know it's been a while since you've asked this question, yet I've been fighting this thing recently and I'd like to talk about what I've found, in case anybody's wondering.

So, Tailwind UI provides components in 3 variants: HTML, React, and Vue. If you pick HTML, you'll have to figure out how to write your own JavaScript. this answer mentions that, but I'll elaborate on that point, though.

Aside from mentioning "do your own JavaScript" on their website, they also give us instructions how exactly we should style our components when we add JavaScript:

          <!--
            Dropdown menu, show/hide based on menu state.

            Entering: "transition ease-out duration-100"
              From: "transform opacity-0 scale-95"
              To: "transform opacity-100 scale-100"
            Leaving: "transition ease-in duration-75"
              From: "transform opacity-100 scale-100"
              To: "transform opacity-0 scale-95"
          -->

Yet, that doesn't really tell us that we must code it ourselves. Surely, there's something we're missing, right? Turns out, not really.

Basically, the "dynamic" aspect of the layout is implemented via Headless UI, a set of components developed & maintained by the same people. It only has three public packages: @headlessui/vue, @headlessui/react and @headlessui/tailwindcss.

I ran npm i @headlessui/tailwindcss and added @headlessui/tailwindcss to the plugins, but it didn't really do much. If you inspect the source code for the package, you'll find a pretty tiny index.js which only adds some utility classes. So that didn't help and I had to scratch it.

So far it seems the most viable option is to grab a React or Vue version of the template and integrate those into your pipeline. Otherwise you'll have to write a bunch of JS to basically reimplement headless UI yourself.

I'm still looking for an importmap-based solution to integrate Vue, while webpack should be pretty much straightfoward.

Cathedral answered 23/1, 2023 at 22:40 Comment(0)
C
0

I agree with you, there is a missing piece. I've been working through this while attempting to install the daisyUI tailwindcss plugin in a new Rails 7.1 app created with -css=tailwind. It's looking like, to use these tailwind plugins (tailwindui and daisyUI), the default javascript use of import-maps falls short. I may be missing something as well, but these UI frameworks want to install through a JS package manager (node, yarn, bun). Once I switched over to bun, I've had a much easier time getting the plugin working.

That required:

  • installing bun locally (if you don't, rails tries to fallback to yarn)
  • run rails new myapp --javascript=bun --css=tailwind

This answer gives more details as well, with the key detail being:

To use any other tailwind plugins you must run a full node.js version of tailwind

Seems like the missing piece is that the standalone tailwind cli that is relied on by --css=tailwind (with javascript handled by importmaps) and the tailwindcss-rails gem are no longer viable solutions as soon as you want to use a tailwind plugin.

Maybe that's changed or least points us in the direction of investigating how to solve the plugin problem with the tailwind cli as it's not really a Rails issue at the core.

Concordance answered 12/1 at 6:39 Comment(1)
Hm, I did get tailwind plugins working with no node.js, just Rails 7 importmaps -- I show a working example here: https://mcmap.net/q/1916088/-javascript-not-working-when-using-tailwind-elements-with-ruby-on-railsHandsaw

© 2022 - 2024 — McMap. All rights reserved.