diff --git a/src/reagent/core.cljs b/src/reagent/core.cljs index b465109..344bb3d 100644 --- a/src/reagent/core.cljs +++ b/src/reagent/core.cljs @@ -195,10 +195,12 @@ (dom/dom-node this)) (defn merge-props - "Utility function that merges two maps, handling :class and :style + "Utility function that merges some maps, handling :class and :style specially, like React's transferPropsTo." - [defaults props] - (util/merge-props defaults props)) + ([] (util/merge-props)) + ([defaults] (util/merge-props defaults)) + ([defaults props] (util/merge-props defaults props)) + ([defaults props & others] (apply util/merge-props (concat [defaults props] others)))) (defn flush "Render dirty components immediately to the DOM. diff --git a/src/reagent/impl/util.cljs b/src/reagent/impl/util.cljs index 6fabd93..23a14a8 100644 --- a/src/reagent/impl/util.cljs +++ b/src/reagent/impl/util.cljs @@ -123,14 +123,18 @@ p2 (assoc p2 :style style)))) -(defn merge-props [p1 p2] - (if (nil? p1) - p2 - (do - (assert (map? p1) - (str "Property must be a map, not " (pr-str p1))) - (merge-style p1 (merge-class p1 (merge p1 p2)))))) - +(defn merge-props + ([] nil) + ([p] p) + ([p1 p2] + (if (nil? p1) + 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 (cons (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 new file mode 100644 index 0000000..81dfdea --- /dev/null +++ b/test/reagent/impl/util_test.cljs @@ -0,0 +1,34 @@ +(ns reagent.impl.util-test + (:require [clojure.test :refer [deftest is testing]] + [reagent.impl.util :as util])) + +(deftest merge-props-test + (testing "It handles no arguments" + (is (nil? (util/merge-props)))) + (testing "It handles one argument" + (is (nil? (util/merge-props nil))) + (is (= {:foo :bar} (util/merge-props {:foo :bar})))) + (testing "It handles 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" + (is (= {:disabled false + :checked true + :style {:align-items "flex-end" + :justify-content "center"} + :class "foo bar baz quux"} + (util/merge-props {:disabled false + :checked false + :style {:align-items "flex-end"} + :class "foo"} + {:disabled false + :checked false + :class "bar"} + {:disabled true + :style {:justify-content "center"} + :class "baz"} + {:disabled false + :checked true + :class "quux"} + nil))))) diff --git a/test/reagenttest/runtests.cljs b/test/reagenttest/runtests.cljs index b32d68a..24c108f 100644 --- a/test/reagenttest/runtests.cljs +++ b/test/reagenttest/runtests.cljs @@ -8,6 +8,7 @@ [reagenttest.testwithlet] [reagenttest.testwrap] [reagent.impl.template-test] + [reagent.impl.util-test] [cljs.test :as test] [doo.runner :as doo :include-macros true] [reagent.core :as r]