[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:
parent
a416267094
commit
f4d6f64a66
|
@ -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)))))
|
|
@ -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})
|
|
@ -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))
|
|
@ -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)
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 %)}]])))
|
Loading…
Reference in New Issue