Malli schemas added to components (#18949)
This commit is contained in:
parent
7d55c98e0a
commit
7754460acc
|
@ -65,7 +65,7 @@
|
|||
{:title "Title"
|
||||
:type :account
|
||||
:account-avatar-emoji "🍿"
|
||||
:networks [{:name :ethereum :short-name "eth"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}]
|
||||
:description "0x62b...0a5"
|
||||
:customization-color :purple}]
|
||||
theme)
|
||||
|
|
|
@ -6,71 +6,101 @@
|
|||
|
||||
(def ^:private theme :light)
|
||||
|
||||
(def ^:private default-props
|
||||
{:account-props {:name "Account name"
|
||||
:address "0x1234567890"
|
||||
:emoji "🍑"
|
||||
:customization-color "blue"}})
|
||||
|
||||
(defn- with-defaults
|
||||
([] default-props)
|
||||
([props] (merge default-props props)))
|
||||
|
||||
(h/describe "List items: account"
|
||||
(h/test "default render'"
|
||||
(h/render-with-theme-provider [account/view] theme)
|
||||
(h/render-with-theme-provider [account/view (with-defaults)] theme)
|
||||
(h/is-truthy (h/query-by-label-text :container)))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed"
|
||||
(h/render-with-theme-provider [account/view] theme)
|
||||
(h/render-with-theme-provider [account/view (with-defaults)] theme)
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/resolve-color :blue :light 5)})))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed with blur? enabled"
|
||||
(h/render-with-theme-provider [account/view {:blur? true}] theme)
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:blur? true})] theme)
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor colors/white-opa-5})))
|
||||
|
||||
(h/test "render with state :active"
|
||||
(h/render-with-theme-provider [account/view {:state :active}] theme)
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:state :active})] theme)
|
||||
(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/resolve-color :blue :light 10)}))
|
||||
|
||||
(h/test "render with state :active and blur? enabled"
|
||||
(h/render-with-theme-provider [account/view
|
||||
{:blur? true
|
||||
:state :active}]
|
||||
(with-defaults
|
||||
{:blur? true
|
||||
:state :active})]
|
||||
theme)
|
||||
(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor colors/white-opa-10}))
|
||||
|
||||
(h/test "render with state :selected"
|
||||
(h/render-with-theme-provider [account/view {:state :selected}] theme)
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:state :selected})] theme)
|
||||
(h/is-truthy (h/query-by-label-text :check-icon)))
|
||||
|
||||
(h/test "calls on-press"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider [account/view {:on-press on-press}] theme)
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:on-press on-press})] theme)
|
||||
(h/fire-event :on-press (h/get-by-label-text :container))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "renders token props if type :tag"
|
||||
(h/render-with-theme-provider [account/view {:type :tag}] theme)
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults {:type :tag
|
||||
:token-props {:symbol "SNT"
|
||||
:value "1,000"}})]
|
||||
theme)
|
||||
(h/is-truthy (h/query-by-label-text :tag-container)))
|
||||
|
||||
(h/test "renders keycard icon if title-icon is present"
|
||||
(h/render-with-theme-provider [account/view {:title-icon :i/placeholder}] theme)
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:title-icon :i/placeholder})] theme)
|
||||
(h/is-truthy (h/query-by-label-text :title-icon)))
|
||||
|
||||
(h/test "doesn't render keycard icon if title-icon is missing"
|
||||
(h/render-with-theme-provider [account/view] theme)
|
||||
(h/render-with-theme-provider [account/view (with-defaults)] theme)
|
||||
(h/is-falsy (h/query-by-label-text :title-icon)))
|
||||
|
||||
(h/test "renders balance container but not arrow icon if type :balance-neutral"
|
||||
(h/render-with-theme-provider [account/view {:type :balance-neutral}] theme)
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults {:type :balance-neutral
|
||||
:balance-props {:fiat-value "€0.00"
|
||||
:percentage-change "0.0"
|
||||
:fiat-change "€0.00"}})]
|
||||
theme)
|
||||
(h/is-truthy (h/query-by-label-text :balance-container))
|
||||
(h/is-falsy (h/query-by-label-text :arrow-icon)))
|
||||
|
||||
(h/test "renders balance container and negative arrow icon if type :balance-negative"
|
||||
(h/render-with-theme-provider [account/view {:type :balance-negative}] theme)
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults {:type :balance-negative
|
||||
:balance-props {:fiat-value "€0.00"
|
||||
:percentage-change "0.0"
|
||||
:fiat-change "€0.00"}})]
|
||||
theme)
|
||||
(h/is-truthy (h/query-by-label-text :balance-container))
|
||||
(h/is-truthy (h/query-by-label-text :icon-negative))
|
||||
(h/is-falsy (h/query-by-label-text :icon-positive)))
|
||||
|
||||
(h/test "renders balance container and positive arrow icon if type :balance-positive"
|
||||
(h/render-with-theme-provider [account/view {:type :balance-positive}] theme)
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults {:type :balance-positive
|
||||
:balance-props {:fiat-value "€0.00"
|
||||
:percentage-change "0.0"
|
||||
:fiat-change "€0.00"}})]
|
||||
theme)
|
||||
(h/is-truthy (h/query-by-label-text :balance-container))
|
||||
(h/is-falsy (h/query-by-label-text :icon-negative))
|
||||
(h/is-truthy (h/query-by-label-text :icon-positive)))
|
||||
|
@ -78,8 +108,9 @@
|
|||
(h/test "renders options button if type :action"
|
||||
(let [on-options-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider [account/view
|
||||
{:type :action
|
||||
:on-options-press on-options-press}]
|
||||
(with-defaults
|
||||
{:type :action
|
||||
:on-options-press on-options-press})]
|
||||
theme)
|
||||
(h/is-truthy (h/query-by-label-text :options-button))
|
||||
(h/fire-event :on-press (h/get-by-label-text :options-button))
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
(ns quo.components.list-items.account.schema)
|
||||
|
||||
(def ^:private ?balance
|
||||
[:map
|
||||
[:balance-props
|
||||
[:map
|
||||
[:fiat-value :string]
|
||||
[:percentage-change :string]
|
||||
[:fiat-change :string]]]])
|
||||
|
||||
(def ^:private ?tag
|
||||
[:map
|
||||
[:token-props
|
||||
[:map
|
||||
[:symbol :string]
|
||||
[:value :string]]]])
|
||||
|
||||
(def ^:private ?action
|
||||
[:map
|
||||
[:on-options-press {:optional true} [:maybe fn?]]])
|
||||
|
||||
(def ^:private ?base
|
||||
[:map
|
||||
[:type {:optional true}
|
||||
[:enum :default :tag :action :balance-neutral :balance-negative :balance-positive]]
|
||||
[:state {:optional true} [:enum :default :selected :active]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:theme :schema.common/theme]
|
||||
[:title-icon {:optional true} [:maybe :keyword]]
|
||||
[:account-props
|
||||
[:map
|
||||
[:name :string]
|
||||
[:address :string]
|
||||
[:emoji :string]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:multi {:dispatch :type}
|
||||
[:balance-neutral [:merge ?base ?balance]]
|
||||
[:balance-negative [:merge ?base ?balance]]
|
||||
[:balance-positive [:merge ?base ?balance]]
|
||||
[:tag [:merge ?base ?tag]]
|
||||
[:action [:merge ?base ?action]]
|
||||
[:default ?base]
|
||||
[:malli.core/default ?base]]]
|
||||
:any])
|
|
@ -2,13 +2,15 @@
|
|||
(:require
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.account.schema :as component-schema]
|
||||
[quo.components.list-items.account.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.wallet.address-text.view :as address-text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- account-view
|
||||
[{:keys [account-props title-icon blur? theme]}]
|
||||
|
@ -130,4 +132,6 @@
|
|||
(and (= type :default) (= state :selected))
|
||||
[check-icon props])]])))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
(h/describe "List items: account list card"
|
||||
(h/test "Test icon renders for ':action :icon'"
|
||||
(h/render [account-list-card/view
|
||||
{:account-props account-props
|
||||
:network :ethereum
|
||||
:state :default
|
||||
:action :icon}])
|
||||
(h/render-with-theme-provider [account-list-card/view
|
||||
{:account-props account-props
|
||||
:network :ethereum
|
||||
:action :icon
|
||||
:on-options-press (fn [])}])
|
||||
(h/is-truthy (h/get-by-label-text :icon))))
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
(ns quo.components.list-items.account-list-card.schema)
|
||||
|
||||
(def ^:private ?base
|
||||
[:map
|
||||
[:action {:optional true} [:enum :icon :none]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:theme :schema.common/theme]
|
||||
[:account-props
|
||||
[:map {:closed true}
|
||||
[:type [:enum :default :watch-only]]
|
||||
[:name :string]
|
||||
[:address :string]
|
||||
[:emoji :string]
|
||||
[:size {:optional true} [:enum 80 :size-64 48 32 28 24 20 16]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]
|
||||
[:networks {:optional true} [:* [:map [:network-name :keyword] [:short-name :string]]]]])
|
||||
|
||||
(def ^:private ?on-option-press
|
||||
[:map
|
||||
[:on-options-press [:maybe fn?]]])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:multi {:dispatch :action}
|
||||
[:icon [:merge ?base ?on-option-press]]
|
||||
[:none ?base]
|
||||
[:malli.core/default ?base]]]
|
||||
:any])
|
|
@ -2,13 +2,15 @@
|
|||
(:require
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.account-list-card.schema :as component-schema]
|
||||
[quo.components.list-items.account-list-card.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.wallet.address-text.view :as address-text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- internal-view
|
||||
[]
|
||||
|
@ -39,4 +41,6 @@
|
|||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))
|
||||
:accessibility-label :icon}]])])))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
|
|
|
@ -4,32 +4,36 @@
|
|||
[quo.foundations.colors :as colors]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn- with-defaults
|
||||
([] (with-defaults {}))
|
||||
([props] (merge {:address "0x0ah...78b"} props)))
|
||||
|
||||
(h/describe "List items: address"
|
||||
(h/test "default render"
|
||||
(h/render [address/view])
|
||||
(h/render-with-theme-provider [address/view (with-defaults)])
|
||||
(h/is-truthy (h/query-by-label-text :container)))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed"
|
||||
(h/render [address/view])
|
||||
(h/render-with-theme-provider [address/view (with-defaults)])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/custom-color :blue 50 5)})))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed with blur? enabled"
|
||||
(h/render [address/view {:blur? true}])
|
||||
(h/render-with-theme-provider [address/view (with-defaults {:blur? true})])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor colors/white-opa-5})))
|
||||
|
||||
(h/test "on-press-out changes state to :active"
|
||||
(h/render [address/view {:active-state? true}])
|
||||
(h/render-with-theme-provider [address/view (with-defaults {:active-state? true})])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press-out (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/custom-color :blue 50 10)})))
|
||||
|
||||
(h/test "on-press-out changes state to :active with blur? enabled"
|
||||
(h/render [address/view {:active-state? true :blur? true}])
|
||||
(h/render-with-theme-provider [address/view (with-defaults {:active-state? true :blur? true})])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press-out (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
|
@ -37,6 +41,6 @@
|
|||
|
||||
(h/test "on-press event is called"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render [address/view {:on-press on-press}])
|
||||
(h/render-with-theme-provider [address/view (with-defaults {:on-press on-press})])
|
||||
(h/fire-event :on-press (h/get-by-label-text :container))
|
||||
(h/was-called on-press))))
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
(ns quo.components.list-items.address.schema)
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map
|
||||
[:address :string]
|
||||
[:networks {:optional true} [:* [:map [:network-name :keyword] [:short-name :string]]]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:theme :schema.common/theme]
|
||||
[:active-state? {:optional true} [:maybe :boolean]]]]
|
||||
:any])
|
|
@ -1,12 +1,14 @@
|
|||
(ns quo.components.list-items.address.view
|
||||
(:require
|
||||
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
|
||||
(quo.components.list-items.address.schema :as component-schema)
|
||||
[quo.components.list-items.address.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]
|
||||
[utils.address :as address]))
|
||||
|
||||
(defn- left-container
|
||||
|
@ -64,4 +66,7 @@
|
|||
:address address
|
||||
:blur? blur?}]]))))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
[quo.foundations.colors :as colors]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn- with-defaults
|
||||
([] (with-defaults {}))
|
||||
([props] (merge {:contact-props {:full-name "Thomas Anderson"}} props)))
|
||||
|
||||
(def account
|
||||
{:name "New House"
|
||||
:address "0x21a...49e"
|
||||
|
@ -12,25 +16,33 @@
|
|||
|
||||
(h/describe "List items: saved contact address"
|
||||
(h/test "default render"
|
||||
(h/render-with-theme-provider [saved-contact-address/view])
|
||||
(h/render-with-theme-provider [saved-contact-address/view (with-defaults)])
|
||||
(h/is-truthy (h/query-by-label-text :container)))
|
||||
|
||||
(h/test "renders account detail when passing one account"
|
||||
(h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}])
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 1 account)})])
|
||||
(h/is-truthy (h/query-by-label-text :account-container)))
|
||||
|
||||
(h/test "renders account count when passing multiple accounts"
|
||||
(h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 2 account)}])
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 2 account)})])
|
||||
(h/is-truthy (h/query-by-label-text :accounts-count)))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed"
|
||||
(h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}])
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 1 account)})])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/custom-color :blue 50 5)})))
|
||||
|
||||
(h/test "on-press-out changes state to :active if active-state? is true (default value)"
|
||||
(h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}])
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 1 account)})])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press-out (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
|
@ -38,8 +50,9 @@
|
|||
|
||||
(h/test "on-press-out changes state to :default if active-state? is false"
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
{:accounts (repeat 1 account)
|
||||
:active-state? false}])
|
||||
(with-defaults
|
||||
{:accounts (repeat 1 account)
|
||||
:active-state? false})])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press-out (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
|
@ -47,9 +60,9 @@
|
|||
|
||||
(h/test "on-press calls on-press"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider
|
||||
[saved-contact-address/view
|
||||
{:on-press on-press
|
||||
:accounts (repeat 1 account)}])
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:on-press on-press
|
||||
:accounts (repeat 1 account)})])
|
||||
(h/fire-event :on-press (h/get-by-label-text :container))
|
||||
(h/was-called on-press))))
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
(ns quo.components.list-items.saved-contact-address.schema)
|
||||
|
||||
(def ^:private ?contact
|
||||
[:map
|
||||
[:full-name :string]
|
||||
[:profile-picture {:optional true} [:maybe [:or :schema.common/image-source :string]]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]])
|
||||
|
||||
(def ^:private ?account
|
||||
[:map
|
||||
[:name :string]
|
||||
[:address :string]
|
||||
[:emoji {:optional true} :string]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]])
|
||||
|
||||
(def ^:private ?accounts
|
||||
[:+ ?account])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map
|
||||
[:contact-props ?contact]
|
||||
[:accounts {:optional true} ?accounts]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:theme :schema.common/theme]
|
||||
[:active-state? {:optional true} [:maybe :boolean]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]
|
||||
:any])
|
|
@ -3,12 +3,14 @@
|
|||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.saved-contact-address.schema :as component-schema]
|
||||
[quo.components.list-items.saved-contact-address.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]
|
||||
[utils.address :as address]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
|
@ -92,4 +94,6 @@
|
|||
colors/neutral-40
|
||||
theme)}])]))))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
|
|
|
@ -8,40 +8,36 @@
|
|||
{:token :snt
|
||||
:state :default
|
||||
:label "Status"
|
||||
:networks [(resources/get-network :ethereum)]
|
||||
:networks [{:source (resources/get-network :ethereum)}]
|
||||
:token-value "100.00 SNT"
|
||||
:fiat-value "€0.00"})
|
||||
|
||||
(h/describe "List items: Token network"
|
||||
(h/test "default state"
|
||||
(h/render [token-network/view (dissoc props :state)])
|
||||
(h/render-with-theme-provider [token-network/view (dissoc props :state)])
|
||||
(h/is-truthy (h/get-by-text "Status")))
|
||||
|
||||
(h/test "default state explicit"
|
||||
(h/render [token-network/view props])
|
||||
(h/render-with-theme-provider [token-network/view props])
|
||||
(h/is-truthy (h/get-by-text "Status")))
|
||||
|
||||
(h/test "Pressed state"
|
||||
(h/render [token-network/view props])
|
||||
(h/render-with-theme-provider [token-network/view props])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :token-network))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :token-network)
|
||||
{:backgroundColor (colors/resolve-color :blue :light 5)})))
|
||||
|
||||
(h/test "Active state"
|
||||
(h/render [token-network/view (assoc props :state :active)])
|
||||
(h/render-with-theme-provider [token-network/view (assoc props :state :active)])
|
||||
(h/has-style (h/query-by-label-text :token-network)
|
||||
{:backgroundColor (colors/resolve-color :blue :light 10)}))
|
||||
|
||||
(h/test "Selected state"
|
||||
(h/render [token-network/view (assoc props :state :selected)])
|
||||
(h/render-with-theme-provider [token-network/view (assoc props :state :selected)])
|
||||
(h/is-truthy (h/query-by-label-text :check-icon)))
|
||||
|
||||
(h/test "Call on-press"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render [token-network/view (assoc props :on-press on-press)])
|
||||
(h/render-with-theme-provider [token-network/view (assoc props :on-press on-press)])
|
||||
(h/fire-event :on-press (h/get-by-label-text :token-network))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "Empty props"
|
||||
(h/render [token-network/view {}])
|
||||
(h/is-truthy (h/get-by-label-text :token-network))))
|
||||
(h/was-called on-press))))
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
(ns quo.components.list-items.token-network.schema)
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map
|
||||
[:token :keyword]
|
||||
[:label :string]
|
||||
[:token-value :string]
|
||||
[:fiat-value :string]
|
||||
[:networks [:* [:map [:source :schema.common/image-source]]]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:state {:optional true} [:enum :default :active :selected]]
|
||||
[:theme :schema.common/theme]]]
|
||||
:any])
|
|
@ -2,12 +2,14 @@
|
|||
(:require
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.preview-list.view :as preview-list]
|
||||
[quo.components.list-items.token-network.schema :as component-schema]
|
||||
[quo.components.list-items.token-network.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- info
|
||||
[{:keys [token label networks]}]
|
||||
|
@ -67,4 +69,6 @@
|
|||
[info props]
|
||||
[values props]]))))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'view-internal component-schema/?schema)))
|
||||
|
|
|
@ -5,29 +5,29 @@
|
|||
|
||||
(h/describe "List Items: Token Value"
|
||||
(h/test "Token label renders"
|
||||
(h/render [token-value/view
|
||||
{:token :snt
|
||||
:token-name "Status"
|
||||
:state :default
|
||||
:status :empty
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:values {:crypto-value "0.00"
|
||||
:fiat-value "€0.00"
|
||||
:percentage-change "0.00"
|
||||
:fiat-change "€0.00"}}])
|
||||
(h/render-with-theme-provider [token-value/view
|
||||
{:token :snt
|
||||
:token-name "Status"
|
||||
:state :default
|
||||
:status :empty
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:values {:crypto-value "0.00"
|
||||
:fiat-value "€0.00"
|
||||
:percentage-change "0.00"
|
||||
:fiat-change "€0.00"}}])
|
||||
(h/is-truthy (h/get-by-text "Status")))
|
||||
|
||||
(h/test "Status change"
|
||||
(h/render [token-value/view
|
||||
{:token :snt
|
||||
:token-name "Status"
|
||||
:state :default
|
||||
:status :positive
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:values {:crypto-value "0.00"
|
||||
:fiat-value "€0.00"
|
||||
:percentage-change "0.00"
|
||||
:fiat-change "€0.00"}}])
|
||||
(h/render-with-theme-provider [token-value/view
|
||||
{:token :snt
|
||||
:token-name "Status"
|
||||
:state :default
|
||||
:status :positive
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:values {:crypto-value "0.00"
|
||||
:fiat-value "€0.00"
|
||||
:percentage-change "0.00"
|
||||
:fiat-change "€0.00"}}])
|
||||
(h/is-truthy (h/get-by-label-text :arrow-icon))))
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
(ns quo.components.list-items.token-value.schema)
|
||||
|
||||
(def ^:private ?values
|
||||
[:map
|
||||
[:crypto-value :string]
|
||||
[:fiat-value :string]
|
||||
[:percentage-change {:optional true} :string]
|
||||
[:fiat-change {:optional true} :string]])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map
|
||||
[:token [:or keyword? string?]]
|
||||
[:token-name :string]
|
||||
[:status [:enum :empty :positive :negative]]
|
||||
[:values ?values]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:on-long-press {:optional true} [:maybe fn?]]
|
||||
[:theme :schema.common/theme]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:metrics? {:optional true} [:maybe :boolean]]]]
|
||||
:any])
|
|
@ -2,13 +2,15 @@
|
|||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.token-value.schema :as component-schema]
|
||||
[quo.components.list-items.token-value.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- internal-view
|
||||
[]
|
||||
|
@ -65,4 +67,6 @@
|
|||
[icon/icon (if (= status :positive) :i/positive :i/negative)
|
||||
(style/arrow-icon status theme)]])])]]))))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
|
|
|
@ -10,5 +10,5 @@
|
|||
[:format {:optional true} [:enum :short :long]]
|
||||
[:theme :schema.common/theme]
|
||||
[:networks {:optional true}
|
||||
[:maybe [:sequential [:map [:name :keyword] [:short-name :string]]]]]]]]
|
||||
[:maybe [:sequential [:map [:network-name :keyword] [:short-name :string]]]]]]]]
|
||||
:any])
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
(let [network-text-xf (map #(colored-network-text theme %))
|
||||
address-text [text/text
|
||||
{:size :paragraph-2
|
||||
;; TODO: monospace font https://github.com/status-im/status-mobile/issues/17009
|
||||
;; TODO: monospace font
|
||||
;; https://github.com/status-im/status-mobile/issues/17009
|
||||
:weight :monospace
|
||||
:style (style/address-text format blur? theme)}
|
||||
(if (= format :short)
|
||||
|
|
|
@ -12,9 +12,8 @@
|
|||
:type :default
|
||||
:name "Trip to Vegas"
|
||||
:address "0x0ah...71a"}
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:state :default
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:action :none}])
|
||||
|
||||
(def default-details
|
||||
|
|
|
@ -86,6 +86,10 @@
|
|||
colors/white-opa-40
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}]])]))
|
||||
|
||||
(defn- acc-list-card
|
||||
[item & _rest]
|
||||
[account-list-card/view item])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [default-selected?]}]
|
||||
(let [selected? (reagent/atom default-selected?)]
|
||||
|
@ -102,7 +106,7 @@
|
|||
[details-view props]]]
|
||||
[rn/flat-list
|
||||
{:data accounts
|
||||
:render-fn account-list-card/view
|
||||
:render-fn acc-list-card
|
||||
:separator [rn/view {:style {:height 8}}]
|
||||
:style {:padding-horizontal 8}}]])))
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
:type :default
|
||||
:label "Drawer label"
|
||||
:keycard? true
|
||||
:networks [{:name :ethereum :short-name "eth"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}]
|
||||
:description "0x62b...0a5"
|
||||
:button-icon :i/placeholder
|
||||
:community-name "Coinbase"
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
{:type :account
|
||||
:blur? false
|
||||
:title "Collectibles vault"
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:description "0x0ah...78b"
|
||||
:account-avatar-emoji "🍿"
|
||||
:customization-color (or customization-color :blue)}]
|
||||
|
|
|
@ -43,9 +43,14 @@
|
|||
:show-blur-background? true
|
||||
:blur-dark-only? true}
|
||||
[quo/account-item
|
||||
(merge @state
|
||||
{:title-icon (when (:title-icon? @state) :i/keycard)
|
||||
:account-props {:name (:title @state)
|
||||
:address (:address @state)
|
||||
:emoji (:emoji @state)
|
||||
:customization-color (:account-color @state)}})]])))
|
||||
(dissoc (merge @state
|
||||
{:title-icon (when (:title-icon? @state) :i/keycard)
|
||||
:account-props {:name (:title @state)
|
||||
:address (:address @state)
|
||||
:emoji (:emoji @state)
|
||||
:customization-color (:account-color @state)}})
|
||||
:emoji
|
||||
:address
|
||||
:title-icon?
|
||||
:account-color
|
||||
:title)]])))
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
:type :default
|
||||
:name "Trip to Vegas"
|
||||
:address "0x0ah...78b"}
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:action :none
|
||||
:on-press (fn [] (js/alert "Item pressed"))
|
||||
:on-options-press (fn [] (js/alert "Options pressed"))
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:address "0x0ah...78b"
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]})]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]})]
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
:type :default
|
||||
:name "Trip to Vegas"
|
||||
:address "0x0ah...71a"}
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:state :default
|
||||
:action :none}
|
||||
{:account-props {:customization-color :purple
|
||||
|
@ -22,8 +22,8 @@
|
|||
:type :default
|
||||
:name "My savings"
|
||||
:address "0x0ah...72b"}
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:state :default
|
||||
:action :none}
|
||||
{:account-props {:customization-color :army
|
||||
|
@ -32,8 +32,8 @@
|
|||
:type :default
|
||||
:name "Coin vault"
|
||||
:address "0x0ah...73c"}
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:state :default
|
||||
:action :none}
|
||||
{:account-props {:customization-color :orange
|
||||
|
@ -42,8 +42,8 @@
|
|||
:type :default
|
||||
:name "Crypto fortress"
|
||||
:address "0x0ah...74e"}
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:state :default
|
||||
:action :none}
|
||||
{:account-props {:customization-color :yellow
|
||||
|
@ -52,8 +52,8 @@
|
|||
:type :default
|
||||
:name "Block treasure"
|
||||
:address "0x0ah...75f"}
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:state :default
|
||||
:action :none}])
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
[status-im.contexts.wallet.home.tabs.assets.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- token-value
|
||||
[item & _rest]
|
||||
[quo/token-value item])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
|
@ -15,6 +19,6 @@
|
|||
:parent-height 560
|
||||
:animated? false}]
|
||||
[rn/flat-list
|
||||
{:render-fn quo/token-value
|
||||
{:render-fn token-value
|
||||
:data tokens
|
||||
:content-container-style style/list-container}])))
|
||||
|
|
Loading…
Reference in New Issue