Fork me on GitHub
#clojurescript
<
2021-01-28
>
zendevil.eth06:01:46

I have a flatlist component from react native like so:

[:> FlatList {:refreshControl (r/as-element [:> RefreshControl {:refreshing @(subscribe [:refreshing])
                                                                   :onRefresh #(dispatch [:load-videos])
                                                                   }])
                 :data @(subscribe [:videos])
                 :renderItem (fn [item] (r/as-element [video-comp (get (js->clj item) "item")]))
                 :keyExtractor (fn [item] (-> (get (js->clj item) "item")
                                              (get "uri")))}]
In this component I have a RefreshControl with the prop:
:refreshing @(subscribe [:refreshing])
but upon using this prop, I’m getting the error:
No protocol method IDeref.-deref defined for type undefined:
How to fix this error?

zendevil.eth06:01:23

there was a typo in the subscription. Problem solved!

West07:01:26

Hey guys!

👋 6
Grigory Shepelev08:01:50

Hi. How could I dynamically load content using Reagent with clojurescript? I wanted to just do:

(:require [cljs-http.client :as http]
          [reagent.core :as reagent]
          [cljs.core.async :refer [<! go]])
...
[:div
     (go (<! (http/get ""
                       {:with-credentials? false})))]

henryw37409:01:49

there's a few problems here... I'd suggest looking at an example of loading async into a reagent app... first hit on google https://github.com/Gonzih/cljs-http-reagent-learning-template

Grigory Shepelev09:01:02

Thnx. That really helped

Grigory Shepelev11:01:03

Well. Not really. Still having a problem. For some reason it renders on "compiling" only.

Grigory Shepelev08:01:50

But it given me an error:

Uncaught Error: Objects are not valid as a React child (found: object with keys {takes, dirty_takes, puts, dirty_puts, buf, closed, add_BANG_}). If you meant to render a collection of children, use an array instead

pinealan10:01:34

Hey guys! Not strictly a CLJS questions, but how would you do deep linking with a reagent+reitit SPA? My first thought was to use :modules to code split, but on second thought it seems over kill?

herald12:01:57

Not sure what you mean. reitit should be able to resolve the URL path fine. You just need to make sure the server serving your SPA returns the SPA's index.html for any path.

jkrasnay13:01:42

In my SPA I use reitit.frontend.easy/start! when I first load. You give start! a function that Reitit will call with the matching route on initial load and any time the URL changes. In my case, the function stores the matching route and my “app” component renders the appropriate page based on the route.

jkrasnay13:01:37

Oh, one more thing: in my app, I don’t have specific server-side routes for each page. Those routes all return the same root page, which performs the initialization above.

pinealan14:01:01

thanks that's sounds like a good setup

West17:01:36

So I just had an idea for a clojurescript project. I want to make a library around https://github.com/Jarzka/stylefy and/or https://github.com/noprompt/garden to wrap around https://github.com/tailwindlabs/tailwindcss. I absolutely love tailwind, but npm isn’t so nice to work with in the clojurescript ecosystem. What do you guys think? Could this be done in an easier way? I was thinking of batch converting the tailwind css file you get via its CDN into garden syntax, then calling each tailwind class using stylefy.

dpsutton17:01:16

i only know a little bit but i think tailwind is enormous and relies on a tool to prune down only to the actually used classes? would your library be able to replicate this?

West17:01:33

Stylefy will already exclude any unused css from your page as far as I can tell.

isak17:01:23

For what it's worth, we use tailwind and don't really have any problems. Only needed to change some of the conventions to make it worth with clojure (e.g., w-1/3 -> w-1_3), and fix the pruning logic so that it works with how reagent specifies css classes. (It's like a 50-100 line npm script to expand the whitelist before pruning)

West18:01:22

@isak Is there any documentation on this? I’m perfectly happy doing:`[:div {:class '[tw classes]}]` I think however we could do better.

isak18:01:38

@c.westrom Hmm we're not doing anything special, just specifying CSS classes as one normally would. I don't really see the problem personally. But yea with a native clojure solution, I guess you could avoid the bloated CSS that needs to be pruned, so it would probably be a bit simpler.

dgb2318:01:05

When you use something like garden, then you are likely building your own compositional semantics / relations between your style rules. What tailwind does is get around the limitations of CSS in another way, by giving you the ability to generate classes based on your design system (with a JSON config). So in a sense they are solving the same problem (vanilla CSS sucks for expressing complex designs) but in a different way.

rgm19:01:24

We also use tailwind and frankly embrace the purgecss part in node and have no problems on the clojurescript side. It’s just so delightfully dumb, scanning for strings in the advanced-build cljs bundle. Here’s the very minimal lib I made up: https://github.com/rgm/tailwind-hiccup

p-himik19:01:52

FWIW, a variant of tw is already implemented in Reagent itself.

p-himik19:01:06

reagent.core/class-names.

rgm19:01:09

oh, that’s good to know.

rgm19:01:42

I’ve been use the fn server-side too, though, and not necessarily with reagent.

p-himik19:01:15

That's a good point.

rgm19:01:52

(also needed a (twp ,,,) to make working with prefixes easier … it’s a tailwind thing that’s sometimes needed to avoid conflicting with existing CSS).

👍 3
rgm19:01:51

(all that said, I think there could be a lot of smarter stuff done with runtime performance, maybe dev-time detection of common usage sets to surface candidates for extraction components, etc).

West20:01:28

Could you recommend some resources I can use to help me build a stack? The individual parts are there but I’m having trouble putting it all together.

West20:01:21

Here’s my best attempt so far. I forked a clojurescript template using shadow-cljs and tailwind. I’m just having trouble making it my own. Also I haven’t figured out dark mode yet. I got the root HTML tag to update, but I’m trying to rewrite https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually, so I can detect OS preferences and manual preferences. https://github.com/wildwestrom/shadow-static

rgm21:01:47

I don’t have any opinions about the clojurescript side, but I’ve tried to put together a decent simple version of the tailwind with purge side in this example: https://github.com/rgm/tailwind-hiccup/tree/master/examples/basic

rgm21:01:10

re: dark mode, when it or something like disabled:text-gray-200 or hover:whatever doesn’t work I usually assume I haven’t turned on the variant in my tailwind config. https://tailwindcss.com/docs/configuring-variants … if you get the purge working correctly, there’s no real downside to turning on absolutely every variant for everything to avoid these head-scratchers.

rgm21:01:36

but for a cljs stack, you might take a look at https://github.com/rgm/experiments/tree/master/template-reframe-reitit. I keep it around to have something I can quickly copy and start sketching in.

rgm21:01:06

figwheel builds, re-frame/reagent and reitit for front-end routing.

rgm21:01:31

I might switch it over to shadow-cljs sometime, and would probably recommend that if you’re starting fresh. There’s just no comparison on how much easier it makes using npm packages. I think the new webpack/bundle target stuff in base cljs will be interesting. But I haven’t really taken the time to grok it.

rgm19:01:01

we have some problems on the clj side if we use server-rendered hiccup… I haven’t figured out quite how to deal with these yet. My first rough thing has been to hijack the dev clj version of the (tw ,,,) calls to just spit out these strings into a temp text file for purgecss to look at.

rgm19:01:11

(also re: the original poster: the trick we’ve used to make life a little easier re NPM is to have separate the cljs build from the tailwind build. Don’t mix the streams. The clojurescript builds first, then the tailwind purge happens second).

rgm19:01:51

(all that said, I think there could be a lot of smarter stuff done with runtime performance, maybe dev-time detection of common usage sets to surface candidates for extraction components, etc).

clyfe21:01:02

Compiling /home/clyfe/dev/riviera/src/riviera/core.cljs to out/riviera/core.js
Unexpected error (ExceptionInfo) compiling at (REPL:1).
No such namespace: monaco-editor, could not locate monaco_editor.cljs, monaco_editor.cljc, or JavaScript source providing "monaco-editor" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file /home/clyfe/dev/riviera/src/riviera/core.cljs
I followed https://clojurescript.org/guides/webpack With monaco-editor instead react & react-dom

clyfe21:01:29

(ns riviera.core
  (:require
   [goog.dom :as dom]
   ["monaco-editor" :as monaco]))

joshmiller22:01:48

Just checking: Did you npm/yarn install?

clyfe06:01:22

> GET http://localhost:9000/out/brepl_deps.js net::ERR_ABORTED 404 (Not Found) I'm also bothered by that.

clyfe07:01:26

Nvm, I nailed it! This guide here is outdated: https://clojurescript.org/guides/webpack

rgm21:01:10

re: dark mode, when it or something like disabled:text-gray-200 or hover:whatever doesn’t work I usually assume I haven’t turned on the variant in my tailwind config. https://tailwindcss.com/docs/configuring-variants … if you get the purge working correctly, there’s no real downside to turning on absolutely every variant for everything to avoid these head-scratchers.