Fork me on GitHub
#reagent
<
2021-12-13
>
dvingo15:12:36

I've found the emotion css-in-js tool (https://emotion.sh/docs/styled) mixes really well with cljs - data driven all the way:

(defstyled multi :div
  {:background "blue"}
  {:color "yellow"}
  #js{"borderRadius" 4}
  [{"border" "1px solid grey"}]
  (fn [_] {":hover" {:background "white"}}))
In this example all those styles are merged together - this way you can have a collection of styles as maps/vectors (or functions of props -> map of styles) and then combine them profitably at runtime however you like. This code is using a wrapper for emotion that I authored: https://github.com/dvingo/cljs-emotion but most of the work is done in emotion proper - there are classnames under the hood, but those are transparent to you. This macro produces a react component which, when rendered, inserts the styles and assigns the resulting react element the generated class name. There is also anonymous style support so if you don't want to def anything, you don't have to:
(defn anon-styles []
  (css :div {:css {:background "lightgrey"}}
    "Some text on a lightgrey background."))

🎉 2
Drew Verlee03:12:45

@U051V5LLP Why use something other then a clojure hashmap as a child?

(defstyled sample1 :div
 {:background-color "RebeccaPurple"}
 #js{:color "yellow"}
 (fn [props] {:border-radius 4}))

Drew Verlee04:12:19

so here normally a media query has to be in a css file and can't be on a html attribute, thats the -in-js part right? the var is just to show you can right, the important bit is the "global-style" function right?

(def mw-700 "@media (min-width:700px)")
[:div
 [:.my-thing "Some content"]
  (global-style
    {:.my-thing {:background "navy" :color "#cce" mw-700 {:background "black"}}})])

Drew Verlee04:12:38

How does this compare with getting the screen with from javascript, i'm guessing js is slower, but i never really looked into confirming it.

Noah Bogart21:12:53

when is :component-will-unmount called?

Noah Bogart21:12:24

I have a timer component that I’m updating with js/setInterval, and I have js/clearInterval in the :component-will-unmount, but I can’t seem to get the clearInterval call to happen when the component stops rendering

Noah Bogart21:12:25

nevermind! false alarm. I had (js/clearInterval interval) instead of (js/clearInterval @interval)

Pablo22:12:50

Hello everyone I’m trying to translate this snippet into ClojureScript:

const ExpandMore = styled((props) => {
  const { expand, ...other } = props;
  return <IconButton {...other} />;
})(({ theme, expand }) => ({
  transform: !expand ? 'rotate(0deg)' : 'rotate(180deg)',
  marginLeft: 'auto',
  transition: theme.transitions.create('transform', {
    duration: theme.transitions.duration.shortest,
  }),
}));
But, I’m getting this error:
Error: Objects are not valid as a React child (found: object with keys {tag, id, className, displayName}). If you meant to render a collection of children, use an array instead.
And I’m having no idea on what I’m doing wrong 😞 ¿Could someone help? This is my translation:
(ns foo
 (:require
  [reagent-mui.material.icon-button :refer [icon-button]]
  [reagent-mui.styles :refer [styled]]))
...

(defn expand-more
  [{:keys [expand] :as props}]
  (let [props (dissoc props :expand)]
    (styled icon-button
            props
            {:margin-left :auto
             :transform   (if expand "rotate(0deg)" "rotate(180deg)")
             :transition  #(let [{:keys [create duration]} (-> ^js/Object % .-transitions (js->clj :keywordize-keys true))]
                             (create "transform" #js{:duration (:shortest duration)}))})))

...

;; There is some example of how I'm calling it:

(defn component
  []
  (r/with-let [expanded? (r/atom false)]
    [expand-more {:expand        @expanded?
                  :on-click      #(swap! expanded? not)
                  :aria-label    "Show more"
                  :aria-expanded @expanded?}]))

p-himik22:12:25

Original code: ExpandMore = styled(...). Your code: (defn expand-more [...] (styled ...)). Do you see the difference?

p-himik22:12:07

The original code wraps the function with styled and assigns the result to a name. Your code creates a function that calls style inside of it and assigns the function - not its result! - to a name.

p-himik22:12:22

It should be (def expand-more (styled ...)) to be the same thing.

👀 1
Pablo22:12:19

Nope, I still don’t get it. In the original example they used ExpandMore as a React Component:

<ExpandMore
          expand={expanded}
          onClick={handleExpandClick}
          aria-expanded={expanded}
          aria-label="show more"
        >
          <ExpandMoreIcon />
        </ExpandMore>
expand-more should be a reagent component

Pablo22:12:32

¿Does expand-more should be

(defn expand-more
  [{:keys [expand] :as props} & body]
  ...)
?

p-himik22:12:01

(styled ...) returns a Reagent component. You don't need to wrap it in a function.

p-himik22:12:28

By using (def expand-more (styled ...)), you already make sure that expand-more is a Reagent component.

Pablo23:12:28

I almost got it, but it does not show anything:

(def expand-more
  (styled (fn [props & body]
            [icon-button (dissoc props :expand) body])
          (fn [theme expand]
            (let [create-fn (get-in theme [:theme :transitions :create])
                  duration  (get-in theme [:theme :transitions :duration])]
              {:margin-left :auto
               :transform   (if (:expand expand) "rotate(180deg)" "rotate(0deg)")
               :transition  (create-fn "transform" #js{:duration (:shortest duration)})}))))

Pablo23:12:52

I printed body but is nil 😞

Pablo23:12:50

props is:

{:expand false, :on-click #object[Function], :aria-label Expandir detalle de fechas, :aria-expanded false, :children #object[reagent.impl.template.NativeWrapper], :class-name css-1tj6xfp, :ref nil}

Pablo23:12:42

If I changed the first argument of styled :

(fn [props] [icon-button (dissoc props :expand)])
I get the Objects are not valid as a React child error again, So I don’t know how to merge icon-button with (dissoc props :expand)

Pablo23:12:46

My bad, I was calling it with the bad childrens

Pablo23:12:52

Thanks a lot 😄

👍 1