Fork me on GitHub
#clojurescript
<
2021-05-23
>
Ale03:05:42

is there a way to destructure js objects in the function arg list? something like (fn [#js {foo :foo bar :bar}] (.log js/console foo bar))

p-himik08:05:46

No, you have to use interop or some library in the body of the function.

emccue13:05:04

@U84UHA68P you can write a macro for it probably

Ale14:05:58

@U3JH98J4R yep, I probably will try writing one if/when the pattern starts annoying me - at the moment I have a wrapper function for it

km05:05:00

Hey clojurians, wondering about key attributes in #reagent. I'm hoping to use css transitions, but these tend to get skipped when components re-render. I supposed using keys would make them persistent, but this only works some of the time, for some of the components. On clicking "Next," I should see both the blue and green boxes move to the left. However, only the blue box does. Any idea how I can fix this?

(ns kimok.example
  (:require
   [reagent.core :as reagent :refer [atom]]
   [reagent.ratom :refer [reaction]]
   [reagent.dom :as rdom]))
(def size 200)
(def place (atom 1))
(def colors ["red" "green" "blue" "yellow"])
(def this-color (reaction (get colors @place)))
(def prev-color (reaction (get colors (dec @place))))
(def next-color (reaction (get colors (inc @place))))
(defn container [& children]
  [:div.container {:style {:position "relative"
                           :width size
                           :height size
                           :margin size
                           :overflow "visible"}}
   children])
(defn slider [color left]
  [:div {:style {:position "absolute"
                 :width size
                 :height size
                 :background color
                 :transition "all 1s"
                 :left left 
                 :top 0}}])
(defn app []
  [:div [container
         ^{:key @this-color}
         [slider @this-color 0]
         ^{:key @next-color}
         [slider @next-color size]
         ^{:key @prev-color}
         [slider @prev-color (- 0 size)]]
   [:button {:on-click #(swap! place dec)}
    "prev (" @prev-color ")"]
   [:button {:on-click #(swap! place inc)}
    "next (" @next-color ")"]])
(rdom/render [app] (.getElementById js/document "app"))

andrewboltachev05:05:47

[:> CSSTransition
          {:in (boolean @open)
           :timeout 300
           :unmountOnExit true
           ;:onExit js/console.log
           ;:onExiting js/console.log
           ;:onExited js/console.log
}
          [:div.dropdown2 {:style {:position :absolute
                         :top 0
                         :right 0}}
           (into [:<>] (r/children (r/current-component)))
           ]]

andrewboltachev05:05:54

example of how you are using it is this

andrewboltachev05:05:00

(of course, do look into :foreign-libs in order to use this [the react-transition-group NPM package] with Reagent)

km05:05:25

@andrewboltachev Thanks. I was hoping not to add dependencies, but I should look into this otherwise.

Carl12:05:58

Is there a way to get intellisense for ClojureScript when using Javascript interop to help with auto completing methods on objects? Specifically for shadow-cljs in emacs. It’s been a bit of a pain point for me

borkdude13:05:16

I am trying to set up a new reagent project from scratch and it's surprisingly difficult to find out what is the recommended way of adding the React dependency by glossing over the README. The README even contains namespace aliases that aren't explained. EDIT: this looked like a shadow-cljs problem

nenadalm13:05:15

I just looked out of curiosity and it seems that all aliases are explained (link to readme: https://github.com/reagent-project/reagent)? I guess you're talking about rd ? I was confused at first, but it's explained after first usage.

borkdude14:05:02

I think it would be better if they add the require with the example

nenadalm14:05:05

sure, but then they would have to duplicate the require into every snippet using the aliases. Or they could just start with alias assumptions like Fulcro does: https://book.fulcrologic.com/#_common_prefixes_and_namespaces (I don't care that much about docs as long as it's clear enough for me - which Reagent is)

p-himik14:05:01

Regarding React dependency - the README states: > [Adding Reagent as a dependency] is all you need to do if you want the standard version of React

p-himik14:05:32

Regarding aliases - this section is there:

(ns example
  (:require [reagent.core :as r]
            [reagent.dom :as rd]))

borkdude14:05:36

I think there was some weirdness with shadow-cljs then\

borkdude14:05:45

I retract my problem :)

Jacob Rosenzweig19:05:05

Because the notion of "private functions" doesn't really work in Clojurescript (and is sort of an illusion in Clojure as well), some have recommended that you use a separate "helper namespace" for all your helper/private functions. Has anyone here done this?

raspasov19:05:31

Perhaps as an aid for autocompletion it can make sense to separate, but the trade-off is that you have “one more place” to make decisions about. I haven’t actually tried this. One convention I’ve used is prefixing the “private” function with ‘-’, so a fn name becomes (defn -my-private-function-name …) Are you designing a library or an API?

raspasov19:05:28

Clojure JVM will actually throw an error and not allow you to call the private fn from another namespace (there’s ways around it but they are non-standard)

raspasov19:05:37

So it’s more “real”.

raspasov19:05:36

(scratch/private-1 1 2) Syntax error (IllegalStateException) compiling scratch/private-1 at (REPL:1:1). var: #’ss.scratch/private-1 is not public

Jacob Rosenzweig19:05:56

@U050KSS8M It's just a reagent project, but I used styled components and the way that the styled components library works is that it'll create a "styled tag" as a function macro (and no obvious way to use a local let binding in my component function itself)

Jacob Rosenzweig19:05:10

And I just don't want to expose all the component specific tags that I use.

Jacob Rosenzweig19:05:39

I'm actually trying to follow this section of "The Joy of Clojure" but I get compilation errors

Jacob Rosenzweig19:05:09

Specifically "The required namespace "joy.component.impl" is not available, it was required by...

raspasov19:05:11

Is it because it’s a .clj namespace that you’re trying to require from ClojureScript? (I don’t remember if that is possible, I think it’s possible for macros)

Jacob Rosenzweig19:05:47

I'm actually writing my own example but I didn't want to write all the source code down.

Jacob Rosenzweig19:05:52

Let me actually show what I'm doing

Jacob Rosenzweig19:05:07

Ideally I want something like this. A single folder per component that will contain the component file itself (in react this would be like index.js) and all the helper functions, styling, and other logic).

Jacob Rosenzweig19:05:01

Ideally, anywhere in my application, I can refer to the todo.cljs file with (:require [components.todo as :todo) but I'm not sure if that's possible.

Jacob Rosenzweig19:05:23

It kind of looks like it is? Because in that example, they do the same thing with the impl file.

Jacob Rosenzweig19:05:22

Basically I want the "index.js" of clojurescript

raspasov19:05:44

It must be either .cljs or .cljc

raspasov19:05:08

.clj does not work the be required from a .cljs file directly

Jacob Rosenzweig19:05:23

Oh yeah I'm only using cljs files here.

Jacob Rosenzweig20:05:27

Maybe this just doesn't translate into clojurescript.

raspasov20:05:01

What’s is your exact project structure and require statements? What error are you getting?

Jacob Rosenzweig20:05:48

The required namespace "components.todo" is not available, it was required by "frontend/core.cljs".

Jacob Rosenzweig20:05:31

src/frontend/core.cljs

(ns frontend.core
    (:require [components.todo as :todo]))

Jacob Rosenzweig20:05:54

src/components/todo/todo.cljs

(ns components.todo (:require [components.todo.tags as :tags]))

raspasov20:05:43

Shouldn’t (ns components.todo … be:

(ns components.todo.todo ...
?

Jacob Rosenzweig20:05:01

Yes it should, but in the example, he does

(ns.joy.impl)
instead of
(ns.joy.impl.impl)

Jacob Rosenzweig20:05:21

Honestly, it's fine. I'll just call the component file "index" or something and use that as a naming convention from now on.

Jacob Rosenzweig20:05:45

Thanks for helping me figure this out. I think it's a lot better than leaving every single styled tag definition in the same file. I don't really want them to be exported unless they're reusable (and thus put into a shared folder)

✌️ 3
borkdude21:05:06

I didn't read the entire thread but yes, this is how I set up a lot of my projects: internal namespaces have an .impl segment in this, communicating that these are implementation details