From bf76ca167a3cbe65fe0a243bd2c98f9514af3880 Mon Sep 17 00:00:00 2001 From: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com> Date: Fri, 29 Sep 2023 20:07:27 +0800 Subject: [PATCH] Implement dropdown component and update it's usage across the codebase (#17412) This commit: - Removes the existing dropdown component which uses the old button component under the hood - Implements the Dropdown component - Updates the usage in the page-nav component for types dropdown, token and wallet-networks - Updates the usage in the photo selector bottom sheet - Updates the usage in the Quo2 preview main screen --------- Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com> --- .../components/buttons/button/properties.cljs | 2 + src/quo2/components/dropdowns/dropdown.cljs | 20 -- .../dropdowns/dropdown/component_spec.cljs | 35 +++ .../dropdowns/dropdown/properties.cljs | 120 ++++++++ .../components/dropdowns/dropdown/style.cljs | 53 ++++ .../components/dropdowns/dropdown/view.cljs | 87 ++++++ .../dropdowns/old_button_style.cljs | 264 ------------------ .../components/dropdowns/old_button_view.cljs | 138 --------- src/quo2/components/icons/svg.cljs | 97 ++++++- .../components/navigation/page_nav/style.cljs | 6 - .../components/navigation/page_nav/view.cljs | 96 ++++--- src/quo2/core.cljs | 4 +- src/quo2/core_spec.cljs | 1 + src/quo2/foundations/colors.cljs | 2 +- .../contexts/chat/photo_selector/view.cljs | 46 +-- .../quo_preview/dropdowns/dropdown.cljs | 97 ++++--- src/status_im2/contexts/quo_preview/main.cljs | 10 +- .../quo_preview/navigation/page_nav.cljs | 7 +- 18 files changed, 540 insertions(+), 545 deletions(-) delete mode 100644 src/quo2/components/dropdowns/dropdown.cljs create mode 100644 src/quo2/components/dropdowns/dropdown/component_spec.cljs create mode 100644 src/quo2/components/dropdowns/dropdown/properties.cljs create mode 100644 src/quo2/components/dropdowns/dropdown/style.cljs create mode 100644 src/quo2/components/dropdowns/dropdown/view.cljs delete mode 100644 src/quo2/components/dropdowns/old_button_style.cljs delete mode 100644 src/quo2/components/dropdowns/old_button_view.cljs diff --git a/src/quo2/components/buttons/button/properties.cljs b/src/quo2/components/buttons/button/properties.cljs index a397dbe086..dcf89f7a6c 100644 --- a/src/quo2/components/buttons/button/properties.cljs +++ b/src/quo2/components/buttons/button/properties.cljs @@ -1,6 +1,8 @@ (ns quo2.components.buttons.button.properties (:require [quo2.foundations.colors :as colors])) +(def backgrounds #{:photo :blur}) + (defn custom-color-type [customization-color icon-only?] {:icon-color colors/white-opa-70 diff --git a/src/quo2/components/dropdowns/dropdown.cljs b/src/quo2/components/dropdowns/dropdown.cljs deleted file mode 100644 index d7e499b8bf..0000000000 --- a/src/quo2/components/dropdowns/dropdown.cljs +++ /dev/null @@ -1,20 +0,0 @@ -(ns quo2.components.dropdowns.dropdown - (:require [quo2.components.dropdowns.old-button-view :as old-button])) - -(defn dropdown - [_ _] - (fn [{:keys [on-change selected] :as opts} children] - ;TODO: Dropdown needs to be implemented/refactored to be its own component - - ;https://github.com/status-im/status-mobile/issues/16456 - [old-button/button - (merge - opts - {:after (if selected :i/chevron-top :i/chevron-down) - :icon-size 12 - :icon-container-size 14 - :icon-container-rounded? true - :override-after-margins {:left 7 - :right 9} - :pressed selected - :on-press #(when on-change (on-change selected))}) - children])) diff --git a/src/quo2/components/dropdowns/dropdown/component_spec.cljs b/src/quo2/components/dropdowns/dropdown/component_spec.cljs new file mode 100644 index 0000000000..4cf6afab3f --- /dev/null +++ b/src/quo2/components/dropdowns/dropdown/component_spec.cljs @@ -0,0 +1,35 @@ +(ns quo2.components.dropdowns.dropdown.component-spec + (:require [quo2.components.dropdowns.dropdown.view :as dropdown] + [test-helpers.component :as h])) + +(h/describe "Dropdown" + (h/test "default render" + (let [label "Recent"] + (h/render [dropdown/view {} label]) + (h/is-truthy (h/get-by-label-text :dropdown)) + (h/is-null (h/query-by-label-text :left-icon)) + (h/is-truthy (h/get-by-text label)) + (h/is-truthy (h/get-by-label-text :right-icon)))) + + (h/test "render with icon" + (let [label "Recent"] + (h/render [dropdown/view {:icon? true} label]) + (h/is-truthy (h/get-by-label-text :dropdown)) + (h/is-truthy (h/get-by-label-text :left-icon)) + (h/is-truthy (h/get-by-text label)) + (h/is-truthy (h/get-by-label-text :right-icon)))) + + (h/test "render only emoji" + (let [label "🍑"] + (h/render [dropdown/view {:emoji? true} label]) + (h/is-truthy (h/get-by-label-text :dropdown)) + (h/is-null (h/query-by-label-text :left-icon)) + (h/is-truthy (h/get-by-text label)) + (h/is-null (h/query-by-label-text :right-icon)))) + + (h/test "on-press" + (let [event (h/mock-fn) + label "Recent"] + (h/render [dropdown/view {:on-press event} label]) + (h/fire-event :press (h/get-by-text label)) + (h/was-called event)))) diff --git a/src/quo2/components/dropdowns/dropdown/properties.cljs b/src/quo2/components/dropdowns/dropdown/properties.cljs new file mode 100644 index 0000000000..8f3f9c29ab --- /dev/null +++ b/src/quo2/components/dropdowns/dropdown/properties.cljs @@ -0,0 +1,120 @@ +(ns quo2.components.dropdowns.dropdown.properties + (:require [quo2.foundations.colors :as colors])) + +(def backgrounds #{:photo :blur}) + +(def sizes + {:size-40 {:size 40 + :icon-size 20 + :emoji-size 20 + :emoji-padding 10 + :padding-vertical 9 + :padding-left {:default 16 :icon 12} + :padding-right 12 + :border-radius 12 + :text-size :paragraph-1} + :size-32 {:size 32 + :icon-size 20 + :emoji-size 20 + :emoji-padding 6 + :padding-vertical 5 + :padding-left {:default 12 :icon 8} + :padding-right 8 + :border-radius 10 + :text-size :paragraph-1} + :size-24 {:size 24 + :icon-size 12 + :emoji-size 12 + :emoji-padding 6 + :padding-vertical 3 + :padding-left {:default 8 :icon 8} + :padding-right 8 + :border-radius 8 + :text-size :paragraph-2}}) + +(defn- custom-color-type + [customization-color] + {:left-icon-color colors/white-opa-70 + :right-icon-color colors/white-opa-20 + :right-icon-color-2 colors/white + :label-color colors/white + :background-color (colors/custom-color customization-color 50)}) + +(def sizes-to-exclude-blur-in-photo-bg #{:size-40}) + +(defn- grey-photo + [theme active? size] + {:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme) + :right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme) + :right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme) + :label-color (colors/theme-colors colors/neutral-100 colors/white theme) + :blur-overlay-color (when (and (= theme :dark) (nil? (sizes-to-exclude-blur-in-photo-bg size))) + (if active? colors/neutral-80-opa-50 colors/neutral-80-opa-40)) + :blur-type (if (= theme :light) :light :dark) + :background-color (cond + (= theme :light) + (if active? colors/white-opa-50 colors/white-opa-40) + + (and (= theme :dark) (sizes-to-exclude-blur-in-photo-bg size)) + (if active? colors/neutral-80-opa-50 colors/neutral-80-opa-40))}) + +(defn- grey-blur + [theme active?] + {:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme) + :right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme) + :right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme) + :label-color (colors/theme-colors colors/neutral-100 colors/white theme) + :background-color (if active? + (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme) + (colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme))}) + +(defn- outline-blur + [theme active?] + {:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme) + :right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme) + :right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme) + :label-color (colors/theme-colors colors/neutral-100 colors/white theme) + :border-color (if active? + (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme) + (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme))}) + +(defn- outline + [theme active?] + {:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme) + :right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme) + :right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme) + :label-color (colors/theme-colors colors/neutral-100 colors/white theme) + :border-color (if active? + (colors/theme-colors colors/neutral-40 colors/neutral-60 theme) + (colors/theme-colors colors/neutral-30 colors/neutral-70 theme))}) + +(defn- grey + [theme active?] + {:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme) + :right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme) + :right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme) + :label-color (colors/theme-colors colors/neutral-100 colors/white theme) + :background-color (if active? + (colors/theme-colors colors/neutral-20 colors/neutral-80 theme) + (colors/theme-colors colors/neutral-5 colors/neutral-90 theme))}) + +(defn- ghost + [theme active?] + {:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme) + :right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme) + :right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme) + :label-color (colors/theme-colors colors/neutral-100 colors/white theme) + :background-color (when active? + (colors/theme-colors colors/neutral-10 colors/neutral-80 theme))}) + +(defn get-colors + [{:keys [customization-color theme type state background size]}] + (let [active? (= state :active)] + (cond + (and (= background :photo) (= type :grey)) (grey-photo theme active? size) + (and (= background :blur) (= type :grey)) (grey-blur theme active?) + (and (= background :blur) (= type :outline)) (outline-blur theme active?) + (= type :outline) (outline theme active?) + (= type :grey) (grey theme active?) + (= type :ghost) (ghost theme active?) + (= type :customization) (custom-color-type customization-color)))) diff --git a/src/quo2/components/dropdowns/dropdown/style.cljs b/src/quo2/components/dropdowns/dropdown/style.cljs new file mode 100644 index 0000000000..7bab033dec --- /dev/null +++ b/src/quo2/components/dropdowns/dropdown/style.cljs @@ -0,0 +1,53 @@ +(ns quo2.components.dropdowns.dropdown.style) + +(def gap 4) + +(def blur-view + {:position :absolute + :top 0 + :left 0 + :right 0 + :bottom 0}) + +(def left-icon + {:margin-right gap}) + +(defn right-icon + [label-color] + {:color label-color + :margin-right gap}) + +(defn- add-styles-for-emoji + [style size emoji-padding] + (-> style + (dissoc :padding-vertical :padding-left :padding-right) + (assoc :width size + :padding emoji-padding))) + +(defn root-container + [{:keys [size border-radius padding-vertical padding-right padding-left emoji-padding]} + {:keys [background-color border-color]} + {:keys [icon? emoji? state]}] + (cond-> {:height size + :align-items :center + :justify-content :center + :flex-direction :row + :padding-vertical padding-vertical + :padding-left (:default padding-left) + :padding-right padding-right + :overflow :hidden + :background-color background-color + :border-radius border-radius} + + icon? + (assoc :padding-left (:icon padding-left)) + + emoji? + (add-styles-for-emoji size emoji-padding) + + border-color + (assoc :border-color border-color + :border-width 1) + + (= state :disabled) + (assoc :opacity 0.3))) diff --git a/src/quo2/components/dropdowns/dropdown/view.cljs b/src/quo2/components/dropdowns/dropdown/view.cljs new file mode 100644 index 0000000000..9acd54fb2d --- /dev/null +++ b/src/quo2/components/dropdowns/dropdown/view.cljs @@ -0,0 +1,87 @@ +(ns quo2.components.dropdowns.dropdown.view + (:require [quo2.components.dropdowns.dropdown.properties :as properties] + [quo2.components.dropdowns.dropdown.style :as style] + [quo2.components.icon :as icon] + [quo2.components.markdown.text :as text] + [quo2.foundations.customization-colors :as customization-colors] + [quo2.theme :as theme] + [react-native.blur :as blur] + [react-native.core :as rn])) + +(defn- view-internal + [{:keys [type size state background customization-color theme on-press icon-name icon? emoji? + accessibility-label] + :or {type :grey + size :size-40 + state :default + icon? false + emoji? false + icon-name :i/placeholder} + :as props} + text] + (let [{:keys [icon-size text-size emoji-size border-radius] + :as size-properties} (properties/sizes size) + {:keys [left-icon-color right-icon-color right-icon-color-2 label-color blur-type + blur-overlay-color] + :as colors} (properties/get-colors props) + right-icon (if (= state :active) :i/pullup :i/dropdown) + customization-type? (= type :customization) + show-blur-background? (and (= background :photo) + (= type :grey) + (nil? (properties/sizes-to-exclude-blur-in-photo-bg size)))] + [rn/pressable + {:accessibility-label (or accessibility-label :dropdown) + :disabled (= state :disabled) + :on-press on-press + :style (style/root-container size-properties colors props)} + (when show-blur-background? + [blur/view + {:blur-radius 20 + :blur-type blur-type + :overlay-color blur-overlay-color + :style style/blur-view}]) + (when customization-type? + [customization-colors/overlay + {:customization-color customization-color + :theme theme + :pressed? (= state :active) + :border-radius border-radius}]) + (if emoji? + [rn/text + {:adjusts-font-size-to-fit true + :style {:font-size emoji-size}} + text] + [:<> + (when icon? + [icon/icon + icon-name + {:accessibility-label :left-icon + :color left-icon-color + :size icon-size + :container-style style/left-icon}]) + [text/text + {:size text-size + :weight :medium + :number-of-lines 1 + :style (style/right-icon label-color)} + text] + [icon/icon + right-icon + {:size icon-size + :accessibility-label :right-icon + :color right-icon-color + :color-2 right-icon-color-2}]])])) + +(def view + "Props: + - type: :outline |:grey (default) | :ghost | :customization + - size: :size-40 (default) | :size-32 | :size-24 + - state: :default (default) | :active | :disabled + - emoji?: boolean + - icon?: boolean + - background: :blur | :photo (optional) + - icon-name: keyword + - on-press: function + + Child: string - used as label or emoji (for emoji only)" + (theme/with-theme view-internal)) diff --git a/src/quo2/components/dropdowns/old_button_style.cljs b/src/quo2/components/dropdowns/old_button_style.cljs deleted file mode 100644 index 2edda941d1..0000000000 --- a/src/quo2/components/dropdowns/old_button_style.cljs +++ /dev/null @@ -1,264 +0,0 @@ -(ns quo2.components.dropdowns.old-button-style - (:require [quo2.foundations.colors :as colors])) - -(def blur-view - {:position :absolute - :top 0 - :left 0 - :right 0 - :bottom 0}) - -(defn before-icon-style - [{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded? - icon-size]}] - (merge - {:margin-left (or (get override-margins :left) - (if (= size 40) 12 8)) - :margin-right (or (get override-margins :right) 4) - :align-items :center - :justify-content :center} - (when icon-container-size - {:width icon-container-size - :height icon-container-size}) - (when icon-background-color - {:background-color icon-background-color}) - (when icon-container-rounded? - {:border-radius (/ (or icon-container-size icon-size) 2)}))) - -(defn after-icon-style - [{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded? - icon-size]}] - (merge - {:margin-left (or (get override-margins :left) 4) - :margin-right (or (get override-margins :right) - (if (= size 40) 12 8)) - :align-items :center - :justify-content :center} - (when icon-container-size - {:width icon-container-size - :height icon-container-size}) - (when icon-background-color - {:background-color icon-background-color}) - (when icon-container-rounded? - {:border-radius (/ (or icon-container-size icon-size) 2)}))) - -(defn themes - [customization-color] - {:light - {:primary {:icon-color colors/white - :icon-secondary-color colors/white-opa-70 - :label-color colors/white - :background-color {:default (colors/custom-color customization-color 50) - :pressed (colors/custom-color customization-color 60) - :disabled (colors/custom-color customization-color 50)}} - :secondary {:icon-color colors/primary-50 - :label-color colors/primary-50 - :background-color {:default colors/primary-50-opa-20 - :pressed colors/primary-50-opa-40 - :disabled colors/primary-50-opa-20}} - :grey {:icon-color colors/neutral-100 - :icon-secondary-color colors/neutral-50 - :label-color colors/neutral-100 - :background-color {:default colors/neutral-10 - :pressed colors/neutral-20 - :disabled colors/neutral-10}} - :dark-grey {:icon-color colors/neutral-100 - :icon-secondary-color colors/neutral-50 - :label-color colors/neutral-100 - :background-color {:default colors/neutral-20 - :pressed colors/neutral-30 - :disabled colors/neutral-20}} - :outline {:icon-color colors/neutral-50 - :icon-secondary-color colors/neutral-50 - :label-color colors/neutral-100 - :border-color {:default colors/neutral-30 - :pressed colors/neutral-40 - :disabled colors/neutral-30}} - :ghost {:icon-color colors/neutral-50 - :icon-secondary-color colors/neutral-50 - :label-color colors/neutral-100 - :background-color {:pressed colors/neutral-10}} - :danger {:icon-color colors/white - :icon-secondary-color colors/white-opa-70 - :label-color colors/white - :background-color {:default colors/danger-50 - :pressed colors/danger-60 - :disabled colors/danger-50}} - :positive {:icon-color colors/white - :icon-secondary-color colors/white-opa-70 - :label-color colors/white - :background-color {:default colors/success-50 - :pressed colors/success-60 - :disabled colors/success-50-opa-30}} - :photo-bg {:icon-color colors/neutral-100 - :icon-secondary-color colors/neutral-80-opa-40 - :label-color colors/neutral-100 - :background-color {:default colors/white-opa-40 - :pressed colors/white-opa-50 - :disabled colors/white-opa-40}} - :blur-bg {:icon-color colors/neutral-100 - :icon-secondary-color colors/neutral-80-opa-40 - :label-color colors/neutral-100 - :background-color {:default colors/neutral-80-opa-5 - :pressed colors/neutral-80-opa-10 - :disabled colors/neutral-80-opa-5}} - :blurred {:icon-color colors/neutral-100 - :icon-secondary-color colors/neutral-100 - :icon-background-color {:default colors/neutral-20 - :blurred colors/neutral-80-opa-10} - :label-color colors/neutral-100 - :background-color {:default colors/neutral-10 - :pressed colors/neutral-10 - :disabled colors/neutral-10-opa-10-blur} - :blur-overlay-color colors/neutral-10-opa-40-blur - :blur-type :light} - :blur-bg-outline {:icon-color colors/neutral-100 - :icon-secondary-color colors/neutral-80-opa-40 - :label-color colors/neutral-100 - :border-color {:default colors/neutral-80-opa-10 - :pressed colors/neutral-80-opa-20 - :disabled colors/neutral-80-opa-10}} - :shell {:icon-color colors/white - :label-color colors/white - :background-color {:default colors/neutral-95 - :pressed colors/neutral-95 - :disabled colors/neutral-95}}} - :dark - {:primary {:icon-color colors/white - :icon-secondary-color colors/white-opa-70 - :label-color colors/white - :background-color {:default (colors/custom-color customization-color 60) - :pressed (colors/custom-color customization-color 50) - :disabled (colors/custom-color customization-color 60)}} - :secondary {:icon-color colors/primary-50 - :label-color colors/primary-50 - :background-color {:default colors/primary-50-opa-20 - :pressed colors/primary-50-opa-30 - :disabled colors/primary-50-opa-20}} - :grey {:icon-color colors/white - :icon-secondary-color colors/neutral-40 - :label-color colors/white - :background-color {:default colors/neutral-90 - :pressed colors/neutral-60 - :disabled colors/neutral-90}} - :dark-grey {:icon-color colors/white - :icon-secondary-color colors/neutral-40 - :label-color colors/white - :background-color {:default colors/neutral-70 - :pressed colors/neutral-60 - :disabled colors/neutral-70}} - :outline {:icon-color colors/neutral-40 - :icon-secondary-color colors/neutral-40 - :label-color colors/white - :border-color {:default colors/neutral-70 - :pressed colors/neutral-60 - :disabled colors/neutral-70}} - :ghost {:icon-color colors/neutral-40 - :icon-secondary-color colors/neutral-40 - :label-color colors/white - :background-color {:pressed colors/neutral-80}} - :danger {:icon-color colors/white - :icon-secondary-color colors/white-opa-70 - :label-color colors/white - :background-color {:default colors/danger-60 - :pressed colors/danger-50 - :disabled colors/danger-60}} - :positive {:icon-color colors/white - :icon-secondary-color colors/white-opa-70 - :label-color colors/white - :background-color {:default colors/success-60 - :pressed colors/success-50 - :disabled colors/success-60-opa-30}} - :photo-bg {:icon-color colors/white - :icon-secondary-color colors/neutral-30 - :label-color colors/white - :background-color {:default colors/neutral-80-opa-40 - :pressed colors/neutral-80-opa-50 - :disabled colors/neutral-80-opa-40}} - :blur-bg {:icon-color colors/white - :icon-secondary-color colors/white-opa-70 - :label-color colors/white - :background-color {:default colors/white-opa-5 - :pressed colors/white-opa-10 - :disabled colors/white-opa-5}} - :blurred {:icon-color colors/white - :icon-secondary-color colors/white - :icon-background-color {:default colors/neutral-80 - :blurred colors/white-opa-10} - :label-color colors/white - :background-color {:default colors/neutral-90 - :pressed colors/neutral-90 - :disabled colors/neutral-90-opa-10-blur} - :blur-overlay-color colors/neutral-80-opa-40 - :blur-type :dark} - :blur-bg-outline {:icon-color colors/white - :icon-secondary-color colors/white-opa-40 - :label-color colors/white - :border-color {:default colors/white-opa-10 - :pressed colors/white-opa-20 - :disabled colors/white-opa-5}} - :shell {:icon-color colors/white - :label-color colors/white - :background-color {:default colors/neutral-95}}}}) - -(defn shape-style-container - [type icon size] - {:height size - :border-radius (if (and icon (#{:primary :secondary :danger} type)) - 24 - (case size - 56 12 - 40 12 - 32 10 - 24 8))}) - -(defn style-container - [{:keys [type size disabled background-color border-color icon above width before after blur-active?]}] - (merge {:height size - :align-items :center - :justify-content :center - :flex-direction (if above :column :row) - :padding-horizontal (when-not (or icon before after) - (case size - 56 16 - 40 16 - 32 12 - 24 8)) - :padding-left (when-not (or icon before) - (case size - 56 16 - 40 16 - 32 12 - 24 8)) - :padding-right (when-not (or icon after) - (case size - 56 16 - 40 16 - 32 12 - 24 8)) - :padding-top (when-not (or icon before after) - (case size - 56 0 - 40 9 - 32 5 - 24 3)) - :padding-bottom (when-not (or icon before after) - (case size - 56 0 - 40 9 - 32 5 - 24 4)) - :overflow :hidden} - (when (or (and (= type :blurred) (not blur-active?)) - (not= type :blurred)) - {:background-color background-color}) - (shape-style-container type icon size) - (when width - {:width width}) - (when icon - {:width size}) - (when border-color - {:border-color border-color - :border-width 1}) - (when disabled - {:opacity 0.3}))) diff --git a/src/quo2/components/dropdowns/old_button_view.cljs b/src/quo2/components/dropdowns/old_button_view.cljs deleted file mode 100644 index a1d80970db..0000000000 --- a/src/quo2/components/dropdowns/old_button_view.cljs +++ /dev/null @@ -1,138 +0,0 @@ -(ns quo2.components.dropdowns.old-button-view - (:require [quo2.components.icon :as quo2.icons] - [quo2.components.markdown.text :as text] - [quo2.theme :as theme] - [react-native.core :as rn] - [react-native.blur :as blur] - [reagent.core :as reagent] - [quo2.components.dropdowns.old-button-style :as style])) - -(defn- button-internal - "with label - [button opts \"label\"] - opts - {:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/ - :danger/:photo-bg/:blur-bg/:blur-bg-outline/:shell/:community - :size 40 [default] /32/24 - :icon true/false - :community-color '#FFFFFF' - :community-text-color '#000000' - :before :icon-keyword - :after :icon-keyword} - - only icon - [button {:icon true} :i/close-circle]" - [_ _] - (let [pressed-in (reagent/atom false)] - (fn - [{:keys [on-press disabled type size before after above icon-secondary-no-color - width customization-color theme override-background-color pressed - on-long-press accessibility-label icon icon-no-color style inner-style test-ID - blur-active? override-before-margins override-after-margins icon-size icon-container-size - icon-container-rounded?] - :or {type :primary - size 40 - customization-color :primary - blur-active? true}} - children] - (let [{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type - blur-overlay-color icon-background-color]} - (get-in (style/themes customization-color) - [theme type]) - state (cond disabled :disabled - (or @pressed-in pressed) :pressed - :else :default) - blur-state (if blur-active? :blurred :default) - icon-size (or icon-size (when (= 24 size) 12)) - icon-secondary-color (or icon-secondary-color icon-color)] - [rn/touchable-without-feedback - (merge {:test-ID test-ID - :disabled disabled - :accessibility-label accessibility-label - :on-press-in #(reset! pressed-in true) - :on-press-out #(reset! pressed-in nil)} - (when on-press - {:on-press on-press}) - (when on-long-press - {:on-long-press on-long-press})) - [rn/view - {:style (merge - (style/shape-style-container type icon size) - {:width width} - style)} - [rn/view - {:style (merge - (style/style-container {:type type - :size size - :disabled disabled - :background-color - (or override-background-color (get background-color state)) - :border-color - (get border-color state) - :icon icon - :above above - :width width - :before before - :after after - :blur-active? blur-active?}) - (when (= state :pressed) {:opacity 0.9}) - inner-style)} - (when (and (= type :blurred) - blur-active?) - [blur/view - {:blur-radius 20 - :blur-type blur-type - :overlay-color blur-overlay-color - :style style/blur-view}]) - (when above - [rn/view - [quo2.icons/icon above - {:container-style {:margin-bottom 2} - :color icon-secondary-color - :size icon-size}]]) - (when before - [rn/view - {:style (style/before-icon-style - {:override-margins override-before-margins - :size size - :icon-container-size icon-container-size - :icon-background-color (get icon-background-color blur-state) - :icon-container-rounded? icon-container-rounded? - :icon-size icon-size})} - [quo2.icons/icon before - {:color icon-secondary-color - :size icon-size}]]) - [rn/view - (cond - (or icon icon-no-color) - [quo2.icons/icon children - {:color icon-color - :no-color icon-no-color - :size icon-size}] - - (string? children) - [text/text - {:size (when (#{56 24} size) :paragraph-2) - :weight :medium - :number-of-lines 1 - :style {:color label-color}} - - children] - - (vector? children) - children)] - (when after - [rn/view - {:style (style/after-icon-style - {:override-margins override-after-margins - :size size - :icon-container-size icon-container-size - :icon-background-color (get icon-background-color blur-state) - :icon-container-rounded? icon-container-rounded? - :icon-size icon-size})} - [quo2.icons/icon after - {:no-color icon-secondary-no-color - :color icon-secondary-color - :size icon-size}]])]]])))) - -(def button (theme/with-theme button-internal)) diff --git a/src/quo2/components/icons/svg.cljs b/src/quo2/components/icons/svg.cljs index 24f0115acc..b62e1c4cc7 100644 --- a/src/quo2/components/icons/svg.cljs +++ b/src/quo2/components/icons/svg.cljs @@ -21,21 +21,92 @@ children)) (defn- clear-20 - [{:keys [color color-2] :as props}] - (let [color (or color colors/neutral-100) - color-2 (or color-2 colors/white)] - [container props - [svg/path - {:d - "M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z" - :fill color}] - [svg/path - {:d - "M9.15142 9.99998L7.07566 12.0757L7.9242 12.9243L9.99994 10.8485L12.0757 12.9242L12.9242 12.0757L10.8485 9.99998L12.9242 7.92421L12.0757 7.07568L9.99994 9.15145L7.92421 7.07572L7.07568 7.92425L9.15142 9.99998Z" - :fill color-2}]])) + [{:keys [color color-2] + :or {color colors/neutral-100 + color-2 colors/white} + :as props}] + [container props + [svg/path + {:d + "M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z" + :fill color}] + [svg/path + {:d + "M9.15142 9.99998L7.07566 12.0757L7.9242 12.9243L9.99994 10.8485L12.0757 12.9242L12.9242 12.0757L10.8485 9.99998L12.9242 7.92421L12.0757 7.07568L9.99994 9.15145L7.92421 7.07572L7.07568 7.92425L9.15142 9.99998Z" + :fill color-2}]]) + +(defn- dropdown-20 + [{:keys [color color-2] + :or {color colors/neutral-100 + color-2 colors/white} + :as props}] + [container props + [svg/path + {:d + "M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z" + :fill color}] + [svg/path + {:d + "M7 8.5L10 11.5L13 8.5" + :stroke color-2 + :stroke-width 1.2}]]) + +(defn- pullup-20 + [{:keys [color color-2] + :or {color colors/neutral-100 + color-2 colors/white} + :as props}] + [container props + [svg/path + {:d + "M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z" + :fill color}] + [svg/path + {:d + "M7 11.5L10 8.5L13 11.5" + :stroke color-2 + :stroke-width 1.2}]]) + +(defn- dropdown-12 + [{:keys [color color-2] + :or {color colors/neutral-100 + color-2 colors/white} + :as props}] + [container props + [svg/circle + {:cx 6 + :cy 6 + :r 6 + :fill color}] + [svg/path + {:d + "M3.5 5L6 7.5L8.5 5" + :stroke color-2 + :stroke-width 1.1}]]) + +(defn- pullup-12 + [{:keys [color color-2] + :or {color colors/neutral-100 + color-2 colors/white} + :as props}] + [container props + [svg/circle + {:cx 6 + :cy 6 + :r 6 + :fill color}] + [svg/path + {:d + "M3.5 7L6 4.5L8.5 7" + :stroke color-2 + :stroke-width 1.1}]]) (def ^:private icons - {:i/clear-20 clear-20}) + {:i/clear-20 clear-20 + :i/dropdown-20 dropdown-20 + :i/pullup-20 pullup-20 + :i/dropdown-12 dropdown-12 + :i/pullup-12 pullup-12}) (defn- append-to-keyword [k & xs] diff --git a/src/quo2/components/navigation/page_nav/style.cljs b/src/quo2/components/navigation/page_nav/style.cljs index b0258c3014..c33a601865 100644 --- a/src/quo2/components/navigation/page_nav/style.cljs +++ b/src/quo2/components/navigation/page_nav/style.cljs @@ -19,12 +19,6 @@ :align-items :center :justify-content (if centered? :center :flex-start)}) -(def account-switcher-placeholder - {:width 32 - :height 32 - :border-radius 10 - :background-color (colors/custom-color :purple 50)}) - (def right-actions-container {:flex-direction :row}) diff --git a/src/quo2/components/navigation/page_nav/view.cljs b/src/quo2/components/navigation/page_nav/view.cljs index 6ac15f71f3..a352d1ed75 100644 --- a/src/quo2/components/navigation/page_nav/view.cljs +++ b/src/quo2/components/navigation/page_nav/view.cljs @@ -1,7 +1,9 @@ (ns quo2.components.navigation.page-nav.view (:require [quo2.components.avatars.group-avatar.view :as group-avatar] [quo2.components.buttons.button.view :as button] - [quo2.components.dropdowns.dropdown :as dropdown] + [quo2.components.buttons.button.properties :as button-properties] + [quo2.components.dropdowns.dropdown.view :as dropdown] + [quo2.components.dropdowns.dropdown.properties :as dropdown-properties] [quo2.components.icon :as icons] [quo2.components.markdown.text :as text] [quo2.components.navigation.page-nav.style :as style] @@ -28,6 +30,7 @@ :icon-only? true :size 32 :on-press on-press + :background (when (button-properties/backgrounds background) background) :accessibility-label accessibility-label} icon-name])] children)) @@ -45,20 +48,28 @@ :icon-only? icon-name :size 32 :accessible true - :background (when (#{:photo :blur} background) background)) + :background (when (button-properties/backgrounds background) background)) (or label icon-name)])) (interpose [right-section-spacing]))) +(defn- account-switcher-content + [{:keys [customization-color on-press emoji state]}] + [dropdown/view + {:type :customization + :customization-color customization-color + :state (or state :default) + :size :size-32 + :on-press on-press + :emoji? true} + emoji]) + (defn- right-content - [{:keys [background content max-actions min-size? support-account-switcher?] + [{:keys [background content max-actions min-size? support-account-switcher? account-switcher] :or {support-account-switcher? true}}] [rn/view (when min-size? {:style style/right-content-min-size}) (cond - ;; TODO: use account-switcher when available (issue #16456) (and support-account-switcher? (= content :account-switcher)) - [rn/pressable - {:style style/account-switcher-placeholder - :on-press #(js/alert "Not implemented yet")}] + [account-switcher-content account-switcher] (coll? content) (into [rn/view {:style style/right-actions-container}] @@ -78,17 +89,19 @@ title]]) (defn- dropdown-center - [{:keys [theme background dropdown-on-change dropdown-selected? dropdown-text]}] - (let [dropdown-type (cond - (= background :photo) :grey - (and (= theme :dark) (= background :blur)) :grey - :else :ghost)] + [{:keys [theme background dropdown-on-press dropdown-selected? dropdown-text]}] + (let [dropdown-type (cond + (= background :photo) :grey + (and (= theme :dark) (= background :blur)) :grey + :else :ghost) + dropdown-state (if dropdown-selected? :active :default)] [rn/view {:style (style/center-content-container true)} - [dropdown/dropdown - {:type dropdown-type - :size 32 - :on-change dropdown-on-change - :selected dropdown-selected?} + [dropdown/view + {:type dropdown-type + :state dropdown-state + :size :size-32 + :background (when (dropdown-properties/backgrounds background) background) + :on-press dropdown-on-press} dropdown-text]])) (defn- token-center @@ -157,7 +170,7 @@ shown-name]])) (defn- view-internal - [{:keys [type right-side background text-align] + [{:keys [type right-side background text-align account-switcher] :or {type :no-title text-align :center right-side :none @@ -173,28 +186,29 @@ [page-nav-base props [title-center (assoc props :centered? centered?)] [right-content - {:background background - :content right-side - :max-actions (if centered? 1 3) - :min-size? centered?}]]) + {:background background + :content right-side + :max-actions (if centered? 1 3) + :min-size? centered? + :account-switcher account-switcher}]]) :dropdown [page-nav-base props [dropdown-center props] - [rn/view {:style style/right-actions-container} - (let [{button-icon :icon-name :as button-props} (first right-side)] - [button/button - (assoc button-props - :type (button-type background) - :icon-only? true - :size 32 - :accessible true) - button-icon])]] + [right-content + {:background background + :content right-side + :max-actions 1 + :support-account-switcher? false}]] :token [page-nav-base props [token-center props] - [right-content {:background background :content right-side :max-actions 3}]] + [right-content + {:background background + :content right-side + :max-actions 3 + :account-switcher account-switcher}]] :channel [page-nav-base props @@ -224,10 +238,11 @@ :number-of-lines 1} "NETWORK DROPDOWN"]] [right-content - {:background background - :content right-side - :max-actions 1 - :min-size? true}]] + {:background background + :content right-side + :max-actions 1 + :min-size? true + :account-switcher account-switcher}]] (:community :network) [page-nav-base props @@ -255,12 +270,19 @@ :on-press (fn callback [] nil) :accessibility-label \"an optional label\"} + - account-switcher (optional) + - props to render dropdown component (emoji only) e.g.: + {:customization-color :purple + :on-press (fn [] nil) + :state :default (inherit dropdown states) + :emoji \"🍑\"} + Depending on the `type` selected, different properties are accepted: `:title` - title - text-align: `:center` or `:left` `:dropdown` - - dropdown-on-change: a callback + - dropdown-on-press: a callback - dropdown-selected?: a boolean - dropdown-text `:token` diff --git a/src/quo2/core.cljs b/src/quo2/core.cljs index f6707fdb38..04dad86c96 100644 --- a/src/quo2/core.cljs +++ b/src/quo2/core.cljs @@ -44,7 +44,7 @@ quo2.components.drawers.drawer-buttons.view quo2.components.drawers.drawer-top.view quo2.components.drawers.permission-context.view - quo2.components.dropdowns.dropdown + quo2.components.dropdowns.dropdown.view quo2.components.dropdowns.network-dropdown.view quo2.components.empty-state.empty-state.view quo2.components.gradient.gradient-cover.view @@ -214,7 +214,7 @@ (def permission-context quo2.components.drawers.permission-context.view/view) ;;;; Dropdowns -(def dropdown quo2.components.dropdowns.dropdown/dropdown) +(def dropdown quo2.components.dropdowns.dropdown.view/view) (def network-dropdown quo2.components.dropdowns.network-dropdown.view/view) ;;;; Empty State diff --git a/src/quo2/core_spec.cljs b/src/quo2/core_spec.cljs index 9c32cbb147..99eb8fd83b 100644 --- a/src/quo2/core_spec.cljs +++ b/src/quo2/core_spec.cljs @@ -24,6 +24,7 @@ [quo2.components.drawers.drawer-buttons.component-spec] [quo2.components.drawers.drawer-top.component-spec] [quo2.components.drawers.permission-context.component-spec] + [quo2.components.dropdowns.dropdown.component-spec] [quo2.components.dropdowns.network-dropdown.component-spec] [quo2.components.gradient.gradient-cover.component-spec] [quo2.components.graph.wallet-graph.component-spec] diff --git a/src/quo2/foundations/colors.cljs b/src/quo2/foundations/colors.cljs index 123dbf3125..f8dbaf1133 100644 --- a/src/quo2/foundations/colors.cljs +++ b/src/quo2/foundations/colors.cljs @@ -68,7 +68,7 @@ (def neutral-80-opa-20 (alpha neutral-80 0.2)) (def neutral-80-opa-30 (alpha neutral-80 0.3)) (def neutral-80-opa-40 (alpha neutral-80 0.4)) -(def neutral-80-opa-50 (alpha neutral-80 0.4)) +(def neutral-80-opa-50 (alpha neutral-80 0.5)) (def neutral-80-opa-60 (alpha neutral-80 0.6)) (def neutral-80-opa-70 (alpha neutral-80 0.7)) (def neutral-80-opa-80 (alpha neutral-80 0.8)) diff --git a/src/status_im2/contexts/chat/photo_selector/view.cljs b/src/status_im2/contexts/chat/photo_selector/view.cljs index 9f079d9c1c..12a761c0d5 100644 --- a/src/status_im2/contexts/chat/photo_selector/view.cljs +++ b/src/status_im2/contexts/chat/photo_selector/view.cljs @@ -100,14 +100,26 @@ window-width (:width (rn/get-window))] [:f> (fn [] - (let [camera-roll-photos (rf/sub [:camera-roll/photos]) - end-cursor (rf/sub [:camera-roll/end-cursor]) - loading? (rf/sub [:camera-roll/loading-more]) - has-next-page? (rf/sub [:camera-roll/has-next-page]) - selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent)) - blur-active? (> @current-scroll min-scroll-to-blur) - window-height (:height (rn/get-window)) - top (reanimated/use-shared-value window-height)] + (let [camera-roll-photos (rf/sub [:camera-roll/photos]) + end-cursor (rf/sub [:camera-roll/end-cursor]) + loading? (rf/sub [:camera-roll/loading-more]) + has-next-page? (rf/sub [:camera-roll/has-next-page]) + selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent)) + blur-active? (> @current-scroll min-scroll-to-blur) + window-height (:height (rn/get-window)) + top (reanimated/use-shared-value window-height) + show-blur? (and (not @album?) blur-active?) + dropdown-type (if show-blur? :grey :ghost) + dropdown-state (if @album? :active :default) + dropdown-background (when show-blur? :photo) + dropdown-on-press (fn [] + (if-not @album? + (do + (reset! album? true) + (reanimated/animate top 0)) + (do + (reanimated/animate top window-height) + (js/setTimeout #(reset! album? false) 300))))] [rn/view {:style {:flex 1 :margin-top -20}} (when @album? [album-selector/album-selector sheet album? selected-album top]) @@ -131,18 +143,10 @@ [confirm-button @selected-images sending-image close]] [rn/view {:style style/buttons-container} [quo/dropdown - {:type :blurred - :size 32 - :on-change (fn [] - (if-not @album? - (do - (reset! album? true) - (reanimated/animate top 0)) - (do - (reanimated/animate top window-height) - (js/setTimeout #(reset! album? false) 300)))) - :selected @album? - :blur-active? (and (not @album?) blur-active?) - :override-background-color (when-not @album? :transparent)} + {:type dropdown-type + :size :size-32 + :state dropdown-state + :on-press dropdown-on-press + :background dropdown-background} selected-album] [clear-button @album? selected-images blur-active?]]]))])) diff --git a/src/status_im2/contexts/quo_preview/dropdowns/dropdown.cljs b/src/status_im2/contexts/quo_preview/dropdowns/dropdown.cljs index d2a8e603fd..b804274e61 100644 --- a/src/status_im2/contexts/quo_preview/dropdowns/dropdown.cljs +++ b/src/status_im2/contexts/quo_preview/dropdowns/dropdown.cljs @@ -1,57 +1,82 @@ (ns status-im2.contexts.quo-preview.dropdowns.dropdown (:require [quo2.core :as quo] + [react-native.core :as rn] [reagent.core :as reagent] + [status-im2.common.resources :as resources] [status-im2.contexts.quo-preview.preview :as preview])) (def descriptor [{:key :type :type :select - :options [{:key :primary} - {:key :secondary} + :options [{:key :outline} {:key :grey} - {:key :dark-grey} - {:key :outline} {:key :ghost} - {:key :danger} - {:key :positive}]} + {:key :customization}]} + {:key :state + :type :select + :options [{:key :default} + {:key :active} + {:key :disabled}]} {:key :size :type :select - :options [{:key 56 - :value "56"} - {:key 40 + :options [{:key :size-40 :value "40"} - {:key 32 + {:key :size-32 :value "32"} - {:key 24 + {:key :size-24 :value "24"}]} - {:key :icon + {:key :background + :type :select + :options [{:key :photo} + {:key :blur}]} + {:key :icon? :type :boolean} - {:label "Before icon:" - :key :before - :type :boolean} - {:key :disabled + {:key :icon-name + :type :select + :options [{:key :i/wallet} + {:key :i/group} + {:key :i/locked}]} + {:key :emoji? :type :boolean} {:key :label - :type :text}]) + :type :text} + (preview/customization-color-option)]) (defn view [] - (let [state (reagent/atom {:label "Press Me" - :size 40}) - label (reagent/cursor state [:label]) - before (reagent/cursor state [:before]) - icon (reagent/cursor state [:icon])] - (fn [] - [preview/preview-container - {:state state - :descriptor descriptor - :component-container-style {:align-items :center}} - [quo/dropdown - (merge (dissoc @state - :theme - :before - :after) - {:on-press #(println "Hello world!")} - (when @before - {:before :i/placeholder})) - (if @icon :i/placeholder @label)]]))) + (let [state (reagent/atom {:type :outline + :state :default + :size :size-40 + :label "Dropdown" + :icon? false + :emoji? false + :customization-color :purple}) + label (reagent/cursor state [:label]) + emoji? (reagent/cursor state [:emoji?]) + background (reagent/cursor state [:background])] + [:f> + (fn [] + (rn/use-effect (fn [] + (swap! state assoc :label (if @emoji? "🍑" "Dropdown"))) + [@emoji?]) + [preview/preview-container + {:state state + :descriptor descriptor + :component-container-style (when-not (= @background :blur) {:align-items :center}) + :blur-container-style {:align-items :center} + :blur? (= @background :blur) + :show-blur-background? true} + (when (= :photo (:background @state)) + [rn/image + {:source (resources/get-mock-image :dark-blur-bg) + :style {:position :absolute + :top 12 + :left 20 + :right 0 + :bottom 0 + :border-radius 12} + :height 250 + :width "100%"}]) + [quo/dropdown + (assoc @state :on-press #(js/alert "Pressed dropdown")) + @label]])])) diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index 98999471c9..6d18d3d2ec 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -431,14 +431,14 @@ (defn- category-view [] - (let [open? (reagent/atom false) - on-change #(swap! open? not)] + (let [open? (reagent/atom false) + on-press #(swap! open? not)] (fn [category] [rn/view {:style {:margin-vertical 8}} [quo/dropdown - {:selected @open? - :on-change on-change - :type :grey} + {:type :grey + :state (if @open? :active :default) + :on-press on-press} (name (key category))] (when @open? (for [{category-name :name} (val category)] diff --git a/src/status_im2/contexts/quo_preview/navigation/page_nav.cljs b/src/status_im2/contexts/quo_preview/navigation/page_nav.cljs index ca59feacd0..392ec13d83 100644 --- a/src/status_im2/contexts/quo_preview/navigation/page_nav.cljs +++ b/src/status_im2/contexts/quo_preview/navigation/page_nav.cljs @@ -173,7 +173,7 @@ {:icon-name :i/mention :on-press #(js/alert "A MENTION!")}] :title "Page title" :text-align :center - :dropdown-on-change #(js/alert "Dropdown pressed!") + :dropdown-on-press #(js/alert "Dropdown pressed!") :dropdown-selected? false :dropdown-text "Recent" :token-logo (resources/get-mock-image :status-logo) @@ -187,7 +187,10 @@ :community-name "Rarible" :community-logo (resources/get-mock-image :coinbase) :network-name "Mainnet" - :network-logo (resources/get-mock-image :diamond)})] + :network-logo (resources/get-mock-image :diamond) + :account-switcher {:customization-color :purple + :on-press #(js/alert "Pressed Account Switcher") + :emoji "🍑"}})] (fn [] [preview/preview-container {:state state