| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 | 
							- (ns frontend.rum
 
-   "Utility fns for rum"
 
-   (:require [cljs-bean.core :as bean]
 
-             [clojure.set :as set]
 
-             [clojure.string :as string]
 
-             [clojure.walk :as w]
 
-             [daiquiri.interpreter :as interpreter]
 
-             [frontend.hooks :as hooks]
 
-             [rum.core :refer [use-state] :as rum]))
 
- ;; copy from https://github.com/priornix/antizer/blob/35ba264cf48b84e6597743e28b3570d8aa473e74/src/antizer/core.cljs
 
- (defn kebab-case->camel-case
 
-   "Converts from kebab case to camel case, eg: on-click to onClick"
 
-   [input]
 
-   (string/replace input #"-([a-z])" (fn [[_ c]] (string/upper-case c))))
 
- (defn map-keys->camel-case
 
-   "Stringifys all the keys of a cljs hashmap and converts them
 
-    from kebab case to camel case. If :html-props option is specified,
 
-    then rename the html properties values to their dom equivalent
 
-    before conversion"
 
-   [data & {:keys [html-props]}]
 
-   (let [convert-to-camel (fn [[key value]]
 
-                            [(kebab-case->camel-case (name key)) value])]
 
-     (w/postwalk (fn [x]
 
-                   (if (map? x)
 
-                     (let [new-map (if html-props
 
-                                     (set/rename-keys x {:class :className :for :htmlFor})
 
-                                     x)]
 
-                       (into {} (map convert-to-camel new-map)))
 
-                     x))
 
-                 data)))
 
- ;; TODO: Replace this with rum's built in rum.core/adapt-class
 
- ;; adapted from https://github.com/tonsky/rum/issues/20
 
- (defn adapt-class
 
-   ([react-class]
 
-    (adapt-class react-class false))
 
-   ([react-class skip-opts-transform?]
 
-    (fn [& args]
 
-      (let [[opts children] (if (map? (first args))
 
-                              [(first args) (rest args)]
 
-                              [{} args])
 
-            type# (first children)
 
-           ;; we have to make sure to check if the children is sequential
 
-           ;; as a list can be returned, eg: from a (for)
 
-            new-children (if (sequential? type#)
 
-                           (let [result (interpreter/interpret children)]
 
-                             (if (sequential? result)
 
-                               result
 
-                               [result]))
 
-                           children)
 
-           ;; convert any options key value to a react element, if
 
-           ;; a valid html element tag is used, using sablono
 
-            vector->react-elems (fn [[key val]]
 
-                                  (if (sequential? val)
 
-                                    [key (interpreter/interpret val)]
 
-                                    [key val]))
 
-            new-options (into {}
 
-                              (if skip-opts-transform?
 
-                                opts
 
-                                (map vector->react-elems opts)))]
 
-        (apply js/React.createElement react-class
 
-         ;; sablono html-to-dom-attrs does not work for nested hashmaps
 
-               (bean/->js (map-keys->camel-case new-options :html-props true))
 
-               new-children)))))
 
- (defn use-atom-fn
 
-   [a getter-fn setter-fn]
 
-   (let [[val set-val] (use-state (getter-fn @a))]
 
-     (hooks/use-effect!
 
-      (fn []
 
-        (let [id (str (random-uuid))]
 
-          (add-watch a id (fn [_ _ prev-state next-state]
 
-                            (let [prev-value (getter-fn prev-state)
 
-                                  next-value (getter-fn next-state)]
 
-                              (when-not (= prev-value next-value)
 
-                                (set-val next-value)))))
 
-          #(remove-watch a id)))
 
-      [])
 
-     [val #(swap! a setter-fn %)]))
 
- (defn use-atom
 
-   "(use-atom my-atom)"
 
-   [a]
 
-   (use-atom-fn a identity (fn [_ v] v)))
 
- (defn use-atom-in
 
-   [a ks]
 
-   (let [ks (if (keyword? ks) [ks] ks)]
 
-     (use-atom-fn a #(get-in % ks) (fn [a' v] (assoc-in a' ks v)))))
 
- (defn use-mounted
 
-   []
 
-   (let [*mounted (rum/use-ref false)]
 
-     (hooks/use-effect!
 
-      (fn []
 
-        (rum/set-ref! *mounted true)
 
-        #(rum/set-ref! *mounted false))
 
-      [])
 
-     #(rum/deref *mounted)))
 
- (defn use-bounding-client-rect
 
-   "Returns the bounding client rect for a given dom node
 
-    You can manually change the tick value, if you want to force refresh the value, you can manually change the tick value"
 
-   ([] (use-bounding-client-rect nil))
 
-   ([tick]
 
-    (let [[ref set-ref] (rum/use-state nil)
 
-          [rect set-rect] (rum/use-state nil)]
 
-      (hooks/use-effect!
 
-       (if ref
 
-         (fn []
 
-           (let [update-rect #(set-rect (. ref getBoundingClientRect))
 
-                 updator (fn [entries]
 
-                           (when (.-contentRect (first (js->clj entries))) (update-rect)))
 
-                 observer (js/ResizeObserver. updator)]
 
-             (update-rect)
 
-             (.observe observer ref)
 
-             #(.disconnect observer)))
 
-         #())
 
-       [ref tick])
 
-      [set-ref rect])))
 
- (defn ->breakpoint
 
-   "Converts a number to a breakpoint string
 
-    Values come from https://tailwindcss.com/docs/responsive-design"
 
-   [size]
 
-   (cond
 
-     (nil? size) :md
 
-     (<= size 640) :sm
 
-     (<= size 768) :md
 
-     (<= size 1024) :lg
 
-     (<= size 1280) :xl
 
-     (<= size 1536) :xl
 
-     :else :2xl))
 
- (defn use-breakpoint
 
-   "Returns the current breakpoint
 
-    You can manually change the tick value, if you want to force refresh the value, you can manually change the tick value"
 
-   ([] (use-breakpoint nil))
 
-   ([tick]
 
-    (let [[ref rect] (use-bounding-client-rect tick)
 
-          bp (->breakpoint (when (some? rect) (.-width rect)))]
 
-      [ref bp])))
 
- (defonce *key->atom (atom {}))
 
- (defn cached-derived-atom
 
-   "Make sure to return the same atom if `key` is the same."
 
-   [ref key f]
 
-   (or (get @*key->atom key)
 
-       (let [a (rum/derived-atom [ref] key f)]
 
-         (swap! *key->atom assoc key a)
 
-         a)))
 
 
  |