clojurescript

meya wudafu 2024-11-14T12:13:11.564959Z

Hello everyone, Still playing with re-frame/reagent and MaterialUI, need help again πŸ™‚ Trying to replicated, more or less, what is here: https://mui.com/material-ui/react-breadcrumbs/#customization

(ns myapp.breadcrumb
  (:require ["@mui/material/Breadcrumbs" :default Breadcrumbs]
            [reagent.core :as r]
            ["@mui/material/Chip" :default Chip]
            ["@mui/material/styles" :refer [styled]]))

(def styled-breadcrumb
  (styled Chip
          (fn [{:keys [theme]}] ;; <- not used for simplification
            {:background-color "#FEEADB"})))

(defn breadcrumb-component []
  [:div {:role "presentation"}
   [r/as-element
    [Breadcrumbs {:aria-label "breadcrumb"}
     [styled-breadcrumb {:component "a"
                         :href "#"
                         :label "Home2"}]
     [styled-breadcrumb {:component "a"
                         :href "#"
                         :label "Catalog"}]
     [styled-breadcrumb {:label "Accessories"}]]]])
What I see on console is:
Error: Assert failed: Invalid Hiccup form: [#js {"$$typeof" #object[Symbol(react.forward_ref)], :render #object[Function], :propTypes #js {:children #object[bound checkType], :classes #object[bound checkType], :className #object[bound checkType], :component #object[bound checkType], :expandText #object[bound checkType], :itemsAfterCollapse #object[validator], :itemsBeforeCollapse #object[validator], :maxItems #object[validator], :separator #object[bound checkType], :slotProps #object[bound checkType], :slots #object[bound checkType], :sx #object[bound checkType]}} {:aria-label "breadcrumb"} [inputOptions {:component "a", :href "#", :label "Home2"}] [inputOptions {:component "a", :href "#", :label "Catalog"}] [inputOptions {:label "Accessories"}]]
 (in reagent.core.as_element)
(valid-tag? tag)
Trying also not wrap r/as-element

p-himik 2024-11-14T12:28:59.815609Z

styled returns a new React component. But you need it to be compatible with Reagent. Just wrap it in r/adapt-react-class. If that doesn't work (not sure if it works with function components, and no clue which one styled returns), try [:f> styled-breadcrumb ...].

p-himik 2024-11-14T12:29:29.830449Z

Also, there's no need in that r/as-element. But you do need to adapt Breadcrumbs component as well.

thheller 2024-11-14T12:36:15.904439Z

I'm not super familiar with reagent, but shouldn't this just be

(defn breadcrumb-component []
  [:div {:role "presentation"}
   [:> Breadcrumbs {:aria-label "breadcrumb"}
    [:> styled-breadcrumb {:component "a"
                           :href "#"
                           :label "Home2"}]
    [:> styled-breadcrumb {:component "a"
                           :href "#"
                           :label "Catalog"}]
    [:> styled-breadcrumb {:label "Accessories"}]]])
?

thheller 2024-11-14T12:36:51.457419Z

also it is unlikely that styled understands the CLJS map you are returning. that likely needs a #js tag or clj->js

p-himik 2024-11-14T12:41:40.610939Z

:> is just a cached sugar for r/adapt-react-class. Right, missed the CLJS map in styled.

liebs 2024-11-14T12:44:10.946449Z

not a tremendous contribution to this discussion, but in case you are interested, there's a Reagent wrapper for MUI: https://github.com/arttuka/reagent-material-ui

p-himik 2024-11-14T12:46:12.329689Z

It's for MUI 5, and now there's MUI 6. No clue which one the OP uses though. I myself got quite a bit tired from their "this update changes every single thing" approach, so I don't use MUI anymore.

liebs 2024-11-14T12:48:37.090199Z

yeah, I've just used it once. There seems to be quite a lot of churn in the library. Also, wrt that code snippet above, is it even legal syntax to call r/as-element with square brackets? bc if so, TIL

p-himik 2024-11-14T12:49:52.829209Z

I've never seen such syntax being mentioned anywhere before, and I'd be surprised if that worked, and worked reliably.

meya wudafu 2024-11-14T12:55:19.761819Z

I try all this but without success, so I'm trying something simpler, like:

(def my-component
  (clj->js
   (styled "div"
           {:color "darkslategray"
            :backgroundColor "aliceblue"
            :padding 8
            :borderRadius 4})))

(defn basic-usage []
  [my-component "Hello"])

thheller 2024-11-14T12:55:55.175729Z

that clj->js should be for the map, not the styled call

thheller 2024-11-14T12:56:10.514049Z

and it should still be [:> my-component ...]

meya wudafu 2024-11-14T12:56:17.711589Z

true, let me try

thheller 2024-11-14T12:58:34.272369Z

and it is also relevant in what context the basic-usage is used there

meya wudafu 2024-11-14T12:59:12.310399Z

now I see: Error: Objects are not valid as a React child (found: object with keys {$$typeof, render, defaultProps, emotion_real, emotion_base, emotion_styles, emotion_forwardProp, withComponent}). If you meant to render a collection of children, use an array instead.

p-himik 2024-11-14T13:00:45.703119Z

What is your current code?

meya wudafu 2024-11-14T13:01:53.155579Z

(def my-component
  (styled "div"
          (clj->js
           {:color "darkslategray"
            :backgroundColor "aliceblue"
            :padding 8
            :borderRadius 4}))
)

(defn basic-usage []
  [:> my-component "Hello"])

meya wudafu 2024-11-14T13:02:16.248349Z

and just call like [basic-usage]

thheller 2024-11-14T13:02:34.920399Z

in what context is this [basic-usage]? πŸ˜› I'm asking because if its in some JS context that is not aware of what hiccup or reagent is then that is the cause problem πŸ˜›

meya wudafu 2024-11-14T13:04:21.576829Z

context is direct on the router component from init :

(rd/render [router-component]
             (.getElementById js/document "app"))
router component is just
(defn router-component []
  [basic-usage])

thheller 2024-11-14T13:04:40.158859Z

ok thats fine

liebs 2024-11-14T13:07:52.434179Z

I'm rusty on MUI but I think you may need to wrap child components in r/as-element, even when their parents have been adapted

p-himik 2024-11-14T13:09:22.505869Z

@wudafumeya Try :f> instead of :> there.

liebs 2024-11-14T13:09:49.564929Z

Here's an example of using styled components in this manner, albeit using the reagent-mui wrapper

p-himik 2024-11-14T13:09:51.991759Z

@bhlieberman93 That's for higher-order components, no the case here.

πŸ‘πŸ» 1
meya wudafu 2024-11-14T13:10:25.082979Z

@p-himik with :f> same thing

p-himik 2024-11-14T13:13:22.420829Z

I'd try to figure out what that object in the exception is exactly. You can do so by making the DevTools debugger break on uncaught exceptions. If that doesn't break before the exception happens, it must be a caught one - so break on caught exceptions and skip any that don't seem relevant.

meya wudafu 2024-11-14T13:24:50.388649Z

Yep, trying it . thanks all!

Ryan 2024-11-14T20:17:38.539019Z

I’m trying to use interop to preform document.body.classList.add(foo)

Ryan 2024-11-14T20:18:16.377959Z

I tried

(.. js/document -body -classList add "foo") .. any clues what I did wrong?

liebs 2024-11-14T20:18:36.160799Z

(.. js/document -body -classList (add "foo"))

liebs 2024-11-14T20:20:24.108099Z

native method invocation is performed with .theMethod and native property access with .-theProperty so when you use .. you can access the properties without wrapping parens but methods still need to be invoked like functions

Ryan 2024-11-14T20:20:43.351679Z

Weird, REPL says its not a function

Ryan 2024-11-14T20:20:50.316699Z

but I’m pretty sure it is https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/add

Roman Liutikov 2024-11-14T20:21:49.642259Z

(js/document.body.classList.add foo) should work

Roman Liutikov 2024-11-14T20:22:31.083739Z

Technically this is not valid Clojure form but it works in cljs

Ryan 2024-11-14T20:22:50.547519Z

Ah understood

Ryan 2024-11-14T20:23:02.019409Z

weird, it also says its not a fn.. let me see whats going on

liebs 2024-11-14T20:23:28.193399Z

yeah something else sounds wrong then, afaik both are valid

πŸ‘ 1
p-himik 2024-11-14T20:55:57.930689Z

As another option, that I personally prefer: (-> js/document .-body .-classList (.add "foo")).

Ryan 2024-11-14T20:57:12.180249Z

That syntax works!

p-himik 2024-11-14T20:59:58.235109Z

Ehm, that's weird. If that works, .. also should've worked. What REPL and environment are you using?

Ryan 2024-11-14T21:01:58.008649Z

Cursive / Shadow-cljs repl

Ryan 2024-11-14T21:02:07.822929Z

I think it’s n-repl?

p-himik 2024-11-14T21:02:31.160219Z

And what is the exact error when you try (.. js/document -body -classList (add "foo"))?

Ryan 2024-11-14T21:04:19.984869Z

(.. js/document -body -classList (add β€œdark”)) Execution error (TypeError) at (<cljs repl>:1). document.body.classList.add is not a function

Ryan 2024-11-14T21:05:14.850679Z

I use that syntax again just now and it works.. I must have gotten my browser into a weird state

p-himik 2024-11-14T21:06:55.745409Z

Yeah, that's quite easy to mess up. :)

cljs.user=> (set! (.-add js/document.body.classList) nil)
nil
cljs.user=> (.. js/document -body -classList (add "foo"))
ERROR - document.body.classList.add is not a function

πŸ˜… 1