javascriptcssclojureclojurescriptre-frame

Why is :style on re-frame sometimes used with brackets, with curly brackets, and without anything?


I have been using Clojure, ClojureScript, lein, shadow-cljs, Emacs, and CIDER to work on a Clojure/ClojureScript dynamic web app project.

Usually, I build the project by executing the command cider-jack-in-cljs in Emacs, choosing shadow-cljs, then shadow for REPL type, and, finally, app for building option.

On the source code of the project we have:

(defn splitter-panel-title
  [text]
  [title
   :label text
   :level :level3
   :style {:margin-top "20px"}])

Notice the style without a direct prefix of bracket or curly bracket :style {:margin-top "20px"}. Also, in a smaller frequency, we have:

(defn left-panel
  []
  [box
   :size "auto"
   :child [:div {:style rounded-panel}
           [splitter-panel-title [:code ":panel-1"]]]])

Notice the style with curly bracket {:style rounded-panel}. Finally, we also have:

(defn header-view []
 [:div
   [:div
    [:style
     {:type "text/css"}]]])

Note the bracket [:style.

Why is :style on re-frame sometimes used with brackets, with curly brackets, and without anything? What is the rule behind the use of each approach?

If my understanding is correct, this is an-inline style in Re-frame. The last two examples are inside a div tag. But each of them uses a different approach.

Is the bracket, the curly bracket, and the non-use of bracket connected somehow to Javascript and/or CSS syntax?

Thanks


Solution

  • The definition of the title or box component will tell you why its done this way. What reagent/re-frame will do here is take the title component and essentially call it as

    (title :label text :level :level3 :style {:margin-top "20px"})
    

    when it is time to render the actual component. So, my guess it that the title component uses variadic destructuring like

    (defn title [& {:keys [...] :as args}] ...)
    

    CLJ(S) allow calling functions with key/value pairs like this. So, essentially what arrives it just a map and could have been this:

    (defn splitter-panel-title
      [text]
      [title
       {:label text
        :level :level3
        :style {:margin-top "20px"}}])