mirror of
https://github.com/status-im/status-react.git
synced 2025-01-23 09:19:59 +00:00
Wallet/Swap Input Component (#20318)
This commit is contained in:
parent
21cc8a199a
commit
c52b3e457e
@ -1,5 +1,6 @@
|
||||
(ns quo.components.avatars.token-avatar.view
|
||||
(:require [quo.components.avatars.token-avatar.style :as style]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hole-view :as hole-view]
|
||||
[react-native.platform :as platform]
|
||||
@ -12,13 +13,14 @@
|
||||
[:map {:closed true}
|
||||
[:type {:optional true} [:enum :asset :collectible]]
|
||||
[:context? {:optional true} [:maybe :boolean]]
|
||||
[:image :schema.common/image-source]
|
||||
[:image {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:token {:optional true} [:maybe [:or :keyword :string]]]
|
||||
[:network-image {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type context? image network-image container-style]}]
|
||||
[{:keys [type context? image token network-image container-style]}]
|
||||
[rn/view
|
||||
{:style (merge style/container container-style)
|
||||
:accessibility-label :token-avatar}
|
||||
@ -32,9 +34,11 @@
|
||||
[])
|
||||
:style style/hole-view}
|
||||
platform/android? (assoc :key context?))
|
||||
[rn/image
|
||||
{:source image
|
||||
:style (style/image type)}]]
|
||||
[token/view
|
||||
{:size :size-32
|
||||
:token token
|
||||
:style (style/image type)
|
||||
:image-source image}]]
|
||||
(when context?
|
||||
[rn/image
|
||||
{:source network-image
|
||||
|
31
src/quo/components/wallet/swap_input/component_spec.cljs
Normal file
31
src/quo/components/wallet/swap_input/component_spec.cljs
Normal file
@ -0,0 +1,31 @@
|
||||
(ns quo.components.wallet.swap-input.component-spec
|
||||
(:require [quo.components.wallet.swap-input.view :as swap-input]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Wallet: Swap Input"
|
||||
(h/test "should render correctly with props"
|
||||
(h/render-with-theme-provider
|
||||
[swap-input/view
|
||||
{:type :pay
|
||||
:error? false
|
||||
:token "SNT"
|
||||
:status :default
|
||||
:currency-symbol "€"
|
||||
:value "5"
|
||||
:fiat-value "1.50"
|
||||
:network-tag-props {:title "Max: 200 SNT"}}])
|
||||
(h/is-truthy (h/get-by-label-text :swap-input))
|
||||
(h/is-truthy (h/get-by-text "SNT"))
|
||||
(h/is-truthy (h/get-by-text "€1.50"))
|
||||
(h/is-truthy (h/get-by-text "Max: 200 SNT")))
|
||||
|
||||
(h/test "should render correctly with approval label"
|
||||
(h/render-with-theme-provider
|
||||
[swap-input/view
|
||||
{:type :pay
|
||||
:show-approval-label? true
|
||||
:approval-label-props
|
||||
{:status :approve
|
||||
:token-value "10"
|
||||
:token-symbol "SNT"}}])
|
||||
(h/is-truthy (h/get-by-text "Approve 10 SNT"))))
|
74
src/quo/components/wallet/swap_input/style.cljs
Normal file
74
src/quo/components/wallet/swap_input/style.cljs
Normal file
@ -0,0 +1,74 @@
|
||||
(ns quo.components.wallet.swap-input.style
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[quo.foundations.typography :as typography]))
|
||||
|
||||
(defn- border-color
|
||||
[theme]
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))
|
||||
|
||||
(defn- loader-color
|
||||
[theme]
|
||||
(colors/theme-colors colors/neutral-5 colors/neutral-90 theme))
|
||||
|
||||
(defn content
|
||||
[theme]
|
||||
{:border-width 1
|
||||
:border-radius 16
|
||||
:border-color (border-color theme)
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
|
||||
|
||||
(defn row-1
|
||||
[loading?]
|
||||
{:padding 12
|
||||
:gap 8
|
||||
:align-items (if loading? :center :flex-end)
|
||||
:flex-direction :row})
|
||||
|
||||
(defn row-1-loader
|
||||
[theme]
|
||||
{:width 74
|
||||
:height 14
|
||||
:border-radius 6
|
||||
:background-color (loader-color theme)})
|
||||
|
||||
(def input-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:gap 5
|
||||
:height 32
|
||||
:align-items :flex-end})
|
||||
|
||||
(defn input
|
||||
[disabled? error? theme]
|
||||
(assoc typography/font-semi-bold
|
||||
:font-size 27
|
||||
:flex-shrink 1
|
||||
:padding 0
|
||||
:color (cond
|
||||
error? (colors/resolve-color :danger theme)
|
||||
disabled? (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:else (colors/theme-colors colors/neutral-100 colors/white theme))
|
||||
:line-height 32))
|
||||
|
||||
(defn token-symbol
|
||||
[theme]
|
||||
{:padding-bottom 3
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
||||
|
||||
(defn row-2
|
||||
[align-right?]
|
||||
{:flex-direction :row
|
||||
:justify-content (if align-right? :flex-end :space-between)
|
||||
:align-items :center
|
||||
:padding 12})
|
||||
|
||||
(defn row-2-loader
|
||||
[theme]
|
||||
{:width 80
|
||||
:height 10
|
||||
:margin-vertical 7
|
||||
:border-radius 6
|
||||
:background-color (loader-color theme)})
|
||||
|
||||
(def fiat-amount
|
||||
{:color colors/neutral-50})
|
121
src/quo/components/wallet/swap_input/view.cljs
Normal file
121
src/quo/components/wallet/swap_input/view.cljs
Normal file
@ -0,0 +1,121 @@
|
||||
(ns quo.components.wallet.swap-input.view
|
||||
(:require [oops.core :as oops]
|
||||
[quo.components.avatars.token-avatar.view :as token-avatar]
|
||||
[quo.components.buttons.button.view :as buttons]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.wallet.approval-label.schema :as approval-label.schema]
|
||||
[quo.components.wallet.approval-label.view :as approval-label]
|
||||
[quo.components.wallet.swap-input.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
quo.theme
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:type {:optional true} [:maybe [:enum :pay :receive]]]
|
||||
[:status {:optional true} [:maybe [:enum :default :disabled :loading]]]
|
||||
[:token {:optional true} [:maybe :string]]
|
||||
[:value {:optional true} [:maybe :string]]
|
||||
[:default-value {:optional true} [:maybe :string]]
|
||||
[:currency-symbol {:optional true} [:maybe :string]]
|
||||
[:fiat-value {:optional true} [:maybe :string]]
|
||||
[:show-approval-label? {:optional true} [:maybe :boolean]]
|
||||
[:error? {:optional true} [:maybe :boolean]]
|
||||
[:show-keyboard? {:optional true} [:maybe :boolean]]
|
||||
[:approval-label-props {:optional true} [:maybe approval-label.schema/?schema]]
|
||||
[:network-tag-props {:optional true} [:maybe :map]]
|
||||
[:on-change-text {:optional true} [:maybe fn?]]
|
||||
[:enable-swap? {:optional true} [:maybe :boolean]]
|
||||
[:on-swap-press {:optional true} [:maybe fn?]]
|
||||
[:on-token-press {:optional true} [:maybe fn?]]
|
||||
[:on-max-press {:optional true} [:maybe fn?]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [type status token value fiat-value show-approval-label? error? network-tag-props
|
||||
approval-label-props default-value enable-swap?
|
||||
currency-symbol on-change-text show-keyboard?
|
||||
container-style on-swap-press on-token-press on-max-press]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
pay? (= type :pay)
|
||||
disabled? (= status :disabled)
|
||||
loading? (= status :loading)
|
||||
controlled-input? (some? value)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
set-input-ref (rn/use-callback (fn [ref] (reset! input-ref ref)) [])
|
||||
focus-input (rn/use-callback (fn []
|
||||
(some-> @input-ref
|
||||
(oops/ocall "focus")))
|
||||
[input-ref])]
|
||||
[rn/view
|
||||
{:style container-style
|
||||
:accessibility-label :swap-input}
|
||||
[rn/view {:style (style/content theme)}
|
||||
[rn/view
|
||||
{:style (style/row-1 loading?)}
|
||||
[rn/pressable {:on-press on-token-press}
|
||||
[token-avatar/view
|
||||
{:type :asset
|
||||
:token token}]]
|
||||
(if loading?
|
||||
[rn/view {:style (style/row-1-loader theme)}]
|
||||
[:<>
|
||||
[rn/pressable
|
||||
{:style style/input-container
|
||||
:on-press focus-input}
|
||||
[rn/text-input
|
||||
(cond-> {:ref set-input-ref
|
||||
:style (style/input disabled? error? theme)
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40
|
||||
colors/neutral-50
|
||||
theme)
|
||||
:keyboard-type :numeric
|
||||
:auto-focus true
|
||||
:on-change-text on-change-text
|
||||
:show-soft-input-on-focus show-keyboard?
|
||||
:default-value default-value
|
||||
:placeholder "0"}
|
||||
controlled-input? (assoc :value value))]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style (style/token-symbol theme)}
|
||||
token]]
|
||||
(when (and pay? enable-swap?)
|
||||
[buttons/button
|
||||
{:type :outline
|
||||
:size 32
|
||||
:on-press on-swap-press
|
||||
:icon-only? true}
|
||||
:i/reorder])])]
|
||||
[divider-line/view]
|
||||
[rn/view
|
||||
{:style (style/row-2 (or (not pay?) loading?))}
|
||||
(when-not loading?
|
||||
[:<>
|
||||
(when pay?
|
||||
[rn/pressable {:on-press on-max-press}
|
||||
[network-tag/view
|
||||
(assoc network-tag-props
|
||||
:status
|
||||
(if error? :error :default))]])
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style style/fiat-amount
|
||||
:weight :medium}
|
||||
(str currency-symbol fiat-value)]])
|
||||
(when loading?
|
||||
[rn/view {:style (style/row-2-loader theme)}])]]
|
||||
(when (and (not= status :loading) (= type :pay) show-approval-label?)
|
||||
[approval-label/view
|
||||
approval-label-props])]))
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
@ -186,6 +186,7 @@
|
||||
quo.components.wallet.progress-bar.view
|
||||
quo.components.wallet.required-tokens.view
|
||||
quo.components.wallet.summary-info.view
|
||||
quo.components.wallet.swap-input.view
|
||||
quo.components.wallet.token-input.view
|
||||
quo.components.wallet.transaction-progress.view
|
||||
quo.components.wallet.transaction-summary.view
|
||||
@ -472,6 +473,7 @@
|
||||
(def progress-bar quo.components.wallet.progress-bar.view/view)
|
||||
(def required-tokens quo.components.wallet.required-tokens.view/view)
|
||||
(def summary-info quo.components.wallet.summary-info.view/view)
|
||||
(def swap-input quo.components.wallet.swap-input.view/view)
|
||||
(def network-link quo.components.wallet.network-link.view/view)
|
||||
(def token-input quo.components.wallet.token-input.view/view)
|
||||
(def wallet-overview quo.components.wallet.wallet-overview.view/view)
|
||||
|
@ -112,6 +112,7 @@
|
||||
quo.components.wallet.progress-bar.component-spec
|
||||
quo.components.wallet.required-tokens.component-spec
|
||||
quo.components.wallet.summary-info.component-spec
|
||||
quo.components.wallet.swap-input.component-spec
|
||||
quo.components.wallet.token-input.component-spec
|
||||
quo.components.wallet.transaction-progress.component-spec
|
||||
quo.components.wallet.transaction-summary.component-spec
|
||||
|
@ -212,6 +212,7 @@
|
||||
[status-im.contexts.preview.quo.wallet.progress-bar :as progress-bar]
|
||||
[status-im.contexts.preview.quo.wallet.required-tokens :as required-tokens]
|
||||
[status-im.contexts.preview.quo.wallet.summary-info :as summary-info]
|
||||
[status-im.contexts.preview.quo.wallet.swap-input :as swap-input]
|
||||
[status-im.contexts.preview.quo.wallet.token-input :as token-input]
|
||||
[status-im.contexts.preview.quo.wallet.transaction-progress :as transaction-progress]
|
||||
[status-im.contexts.preview.quo.wallet.transaction-summary :as
|
||||
@ -570,6 +571,7 @@
|
||||
{:name :required-tokens
|
||||
:component required-tokens/view}
|
||||
{:name :summary-info :component summary-info/view}
|
||||
{:name :swap-input :component swap-input/view}
|
||||
{:name :token-input :component token-input/view}
|
||||
{:name :wallet-activity :component wallet-activity/view}
|
||||
{:name :transaction-progress :component transaction-progress/view}
|
||||
|
68
src/status_im/contexts/preview/quo/wallet/swap_input.cljs
Normal file
68
src/status_im/contexts/preview/quo/wallet/swap_input.cljs
Normal file
@ -0,0 +1,68 @@
|
||||
(ns status-im.contexts.preview.quo.wallet.swap-input
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.resources :as resources]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:type :select
|
||||
:key :type
|
||||
:options [{:key :pay}
|
||||
{:key :receive}]}
|
||||
{:type :select
|
||||
:key :status
|
||||
:options [{:key :default}
|
||||
{:key :disabled}
|
||||
{:key :loading}]}
|
||||
{:type :select
|
||||
:key :value
|
||||
:options [{:key :token}
|
||||
{:key :fiat}]}
|
||||
{:type :boolean
|
||||
:key :error?}
|
||||
{:type :boolean
|
||||
:key :enable-swap?}
|
||||
{:type :boolean
|
||||
:key :show-approval-label?}
|
||||
(preview/customization-color-option)])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [[state set-state] (rn/use-state {:type :pay
|
||||
:error? false
|
||||
:token "SNT"
|
||||
:customization-color :blue
|
||||
:show-approval-label? false
|
||||
:enable-swap? true
|
||||
:status :default
|
||||
:currency-symbol "€"})
|
||||
[value set-value] (rn/use-state "")
|
||||
on-press (fn [v] (set-value (str value v)))
|
||||
delete (fn [] (set-value #(subs % 0 (dec (count %)))))]
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:set-state set-state
|
||||
:descriptor descriptor}
|
||||
[quo/swap-input
|
||||
(assoc state
|
||||
:on-swap-press #(js/alert "Swap Pressed")
|
||||
:on-token-press #(js/alert "Token Pressed")
|
||||
:on-max-press #(js/alert "Max Pressed")
|
||||
:value value
|
||||
:fiat-value (str (.toFixed (* value 0.3) 2))
|
||||
:container-style {:margin-bottom 20}
|
||||
:network-tag-props {:title "Max: 200 SNT"
|
||||
:networks [{:source (resources/get-network :ethereum)}]}
|
||||
:approval-label-props
|
||||
{:status :approve
|
||||
:token-value "10"
|
||||
:button-props {:on-press
|
||||
#(js/alert "Approve Pressed")}
|
||||
:customization-color (:customization-color state)
|
||||
:token-symbol "SNT"})]
|
||||
[quo/numbered-keyboard
|
||||
{:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press on-press
|
||||
:on-delete delete}]]))
|
Loading…
x
Reference in New Issue
Block a user