[#17974] text combinations - username component (#17987)

* Move docstring to be available while using `colors/resolve-color`
* Add text combinations - username component and tests
* Add username related svg icons
This commit is contained in:
Ulises Manuel 2023-12-07 17:44:24 -06:00 committed by GitHub
parent 55a99da2f5
commit de4e233884
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 275 additions and 12 deletions

View File

@ -118,13 +118,61 @@
"M2.79504 9.01494C2.89473 8.85584 3.00297 8.70977 3.11963 8.5761C3.90594 7.67512 4.97212 7.45024 5.99992 7.45024C7.02772 7.45024 8.0939 7.67512 8.88021 8.5761C8.99688 8.70978 9.10512 8.85585 9.2048 9.01495C8.9501 9.28561 8.66149 9.52401 8.34577 9.72335C8.25403 9.55824 8.15512 9.41818 8.05145 9.29939C7.56503 8.74204 6.88121 8.55024 5.99992 8.55024C5.11862 8.55024 4.43481 8.74204 3.94839 9.29939C3.84472 9.41818 3.74582 9.55824 3.65408 9.72334C3.33835 9.524 3.04975 9.2856 2.79504 9.01494ZM5.99992 3.5502C5.47525 3.5502 5.04992 3.97552 5.04992 4.5002C5.04992 5.02487 5.47525 5.4502 5.99992 5.4502C6.52459 5.4502 6.94992 5.02487 6.94992 4.5002C6.94992 3.97552 6.52459 3.5502 5.99992 3.5502ZM3.94992 4.5002C3.94992 3.36801 4.86773 2.4502 5.99992 2.4502C7.1321 2.4502 8.04992 3.36801 8.04992 4.5002C8.04992 5.63238 7.1321 6.5502 5.99992 6.5502C4.86773 6.5502 3.94992 5.63238 3.94992 4.5002Z" "M2.79504 9.01494C2.89473 8.85584 3.00297 8.70977 3.11963 8.5761C3.90594 7.67512 4.97212 7.45024 5.99992 7.45024C7.02772 7.45024 8.0939 7.67512 8.88021 8.5761C8.99688 8.70978 9.10512 8.85585 9.2048 9.01495C8.9501 9.28561 8.66149 9.52401 8.34577 9.72335C8.25403 9.55824 8.15512 9.41818 8.05145 9.29939C7.56503 8.74204 6.88121 8.55024 5.99992 8.55024C5.11862 8.55024 4.43481 8.74204 3.94839 9.29939C3.84472 9.41818 3.74582 9.55824 3.65408 9.72334C3.33835 9.524 3.04975 9.2856 2.79504 9.01494ZM5.99992 3.5502C5.47525 3.5502 5.04992 3.97552 5.04992 4.5002C5.04992 5.02487 5.47525 5.4502 5.99992 5.4502C6.52459 5.4502 6.94992 5.02487 6.94992 4.5002C6.94992 3.97552 6.52459 3.5502 5.99992 3.5502ZM3.94992 4.5002C3.94992 3.36801 4.86773 2.4502 5.99992 2.4502C7.1321 2.4502 8.04992 3.36801 8.04992 4.5002C8.04992 5.63238 7.1321 6.5502 5.99992 6.5502C4.86773 6.5502 3.94992 5.63238 3.94992 4.5002Z"
:fill color-2}]]) :fill color-2}]])
(defn- contact-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/circle
{:cx 10
:cy 10
:r 7.5
:fill color}]
[svg/path
{:d
"M8.65002 7.99998C8.65002 7.25439 9.25443 6.64998 10 6.64998C10.7456 6.64998 11.35 7.25439 11.35 7.99998C11.35 8.74556 10.7456 9.34998 10 9.34998C9.25443 9.34998 8.65002 8.74556 8.65002 7.99998ZM10 5.34998C8.53646 5.34998 7.35002 6.53642 7.35002 7.99998C7.35002 9.46353 8.53646 10.65 10 10.65C11.4636 10.65 12.65 9.46353 12.65 7.99998C12.65 6.53642 11.4636 5.34998 10 5.34998ZM10 13.65C8.67557 13.65 7.53064 14.4186 6.98692 15.5341C6.60094 15.3235 6.23942 15.0737 5.90771 14.79C6.69408 13.3369 8.23179 12.35 10 12.35C11.7682 12.35 13.306 13.3369 14.0923 14.79C13.7606 15.0737 13.3991 15.3235 13.0131 15.5341C12.4694 14.4186 11.3245 13.65 10 13.65Z"
:fill color-2}]])
(defn- verified-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d
"M18 10C18 8.77003 17.1118 7.74751 15.9418 7.53891C16.6216 6.56407 16.5267 5.21294 15.6569 4.34321C14.7872 3.47344 13.436 3.37852 12.4611 4.05845C12.2526 2.88834 11.23 2 10 2C8.77 2 7.74747 2.88827 7.53889 4.05832C6.56406 3.37846 5.21292 3.47339 4.34318 4.34313C3.47343 5.21288 3.3785 6.56404 4.05839 7.53888C2.88831 7.74743 2 8.76998 2 10C2 11.23 2.88824 12.2525 4.05826 12.4611C3.3784 13.4359 3.47333 14.7871 4.34307 15.6568C5.21284 16.5266 6.56403 16.6215 7.53887 15.9416C7.74741 17.1117 8.76996 18 10 18C11.23 18 12.2525 17.1117 12.4611 15.9417C13.4359 16.6215 14.7871 16.5266 15.6568 15.6569C16.5265 14.7871 16.6215 13.436 15.9416 12.4611C17.1117 12.2526 18 11.23 18 10Z"
:fill color}]
[svg/path
{:d "M7.25 10.75L9.25 12.25L12.75 7.75"
:stroke color-2
:stroke-width "1.2"}]])
(defn- untrustworthy-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d "M10 2L15.6569 4.34315L18 10L15.6569 15.6569L10 18L4.34315 15.6569L2 10L4.34315 4.34315L10 2Z"
:fill color}]
[svg/path
{:d
"M10.75 5.5L10.55 11.5H9.45L9.25 5.5H10.75ZM10 13C10.4142 13 10.75 13.3358 10.75 13.75C10.75 14.1642 10.4142 14.5 10 14.5C9.58579 14.5 9.25 14.1642 9.25 13.75C9.25 13.3358 9.58579 13 10 13Z"
:fill color-2}]])
(def ^:private icons (def ^:private icons
{:i/clear-20 clear-20 {:i/clear-20 clear-20
:i/dropdown-20 dropdown-20 :i/dropdown-20 dropdown-20
:i/pullup-20 pullup-20 :i/pullup-20 pullup-20
:i/dropdown-12 dropdown-12 :i/dropdown-12 dropdown-12
:i/pullup-12 pullup-12 :i/pullup-12 pullup-12
:i/contact-12 contact-12}) :i/contact-12 contact-12
:i/contact-20 contact-20
:i/verified-20 verified-20
:i/untrustworthy-20 untrustworthy-20})
(defn- append-to-keyword (defn- append-to-keyword
[k & xs] [k & xs]

View File

@ -0,0 +1,68 @@
(ns quo.components.text-combinations.username.component-spec
(:require [quo.components.text-combinations.username.view :as username]
[test-helpers.component :as h]))
(defn test-all-status
[component-to-render component-props]
(h/test "Verified status"
(h/render [component-to-render (assoc component-props :status :verified)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Contact status"
(h/render [component-to-render (assoc component-props :status :contact)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Untrustworthy status"
(h/render [component-to-render (assoc component-props :status :untrustworthy)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Untrustworthy contact status"
(h/render [component-to-render (assoc component-props :status :untrustworthy-contact)])
(let [icons (h/get-all-by-label-text :username-status-icon)]
(h/is-truthy (aget icons 0))
(h/is-truthy (aget icons 1))))
(h/test "Blocked status"
(h/render [component-to-render (assoc component-props :status :blocked)])
(h/is-truthy (h/get-by-label-text :username-status-icon))))
(h/describe "Text combinations - Username"
(h/test "Renders default"
(h/render [username/view {:username "Test username"}])
(h/is-truthy (h/get-by-text "Test username")))
(h/describe "Render different :name-type values"
(h/describe "default"
(let [props {:name-type :default
:username "Test username"}]
(h/test "default render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "Test username")))
(h/describe "All status are rendered"
(test-all-status username/view props))))
(h/describe "ens"
(let [props {:name-type :ens
:username "test-username.eth"}]
(h/test "no status render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "test-username.eth")))
(h/describe "All status are rendered"
(test-all-status username/view props))))
(h/describe "nickname"
(let [props {:name-type :nickname
:username "Nickname"
:name "Real name"}]
(h/test "no status render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "Nickname"))
(h/is-truthy (h/get-by-text "Real name")))
(h/describe "All status are rendered"
(test-all-status username/view props))))))

View File

@ -0,0 +1,30 @@
(ns quo.components.text-combinations.username.style
(:require [quo.foundations.colors :as colors]))
(def container
{:flex-direction :row
:height 32})
(def username-text-container
{:flex-direction :row
:align-items :flex-end})
(defn real-name-text
[theme blur?]
{:color (if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-60 colors/neutral-40 theme))})
(defn real-name-dot
[theme blur?]
(assoc (real-name-text theme blur?) :margin-horizontal 6))
(defn status-icon-container
[name-type status]
(cond-> {:flex-direction :row
:margin-left 4}
(#{:default :ens} name-type) (assoc :margin-top 8
:margin-bottom 4)
(= :nickname name-type) (assoc :margin-top 10
:margin-bottom 2)
(= status :untrustworthy-contact) (assoc :margin-right 2)))

View File

@ -0,0 +1,57 @@
(ns quo.components.text-combinations.username.view
(:require [quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.text-combinations.username.style :as style]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]))
(defn- username-text
[{:keys [theme name-type username blur?]
real-name :name}]
[rn/view {:style style/username-text-container}
[text/text
{:size :heading-1
:weight :semi-bold}
username]
(when (= name-type :nickname)
[:<>
[text/text
{:style (style/real-name-dot theme blur?)
:size :paragraph-1
:weight :medium}
"∙"]
[text/text
{:style (style/real-name-text theme blur?)
:size :paragraph-1
:weight :medium}
real-name]])])
(defn- icon-20
[icon-name theme color]
[icon/icon icon-name
{:accessibility-label :username-status-icon
:size 20
:color (colors/resolve-color color theme)}])
(defn status-icon
[{:keys [theme name-type status]
:or {name-type :default}}]
[rn/view {:style (style/status-icon-container name-type status)}
(case status
:verified [icon-20 :i/verified theme :success]
:contact [icon-20 :i/contact theme :blue]
:untrustworthy [icon-20 :i/untrustworthy theme :danger]
:blocked [icon-20 :i/block theme :danger]
:untrustworthy-contact [:<>
[icon-20 :i/untrustworthy theme :danger]
[icon-20 :i/contact theme :blue]]
nil)])
(defn view-internal
[props]
[rn/view {:style style/container}
[username-text props]
[status-icon props]])
(def view (quo.theme/with-theme view-internal))

View File

@ -141,6 +141,7 @@
quo.components.tags.token-tag.view quo.components.tags.token-tag.view
quo.components.text-combinations.channel-name.view quo.components.text-combinations.channel-name.view
quo.components.text-combinations.standard-title.view quo.components.text-combinations.standard-title.view
quo.components.text-combinations.username.view
quo.components.text-combinations.view quo.components.text-combinations.view
quo.components.wallet.account-card.view quo.components.wallet.account-card.view
quo.components.wallet.account-origin.view quo.components.wallet.account-origin.view
@ -385,6 +386,7 @@
(def channel-name quo.components.text-combinations.channel-name.view/view) (def channel-name quo.components.text-combinations.channel-name.view/view)
(def standard-title quo.components.text-combinations.standard-title.view/view) (def standard-title quo.components.text-combinations.standard-title.view/view)
(def text-combinations quo.components.text-combinations.view/view) (def text-combinations quo.components.text-combinations.view/view)
(def username quo.components.text-combinations.username.view/view)
;;;; Wallet ;;;; Wallet
(def account-card quo.components.wallet.account-card.view/view) (def account-card quo.components.wallet.account-card.view/view)

View File

@ -77,6 +77,7 @@
[quo.components.tags.summary-tag.component-spec] [quo.components.tags.summary-tag.component-spec]
[quo.components.tags.tiny-tag.component-spec] [quo.components.tags.tiny-tag.component-spec]
[quo.components.text-combinations.channel-name.component-spec] [quo.components.text-combinations.channel-name.component-spec]
[quo.components.text-combinations.username.component-spec]
[quo.components.wallet.account-card.component-spec] [quo.components.wallet.account-card.component-spec]
[quo.components.wallet.account-origin.component-spec] [quo.components.wallet.account-origin.component-spec]
[quo.components.wallet.account-overview.component-spec] [quo.components.wallet.account-overview.component-spec]

View File

@ -285,10 +285,6 @@
(get-in colors-map [color suffix])))) (get-in colors-map [color suffix]))))
(defn- resolve-color* (defn- resolve-color*
"(resolve-color color theme opacity)
color hex string or keyword (resolves from custom, network and semantic colors)
theme :light/:dark
opacity 0-100 (optional) - if set theme is ignored and goes to 50 suffix internally"
([color theme] ([color theme]
(resolve-color* color theme nil)) (resolve-color* color theme nil))
([color theme opacity] ([color theme opacity]
@ -300,7 +296,12 @@
suffix (get-from-colors-map suffix) suffix (get-from-colors-map suffix)
opacity (alpha (/ opacity 100)))))) opacity (alpha (/ opacity 100))))))
(def resolve-color (memoize resolve-color*)) (def resolve-color
"(resolve-color color theme opacity)
color hex string or keyword (resolves from custom, network and semantic colors)
theme :light/:dark
opacity 0-100 (optional) - if set theme is ignored and goes to 50 suffix internally"
(memoize resolve-color*))
(def ^{:deprecated true :superseded-by "resolve-color"} (def ^{:deprecated true :superseded-by "resolve-color"}
custom-color custom-color

View File

@ -166,6 +166,7 @@
[status-im2.contexts.quo-preview.text-combinations.preview :as [status-im2.contexts.quo-preview.text-combinations.preview :as
text-combinations] text-combinations]
[status-im2.contexts.quo-preview.text-combinations.standard-title :as standard-title] [status-im2.contexts.quo-preview.text-combinations.standard-title :as standard-title]
[status-im2.contexts.quo-preview.text-combinations.username :as username]
[status-im2.contexts.quo-preview.wallet.account-card :as account-card] [status-im2.contexts.quo-preview.wallet.account-card :as account-card]
[status-im2.contexts.quo-preview.wallet.account-origin :as account-origin] [status-im2.contexts.quo-preview.wallet.account-origin :as account-origin]
[status-im2.contexts.quo-preview.wallet.account-overview :as [status-im2.contexts.quo-preview.wallet.account-overview :as
@ -461,7 +462,9 @@
{:name :channel-name {:name :channel-name
:component channel-name/view} :component channel-name/view}
{:name :standard-title {:name :standard-title
:component standard-title/view}] :component standard-title/view}
{:name :username
:component username/view}]
:wallet [{:name :account-card :component account-card/view} :wallet [{:name :account-card :component account-card/view}
{:name :account-origin :component account-origin/view} {:name :account-origin :component account-origin/view}
{:name :account-overview {:name :account-overview

View File

@ -0,0 +1,52 @@
(ns status-im2.contexts.quo-preview.text-combinations.username
(:require [quo.core :as quo]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:key :name-type
:type :select
:options [{:key :default}
{:key :ens
:value "ENS"}
{:key :nickname}]}
{:key :username
:type :text}
{:key :name
:type :text}
{:key :status
:type :select
:options [{:key nil
:value "(Nothing)"}
{:key :verified}
{:key :contact}
{:key :untrustworthy}
{:key :untrustworthy-contact}
{:key :blocked}]}
{:key :blur?
:type :boolean}])
(defn- set-username-based-on-name-type
[_ ratom {previous-type :name-type} {new-type :name-type}]
(when (not= previous-type new-type)
(swap! ratom assoc
:username
(if (= new-type :ens)
"juan.eth"
"Juanito Mdz"))))
(defn view
[]
(let [state (reagent/atom {:name-type :default
:username "Juanito Mdz"
:name "Juan Méndez"
:status nil
:blur? true})
_ (add-watch state :on-state-change set-username-based-on-name-type)]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:show-blur-background? true
:blur? (:blur? @state)}
[quo/username @state]])))

View File

@ -15,6 +15,7 @@
(defn get-derivation-path (defn get-derivation-path
[number-of-accounts] [number-of-accounts]
(str constants/path-wallet-root "/" number-of-accounts)) (str constants/path-wallet-root "/" number-of-accounts))
(defn format-derivation-path (defn format-derivation-path
[path] [path]
(string/replace path "/" " / ")) (string/replace path "/" " / "))