I use safari as a daily driver, and do almost all of my dev work there.
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.
it feels snappier and less bloated, basically...
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?
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.
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.
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.
@danvingo thanks for sharing that’s interesting! have you had a look at https://herb.roosta.sh/ as well?
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?
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"]]]))
nice
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"})} ,,,)
ah, very cool, that makes sense
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?
@smith.adriane Thanks, I'll give the thesis a read too 😄
np! I haven't looked at it yet, actually just heard about it, so don't have any strong opinions at this time
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
This should however run every 100 ms AFAICS
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
(timeout 100) would only give one value after 100ms and then close the channel, no? that was the rationale behind the (while true) bit
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 😅
maybe make some-function execute asynchronously? ie run it in setTimeout with 0 millis.
but it will always have the possibility to drift, because after the timeout elapses, there may be other stuff that the thread is executing
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
@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.
@mfikes Thanks, I was mostly curious. Backward compatibility is a good enough reason to be cautious
@adam678 performance really is a concern as well at least as important as backwards compatibility
@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?
Yeah, that's a good question. It seems you can't use js*
as it emits parens around the number.
try:
(go (while true
(<! (timeout 100))
(go (some-function))))
This will immediately start the next timer rather than waiting for some-function
to finishto 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.)))]
(<! (timeout delay)))
(go (some-function))
(recur i))))
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"
"&:hover" {:color "green"}})
etc.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)} ,,,)