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:
parent
abe0342be0
commit
e86faa0767
Binary file not shown.
After Width: | Height: | Size: 181 B |
Binary file not shown.
After Width: | Height: | Size: 217 B |
|
@ -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))))
|
|
@ -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])
|
|
@ -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))})
|
|
@ -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)))
|
|
@ -157,6 +157,7 @@
|
||||||
quo.components.wallet.account-overview.view
|
quo.components.wallet.account-overview.view
|
||||||
quo.components.wallet.account-permissions.view
|
quo.components.wallet.account-permissions.view
|
||||||
quo.components.wallet.address-text.view
|
quo.components.wallet.address-text.view
|
||||||
|
quo.components.wallet.amount-input.view
|
||||||
quo.components.wallet.confirmation-progress.view
|
quo.components.wallet.confirmation-progress.view
|
||||||
quo.components.wallet.keypair.view
|
quo.components.wallet.keypair.view
|
||||||
quo.components.wallet.network-amount.view
|
quo.components.wallet.network-amount.view
|
||||||
|
@ -416,6 +417,7 @@
|
||||||
(def account-overview quo.components.wallet.account-overview.view/view)
|
(def account-overview quo.components.wallet.account-overview.view/view)
|
||||||
(def account-permissions quo.components.wallet.account-permissions.view/view)
|
(def account-permissions quo.components.wallet.account-permissions.view/view)
|
||||||
(def address-text quo.components.wallet.address-text.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 confirmation-propgress quo.components.wallet.confirmation-progress.view/view)
|
||||||
(def keypair quo.components.wallet.keypair.view/view)
|
(def keypair quo.components.wallet.keypair.view/view)
|
||||||
(def network-amount quo.components.wallet.network-amount.view/view)
|
(def network-amount quo.components.wallet.network-amount.view/view)
|
||||||
|
|
|
@ -90,6 +90,7 @@
|
||||||
quo.components.wallet.account-origin.component-spec
|
quo.components.wallet.account-origin.component-spec
|
||||||
quo.components.wallet.account-overview.component-spec
|
quo.components.wallet.account-overview.component-spec
|
||||||
quo.components.wallet.account-permissions.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.confirmation-progress.component-spec
|
||||||
quo.components.wallet.keypair.component-spec
|
quo.components.wallet.keypair.component-spec
|
||||||
quo.components.wallet.network-amount.component-spec
|
quo.components.wallet.network-amount.component-spec
|
||||||
|
|
|
@ -179,6 +179,7 @@
|
||||||
[status-im.contexts.preview.quo.wallet.account-overview :as
|
[status-im.contexts.preview.quo.wallet.account-overview :as
|
||||||
account-overview]
|
account-overview]
|
||||||
[status-im.contexts.preview.quo.wallet.account-permissions :as account-permissions]
|
[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
|
[status-im.contexts.preview.quo.wallet.confirmation-progress :as
|
||||||
confirmation-progress]
|
confirmation-progress]
|
||||||
[status-im.contexts.preview.quo.wallet.keypair :as keypair]
|
[status-im.contexts.preview.quo.wallet.keypair :as keypair]
|
||||||
|
@ -496,6 +497,8 @@
|
||||||
:component account-overview/view}
|
:component account-overview/view}
|
||||||
{:name :account-permissions
|
{:name :account-permissions
|
||||||
:component account-permissions/view}
|
:component account-permissions/view}
|
||||||
|
{:name :amount-input
|
||||||
|
:component amount-input/view}
|
||||||
{:name :confirmation-progress
|
{:name :confirmation-progress
|
||||||
:component confirmation-progress/view}
|
:component confirmation-progress/view}
|
||||||
{:name :keypair :component keypair/view}
|
{:name :keypair :component keypair/view}
|
||||||
|
|
|
@ -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]])))
|
Loading…
Reference in New Issue