diff --git a/src/reagent/core.cljs b/src/reagent/core.cljs index 79c6e9e..f59a32d 100644 --- a/src/reagent/core.cljs +++ b/src/reagent/core.cljs @@ -43,6 +43,9 @@ which is equivalent to [form] (tmpl/as-element form)) +(defn adapt-react-class [c] + (tmpl/adapt-react-class c)) + (defn render "Render a Reagent component into the DOM. The first argument may be either a vector (using Reagent's Hiccup syntax), or a React element. The second argument should be a DOM node. diff --git a/src/reagent/impl/template.cljs b/src/reagent/impl/template.cljs index 9e057b9..cb6ff1d 100644 --- a/src/reagent/impl/template.cljs +++ b/src/reagent/impl/template.cljs @@ -13,6 +13,8 @@ from a tag name."} re-tag #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?") +(deftype NativeWrapper [comp]) + ;;; Common utilities @@ -26,7 +28,8 @@ (defn valid-tag? [x] (or (hiccup-tag? x) - (ifn? x))) + (ifn? x) + (instance? NativeWrapper x))) ;;; Props conversion @@ -186,20 +189,26 @@ (.' js/React createElement c jsprops))) +(defn adapt-react-class [c] + (NativeWrapper. #js{:name c + :id nil + :class nil})) + (def tag-name-cache #js{}) (defn cached-parse [x] - (if-some [s (obj-get tag-name-cache (name x))] - s - (aset tag-name-cache (name x) (parse-tag x)))) - + (if (hiccup-tag? x) + (if-some [s (obj-get tag-name-cache (name x))] + s + (aset tag-name-cache (name x) (parse-tag x))) + (when (instance? NativeWrapper x) + (.-comp x)))) (declare as-element) (defn native-element [tag argv] - (when (hiccup-tag? tag) - (let [parsed (cached-parse tag) - comp (.' parsed :name)] + (when-let [parsed (cached-parse tag)] + (let [comp (.' parsed :name)] (let [props (nth argv 1 nil) hasprops (or (nil? props) (map? props)) jsprops (convert-props (if hasprops props) parsed) diff --git a/test/testreagent.cljs b/test/testreagent.cljs index 8262012..35906eb 100644 --- a/test/testreagent.cljs +++ b/test/testreagent.cljs @@ -2,6 +2,7 @@ (:require [cljs.test :as t :refer-macros [is deftest testing]] [reagent.ratom :as rv :refer-macros [reaction]] [reagent.debug :refer-macros [dbg println log]] + [reagent.interop :refer-macros [.' .!]] [reagent.core :as reagent :refer [atom]])) (defn running [] (rv/running)) @@ -436,3 +437,37 @@ (is (= (rstr (ae [:div [:div "foo"]])) (rstr (ae [:div (ce "div" nil "foo")])))))) +(def ndiv (.' js/React + createClass + #js{:render + (fn [] + (this-as + this + (reagent/create-element + "div" #js{:className (.' this :props.className)} + (.' this :props.children))))})) + +(deftest test-adapt-class + (let [d1 (reagent/adapt-react-class ndiv) + d2 (reagent/adapt-react-class "div")] + (is (= (rstr [:div]) + (rstr [d1]))) + (is (= (rstr [:div "a"]) + (rstr [d1 "a"]))) + (is (= (rstr [:div "a" "b"]) + (rstr [d1 "a" "b"]))) + (is (= (rstr [:div.foo "a"]) + (rstr [d1 {:class "foo"} "a"]))) + (is (= (rstr [:div "a" "b" [:div "c"]]) + (rstr [d1 "a" "b" [:div "c"]]))) + + (is (= (rstr [:div]) + (rstr [d2]))) + (is (= (rstr [:div "a"]) + (rstr [d2 "a"]))) + (is (= (rstr [:div "a" "b"]) + (rstr [d2 "a" "b"]))) + (is (= (rstr [:div.foo "a"]) + (rstr [d2 {:class "foo"} "a"]))) + (is (= (rstr [:div "a" "b" [:div "c"]]) + (rstr [d2 "a" "b" [:div "c"]])))))