diff --git a/src/quo/components/avatars/collection_avatar/style.cljs b/src/quo/components/avatars/collection_avatar/style.cljs index aebc90899c..51edd5c185 100644 --- a/src/quo/components/avatars/collection_avatar/style.cljs +++ b/src/quo/components/avatars/collection_avatar/style.cljs @@ -5,6 +5,7 @@ (defn- get-dimensions [size] (case size + :size-32 32 :size-24 24 :size-20 20 nil)) diff --git a/src/quo/components/list_items/approval_info/component_spec.cljs b/src/quo/components/list_items/approval_info/component_spec.cljs new file mode 100644 index 0000000000..bb67767081 --- /dev/null +++ b/src/quo/components/list_items/approval_info/component_spec.cljs @@ -0,0 +1,57 @@ +(ns quo.components.list-items.approval-info.component-spec + (:require [quo.components.list-items.approval-info.view :as approval-info] + [test-helpers.component :as h])) + +(h/describe "List Items: Approval Info" + (h/test "should render correctly with basic props" + (h/render-with-theme-provider + [approval-info/view + {:type :spending-cap + :label "Spending Cap" + :avatar-props {:image "image"}}]) + (h/is-truthy (h/get-by-label-text :approval-info))) + + (h/test "should render correctly with label & description" + (h/render-with-theme-provider + [approval-info/view + {:type :spending-cap + :label "Spending Cap" + :description "Description" + :avatar-props {:image "image"}}]) + (h/is-truthy (h/get-by-text "Spending Cap")) + (h/is-truthy (h/get-by-text "Description"))) + + (h/test "on-button-press event is called when button is pressed" + (let [on-button-press (h/mock-fn)] + (h/render-with-theme-provider + [approval-info/view + {:type :spending-cap + :label "Spending Cap" + :button-label "Edit" + :on-button-press on-button-press + :avatar-props {:image "image"}}]) + (h/fire-event :press (h/get-by-text "Edit")) + (h/was-called on-button-press))) + + (h/test "on-option-press event is called when option icon is pressed" + (let [on-option-press (h/mock-fn)] + (h/render-with-theme-provider + [approval-info/view + {:type :spending-cap + :label "Spending Cap" + :option-icon :i/options + :on-option-press on-option-press + :avatar-props {:image "image"}}]) + (h/fire-event :press (h/get-by-label-text :icon)) + (h/was-called on-option-press))) + + (h/test "on-avatar-press event is called when avatar is pressed" + (let [on-avatar-press (h/mock-fn)] + (h/render-with-theme-provider + [approval-info/view + {:type :spending-cap + :label "Spending Cap" + :on-avatar-press on-avatar-press + :avatar-props {:image "image"}}]) + (h/fire-event :press (h/get-by-label-text :token-avatar)) + (h/was-called on-avatar-press)))) diff --git a/src/quo/components/list_items/approval_info/style.cljs b/src/quo/components/list_items/approval_info/style.cljs new file mode 100644 index 0000000000..38e81d43e1 --- /dev/null +++ b/src/quo/components/list_items/approval_info/style.cljs @@ -0,0 +1,36 @@ +(ns quo.components.list-items.approval-info.style + (:require [quo.foundations.colors :as colors])) + +(defn icon-description-color + [blur? theme] + (if blur? + colors/white-opa-40 + (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))) + +(defn container + [description? blur? theme] + {:flex-direction :row + :padding-horizontal 12 + :padding-vertical (if description? 8 12) + :border-radius 16 + :gap 8 + :align-items :center + :border-width 1 + :border-color (if blur? + colors/white-opa-5 + (colors/theme-colors colors/neutral-10 colors/neutral-80 theme))}) + +(def labels + {:flex 1 + :justify-content :center + :padding-right 4}) + +(defn label + [blur? theme] + {:color (if blur? + colors/white + (colors/theme-colors colors/neutral-100 colors/white theme))}) + +(defn description + [blur? theme] + {:color (icon-description-color blur? theme)}) diff --git a/src/quo/components/list_items/approval_info/view.cljs b/src/quo/components/list_items/approval_info/view.cljs new file mode 100644 index 0000000000..93c912969d --- /dev/null +++ b/src/quo/components/list_items/approval_info/view.cljs @@ -0,0 +1,124 @@ +(ns quo.components.list-items.approval-info.view + (:require [clojure.string :as string] + [quo.components.avatars.account-avatar.view :as account-avatar] + [quo.components.avatars.collection-avatar.view :as collection-avatar] + [quo.components.avatars.community-avatar.view :as community-avatar] + [quo.components.avatars.dapp-avatar.view :as dapp-avatar] + [quo.components.avatars.icon-avatar :as icon-avatar] + [quo.components.avatars.token-avatar.view :as token-avatar] + [quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar] + [quo.components.buttons.button.view :as button] + [quo.components.icon :as icon] + [quo.components.list-items.approval-info.style :as style] + [quo.components.markdown.text :as text] + [quo.components.tags.tiny-tag.view :as tiny-tag] + [quo.foundations.colors :as colors] + quo.theme + [react-native.core :as rn] + [schema.core :as schema])) + +(def ?schema + [:=> + [:catn + [:props + [:map {:closed true} + [:type + [:enum :spending-cap :token-contract :account :spending-contract :network :date-signed + :collectible :address :community :collectible-contract]] + [:avatar-props :map] + [:label :string] + [:description {:optional true} [:maybe :string]] + [:button-label {:optional true} [:maybe :string]] + [:button-icon {:optional true} [:maybe :keyword]] + [:blur? {:optional true} [:maybe :boolean]] + [:unlimited-icon? {:optional true} [:maybe :boolean]] + [:option-icon {:optional true} [:maybe :keyword]] + [:tag-label {:optional true} [:maybe :string]] + [:on-button-press {:optional true} [:maybe fn?]] + [:on-avatar-press {:optional true} [:maybe fn?]] + [:on-option-press {:optional true} [:maybe fn?]] + [:container-style {:optional true} [:maybe :any]]]]] + :any]) + +(defn- avatar + [{:keys [type avatar-props blur? theme on-press]}] + [rn/pressable {:on-press on-press} + (case type + :account [account-avatar/view (assoc avatar-props :size 32)] + :collectible-contract [collection-avatar/view (assoc avatar-props :size :size-32)] + :spending-contract [dapp-avatar/view avatar-props] + :date-signed [icon-avatar/icon-avatar + (assoc avatar-props + :size :size-32 + :opacity 10 + :color (if blur? + colors/white + (colors/theme-colors colors/neutral-50 + colors/neutral-40 + theme)))] + :address [wallet-user-avatar/wallet-user-avatar + (assoc avatar-props + :size :size-32 + :monospace? true + :lowercase? true + :neutral? true)] + :community [community-avatar/view avatar-props] + [token-avatar/view + (assoc avatar-props + :type + (if (= type :collectible) :collectible :asset))])]) + +(defn- view-internal + [{:keys [type avatar-props label description blur? unlimited-icon? container-style + on-option-press on-avatar-press on-button-press button-label button-icon tag-label + option-icon]}] + (let [theme (quo.theme/use-theme) + description? (not (string/blank? description))] + [rn/view + {:style (merge (style/container description? blur? theme) container-style) + :accessibility-label :approval-info} + [avatar + {:type type + :blur? blur? + :theme theme + :on-press on-avatar-press + :avatar-props avatar-props}] + [rn/view + {:style style/labels} + [rn/view + {:style {:flex-direction :row :align-items :center}} + [text/text + {:size :paragraph-1 + :weight (if (= type :address) :monospace :semi-bold) + :style (style/label blur? theme)} + label] + (when unlimited-icon? + [icon/icon :i/alert + {:container-style {:margin-left 4} + :size 16 + :color (style/icon-description-color blur? theme)}])] + (when description? + [text/text + {:size :paragraph-2 + :weight (if (contains? #{:collectible-contract :spending-contract :account :token-contract} + type) + :monospace + :regular) + :style (style/description blur? theme)} + description])] + (when (= type :account) [tiny-tag/view {:label tag-label}]) + (when (= type :spending-cap) + [button/button + {:type :outline + :size 24 + :blur? blur? + :icon-left button-icon + :on-press on-button-press} + button-label]) + (when option-icon + [rn/pressable {:on-press on-option-press} + [icon/icon option-icon + {:color (style/icon-description-color blur? theme) + :size 20}]])])) + +(def view (schema/instrument #'view-internal ?schema)) diff --git a/src/quo/core.cljs b/src/quo/core.cljs index 9ea0c9a71b..dd01cf0b75 100644 --- a/src/quo/core.cljs +++ b/src/quo/core.cljs @@ -86,6 +86,7 @@ quo.components.list-items.account-list-card.view quo.components.list-items.account.view quo.components.list-items.address.view + quo.components.list-items.approval-info.view quo.components.list-items.channel.view quo.components.list-items.community.view quo.components.list-items.dapp.view @@ -334,6 +335,7 @@ (def account-item quo.components.list-items.account.view/view) (def account-list-card quo.components.list-items.account-list-card.view/view) (def address quo.components.list-items.address.view/view) +(def approval-info quo.components.list-items.approval-info.view/view) (def channel quo.components.list-items.channel.view/view) (def community-list quo.components.list-items.community.view/view) (def dapp quo.components.list-items.dapp.view/view) diff --git a/src/quo/core_spec.cljs b/src/quo/core_spec.cljs index 6ba9fb8e09..aa685d80c5 100644 --- a/src/quo/core_spec.cljs +++ b/src/quo/core_spec.cljs @@ -55,6 +55,7 @@ quo.components.links.url-preview.component-spec quo.components.list-items.account.component-spec quo.components.list-items.address.component-spec + quo.components.list-items.approval-info.component-spec quo.components.list-items.channel.component-spec quo.components.list-items.community.component-spec quo.components.list-items.dapp.component-spec diff --git a/src/status_im/contexts/preview/quo/list_items/approval_info.cljs b/src/status_im/contexts/preview/quo/list_items/approval_info.cljs new file mode 100644 index 0000000000..a716a99388 --- /dev/null +++ b/src/status_im/contexts/preview/quo/list_items/approval_info.cljs @@ -0,0 +1,80 @@ +(ns status-im.contexts.preview.quo.list-items.approval-info + (:require + [quo.core :as quo] + [quo.foundations.resources :as resources] + [react-native.core :as rn] + [status-im.common.resources :as common.resources] + [status-im.contexts.preview.quo.preview :as preview])) + +(def descriptor + [{:type :select + :key :type + :options [{:key :spending-cap} + {:key :token-contract} + {:key :account} + {:key :spending-contract} + {:key :network} + {:key :date-signed} + {:key :collectible} + {:key :collectible-contract} + {:key :address} + {:key :community}]} + {:type :text + :key :label} + {:type :text + :key :description} + {:type :boolean + :key :blur?} + {:type :boolean + :key :unlimited-icon?} + {:type :text + :key :button-label} + {:type :text + :key :tag-label} + {:type :select + :key :option-icon + :options [{:key nil + :value "None"} + {:key :i/options} + {:key :i/chevron-right}]}]) + +(defn- get-avatar-props + [type] + (case type + :collectible {:image (common.resources/get-mock-image :collectible2)} + :account {:customization-color :orange + :emoji "😇"} + :collectible-contract {:image (common.resources/get-mock-image :bored-ape)} + :spending-contract {:network-image (resources/get-network :ethereum) + :image (resources/get-dapp :coingecko)} + :date-signed {:icon :i/signature} + :address {:customization-color :blue + :full-name "0 x"} + :community {:image (common.resources/get-mock-image :status-logo) + :size :size-32} + {:image (common.resources/get-mock-image :status-logo)})) + +(defn view + [] + (let [[state set-state] (rn/use-state {:type :spending-cap + :label "Label" + :description "Description" + :blur? false + :unlimited-icon? false + :button-label "Edit" + :tag-label "31,283.77 EUR" + :option-icon :i/options})] + [preview/preview-container + {:state state + :set-state set-state + :blur? (:blur? state) + :show-blur-background? true + :blur-dark-only? true + :descriptor descriptor} + [quo/approval-info + (assoc state + :button-icon :i/edit + :on-button-press #(js/alert "Button Pressed") + :on-avatar-press #(js/alert "Token Pressed") + :avatar-props (get-avatar-props (:type state)) + :on-option-press #(js/alert "Option Pressed"))]])) diff --git a/src/status_im/contexts/preview/quo/main.cljs b/src/status_im/contexts/preview/quo/main.cljs index 1875c47d8e..2f6ff77299 100644 --- a/src/status_im/contexts/preview/quo/main.cljs +++ b/src/status_im/contexts/preview/quo/main.cljs @@ -105,6 +105,7 @@ [status-im.contexts.preview.quo.list-items.account-list-card :as account-list-card] [status-im.contexts.preview.quo.list-items.address :as address] + [status-im.contexts.preview.quo.list-items.approval-info :as approval-info] [status-im.contexts.preview.quo.list-items.channel :as channel] [status-im.contexts.preview.quo.list-items.dapp :as dapp] [status-im.contexts.preview.quo.list-items.missing-keypair :as missing-keypair] @@ -390,6 +391,8 @@ :component account-list-card/view} {:name :address :component address/view} + {:name :approval-info + :component approval-info/view} {:name :channel :component channel/view} {:name :community-list