how to integrate tailwindui JS in rails app
Asked Answered
P

3

7

i'm on rails 7 with esbuild. I'm using tailwindUI. It works properly when using only css components. When a component uses JS it does not work anymore. For example the dropdown menu is open by default and i can't close it. I added require('@tailwindcss/ui') in tailwind.config.js

Rails 7.0.0.alpha2 ruby 3.0.2p107 "@tailwindcss/ui": "^0.7.2"

Any idea?

Plasm answered 21/11, 2021 at 0:48 Comment(0)
T
3

I'm not sure if I fully understand your question, but I've experienced the same issue. The way I solved it was by using stimulus js tailwind components to add Javascript to the elements.

I ended up having to add a "hidden" tag to the class for each element to ensure that it wouldn't flash on screen when the page loaded due to the lag time between the HTML and JS rendering.

You can find them here: https://github.com/excid3/tailwindcss-stimulus-components

Here is an example of the dropdown code. If you've got stimulus installed you can do the following:

yarn add tailwindcss-stimulus-components

or

npm install tailwindcss-stimulus-components

then simply add the data-controller, data-action and data-target to the elements you need:

<div class="inline-block text-sm px-4 py-2 leading-none rounded no-underline text-gray hover:text-gray-900 hover:bg-white mt-4 lg:mt-0">
  <div class="relative" data-controller="dropdown">
    <div data-action="click->dropdown#toggle click@window->dropdown#hide" role="button" data-dropdown-target="button" tabindex="0" class="inline-block select-none">
      <span class="appearance-none flex items-center inline-block text-gray-700">
        <% if current_user %>
          <%= image_tag avatar_url_for(current_user), class: "rounded-full h-8 w-8 align-middle" %>
        <% end %>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="h-4 w-4"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path></svg>
      </span>
    </div>
    <div data-dropdown-target="menu" class="absolute right-0 mt-2 hidden">
      <div class="bg-white shadow rounded border overflow-hidden">
          <%= link_to 'Profile',  edit_user_registration_path, data: {action: "click->dropdown#toggle"}, class: 'no-underline block pl-8 py-3 text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %>
          <%= link_to 'Password', password_path, data: {action: "click->dropdown#toggle"}, class: 'no-underline block px-8 py-3 text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %>
          <%= link_to 'Accounts', user_connected_accounts_path, data: {action: "click->dropdown#toggle"}, class: 'no-underline block px-8 py-3 text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %>
          <%= link_to 'Billing',  subscription_path, data: {action: "click->dropdown#toggle"}, class: 'no-underline block px-8 py-3 text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %>
          <%= link_to 'Sign Out', destroy_user_session_path, method: :delete, data: {action: "click->dropdown#toggle"}, class: 'no-underline block px-8 py-3 border-t text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %>
      </div>
    </div>
  </div>
</div>
Tearle answered 25/11, 2021 at 4:5 Comment(0)
M
3

I got Tailwind UI components that require JavaScript working with Rails 7 on esbuild by adding alpine.js to my app. https://alpinejs.dev/start-here

Alpine.js can be used for animating dropdowns, toggles, navbars, etc... and the TailwindUI documentation uses it in some example code.

you can either use it via the CDN or install as a package.

if you use it as a CDN then just put the current version number in the URL and add the script tag above your code.

<script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>
  <div x-data="{ open: false }">
    <button type="button" @click="open = ! open" class="inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
      Button text
    </button>
  <div x-show="open" @click.outside="open = false">Contents...</div>
</div>

I opted to install the npm packages alpinejs and alpine-turbo-drive-adapter so that I didn't have to add the script tag all over my views. In app/javascript/controllers/applications.js I added the import statements.

import { Application } from "@hotwired/stimulus"
import Alpine from 'alpinejs'
import 'alpine-turbo-drive-adapter'

const application = Application.start()

// Configure Stimulus development experience
application.debug = false

window.Stimulus   = application
window.Alpine = Alpine

window.Alpine = Alpine  
Alpine.start()

export { application }

another thing to note is that you can't just drop the TailwindUI components that require JavaScript into your code like with Bootstrap. You have to checkout the comments in the TailwindUI code and configure Apline.js to do what they recommend.

for example, if you check out the "simple toggle" the comments say what to change to make the toggle enabled/disabled https://tailwindui.com/components/application-ui/forms/toggles

<!-- This example requires Tailwind CSS v2.0+ -->
<!-- Enabled: "bg-indigo-600", Not Enabled: "bg-gray-200" -->
<button type="button" class="bg-gray-200 relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" role="switch" aria-checked="false">
  <span class="sr-only">Use setting</span>
  <!-- Enabled: "translate-x-5", Not Enabled: "translate-x-0" -->
  <span aria-hidden="true" class="translate-x-0 pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200"></span>
</button>

if you checkout the TailwindUI documentation https://tailwindui.com/documentation#using-html-and-your-own-js they give an example of how to use alpine.js to make the toggle functionality work. Essentially you just have to toggle the x-data attribute isOn from true to false so that menus, dropdown, etc... open and close.

  <span
    x-data="{ isOn: false }"
    @click="isOn = !isOn"
    :aria-checked="isOn"
    :class="{'bg-indigo-600': isOn, 'bg-gray-200': !isOn }"
    class="bg-gray-200 relative inline-block flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:shadow-outline"
    role="checkbox"
    tabindex="0"
  >
    <span
      aria-hidden="true"
      :class="{'translate-x-5': isOn, 'translate-x-0': !isOn }"
      class="translate-x-0 inline-block h-5 w-5 rounded-full bg-white shadow transform transition ease-in-out duration-200"
    ></span>
  </span>
Muoimuon answered 31/12, 2021 at 16:40 Comment(1)
So every single person who pays Tailwind UI has to custom implement their own JS code (via AlpineJS / Hyperscript / Stimulus JS) to get TailwindUI to play ball?Lew
P
0

thanks @Marco the answer was in the doc. When you use html you'll needs to write your custom JS if you want to make it work

Plasm answered 7/1, 2022 at 10:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.