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