diff --git a/CHANGELOG.md b/CHANGELOG.md index ace180e..cc9cb8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ **[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)) -- 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) diff --git a/src/reagent/core.cljs b/src/reagent/core.cljs index 6af869b..d5c687b 100644 --- a/src/reagent/core.cljs +++ b/src/reagent/core.cljs @@ -195,8 +195,7 @@ (dom/dom-node this)) (defn merge-props - "Utility function that merges some maps, handling :class and :style - specially, like React's transferPropsTo." + "Utility function that merges some maps, handling :class and :style" ([] (util/merge-props)) ([defaults] (util/merge-props defaults)) ([defaults props] (util/merge-props defaults props)) @@ -210,8 +209,6 @@ [] (batch/flush)) - - ;; Ratom (defn atom diff --git a/src/reagent/impl/template.cljs b/src/reagent/impl/template.cljs index e9fc660..2fc6a21 100644 --- a/src/reagent/impl/template.cljs +++ b/src/reagent/impl/template.cljs @@ -2,7 +2,7 @@ (:require [react :as react] [clojure.string :as string] [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.batching :as batch] [reagent.ratom :as ratom] @@ -22,10 +22,6 @@ ;;; Common utilities -(defn ^boolean named? [x] - (or (keyword? x) - (symbol? x))) - (defn ^boolean hiccup-tag? [x] (or (named? x) (string? x))) @@ -128,19 +124,12 @@ (defn stringify-class [{:keys [class] :as props}] (if (coll? class) - (->> class - (keep (fn [c] - (if c - (if (named? c) - (name c) - c)))) - (string/join " ") - (assoc props :class)) + (assoc props :class (util/stringify-class class)) props)) (defn convert-props [props id-class] (let [props (-> props - stringify-class + util/stringify-class (set-id-class id-class))] (if ($ id-class :custom) (convert-custom-prop-value props) diff --git a/src/reagent/impl/util.cljs b/src/reagent/impl/util.cljs index 97fe805..e9f7a8a 100644 --- a/src/reagent/impl/util.cljs +++ b/src/reagent/impl/util.cljs @@ -107,8 +107,27 @@ (defn make-partial-fn [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] - (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)] (str c1 " " c2)))] (if (nil? class) @@ -125,16 +144,16 @@ (defn merge-props ([] nil) - ([p] p) + ([p] (stringify-class p)) ([p1 p2] (if (nil? p1) - p2 + (stringify-class p2) (do (assert (map? p1) (str "Property must be a map, not " (pr-str p1))) (merge p1 (merge-style p1 (merge-class p1 p2)))))) ([p1 p2 & ps] - (apply merge-props (merge-props p1 p2) ps))) + (reduce merge-props (merge-props p1 p2) ps))) (def ^:dynamic *always-update* false) diff --git a/test/reagent/impl/util_test.cljs b/test/reagent/impl/util_test.cljs index 81dfdea..f6a433d 100644 --- a/test/reagent/impl/util_test.cljs +++ b/test/reagent/impl/util_test.cljs @@ -3,16 +3,19 @@ [reagent.impl.util :as util])) (deftest merge-props-test - (testing "It handles no arguments" + (testing "no arguments" (is (nil? (util/merge-props)))) - (testing "It handles one argument" + + (testing "one argument" (is (nil? (util/merge-props nil))) (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"} (util/merge-props {:disabled true :style {:flex 1} :class "foo"} {:disabled false :style {:flex-direction "row"} :class "bar"})))) - (testing "It handles n arguments" + + (testing "n arguments" (is (= {:disabled false :checked true :style {:align-items "flex-end" @@ -31,4 +34,11 @@ {:disabled false :checked true :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"]})))))