diff --git a/resources/images/mock/small_opt_card_icon.png b/resources/images/mock/small_opt_card_icon.png new file mode 100644 index 0000000000..49c5fd2f45 Binary files /dev/null and b/resources/images/mock/small_opt_card_icon.png differ diff --git a/resources/images/mock/small_opt_card_main.png b/resources/images/mock/small_opt_card_main.png new file mode 100644 index 0000000000..803ec43f7f Binary files /dev/null and b/resources/images/mock/small_opt_card_main.png differ diff --git a/src/quo2/components/onboarding/small_option_card/component_spec.cljs b/src/quo2/components/onboarding/small_option_card/component_spec.cljs new file mode 100644 index 0000000000..a3e6808f5d --- /dev/null +++ b/src/quo2/components/onboarding/small_option_card/component_spec.cljs @@ -0,0 +1,54 @@ +(ns quo2.components.onboarding.small-option-card.component-spec + (:require [quo2.components.onboarding.small-option-card.view :as small-option-card] + [status-im.react-native.resources :as resources] + [test-helpers.component :as h])) + +(defn- testing-small-option-card + [variant + {:keys [title subtitle image on-press] + :or {title "title" subtitle "subtitle"}}] + [small-option-card/small-option-card + {:variant variant + :title title + :subtitle subtitle + :image image + :on-press on-press}]) + +(h/describe "small-option-card" + (h/describe "Title & subtitle are rendered" + (let [title "A title" + subtitle "A subtitle" + component-props {:title title :subtitle subtitle}] + (h/test "`:main` variant" + (h/render (testing-small-option-card :main component-props)) + (-> (h/get-by-text title) h/expect .toBeTruthy) + (-> (h/get-by-text subtitle) h/expect .toBeTruthy)) + + (h/test "`:icon` variant" + (h/render (testing-small-option-card :icon component-props)) + (-> (h/get-by-text title) h/expect .toBeTruthy) + (-> (h/get-by-text subtitle) h/expect .toBeTruthy)))) + + (h/describe "Card pressed" + (let [on-press-fn (h/mock-fn) + component-props {:on-press on-press-fn}] + (h/test "`:main` variant" + (h/render (testing-small-option-card :main component-props)) + (h/fire-event :press (h/get-by-label-text :small-option-card)) + (-> on-press-fn js/expect .toHaveBeenCalled)) + + (h/test "`:icon` variant" + (h/render (testing-small-option-card :icon component-props)) + (h/fire-event :press (h/get-by-label-text :small-option-card)) + (-> on-press-fn js/expect .toHaveBeenCalled)))) + + (h/describe "Image rendered" + (let [image (resources/get-mock-image :small-opt-card-main) + component-props {:image image}] + (h/test "`:main` variant" + (h/render (testing-small-option-card :main component-props)) + (-> (h/get-by-label-text :small-option-card-main-image) h/expect .-not .toBeNull)) + + (h/test "`:icon` variant" + (h/render (testing-small-option-card :icon component-props)) + (-> (h/get-by-label-text :small-option-card-icon-image) h/expect .-not .toBeNull))))) diff --git a/src/quo2/components/onboarding/small_option_card/style.cljs b/src/quo2/components/onboarding/small_option_card/style.cljs new file mode 100644 index 0000000000..d7889a435e --- /dev/null +++ b/src/quo2/components/onboarding/small_option_card/style.cljs @@ -0,0 +1,52 @@ +(ns quo2.components.onboarding.small-option-card.style + (:require [quo2.foundations.colors :as colors])) + +(def text-container {:flex 1}) + +(def title + {:color colors/white + :height 22}) + +(def subtitle + {:color colors/white-opa-70 + :height 18}) + +(def icon-variant + {:flex-direction :row + :padding-vertical 8 + :padding-horizontal 12}) + +(def icon-variant-image-container + {:width 32 + :height 40 + :justify-content :center + :align-items :center + :padding-vertical 4 + :margin-right 8}) + +(def icon-variant-image + {:flex 1 + :width 32 + :height 32}) + +(def main-variant + {:flex 1 + :margin-bottom -8}) + +(def main-variant-text-container + {:height 62 + :padding-top 10 + :padding-bottom 12 + :padding-horizontal 12}) + +(def touchable-overlay {:border-radius 16}) + +(defn card-container + [main-variant?] + (when main-variant? {:height 343})) + +(defn card + [main-variant?] + {:background-color colors/white-opa-5 + :border-radius 16 + :height (if main-variant? 335 56)}) diff --git a/src/quo2/components/onboarding/small_option_card/view.cljs b/src/quo2/components/onboarding/small_option_card/view.cljs new file mode 100644 index 0000000000..a0c768847c --- /dev/null +++ b/src/quo2/components/onboarding/small_option_card/view.cljs @@ -0,0 +1,66 @@ +(ns quo2.components.onboarding.small-option-card.view + (:require [quo2.components.markdown.text :as text] + [quo2.components.onboarding.small-option-card.style :as style] + [quo2.foundations.colors :as colors] + [react-native.core :as rn] + [react-native.fast-image :as fast-image])) + +(defn- texts + [{:keys [title subtitle]}] + [rn/view {:style style/text-container} + [text/text + {:style style/title + :size :paragraph-1 + :weight :semi-bold + :number-of-lines 1} + title] + [text/text + {:style style/subtitle + :size :paragraph-2 + :weight :regular + :number-of-lines 1} + subtitle]]) + +(defn- icon-variant + [{:keys [title subtitle image]}] + [rn/view {:style style/icon-variant} + [rn/view {:style style/icon-variant-image-container} + [fast-image/fast-image + {:accessibility-label :small-option-card-icon-image + :style style/icon-variant-image + :resize-mode :contain + :source image}]] + [texts + {:title title + :subtitle subtitle}]]) + +(defn- main-variant + [{:keys [title subtitle image]}] + [rn/view {:style style/main-variant} + [rn/view {:style style/main-variant-text-container} + [texts + {:title title + :subtitle subtitle}]] + [fast-image/fast-image + {:accessibility-label :small-option-card-main-image + :style {:flex 1} + :resize-mode :contain + :source image}]]) + +(defn small-option-card + [{:keys [variant title subtitle image on-press] + :or {variant :main}}] + (let [main-variant? (= variant :main) + card-component (if main-variant? main-variant icon-variant)] + [rn/touchable-highlight + {:accessibility-label :small-option-card + :style style/touchable-overlay + :active-opacity 1 + :underlay-color colors/white-opa-5 + :on-press on-press} + [rn/view {:style (style/card-container main-variant?)} + [rn/view {:style (style/card main-variant?)} + [card-component + {:title title + :subtitle subtitle + :image image}]]]])) diff --git a/src/quo2/core.cljs b/src/quo2/core.cljs index 22cb61528f..eece55b2fe 100644 --- a/src/quo2/core.cljs +++ b/src/quo2/core.cljs @@ -50,6 +50,7 @@ quo2.components.separator quo2.components.settings.accounts.view quo2.components.settings.privacy-option + quo2.components.onboarding.small-option-card.view quo2.components.tabs.account-selector quo2.components.tabs.tabs quo2.components.tags.context-tags @@ -101,6 +102,9 @@ ;;;; BANNER (def banner quo2.components.banners.banner.view/banner) +;;;; CARDS +(def small-option-card quo2.components.onboarding.small-option-card.view/small-option-card) + ;;;; COMMUNITY (def community-card-view-item quo2.components.community.community-card-view/community-card-view-item) (def communities-list-view-item quo2.components.community.community-list-view/communities-list-view-item) diff --git a/src/quo2/core_spec.cljs b/src/quo2/core_spec.cljs index e1fee0bdd0..ba6e1573b7 100644 --- a/src/quo2/core_spec.cljs +++ b/src/quo2/core_spec.cljs @@ -6,7 +6,8 @@ [quo2.components.drawers.action-drawers.component-spec] [quo2.components.drawers.permission-context.component-spec] [quo2.components.markdown.--tests--.text-component-spec] - [quo2.components.selectors.--tests--.selectors-component-spec] - [quo2.components.selectors.filter.component-spec] + [quo2.components.onboarding.small-option-card.component-spec] [quo2.components.record-audio.record-audio.--tests--.record-audio-component-spec] - [quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec])) + [quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec] + [quo2.components.selectors.--tests--.selectors-component-spec] + [quo2.components.selectors.filter.component-spec])) diff --git a/src/status_im/react_native/resources.cljs b/src/status_im/react_native/resources.cljs index 2b2ce7d9fa..06d8202273 100644 --- a/src/status_im/react_native/resources.cljs +++ b/src/status_im/react_native/resources.cljs @@ -67,7 +67,9 @@ :user-picture-female2 (js/require "../resources/images/mock/user_picture_female2.png") :user-picture-male4 (js/require "../resources/images/mock/user_picture_male4.png") :user-picture-male5 (js/require "../resources/images/mock/user_picture_male5.png") - :coinbase (js/require "../resources/images/mock/coinbase.png")}) + :coinbase (js/require "../resources/images/mock/coinbase.png") + :small-opt-card-icon (js/require "../resources/images/mock/small_opt_card_icon.png") + :small-opt-card-main (js/require "../resources/images/mock/small_opt_card_main.png")}) (defn get-theme-image [k] diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index 6bf052b118..45c88863b1 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -8,6 +8,7 @@ [re-frame.core :as re-frame] [react-native.core :as rn] [react-native.safe-area :as safe-area] + [status-im2.contexts.quo-preview.animated-header-list.animated-header-list :as animated-header-list] [status-im2.contexts.quo-preview.avatars.account-avatar :as account-avatar] [status-im2.contexts.quo-preview.avatars.channel-avatar :as channel-avatar] [status-im2.contexts.quo-preview.avatars.group-avatar :as group-avatar] @@ -46,6 +47,7 @@ [status-im2.contexts.quo-preview.navigation.top-nav :as top-nav] [status-im2.contexts.quo-preview.notifications.activity-logs :as activity-logs] [status-im2.contexts.quo-preview.notifications.toast :as toast] + [status-im2.contexts.quo-preview.onboarding.small-option-card :as small-option-card] [status-im2.contexts.quo-preview.posts-and-attachments.messages-skeleton :as messages-skeleton] [status-im2.contexts.quo-preview.profile.collectible :as collectible] [status-im2.contexts.quo-preview.profile.profile-card :as profile-card] @@ -68,8 +70,7 @@ [status-im2.contexts.quo-preview.wallet.lowest-price :as lowest-price] [status-im2.contexts.quo-preview.wallet.network-amount :as network-amount] [status-im2.contexts.quo-preview.wallet.network-breakdown :as network-breakdown] - [status-im2.contexts.quo-preview.wallet.token-overview :as token-overview] - [status-im2.contexts.quo-preview.animated-header-list.animated-header-list :as animated-header-list])) + [status-im2.contexts.quo-preview.wallet.token-overview :as token-overview])) (def screens-categories {:foundations [{:name :shadows @@ -186,6 +187,9 @@ {:name :toast :insets {:top false} :component toast/preview-toasts}] + :onboarding [{:name :small-option-card + :insets {:top false} + :component small-option-card/preview-small-option-card}] :posts-and-attachments [{:name :messages-skeleton :insets {:top false} :component messages-skeleton/preview-messages-skeleton}] diff --git a/src/status_im2/contexts/quo_preview/onboarding/small_option_card.cljs b/src/status_im2/contexts/quo_preview/onboarding/small_option_card.cljs new file mode 100644 index 0000000000..d668439b53 --- /dev/null +++ b/src/status_im2/contexts/quo_preview/onboarding/small_option_card.cljs @@ -0,0 +1,58 @@ +(ns status-im2.contexts.quo-preview.onboarding.small-option-card + (:require + [quo.react-native :as rn] + [quo2.components.onboarding.small-option-card.view :as quo2] + [quo2.foundations.colors :as colors] + [reagent.core :as reagent] + [status-im.react-native.resources :as resources] + [status-im2.contexts.quo-preview.preview :as preview])) + +(def descriptor + [{:label "Variant" + :key :variant + :type :select + :options [{:key :main + :value "Main"} + {:key :icon + :value "Icon"}]} + {:label "Image" + :key :image + :type :select + :options [{:key (resources/get-mock-image :small-opt-card-main) + :value "Image 1"} + {:key (resources/get-mock-image :small-opt-card-icon) + :value "Image 2"}]} + {:label "Title" + :key :title + :type :text} + {:label "Subtitle" + :key :subtitle + :type :text}]) + +(defn cool-preview + [] + (let [state (reagent/atom {:variant :main + :image (-> descriptor second :options first :key) + :title "Generate keys " + :subtitle "Your new self-sovereign identity in Status" + :on-press #(js/alert "Small option card pressed!")})] + (fn [] + [rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!} + [rn/view {:style {:padding-bottom 150}} + [rn/view {:style {:flex 1}} + [preview/customizer state descriptor]] + [rn/view + {:style {:background-color colors/neutral-80 + :padding 20}} + [quo2/small-option-card @state]]]]))) + +(defn preview-small-option-card + [] + [rn/view + {:style {:background-color (colors/theme-colors colors/white colors/neutral-90) + :flex 1}} + [rn/flat-list + {:flex 1 + :keyboardShouldPersistTaps :always + :header [cool-preview] + :key-fn str}]]) diff --git a/src/test_helpers/component.cljs b/src/test_helpers/component.cljs index 7603632390..52119ed515 100644 --- a/src/test_helpers/component.cljs +++ b/src/test_helpers/component.cljs @@ -45,3 +45,5 @@ (defn advance-timers-by-time [time-ms] (js/jest.advanceTimersByTime time-ms)) + +(def mock-fn js/jest.fn)