fix input issues (#19341)

This commit is contained in:
flexsurfer 2024-03-25 10:42:20 +01:00 committed by GitHub
parent 399da799a6
commit 2528efb538
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 123 additions and 119 deletions

View File

@ -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 #(% "")]

View File

@ -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

View File

@ -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])))

View File

@ -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

View File

@ -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}}]]

View File

@ -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)))}]))

View File

@ -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