diff --git a/src/status_im/components/styles.cljs b/src/status_im/components/styles.cljs index 15e7ac1697..e3216be35a 100644 --- a/src/status_im/components/styles.cljs +++ b/src/status_im/components/styles.cljs @@ -23,7 +23,9 @@ (def color-dark-blue-2 "#1f253f") (def color-dark-blue-3 "#191f37") (def color-light-gray "#EEF2F5") +(def color-light-gray2 "#ececf0") (def color-red "red") +(def color-red2 "#d84b4b") (def color-light-red "#e86363") (def color-light-red2 "#f47979") diff --git a/src/status_im/components/text_input_with_label/animation.cljs b/src/status_im/components/text_input_with_label/animation.cljs new file mode 100644 index 0000000000..d8eb17ba98 --- /dev/null +++ b/src/status_im/components/text_input_with_label/animation.cljs @@ -0,0 +1,32 @@ +(ns status-im.components.text-input-with-label.animation + (:require [status-im.components.animation :as animation] + [clojure.string :as str])) + +(def anim-duration 200) + +(defn animate-underline [underline-width to-line-width underline-height to-line-height] + (let [anim (animation/parallel [(animation/timing underline-width {:toValue to-line-width + :duration anim-duration}) + (animation/timing underline-height {:toValue to-line-height + :duration anim-duration})])] + (animation/start anim))) + +(defn text-input-on-focus [{:keys [underline-width underline-max-width* underline-height underline-max-height]}] + (animate-underline underline-width @underline-max-width* underline-height underline-max-height)) + +(defn text-input-on-blur [{:keys [underline-width underline-height]}] + (animate-underline underline-width 0 underline-height 1)) + +(defn animate-label [text {:keys [value* label-top label-font-size + label-top-top label-top-bottom label-font-size-top label-font-size-bottom]}] + (when (or (str/blank? text) (str/blank? @value*)) + (let [was-blank? (str/blank? @value*) + anim (animation/parallel [(animation/timing label-top {:toValue (if was-blank? + label-top-top + label-top-bottom) + :duration anim-duration}) + (animation/timing label-font-size {:toValue (if was-blank? + label-font-size-top + label-font-size-bottom) + :duration anim-duration})])] + (animation/start anim)))) \ No newline at end of file diff --git a/src/status_im/components/text_input_with_label/styles.cljs b/src/status_im/components/text_input_with_label/styles.cljs new file mode 100644 index 0000000000..cffa1805d0 --- /dev/null +++ b/src/status_im/components/text_input_with_label/styles.cljs @@ -0,0 +1,70 @@ +(ns status-im.components.text-input-with-label.styles + (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]]) + (:require [status-im.utils.platform :refer [ios?]] + [status-im.components.styles :as common])) + +(defstyle text-input + {:placeholder "" + :android {:height 24 + :padding-top 0 + :padding-bottom 0 + :padding-left 0 + :margin-top 26 + :margin-bottom 4 + :font-size 16} + :ios {:height 26 + :margin-top 24 + :margin-bottom 6 + :font-size 17 + :letter-spacing -0.2}}) + +(defstyle component-container + {:padding-left 16 + :android {:min-height 76} + :ios {:min-height 78}}) + +(defnstyle label-animated-text [{:keys [label-top label-font-size]}] + {:position :absolute + :top label-top + :font-size label-font-size + :color common/color-gray4 + :ios {:letter-spacing -0.2}}) + +(defstyle description-text + {:color common/color-gray4 + :android {:margin-top 6 + :height 14 + :font-size 12} + :ios {:margin-top 4 + :height 16 + :font-size 14 + :letter-spacing -0.2}}) + +(defstyle error-text + {:color common/color-red2 + :android {:margin-top 6 + :height 14 + :font-size 12} + :ios {:margin-top 4 + :height 16 + :font-size 14 + :letter-spacing -0.2}}) + +(defn underline-blured [error] + {:background-color (if error common/color-red2 common/color-light-gray2) + :align-items :center}) + +(defn underline-focused [underline-width underline-height error] + {:height underline-height + :width underline-width + :background-color (if error common/color-red2 common/color-light-blue)}) + +(def label-top-top (if ios? 6 6)) + +(def label-top-bottom (if ios? 26 26)) + +(def label-font-size-top (if ios? 14 12)) + +(def label-font-size-bottom (if ios? 17 16)) + +(def underline-max-height (if ios? 1 2)) diff --git a/src/status_im/components/text_input_with_label/view.cljs b/src/status_im/components/text_input_with_label/view.cljs new file mode 100644 index 0000000000..21c567aab1 --- /dev/null +++ b/src/status_im/components/text_input_with_label/view.cljs @@ -0,0 +1,75 @@ +(ns status-im.components.text-input-with-label.view + (:require [reagent.core :as r] + [status-im.components.animation :as animation] + [status-im.components.text-input-with-label.animation :refer [animate-label + text-input-on-focus + text-input-on-blur]] + [status-im.components.react :refer [view + text + animated-text + animated-view + text-input]] + [status-im.components.text-input-with-label.styles :as st] + [clojure.string :as str])) + +(defn get-init-props [{:keys [default-value]}] + (let [blank? (str/blank? default-value)] + {:underline-width (animation/create-value 0) + :underline-height (animation/create-value 1) + :label-top (animation/create-value (if blank? + st/label-top-bottom + st/label-top-top)) + :label-font-size (animation/create-value (if blank? + st/label-font-size-bottom + st/label-font-size-top)) + :label-top-top st/label-top-top + :label-top-bottom st/label-top-bottom + :label-font-size-top st/label-font-size-top + :label-font-size-bottom st/label-font-size-bottom + :underline-max-height st/underline-max-height + :input-ref* (r/atom nil) + :value* (r/atom default-value) + :underline-max-width* (r/atom 0)})) + +(defn get-width [event] + (.-width (.-layout (.-nativeEvent event)))) + +(defn text-input-on-change-text [text props] + (animate-label text props) + (reset! (:value* props) text)) + +(defn text-input-handlers [{:keys [on-focus on-blur on-change-text on-submit-editing ref]} props] + {:ref #(do + (reset! (:input-ref* props) %) + (when ref (ref %))) + :on-submit-editing #(do + (.blur @(:input-ref* props)) + (when on-submit-editing (on-submit-editing))) + :on-focus #(do + (text-input-on-focus props) + (when on-focus (on-focus))) + :on-blur #(do + (text-input-on-blur props) + (when on-blur (on-blur))) + :on-change-text #(do + (text-input-on-change-text % props) + (when on-change-text (on-change-text %)))}) + +(defn text-input-with-label [options] + (let [props (get-init-props options)] + (fn [{:keys [label description error] :as options}] + [view st/component-container + [animated-text {:style (st/label-animated-text props)} label] + [text-input (merge st/text-input + (dissoc options :label :description :error) + (text-input-handlers options props))] + [view {:style (st/underline-blured error) + :on-layout #(reset! (:underline-max-width* props) (get-width %))} + [animated-view {:style (st/underline-focused + (:underline-width props) + (:underline-height props) + error)}]] + (cond error + [text {:style st/error-text} error] + description + [text {:style st/description-text} description])]))) diff --git a/src/status_im/contacts/views/contact_list.cljs b/src/status_im/contacts/views/contact_list.cljs index af0e02e44c..de834d0d93 100644 --- a/src/status_im/contacts/views/contact_list.cljs +++ b/src/status_im/contacts/views/contact_list.cljs @@ -11,7 +11,6 @@ touchable-highlight list-view list-item]] - [status-im.components.text-field.view :refer [text-field]] [status-im.components.status-bar :refer [status-bar]] [status-im.components.toolbar-new.view :refer [toolbar-with-search toolbar]] [status-im.components.toolbar-new.actions :as act] diff --git a/src/status_im/contacts/views/contact_list_modal.cljs b/src/status_im/contacts/views/contact_list_modal.cljs index c1ceec9a8b..7915af9cb0 100644 --- a/src/status_im/contacts/views/contact_list_modal.cljs +++ b/src/status_im/contacts/views/contact_list_modal.cljs @@ -13,7 +13,6 @@ [status-im.components.action-button.action-button :refer [action-button action-separator]] [status-im.components.action-button.styles :refer [actions-list]] - [status-im.components.text-field.view :refer [text-field]] [status-im.components.status-bar :refer [status-bar]] [status-im.components.toolbar-new.view :refer [toolbar-with-search toolbar]] [status-im.components.toolbar-new.actions :as act] diff --git a/src/status_im/new_group/screen_private.cljs b/src/status_im/new_group/screen_private.cljs index 0140c117dd..db7fb04898 100644 --- a/src/status_im/new_group/screen_private.cljs +++ b/src/status_im/new_group/screen_private.cljs @@ -59,7 +59,7 @@ st/group-container) [group-toolbar type true] [group-name-view] - [view {:flex 1} + [view st/list-view-container [add-btn #(dispatch [:navigate-to :add-contacts-toggle-list])] [group-contacts-view group] [view st/separator] @@ -83,7 +83,7 @@ st/group-container) [group-toolbar group-type false] [group-name-view] - [view {:flex 1} + [view st/list-view-container [list-view {:dataSource (to-datasource contacts) :enableEmptySections true :renderRow render-row diff --git a/src/status_im/new_group/styles.cljs b/src/status_im/new_group/styles.cljs index f3ef2edc43..6f5a391313 100644 --- a/src/status_im/new_group/styles.cljs +++ b/src/status_im/new_group/styles.cljs @@ -33,8 +33,7 @@ :android {:padding-top 16}}) (def chat-name-container - {:margin-top 21 - :margin-left 16}) + {:margin-top 10}) (def add-button-container {:margin-left 16}) @@ -221,6 +220,10 @@ :height 1 :opacity 0.5}) +(def list-view-container + {:flex 1 + :margin-top 10}) + diff --git a/src/status_im/new_group/views/group.cljs b/src/status_im/new_group/views/group.cljs index fb9b25c081..af644b3047 100644 --- a/src/status_im/new_group/views/group.cljs +++ b/src/status_im/new_group/views/group.cljs @@ -10,7 +10,7 @@ text icon touchable-highlight]] - [status-im.components.text-field.view :refer [text-field]] + [status-im.components.text-input-with-label.view :refer [text-input-with-label]] [status-im.components.styles :refer [color-blue color-gray5 color-light-blue]] [status-im.components.status-bar :refer [status-bar]] [status-im.components.toolbar-new.view :refer [toolbar]] @@ -18,20 +18,6 @@ [status-im.new-group.styles :as st] [status-im.i18n :refer [label]])) -(defview group-name-input [] - [new-group-name [:get :new-chat-name]] - [view - [text-field - {:wrapper-style st/group-chat-name-wrapper - :line-color color-gray5 - :focus-line-color color-light-blue - :focus-line-height st/group-chat-focus-line-height - :label-hidden? true - :input-style st/group-chat-name-input - :auto-focus true - :on-change-text #(dispatch [:set :new-chat-name %]) - :value new-group-name}]]) - (defn group-toolbar [group-type edit?] [view [status-bar] @@ -42,15 +28,18 @@ (if edit? :t/chat-settings :t/new-group-chat))) :actions [{:image :blank}]}]]) -(defn group-name-view [] +(defview group-name-view [] + [new-group-name [:get :new-chat-name]] [view st/chat-name-container - [text {:style st/group-name-text} - (label :t/name)] - [group-name-input]]) + [text-input-with-label + {:auto-focus true + :label (label :t/name) + :on-change-text #(dispatch [:set :new-chat-name %]) + :default-value new-group-name}]]) (defn add-btn [on-press] [action-button (label :t/add-members) - :add_blue + :add_blue on-press]) (defn delete-btn [on-press] diff --git a/src/status_im/profile/edit/screen.cljs b/src/status_im/profile/edit/screen.cljs index 7af773ffd4..c6b3d17533 100644 --- a/src/status_im/profile/edit/screen.cljs +++ b/src/status_im/profile/edit/screen.cljs @@ -1,12 +1,12 @@ (ns status-im.profile.edit.screen (:require-macros [status-im.utils.views :refer [defview]]) (:require [status-im.profile.styles :as st] + [status-im.components.text-input-with-label.view :refer [text-input-with-label]] [status-im.components.styles :refer [color-blue color-gray5]] [re-frame.core :refer [dispatch]] [status-im.components.status-bar :refer [status-bar]] [status-im.components.toolbar-new.view :refer [toolbar]] [status-im.components.toolbar-new.actions :as act] - [status-im.components.text-field.view :refer [text-field]] [status-im.i18n :refer [label]] [status-im.profile.screen :refer [colorize-status-hashtags]] [status-im.components.sticky-button :refer [sticky-button]] @@ -32,14 +32,9 @@ (defview profile-name-input [] [new-profile-name [:get-in [:profile-edit :name]]] [view - [text-field - {:line-color st/edit-line-color - :focus-line-color st/profile-focus-line-color - :focus-line-height st/profile-focus-line-height - :label (label :t/name) - :input-style st/profile-name-input - :on-change-text #(dispatch [:set-in [:profile-edit :name] %]) - :value new-profile-name}]]) + [text-input-with-label {:label (label :t/name) + :default-value new-profile-name + :on-change-text #(dispatch [:set-in [:profile-edit :name] %])}]]) (def profile-icon-options [{:text (label :t/image-source-gallery) :value #(dispatch [:open-image-picker])} diff --git a/src/status_im/profile/styles.cljs b/src/status_im/profile/styles.cljs index 0e3d5bb48d..53a1a850c2 100644 --- a/src/status_im/profile/styles.cljs +++ b/src/status_im/profile/styles.cljs @@ -51,18 +51,14 @@ (def edit-profile-bage {:flex-direction :row - :align-items :center :padding-left 24}) (def context-menu-custom-styles {:optionsContainer {:margin-top 78}}) -(defstyle edit-profile-name-container +(def edit-profile-name-container {:flex 1 - :ios {:padding-left 32 - :padding-top 15} - :android {:padding-top 16 - :padding-left 16}}) + :padding-top 30}) (def edit-profile-icon-container {:padding-top 25}) @@ -185,9 +181,10 @@ :padding-bottom 16 :margin-left 16 :margin-right 16 - :margin-top 24 - :ios {:padding-top 10} - :android {:padding-top 13}}) + :ios {:padding-top 10 + :margin-top 10} + :android {:padding-top 13 + :margin-top 13}}) (def add-a-status (merge profile-status-text