[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>
This commit is contained in:
Mohamed Javid 2023-08-25 23:46:26 +08:00 committed by GitHub
parent a416267094
commit f4d6f64a66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 150 additions and 1 deletions

View File

@ -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)))))

View File

@ -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})

View File

@ -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))

View File

@ -87,6 +87,7 @@
quo2.components.password.tips.view quo2.components.password.tips.view
quo2.components.profile.profile-card.view quo2.components.profile.profile-card.view
quo2.components.profile.select-profile.view quo2.components.profile.select-profile.view
quo2.components.profile.showcase-nav.view
quo2.components.reactions.reaction quo2.components.reactions.reaction
quo2.components.record-audio.record-audio.view quo2.components.record-audio.record-audio.view
quo2.components.record-audio.soundtrack.view quo2.components.record-audio.soundtrack.view
@ -273,6 +274,7 @@
;;;; Profile ;;;; Profile
(def profile-card quo2.components.profile.profile-card.view/profile-card) (def profile-card quo2.components.profile.profile-card.view/profile-card)
(def select-profile quo2.components.profile.select-profile.view/view) (def select-profile quo2.components.profile.select-profile.view/view)
(def showcase-nav quo2.components.profile.showcase-nav.view/view)
;;;; Reactions ;;;; Reactions
(def reaction quo2.components.reactions.reaction/reaction) (def reaction quo2.components.reactions.reaction/reaction)

View File

@ -45,6 +45,7 @@
[quo2.components.onboarding.small-option-card.component-spec] [quo2.components.onboarding.small-option-card.component-spec]
[quo2.components.password.tips.component-spec] [quo2.components.password.tips.component-spec]
[quo2.components.profile.select-profile.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.record-audio.component-spec]
[quo2.components.record-audio.soundtrack.component-spec] [quo2.components.record-audio.soundtrack.component-spec]
[quo2.components.selectors.disclaimer.component-spec] [quo2.components.selectors.disclaimer.component-spec]

View File

@ -85,6 +85,7 @@
[status-im2.contexts.quo-preview.profile.collectible :as collectible] [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.profile-card :as profile-card]
[status-im2.contexts.quo-preview.profile.select-profile :as select-profile] [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.reactions.react :as react]
[status-im2.contexts.quo-preview.record-audio.record-audio :as record-audio] [status-im2.contexts.quo-preview.record-audio.record-audio :as record-audio]
[status-im2.contexts.quo-preview.selectors.disclaimer :as disclaimer] [status-im2.contexts.quo-preview.selectors.disclaimer :as disclaimer]
@ -294,7 +295,9 @@
{:name :collectible {:name :collectible
:component collectible/preview-collectible} :component collectible/preview-collectible}
{:name :select-profile {: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 :reactions [{:name :react
:component react/preview-react}] :component react/preview-react}]
:record-audio [{:name :record-audio :record-audio [{:name :record-audio

View File

@ -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 %)}]])))