Status Tag UI and usage update (#15282)
* [Feature][#15267] Status Tag UI Update * [Fix] Typo in comment * [Fix] Feedback from PR * [Fix] Feedback from PR * [Fix] Blur Type on Preview Screen * [Fix] Blur Type on Preview Screen
After Width: | Height: | Size: 898 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 591 B |
After Width: | Height: | Size: 884 B |
After Width: | Height: | Size: 864 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 946 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 927 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 768 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
|
@ -7,9 +7,9 @@
|
||||||
[quo2.components.notifications.activity-log.style :as style]
|
[quo2.components.notifications.activity-log.style :as style]
|
||||||
[quo2.components.tags.status-tags :as status-tags]
|
[quo2.components.tags.status-tags :as status-tags]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[utils.i18n :as i18n]
|
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]
|
||||||
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(defn- activity-reply-text-input
|
(defn- activity-reply-text-input
|
||||||
[{:keys [on-update-reply max-reply-length valid-reply?]} reply-input]
|
[{:keys [on-update-reply max-reply-length valid-reply?]} reply-input]
|
||||||
|
@ -134,11 +134,12 @@
|
||||||
label]))
|
label]))
|
||||||
|
|
||||||
(defmethod footer-item-view :status
|
(defmethod footer-item-view :status
|
||||||
[{:keys [label subtype]} _ _]
|
[{:keys [label subtype blur?]} _ _]
|
||||||
[status-tags/status-tag
|
[status-tags/status-tag
|
||||||
{:size :small
|
{:size :small
|
||||||
:label label
|
:label label
|
||||||
:status {:type subtype}}])
|
:status {:type subtype}
|
||||||
|
:blur? blur?}])
|
||||||
|
|
||||||
(defn- footer
|
(defn- footer
|
||||||
[_ _]
|
[_ _]
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
(ns quo2.components.tags.--tests--.status-tags-component-spec
|
||||||
|
(:require [quo2.components.tags.status-tags :as quo2]
|
||||||
|
[test-helpers.component :as h]))
|
||||||
|
|
||||||
|
(defn render-status-tag
|
||||||
|
[opts]
|
||||||
|
(h/render [quo2/status-tag opts]))
|
||||||
|
|
||||||
|
(h/describe "status tag component"
|
||||||
|
(h/test "renders status tag with positive type"
|
||||||
|
(render-status-tag {:status {:type :positive}
|
||||||
|
:label "Positive"
|
||||||
|
:size :small})
|
||||||
|
(-> (h/expect (h/get-all-by-label-text :status-tag-positive))
|
||||||
|
(.toBeTruthy))
|
||||||
|
(-> (h/expect (h/get-by-text "Positive"))
|
||||||
|
(.toBeTruthy)))
|
||||||
|
(h/test "renders status tag with negative type"
|
||||||
|
(render-status-tag {:status {:type :negative}
|
||||||
|
:label "Negative"
|
||||||
|
:size :small})
|
||||||
|
(-> (h/expect (h/get-all-by-label-text :status-tag-negative))
|
||||||
|
(.toBeTruthy))
|
||||||
|
(-> (h/expect (h/get-by-text "Negative"))
|
||||||
|
(.toBeTruthy)))
|
||||||
|
(h/test "renders status tag with pending type"
|
||||||
|
(render-status-tag {:status {:type :pending}
|
||||||
|
:label "Pending"
|
||||||
|
:size :small})
|
||||||
|
(-> (h/expect (h/get-all-by-label-text :status-tag-pending))
|
||||||
|
(.toBeTruthy))
|
||||||
|
(-> (h/expect (h/get-by-text "Pending"))
|
||||||
|
(.toBeTruthy))))
|
|
@ -27,15 +27,18 @@
|
||||||
background-color
|
background-color
|
||||||
icon
|
icon
|
||||||
text-color
|
text-color
|
||||||
label]}]
|
label
|
||||||
|
accessibility-label]}]
|
||||||
(let [paragraph-size (if (= size :small) :paragraph-2 :paragraph-1)]
|
(let [paragraph-size (if (= size :small) :paragraph-2 :paragraph-1)]
|
||||||
[rn/view
|
[rn/view
|
||||||
(assoc (if (= size :small)
|
{:accessible true
|
||||||
small-container-style
|
:accessibility-label accessibility-label
|
||||||
large-container-style)
|
:style (assoc (if (= size :small)
|
||||||
:border-width 1
|
small-container-style
|
||||||
:border-color border-color
|
large-container-style)
|
||||||
:background-color background-color)
|
:border-width 1
|
||||||
|
:border-color border-color
|
||||||
|
:background-color background-color)}
|
||||||
[rn/view
|
[rn/view
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:flex 1}
|
:flex 1}
|
||||||
|
@ -45,7 +48,7 @@
|
||||||
[icon/icon
|
[icon/icon
|
||||||
icon
|
icon
|
||||||
{:no-color true
|
{:no-color true
|
||||||
:size 12}]]
|
:size (if (= size :large) 20 12)}]]
|
||||||
[text/text
|
[text/text
|
||||||
{:size paragraph-size
|
{:size paragraph-size
|
||||||
:weight :medium
|
:weight :medium
|
||||||
|
@ -53,41 +56,51 @@
|
||||||
:color text-color}} label]]])))
|
:color text-color}} label]]])))
|
||||||
|
|
||||||
(defn- positive
|
(defn- positive
|
||||||
[size theme label]
|
[size theme label _]
|
||||||
[base-tag
|
[base-tag
|
||||||
{:size size
|
{:accessibility-label :status-tag-positive
|
||||||
:icon :verified
|
:size size
|
||||||
:background-color colors/success-50-opa-10
|
:icon :i/positive-state
|
||||||
:border-color colors/success-50-opa-20
|
:background-color colors/success-50-opa-10
|
||||||
:label label
|
:border-color colors/success-50-opa-20
|
||||||
:text-color (if (= theme :light)
|
:label label
|
||||||
colors/success-50
|
;; The positive tag uses the same color for `light` and `dark blur` variant
|
||||||
colors/success-60)}])
|
:text-color (if (= theme :dark) colors/success-60 colors/success-50)}])
|
||||||
|
|
||||||
(defn- negative
|
(defn- negative
|
||||||
[size theme label]
|
[size theme label _]
|
||||||
[base-tag
|
[base-tag
|
||||||
{:size size
|
{:accessibility-label :status-tag-negative
|
||||||
:icon :untrustworthy
|
:size size
|
||||||
:background-color colors/danger-50-opa-10
|
:icon :i/negative-state
|
||||||
:border-color colors/danger-50-opa-20
|
:background-color colors/danger-50-opa-10
|
||||||
:label label
|
:border-color colors/danger-50-opa-20
|
||||||
:text-color (if (= theme :light)
|
:label label
|
||||||
colors/danger-50
|
;; The negative tag uses the same color for `dark` and `dark blur` variant
|
||||||
colors/danger-60)}])
|
:text-color (if (= theme :light) colors/danger-50 colors/danger-60)}])
|
||||||
|
|
||||||
(defn- pending
|
(defn- pending
|
||||||
[size _ label]
|
[size theme label blur?]
|
||||||
[base-tag
|
[base-tag
|
||||||
{:size size
|
{:accessibility-label :status-tag-pending
|
||||||
:icon :pending
|
:size size
|
||||||
:label label
|
:label label
|
||||||
:background-color colors/white-opa-5
|
:icon (if blur?
|
||||||
:border-color colors/white-opa-5
|
:i/pending-dark-blur
|
||||||
:text-color colors/white-opa-70}])
|
(if (= theme :light) :i/pending-light :i/pending-dark))
|
||||||
|
:background-color (if blur?
|
||||||
|
colors/white-opa-5
|
||||||
|
(colors/theme-colors colors/neutral-10 colors/neutral-80-opa-40 theme))
|
||||||
|
:border-color (if blur?
|
||||||
|
colors/white-opa-5
|
||||||
|
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme))
|
||||||
|
|
||||||
|
:text-color (if blur?
|
||||||
|
colors/white-opa-70
|
||||||
|
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}])
|
||||||
|
|
||||||
(defn status-tag
|
(defn status-tag
|
||||||
[{:keys [status size override-theme label]}]
|
[{:keys [status size override-theme label blur?]}]
|
||||||
(when status
|
(when status
|
||||||
(when-let [status-component (case (:type status)
|
(when-let [status-component (case (:type status)
|
||||||
:positive positive
|
:positive positive
|
||||||
|
@ -97,4 +110,5 @@
|
||||||
[status-component
|
[status-component
|
||||||
size
|
size
|
||||||
(or override-theme (quo2.theme/get-theme))
|
(or override-theme (quo2.theme/get-theme))
|
||||||
label])))
|
label
|
||||||
|
blur?])))
|
||||||
|
|
|
@ -16,4 +16,5 @@
|
||||||
[quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec]
|
[quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec]
|
||||||
[quo2.components.profile.select-profile.component-spec]
|
[quo2.components.profile.select-profile.component-spec]
|
||||||
[quo2.components.selectors.--tests--.selectors-component-spec]
|
[quo2.components.selectors.--tests--.selectors-component-spec]
|
||||||
[quo2.components.selectors.filter.component-spec]))
|
[quo2.components.selectors.filter.component-spec]
|
||||||
|
[quo2.components.tags.--tests--.status-tags-component-spec]))
|
||||||
|
|
|
@ -139,8 +139,8 @@
|
||||||
;;;;Success
|
;;;;Success
|
||||||
|
|
||||||
;;Solid
|
;;Solid
|
||||||
(def success-50 "#26A69A")
|
(def success-50 "#23ADA0")
|
||||||
(def success-60 "#208B81")
|
(def success-60 "#1C8A80")
|
||||||
|
|
||||||
;;50 with transparency
|
;;50 with transparency
|
||||||
(def success-50-opa-5 (alpha success-50 0.05))
|
(def success-50-opa-5 (alpha success-50 0.05))
|
||||||
|
@ -162,8 +162,8 @@
|
||||||
(def danger-opa-40 (alpha danger 0.4))
|
(def danger-opa-40 (alpha danger 0.4))
|
||||||
|
|
||||||
;;Solid
|
;;Solid
|
||||||
(def danger-50 "#E65F5C")
|
(def danger-50 "#E95460")
|
||||||
(def danger-60 "#C1504D")
|
(def danger-60 "#BA434D")
|
||||||
|
|
||||||
;;50 with transparency
|
;;50 with transparency
|
||||||
(def danger-50-opa-5 (alpha danger-50 0.05))
|
(def danger-50-opa-5 (alpha danger-50 0.05))
|
||||||
|
|
|
@ -49,12 +49,14 @@
|
||||||
[{:type :status
|
[{:type :status
|
||||||
:subtype :positive
|
:subtype :positive
|
||||||
:key :status-accepted
|
:key :status-accepted
|
||||||
|
:blur? true
|
||||||
:label (i18n/label :t/accepted)}]
|
:label (i18n/label :t/accepted)}]
|
||||||
|
|
||||||
constants/activity-center-membership-status-declined
|
constants/activity-center-membership-status-declined
|
||||||
[{:type :status
|
[{:type :status
|
||||||
:subtype :negative
|
:subtype :negative
|
||||||
:key :status-declined
|
:key :status-declined
|
||||||
|
:blur? true
|
||||||
:label (i18n/label :t/declined)}]
|
:label (i18n/label :t/declined)}]
|
||||||
|
|
||||||
constants/activity-center-membership-status-pending
|
constants/activity-center-membership-status-pending
|
||||||
|
|
|
@ -63,12 +63,14 @@
|
||||||
{:type :status
|
{:type :status
|
||||||
:subtype :pending
|
:subtype :pending
|
||||||
:key :status-pending
|
:key :status-pending
|
||||||
|
:blur? true
|
||||||
:label (i18n/label :t/pending)}]
|
:label (i18n/label :t/pending)}]
|
||||||
|
|
||||||
constants/contact-request-message-state-declined
|
constants/contact-request-message-state-declined
|
||||||
[{:type :status
|
[{:type :status
|
||||||
:subtype :pending
|
:subtype :pending
|
||||||
:key :status-pending
|
:key :status-pending
|
||||||
|
:blur? true
|
||||||
:label (i18n/label :t/pending)}]
|
:label (i18n/label :t/pending)}]
|
||||||
|
|
||||||
nil)}])))
|
nil)}])))
|
||||||
|
@ -92,12 +94,14 @@
|
||||||
[{:type :status
|
[{:type :status
|
||||||
:subtype :positive
|
:subtype :positive
|
||||||
:key :status-accepted
|
:key :status-accepted
|
||||||
|
:blur? true
|
||||||
:label (i18n/label :t/accepted)}]
|
:label (i18n/label :t/accepted)}]
|
||||||
|
|
||||||
constants/contact-request-message-state-declined
|
constants/contact-request-message-state-declined
|
||||||
[{:type :status
|
[{:type :status
|
||||||
:subtype :negative
|
:subtype :negative
|
||||||
:key :status-declined
|
:key :status-declined
|
||||||
|
:blur? true
|
||||||
:label (i18n/label :t/declined)}]
|
:label (i18n/label :t/declined)}]
|
||||||
|
|
||||||
constants/contact-request-message-state-pending
|
constants/contact-request-message-state-pending
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
:key :danger}
|
:key :danger}
|
||||||
{:value "Primary"
|
{:value "Primary"
|
||||||
:key :primary}
|
:key :primary}
|
||||||
{:value "Success"
|
{:value "Positive"
|
||||||
:key :success}]}
|
:key :positive}]}
|
||||||
{:label "Button 1 label"
|
{:label "Button 1 label"
|
||||||
:key :button-1-label
|
:key :button-1-label
|
||||||
:type :text}
|
:type :text}
|
||||||
|
@ -59,8 +59,8 @@
|
||||||
:key :danger}
|
:key :danger}
|
||||||
{:value "Primary"
|
{:value "Primary"
|
||||||
:key :primary}
|
:key :primary}
|
||||||
{:value "Success"
|
{:value "Positive"
|
||||||
:key :success}]}
|
:key :positive}]}
|
||||||
{:label "Button 2 label"
|
{:label "Button 2 label"
|
||||||
:key :button-2-label
|
:key :button-2-label
|
||||||
:type :text}
|
:type :text}
|
||||||
|
@ -122,25 +122,33 @@
|
||||||
:message :with-title
|
:message :with-title
|
||||||
:timestamp "Today 00:00"
|
:timestamp "Today 00:00"
|
||||||
:title "Activity Title"
|
:title "Activity Title"
|
||||||
:unread? true})]
|
:unread? true
|
||||||
|
:items []})]
|
||||||
(fn []
|
(fn []
|
||||||
(let [{:keys [button-1-type
|
(let [{:keys [button-1-type
|
||||||
button-1-label
|
button-1-label
|
||||||
button-2-type
|
button-2-type
|
||||||
button-2-label]}
|
button-2-label
|
||||||
|
status]}
|
||||||
@state
|
@state
|
||||||
props (cond-> @state
|
props (cond-> @state
|
||||||
(and (seq button-1-label)
|
(and (seq button-1-label)
|
||||||
button-1-type)
|
button-1-type)
|
||||||
(assoc :button-1
|
(update :items
|
||||||
{:label button-1-label
|
conj
|
||||||
:type button-1-type})
|
{:type :button
|
||||||
|
:label button-1-label
|
||||||
|
:subtype button-1-type
|
||||||
|
:on-press #(js/alert "Button 1 Clicked")})
|
||||||
|
|
||||||
(and (seq button-2-label)
|
(and (seq button-2-label)
|
||||||
button-2-type)
|
button-2-type)
|
||||||
(assoc :button-2
|
(update :items
|
||||||
{:label button-2-label
|
conj
|
||||||
:type button-2-type})
|
{:type :button
|
||||||
|
:label button-2-label
|
||||||
|
:subtype button-2-type
|
||||||
|
:on-press #(js/alert "Button 2 Clicked")})
|
||||||
|
|
||||||
(= (:message @state) :simple)
|
(= (:message @state) :simple)
|
||||||
(assoc :message {:body "The quick brown fox forgot to jump."})
|
(assoc :message {:body "The quick brown fox forgot to jump."})
|
||||||
|
@ -148,10 +156,13 @@
|
||||||
(= (:message @state) :with-mention)
|
(= (:message @state) :with-mention)
|
||||||
(assoc :message message-with-mention)
|
(assoc :message message-with-mention)
|
||||||
|
|
||||||
(some? (:status @state))
|
(some? status)
|
||||||
(update :status
|
(update :items
|
||||||
(fn [status]
|
conj
|
||||||
{:label (name status) :type status}))
|
{:type :status
|
||||||
|
:subtype status
|
||||||
|
:blur? true
|
||||||
|
:label (name status)})
|
||||||
|
|
||||||
(= (:message @state) :with-title)
|
(= (:message @state) :with-title)
|
||||||
(assoc :message message-with-title)
|
(assoc :message message-with-title)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
(ns status-im2.contexts.quo-preview.preview
|
(ns status-im2.contexts.quo-preview.preview
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
|
[react-native.blur :as blur]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent])
|
[reagent.core :as reagent]
|
||||||
|
[status-im2.common.resources :as resources])
|
||||||
(:require-macros status-im2.contexts.quo-preview.preview))
|
(:require-macros status-im2.contexts.quo-preview.preview))
|
||||||
|
|
||||||
(def container
|
(def container
|
||||||
|
@ -212,3 +214,36 @@
|
||||||
:type :select
|
:type :select
|
||||||
:options [{:key :primary :value "Primary"}
|
:options [{:key :primary :value "Primary"}
|
||||||
{:key :secondary :value "Secondary"}]}])
|
{:key :secondary :value "Secondary"}]}])
|
||||||
|
|
||||||
|
(defn blur-view
|
||||||
|
[{:keys [show-blur-background? image height blur-view-props style]} children]
|
||||||
|
[rn/view
|
||||||
|
{:style {:flex 1
|
||||||
|
:padding-horizontal 16
|
||||||
|
:padding-vertical 16}}
|
||||||
|
(when show-blur-background?
|
||||||
|
[rn/view
|
||||||
|
{:style {:height (or height 100)
|
||||||
|
:border-radius 16
|
||||||
|
:overflow :hidden}}
|
||||||
|
[rn/image
|
||||||
|
{:source (or image (resources/get-mock-image :community-cover))
|
||||||
|
:style {:height "100%"
|
||||||
|
:width "100%"}}]
|
||||||
|
[blur/view
|
||||||
|
(merge {:style {:position :absolute
|
||||||
|
:top 0
|
||||||
|
:bottom 0
|
||||||
|
:left 0
|
||||||
|
:right 0}
|
||||||
|
:blur-amount 10
|
||||||
|
:overlay-color (colors/theme-colors
|
||||||
|
colors/white-opa-70
|
||||||
|
colors/neutral-80-opa-80)}
|
||||||
|
blur-view-props)]])
|
||||||
|
[rn/view
|
||||||
|
{:style (merge {:position :absolute
|
||||||
|
:top 32
|
||||||
|
:padding-horizontal 16}
|
||||||
|
style)}
|
||||||
|
children]])
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[utils.i18n :as i18n]
|
[status-im2.contexts.quo-preview.preview :as preview]
|
||||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(def status-tags-options
|
(def status-tags-options
|
||||||
{:label "Status"
|
{:label "Status"
|
||||||
|
@ -25,32 +25,36 @@
|
||||||
:options [{:value "Small"
|
:options [{:value "Small"
|
||||||
:key :small}
|
:key :small}
|
||||||
{:value "Large"
|
{:value "Large"
|
||||||
:key :large}]}])
|
:key :large}]}
|
||||||
|
{:label "Blur?"
|
||||||
|
:key :blur?
|
||||||
|
:type :boolean}])
|
||||||
|
|
||||||
(defn cool-preview
|
(defn cool-preview
|
||||||
[]
|
[]
|
||||||
(let [state (reagent/atom {:status :positive
|
(let [state (reagent/atom {:status :positive
|
||||||
:size :small})]
|
:size :small
|
||||||
|
:blur? false})]
|
||||||
(fn []
|
(fn []
|
||||||
(let [props (cond-> @state
|
(let [props (case (:status @state)
|
||||||
(= :positive (:status @state)) (assoc :status
|
:positive (-> @state
|
||||||
{:label (i18n/label :positive)
|
(assoc :status {:type :positive})
|
||||||
:type :positive})
|
(assoc :label (i18n/label :t/positive)))
|
||||||
(= :negative (:status @state)) (assoc :status
|
:negative (-> @state
|
||||||
{:label (i18n/label :negative)
|
(assoc :status {:type :negative})
|
||||||
:type :negative})
|
(assoc :label (i18n/label :t/negative)))
|
||||||
(= :pending (:status @state)) (assoc :status
|
:pending (-> @state
|
||||||
{:label (i18n/label :pending)
|
(assoc :status {:type :pending})
|
||||||
:type :pending}))]
|
(assoc :label (i18n/label :t/pending))))]
|
||||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||||
[rn/view {:padding-bottom 150}
|
[rn/view {:padding-bottom 150}
|
||||||
[rn/view {:flex 1}
|
[rn/view {:flex 1}
|
||||||
[preview/customizer state descriptor]]
|
[preview/customizer state descriptor]]
|
||||||
[rn/view
|
[preview/blur-view
|
||||||
{:padding-vertical 60
|
{:show-blur-background? (:blur? @state)
|
||||||
:flex-direction :row
|
:blur-view-props {:blur-type :dark
|
||||||
:justify-content :center}
|
:overlay-color colors/neutral-80-opa-80}
|
||||||
[quo2/status-tag props]]]]))))
|
:style {:align-self :center}} [quo2/status-tag props]]]]))))
|
||||||
|
|
||||||
(defn preview-status-tags
|
(defn preview-status-tags
|
||||||
[]
|
[]
|
||||||
|
|