Implement :<> hiccup tag for fragments

Fixes #319
This commit is contained in:
Juho Teperi 2018-03-12 13:53:48 +02:00
parent 1e19d31be8
commit 87b61475e2
2 changed files with 49 additions and 3 deletions

View File

@ -10,6 +10,8 @@
[reagent.debug :refer-macros [dbg prn println log dev?
warn warn-unless]]))
(declare as-element)
;; From Weavejester's Hiccup, via pump:
(def ^{:doc "Regular expression that parses a CSS-style id and class
from a tag name."}
@ -342,6 +344,15 @@
($! jsprops :key key))
(react/createElement c jsprops)))
(defn fragment-element [argv]
(let [props (nth argv 1 nil)
hasprops (or (nil? props) (map? props))
jsprops (convert-prop-value (if hasprops props))
first-child (+ 1 (if hasprops 1 0))]
(when-some [key (key-from-vec argv)]
(oset jsprops "key" key))
(make-element argv react/Fragment jsprops first-child)))
(defn adapt-react-class
([c {:keys [synthetic-input]}]
(let [on-update (:on-update synthetic-input)
@ -383,8 +394,6 @@
s
(aset tag-name-cache x (parse-tag x))))
(declare as-element)
(defn native-element [parsed argv first]
(let [comp ($ parsed :name)
synthetic-input ($ parsed :syntheticInput)]
@ -429,6 +438,9 @@
(let [tag (nth v 0 nil)]
(assert (valid-tag? tag) (hiccup-err v "Invalid Hiccup form"))
(cond
(keyword-identical? :<> tag)
(fragment-element v)
(hiccup-tag? tag)
(let [n (name tag)
pos (.indexOf n ">")]

View File

@ -252,7 +252,7 @@
(is (= 2 @ran)))))
(defn as-string [comp]
(server/render-to-string comp))
(server/render-to-static-markup comp))
(deftest to-string-test []
(let [comp (fn [props]
@ -1125,3 +1125,37 @@
(fn [c div]
(is (= "parent,child,bar"
(.-innerText div))))))
(deftest test-fragments
(when (>= (js/parseInt react/version) 16)
(testing "Fragment as array"
(let [comp (fn []
#js [(r/as-element [:div "hello"])
(r/as-element [:div "world"])])]
(is (= "<div>hello</div><div>world</div>"
(as-string [comp])))))
(testing "Fragment element, :<>"
(let [comp (fn []
[:<>
[:div "hello"]
[:div "world"]
[:div "foo"] ])]
(is (= "<div>hello</div><div>world</div><div>foo</div>"
(as-string [comp])))))
(testing "Fragment key"
;; This would cause React warning if both fragements didn't have key set
(let [comp (fn []
[:div
(list
[:<>
{:key 1}
[:div "hello"]
[:div "world"]]
^{:key 2}
[:<>
[:div "foo"]])])]
(is (= "<div><div>hello</div><div>world</div><div>foo</div></div>"
(as-string [comp])))))))