clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
Ale 2021-05-23T03:55:42.209200Z

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-himik 2021-05-23T08:36:46.217200Z

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

emccue 2021-05-24T13:27:04.246700Z

@laynor you can write a macro for it probably

Ale 2021-05-24T14:20:58.247Z

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

km 2021-05-23T05:37:00.213200Z

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"))

andrewboltachev 2021-05-23T05:47:04.214300Z

Hello @kimo for CSS transitions please look into: http://reactcommunity.org/react-transition-group/css-transition

andrewboltachev 2021-05-23T05:48:47.214700Z

[:> 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)))
           ]]

andrewboltachev 2021-05-23T05:48:54.215100Z

example of how you are using it is this

andrewboltachev 2021-05-23T05:51:00.215900Z

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

km 2021-05-23T05:53:25.217Z

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

2021-05-23T12:30:58.220400Z

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

borkdude 2021-05-23T13:47:16.221300Z

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

nenadalm 2021-05-23T13:56:15.221600Z

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.

borkdude 2021-05-23T14:04:02.221900Z

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

nenadalm 2021-05-23T14:08:05.222100Z

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-himik 2021-05-23T14:17:01.222400Z

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-himik 2021-05-23T14:17:32.222600Z

Regarding aliases - this section is there:

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

borkdude 2021-05-23T14:35:36.222800Z

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

borkdude 2021-05-23T14:35:45.223Z

I retract my problem :)

borkdude 2021-05-23T14:36:17.223300Z

https://borkdude.github.io/sci-script-tag/#reagent ;)

👍 2
Jacob Rosenzweig 2021-05-23T19:19:05.224800Z

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?

raspasov 2021-05-23T19:23:31.224900Z

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?

raspasov 2021-05-23T19:25:28.225100Z

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)

raspasov 2021-05-23T19:25:37.225300Z

So it’s more “real”.

raspasov 2021-05-23T19:26:36.225600Z

(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 Rosenzweig 2021-05-23T19:30:56.225800Z

@raspasov 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 Rosenzweig 2021-05-23T19:31:10.226Z

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

Jacob Rosenzweig 2021-05-23T19:37:39.226300Z

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

Jacob Rosenzweig 2021-05-23T19:39:09.226500Z

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

raspasov 2021-05-23T19:49:11.226700Z

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 Rosenzweig 2021-05-23T19:49:47.226900Z

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

Jacob Rosenzweig 2021-05-23T19:49:52.227100Z

Let me actually show what I'm doing

Jacob Rosenzweig 2021-05-23T19:52:07.227300Z

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 Rosenzweig 2021-05-23T19:53:01.227500Z

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 Rosenzweig 2021-05-23T19:53:23.227700Z

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

Jacob Rosenzweig 2021-05-23T19:54:22.227900Z

Basically I want the "index.js" of clojurescript

raspasov 2021-05-23T19:54:44.228100Z

It must be either .cljs or .cljc

raspasov 2021-05-23T19:55:08.228300Z

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

Jacob Rosenzweig 2021-05-23T19:55:23.228500Z

Oh yeah I'm only using cljs files here.

Jacob Rosenzweig 2021-05-23T20:02:27.228700Z

Maybe this just doesn't translate into clojurescript.

raspasov 2021-05-23T20:05:01.230200Z

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

Jacob Rosenzweig 2021-05-23T20:06:48.230400Z

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

Jacob Rosenzweig 2021-05-23T20:07:31.230600Z

src/frontend/core.cljs

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

Jacob Rosenzweig 2021-05-23T20:08:54.231Z

src/components/todo/todo.cljs

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

raspasov 2021-05-23T20:10:43.231300Z

Shouldn’t (ns components.todo … be:

(ns components.todo.todo ...
?

Jacob Rosenzweig 2021-05-23T20:12:01.231500Z

Yes it should, but in the example, he does

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

Jacob Rosenzweig 2021-05-23T20:12:21.231700Z

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

raspasov 2021-05-23T20:14:35.231900Z

👌

Jacob Rosenzweig 2021-05-23T20:16:45.232200Z

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)

✌️ 1
borkdude 2021-05-23T21:33:06.232600Z

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