fix input issues (#19341)
This commit is contained in:
parent
399da799a6
commit
2528efb538
|
@ -61,7 +61,7 @@
|
||||||
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
|
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
|
||||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||||
:placeholder-text-color
|
:placeholder-text-color
|
||||||
colors/neutral-30))))))
|
colors/neutral-40))))))
|
||||||
|
|
||||||
(h/test "on blur with text blur? true"
|
(h/test "on blur with text blur? true"
|
||||||
(with-redefs [clipboard/get-string #(% "")]
|
(with-redefs [clipboard/get-string #(% "")]
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
|
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
|
||||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||||
:placeholder-text-color
|
:placeholder-text-color
|
||||||
colors/neutral-80-opa-20))))))
|
colors/neutral-80-opa-40))))))
|
||||||
|
|
||||||
(h/test "on blur with no text and blur? false"
|
(h/test "on blur with no text and blur? false"
|
||||||
(with-redefs [clipboard/get-string #(% "")]
|
(with-redefs [clipboard/get-string #(% "")]
|
||||||
|
|
|
@ -58,78 +58,64 @@
|
||||||
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan
|
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan
|
||||||
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
|
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
|
||||||
valid-ens-or-address? container-style]}]
|
valid-ens-or-address? container-style]}]
|
||||||
(let [theme (quo.theme/use-theme-value)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
[status set-status] (rn/use-state :default)
|
[status set-status] (rn/use-state :default)
|
||||||
value (rn/use-ref-atom nil)
|
[value set-value] (rn/use-state nil)
|
||||||
[_ trigger-render-value] (rn/use-state @value)
|
[focused? set-focused] (rn/use-state false)
|
||||||
[focused? set-focused] (rn/use-state false)
|
on-change (rn/use-callback
|
||||||
on-change (rn/use-callback
|
(fn [text]
|
||||||
(fn [text]
|
(let [address? (when address-regex
|
||||||
(let [address? (when address-regex
|
(boolean (re-matches address-regex text)))
|
||||||
(boolean (re-matches address-regex text)))
|
ens? (when ens-regex
|
||||||
ens? (when ens-regex
|
(boolean (re-matches ens-regex text)))]
|
||||||
(boolean (re-matches ens-regex text)))]
|
(set-value text)
|
||||||
(reset! value text)
|
(if (> (count text) 0)
|
||||||
(if (> (count text) 0)
|
(set-status :typing)
|
||||||
(set-status :typing)
|
|
||||||
(set-status :active))
|
|
||||||
(when on-change-text
|
|
||||||
(on-change-text text))
|
|
||||||
(when (and on-detect-ens ens?)
|
|
||||||
(set-status :loading)
|
|
||||||
(on-detect-ens text #(set-status :typing)))
|
|
||||||
(when (and address? on-detect-address)
|
|
||||||
(set-status :loading)
|
|
||||||
(on-detect-address text))
|
|
||||||
(when (and (not address?)
|
|
||||||
(not ens?)
|
|
||||||
on-detect-unclassified)
|
|
||||||
(on-detect-unclassified text)))))
|
|
||||||
set-value (rn/use-callback
|
|
||||||
(fn [new-value]
|
|
||||||
(reset! value new-value)
|
|
||||||
(on-change new-value)
|
|
||||||
(trigger-render-value new-value)))
|
|
||||||
on-paste (rn/use-callback
|
|
||||||
(fn []
|
|
||||||
(clipboard/get-string
|
|
||||||
(fn [clipboard]
|
|
||||||
(when-not (empty? clipboard)
|
|
||||||
(set-value clipboard))))))
|
|
||||||
on-clear (rn/use-callback
|
|
||||||
(fn []
|
|
||||||
(set-value "")
|
|
||||||
(set-status (if focused? :active :default))
|
|
||||||
(when on-change-text
|
|
||||||
(on-change-text ""))
|
|
||||||
(when on-clear
|
|
||||||
(on-clear)))
|
|
||||||
[focused?])
|
|
||||||
on-clear (rn/use-callback
|
|
||||||
(fn []
|
|
||||||
(set-value "")
|
|
||||||
(set-status (if focused? :active :default))
|
|
||||||
(when on-change-text
|
|
||||||
(on-change-text ""))
|
|
||||||
(when on-clear
|
|
||||||
(on-clear)))
|
|
||||||
[focused?])
|
|
||||||
on-scan (when on-scan (rn/use-callback #(on-scan set-value)))
|
|
||||||
on-focus (rn/use-callback
|
|
||||||
(fn []
|
|
||||||
(when (= (count @value) 0)
|
|
||||||
(set-status :active))
|
(set-status :active))
|
||||||
(set-focused true)
|
(when on-change-text
|
||||||
(when on-focus (on-focus))))
|
(on-change-text text))
|
||||||
on-blur (rn/use-callback
|
(when (and on-detect-ens ens?)
|
||||||
(fn []
|
(set-status :loading)
|
||||||
(when (= status :active)
|
(on-detect-ens text #(set-status :typing)))
|
||||||
(set-status :default))
|
(when (and address? on-detect-address)
|
||||||
(set-focused false)
|
(set-status :loading)
|
||||||
(when on-blur (on-blur)))
|
(on-detect-address text))
|
||||||
[status])
|
(when (and (not address?)
|
||||||
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
|
(not ens?)
|
||||||
[status theme blur?])]
|
on-detect-unclassified)
|
||||||
|
(on-detect-unclassified text)))))
|
||||||
|
on-paste (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(clipboard/get-string
|
||||||
|
(fn [clipboard]
|
||||||
|
(when-not (empty? clipboard)
|
||||||
|
(on-change clipboard))))))
|
||||||
|
on-clear (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(on-change "")
|
||||||
|
(set-status (if focused? :active :default))
|
||||||
|
(when on-change-text
|
||||||
|
(on-change-text ""))
|
||||||
|
(when on-clear
|
||||||
|
(on-clear)))
|
||||||
|
[focused?])
|
||||||
|
on-scan (rn/use-callback #(when on-scan (on-scan on-change))
|
||||||
|
[on-scan])
|
||||||
|
on-focus (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(when (= (count value) 0)
|
||||||
|
(set-status :active))
|
||||||
|
(set-focused true)
|
||||||
|
(when on-focus (on-focus))))
|
||||||
|
on-blur (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(when (= status :active)
|
||||||
|
(set-status :default))
|
||||||
|
(set-focused false)
|
||||||
|
(when on-blur (on-blur)))
|
||||||
|
[status])
|
||||||
|
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
|
||||||
|
[status theme blur?])]
|
||||||
(rn/use-mount #(on-change (or default-value "")))
|
(rn/use-mount #(on-change (or default-value "")))
|
||||||
[rn/view {:style (style/container container-style)}
|
[rn/view {:style (style/container container-style)}
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
|
@ -137,7 +123,7 @@
|
||||||
:style (style/input-text theme)
|
:style (style/input-text theme)
|
||||||
:placeholder (i18n/label :t/name-ens-or-address)
|
:placeholder (i18n/label :t/name-ens-or-address)
|
||||||
:placeholder-text-color placeholder-text-color
|
:placeholder-text-color placeholder-text-color
|
||||||
:value @value
|
:value value
|
||||||
:auto-complete (when platform/ios? :off)
|
:auto-complete (when platform/ios? :off)
|
||||||
:auto-capitalize :none
|
:auto-capitalize :none
|
||||||
:auto-correct false
|
:auto-correct false
|
||||||
|
|
|
@ -57,14 +57,19 @@
|
||||||
"Custom properties that must be removed from properties map passed to InputText."
|
"Custom properties that must be removed from properties map passed to InputText."
|
||||||
[:type :blur? :error? :right-icon :left-icon :disabled? :small? :button
|
[:type :blur? :error? :right-icon :left-icon :disabled? :small? :button
|
||||||
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur
|
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur
|
||||||
:container-style])
|
:container-style :ref])
|
||||||
|
|
||||||
(defn- base-input
|
(defn- base-input
|
||||||
[{:keys [blur? error? right-icon left-icon disabled? small? button
|
[{:keys [blur? error? right-icon left-icon disabled? small? button
|
||||||
label char-limit multiline? clearable? on-focus on-blur container-style
|
label char-limit multiline? clearable? on-focus on-blur container-style
|
||||||
on-change-text on-char-limit-reach weight default-value]
|
on-change-text on-char-limit-reach weight default-value on-clear]
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [theme (quo.theme/use-theme-value)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
|
ref (rn/use-ref-atom nil)
|
||||||
|
on-ref (rn/use-callback (fn [value]
|
||||||
|
(when (:ref props)
|
||||||
|
((:ref props) value))
|
||||||
|
(reset! ref value)))
|
||||||
[status set-status] (rn/use-state :default)
|
[status set-status] (rn/use-state :default)
|
||||||
internal-on-focus (rn/use-callback #(set-status :focus))
|
internal-on-focus (rn/use-callback #(set-status :focus))
|
||||||
internal-on-blur (rn/use-callback #(set-status :default))
|
internal-on-blur (rn/use-callback #(set-status :default))
|
||||||
|
@ -93,6 +98,15 @@
|
||||||
:else status)
|
:else status)
|
||||||
colors-by-status (style/status-colors status-kw blur? theme)
|
colors-by-status (style/status-colors status-kw blur? theme)
|
||||||
variant-colors (style/variants-colors blur? theme)
|
variant-colors (style/variants-colors blur? theme)
|
||||||
|
clear-on-press (rn/use-callback (fn []
|
||||||
|
(.clear ^js @ref)
|
||||||
|
(when on-clear (on-clear)))
|
||||||
|
[on-clear])
|
||||||
|
right-icon (or right-icon
|
||||||
|
(when clearable?
|
||||||
|
{:style-fn style/clear-icon
|
||||||
|
:icon-name :i/clear
|
||||||
|
:on-press clear-on-press}))
|
||||||
clean-props (apply dissoc props custom-props)]
|
clean-props (apply dissoc props custom-props)]
|
||||||
[rn/view {:style container-style}
|
[rn/view {:style container-style}
|
||||||
(when (or label char-limit)
|
(when (or label char-limit)
|
||||||
|
@ -108,7 +122,8 @@
|
||||||
:small? small?
|
:small? small?
|
||||||
:icon-name icon-name}])
|
:icon-name icon-name}])
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
(cond-> {:style (style/input colors-by-status small? multiple-lines? weight)
|
(cond-> {:ref on-ref
|
||||||
|
:style (style/input colors-by-status small? multiple-lines? weight)
|
||||||
:accessibility-label :input
|
:accessibility-label :input
|
||||||
:placeholder-text-color (:placeholder colors-by-status)
|
:placeholder-text-color (:placeholder colors-by-status)
|
||||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||||
|
@ -147,7 +162,10 @@
|
||||||
[{:keys [default-shown?]
|
[{:keys [default-shown?]
|
||||||
:or {default-shown? false}
|
:or {default-shown? false}
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [[password-shown? set-password-shown] (rn/use-state default-shown?)]
|
(let [[password-shown?
|
||||||
|
set-password-shown] (rn/use-state default-shown?)
|
||||||
|
on-press (rn/use-callback #(set-password-shown (not password-shown?))
|
||||||
|
[password-shown?])]
|
||||||
[base-input
|
[base-input
|
||||||
(assoc props
|
(assoc props
|
||||||
:accessibility-label :password-input
|
:accessibility-label :password-input
|
||||||
|
@ -156,7 +174,7 @@
|
||||||
:secure-text-entry (not password-shown?)
|
:secure-text-entry (not password-shown?)
|
||||||
:right-icon {:style-fn style/password-icon
|
:right-icon {:style-fn style/password-icon
|
||||||
:icon-name (if password-shown? :i/hide-password :i/reveal)
|
:icon-name (if password-shown? :i/hide-password :i/reveal)
|
||||||
:on-press #(set-password-shown (not password-shown?))})]))
|
:on-press on-press})]))
|
||||||
|
|
||||||
(defn input
|
(defn input
|
||||||
"This input supports the following properties:
|
"This input supports the following properties:
|
||||||
|
@ -182,15 +200,11 @@
|
||||||
- :on-change-text
|
- :on-change-text
|
||||||
...
|
...
|
||||||
"
|
"
|
||||||
[{:keys [type clearable? on-clear icon-name]
|
[{:keys [type icon-name]
|
||||||
:or {type :text}
|
:or {type :text}
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [base-props (cond-> props
|
(let [base-props (cond-> props
|
||||||
icon-name (assoc-in [:left-icon :icon-name] icon-name)
|
icon-name (assoc-in [:left-icon :icon-name] icon-name))]
|
||||||
clearable? (assoc :right-icon
|
|
||||||
{:style-fn style/clear-icon
|
|
||||||
:icon-name :i/clear
|
|
||||||
:on-press #(when on-clear (on-clear))}))]
|
|
||||||
(if (= type :password)
|
(if (= type :password)
|
||||||
[password-input base-props]
|
[password-input base-props]
|
||||||
[base-input base-props])))
|
[base-input base-props])))
|
||||||
|
|
|
@ -148,28 +148,26 @@
|
||||||
(reset! search-text ""))
|
(reset! search-text ""))
|
||||||
|
|
||||||
(defn f-view
|
(defn f-view
|
||||||
[{:keys [search-text on-change-text clear-states active-category scroll-ref theme]
|
[{:keys [search-active? on-change-text clear-states active-category scroll-ref theme]
|
||||||
:as sheet-opts}]
|
:as sheet-opts}]
|
||||||
(let [search-active? (pos? (count @search-text))]
|
[rn/keyboard-avoiding-view
|
||||||
[rn/keyboard-avoiding-view
|
{:style style/flex-spacer
|
||||||
{:style style/flex-spacer
|
:keyboard-vertical-offset 8}
|
||||||
:keyboard-vertical-offset 8}
|
[rn/view {:style style/flex-spacer}
|
||||||
[rn/view {:style style/flex-spacer}
|
[rn/view {:style style/search-input-container}
|
||||||
[rn/view {:style style/search-input-container}
|
[quo/input
|
||||||
[quo/input
|
{:small? true
|
||||||
{:small? true
|
:placeholder (i18n/label :t/emoji-search-placeholder)
|
||||||
:placeholder (i18n/label :t/emoji-search-placeholder)
|
:icon-name :i/search
|
||||||
:icon-name :i/search
|
:on-change-text on-change-text
|
||||||
:value @search-text
|
:clearable? search-active?
|
||||||
:on-change-text on-change-text
|
:on-clear clear-states}]]
|
||||||
:clearable? search-active?
|
[render-list sheet-opts]
|
||||||
:on-clear clear-states}]]
|
(when-not search-active?
|
||||||
[render-list sheet-opts]
|
[footer
|
||||||
(when-not search-active?
|
{:theme theme
|
||||||
[footer
|
:active-category active-category
|
||||||
{:theme theme
|
:scroll-ref scroll-ref}])]])
|
||||||
:active-category active-category
|
|
||||||
:scroll-ref scroll-ref}])]]))
|
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[_]
|
[_]
|
||||||
|
@ -202,7 +200,7 @@
|
||||||
(fn [sheet-opts]
|
(fn [sheet-opts]
|
||||||
[:f> f-view
|
[:f> f-view
|
||||||
(assoc sheet-opts
|
(assoc sheet-opts
|
||||||
:search-text search-text
|
:search-active? (pos? (count @search-text))
|
||||||
:on-change-text on-change-text
|
:on-change-text on-change-text
|
||||||
:clear-states clear-states
|
:clear-states clear-states
|
||||||
:filtered-data @filtered-data
|
:filtered-data @filtered-data
|
||||||
|
|
|
@ -153,7 +153,7 @@
|
||||||
@full-name
|
@full-name
|
||||||
(i18n/label :t/your-name))
|
(i18n/label :t/your-name))
|
||||||
:customization-color @custom-color}
|
:customization-color @custom-color}
|
||||||
:title-input-props {:default-value @full-name
|
:title-input-props {:default-value display-name
|
||||||
:auto-focus true
|
:auto-focus true
|
||||||
:max-length c/profile-name-max-length
|
:max-length c/profile-name-max-length
|
||||||
:on-change-text on-change-text}}]]
|
:on-change-text on-change-text}}]]
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
(:require [status-im.common.scan-qr-code.view :as scan-qr-code]
|
(:require [status-im.common.scan-qr-code.view :as scan-qr-code]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[utils.debounce :as debounce]
|
[utils.debounce :as debounce]
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- contains-address?
|
(defn- contains-address?
|
||||||
[s]
|
[s]
|
||||||
|
@ -14,11 +15,15 @@
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
[scan-qr-code/view
|
(let [{:keys [on-result]} (rf/sub [:get-screen-params])]
|
||||||
{:title (i18n/label :t/scan-qr)
|
[scan-qr-code/view
|
||||||
:subtitle (i18n/label :t/scan-an-account-qr-code)
|
{:title (i18n/label :t/scan-qr)
|
||||||
:error-message (i18n/label :t/oops-this-qr-does-not-contain-an-address)
|
:subtitle (i18n/label :t/scan-an-account-qr-code)
|
||||||
:validate-fn #(contains-address? %)
|
:error-message (i18n/label :t/oops-this-qr-does-not-contain-an-address)
|
||||||
:on-success-scan #(debounce/debounce-and-dispatch [:wallet/scan-address-success
|
:validate-fn #(contains-address? %)
|
||||||
(extract-address %)]
|
:on-success-scan (fn [result]
|
||||||
300)}])
|
(let [address (extract-address result)]
|
||||||
|
(when on-result (on-result address))
|
||||||
|
(debounce/debounce-and-dispatch
|
||||||
|
[:wallet/scan-address-success address]
|
||||||
|
300)))}]))
|
||||||
|
|
|
@ -35,10 +35,11 @@
|
||||||
[quo/address-input
|
[quo/address-input
|
||||||
{:on-focus #(reset! input-focused? true)
|
{:on-focus #(reset! input-focused? true)
|
||||||
:on-blur #(reset! input-focused? false)
|
:on-blur #(reset! input-focused? false)
|
||||||
:on-scan (fn []
|
:on-scan (fn [on-result]
|
||||||
(rn/dismiss-keyboard!)
|
(rn/dismiss-keyboard!)
|
||||||
(rf/dispatch [:wallet/clean-scanned-address])
|
(rf/dispatch [:wallet/clean-scanned-address])
|
||||||
(rf/dispatch [:open-modal :screen/wallet.scan-address]))
|
(rf/dispatch [:open-modal :screen/wallet.scan-address
|
||||||
|
{:on-result on-result}]))
|
||||||
:ens-regex constants/regx-ens
|
:ens-regex constants/regx-ens
|
||||||
:scanned-value (or (when recipient-plain-address? send-address) scanned-address)
|
:scanned-value (or (when recipient-plain-address? send-address) scanned-address)
|
||||||
:address-regex constants/regx-multichain-address
|
:address-regex constants/regx-multichain-address
|
||||||
|
|
Loading…
Reference in New Issue