clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
dazld 2021-02-18T07:55:43.222700Z

I use safari as a daily driver, and do almost all of my dev work there.

dazld 2021-02-18T07:57:00.222900Z

few reasons - integration with iOS / icloud, the CSS engine is 👌 , it's lighter on my battery and CPU, and the devtools are great and aren't constantly changing.

dazld 2021-02-18T07:58:43.223100Z

it feels snappier and less bloated, basically...

ajithkumar 2021-02-18T09:52:41.223300Z

(-> "app" (js/document) .getElementById)

martinklepsch 2021-02-18T11:47:26.224700Z

I’m currently developing a new design system and am curious about people’s experiences with CSS-in-JS from a ClojureScript perspective. Have you tried it? What was good about it, what was bad?

2021-02-18T12:09:15.229600Z

I've been really enjoying using emotion from cljs. I made a small macro over the styled API: https://dvingo.github.io/cljs-emotion/#!/dv.cljs_emotion.devcards I recently added support for using other components as part of a CSS selector (bottom of this page): https://dvingo.github.io/cljs-emotion/#!/dv.cljs_emotion.target_styled and with that I have all the use-cases supported that I need to style pages and style complex components. A lot of features in the JS version require a babel compiler plugin, but we have macros which makes implementing certain features possible without that. You can use JS objects in your styles, so things like polished are supported https://polished.js.org too, and it supports SSR on node.js.

thheller 2021-02-18T12:09:50.230400Z

I have used my solution https://github.com/thheller/shadow/wiki/shadow.markup for years but nowadays mostly use tailwind. It is ok and I prefer it over vanilla CSS but in my case naming every element gets tedious very quickly. tailwind isn't perfect either though so maybe some kind of inbetween would be good but I'm not sure how that would look.

2021-02-18T12:16:32.231900Z

I've noticed it gets annoying with having to name every component as well. emotion allows using the css prop https://emotion.sh/docs/css-prop for anonymous styles, but I haven't looked into translating this to cljs use yet.

martinklepsch 2021-02-18T13:12:32.233400Z

@danvingo thanks for sharing that’s interesting! have you had a look at https://herb.roosta.sh/ as well?

2021-02-19T16:07:35.252600Z

Nice, but you still have to come up with a name for the styles. Does this use @emotion/css or @emotion/react? And do you do SSR or is that not a use case for you?

2021-02-20T18:32:52.008200Z

Playing around with the anon-styles support - works well enough:

["@emotion/react" :refer [jsx]]
(jsx "div"
  (clj->js {:ref my-ref
            :css
                 {:position        "absolute"
                  :backgroundColor "white"
                  :width           "10em"
                  :height          (if is-open? height 0)
                  :overflow        "hidden"
                  :transition      (str "height 0.2s ease-in")}})
  (re/as-element
    [dropdown-menu {:role "menu"}
     [dropdown-item [:a {:href "/features"} "Features"]]
     [dropdown-item [:a {:href "/pricing"} "Pricing"]]
     [dropdown-item [:a {:href "/support"} "Support"]]
     [dropdown-item [:a {:href "/about"} "About"]]]))

lilactown 2021-02-20T18:42:56.008400Z

nice

lilactown 2021-02-20T18:43:55.008600Z

we use @emotion/css. if you don't want to name the styles, you can use the css function:

(d/div {:class (css {:transition "height 0.2s eaase-in"})} ,,,)

2021-02-20T19:00:42.008800Z

ah, very cool, that makes sense

Baibhav Bista 2021-02-18T13:16:43.236800Z

Hello everyone, I'm trying to replicate functionality similar to js/setInterval using cljs.core.async What I need is a regular tick (say every 100ms) This is what I've tried (go (while true       `(<! (timeout 100))`       `(some-function)))` The problem here is that since some-function takes a non-negligible amount of time, and so, time between ticks becomes more than 100ms Could anyone give me any pointers?

Baibhav Bista 2021-02-19T10:01:31.251600Z

@smith.adriane Thanks, I'll give the thesis a read too 😄

2021-02-18T13:23:52.237Z

np! I haven't looked at it yet, actually just heard about it, so don't have any strong opinions at this time

2021-02-18T13:30:28.237300Z

while true doesn’t do anything here, so you can just skip that I presume This will however run async, so if you want to use the result of some-function in the next iteration, you’re better of falling back to js timeouts

2021-02-18T13:31:18.237500Z

This should however run every 100 ms AFAICS

2021-02-18T13:33:57.237700Z

Out of curiosity, what heavy operation do you have to run every 100ms? Maybe the body of some-function can be optimized and/or moved to a worker

Baibhav Bista 2021-02-18T13:34:12.237900Z

(timeout 100) would only give one value after 100ms and then close the channel, no? that was the rationale behind the (while true) bit

Baibhav Bista 2021-02-18T13:37:33.238100Z

The function is actually not that heavy, I was just swapping an atom for a timer (was doing task 4 of https://eugenkiss.github.io/7guis/tasks/) I found that after some time, the value started to deviate from my watch time. Exaggerated the heaviness of the function in the question a bit 😅

2021-02-18T13:57:41.238500Z

maybe make some-function execute asynchronously? ie run it in setTimeout with 0 millis.

2021-02-18T14:01:08.238800Z

but it will always have the possibility to drift, because after the timeout elapses, there may be other stuff that the thread is executing

Helins 2021-02-18T15:11:03.239700Z

Is there a reason Clojure's BigInt notation hasn't been ported to CLJS? Mike Fikes did some work on this: https://gist.github.com/mfikes/9fc981ed7a190b8e9b2912eee98fdd5e

mfikes 2021-02-18T15:16:07.241500Z

@adam678 I think there would still be a lot of work to do to ensure that nothing breaks (probably fairly challenging) and that there are no perf regressions. The above is really like the tip of the iceberg just showing that it might be possible. Also that stuff would only work with newer JavaScript engines, potentially creating a problem for the case where it doesn't exist.

Helins 2021-02-18T15:18:13.242700Z

@mfikes Thanks, I was mostly curious. Backward compatibility is a good enough reason to be cautious

dnolen 2021-02-18T15:36:00.243400Z

@adam678 performance really is a concern as well at least as important as backwards compatibility

1👍
Helins 2021-02-18T18:27:32.246200Z

@mfikes However, is there a way to emit the literal syntax? I get a syntax error when a macro outputs (js* "~{}n" n) Otherwise I can simply return a form calling BigInt with a string version of the input. Wouldn't make much difference I guess, would it?

mfikes 2021-02-18T18:32:11.247100Z

Yeah, that's a good question. It seems you can't use js* as it emits parens around the number.

phronmophobic 2021-02-18T20:31:50.247800Z

try:

(go (while true
      (&lt;! (timeout 100))
      (go (some-function))))
This will immediately start the next timer rather than waiting for some-function to finish

phronmophobic 2021-02-18T20:38:24.248Z

to prevent drift over time, you can also recalculate the timeout's delay each loop:

(let [start-time (.now (js/Date.))]
  (go (loop [i 1]
        (let [delay (- (+ start-time (* i 100))
                       (.now (js/Date.)))]
         (&lt;! (timeout delay)))
        (go (some-function))
        (recur i))))

lilactown 2021-02-18T21:49:33.248400Z

I've had great success with use emotion's css function rather than the styled components. I agree w/ thheller that I dislike tying the styles directly to a named component; instead we use a macro like:

(defcss header-styles
  {:font-weight :bolder
   :font-size "2rem"
   "&amp;:hover" {:color "green"}})
etc.

lilactown 2021-02-18T21:51:27.248600Z

and then you can refer to the header-styles class by var:

(d/div {:class header-styles} ,,,)

[:div {:class header-styles} ,,,]
and combine them with the cx function without messing around with complex inheritance issues:
(d/div {:class (cx header-styles some-other-style)} ,,,)