mirror of
https://github.com/status-im/status-react.git
synced 2025-02-02 22:25:12 +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
|
(ns quo.components.avatars.token-avatar.view
|
||||||
(:require [quo.components.avatars.token-avatar.style :as style]
|
(:require [quo.components.avatars.token-avatar.style :as style]
|
||||||
|
[quo.components.utilities.token.view :as token]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.hole-view :as hole-view]
|
[react-native.hole-view :as hole-view]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
@ -12,13 +13,14 @@
|
|||||||
[:map {:closed true}
|
[:map {:closed true}
|
||||||
[:type {:optional true} [:enum :asset :collectible]]
|
[:type {:optional true} [:enum :asset :collectible]]
|
||||||
[:context? {:optional true} [:maybe :boolean]]
|
[: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]]
|
[:network-image {:optional true} [:maybe :schema.common/image-source]]
|
||||||
[:container-style {:optional true} [:maybe :map]]]]]
|
[:container-style {:optional true} [:maybe :map]]]]]
|
||||||
:any])
|
:any])
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[{:keys [type context? image network-image container-style]}]
|
[{:keys [type context? image token network-image container-style]}]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (merge style/container container-style)
|
{:style (merge style/container container-style)
|
||||||
:accessibility-label :token-avatar}
|
:accessibility-label :token-avatar}
|
||||||
@ -32,9 +34,11 @@
|
|||||||
[])
|
[])
|
||||||
:style style/hole-view}
|
:style style/hole-view}
|
||||||
platform/android? (assoc :key context?))
|
platform/android? (assoc :key context?))
|
||||||
[rn/image
|
[token/view
|
||||||
{:source image
|
{:size :size-32
|
||||||
:style (style/image type)}]]
|
:token token
|
||||||
|
:style (style/image type)
|
||||||
|
:image-source image}]]
|
||||||
(when context?
|
(when context?
|
||||||
[rn/image
|
[rn/image
|
||||||
{:source network-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.progress-bar.view
|
||||||
quo.components.wallet.required-tokens.view
|
quo.components.wallet.required-tokens.view
|
||||||
quo.components.wallet.summary-info.view
|
quo.components.wallet.summary-info.view
|
||||||
|
quo.components.wallet.swap-input.view
|
||||||
quo.components.wallet.token-input.view
|
quo.components.wallet.token-input.view
|
||||||
quo.components.wallet.transaction-progress.view
|
quo.components.wallet.transaction-progress.view
|
||||||
quo.components.wallet.transaction-summary.view
|
quo.components.wallet.transaction-summary.view
|
||||||
@ -472,6 +473,7 @@
|
|||||||
(def progress-bar quo.components.wallet.progress-bar.view/view)
|
(def progress-bar quo.components.wallet.progress-bar.view/view)
|
||||||
(def required-tokens quo.components.wallet.required-tokens.view/view)
|
(def required-tokens quo.components.wallet.required-tokens.view/view)
|
||||||
(def summary-info quo.components.wallet.summary-info.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 network-link quo.components.wallet.network-link.view/view)
|
||||||
(def token-input quo.components.wallet.token-input.view/view)
|
(def token-input quo.components.wallet.token-input.view/view)
|
||||||
(def wallet-overview quo.components.wallet.wallet-overview.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.progress-bar.component-spec
|
||||||
quo.components.wallet.required-tokens.component-spec
|
quo.components.wallet.required-tokens.component-spec
|
||||||
quo.components.wallet.summary-info.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.token-input.component-spec
|
||||||
quo.components.wallet.transaction-progress.component-spec
|
quo.components.wallet.transaction-progress.component-spec
|
||||||
quo.components.wallet.transaction-summary.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.progress-bar :as progress-bar]
|
||||||
[status-im.contexts.preview.quo.wallet.required-tokens :as required-tokens]
|
[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.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.token-input :as token-input]
|
||||||
[status-im.contexts.preview.quo.wallet.transaction-progress :as transaction-progress]
|
[status-im.contexts.preview.quo.wallet.transaction-progress :as transaction-progress]
|
||||||
[status-im.contexts.preview.quo.wallet.transaction-summary :as
|
[status-im.contexts.preview.quo.wallet.transaction-summary :as
|
||||||
@ -570,6 +571,7 @@
|
|||||||
{:name :required-tokens
|
{:name :required-tokens
|
||||||
:component required-tokens/view}
|
:component required-tokens/view}
|
||||||
{:name :summary-info :component summary-info/view}
|
{:name :summary-info :component summary-info/view}
|
||||||
|
{:name :swap-input :component swap-input/view}
|
||||||
{:name :token-input :component token-input/view}
|
{:name :token-input :component token-input/view}
|
||||||
{:name :wallet-activity :component wallet-activity/view}
|
{:name :wallet-activity :component wallet-activity/view}
|
||||||
{:name :transaction-progress :component transaction-progress/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