2015-12-17 16:43:58 +02:00
|
|
|
|
(ns uxbox.ui.mixins
|
2015-06-18 19:35:50 +02:00
|
|
|
|
(:refer-clojure :exclude [derive])
|
|
|
|
|
(:require [rum.core :as rum]
|
|
|
|
|
[cats.labs.lens :as l]
|
|
|
|
|
[goog.dom.forms :as gforms]))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;; Cursored & Lenses
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(defn- cursored-key
|
|
|
|
|
[state]
|
|
|
|
|
(str ":rum/cursored-" (:rum/id state)))
|
|
|
|
|
|
|
|
|
|
(def ^:private
|
2015-12-15 15:41:11 +02:00
|
|
|
|
deref-xform
|
|
|
|
|
(map (fn [x] (if (satisfies? IDeref x) @x x))))
|
2015-06-18 19:35:50 +02:00
|
|
|
|
|
|
|
|
|
(defn- deref-props
|
|
|
|
|
[data]
|
2015-12-15 15:41:11 +02:00
|
|
|
|
(into [] deref-xform data))
|
2015-06-18 19:35:50 +02:00
|
|
|
|
|
|
|
|
|
(defn- cursored-did-mount
|
|
|
|
|
[state]
|
2015-12-15 15:41:11 +02:00
|
|
|
|
(doseq [v (:rum/props state)
|
2015-06-18 19:35:50 +02:00
|
|
|
|
:when (satisfies? IWatchable v)]
|
|
|
|
|
(add-watch v (cursored-key state)
|
|
|
|
|
(fn [_ _ _ _]
|
|
|
|
|
(rum/request-render (:rum/react-component state)))))
|
|
|
|
|
state)
|
|
|
|
|
|
|
|
|
|
(defn- cursored-will-umount
|
|
|
|
|
[state]
|
2015-12-15 15:49:19 +02:00
|
|
|
|
(doseq [v (:rum/props state)
|
2015-06-18 19:35:50 +02:00
|
|
|
|
:when (satisfies? IWatchable v)]
|
|
|
|
|
(remove-watch v (cursored-key state)))
|
|
|
|
|
state)
|
|
|
|
|
|
|
|
|
|
(defn- cursored-transfer-state
|
|
|
|
|
[old new]
|
|
|
|
|
(assoc new :rum/old-props (:rum/old-props old)))
|
|
|
|
|
|
|
|
|
|
(defn- cursored-should-update
|
|
|
|
|
[old-state new-state]
|
|
|
|
|
(not= (:rum/old-props old-state) (deref-props (:rum/props new-state))))
|
|
|
|
|
|
|
|
|
|
(defn- cursored-wrap-render
|
|
|
|
|
[render-fn]
|
|
|
|
|
(fn [state]
|
|
|
|
|
(let [[dom next-state] (render-fn state)]
|
|
|
|
|
[dom (assoc next-state :rum/old-props (deref-props (:rum/props state)))])))
|
|
|
|
|
|
|
|
|
|
(def cursored
|
|
|
|
|
"A cursor like mixin that works with
|
|
|
|
|
the `component` sugar syntax and lenses
|
|
|
|
|
from the cats library."
|
|
|
|
|
{:did-mount cursored-did-mount
|
|
|
|
|
:will-unmount cursored-will-umount
|
|
|
|
|
:transfer-state cursored-transfer-state
|
|
|
|
|
:should-update cursored-should-update
|
|
|
|
|
:wrap-render cursored-wrap-render})
|
|
|
|
|
|
2015-12-13 22:57:14 +02:00
|
|
|
|
(defn local
|
|
|
|
|
"Adds an atom to component’s state that can be used as local state.
|
|
|
|
|
Atom is stored under key `:rum/local`.
|
|
|
|
|
Component will be automatically re-rendered if atom’s value changes"
|
|
|
|
|
([]
|
|
|
|
|
(local {} :rum/local))
|
|
|
|
|
([initial]
|
|
|
|
|
(local initial :rum/local))
|
|
|
|
|
([initial key]
|
|
|
|
|
{:transfer-state
|
|
|
|
|
(fn [old new]
|
|
|
|
|
(assoc new key (old key)))
|
|
|
|
|
:will-mount
|
|
|
|
|
(fn [state]
|
|
|
|
|
(let [local-state (atom initial)
|
|
|
|
|
component (:rum/react-component state)]
|
|
|
|
|
(add-watch local-state key
|
|
|
|
|
(fn [_ _ _ _]
|
|
|
|
|
(rum/request-render component)))
|
|
|
|
|
(assoc state key local-state)))
|
|
|
|
|
}))
|
|
|
|
|
|
2015-12-17 15:44:05 +02:00
|
|
|
|
|
|
|
|
|
(def static
|
|
|
|
|
{:should-update
|
|
|
|
|
(fn [old-state new-state]
|
|
|
|
|
(not= (:rum/props old-state) (:rum/props new-state)))})
|