Fork me on GitHub
#clojurescript
<
2020-07-31
>
Joseph Hance12:07:53

I'm working on a page with some elements that have an :on-click handler, something like: [:tr {:class "stripe row-normal"             `:style {:font-size "10px"}`            `:id (str "row-" content-id)`           `:key (get record-item :DocumentId)`            `:on-click #(select-row-event %)}` This is working fine but I also want to handle the onmouseover and onmouseout events and I can't figure out how to do this. I'm sure I'm missing something obvious but after trying every combination I can think of (:onmouseover, :on-mouseover, :on-mouse-over, etc.) I can't seem to get the event handler to fire.

Sam Ritchie14:07:10

hey all, cljs question for you... I'm trying to work with BigInt, and finding that I can compare bigints no problem:

cljs.user> (= (js/BigInt 0) (js/BigInt 0))
;; => true

Sam Ritchie14:07:27

but then if I make a protocol...

(defprotocol Cake
  (is-zero? [this]))

(extend-protocol Cake
  js/BigInt
  (is-zero? [x] (= x (js/BigInt 0))))

Sam Ritchie14:07:36

sicmutils.value> (is-zero? (js/BigInt 0))
;; => false

Sam Ritchie14:07:40

I can't get this to return true

Sam Ritchie14:07:17

ah, boom, got it!

Sam Ritchie14:07:25

(let [big-zero (js/BigInt 0)]
  (extend-protocol Cake
    js/BigInt
    (is-zero? [x] (= (.valueOf x) big-zero))))

Sam Ritchie14:07:35

you need (.valueOf x) inside the protocol, apparently

dpsutton14:07:32

there's probably a (.equals x (js/BigInt 0) style that could work.

dpsutton14:07:58

hmm, reading on that page, a BigInt should compare loosely to a number with the same value. 0n == 0.

(extend-type number
  IEquiv
  (-equiv [x o] (identical? x o)))
this is a bit too harsh there then

dpsutton14:07:44

i would expect (== (BigInt 0) 0) to return true then.

Sam Ritchie16:07:23

@dpsutton it does not, unfortunately

dpsutton16:07:10

(js* "~{} == ~{}" (js/BigInt 0) 0) is the best i've got

Sam Ritchie16:07:58

@dpsutton you'd prefer that over (= (.valueOf x) (js/BigInt 0))?

Sam Ritchie16:07:07

which seems to work, but is maybe more mysterious?

dpsutton16:07:27

i didn't see .valueOf on MDN. and its stated that they compare ==

Sam Ritchie16:07:02

yup, that's almost certainly better, then

Sam Ritchie16:07:15

(nullity? [x] (js*  "~{} == ~{}" big-zero x))
(unity? [x] (js*  "~{} == ~{}" big-one x))

Sam Ritchie16:07:17

okay, here we go!

Sam Ritchie16:07:34

I'm caching big-one and big-zero maybe too defensively...

Sam Ritchie16:07:45

thanks for the tips

phronmophobic19:07:48

I think "bubbling" is a good alternative to callbacks. here's some pseudo code for how it would look like with bubbling:

(ns my.generic-components.date)


(defn datepicker [& {:keys [current-date]} ]
  (date-layout
   (for [date (date-range current-data)]
     (on
      :mouse-down
      (fn [_]
        [[::select-date date]])))))

(ns my.specific.ui.order-form )

(defn delivery-date-field [& {:keys [order-form]}]
  (vertical-layout
   (ui/label "Please choose a delivery date:")
   (ui/on
    ::select-date
    (fn [child-handler d]
      (when (time/after? 
             (time/floor d time/day)
             today-date)
        [:mayapp.orders.events/set-order-delivery-date cart-id new-delivery-date]))
    (datepicker :current-date (:myapp.order-form/date order-form)))))

phronmophobic19:07:36

In this example, the ::select-date event bubbles up and can be caught by any parent component. the parent component can then transform that into a new event :myapp.orders.event/set-order-delivery-date

dominicm19:07:22

There's a clojure react wrapper that does this

val_waeselynck20:07:14

@U7RJTCH6J sometimes you want to customize other things than events, e.g sub-parts of the rendering

lilactown20:07:00

bubbling like that could be simply implemented using React Context + Hooks

phronmophobic21:07:29

i've been experimenting with bubbling and liking it, but my implementation circumvents the usual event handling rather than leveraging it.