diff --git a/src/quo2/components/navigation/page_nav.cljs b/src/quo2/components/navigation/page_nav.cljs new file mode 100644 index 0000000000..c504fd7bda --- /dev/null +++ b/src/quo2/components/navigation/page_nav.cljs @@ -0,0 +1,175 @@ +(ns quo2.components.navigation.page-nav + (:require [quo.react-native :as rn] + [quo2.foundations.colors :as colors] + [quo2.components.icon :as icons] + [status-im.utils.dimensions :as dimensions] + [clojure.string :as string] + [quo2.components.markdown.text :as text])) + +(def ^:private centrify-style + {:display :flex + :justify-content :center + :align-items :center}) + +(def ^:private align-left (assoc centrify-style :align-items :flex-start)) + +(def ^:private icon-styles (assoc centrify-style :width 32 :height 32 :border-radius 10)) + +(defn- big? [size] (= size :big)) + +(defn- icon-props [color size] + (merge {:size 20 + :container-style {:width (if (big? size) + 20 + 16) + :height (if (big? size) + 20 + 16)}} + (if-not (string/blank? color) + {:color color} + {:no-color true}))) + +(defn- mid-section-comp + [{:keys [mid-section-description-user-icon horizontal-description? text-secondary-color align-mid? text-color mid-section-icon mid-section-main-text mid-section-type mid-section-description]}] + [rn/view {:style (assoc + centrify-style + :flex-direction :row + :margin-horizontal 2)} + (when (or (and (not horizontal-description?) + align-mid? + (not= :text-with-description mid-section-type)) + (and mid-section-description-user-icon + (not mid-section-icon))) + [rn/image {:source {:uri mid-section-description-user-icon} + :style {:width 32 + :height 32 + :border-radius 32 + :margin-right 8}}]) + [rn/view {:style {:flex-direction (if horizontal-description? + :row + :column)}} + [text/text {:size :paragraph-1 + :weight :semi-bold + :style {:color text-color + :line-height 21}} + mid-section-main-text] + (when mid-section-description + [text/text {:size :paragraph-2 + :weight :medium + :style (cond-> {:padding-right 4 + :color text-secondary-color + :line-height 18} + horizontal-description? (assoc :margin-left 4 :margin-top 2))} + mid-section-description])]]) + +(defn- mid-section + [{:keys [horizontal-description? one-icon-align-left? mid-section-type left-align? mid-section-main-text mid-section-right-icon mid-section-main-text-icon-color mid-section-left-icon] :as mid-section-props}] + (let [text-color (if (colors/dark?) colors/neutral-5 colors/neutral-95) + text-secondary-color (if (colors/dark?) colors/neutral-40 colors/neutral-50) + mid-section-comp-instance [mid-section-comp (assoc mid-section-props :text-secondary-color text-secondary-color)]] + [rn/view {:style (merge + (if left-align? + align-left + centrify-style) + {:flex 1 + :margin-left 4 + :text-align-vertical :center})} + (case mid-section-type + :text-only [text/text {:size :paragraph-1 + :weight :semi-bold + :style {:color text-color}} + mid-section-main-text] + :text-with-two-icons [rn/view {:style (assoc centrify-style :flex-direction :row)} + [icons/icon mid-section-left-icon + (icon-props mid-section-main-text-icon-color :big)] + [text/text {:size :paragraph-1 + :weight :semi-bold + :style {:padding-horizontal 4 + :color text-color}} + mid-section-main-text] + + [icons/icon mid-section-right-icon + (icon-props mid-section-main-text-icon-color :big)]] + :text-with-one-icon [rn/view {:style {:flex-direction :row}} + (if one-icon-align-left? + [rn/view {:style {:flex-direction :row + :align-items :center}} + (when horizontal-description? + [icons/icon mid-section-left-icon + (icon-props mid-section-main-text-icon-color :big)]) + mid-section-comp-instance] + [rn/view {:style {:flex-direction :row + :align-items :center}} + mid-section-comp-instance + (when horizontal-description? + [icons/icon mid-section-left-icon + (icon-props mid-section-main-text-icon-color :big)])])] + :text-with-description mid-section-comp-instance)])) + +(defn- right-section-icon + [{:keys [background-color icon icon-color push-to-the-left?] :or {push-to-the-left? false}}] + [rn/view {:style (assoc + icon-styles + :background-color background-color + :width 32 + :height 32 + :margin-right (if push-to-the-left? 8 0))} + [icons/icon icon (icon-props icon-color :big)]]) + +(defn page-nav + [{:keys [one-icon-align-left? horizontal-description? align-mid? page-nav-color page-nav-background-uri mid-section-type mid-section-icon mid-section-main-text mid-section-left-icon mid-section-right-icon mid-section-description mid-section-description-color mid-section-description-icon mid-section-description-user-icon mid-section-main-text-icon-color left-section-icon left-section-icon-color left-section-icon-background-color right-section-icons]}] + (let [{:keys [height width]} (dimensions/window) + put-middle-section-on-left? (or align-mid? + (> (count right-section-icons) 1)) + mid-section-props {:mid-section-type mid-section-type + :horizontal-description? horizontal-description? + :mid-section-main-text mid-section-main-text + :one-icon-align-left? one-icon-align-left? + :mid-section-right-icon mid-section-right-icon + :mid-section-icon mid-section-icon + :mid-section-main-text-icon-color mid-section-main-text-icon-color + :mid-section-left-icon mid-section-left-icon}] + [rn/view {:style (cond-> + {:display :flex + :flex-direction :row + :width width + :height (* 0.0497 height) + ;; iPhone 11 Pro's height in Figma divided by Component height 56/1125 + :align-items :center + :padding-horizontal 20 + :justify-content :space-between} + page-nav-background-uri (assoc :background-color page-nav-color) + page-nav-color (assoc :background page-nav-background-uri))} + [rn/view {:style {:flex 1 + :flex-direction :row + :align-items :center}} + [rn/view {:style (merge + icon-styles + {:background-color left-section-icon-background-color + :width 32 + :height 32} + (when put-middle-section-on-left? {:margin-right 5}))} + [icons/icon left-section-icon (icon-props left-section-icon-color :big)]] + (when put-middle-section-on-left? + [mid-section (assoc mid-section-props + :left-align? true + :mid-section-description mid-section-description + :mid-section-description-color mid-section-description-color + :mid-section-description-icon mid-section-description-icon + :align-mid? align-mid? + :mid-section-description-user-icon mid-section-description-user-icon)])] + (when-not put-middle-section-on-left? + [mid-section mid-section-props]) + [rn/view {:style (assoc + centrify-style + :flex-direction :row + :flex 1 + :justify-content :flex-end)} + (let [last-icon-index (- (count right-section-icons) 1)] + (map-indexed (fn [index {:keys [icon background-color icon-color]}] + ^{:key index} + [right-section-icon {:icon icon + :background-color background-color + :icon-color icon-color + :push-to-the-left? (if (= index last-icon-index) false true)}]) + right-section-icons))]])) diff --git a/src/quo2/screens/main.cljs b/src/quo2/screens/main.cljs index 0e38015753..ebdfea07b2 100644 --- a/src/quo2/screens/main.cljs +++ b/src/quo2/screens/main.cljs @@ -45,6 +45,7 @@ [quo2.screens.wallet.token-overview :as token-overview] [quo2.screens.wallet.network-breakdown :as network-breakdown] [quo2.screens.wallet.network-amount :as network-amount] + [quo2.screens.navigation.page-nav :as page-nav] [re-frame.core :as re-frame])) (def screens-categories @@ -110,7 +111,10 @@ :component bottom-nav-tab/preview-bottom-nav-tab} {:name :top-nav :insets {:top false} - :component top-nav/preview-top-nav}] + :component top-nav/preview-top-nav} + {:name :page-nav + :insets {:top false} + :component page-nav/preview-page-nav}] :notifications [{:name :activity-logs :insets {:top false} :component activity-logs/preview-activity-logs}] diff --git a/src/quo2/screens/navigation/page_nav.cljs b/src/quo2/screens/navigation/page_nav.cljs new file mode 100644 index 0000000000..284d218686 --- /dev/null +++ b/src/quo2/screens/navigation/page_nav.cljs @@ -0,0 +1,106 @@ +(ns quo2.screens.navigation.page-nav + (:require [quo.previews.preview :as preview] + [quo.react-native :as rn] + [quo2.components.navigation.page-nav :as quo2] + [quo2.foundations.colors :as colors] + [reagent.core :as reagent])) + +(def ^:private descriptor + [{:label "Page nav variation" + :key :selected-variation + :type :select + :options [{:key :text-only? + :value "Text only"} + {:key :align-left? + :value "Align Left"} + {:key :align-left-top-down-text? + :value "Align left top down text?"} + {:key :align-left-with-icon? + :value "Align Left with icon ?"} + {:key :one-icon-align-left? + :value "One icon on the left ?"} + {:key :one-icon-align-right? + :value "One icon on the right ?"} + {:key :two-icons? + :value "Two icons ?"} + {:key :user-icon? + :value "User icon ?"} + {:key :empty? + :value "Empty ?"}]} + {:label "Number of right icons" + :key :number-of-right-icons + :type :select + :options [{:key 1 + :value 1} + {:key 2 + :value 2} + {:key 3 + :value 3}]}]) + +(def ^:private selected-variation (reagent/atom {:selected-variation :text-only? + :number-of-right-icons 1})) + +(defn- cool-preview [] + (let [right-icon {:background-color (if (colors/dark?) + colors/neutral-80 + colors/neutral-20) + :icon :main-icons/placeholder + :icon-color nil} + base-props {:horizontal-description? true + :one-icon-align-left? true + :align-mid? false + :page-nav-color :transparent + :page-nav-background-uri "" + :mid-section-type :text-with-description + :mid-section-icon :main-icons/placeholder + :mid-section-main-text "Status" + :mid-section-left-icon :main-icons/placeholder + :mid-section-right-icon :main-icons/placeholder + :mid-section-description "SNT" + :mid-section-description-color "black" + :mid-section-description-icon :main-icons/placeholder + :mid-section-description-user-icon "https://i.picsum.photos/id/810/200/300.jpg?hmac=HgwlXd-OaLOAqhGyCiZDUb_75EgUI4u0GtS7nfgxd8s" + :left-section-icon :main-icons/unlocked + :left-section-icon-background-color (if (colors/dark?) + colors/neutral-80 + colors/neutral-20)} + create-variation #(merge %1 %2) + variations {:text-only? base-props + :align-left? (create-variation base-props {:align-mid? true}) + :one-icon-align-left? (create-variation base-props {:one-icon-align-left? true + :mid-section-type :text-with-one-icon}) + :one-icon-align-right? (create-variation base-props {:one-icon-align-left? false + :mid-section-type :text-with-one-icon}) + :two-icons? (create-variation base-props {:mid-section-type :text-with-two-icons}) + :user-icon? (create-variation base-props {:align-mid? true + :horizontal-description? false + :mid-section-type :text-with-one-icon}) + :empty? (create-variation base-props {:mid-section-main-text "" + :mid-section-description ""}) + :align-left-with-icon? (create-variation base-props {:align-mid? true + :mid-section-type :text-with-one-icon}) + :align-left-top-down-text? (create-variation base-props {:align-mid? true + :horizontal-description? false + :mid-section-type :text-with-description})} + state (reagent/atom (-> (get variations (:selected-variation @selected-variation)) + (assoc :right-section-icons (repeat (:number-of-right-icons @selected-variation) right-icon))))] + (fn [] + [rn/view {:margin-bottom 50 + :padding 16} + [rn/view {:flex 1} + [preview/customizer selected-variation descriptor]] + [rn/view {:padding-vertical 30 + :flex-direction :row + :justify-content :center} + [quo2/page-nav @state]]]))) + +(def ^:private trackable-cool-preview (reagent/track cool-preview selected-variation)) + +(defn preview-page-nav [] + [rn/view {:background-color (colors/theme-colors colors/white + colors/neutral-90) + :flex 1} + [rn/flat-list {:flex 1 + :keyboardShouldPersistTaps :always + :header [@trackable-cool-preview] + :key-fn str}]])