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)})
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
_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]
|
||||
[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]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.input.style :as style]
|
||||
[quo2.components.inputs.input.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
|
@ -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)))))
|
|
@ -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})
|
|
@ -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]))
|
||||
|
||||
(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)}]])
|
||||
|
||||
(defn avatar
|
||||
|
@ -28,12 +28,12 @@
|
|||
:i/more]])
|
||||
|
||||
(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}
|
||||
[card-background {:custom-color custom-color}]
|
||||
[card-background {:customization-color customization-color}]
|
||||
[rn/view {:style style/card-top}
|
||||
[avatar
|
||||
{:color custom-color
|
||||
{:color customization-color
|
||||
:icon avatar-icon}]
|
||||
[menu-button {:on-press on-press-menu}]]
|
||||
[rn/view {:style style/card-bottom}
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
quo2.components.icon
|
||||
quo2.components.info.info-message
|
||||
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.menu-item
|
||||
quo2.components.list-items.preview-list
|
||||
|
@ -142,7 +143,8 @@
|
|||
(def permission-context quo2.components.drawers.permission-context.view/view)
|
||||
|
||||
;;;; 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
|
||||
(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.permission-context.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.onboarding.small-option-card.component-spec]
|
||||
[quo2.components.password.tips.component-spec]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns status-im2.contexts.quo-preview.inputs.input
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo2.components.input.view :as quo2]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
|
@ -94,7 +94,7 @@
|
|||
:padding-vertical 60
|
||||
:background-color background-color}}
|
||||
[rn/view {:style {:width 300}}
|
||||
[quo2/input
|
||||
[quo/input
|
||||
(cond-> @state
|
||||
:always (assoc
|
||||
:on-clear #(swap! state assoc :value "")
|
||||
|
|
|
@ -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.info.info-message :as info-message]
|
||||
[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.preview-lists :as preview-lists]
|
||||
[status-im2.contexts.quo-preview.markdown.text :as text]
|
||||
|
@ -168,7 +169,10 @@
|
|||
:component information-box/preview-information-box}]
|
||||
:inputs [{:name :input
|
||||
: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
|
||||
:insets {:top false}
|
||||
:component channel/preview-channel}
|
||||
|
|
|
@ -218,9 +218,8 @@
|
|||
(defn blur-view
|
||||
[{:keys [show-blur-background? image height blur-view-props style]} children]
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:padding-horizontal 16
|
||||
:padding-vertical 16}}
|
||||
{:style {:flex 1
|
||||
:padding-vertical 16}}
|
||||
(when show-blur-background?
|
||||
[rn/view
|
||||
{:style {:height (or height 100)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
(def descriptor
|
||||
[{:label "Custom color"
|
||||
:key :custom-color
|
||||
:key :customization-color
|
||||
:type :select
|
||||
:options (map (fn [[k _]]
|
||||
{:key k :value (string/capitalize (name k))})
|
||||
|
@ -22,12 +22,12 @@
|
|||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:custom-color :blue
|
||||
:account-name "Booze for Dubai"
|
||||
:account-address "0x21a ... 49e"
|
||||
:avatar-icon :i/placeholder
|
||||
:on-press-menu (fn []
|
||||
(js/alert "Menu button pressed"))})]
|
||||
(let [state (reagent/atom {:customization-color :blue
|
||||
:account-name "Booze for Dubai"
|
||||
:account-address "0x21a ... 49e"
|
||||
:avatar-icon :i/placeholder
|
||||
:on-press-menu (fn []
|
||||
(js/alert "Menu button pressed"))})]
|
||||
(fn []
|
||||
[rn/view
|
||||
{:margin-bottom 50
|
||||
|
|
Loading…
Reference in New Issue