diff --git a/src/quo/components/dropdowns/dropdown_input/component_spec.cljs b/src/quo/components/dropdowns/dropdown_input/component_spec.cljs new file mode 100644 index 0000000000..d0d96ceb7c --- /dev/null +++ b/src/quo/components/dropdowns/dropdown_input/component_spec.cljs @@ -0,0 +1,56 @@ +(ns quo.components.dropdowns.dropdown-input.component-spec + (:require + [quo.components.dropdowns.dropdown-input.view :as dropdown-input] + [test-helpers.component :as h])) + +(h/describe "Dropdown Input" + + (h/test "default render" + (let [header-label "Label" + label "Dropdown"] + (h/render [dropdown-input/view + {:label? true + :header-label + header-label} label]) + (h/is-truthy (h/get-by-label-text :dropdown)) + (h/is-truthy (h/get-by-text header-label)) + (h/is-truthy (h/get-by-text label)))) + + (h/test "render with icon" + (let [label "Dropdown"] + (h/render [dropdown-input/view + {:icon? true + :icon-name + :i/wallet + :label? 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/test "render in active state" + (let [label "Dropdown"] + (h/render [dropdown-input/view + {:state :active + :label? + true} label]) + (h/is-truthy (h/get-by-label-text :dropdown)) + (h/is-truthy (h/get-by-label-text :right-icon "Expecting active state icon")))) + + (h/test "render in disabled state" + (let [label "Dropdown"] + (h/render [dropdown-input/view + {:state :disabled + :label? true} label]) + (h/is-truthy (h/get-by-label-text :dropdown)) + (h/is-disabled (h/get-by-text label "Dropdown should be disabled in disabled state")))) + + (h/test "on-press" + (let [event (h/mock-fn) + label "Dropdown"] + (h/render [dropdown-input/view + {:on-press event + :label? + true} label]) + (h/fire-event :press (h/get-by-text label)) + (h/was-called event)))) diff --git a/src/quo/components/dropdowns/dropdown_input/properties.cljs b/src/quo/components/dropdowns/dropdown_input/properties.cljs new file mode 100644 index 0000000000..33153bdb49 --- /dev/null +++ b/src/quo/components/dropdowns/dropdown_input/properties.cljs @@ -0,0 +1,49 @@ +(ns quo.components.dropdowns.dropdown-input.properties + (:require + [quo.foundations.colors :as colors])) + +(def icon-size 20) + +(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) + :border-color (if active? + (colors/theme-colors colors/neutral-80-opa-20 + colors/white-opa-40 + 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) + :border-color (if active? + (colors/theme-colors colors/neutral-40 colors/neutral-60 theme) + (colors/theme-colors colors/neutral-20 + colors/neutral-60 + theme))}) + +(defn get-colors + [{:keys [theme state blur?]}] + (let [active? (= state :active)] + (cond + blur? (grey-blur theme active?) + (= theme :dark) (outline theme active?) + (= theme :light) (grey theme active?)))) diff --git a/src/quo/components/dropdowns/dropdown_input/style.cljs b/src/quo/components/dropdowns/dropdown_input/style.cljs new file mode 100644 index 0000000000..14fe9132d0 --- /dev/null +++ b/src/quo/components/dropdowns/dropdown_input/style.cljs @@ -0,0 +1,62 @@ +(ns quo.components.dropdowns.dropdown-input.style + (:require + [quo.foundations.colors :as colors])) + +(def gap 8) + +(def blur-view + {:position :absolute + :top 0 + :left 0 + :right 0 + :bottom 0}) + +(def left-icon + {:margin-right gap}) + +(defn right-icon + [theme] + {:color (colors/theme-colors colors/neutral-100 colors/white theme) + :margin-right gap}) + +(defn header-label + [theme blur?] + {:color (if blur? + (colors/theme-colors colors/neutral-80-opa-40 + colors/white-opa-70 + theme) + (colors/theme-colors colors/neutral-50 + colors/neutral-40 + theme)) + :margin-bottom gap}) + +(def root-container + {:width "100%" + :height 40}) + +(defn container + [{:keys [background-color border-color]} + {:keys [icon? state]}] + (cond-> {:align-items :center + :justify-content :space-between + :flex-direction :row + :padding-vertical 9 + :padding-left 16 + :padding-right 12 + :overflow :hidden + :background-color background-color + :border-radius 12} + + icon? + (assoc :padding-left 12) + + border-color + (assoc :border-color border-color + :border-width 1) + + (= state :disabled) + (assoc :opacity 0.3))) + +(def right-half-container + {:flex-direction :row + :align-items :center}) diff --git a/src/quo/components/dropdowns/dropdown_input/view.cljs b/src/quo/components/dropdowns/dropdown_input/view.cljs new file mode 100644 index 0000000000..bdf74d6f9d --- /dev/null +++ b/src/quo/components/dropdowns/dropdown_input/view.cljs @@ -0,0 +1,68 @@ +(ns quo.components.dropdowns.dropdown-input.view + (:require + [quo.components.dropdowns.dropdown-input.properties :as properties] + [quo.components.dropdowns.dropdown-input.style :as style] + [quo.components.icon :as icon] + [quo.components.markdown.text :as text] + [quo.theme :as theme] + [react-native.core :as rn])) + +(defn- view-internal + [{:keys [state theme on-press icon? + label? blur? + accessibility-label header-label] + :or {state :default + icon? true + label? true + blur? false + header-label "Label"} + :as props} + label] + (let [{:keys [left-icon-color right-icon-color right-icon-color-2] + :as colors} (properties/get-colors props) + right-icon (if (= state :active) :i/pullup :i/dropdown)] + [rn/view + {:style style/root-container} + (when label? + [text/text + {:size :paragraph-2 + :weight :medium + :align :left + :style (style/header-label theme blur?)} header-label]) + [rn/pressable + {:accessibility-label (or accessibility-label :dropdown) + :disabled (= state :disabled) + :on-press on-press + :style (style/container colors props)} + [rn/view + {:style style/right-half-container} + (when icon? + [icon/icon + :i/placeholder + {:accessibility-label :left-icon + :color left-icon-color + :size properties/icon-size + :container-style style/left-icon}]) + [text/text + {:size :paragraph-1 + :weight :regular + :number-of-lines 1 + :style (style/right-icon theme)} + label]] + [icon/icon + right-icon + {:size properties/icon-size + :accessibility-label :right-icon + :color right-icon-color + :color-2 right-icon-color-2}]]])) + +(def view + "Props: + - state: :default (default) | :active | :disabled + - label: string + - header-label: string + - icon?: boolean + - label?: boolean + - blur?: boolean + - on-press: function" + (theme/with-theme view-internal)) diff --git a/src/quo/core.cljs b/src/quo/core.cljs index 79a6f094e5..04b0610807 100644 --- a/src/quo/core.cljs +++ b/src/quo/core.cljs @@ -48,6 +48,7 @@ quo.components.drawers.drawer-buttons.view quo.components.drawers.drawer-top.view quo.components.drawers.permission-context.view + quo.components.dropdowns.dropdown-input.view quo.components.dropdowns.dropdown.view quo.components.dropdowns.network-dropdown.view quo.components.empty-state.empty-state.view @@ -232,6 +233,7 @@ ;;;; Dropdowns (def dropdown quo.components.dropdowns.dropdown.view/view) +(def dropdown-input quo.components.dropdowns.dropdown-input.view/view) (def network-dropdown quo.components.dropdowns.network-dropdown.view/view) ;;;; Empty State diff --git a/src/quo/core_spec.cljs b/src/quo/core_spec.cljs index a96fe3cc6a..d642ebfc3c 100644 --- a/src/quo/core_spec.cljs +++ b/src/quo/core_spec.cljs @@ -26,6 +26,7 @@ [quo.components.drawers.drawer-buttons.component-spec] [quo.components.drawers.drawer-top.component-spec] [quo.components.drawers.permission-context.component-spec] + [quo.components.dropdowns.dropdown-input.component-spec] [quo.components.dropdowns.dropdown.component-spec] [quo.components.dropdowns.network-dropdown.component-spec] [quo.components.gradient.gradient-cover.component-spec] diff --git a/src/status_im2/contexts/quo_preview/dropdowns/dropdown_input.cljs b/src/status_im2/contexts/quo_preview/dropdowns/dropdown_input.cljs new file mode 100644 index 0000000000..ddbf374e9e --- /dev/null +++ b/src/status_im2/contexts/quo_preview/dropdowns/dropdown_input.cljs @@ -0,0 +1,47 @@ +(ns status-im2.contexts.quo-preview.dropdowns.dropdown-input + (:require + [quo.core :as quo] + [reagent.core :as reagent] + [status-im2.contexts.quo-preview.preview :as preview])) + +(def descriptor + [{:key :state + :type :select + :options [{:key :default} + {:key :active} + {:key :disabled}]} + {:key :icon? + :type :boolean} + {:key :label? + :type :boolean} + {:key :blur? + :type :boolean} + {:key :header-label + :type :text} + {:key :label + :type :text}]) + +(defn view + [] + (let [state (reagent/atom {:state :default + :label "Dropdown" + :header-label "Label" + :icon? true + :label? true + :blur? false}) + label (reagent/cursor state [:label]) + blur? (reagent/cursor state [:blur?])] + [:f> + (fn [] + [preview/preview-container + {:state state + :descriptor descriptor + :component-container-style (when-not @blur? + {:align-items :center + :margin-horizontal 30}) + :blur-container-style {:align-items :center} + :blur? @blur? + :show-blur-background? true} + [quo/dropdown-input + (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 471ce863c7..9323f2e6d3 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -58,6 +58,8 @@ [status-im2.contexts.quo-preview.drawers.permission-drawers :as permission-drawers] [status-im2.contexts.quo-preview.dropdowns.dropdown :as dropdown] + [status-im2.contexts.quo-preview.dropdowns.dropdown-input :as + dropdown-input] [status-im2.contexts.quo-preview.dropdowns.network-dropdown :as network-dropdown] [status-im2.contexts.quo-preview.empty-state.empty-state :as empty-state] @@ -275,7 +277,9 @@ :dropdowns [{:name :dropdown :component dropdown/view} {:name :network-dropdown - :component network-dropdown/view}] + :component network-dropdown/view} + {:name :dropdown-input + :component dropdown-input/view}] :empty-state [{:name :empty-state :component empty-state/view}] :gradient [{:name :gradient-cover