0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-24 07:29:08 -05:00
penpot/frontend/uxbox/ui/mixins.cljs
2016-01-03 18:44:57 +02:00

92 lines
2.5 KiB
Clojure
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(ns uxbox.ui.mixins
(: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
deref-xform
(map (fn [x] (if (satisfies? IDeref x) @x x))))
(defn- deref-props
[data]
(into [] deref-xform data))
(defn- cursored-did-mount
[state]
(let [key (gensym "foobar")]
(doseq [v (:rum/props state)
:when (satisfies? IWatchable v)]
(add-watch v key
(fn [_ _ _ _]
(rum/request-render (:rum/react-component state)))))
(assoc state ::key key)))
(defn- cursored-will-unmount
[state]
(let [key (::key state)]
(doseq [v (:rum/props state)
:when (satisfies? IWatchable v)]
(remove-watch v key))
(dissoc state ::key)))
(defn- cursored-transfer-state
[old new]
(assoc new
:rum/old-props (:rum/old-props old)
::key (::key 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
{:transfer-state cursored-transfer-state
:should-update cursored-should-update
:wrap-render cursored-wrap-render})
(def cursored-watch
{:did-mount cursored-did-mount
:will-unmount cursored-will-unmount})
(defn local
"Adds an atom to components state that can be used as local state.
Atom is stored under key `:rum/local`.
Component will be automatically re-rendered if atoms 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)))
}))
(def static
{:should-update
(fn [old-state new-state]
(not= (:rum/props old-state) (:rum/props new-state)))})