From f4d6f64a66a11e1f71859abd864c1d6c9a9e1740 Mon Sep 17 00:00:00 2001 From: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com> Date: Fri, 25 Aug 2023 23:46:26 +0800 Subject: [PATCH] [Feature] Implement "Showcase nav" component (#17100) This commit implements the "Showcase nav" component which is needed for emoji picker development. Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com> --- .../profile/showcase_nav/component_spec.cljs | 43 +++++++++++++++++++ .../profile/showcase_nav/style.cljs | 17 ++++++++ .../components/profile/showcase_nav/view.cljs | 40 +++++++++++++++++ src/quo2/core.cljs | 2 + src/quo2/core_spec.cljs | 1 + src/status_im2/contexts/quo_preview/main.cljs | 5 ++- .../quo_preview/profile/showcase_nav.cljs | 43 +++++++++++++++++++ 7 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 src/quo2/components/profile/showcase_nav/component_spec.cljs create mode 100644 src/quo2/components/profile/showcase_nav/style.cljs create mode 100644 src/quo2/components/profile/showcase_nav/view.cljs create mode 100644 src/status_im2/contexts/quo_preview/profile/showcase_nav.cljs diff --git a/src/quo2/components/profile/showcase_nav/component_spec.cljs b/src/quo2/components/profile/showcase_nav/component_spec.cljs new file mode 100644 index 0000000000..8c2c3a527b --- /dev/null +++ b/src/quo2/components/profile/showcase_nav/component_spec.cljs @@ -0,0 +1,43 @@ +(ns quo2.components.profile.showcase-nav.component-spec + (:require [quo2.components.profile.showcase-nav.view :as view] + [reagent.core :as reagent] + [test-helpers.component :as h])) + +(def nav-data + [{:icon :i/recent + :id :recent} + {:icon :i/profile + :id :profile} + {:icon :i/communities + :id :communities} + {:icon :i/wallet + :id :wallet} + {:icon :i/nft + :id :nft} + {:icon :i/token + :id :token}]) + +(h/describe "Profile - Showcase nav" + (h/test "default render" + (h/render [view/view {:data nav-data}]) + (-> (count (h/query-all-by-label-text :showcase-nav-item)) + (h/expect) + (.toEqual (count nav-data)))) + + (h/test "on press button" + (let [event (h/mock-fn)] + (h/render [view/view + {:data nav-data + :on-press #(event)}]) + (h/fire-event :press (get (h/get-all-by-label-text :showcase-nav-item) 0)) + (-> (h/expect event) + (.toHaveBeenCalled)))) + + (h/test "active id updated" + (let [active-id (reagent/atom :recent)] + (h/render [view/view + {:data nav-data + :on-press #(reset! active-id %)}]) + (h/fire-event :press (get (h/get-all-by-label-text :showcase-nav-item) 3)) + (-> (h/expect @active-id) + (.toStrictEqual :wallet))))) diff --git a/src/quo2/components/profile/showcase_nav/style.cljs b/src/quo2/components/profile/showcase_nav/style.cljs new file mode 100644 index 0000000000..22ee2a101f --- /dev/null +++ b/src/quo2/components/profile/showcase_nav/style.cljs @@ -0,0 +1,17 @@ +(ns quo2.components.profile.showcase-nav.style + (:require [quo2.foundations.colors :as colors])) + +(def root-container + {:height 56}) + +(defn container + [state theme] + {:padding-top 12 + :padding-left 20 + :padding-bottom 12 + :background-color (case state + :default (colors/theme-colors colors/white colors/neutral-95 theme) + :transparent)}) + +(def button-container + {:margin-right 8}) diff --git a/src/quo2/components/profile/showcase_nav/view.cljs b/src/quo2/components/profile/showcase_nav/view.cljs new file mode 100644 index 0000000000..b6e3c22595 --- /dev/null +++ b/src/quo2/components/profile/showcase_nav/view.cljs @@ -0,0 +1,40 @@ +(ns quo2.components.profile.showcase-nav.view + (:require [quo2.components.buttons.button.view :as button] + [quo2.components.profile.showcase-nav.style :as style] + [quo2.theme :as quo.theme] + [react-native.core :as rn])) + +(defn- render-button + [{:keys [icon id]} _ _ {:keys [state on-press active-id]}] + (let [active? (= id active-id) + button-type (if active? :grey :ghost) + scroll-state? (= state :scroll)] + [button/button + {:accessibility-label :showcase-nav-item + :size 32 + :type button-type + :background (when scroll-state? :blur) + :icon-only? true + :on-press (fn [] + (when on-press + (on-press id))) + :container-style style/button-container} + icon])) + +(defn- view-internal + [{:keys [theme container-style default-active state data on-press active-id]}] + [rn/view + {:style style/root-container + :accessibility-label :showcase-nav} + [rn/flat-list + {:data data + :key-fn str + :horizontal true + :shows-horizontal-scroll-indicator false + :content-container-style (merge (style/container state theme) container-style) + :render-fn render-button + :render-data {:state state + :on-press on-press + :active-id (or active-id default-active)}}]]) + +(def view (quo.theme/with-theme view-internal)) diff --git a/src/quo2/core.cljs b/src/quo2/core.cljs index 093ed4bfda..2fbc90cae2 100644 --- a/src/quo2/core.cljs +++ b/src/quo2/core.cljs @@ -87,6 +87,7 @@ quo2.components.password.tips.view quo2.components.profile.profile-card.view quo2.components.profile.select-profile.view + quo2.components.profile.showcase-nav.view quo2.components.reactions.reaction quo2.components.record-audio.record-audio.view quo2.components.record-audio.soundtrack.view @@ -273,6 +274,7 @@ ;;;; Profile (def profile-card quo2.components.profile.profile-card.view/profile-card) (def select-profile quo2.components.profile.select-profile.view/view) +(def showcase-nav quo2.components.profile.showcase-nav.view/view) ;;;; Reactions (def reaction quo2.components.reactions.reaction/reaction) diff --git a/src/quo2/core_spec.cljs b/src/quo2/core_spec.cljs index d1d4523285..6d3648c81d 100644 --- a/src/quo2/core_spec.cljs +++ b/src/quo2/core_spec.cljs @@ -45,6 +45,7 @@ [quo2.components.onboarding.small-option-card.component-spec] [quo2.components.password.tips.component-spec] [quo2.components.profile.select-profile.component-spec] + [quo2.components.profile.showcase-nav.component-spec] [quo2.components.record-audio.record-audio.component-spec] [quo2.components.record-audio.soundtrack.component-spec] [quo2.components.selectors.disclaimer.component-spec] diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index fa51d5d8ac..d7dca05eaf 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -85,6 +85,7 @@ [status-im2.contexts.quo-preview.profile.collectible :as collectible] [status-im2.contexts.quo-preview.profile.profile-card :as profile-card] [status-im2.contexts.quo-preview.profile.select-profile :as select-profile] + [status-im2.contexts.quo-preview.profile.showcase-nav :as showcase-nav] [status-im2.contexts.quo-preview.reactions.react :as react] [status-im2.contexts.quo-preview.record-audio.record-audio :as record-audio] [status-im2.contexts.quo-preview.selectors.disclaimer :as disclaimer] @@ -294,7 +295,9 @@ {:name :collectible :component collectible/preview-collectible} {:name :select-profile - :component select-profile/preview-select-profile}] + :component select-profile/preview-select-profile} + {:name :showcase-nav + :component showcase-nav/view}] :reactions [{:name :react :component react/preview-react}] :record-audio [{:name :record-audio diff --git a/src/status_im2/contexts/quo_preview/profile/showcase_nav.cljs b/src/status_im2/contexts/quo_preview/profile/showcase_nav.cljs new file mode 100644 index 0000000000..4b609e5983 --- /dev/null +++ b/src/status_im2/contexts/quo_preview/profile/showcase_nav.cljs @@ -0,0 +1,43 @@ +(ns status-im2.contexts.quo-preview.profile.showcase-nav + (:require [quo2.core :as quo] + [reagent.core :as reagent] + [status-im2.contexts.quo-preview.preview :as preview])) + +(def generate-nav-data + (->> (range 15) + (map inc) + (mapv (fn [index] + {:icon (rand-nth [:i/recent :i/profile :i/communities :i/wallet :i/nft :i/token + :i/delete]) + :id index})))) + +(def descriptor + [{:type :number + :key :previews-length} + {:type :select + :key :state + :options [{:key :default + :value "default"} + {:key :scroll + :value "scroll"}]}]) + +(defn view + [] + (let [state (reagent/atom {:state :default + :previews-length 10 + :active-id 0}) + component-state (reagent/cursor state [:state]) + previews-length (reagent/cursor state [:previews-length]) + active-id (reagent/cursor state [:active-id]) + nav-data generate-nav-data] + (fn [] + [preview/preview-container + {:state state + :descriptor descriptor + :component-container-style {:padding-horizontal 0}} + [quo/showcase-nav + {:default-active 3 + :state @component-state + :active-id @active-id + :data (take (or @previews-length 1) nav-data) + :on-press #(swap! state assoc :active-id %)}]])))