mirror of https://github.com/status-im/reagent.git
Add class-names utility function
This commit is contained in:
parent
18143e6e97
commit
f7ca1ff8ff
|
@ -8,6 +8,8 @@
|
|||
- Create React Component without `create-react-class` ([#416](https://github.com/reagent-project/reagent/issues/416))
|
||||
- Allow any number of arguments for `reagent.core/merge-props` and
|
||||
ensure `:class` is merged correctly when it is defined as collection. ([#412](https://github.com/reagent-project/reagent/issues/412))
|
||||
- Add `reagent.core/class-names` utility functions which can be used
|
||||
to normalize and combine `:class` values (similar to `classnames` JS library)
|
||||
|
||||
## 0.8.1 (2018-05-15)
|
||||
|
||||
|
|
|
@ -194,8 +194,23 @@
|
|||
[this]
|
||||
(dom/dom-node this))
|
||||
|
||||
(defn class-names
|
||||
"Function which normalizes and combines class values to a string
|
||||
|
||||
Reagent allows classes to be defined as:
|
||||
- Strings
|
||||
- Named objects (Symbols or Keywords)
|
||||
- Collections of previous types"
|
||||
([])
|
||||
([class] (util/class-names class))
|
||||
([class1 class2] (util/class-names class1 class2))
|
||||
([class1 class2 & others] (apply util/class-names class1 class2 others)))
|
||||
|
||||
(defn merge-props
|
||||
"Utility function that merges some maps, handling :class and :style"
|
||||
"Utility function that merges some maps, handling `:class` and `:style`.
|
||||
|
||||
The :class value is always normalized (using `class-names`) even if no
|
||||
merging is done."
|
||||
([] (util/merge-props))
|
||||
([defaults] (util/merge-props defaults))
|
||||
([defaults props] (util/merge-props defaults props))
|
||||
|
|
|
@ -117,19 +117,12 @@
|
|||
|
||||
;; Merge classes
|
||||
class
|
||||
(assoc :class (let [old-class (:class props)]
|
||||
(if (nil? old-class) class (str class " " (if (named? old-class)
|
||||
(name old-class)
|
||||
old-class))))))))
|
||||
|
||||
(defn stringify-class [{:keys [class] :as props}]
|
||||
(if (coll? class)
|
||||
(assoc props :class (util/stringify-class class))
|
||||
props))
|
||||
(assoc :class (util/class-names class (:class props))))))
|
||||
|
||||
(defn convert-props [props id-class]
|
||||
(let [props (-> props
|
||||
util/stringify-class
|
||||
(let [class (:class props)
|
||||
props (-> props
|
||||
(cond-> class (assoc :class (util/class-names class)))
|
||||
(set-id-class id-class))]
|
||||
(if ($ id-class :custom)
|
||||
(convert-custom-prop-value props)
|
||||
|
|
|
@ -111,28 +111,34 @@
|
|||
(or (keyword? x)
|
||||
(symbol? x)))
|
||||
|
||||
(defn stringify-class [props]
|
||||
(let [class (:class props)]
|
||||
(if (coll? class)
|
||||
(->> class
|
||||
(keep (fn [c]
|
||||
(if c
|
||||
(if (named? c)
|
||||
(name c)
|
||||
c))))
|
||||
(string/join " ")
|
||||
(assoc props :class))
|
||||
props)))
|
||||
(defn class-names
|
||||
([])
|
||||
([class]
|
||||
(if (coll? class)
|
||||
(let [classes (keep (fn [c]
|
||||
(if c
|
||||
(if (named? c)
|
||||
(name c)
|
||||
c)))
|
||||
class)]
|
||||
(if (seq classes)
|
||||
(string/join " " classes)))
|
||||
(if (named? class)
|
||||
(name class)
|
||||
class)))
|
||||
([a b]
|
||||
(if a
|
||||
(if b
|
||||
(str (class-names a) " " (class-names b))
|
||||
(class-names a))
|
||||
(class-names b)))
|
||||
([a b & rst]
|
||||
(reduce class-names
|
||||
(class-names a b)
|
||||
rst)))
|
||||
|
||||
(defn- merge-class [p1 p2]
|
||||
(let [p1 (stringify-class p1)
|
||||
p2 (stringify-class p2)
|
||||
class (when-let [c1 (:class p1)]
|
||||
(when-let [c2 (:class p2)]
|
||||
(str c1 " " c2)))]
|
||||
(if (nil? class)
|
||||
p2
|
||||
(assoc p2 :class class))))
|
||||
(assoc p2 :class (class-names (:class p1) (:class p2))))
|
||||
|
||||
(defn- merge-style [p1 p2]
|
||||
(let [style (when-let [s1 (:style p1)]
|
||||
|
@ -144,10 +150,16 @@
|
|||
|
||||
(defn merge-props
|
||||
([] nil)
|
||||
([p] (stringify-class p))
|
||||
;; Normalize :class even if there are no merging
|
||||
([p]
|
||||
(if-let [c (:class p)]
|
||||
(assoc p :class (class-names c))
|
||||
p))
|
||||
([p1 p2]
|
||||
(if (nil? p1)
|
||||
(stringify-class p2)
|
||||
(if-let [c (:class p2)]
|
||||
(assoc p2 :class (class-names c))
|
||||
p2)
|
||||
(do
|
||||
(assert (map? p1)
|
||||
(str "Property must be a map, not " (pr-str p1)))
|
||||
|
|
|
@ -2,6 +2,33 @@
|
|||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[reagent.impl.util :as util]))
|
||||
|
||||
(deftest class-names-test
|
||||
(is (= nil
|
||||
(util/class-names)
|
||||
(util/class-names nil)
|
||||
(util/class-names [])
|
||||
(util/class-names nil [])))
|
||||
(is (= "a b"
|
||||
(util/class-names ["a" "b"])
|
||||
(util/class-names "a" "b")))
|
||||
(is (= "a"
|
||||
(util/class-names :a)
|
||||
(util/class-names [:a])
|
||||
(util/class-names nil "a")
|
||||
(util/class-names [] nil "a")))
|
||||
(is (= "a b c d"
|
||||
(util/class-names "a" "b" nil ["c" "d"]))))
|
||||
|
||||
; (simple-benchmark []
|
||||
; (do (util/class-names "a" "b")
|
||||
; (util/class-names nil "a")
|
||||
; (util/class-names "a" nil))
|
||||
; 10000)
|
||||
|
||||
; (simple-benchmark []
|
||||
; (util/class-names "a" "b" nil "c" "d")
|
||||
; 10000)
|
||||
|
||||
(deftest merge-props-test
|
||||
(testing "no arguments"
|
||||
(is (nil? (util/merge-props))))
|
||||
|
@ -36,9 +63,9 @@
|
|||
:class "quux"}
|
||||
nil))))
|
||||
|
||||
(testing ":class collection"
|
||||
(testing ":class"
|
||||
(is (= {:class "foo bar baz quux"}
|
||||
(util/merge-props {:class "foo bar"}
|
||||
{:class ["baz" "quux"]})
|
||||
(util/merge-props {} {:class ["foo" "bar" "baz" "quux"]})
|
||||
(util/merge-props nil {:class ["foo" "bar" "baz" "quux"]})
|
||||
(util/merge-props {:class ["foo" "bar" "baz" "quux"]})))))
|
||||
|
|
Loading…
Reference in New Issue