Implement `Account Avatar` Component (#16795)
This commit implements the "Account Avatar" component which is needed for wallet screen development. Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
parent
96ff8ab382
commit
81b8c7ca65
|
@ -1,41 +0,0 @@
|
|||
(ns quo2.components.avatars.account-avatar
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn get-border-radius
|
||||
[size]
|
||||
(case size
|
||||
80 16
|
||||
48 12
|
||||
32 10
|
||||
24 8
|
||||
20 6))
|
||||
|
||||
(defn get-inner-icon-sizes
|
||||
[size]
|
||||
(case size
|
||||
80 36
|
||||
48 24
|
||||
32 15
|
||||
24 11
|
||||
20 11))
|
||||
|
||||
(defn account-avatar
|
||||
[{:keys [size icon color]
|
||||
:or {size 80
|
||||
icon :i/placeholder
|
||||
color :purple}}]
|
||||
(let [icon-color (colors/custom-color-by-theme color 50 60)
|
||||
avatar-border-radius (get-border-radius size)
|
||||
inner-icon-size (get-inner-icon-sizes size)]
|
||||
[rn/view
|
||||
{:style {:width size
|
||||
:background-color icon-color
|
||||
:height size
|
||||
:border-radius avatar-border-radius
|
||||
:justify-content :center
|
||||
:align-items :center}}
|
||||
[icons/icon icon
|
||||
{:no-color true
|
||||
:size inner-icon-size}]]))
|
|
@ -0,0 +1,90 @@
|
|||
(ns quo2.components.avatars.account-avatar.component-spec
|
||||
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo2.components.avatars.account-avatar.style :as style]
|
||||
[test-helpers.component :as h]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(h/describe "Account Avatar"
|
||||
(h/test "default render"
|
||||
(h/render [account-avatar/view])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji)))
|
||||
|
||||
(h/test "with emoji"
|
||||
(let [emoji "💸"]
|
||||
(h/render [account-avatar/view {:emoji emoji :size 80}])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/is-truthy (h/query-by-text emoji))))
|
||||
|
||||
(h/test "size 80 with emoji, with type - default"
|
||||
(let [opts {:emoji "🏝️"
|
||||
:size 80
|
||||
:type :default
|
||||
:customization-color :blue}]
|
||||
(h/render [account-avatar/view opts])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/has-style (h/get-by-label-text :account-avatar)
|
||||
{:height (:size opts)
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 60)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 48 with emoji, with type - watch only"
|
||||
(let [opts {:emoji "💵"
|
||||
:size 48
|
||||
:type :watch-only
|
||||
:customization-color :purple}]
|
||||
(h/render [account-avatar/view opts])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/has-style
|
||||
(h/get-by-label-text :account-avatar)
|
||||
{:height (:size opts)
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:borderWidth 1
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 50 10 10)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 28 with emoji, with type - default"
|
||||
(let [opts {:emoji "🏝️"
|
||||
:size 28
|
||||
:type :default
|
||||
:customization-color :turquoise}]
|
||||
(h/render [account-avatar/view opts])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/has-style (h/get-by-label-text :account-avatar)
|
||||
{:height (:size opts)
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 60)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 16 with emoji, with type - watch only"
|
||||
(let [opts {:emoji "🎉"
|
||||
:size 16
|
||||
:type :watch-only
|
||||
:customization-color :copper}]
|
||||
(h/render [account-avatar/view opts])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/has-style
|
||||
(h/get-by-label-text :account-avatar)
|
||||
{:height (:size opts)
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:borderWidth 0.8
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 50 10 10)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts))))))
|
|
@ -0,0 +1,69 @@
|
|||
(ns quo2.components.avatars.account-avatar.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def default-size 80)
|
||||
(def default-border-radius 16)
|
||||
(def default-padding 16)
|
||||
(def default-emoji-size 36)
|
||||
|
||||
(defn get-border-radius
|
||||
[size]
|
||||
(case size
|
||||
80 16
|
||||
48 12
|
||||
32 10
|
||||
28 8
|
||||
24 8
|
||||
20 6
|
||||
16 4
|
||||
default-border-radius))
|
||||
|
||||
(defn get-padding
|
||||
[size]
|
||||
(case size
|
||||
80 16
|
||||
48 8
|
||||
32 6
|
||||
28 6
|
||||
24 6
|
||||
20 4
|
||||
16 2
|
||||
default-padding))
|
||||
|
||||
(defn get-emoji-size
|
||||
[size]
|
||||
(case size
|
||||
80 36
|
||||
48 24
|
||||
32 15
|
||||
28 12
|
||||
24 11
|
||||
20 11
|
||||
16 11
|
||||
default-emoji-size))
|
||||
|
||||
(defn get-border-width
|
||||
[size]
|
||||
(case size
|
||||
16 0.8 ;; 0.8 px is for only size 16
|
||||
;; Rest of the size will have 1 px
|
||||
1))
|
||||
|
||||
(defn root-container
|
||||
[{:keys [type size theme customization-color]
|
||||
:or {size default-size
|
||||
customization-color :blue}}]
|
||||
(let [watch-only? (= type :watch-only)]
|
||||
(cond-> {:width size
|
||||
:height size
|
||||
:background-color (colors/custom-color-by-theme customization-color 50 60 nil nil theme)
|
||||
:border-radius (get-border-radius size)
|
||||
:border-color (if (= theme :light) colors/neutral-80-opa-5 colors/white-opa-5)
|
||||
:padding (get-padding size)
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
|
||||
watch-only?
|
||||
(assoc :border-width (get-border-width size)
|
||||
:background-color (colors/custom-color-by-theme customization-color 50 50 10 10 theme)))))
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
(ns quo2.components.avatars.account-avatar.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo2.components.avatars.account-avatar.style :as style]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- view-internal
|
||||
"Opts:
|
||||
|
||||
:type - keyword -> :default/:watch-only
|
||||
|
||||
:emoji - string -> 🍑 [default]
|
||||
|
||||
:size - number -> 80 [default] /48/32/28/24/20/16
|
||||
|
||||
:customization-color - keyword or hexstring -> :blue/:army/... or #ABCEDF
|
||||
|
||||
:theme - keyword -> :light/:dark"
|
||||
[{:keys [size emoji]
|
||||
:or {size style/default-size
|
||||
emoji "🍑"}
|
||||
:as opts}]
|
||||
(let [emoji-size (style/get-emoji-size size)]
|
||||
[rn/view
|
||||
{:accessible true
|
||||
:accessibility-label :account-avatar
|
||||
:style (style/root-container opts)}
|
||||
[rn/text
|
||||
{:accessibility-label :account-emoji
|
||||
:adjusts-font-size-to-fit true
|
||||
:style {:font-size emoji-size}}
|
||||
(string/trim emoji)]]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
|
@ -1,5 +1,5 @@
|
|||
(ns quo2.components.settings.accounts.view
|
||||
(:require [quo2.components.avatars.account-avatar :as account-avatar]
|
||||
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo2.components.buttons.button.view :as button]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.settings.accounts.style :as style]
|
||||
|
@ -14,7 +14,7 @@
|
|||
(defn avatar
|
||||
[avatar-props]
|
||||
[rn/view {:style (style/avatar-border)}
|
||||
[account-avatar/account-avatar (assoc avatar-props :size 48)]])
|
||||
[account-avatar/view (assoc avatar-props :size 48)]])
|
||||
|
||||
(defn menu-button
|
||||
[{:keys [on-press]}]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns quo2.components.tabs.account-selector
|
||||
(:require [quo2.components.markdown.text :as quo2]
|
||||
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo2.components.markdown.text :as quo2]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
|
@ -31,14 +32,9 @@
|
|||
{:height 16
|
||||
:width 16})
|
||||
|
||||
(def account-emoji-container
|
||||
{:background-color (colors/custom-color :purple 50)
|
||||
:padding 8
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:border-radius 10
|
||||
:margin-left 4
|
||||
:margin-right 8})
|
||||
(def account-avatar-container
|
||||
{:margin-left 4
|
||||
:margin-right 8})
|
||||
|
||||
(defn get-color-by-type
|
||||
[type k]
|
||||
|
@ -66,8 +62,8 @@
|
|||
:margin-bottom 8}}
|
||||
label-text])
|
||||
[rn/view {:style (account-container-row background-color)}
|
||||
[rn/view {:style account-emoji-container}
|
||||
[quo2/text account-emoji]]
|
||||
[rn/view {:style account-avatar-container}
|
||||
[account-avatar/view {:emoji account-emoji :size 32}]]
|
||||
[quo2/text
|
||||
{:weight :medium
|
||||
:size :paragraph-1
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns quo2.core
|
||||
(:refer-clojure :exclude [filter])
|
||||
(:require
|
||||
quo2.components.avatars.account-avatar
|
||||
quo2.components.avatars.account-avatar.view
|
||||
quo2.components.avatars.channel-avatar.view
|
||||
quo2.components.avatars.group-avatar
|
||||
quo2.components.avatars.icon-avatar
|
||||
|
@ -106,7 +106,7 @@
|
|||
(def separator quo2.components.common.separator.view/separator)
|
||||
|
||||
;;;; AVATAR
|
||||
(def account-avatar quo2.components.avatars.account-avatar/account-avatar)
|
||||
(def account-avatar quo2.components.avatars.account-avatar.view/view)
|
||||
(def channel-avatar quo2.components.avatars.channel-avatar.view/view)
|
||||
(def group-avatar quo2.components.avatars.group-avatar/group-avatar)
|
||||
(def icon-avatar quo2.components.avatars.icon-avatar/icon-avatar)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns quo2.core-spec
|
||||
(:require
|
||||
[quo2.components.avatars.account-avatar.component-spec]
|
||||
[quo2.components.avatars.user-avatar.component-spec]
|
||||
[quo2.components.banners.banner.component-spec]
|
||||
[quo2.components.buttons.button.component-spec]
|
||||
|
|
|
@ -1,50 +1,61 @@
|
|||
(ns status-im2.contexts.quo-preview.avatars.account-avatar
|
||||
(:require [quo2.components.avatars.account-avatar :as quo2]
|
||||
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Icon"
|
||||
:key :icon
|
||||
[{:label "Type"
|
||||
:key :type
|
||||
:type :select
|
||||
:options [{:key :main-icons/wallet
|
||||
:value "Wallet"}
|
||||
{:key :main-icons/token
|
||||
:value "Token"}
|
||||
{:key :main-icons/status
|
||||
:value "Status"}]}
|
||||
:options [{:key :default
|
||||
:value "default"}
|
||||
{:key :watch-only
|
||||
:value "watch only"}]}
|
||||
{:label "Size"
|
||||
:key :size
|
||||
:type :select
|
||||
:options [{:key 20
|
||||
:value "Small"}
|
||||
:options [{:key 16
|
||||
:value "16"}
|
||||
{:key 20
|
||||
:value "20"}
|
||||
{:key 24
|
||||
:value "Medium"}
|
||||
:value "24"}
|
||||
{:key 28
|
||||
:value "28"}
|
||||
{:key 32
|
||||
:value "Big"}
|
||||
:value "32"}
|
||||
{:key 48
|
||||
:value "Very big"}
|
||||
:value "48"}
|
||||
{:key 80
|
||||
:value "Seriously Big!"}]}])
|
||||
:value "80"}]}
|
||||
{:label "Emoji"
|
||||
:key :emoji
|
||||
:type :text}
|
||||
(preview/customization-color-option)])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:size 80
|
||||
:icon :main-icons/wallet})]
|
||||
(let [state (reagent/atom {:customization-color :purple
|
||||
:size 80
|
||||
:emoji "🍑"
|
||||
:type :default})]
|
||||
(fn []
|
||||
[rn/view
|
||||
{:margin-bottom 50
|
||||
:padding 16}
|
||||
{:style {:margin-bottom 50
|
||||
:padding 16}}
|
||||
[preview/customizer state descriptor]
|
||||
[rn/view
|
||||
{:padding-vertical 60
|
||||
:align-items :center}
|
||||
[quo2/account-avatar @state]]])))
|
||||
{:style {:padding-vertical 60
|
||||
:align-items :center}}
|
||||
[account-avatar/view @state]]])))
|
||||
|
||||
(defn preview-account-avatar
|
||||
[]
|
||||
[rn/view {:flex 1}
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95)}}
|
||||
[rn/flat-list
|
||||
{:flex 1
|
||||
:keyboard-should-persist-taps :always
|
||||
|
|
Loading…
Reference in New Issue