javascriptreactjsclojurescripttailwind-elements

Tailwind-Elements React integration into ClojureScript


I am currently trying to use TailWindElements-React in Clojure Script. In JS an example would look like this:

import React, { useState } from "react";
import { TECollapse, TERipple } from "tw-elements-react";

export default function App(): JSX.Element {
  const [show, setShow] = useState(false);

  const toggleShow = () => setShow(!show);

  return (
    <>
      <TERipple rippleColor="light">
        <a
          className="inline-block rounded bg-primary mr-2 px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
          role="button"
          onClick={toggleShow}
        >
          Link
        </a>
      </TERipple>
      <TERipple rippleColor="light">
        <button
          type="button"
          className="inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
          onClick={toggleShow}
        >
          Button
        </button>
      </TERipple>

      <TECollapse show={show}>
        <div className="block rounded-lg bg-white p-6 shadow-lg dark:bg-neutral-700 dark:text-neutral-50">
          Some placeholder content for the collapse component. This panel is
          hidden by default but revealed when the user activates the relevant
          trigger.
        </div>
      </TECollapse>
    </>
  );
}

Now if I want to use these classes I write

(:require ["tw-elements-react" :refer (TECollapse TERipple)])

and then

[:> TERipple
  [:div ... ]
]

Doing so compiles without a problem but in the browser console I get

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

and

Uncaught TypeError: resolveDispatcher() is null

If I do not wrap the div with TERipple the code works fine.

Is anyone of you able to make this work? I am using shadow-cljs version 2.28.6.

Edit: I decontextualized my problem and tried to build a minimal working example. I used the leiningen template clojure lein new re-frame test +10x and then upgraded the shadow-cljs version to 2.28.6. Then I installed TWE-React and TW. The only thing I altered from the template was that I added a button and wrapped it within the TERipple component. Here is my views.cljs:

(ns test.views
  (:require
   [re-frame.core :as re-frame]
   [test.subs :as subs]
   ["tw-elements-react" :refer (TECollapse TERipple)]))

(defn main-panel []
  (let [name (re-frame/subscribe [::subs/name])]
    [:div
     [:h1
      "Hello from " @name]
     [:> TERipple
      [:button.bg-red "Press me"]]]))

The error remains the same.


Solution

    1. You might have mismatching versions of React and the renderer (such as React DOM)

    This is the problem here. tw-elements-react depends on version "^18.2.0" of react+react-dom, but the default generated package depends on react+react-dom version "17.0.2". This leads npm to install and use both. Thus you end up with the warnings above.

    I verified this by doing a shadow-cljs build report and finding that there were indeed two separate react+react-dom versions in the build.

    Running npm install react@18.3.1 react-dom@18.3.1 fixes the TERipple issue.