mirror of https://github.com/status-im/reagent.git
Add import-react macro
This commit is contained in:
parent
429ed50fab
commit
41a687faa7
|
@ -1,6 +1,6 @@
|
||||||
(ns demo
|
(ns demo
|
||||||
(:require [reagent.core :as reagent :refer [atom]]
|
(:require [reagent.core :as reagent :refer [atom]]
|
||||||
[reagent.interop :refer-macros [.' .! fvar]]
|
[reagent.interop :as i :refer-macros [.' .! fvar]]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[reagentdemo.page :as page :refer [page-map page link prefix]]
|
[reagentdemo.page :as page :refer [page-map page link prefix]]
|
||||||
[reagentdemo.common :as common :refer [demo-component]]
|
[reagentdemo.common :as common :refer [demo-component]]
|
||||||
|
@ -8,6 +8,8 @@
|
||||||
[reagentdemo.news :as news]
|
[reagentdemo.news :as news]
|
||||||
[reagent.debug :refer-macros [dbg println]]))
|
[reagent.debug :refer-macros [dbg println]]))
|
||||||
|
|
||||||
|
(i/import-react)
|
||||||
|
|
||||||
(swap! page-map assoc
|
(swap! page-map assoc
|
||||||
"index.html" (fvar intro/main)
|
"index.html" (fvar intro/main)
|
||||||
"news/index.html" (fvar news/main))
|
"news/index.html" (fvar news/main))
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
{:client {:compiler
|
{:client {:compiler
|
||||||
{:optimizations :advanced
|
{:optimizations :advanced
|
||||||
:elide-asserts true
|
:elide-asserts true
|
||||||
:preamble ^:replace ["reagent/react.min.js"]
|
|
||||||
:pretty-print false}}}}}
|
:pretty-print false}}}}}
|
||||||
:test {:cljsbuild
|
:test {:cljsbuild
|
||||||
{:builds
|
{:builds
|
||||||
|
@ -37,7 +36,6 @@
|
||||||
"examples/geometry/src"]
|
"examples/geometry/src"]
|
||||||
:notify-command ["node" "./bin/gen-site.js"]
|
:notify-command ["node" "./bin/gen-site.js"]
|
||||||
:compiler
|
:compiler
|
||||||
{:preamble ["reagent/react.js"]
|
{:output-dir "target/client"
|
||||||
:output-dir "target/client"
|
|
||||||
:output-to "target/cljs-client.js"
|
:output-to "target/cljs-client.js"
|
||||||
:pretty-print true}}}})
|
:pretty-print true}}}})
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
[reagent.debug :refer-macros [dbg prn]]
|
[reagent.debug :refer-macros [dbg prn]]
|
||||||
[reagent.interop :refer-macros [.' .!]]))
|
[reagent.interop :refer-macros [.' .!]]))
|
||||||
|
|
||||||
(def React util/React)
|
|
||||||
|
|
||||||
(def is-client util/is-client)
|
(def is-client util/is-client)
|
||||||
|
|
||||||
(defn as-component
|
(defn as-component
|
||||||
|
@ -40,7 +38,7 @@ Returns the mounted component instance."
|
||||||
(defn render-component-to-string
|
(defn render-component-to-string
|
||||||
"Turns a component into an HTML string."
|
"Turns a component into an HTML string."
|
||||||
([component]
|
([component]
|
||||||
(.' React renderComponentToString (as-component component))))
|
(.' js/React renderComponentToString (as-component component))))
|
||||||
|
|
||||||
(defn ^:export force-update-all []
|
(defn ^:export force-update-all []
|
||||||
(util/force-update-all))
|
(util/force-update-all))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
(ns reagent.impl.component
|
(ns reagent.impl.component
|
||||||
(:require [reagent.impl.util :as util :refer [React]]
|
(:require [reagent.impl.util :as util]
|
||||||
[reagent.impl.batching :as batch]
|
[reagent.impl.batching :as batch]
|
||||||
[reagent.ratom :as ratom]
|
[reagent.ratom :as ratom]
|
||||||
[reagent.interop :refer-macros [.' .!]]
|
[reagent.interop :refer-macros [.' .!]]
|
||||||
|
@ -183,7 +183,7 @@
|
||||||
(assert (map? body))
|
(assert (map? body))
|
||||||
(let [spec (cljsify body)
|
(let [spec (cljsify body)
|
||||||
_ (.! spec :asComponent (dont-bind as-component))
|
_ (.! spec :asComponent (dont-bind as-component))
|
||||||
res (.' React createClass spec)
|
res (.' js/React createClass spec)
|
||||||
f (fn [& args]
|
f (fn [& args]
|
||||||
(as-component (apply vector res args)))]
|
(as-component (apply vector res args)))]
|
||||||
(util/cache-react-class f res)
|
(util/cache-react-class f res)
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
|
|
||||||
(ns reagent.impl.template
|
(ns reagent.impl.template
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[reagent.impl.util :as util :refer [is-client React]]
|
[reagent.impl.util :as util :refer [is-client]]
|
||||||
[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]
|
||||||
[reagent.interop :refer-macros [.' .!]]
|
[reagent.interop :refer-macros [.' .!]]
|
||||||
[reagent.debug :refer-macros [dbg prn println log dev?]]))
|
[reagent.debug :refer-macros [dbg prn println log dev?]]))
|
||||||
|
|
||||||
|
|
||||||
;; From Weavejester's Hiccup, via pump:
|
;; From Weavejester's Hiccup, via pump:
|
||||||
(def ^{:doc "Regular expression that parses a CSS-style id and class
|
(def ^{:doc "Regular expression that parses a CSS-style id and class
|
||||||
from a tag name."}
|
from a tag name."}
|
||||||
re-tag #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?")
|
re-tag #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?")
|
||||||
|
|
||||||
(def DOM (.' React :DOM))
|
|
||||||
|
|
||||||
(def attr-aliases {:class "className"
|
(def attr-aliases {:class "className"
|
||||||
:for "htmlFor"
|
:for "htmlFor"
|
||||||
:charset "charSet"})
|
:charset "charSet"})
|
||||||
|
@ -117,8 +116,10 @@
|
||||||
(.! :value nil)
|
(.! :value nil)
|
||||||
(.! :onChange #(input-handle-change this on-change %))))))
|
(.! :onChange #(input-handle-change this on-change %))))))
|
||||||
|
|
||||||
(def input-components #{(.' DOM :input)
|
(defn input-component? [x]
|
||||||
(.' DOM :textarea)})
|
(let [DOM (.' js/React :DOM)]
|
||||||
|
(or (identical? x (.' DOM :input))
|
||||||
|
(identical? x (.' DOM :textarea)))))
|
||||||
|
|
||||||
|
|
||||||
;;; Wrapping of native components
|
;;; Wrapping of native components
|
||||||
|
@ -151,7 +152,7 @@
|
||||||
(.! :componentWillUnmount #(this-as c (batch/dispose c)))))
|
(.! :componentWillUnmount #(this-as c (batch/dispose c)))))
|
||||||
|
|
||||||
(defn wrap-component [comp extras name]
|
(defn wrap-component [comp extras name]
|
||||||
(let [input? (input-components comp)
|
(let [input? (input-component? comp)
|
||||||
input-setup (if input? input-render-setup)
|
input-setup (if input? input-render-setup)
|
||||||
spec #js{:render
|
spec #js{:render
|
||||||
#(this-as C (wrapped-render C comp extras input-setup))
|
#(this-as C (wrapped-render C comp extras input-setup))
|
||||||
|
@ -160,14 +161,14 @@
|
||||||
:displayName (or name "ComponentWrapper")}]
|
:displayName (or name "ComponentWrapper")}]
|
||||||
(when input?
|
(when input?
|
||||||
(add-input-methods spec))
|
(add-input-methods spec))
|
||||||
(.' React createClass spec)))
|
(.' js/React createClass spec)))
|
||||||
|
|
||||||
|
|
||||||
;;; Conversion from Hiccup forms
|
;;; Conversion from Hiccup forms
|
||||||
|
|
||||||
(defn parse-tag [hiccup-tag]
|
(defn parse-tag [hiccup-tag]
|
||||||
(let [[tag id class] (->> hiccup-tag name (re-matches re-tag) next)
|
(let [[tag id class] (->> hiccup-tag name (re-matches re-tag) next)
|
||||||
comp (aget DOM tag)
|
comp (aget (.' js/React :DOM) tag)
|
||||||
class' (when class
|
class' (when class
|
||||||
(string/replace class #"\." " "))]
|
(string/replace class #"\." " "))]
|
||||||
(assert comp (str "Unknown tag: '" hiccup-tag "'"))
|
(assert comp (str "Unknown tag: '" hiccup-tag "'"))
|
||||||
|
@ -197,7 +198,7 @@
|
||||||
(let [cached-class (util/cached-react-class tag)]
|
(let [cached-class (util/cached-react-class tag)]
|
||||||
(if-not (nil? cached-class)
|
(if-not (nil? cached-class)
|
||||||
cached-class
|
cached-class
|
||||||
(if (.' React isValidClass tag)
|
(if (.' js/React isValidClass tag)
|
||||||
(util/cache-react-class tag (wrap-component tag nil nil))
|
(util/cache-react-class tag (wrap-component tag nil nil))
|
||||||
(fn-to-class tag)))))))
|
(fn-to-class tag)))))))
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
(def is-client (and (exists? js/window)
|
(def is-client (and (exists? js/window)
|
||||||
(-> js/window (.' :document) nil? not)))
|
(-> js/window (.' :document) nil? not)))
|
||||||
|
|
||||||
(def React js/React)
|
|
||||||
|
|
||||||
;;; Props accessors
|
;;; Props accessors
|
||||||
|
|
||||||
(defn extract-props [v]
|
(defn extract-props [v]
|
||||||
|
@ -128,11 +126,11 @@
|
||||||
|
|
||||||
(defn re-render-component [comp container]
|
(defn re-render-component [comp container]
|
||||||
(try
|
(try
|
||||||
(.' React renderComponent (comp) container)
|
(.' js/React renderComponent (comp) container)
|
||||||
(catch js/Object e
|
(catch js/Object e
|
||||||
(do
|
(do
|
||||||
(try
|
(try
|
||||||
(.' React unmountComponentAtNode container)
|
(.' js/React unmountComponentAtNode container)
|
||||||
(catch js/Object e
|
(catch js/Object e
|
||||||
(log e)))
|
(log e)))
|
||||||
(when-let [n (get-react-node container)]
|
(when-let [n (get-react-node container)]
|
||||||
|
@ -141,7 +139,7 @@
|
||||||
(throw e)))))
|
(throw e)))))
|
||||||
|
|
||||||
(defn render-component [comp container callback]
|
(defn render-component [comp container callback]
|
||||||
(.' React renderComponent (comp) container
|
(.' js/React renderComponent (comp) container
|
||||||
(fn []
|
(fn []
|
||||||
(let [id (get-root-id container)]
|
(let [id (get-root-id container)]
|
||||||
(when-not (nil? id)
|
(when-not (nil? id)
|
||||||
|
@ -154,7 +152,7 @@
|
||||||
(let [id (get-root-id container)]
|
(let [id (get-root-id container)]
|
||||||
(when-not (nil? id)
|
(when-not (nil? id)
|
||||||
(swap! roots dissoc id)))
|
(swap! roots dissoc id)))
|
||||||
(.' React unmountComponentAtNode container))
|
(.' js/React unmountComponentAtNode container))
|
||||||
|
|
||||||
(defn force-update-all []
|
(defn force-update-all []
|
||||||
(binding [*always-update* true]
|
(binding [*always-update* true]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns reagent.interop
|
(ns reagent.interop
|
||||||
(:require [clojure.string :as string :refer [join]]))
|
(:require [clojure.string :as string :refer [join]]
|
||||||
|
[clojure.java.io :as io]))
|
||||||
|
|
||||||
(defn- js-call [f args]
|
(defn- js-call [f args]
|
||||||
(let [argstr (->> (repeat (count args) "~{}")
|
(let [argstr (->> (repeat (count args) "~{}")
|
||||||
|
@ -48,6 +49,38 @@
|
||||||
(assert field (str "Field name must start with - in " field))
|
(assert field (str "Field name must start with - in " field))
|
||||||
`(aset ~object ~@names ~value)))
|
`(aset ~object ~@names ~value)))
|
||||||
|
|
||||||
|
(def react-import-ns (atom nil))
|
||||||
|
|
||||||
|
(defmacro import-react
|
||||||
|
[]
|
||||||
|
"Import React.js.
|
||||||
|
This can be used instead of adding :preamble in project.clj
|
||||||
|
(or adding react.js in a script tag). This may be more convenient when
|
||||||
|
using :optimizations :none, since that doesn't take :preamble into account.
|
||||||
|
Imports minimized version of React if :elide-asserts is true."
|
||||||
|
(if-not (or (nil? @react-import-ns)
|
||||||
|
(= *ns* @react-import-ns))
|
||||||
|
;; React was already imported in another namespace; so we avoid
|
||||||
|
;; duplicate imports.
|
||||||
|
true
|
||||||
|
(let [srcfile (if *assert* "reagent/react.js"
|
||||||
|
"reagent/react.min.js")
|
||||||
|
src (slurp (io/resource srcfile))]
|
||||||
|
(if (nil? @react-import-ns)
|
||||||
|
(reset! react-import-ns *ns*))
|
||||||
|
`(js/eval ~(str "if (typeof React != 'undefined' &&
|
||||||
|
typeof console != 'undefined') {
|
||||||
|
console.log('WARNING: React is already defined');
|
||||||
|
}"
|
||||||
|
src "; \n"
|
||||||
|
"console.log('importing');"
|
||||||
|
"if (typeof module != 'undefined' &&
|
||||||
|
typeof global != 'undefined' &&
|
||||||
|
module.exports && module.exports.DOM) {
|
||||||
|
global.React = module.exports;
|
||||||
|
} \n
|
||||||
|
//@ sourceURL=" srcfile "\n")))))
|
||||||
|
|
||||||
|
|
||||||
(defmacro fvar
|
(defmacro fvar
|
||||||
[f]
|
[f]
|
||||||
|
|
Loading…
Reference in New Issue