mirror of
https://github.com/status-im/reagent.git
synced 2025-01-27 04:05:50 +00:00
Enhance TextField example with other options
This commit is contained in:
parent
91ea195796
commit
199533a1ea
@ -50,8 +50,16 @@ it is useful to wrap the `TextField` component in a way that the option is added
|
||||
(let [props (-> props
|
||||
(assoc-in [:InputProps :inputComponent] input-component)
|
||||
rtpl/convert-prop-value)]
|
||||
(apply r/create-element mui/TextField props children)))
|
||||
(apply r/create-element mui/TextField props (map r/as-element children))))
|
||||
```
|
||||
|
||||
Here `r/create-element` and `reagent.impl.template/covert-prop-values` achieve
|
||||
the same as what `adapt-react-class` does, but allows modifying the props.
|
||||
|
||||
**Check the example project for complete code.** Some additional logic is
|
||||
required to ensure option like `:multiline` and `:select` work correctly,
|
||||
as they affect how the `inputComponent` should work.
|
||||
|
||||
TODO: `:multiline` `TextField` without `:rows` (i.e. automatic height) doesn't
|
||||
work, because that requires Material-UI `Input/Textarea`, which doesn't work
|
||||
with Reagent cursor fix.
|
||||
|
@ -5,6 +5,7 @@
|
||||
[reagent.impl.template :as rtpl]))
|
||||
|
||||
(def mui-theme-provider (r/adapt-react-class mui/MuiThemeProvider))
|
||||
(def menu-item (r/adapt-react-class mui/MenuItem))
|
||||
|
||||
(def ^:private input-component
|
||||
(r/reactify-component
|
||||
@ -13,36 +14,88 @@
|
||||
(assoc :ref (:inputRef props))
|
||||
(dissoc :inputRef))])))
|
||||
|
||||
(def ^:private textarea-component
|
||||
(r/reactify-component
|
||||
(fn [props]
|
||||
[:textarea (-> props
|
||||
(assoc :ref (:inputRef props))
|
||||
(dissoc :inputRef))])))
|
||||
|
||||
;; To fix cursor jumping when controlled input value is changed,
|
||||
;; use wrapper input element created by Reagent instead of
|
||||
;; letting Material-UI to create input element directly using React.
|
||||
;; Create-element + convert-props-value is the same as what adapt-react-class does.
|
||||
(defn text-field [props & children]
|
||||
(let [props (-> props
|
||||
(assoc-in [:InputProps :inputComponent] input-component)
|
||||
(assoc-in [:InputProps :inputComponent] (cond
|
||||
(and (:multiline props) (:rows props) (not (:maxRows props)))
|
||||
textarea-component
|
||||
|
||||
;; FIXME: Autosize multiline input is broken.
|
||||
(:multiline props)
|
||||
nil
|
||||
|
||||
(not (:select props))
|
||||
nil
|
||||
|
||||
:else
|
||||
input-component))
|
||||
rtpl/convert-prop-value)]
|
||||
(apply r/create-element mui/TextField props children)))
|
||||
(apply r/create-element mui/TextField props (map r/as-element children))))
|
||||
|
||||
(defonce text-state (r/atom "foobar"))
|
||||
|
||||
(defn main []
|
||||
[:div
|
||||
[:form
|
||||
{:style {:display "flex"
|
||||
:flex-direction "column"
|
||||
:flex-wrap "wrap"}}
|
||||
[:div
|
||||
[:strong @text-state]]
|
||||
|
||||
[:button
|
||||
{:on-click #(swap! text-state str " foo")}
|
||||
"update value property"]
|
||||
|
||||
[:button
|
||||
{:on-click #(reset! text-state "")}
|
||||
"reset"]
|
||||
|
||||
[text-field
|
||||
{:id "example"
|
||||
:value @text-state
|
||||
:label "Label"
|
||||
:label "Text input"
|
||||
:placeholder "Placeholder"
|
||||
:helper-text "Helper text"
|
||||
:on-change (fn [e]
|
||||
(reset! text-state (.. e -target -value)))
|
||||
:inputRef #(js/console.log "input-ref" %)}]])
|
||||
:inputRef #(js/console.log "input-ref" %)}]
|
||||
|
||||
[text-field
|
||||
{:id "example"
|
||||
:value @text-state
|
||||
:label "Textarea"
|
||||
:placeholder "Placeholder"
|
||||
:helper-text "Helper text"
|
||||
:on-change (fn [e]
|
||||
(reset! text-state (.. e -target -value)))
|
||||
:multiline true
|
||||
;; TODO: Autosize textarea is broken.
|
||||
:rows 10}]
|
||||
|
||||
[text-field
|
||||
{:id "example"
|
||||
:value @text-state
|
||||
:label "Select"
|
||||
:placeholder "Placeholder"
|
||||
:helper-text "Helper text"
|
||||
:on-change (fn [e]
|
||||
(reset! text-state (.. e -target -value)))
|
||||
:select true}
|
||||
[menu-item
|
||||
{:value 1} "Item 1"]
|
||||
[menu-item
|
||||
{:value 2} "Item 2"]]])
|
||||
|
||||
(defn start []
|
||||
(r/render [main] (js/document.getElementById "app")))
|
||||
|
Loading…
x
Reference in New Issue
Block a user