feat(quo): implement wallet - input amount component (#18687)

Co-authored-by: Siddarth Kumar <siddarthkay@gmail.com>
Co-authored-by: Jamie Caprani <jamiecaprani@gmail.com>
This commit is contained in:
Nazarii F 2024-02-12 17:36:23 +02:00 committed by GitHub
parent abe0342be0
commit e86faa0767
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 197 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

View File

@ -0,0 +1,43 @@
(ns quo.components.wallet.amount-input.component-spec
(:require
[oops.core :as oops]
[quo.components.wallet.amount-input.view :as amount-input]
[quo.foundations.colors :as colors]
[test-helpers.component :as h]))
(defn- render
[component]
(h/render-with-theme-provider component :light))
(h/describe "Amount input component"
(h/test "Renders with default value"
(let [text-expected 0]
(render [amount-input/view {:init-value text-expected}])
(h/is-truthy (h/query-by-label-text :amount-input))
(h/is-equal (oops/oget (h/get-by-label-text :amount-input) "props" "value")
(str text-expected))))
(h/test "When the value = minimum dec button is disabled"
(render [amount-input/view
{:init-value 0
:min-value 0}])
(h/is-truthy
(oops/oget (h/get-by-label-text :amount-input-dec-button) "props" "accessibilityState" "disabled")))
(h/test "When the value = maximum inc button is disabled"
(render [amount-input/view
{:init-value 100
:max-value 100}])
(h/is-truthy
(oops/oget (h/get-by-label-text :amount-input-inc-button) "props" "accessibilityState" "disabled")))
(h/test "Renders the error state"
(render [amount-input/view {:status :error}])
(h/is-equal (colors/resolve-color :danger :light)
(oops/oget (h/get-by-label-text :amount-input) "props" "style" "color")))
(h/test "on-change-text function is fired"
(let [on-change-text (h/mock-fn)]
(render [amount-input/view {:on-change-text on-change-text}])
(h/fire-event :change-text (h/get-by-label-text :amount-input) "100")
(h/was-called on-change-text))))

View File

@ -0,0 +1,21 @@
(ns quo.components.wallet.amount-input.schema)
(def return-key-types
[:enum :done :go :next :search :send :none :previous :default
:emergency-call :google :join :route :yahoo])
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:status {:optional true} [:maybe [:enum :default :error]]]
[:theme :schema.common/theme]
[:on-change-text {:optional true} [:maybe fn?]]
[:container-style {:optional true} [:maybe :map]]
[:auto-focus? {:optional true} [:maybe :boolean]]
[:min-value {:optional true} [:maybe :int]]
[:max-value {:optional true} [:maybe :int]]
[:return-key-type {:optional true} [:maybe return-key-types]]
[:init-value {:optional true} [:maybe :int]]]]]
:any])

View File

@ -0,0 +1,17 @@
(ns quo.components.wallet.amount-input.style
(:require
[quo.foundations.colors :as colors]))
(def container
{:flex-direction :row
:justify-content :center
:align-items :center})
(def input-container {:flex 1})
(defn input-text
[theme type]
{:padding 0
:color (if (= type :error)
(colors/resolve-color :danger theme)
(colors/theme-colors colors/neutral-100 colors/white theme))})

View File

@ -0,0 +1,81 @@
(ns quo.components.wallet.amount-input.view
(:require
[quo.components.buttons.button.view :as button]
[quo.components.markdown.text :as text]
[quo.components.wallet.amount-input.schema :as amount-input.schema]
[quo.components.wallet.amount-input.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]
[schema.core :as schema]))
(defn- amount-button
[{:keys [theme accessibility-label disabled? icon on-press]}]
[button/button
{:icon-only? true
:theme theme
:disabled? disabled?
:type :outline
:accessibility-label accessibility-label
:size 32
:on-press on-press}
icon])
(defn- process-amount
[input-value min-value max-value]
(let [parsed-input-value (parse-double input-value)]
(cond
(nil? parsed-input-value) min-value
(>= input-value max-value) max-value
(<= input-value min-value) min-value
:else parsed-input-value)))
(defn- view-internal
[{:keys [init-value]}]
(let [init-value (or init-value 0)
value (reagent/atom init-value)
on-dec-press #(swap! value dec)
on-inc-press #(swap! value inc)]
(fn [{:keys [theme status min-value max-value auto-focus?
return-key-type container-style on-change-text]}]
(let [min-value (or min-value 0)
max-value (or max-value 999999999)]
[rn/view
{:style (merge style/container container-style)}
[amount-button
{:theme theme
:accessibility-label :amount-input-dec-button
:icon :i/remove
:on-press on-dec-press
:disabled? (>= min-value @value)}]
[rn/view {:style style/input-container}
[rn/text-input
{:style
(text/text-style
{:size :heading-1
:weight :semi-bold
:align :center
:style (style/input-text theme (or status :default))})
:accessibility-label :amount-input
:editable true
:auto-focus (or auto-focus? false)
:value (str @value)
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
:return-key-type (or return-key-type :done)
:input-mode :numeric
:on-change-text (fn [input-value]
(let [processed-amount (process-amount input-value min-value max-value)]
(reset! value processed-amount)
(when on-change-text
(on-change-text processed-amount))
(reagent/flush)))}]] ; Fixes the input flickering issue when typing.
[amount-button
{:theme theme
:icon :i/add
:accessibility-label :amount-input-inc-button
:on-press on-inc-press
:disabled? (>= @value max-value)}]]))))
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal amount-input.schema/?schema)))

View File

@ -157,6 +157,7 @@
quo.components.wallet.account-overview.view
quo.components.wallet.account-permissions.view
quo.components.wallet.address-text.view
quo.components.wallet.amount-input.view
quo.components.wallet.confirmation-progress.view
quo.components.wallet.keypair.view
quo.components.wallet.network-amount.view
@ -416,6 +417,7 @@
(def account-overview quo.components.wallet.account-overview.view/view)
(def account-permissions quo.components.wallet.account-permissions.view/view)
(def address-text quo.components.wallet.address-text.view/view)
(def amount-input quo.components.wallet.amount-input.view/view)
(def confirmation-propgress quo.components.wallet.confirmation-progress.view/view)
(def keypair quo.components.wallet.keypair.view/view)
(def network-amount quo.components.wallet.network-amount.view/view)

View File

@ -90,6 +90,7 @@
quo.components.wallet.account-origin.component-spec
quo.components.wallet.account-overview.component-spec
quo.components.wallet.account-permissions.component-spec
quo.components.wallet.amount-input.component-spec
quo.components.wallet.confirmation-progress.component-spec
quo.components.wallet.keypair.component-spec
quo.components.wallet.network-amount.component-spec

View File

@ -179,6 +179,7 @@
[status-im.contexts.preview.quo.wallet.account-overview :as
account-overview]
[status-im.contexts.preview.quo.wallet.account-permissions :as account-permissions]
[status-im.contexts.preview.quo.wallet.amount-input :as amount-input]
[status-im.contexts.preview.quo.wallet.confirmation-progress :as
confirmation-progress]
[status-im.contexts.preview.quo.wallet.keypair :as keypair]
@ -496,6 +497,8 @@
:component account-overview/view}
{:name :account-permissions
:component account-permissions/view}
{:name :amount-input
:component amount-input/view}
{:name :confirmation-progress
:component confirmation-progress/view}
{:name :keypair :component keypair/view}

View File

@ -0,0 +1,29 @@
(ns status-im.contexts.preview.quo.wallet.amount-input
(:require
[quo.core :as quo]
[reagent.core :as reagent]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :max-value
:type :number}
{:key :min-value
:type :number}
{:key :init-value
:type :number}
{:type :select
:key :status
:options [{:key :default}
{:key :error}]}])
(defn view
[]
(let [state (reagent/atom {:max-value 10000
:min-value 0
:init-value 1
:status :default})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor}
[quo/amount-input @state]])))