Fork me on GitHub
#clojurescript
<
2020-06-10
>
dnolen00:06:27

@jonas I haven't done any testing at all - but in theory it should work. You would have to run the bundler on your splits

dnolen00:06:47

experience reports welcome

raspasov02:06:53

7 years later, this runs great on a mobile device! 😃 cljs (http://swannodette.github.io/2013/08/02/100000-dom-updates/)

🙂 12
Schpaa11:06:22

I need an ordered set for clojurescript, which should I use?

Schpaa11:06:15

(something that preserves the insert order)

pithyless11:06:38

sorted-set or perhaps sorted-set-by ?

p-himik11:06:42

This is value order, not insertion order.

pithyless11:06:45

oops, I misread the question.

Schpaa11:06:50

I could use a regular map with the values at the key and the count (as I insert them) as the value

p-himik11:06:49

If your use-case doesn't require frequent iteration over the collection in the insertion order, then it should be fine.

p-himik11:06:18

Alternatively, you could port something like https://github.com/clj-commons/ordered/blob/master/src/flatland/ordered/set.clj to ClojureScript.

Schpaa11:06:22

next summer perhaps 😉

pithyless11:06:59

You can also take a look at https://github.com/tonsky/persistent-sorted-set - it was written for DataScript

pithyless11:06:31

damnit, nevermind. facepalm

pithyless11:06:53

I'm going to get a coffee now and log off the interwebs for a while 😄

gerred12:06:58

this may not be the best channel, but I wanted to kick this off as a starting point. I've been looking at https://svelte.dev and found it pretty interesting to potentially kick the tires with. digging deeper, I found https://www.reddit.com/r/Clojure/comments/bqh0z4/virtual_dom_is_pure_overhead/ with a nice discussion that @yogthos and @thheller had. this is a fairly old thread now - is there any interesting work going on in the space of Svelte's goals?

thheller14:06:55

which now lives in https://github.com/thheller/shadow-experiments and is used by the shadow-cljs UI

thheller14:06:58

no react anywhere 😛

thheller14:06:24

works quite well .. just not much time to work on it

👍 3
phronmophobic14:06:40

I’ve been working on a library called https://github.com/phronmophobic/membrane. Similar to svelte, the ui framework reads your code(via macros) and can figure out how a child component’s properties depend on their parent’s component properties. It’s still experimental, but feels pretty good. Your code ends up being fairly terse. Here’s a simple todo app:

;; Display a single todo item
(defui todo-item [ & {:keys [todo]}]
  (horizontal-layout
   (translate 5 5
              (on
               :mouse-down
               (fn [[mx my]]
                 [[:delete $todo]])
               (delete-X)))
   (translate 10 4
              (basic/checkbox :checked? (:complete? todo)))
   (spacer 10 0)
   (basic/textarea :text (:description todo))))

(comment
  (run-ui #'todo-item {:todo
                       {:complete? false
                        :description "fix me"}}))


(defeffect ::add-todo [$todos next-todo-text]
  (dispatch! :update $todos #(conj % {:description next-todo-text
                                      :complete? false})))

;; Display a list of `todo-item`s stacked vertically
;; Add 5px of spacing between `todo-item`s
(defui todo-list [ & {:keys [todos next-todo-text]}]
  (apply
   vertical-layout
   (horizontal-layout
    (basic/button :text "Add Todo"
                  :on-click (fn []
                              [[::add-todo $todos next-todo-text]
                               [:set $next-todo-text ""]]))
    (translate 10 10
               (basic/textarea :text next-todo-text)))
   (interpose
    (spacer 0 5)
    (for [todo todos]
      (todo-item :todo todo)))))

(comment
  (run-ui #'todo-list {:todos
                       [{:complete? false
                         :description "first"}
                        {:complete? false
                         :description "second"}
                        {:complete? true
                         :description "third"}]}))

Michaël Salihi15:06:09

I wonder if we can toying with CLJS and Svelte with Svelte-preprocess https://github.com/sveltejs/svelte-preprocess

Michaël Salihi15:06:38

I'm sure @thheller is going to find something mindblowing again 🙂

thheller15:06:37

happy to look at other things for inspiration but I have no intention of actually using svelte 😉

👍 3
Michaël Salihi17:06:40

Yes, I remember read you about Svelte on some Clojureverse post.

gerred18:06:52

membrane looks cool. Yeah, I don't have any intention of using it either - I think we're mostly already there with cljs and existing libraries, and by mostly I mean all the way except for getting a satisfying user experience around it, everything tied together - work like membrane and arborist

phronmophobic18:06:11

I think there’s still a huge amount of improvement available in the UI library design space.

gerred13:06:33

Yeah. I'm working on a direct port of tailwind (given another convo) to cljc to start helping improve the availability of this type of tooling.

reefersleep13:06:51

I’ve recently learned that input type=number has some odd behaviour that does not gel well with e.g. Reagent. For example, since 42e3 is a valid js number, you are free to enter that into your input. However, even if e4e2e3e is not a valid js number, you are allowed to put it into your input field. Since it’s not a valid js number, the on-change function that you are normally relying on won’t fire, so you’ll end up with a browser state that has e4e2e3e and an atom state that doesn’t. (That’s my own reasoning, based on what I’ve witnessed.) Is there some general wisdom somewhere about using input type=number regarding such gotchas as the above somewhere on the internet? I tried googling for it, but didn’t find what I was looking for. Specifically, it seems to me that using input type=text instead and rolling your own validation (and whatever else behavior you need) seems to be the more appropriate solution in general, as you’ll be more in control of what happens and how it should look.

reefersleep14:06:25

(I prefer using whatever is provided directly by HTML for a number of reasons, such as A11Y, hand-rolled solutions not covering corner cases that the HTML implementers already took care of, the extra upkeep that comes with rolling your own solution and so on. So I’m kind of sad about my current conclusion.)

orestis14:06:46

Number inputs are tricky also across different browsers and mobile. I remember a recent article that advocated type=text and using a pattern to do things like bringing up the number keyboard on mobile.

chepprey01:06:44

input type=number also takes you to even deeper levels of hell when you need to support multiple locales. Maybe the situation has improved since 3-4 years ago, but back then, we 100% punted on this, and we implemented our own numeric-entry UI. We did this in html/JS and never looked back. (we didn't implement custom mobile-OS keyboards, which I suppose is possible, but we have a html/JS app and use Cordova to run it on multiple mobile OSs)

chepprey01:06:38

The locale problem was something goofy like... say you were in a locale that uses a comma , to be a decimal separator instead of the .

chepprey01:06:48

When you pre-populated an <input type="number" with a number like 1,23 and you were in such a locale, this was fine... BUT after a user manipulates the value and you need to pull it out of the <input, it would get a non-locale copy of the value (like, it'd convert it to 1.23 even though).

chepprey01:06:28

Note: I might have this description exactly backwards... like, maybe it was you had to always SET the value with a non-locale-specific version (like 1.23) but when you would take the value out, then it'd be formatted 1,23 Anyhoo --- it was utter madness. And it was not always consistent across iOS, Android, and Chrome.

chepprey01:06:41

BTW - with our approach, we didn't even use ANY html input box. We just styled up something that looks like a textbox using plain old divs, and then pull up a keypad entry widget (of our own creation) elsewhere on the screen.

reefersleep19:06:29

@UHL84CDTP crikey, that’s some endeavour you went through! I wasn’t aware of the decimal issue, that sounds horrible.

reefersleep19:06:07

It’s too bad that things are not more stable and standardized in the world of HTML. Yet, at least. We can hope for a better future 🙂

reefersleep19:06:17

Thanks for sharing your tale!

Stuart15:06:36

I'mhaving a problem getting a very basic reagent app to work. My deps.edn

{:deps {com.bhauman/figwheel-main {:mvn/version "0.2.8"}
        com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}
        reagent {:mvn/version "1.0.0-alpha2"}}
 :paths ["src" "target" "resources"]}
My demo.cljs.edn
^{:css-dirs ["resources/public/css"]}
{:main todo-demo.main}
My folder structure looks like this:
.                                                                                                   
     ├── demo.cljs.edn                                                                                   
     ├── deps.edn                                                                                        
     ├── resources                                                                                       
     │   └── public                                                                                      
     │       └── index.html                                                                              
     ├── src                                                                                             
     │   └── todo_demo                                                                                   
     │       └── main.cljs   
My main.cljs:
(ns todo-demo.main
  (:require [reagent.core :as r]
            [reagent.dom :as rdom]))

(defn title []
  [:div
   [:p "Hello, World"]])

(defn app []
  [:div
   [title]])

(defn main []
  (rdom/render [app] (js/document.getElementById "app")))
I run it with
$ clj -m figwheel.main -m --build demo --repl
But I can't get it to display Hello World in a div. My index.html:

<html>
  <head>
    <!-- this refers to resources/public/css/style.css -->
    <link href="css/style.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div id="app"></div>
	<!-- this refers to target/public/cljs-out/cruel-main.js -->
    <script src="cljs-out/demo-main.js"></script>
  </body>
</html>
Have I maybe missed what I need to call the main function for it to be called? I can do this at the repl from the docs:
(def app-element (js/document.getElementById "app"))
(set! (.-innerHTML app-element) "Hello, World!")
And I get Hello, World on the page.

bhauman15:06:07

@qmstuart if you open the devtools console in your browser what does it say?

Stuart15:06:00

This is the console output

thheller15:06:41

@qmstuart you are not calling the main fn anywhere. add <script>todo_demo.main.main();</script> in your html

👍 8
Stuart15:06:31

That did it!! Thank you 😄

👍 8
dpsutton15:06:51


<html>
  <head>
    <!-- this refers to resources/public/css/style.css -->
    <link href="css/style.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div id="app"></div>
	<!-- this refers to target/public/cljs-out/cruel-main.js -->
    <script src="cljs-out/cruel-main.js"></script>
  </body>
</html>

bhauman15:06:38

the tutorial doesn’t encapsulate start in a main function

flyboarder16:06:58

Is there a way to read the cljs compiler options during macro expansion?

thheller16:06:40

careful with this though. might get you into trouble with caching.

mengu16:06:42

it looks like versions after 1.10.520 broke IE

mengu16:06:36

the new one spits out a const eb in a and IE 11 does not support that

thheller16:06:09

no CLJS code outputs const anywhere. likely one of your JS dependencies?

mengu16:06:30

@thheller I don't think my dependencies are getting minified depending on my clojurescript version but I'll try to reproduce it in a clean repo

mengu16:06:43

@thheller, here's a repro way:

lein new figwheel repro
lein cljsbuild once min

mengu16:06:56

in the file you'll see function ha(a){const b=[];let c=0;for(const d in a)b[c++]=d;return b}

bhauman17:06:01

@mengu that output needs to be bundled

thheller17:06:19

run it with :pretty-print true :pseudo-names true in your compiler options to see where that is coming from

bhauman17:06:22

actually I take that back

thheller17:06:57

ah wait ... it probably is from the closure library

mengu17:06:00

and when I set the version as 1.10.520, no consts of any kind

thheller17:06:05

so try :language-out :es3 in your compiler options

mengu17:06:38

that worked

mengu17:06:52

looks like I've missed that change in the release notes

mengu17:06:05

apologies for taking your time @thheller & @bhauman

bhauman17:06:50

super easy to miss

mengu17:06:00

thanks again 🙂

dominicm21:06:19

What's my option(s) for REBL (or alike) in ClojureScript? Does the official cognitect REBL work with Cljs?

lilactown23:06:03

I think shadow-cljs inspect is moving towards that

lilactown23:06:35

I think a remote REBL makes a lot of sense. if I ever take a sabbatical it will be one of the projects I try and work on 😄

💯 3
lilactown23:06:28

is there a way to say, “run this at the end of the current tick?”

lilactown23:06:14

I don’t want to use setTimeout/rAF/promises because I want to do the work in the current tick

lilactown23:06:04

ah, actually Promise.resolve might do what I want