mirror of
https://github.com/status-im/status-react.git
synced 2025-01-09 10:42:53 +00:00
feat: add title input component to quo2 (#15133)
This commit is contained in:
parent
ff3249c514
commit
d8c110bf85
@ -116,6 +116,20 @@ deref'ed atoms.
|
|||||||
{:background-color (colors/theme-colors colors/white colors/neutral-90)})
|
{:background-color (colors/theme-colors colors/white colors/neutral-90)})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Custom Colors
|
||||||
|
|
||||||
|
The Status designs have a lot of customization of user and group colors with components and pages. For consistency it is best to use `customization-color` as the prop key on pages and components. This will help easily identify what pages and components in the application are using customized colors.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
;; bad
|
||||||
|
(defn community-card [{keys [custom-color]}]
|
||||||
|
...)
|
||||||
|
|
||||||
|
;; good
|
||||||
|
(defn community-card [{keys [customization-color]}]
|
||||||
|
...)
|
||||||
|
```
|
||||||
|
|
||||||
### Using TODOs comments
|
### Using TODOs comments
|
||||||
|
|
||||||
_TODO_ comments are used extensively in the codebase, but prefer to use them
|
_TODO_ comments are used extensively in the codebase, but prefer to use them
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
(ns quo2.components.input.style
|
(ns quo2.components.inputs.input.style
|
||||||
(:require [quo2.components.markdown.text :as text]
|
(:require [quo2.components.markdown.text :as text]
|
||||||
[quo2.foundations.colors :as colors]))
|
[quo2.foundations.colors :as colors]))
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
(ns quo2.components.input.view
|
(ns quo2.components.inputs.input.view
|
||||||
(:require [oops.core :as oops]
|
(:require [oops.core :as oops]
|
||||||
[quo2.components.icon :as icon]
|
[quo2.components.icon :as icon]
|
||||||
[quo2.components.input.style :as style]
|
[quo2.components.inputs.input.style :as style]
|
||||||
[quo2.components.markdown.text :as text]
|
[quo2.components.markdown.text :as text]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]))
|
40
src/quo2/components/inputs/title_input/component_spec.cljs
Normal file
40
src/quo2/components/inputs/title_input/component_spec.cljs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
(ns quo2.components.inputs.title-input.component-spec
|
||||||
|
(:require [quo2.components.inputs.title-input.view :as title-input]
|
||||||
|
[test-helpers.component :as h]))
|
||||||
|
|
||||||
|
(h/describe "profile: title-input"
|
||||||
|
(h/test "renders empty"
|
||||||
|
(h/render [title-input/title-input
|
||||||
|
{:value ""
|
||||||
|
:on-change-text (h/mock-fn)}])
|
||||||
|
(-> (js/expect (h/get-by-label-text :profile-title-input))
|
||||||
|
(.toBeTruthy)))
|
||||||
|
|
||||||
|
(h/test "empty text renders with max length digits and 00"
|
||||||
|
(h/render [title-input/title-input
|
||||||
|
{:value ""
|
||||||
|
:max-length 24
|
||||||
|
:on-change-text (h/mock-fn)}])
|
||||||
|
(-> (js/expect (h/get-by-text "00"))
|
||||||
|
(.toBeTruthy))
|
||||||
|
(-> (js/expect (h/get-by-text "/24"))
|
||||||
|
(.toBeTruthy)))
|
||||||
|
|
||||||
|
(h/test "renders with max length digits and character count"
|
||||||
|
(h/render [title-input/title-input
|
||||||
|
{:default-value "abc"
|
||||||
|
:max-length 24
|
||||||
|
:on-change-text (h/mock-fn)} "abc"])
|
||||||
|
(-> (js/expect (h/get-by-text "03"))
|
||||||
|
(.toBeTruthy))
|
||||||
|
(-> (js/expect (h/get-by-text "/24"))
|
||||||
|
(.toBeTruthy)))
|
||||||
|
|
||||||
|
(h/test "text updates on change"
|
||||||
|
(let [on-change-text (h/mock-fn)]
|
||||||
|
(h/render [title-input/title-input
|
||||||
|
{:value "mock text"
|
||||||
|
:on-change-text on-change-text}])
|
||||||
|
(h/fire-event :change-text (h/get-by-label-text :profile-title-input) "mock-text-new")
|
||||||
|
(-> (js/expect on-change-text)
|
||||||
|
(.toHaveBeenCalled)))))
|
52
src/quo2/components/inputs/title_input/style.cljs
Normal file
52
src/quo2/components/inputs/title_input/style.cljs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
(ns quo2.components.inputs.title-input.style
|
||||||
|
(:require [quo2.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(defn get-focused-placeholder-color
|
||||||
|
[blur?]
|
||||||
|
(if blur?
|
||||||
|
(colors/theme-colors colors/neutral-80-opa-20 (colors/alpha colors/white 0.2))
|
||||||
|
(colors/theme-colors colors/neutral-30 colors/neutral-60)))
|
||||||
|
|
||||||
|
(defn get-placeholder-color
|
||||||
|
[blur?]
|
||||||
|
(if blur?
|
||||||
|
(colors/theme-colors colors/neutral-80-opa-40 (colors/alpha colors/white 0.3))
|
||||||
|
(colors/theme-colors colors/neutral-40 colors/neutral-50)))
|
||||||
|
|
||||||
|
(defn- get-disabled-color
|
||||||
|
[blur?]
|
||||||
|
(if blur?
|
||||||
|
(colors/theme-colors colors/neutral-80-opa-40 (colors/alpha colors/white 0.3))
|
||||||
|
(colors/theme-colors colors/neutral-40 colors/neutral-50)))
|
||||||
|
|
||||||
|
(defn- get-char-count-color
|
||||||
|
[blur?]
|
||||||
|
(if blur?
|
||||||
|
(colors/theme-colors colors/neutral-80-opa-40 (colors/alpha colors/white 0.4))
|
||||||
|
(colors/theme-colors colors/neutral-40 colors/neutral-50)))
|
||||||
|
|
||||||
|
(defn get-selection-color
|
||||||
|
[customization-color blur?]
|
||||||
|
(if blur?
|
||||||
|
(colors/theme-colors colors/neutral-100 colors/white)
|
||||||
|
(colors/custom-color customization-color (if colors/dark? 60 50))))
|
||||||
|
|
||||||
|
(def text-input-container {:flex 1})
|
||||||
|
|
||||||
|
(defn title-text
|
||||||
|
[disabled? blur?]
|
||||||
|
{:text-align-vertical :bottom
|
||||||
|
:color (when disabled? (get-disabled-color blur?))})
|
||||||
|
|
||||||
|
(defn char-count
|
||||||
|
[blur?]
|
||||||
|
{:color (get-char-count-color blur?)})
|
||||||
|
|
||||||
|
(def container
|
||||||
|
{:flex-direction :row
|
||||||
|
:flex 1
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center})
|
||||||
|
|
||||||
|
(def counter-container
|
||||||
|
{:padding-top 8})
|
65
src/quo2/components/inputs/title_input/view.cljs
Normal file
65
src/quo2/components/inputs/title_input/view.cljs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
(ns quo2.components.inputs.title-input.view
|
||||||
|
(:require
|
||||||
|
[quo2.components.inputs.title-input.style :as style]
|
||||||
|
[quo2.components.markdown.text :as text]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[react-native.core :as rn]))
|
||||||
|
|
||||||
|
(defn- pad-0
|
||||||
|
[value]
|
||||||
|
(if (<= (count value) 1)
|
||||||
|
(str 0 value)
|
||||||
|
value))
|
||||||
|
|
||||||
|
(defn title-input
|
||||||
|
[{:keys [blur?
|
||||||
|
on-change-text
|
||||||
|
placeholder
|
||||||
|
max-length
|
||||||
|
default-value]
|
||||||
|
:or {max-length 0
|
||||||
|
default-value ""}}]
|
||||||
|
(let [focused? (reagent/atom false)
|
||||||
|
value (reagent/atom default-value)
|
||||||
|
on-change (fn [v]
|
||||||
|
(reset! value v)
|
||||||
|
(when on-change-text
|
||||||
|
(on-change-text v)))]
|
||||||
|
(fn [{:keys [customization-color disabled?]}]
|
||||||
|
[rn/view
|
||||||
|
{:style style/container}
|
||||||
|
[rn/view {:style style/text-input-container}
|
||||||
|
[rn/text-input
|
||||||
|
{:style
|
||||||
|
(text/text-style
|
||||||
|
{:size :heading-2
|
||||||
|
:weight :semi-bold
|
||||||
|
:style (style/title-text disabled? blur?)})
|
||||||
|
:default-value default-value
|
||||||
|
:accessibility-label :profile-title-input
|
||||||
|
:on-focus #(swap! focused? (fn [] true))
|
||||||
|
:on-blur #(swap! focused? (fn [] false))
|
||||||
|
:input-mode :text
|
||||||
|
:on-change-text on-change
|
||||||
|
:editable (not disabled?)
|
||||||
|
:max-length max-length
|
||||||
|
:placeholder placeholder
|
||||||
|
:selection-color (style/get-selection-color customization-color blur?)
|
||||||
|
:placeholder-text-color (if @focused?
|
||||||
|
(style/get-focused-placeholder-color blur?)
|
||||||
|
(style/get-placeholder-color blur?))}]]
|
||||||
|
[rn/view
|
||||||
|
{:style style/counter-container}
|
||||||
|
[text/text
|
||||||
|
[text/text
|
||||||
|
{:style (style/char-count blur?)
|
||||||
|
:size :paragraph-2}
|
||||||
|
(pad-0
|
||||||
|
(str
|
||||||
|
(count @value)))]
|
||||||
|
[text/text
|
||||||
|
{:style (style/char-count blur?)
|
||||||
|
:size :paragraph-2}
|
||||||
|
(str "/"
|
||||||
|
(pad-0
|
||||||
|
(str max-length)))]]]])))
|
@ -6,9 +6,9 @@
|
|||||||
[react-native.core :as rn]))
|
[react-native.core :as rn]))
|
||||||
|
|
||||||
(defn card-background
|
(defn card-background
|
||||||
[{:keys [custom-color]}]
|
[{:keys [customization-color]}]
|
||||||
[:<>
|
[:<>
|
||||||
[rn/view {:style (style/background-top custom-color)}]
|
[rn/view {:style (style/background-top customization-color)}]
|
||||||
[rn/view {:style (style/background-bottom)}]])
|
[rn/view {:style (style/background-bottom)}]])
|
||||||
|
|
||||||
(defn avatar
|
(defn avatar
|
||||||
@ -28,12 +28,12 @@
|
|||||||
:i/more]])
|
:i/more]])
|
||||||
|
|
||||||
(defn account
|
(defn account
|
||||||
[{:keys [account-name account-address avatar-icon custom-color on-press-menu]}]
|
[{:keys [account-name account-address avatar-icon customization-color on-press-menu]}]
|
||||||
[rn/view {:style style/card}
|
[rn/view {:style style/card}
|
||||||
[card-background {:custom-color custom-color}]
|
[card-background {:customization-color customization-color}]
|
||||||
[rn/view {:style style/card-top}
|
[rn/view {:style style/card-top}
|
||||||
[avatar
|
[avatar
|
||||||
{:color custom-color
|
{:color customization-color
|
||||||
:icon avatar-icon}]
|
:icon avatar-icon}]
|
||||||
[menu-button {:on-press on-press-menu}]]
|
[menu-button {:on-press on-press-menu}]]
|
||||||
[rn/view {:style style/card-bottom}
|
[rn/view {:style style/card-bottom}
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
quo2.components.icon
|
quo2.components.icon
|
||||||
quo2.components.info.info-message
|
quo2.components.info.info-message
|
||||||
quo2.components.info.information-box
|
quo2.components.info.information-box
|
||||||
quo2.components.input.view
|
quo2.components.inputs.input.view
|
||||||
|
quo2.components.inputs.title-input.view
|
||||||
quo2.components.list-items.channel
|
quo2.components.list-items.channel
|
||||||
quo2.components.list-items.menu-item
|
quo2.components.list-items.menu-item
|
||||||
quo2.components.list-items.preview-list
|
quo2.components.list-items.preview-list
|
||||||
@ -142,7 +143,8 @@
|
|||||||
(def permission-context quo2.components.drawers.permission-context.view/view)
|
(def permission-context quo2.components.drawers.permission-context.view/view)
|
||||||
|
|
||||||
;;;; INPUTS
|
;;;; INPUTS
|
||||||
(def input quo2.components.input.view/input)
|
(def input quo2.components.inputs.input.view/input)
|
||||||
|
(def title-input quo2.components.inputs.title-input.view/title-input)
|
||||||
|
|
||||||
;;;; LIST ITEMS
|
;;;; LIST ITEMS
|
||||||
(def channel-list-item quo2.components.list-items.channel/list-item)
|
(def channel-list-item quo2.components.list-items.channel/list-item)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
[quo2.components.drawers.drawer-buttons.component-spec]
|
[quo2.components.drawers.drawer-buttons.component-spec]
|
||||||
[quo2.components.drawers.permission-context.component-spec]
|
[quo2.components.drawers.permission-context.component-spec]
|
||||||
[quo2.components.colors.color-picker.component-spec]
|
[quo2.components.colors.color-picker.component-spec]
|
||||||
|
[quo2.components.inputs.title-input.component-spec]
|
||||||
[quo2.components.markdown.--tests--.text-component-spec]
|
[quo2.components.markdown.--tests--.text-component-spec]
|
||||||
[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]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
(ns status-im2.contexts.quo-preview.inputs.input
|
(ns status-im2.contexts.quo-preview.inputs.input
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[quo2.components.input.view :as quo2]
|
[quo2.core :as quo]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
@ -94,7 +94,7 @@
|
|||||||
:padding-vertical 60
|
:padding-vertical 60
|
||||||
:background-color background-color}}
|
:background-color background-color}}
|
||||||
[rn/view {:style {:width 300}}
|
[rn/view {:style {:width 300}}
|
||||||
[quo2/input
|
[quo/input
|
||||||
(cond-> @state
|
(cond-> @state
|
||||||
:always (assoc
|
:always (assoc
|
||||||
:on-clear #(swap! state assoc :value "")
|
:on-clear #(swap! state assoc :value "")
|
||||||
|
57
src/status_im2/contexts/quo_preview/inputs/title_input.cljs
Normal file
57
src/status_im2/contexts/quo_preview/inputs/title_input.cljs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
(ns status-im2.contexts.quo-preview.inputs.title-input
|
||||||
|
(:require [quo2.foundations.colors :as colors]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[quo2.core :as quo]
|
||||||
|
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||||
|
|
||||||
|
(def descriptor
|
||||||
|
[{:label "disabled?"
|
||||||
|
:key :disabled?
|
||||||
|
:type :boolean}
|
||||||
|
{:label "blur?"
|
||||||
|
:key :blur?
|
||||||
|
:type :boolean}
|
||||||
|
{:label "Cursor Color"
|
||||||
|
:key :color
|
||||||
|
:type :select
|
||||||
|
:options (map (fn [{:keys [name]}] {:key name :value name}) (quo/picker-colors))}])
|
||||||
|
|
||||||
|
(defn cool-preview
|
||||||
|
[]
|
||||||
|
(let [state (reagent/atom {:color nil
|
||||||
|
:blur? false
|
||||||
|
:disabled? false})
|
||||||
|
max-length 24
|
||||||
|
on-change-text (fn [_v]
|
||||||
|
(println (str "cool-preview -> on-change-text called " _v)))]
|
||||||
|
(fn []
|
||||||
|
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||||
|
[rn/view {:padding-bottom 150}
|
||||||
|
[rn/view {:flex 1}]
|
||||||
|
[preview/customizer state descriptor]
|
||||||
|
|
||||||
|
[preview/blur-view
|
||||||
|
{:show-blur-background? (:blur? @state)
|
||||||
|
:style {:flex-direction :row
|
||||||
|
:justify-content :center}}
|
||||||
|
[quo/title-input
|
||||||
|
{:max-length max-length
|
||||||
|
:default-value ""
|
||||||
|
:on-change-text on-change-text
|
||||||
|
:disabled? (:disabled? @state)
|
||||||
|
:customization-color (:color @state)
|
||||||
|
:blur? (:blur? @state)
|
||||||
|
:placeholder "type something here"}]]]])))
|
||||||
|
|
||||||
|
(defn preview-title-input
|
||||||
|
[]
|
||||||
|
[rn/view
|
||||||
|
{:background-color (colors/theme-colors colors/white
|
||||||
|
colors/neutral-90)
|
||||||
|
:flex 1}
|
||||||
|
[rn/flat-list
|
||||||
|
{:flex 1
|
||||||
|
:keyboard-should-persist-taps :always
|
||||||
|
:header [cool-preview]
|
||||||
|
:key-fn str}]])
|
@ -37,6 +37,7 @@
|
|||||||
[status-im2.contexts.quo-preview.foundations.shadows :as shadows]
|
[status-im2.contexts.quo-preview.foundations.shadows :as shadows]
|
||||||
[status-im2.contexts.quo-preview.info.info-message :as info-message]
|
[status-im2.contexts.quo-preview.info.info-message :as info-message]
|
||||||
[status-im2.contexts.quo-preview.info.information-box :as information-box]
|
[status-im2.contexts.quo-preview.info.information-box :as information-box]
|
||||||
|
[status-im2.contexts.quo-preview.inputs.title-input :as title-input]
|
||||||
[status-im2.contexts.quo-preview.list-items.channel :as channel]
|
[status-im2.contexts.quo-preview.list-items.channel :as channel]
|
||||||
[status-im2.contexts.quo-preview.list-items.preview-lists :as preview-lists]
|
[status-im2.contexts.quo-preview.list-items.preview-lists :as preview-lists]
|
||||||
[status-im2.contexts.quo-preview.markdown.text :as text]
|
[status-im2.contexts.quo-preview.markdown.text :as text]
|
||||||
@ -168,7 +169,10 @@
|
|||||||
:component information-box/preview-information-box}]
|
:component information-box/preview-information-box}]
|
||||||
:inputs [{:name :input
|
:inputs [{:name :input
|
||||||
:insets {:top false}
|
:insets {:top false}
|
||||||
:component input/preview-input}]
|
:component input/preview-input}
|
||||||
|
{:name :title-input
|
||||||
|
:insets {:top false}
|
||||||
|
:component title-input/preview-title-input}]
|
||||||
:list-items [{:name :channel
|
:list-items [{:name :channel
|
||||||
:insets {:top false}
|
:insets {:top false}
|
||||||
:component channel/preview-channel}
|
:component channel/preview-channel}
|
||||||
|
@ -218,9 +218,8 @@
|
|||||||
(defn blur-view
|
(defn blur-view
|
||||||
[{:keys [show-blur-background? image height blur-view-props style]} children]
|
[{:keys [show-blur-background? image height blur-view-props style]} children]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style {:flex 1
|
{:style {:flex 1
|
||||||
:padding-horizontal 16
|
:padding-vertical 16}}
|
||||||
:padding-vertical 16}}
|
|
||||||
(when show-blur-background?
|
(when show-blur-background?
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style {:height (or height 100)
|
{:style {:height (or height 100)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
(def descriptor
|
(def descriptor
|
||||||
[{:label "Custom color"
|
[{:label "Custom color"
|
||||||
:key :custom-color
|
:key :customization-color
|
||||||
:type :select
|
:type :select
|
||||||
:options (map (fn [[k _]]
|
:options (map (fn [[k _]]
|
||||||
{:key k :value (string/capitalize (name k))})
|
{:key k :value (string/capitalize (name k))})
|
||||||
@ -22,12 +22,12 @@
|
|||||||
|
|
||||||
(defn cool-preview
|
(defn cool-preview
|
||||||
[]
|
[]
|
||||||
(let [state (reagent/atom {:custom-color :blue
|
(let [state (reagent/atom {:customization-color :blue
|
||||||
:account-name "Booze for Dubai"
|
:account-name "Booze for Dubai"
|
||||||
:account-address "0x21a ... 49e"
|
:account-address "0x21a ... 49e"
|
||||||
:avatar-icon :i/placeholder
|
:avatar-icon :i/placeholder
|
||||||
:on-press-menu (fn []
|
:on-press-menu (fn []
|
||||||
(js/alert "Menu button pressed"))})]
|
(js/alert "Menu button pressed"))})]
|
||||||
(fn []
|
(fn []
|
||||||
[rn/view
|
[rn/view
|
||||||
{:margin-bottom 50
|
{:margin-bottom 50
|
||||||
|
Loading…
x
Reference in New Issue
Block a user