Implement account_card and variants (#16801)
* Implement account_card and variants with tests
This commit is contained in:
parent
1a97731454
commit
7c73b7ea12
|
@ -0,0 +1,62 @@
|
|||
(ns quo2.components.wallet.account-card.component-spec
|
||||
(:require [quo2.components.wallet.account-card.view :as account-card]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(def username "Alisher account")
|
||||
(def empty-username "Account 1")
|
||||
|
||||
(defn get-test-data
|
||||
[type watch-only? empty? loading? metrics?]
|
||||
{:name (if empty? empty-username username)
|
||||
:balance "€1,000.00"
|
||||
:percentage-value "50%"
|
||||
:amount "€500.00"
|
||||
:customization-color :blue
|
||||
:watch-only? watch-only?
|
||||
:loading? loading?
|
||||
:metrics? metrics?
|
||||
:type type})
|
||||
|
||||
(h/describe "Account_card tests"
|
||||
(h/test "Renders Default"
|
||||
(let [data (get-test-data :default false false false true)]
|
||||
(h/render [account-card/view data])
|
||||
(h/is-truthy (h/get-by-text username))))
|
||||
|
||||
(h/test "Renders Watch-Only"
|
||||
(let [data (get-test-data :watch-only true false false true)]
|
||||
(h/render [account-card/view data])
|
||||
(h/is-truthy (h/get-by-text username))))
|
||||
|
||||
(h/test "Renders Add-Account"
|
||||
(let [data {:type :add-account}]
|
||||
(h/render [account-card/view data])
|
||||
(h/is-truthy (h/get-by-label-text :add-account))))
|
||||
|
||||
(h/test "Renders Empty"
|
||||
(let [data (get-test-data :empty false true false true)]
|
||||
(h/render [account-card/view data])
|
||||
(h/is-truthy (h/get-by-text empty-username))))
|
||||
|
||||
(h/test "Add account on press fires correctly"
|
||||
(let [on-press (h/mock-fn)
|
||||
data {:type :add-account
|
||||
:on-press on-press}]
|
||||
(h/render [account-card/view data])
|
||||
(h/fire-event :on-press (h/get-by-label-text :add-account))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "Renders component without metrics"
|
||||
(let [data (get-test-data :default false false false false)]
|
||||
(h/render [account-card/view data])
|
||||
(h/is-falsy (h/query-by-label-text :metrics))))
|
||||
|
||||
(h/test "Renders loading state"
|
||||
(let [data (get-test-data :default false false true true)]
|
||||
(h/render [account-card/view data])
|
||||
(h/is-truthy (h/get-by-label-text :loading))))
|
||||
|
||||
(h/test "Renders loading state without metrics"
|
||||
(let [data (get-test-data :default false false true false)]
|
||||
(h/render [account-card/view data])
|
||||
(h/is-falsy (h/query-by-label-text :metrics)))))
|
|
@ -0,0 +1,95 @@
|
|||
(ns quo2.components.wallet.account-card.style
|
||||
(:require
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn text-color
|
||||
[watch-only? theme]
|
||||
(if (and watch-only? (= :light theme))
|
||||
colors/neutral-100
|
||||
colors/white))
|
||||
|
||||
(defn card
|
||||
[customization-color watch-only? metrics? theme]
|
||||
{:width 162
|
||||
:height (if metrics? 88 68)
|
||||
:background-color (if watch-only?
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/neutral-95 theme)
|
||||
(colors/theme-colors
|
||||
(colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
theme))
|
||||
:border-radius 16
|
||||
:border-width 1
|
||||
:border-color (if watch-only?
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)
|
||||
colors/neutral-80-opa-10)
|
||||
:padding-horizontal 12
|
||||
:padding-top 6
|
||||
:padding-bottom 10})
|
||||
|
||||
(def profile-container
|
||||
{:margin-bottom 6
|
||||
:flex-direction :row})
|
||||
|
||||
(def metrics-container
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defn account-name
|
||||
[watch-only? theme]
|
||||
{:color (text-color watch-only? theme)
|
||||
:margin-left 2})
|
||||
|
||||
(def watch-only-container
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:flex 1})
|
||||
|
||||
(defn account-value
|
||||
[watch-only? theme]
|
||||
{:color (text-color watch-only? theme)})
|
||||
|
||||
(defn metrics
|
||||
[watch-only? theme]
|
||||
{:color (if (and watch-only? (= :light theme))
|
||||
colors/neutral-80-opa-60
|
||||
colors/white-opa-70)})
|
||||
|
||||
(defn separator
|
||||
[watch-only? theme]
|
||||
{:width 2
|
||||
:height 2
|
||||
:border-radius 20
|
||||
:background-color (if (and watch-only? (= :light theme))
|
||||
colors/neutral-80-opa-20
|
||||
colors/white-opa-40)
|
||||
:margin-horizontal 4})
|
||||
|
||||
(defn add-account-container
|
||||
[theme metrics?]
|
||||
{:width 161
|
||||
:height (if metrics? 88 68)
|
||||
:border-color (colors/theme-colors colors/neutral-20 colors/white-opa-5 theme)
|
||||
:border-width 1
|
||||
:border-style :dashed
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius 16
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 10})
|
||||
|
||||
(def emoji
|
||||
{:font-size 10
|
||||
:line-height 20})
|
||||
|
||||
(defn loader-view
|
||||
[width height watch-only? theme]
|
||||
{:width width
|
||||
:height height
|
||||
:background-color (if (and watch-only? (= :light theme)) colors/neutral-80-opa-5 colors/white-opa-10)
|
||||
:border-radius 6})
|
||||
|
||||
(def loader-container
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
|
@ -0,0 +1,122 @@
|
|||
(ns quo2.components.wallet.account-card.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.wallet.account-card.style :as style]
|
||||
[quo2.components.buttons.button.view :as button]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[utils.i18n :as i18n]
|
||||
[quo2.theme :as theme]))
|
||||
|
||||
(defn- loading-view
|
||||
[{:keys [customization-color type theme metrics?]}]
|
||||
(let [watch-only? (= :watch-only type)
|
||||
empty? (= :empty type)]
|
||||
[rn/view
|
||||
{:accessibility-label :loading
|
||||
:style (style/card customization-color watch-only? metrics? theme)}
|
||||
[rn/view {:style style/loader-container}
|
||||
[rn/view
|
||||
{:style (assoc (style/loader-view 16
|
||||
16
|
||||
watch-only?
|
||||
theme)
|
||||
:margin-right 8
|
||||
:margin-top 2)}]
|
||||
[rn/view {:style style/watch-only-container}
|
||||
[rn/view {:style (style/loader-view 57 8 watch-only? theme)}]
|
||||
(when watch-only? [icon/icon :reveal {:color colors/neutral-50 :size 12}])]]
|
||||
[rn/view
|
||||
{:style (assoc (style/loader-view
|
||||
(if empty? 56 80)
|
||||
16
|
||||
watch-only?
|
||||
theme)
|
||||
:margin-top
|
||||
13)}]
|
||||
(when metrics?
|
||||
[rn/view
|
||||
{:accessibility-label :metrics
|
||||
:style (assoc (style/loader-view
|
||||
(if empty? 37 96)
|
||||
8
|
||||
watch-only?
|
||||
theme)
|
||||
:margin-top
|
||||
10)}])]))
|
||||
|
||||
(defn- user-account
|
||||
[{:keys [state name balance percentage-value loading? amount customization-color type emoji metrics?
|
||||
theme]}]
|
||||
(let [watch-only? (= :watch-only type)
|
||||
empty? (= :empty type)
|
||||
account-amount (if (= :empty state) "€0.00" amount)
|
||||
account-name (if (= :empty state) (i18n/label :t/Account 1) name)
|
||||
account-percentage (if (= :empty state) "€0.00" percentage-value)]
|
||||
(if loading?
|
||||
[loading-view
|
||||
{:customization-color customization-color
|
||||
:type type
|
||||
:theme theme
|
||||
:metrics? metrics?}]
|
||||
[:<>
|
||||
[rn/view {:style (style/card customization-color watch-only? metrics? theme)}
|
||||
[rn/view {:style style/profile-container}
|
||||
[rn/view {:style {:padding-bottom 2 :margin-right 2}}
|
||||
[text/text {:style style/emoji} emoji]]
|
||||
[rn/view {:style style/watch-only-container}
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/account-name watch-only? theme)}
|
||||
account-name]
|
||||
(when watch-only? [icon/icon :reveal {:color colors/neutral-50 :size 12}])]]
|
||||
[text/text
|
||||
{:size :heading-2
|
||||
:weight :semi-bold
|
||||
:style (style/account-value watch-only? theme)}
|
||||
balance]
|
||||
(when metrics?
|
||||
[rn/view {:style style/metrics-container}
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:accessibility-label :metrics
|
||||
:style (style/metrics watch-only? theme)}
|
||||
account-percentage]
|
||||
(when (not empty?)
|
||||
[:<>
|
||||
[rn/view (style/separator watch-only? theme)]
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/metrics watch-only? theme)} account-amount]
|
||||
[rn/view {:style {:margin-left 4}}
|
||||
[icon/icon :positive
|
||||
{:color (if (and watch-only? (not (colors/dark?)))
|
||||
colors/neutral-50
|
||||
colors/white-opa-70)
|
||||
:size 16}]]])])]])))
|
||||
|
||||
(defn- add-account-view
|
||||
[{:keys [on-press customization-color theme metrics?]}]
|
||||
[rn/view (style/add-account-container theme metrics?)
|
||||
[button/button
|
||||
{:type :primary
|
||||
:size 24
|
||||
:icon true
|
||||
:accessibility-label :add-account
|
||||
:on-press on-press
|
||||
:customization-color customization-color}
|
||||
:i/add]])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type] :as props}]
|
||||
(case type
|
||||
:watch-only [user-account props]
|
||||
:add-account [add-account-view props]
|
||||
:default [user-account props]
|
||||
:empty [user-account props]
|
||||
nil))
|
||||
|
||||
(def view (theme/with-theme view-internal))
|
|
@ -103,7 +103,8 @@
|
|||
quo2.components.tags.token-tag
|
||||
quo2.components.text-combinations.title.view
|
||||
quo2.components.wallet.network-amount.view
|
||||
quo2.components.wallet.network-bridge.view))
|
||||
quo2.components.wallet.network-bridge.view
|
||||
quo2.components.wallet.account-card.view))
|
||||
|
||||
(def separator quo2.components.common.separator.view/separator)
|
||||
|
||||
|
@ -295,3 +296,4 @@
|
|||
;;;; WALLET
|
||||
(def network-amount quo2.components.wallet.network-amount.view/view)
|
||||
(def network-bridge quo2.components.wallet.network-bridge.view/view)
|
||||
(def account-card quo2.components.wallet.account-card.view/view)
|
||||
|
|
|
@ -49,4 +49,5 @@
|
|||
[quo2.components.share.share-qr-code.component-spec]
|
||||
[quo2.components.tags.status-tags-component-spec]
|
||||
[quo2.components.wallet.network-amount.component-spec]
|
||||
[quo2.components.wallet.network-bridge.component-spec]))
|
||||
[quo2.components.wallet.network-bridge.component-spec]
|
||||
[quo2.components.wallet.account-card.component-spec]))
|
||||
|
|
|
@ -103,7 +103,8 @@
|
|||
[status-im2.contexts.quo-preview.community.channel-actions :as channel-actions]
|
||||
[status-im2.contexts.quo-preview.gradient.gradient-cover :as gradient-cover]
|
||||
[status-im2.contexts.quo-preview.wallet.network-amount :as network-amount]
|
||||
[status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge]))
|
||||
[status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge]
|
||||
[status-im2.contexts.quo-preview.wallet.account-card :as account-card]))
|
||||
|
||||
(def screens-categories
|
||||
{:foundations [{:name :shadows
|
||||
|
@ -394,7 +395,10 @@
|
|||
:text-combinations [{:name :title
|
||||
:options {:topBar {:visible true}}
|
||||
:component title/preview-title}]
|
||||
:wallet [{:name :network-amount
|
||||
:wallet [{:name :account-card
|
||||
:options {:topBar {:visible true}}
|
||||
:component account-card/preview-account-card}
|
||||
{:name :network-amount
|
||||
:options {:topBar {:visible true}}
|
||||
:component network-amount/preview}
|
||||
{:name :network-bridge
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
(ns status-im2.contexts.quo-preview.wallet.account-card
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.core :as quo]
|
||||
[quo2.components.icon :as icon]
|
||||
[reagent.core :as reagent]
|
||||
[utils.collection]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Type:"
|
||||
:key :type
|
||||
:type :select
|
||||
:options [{:key :default
|
||||
:value "Default"}
|
||||
{:key :watch-only
|
||||
:value "Watch Only"}
|
||||
{:key :add-account
|
||||
:value "Add Account"}
|
||||
{:key :empty
|
||||
:value "Empty"}]}
|
||||
{:label "Customization color:"
|
||||
:key :customization-color
|
||||
:type :select
|
||||
:options (map (fn [[color-kw _]]
|
||||
{:key color-kw
|
||||
:value (name color-kw)})
|
||||
colors/customization)}
|
||||
{:label "Name:"
|
||||
:key :name
|
||||
:type :text}
|
||||
{:label "Balance:"
|
||||
:key :balance
|
||||
:type :text}
|
||||
{:label "Percentage value:"
|
||||
:key :percentage-value
|
||||
:type :text}
|
||||
{:label "Amount:"
|
||||
:key :amount
|
||||
:type :text}
|
||||
{:label "Metrics:"
|
||||
:key :metrics?
|
||||
:type :boolean}
|
||||
{:label "Loading:"
|
||||
:key :loading?
|
||||
:type :boolean}
|
||||
{:label "Emoji:"
|
||||
:key :emoji
|
||||
:type :text}])
|
||||
|
||||
(defn initial-state
|
||||
[type]
|
||||
(case type
|
||||
:default
|
||||
{:name "Alisher account"
|
||||
:balance "€2,269.12"
|
||||
:percentage-value "16.9%"
|
||||
:amount "€570.24"
|
||||
:customization-color :turquoise
|
||||
:metrics? true
|
||||
:type :default
|
||||
:emoji "💎"}
|
||||
|
||||
:empty
|
||||
{:name "Account 1"
|
||||
:balance "€0.00"
|
||||
:percentage-value "€0.00"
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:type :empty
|
||||
:emoji "🍑"}
|
||||
|
||||
:watch-only
|
||||
{:name "Alisher account"
|
||||
:balance "€2,269.12"
|
||||
:percentage-value "16.9%"
|
||||
:amount "€570.24"
|
||||
:metrics? true
|
||||
:type :watch-only
|
||||
:emoji "💸"}
|
||||
|
||||
:add-account
|
||||
{:customization-color :blue
|
||||
:on-press #(js/alert "Button pressed")
|
||||
:metrics? true
|
||||
:type :add-account}))
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom (initial-state :default))]
|
||||
[:f>
|
||||
(fn []
|
||||
(rn/use-effect
|
||||
(fn [] (reset! state (initial-state (:type @state))))
|
||||
[(:type @state)])
|
||||
[rn/view
|
||||
{:style {:flex 1}}
|
||||
[rn/view
|
||||
{:style {:margin-vertical 40
|
||||
:padding-left 40
|
||||
:flex-direction :row
|
||||
:align-items :center}}
|
||||
[text/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold}
|
||||
"Account card"]
|
||||
[rn/view
|
||||
{:style {:width 20
|
||||
:height 20
|
||||
:border-radius 60
|
||||
:background-color colors/success-50
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:margin-left 8}}
|
||||
[icon/icon :i/check {:color colors/white :size 16}]]]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view {:style {:align-items :center :margin-top 40}}
|
||||
[quo/account-card @state]]])]))
|
||||
|
||||
(defn preview-account-card
|
||||
[]
|
||||
[rn/view
|
||||
{:background-color (colors/theme-colors colors/white
|
||||
colors/neutral-90)
|
||||
:flex 1}
|
||||
[rn/flat-list
|
||||
{:flex 1
|
||||
:keyboard-should-persist-taps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
Loading…
Reference in New Issue