Fix :class collection with merge-props

This commit is contained in:
Juho Teperi 2018-12-31 11:04:50 +02:00
parent 364e19191e
commit 18143e6e97
5 changed files with 45 additions and 28 deletions

View File

@ -5,7 +5,9 @@
**[compare](https://github.com/reagent-project/reagent/compare/v0.8.1...master)** **[compare](https://github.com/reagent-project/reagent/compare/v0.8.1...master)**
- Fix using metadata to set React key with Fragment shortcut (`:<>`) ([#401](https://github.com/reagent-project/reagent/issues/401)) - Fix using metadata to set React key with Fragment shortcut (`:<>`) ([#401](https://github.com/reagent-project/reagent/issues/401))
- Create React Component without `create-react-class` - 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))
## 0.8.1 (2018-05-15) ## 0.8.1 (2018-05-15)

View File

@ -195,8 +195,7 @@
(dom/dom-node this)) (dom/dom-node this))
(defn merge-props (defn merge-props
"Utility function that merges some maps, handling :class and :style "Utility function that merges some maps, handling :class and :style"
specially, like React's transferPropsTo."
([] (util/merge-props)) ([] (util/merge-props))
([defaults] (util/merge-props defaults)) ([defaults] (util/merge-props defaults))
([defaults props] (util/merge-props defaults props)) ([defaults props] (util/merge-props defaults props))
@ -210,8 +209,6 @@
[] []
(batch/flush)) (batch/flush))
;; Ratom ;; Ratom
(defn atom (defn atom

View File

@ -2,7 +2,7 @@
(:require [react :as react] (:require [react :as react]
[clojure.string :as string] [clojure.string :as string]
[clojure.walk :refer [prewalk]] [clojure.walk :refer [prewalk]]
[reagent.impl.util :as util :refer [is-client]] [reagent.impl.util :as util :refer [is-client named?]]
[reagent.impl.component :as comp] [reagent.impl.component :as comp]
[reagent.impl.batching :as batch] [reagent.impl.batching :as batch]
[reagent.ratom :as ratom] [reagent.ratom :as ratom]
@ -22,10 +22,6 @@
;;; Common utilities ;;; Common utilities
(defn ^boolean named? [x]
(or (keyword? x)
(symbol? x)))
(defn ^boolean hiccup-tag? [x] (defn ^boolean hiccup-tag? [x]
(or (named? x) (or (named? x)
(string? x))) (string? x)))
@ -128,19 +124,12 @@
(defn stringify-class [{:keys [class] :as props}] (defn stringify-class [{:keys [class] :as props}]
(if (coll? class) (if (coll? class)
(->> class (assoc props :class (util/stringify-class class))
(keep (fn [c]
(if c
(if (named? c)
(name c)
c))))
(string/join " ")
(assoc props :class))
props)) props))
(defn convert-props [props id-class] (defn convert-props [props id-class]
(let [props (-> props (let [props (-> props
stringify-class util/stringify-class
(set-id-class id-class))] (set-id-class id-class))]
(if ($ id-class :custom) (if ($ id-class :custom)
(convert-custom-prop-value props) (convert-custom-prop-value props)

View File

@ -107,8 +107,27 @@
(defn make-partial-fn [f args] (defn make-partial-fn [f args]
(->PartialFn (apply partial f args) f args)) (->PartialFn (apply partial f args) f args))
(defn ^boolean named? [x]
(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- merge-class [p1 p2] (defn- merge-class [p1 p2]
(let [class (when-let [c1 (:class p1)] (let [p1 (stringify-class p1)
p2 (stringify-class p2)
class (when-let [c1 (:class p1)]
(when-let [c2 (:class p2)] (when-let [c2 (:class p2)]
(str c1 " " c2)))] (str c1 " " c2)))]
(if (nil? class) (if (nil? class)
@ -125,16 +144,16 @@
(defn merge-props (defn merge-props
([] nil) ([] nil)
([p] p) ([p] (stringify-class p))
([p1 p2] ([p1 p2]
(if (nil? p1) (if (nil? p1)
p2 (stringify-class p2)
(do (do
(assert (map? p1) (assert (map? p1)
(str "Property must be a map, not " (pr-str p1))) (str "Property must be a map, not " (pr-str p1)))
(merge p1 (merge-style p1 (merge-class p1 p2)))))) (merge p1 (merge-style p1 (merge-class p1 p2))))))
([p1 p2 & ps] ([p1 p2 & ps]
(apply merge-props (merge-props p1 p2) ps))) (reduce merge-props (merge-props p1 p2) ps)))
(def ^:dynamic *always-update* false) (def ^:dynamic *always-update* false)

View File

@ -3,16 +3,19 @@
[reagent.impl.util :as util])) [reagent.impl.util :as util]))
(deftest merge-props-test (deftest merge-props-test
(testing "It handles no arguments" (testing "no arguments"
(is (nil? (util/merge-props)))) (is (nil? (util/merge-props))))
(testing "It handles one argument"
(testing "one argument"
(is (nil? (util/merge-props nil))) (is (nil? (util/merge-props nil)))
(is (= {:foo :bar} (util/merge-props {:foo :bar})))) (is (= {:foo :bar} (util/merge-props {:foo :bar}))))
(testing "It handles two arguments"
(testing "two arguments"
(is (= {:disabled false :style {:flex 1 :flex-direction "row"} :class "foo bar"} (is (= {:disabled false :style {:flex 1 :flex-direction "row"} :class "foo bar"}
(util/merge-props {:disabled true :style {:flex 1} :class "foo"} (util/merge-props {:disabled true :style {:flex 1} :class "foo"}
{:disabled false :style {:flex-direction "row"} :class "bar"})))) {:disabled false :style {:flex-direction "row"} :class "bar"}))))
(testing "It handles n arguments"
(testing "n arguments"
(is (= {:disabled false (is (= {:disabled false
:checked true :checked true
:style {:align-items "flex-end" :style {:align-items "flex-end"
@ -31,4 +34,11 @@
{:disabled false {:disabled false
:checked true :checked true
:class "quux"} :class "quux"}
nil))))) nil))))
(testing ":class collection"
(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 {:class ["foo" "bar" "baz" "quux"]})))))