quo2 predictive keyboard component (#15806)
This commit is contained in:
parent
6aae68ba04
commit
5f362f333f
|
@ -0,0 +1,20 @@
|
||||||
|
(ns quo2.components.buttons.predictive-keyboard.component-spec
|
||||||
|
(:require [quo2.components.buttons.predictive-keyboard.view :as predictive-keyboard]
|
||||||
|
[test-helpers.component :as h]))
|
||||||
|
|
||||||
|
(h/describe "predictive-keyboard"
|
||||||
|
(h/test "basic render"
|
||||||
|
(h/render [predictive-keyboard/view {:type :error :text "Error message"}])
|
||||||
|
(h/is-truthy (h/get-by-label-text :predictive-keyboard)))
|
||||||
|
(h/test "rendered with correct text"
|
||||||
|
(h/render [predictive-keyboard/view {:type :info :text "Error message"}])
|
||||||
|
(h/is-truthy (h/get-by-text "Error message")))
|
||||||
|
(h/test "rendered with correct words"
|
||||||
|
(h/render [predictive-keyboard/view {:type :words :words ["lab" "label"]}])
|
||||||
|
(h/is-truthy (h/get-by-text "lab"))
|
||||||
|
(h/is-truthy (h/get-by-text "label")))
|
||||||
|
(h/test "word press event"
|
||||||
|
(let [event (h/mock-fn)]
|
||||||
|
(h/render [predictive-keyboard/view {:type :words :words ["lab" "label"] :on-press #(event %)}])
|
||||||
|
(h/fire-event :press (h/get-by-text "lab"))
|
||||||
|
(h/was-called event))))
|
|
@ -0,0 +1,11 @@
|
||||||
|
(ns quo2.components.buttons.predictive-keyboard.style)
|
||||||
|
|
||||||
|
(defn wrapper
|
||||||
|
[type]
|
||||||
|
{:flex 1
|
||||||
|
:min-height 48
|
||||||
|
:padding-vertical 8
|
||||||
|
:justify-content :center
|
||||||
|
:padding-horizontal (if (= type :words) 0 20)})
|
||||||
|
|
||||||
|
(def word-list {:align-items :center :padding-horizontal 20})
|
|
@ -0,0 +1,71 @@
|
||||||
|
(ns quo2.components.buttons.predictive-keyboard.view
|
||||||
|
(:require [react-native.core :as rn]
|
||||||
|
[quo2.components.buttons.predictive-keyboard.style :as style]
|
||||||
|
[quo2.components.info.info-message :as info-message]
|
||||||
|
[react-native.linear-gradient :as linear-gradient]
|
||||||
|
[quo2.foundations.colors :as colors]
|
||||||
|
[quo2.components.buttons.button :as button]))
|
||||||
|
|
||||||
|
(def ^:private gradients
|
||||||
|
{:light [(colors/alpha colors/neutral-40 0.05) (colors/alpha colors/neutral-40 0)]
|
||||||
|
:dark [(colors/alpha colors/neutral-80 0.7) (colors/alpha colors/neutral-80 0)]
|
||||||
|
:blur [colors/white-opa-5 colors/white-opa-0]})
|
||||||
|
|
||||||
|
(defn- word-component
|
||||||
|
[word _ _ {:keys [blur? on-press]}]
|
||||||
|
[button/button
|
||||||
|
(merge {:type :blur-bg
|
||||||
|
:size 32
|
||||||
|
:on-press #(on-press word)}
|
||||||
|
(when blur? {:override-theme :dark}))
|
||||||
|
word])
|
||||||
|
|
||||||
|
(defn- separator
|
||||||
|
[]
|
||||||
|
[rn/view {:style {:width 8}}])
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
"Options
|
||||||
|
- `type` `:words`/`:error`/`:info`/`:empty`.
|
||||||
|
- `blur?` Boolean to enable blur background support.
|
||||||
|
- `text` error/info text.
|
||||||
|
- `words` List of words to display in the keyboard.
|
||||||
|
- `on-press` Callback called when a word is pressed `(fn [word])`."
|
||||||
|
[{:keys [type blur? text words on-press]}]
|
||||||
|
[linear-gradient/linear-gradient
|
||||||
|
{:style {:flex-direction :row}
|
||||||
|
:accessibility-label :predictive-keyboard
|
||||||
|
:colors (if blur?
|
||||||
|
(gradients :blur)
|
||||||
|
(colors/theme-colors (gradients :light) (gradients :dark)))}
|
||||||
|
[rn/view {:style (style/wrapper type)}
|
||||||
|
(case type
|
||||||
|
:words
|
||||||
|
[rn/flat-list
|
||||||
|
{:data words
|
||||||
|
:content-container-style style/word-list
|
||||||
|
:render-fn word-component
|
||||||
|
:render-data {:blur? blur?
|
||||||
|
:on-press on-press}
|
||||||
|
:shows-horizontal-scroll-indicator false
|
||||||
|
:separator [separator]
|
||||||
|
:horizontal true
|
||||||
|
:key-fn str}]
|
||||||
|
|
||||||
|
:error
|
||||||
|
[info-message/info-message
|
||||||
|
{:icon :i/info
|
||||||
|
:size :default
|
||||||
|
:type :error}
|
||||||
|
text]
|
||||||
|
|
||||||
|
:info
|
||||||
|
[info-message/info-message
|
||||||
|
(merge {:icon :i/info
|
||||||
|
:size :default
|
||||||
|
:type (if (= type :error) :error :default)}
|
||||||
|
(when blur?
|
||||||
|
{:text-color colors/white-opa-70
|
||||||
|
:icon-color colors/white-opa-70}))
|
||||||
|
text]
|
||||||
|
nil)]])
|
|
@ -6,10 +6,10 @@
|
||||||
[react-native.core :as rn]))
|
[react-native.core :as rn]))
|
||||||
|
|
||||||
(def themes
|
(def themes
|
||||||
{:light {:default colors/neutral-40
|
{:light {:default colors/neutral-50
|
||||||
:success colors/success-50
|
:success colors/success-50
|
||||||
:error colors/danger-50}
|
:error colors/danger-50}
|
||||||
:dark {:default colors/neutral-60
|
:dark {:default colors/neutral-40
|
||||||
:success colors/success-60
|
:success colors/success-60
|
||||||
:error colors/danger-60}})
|
:error colors/danger-60}})
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@
|
||||||
:no-icon-color? false ;; disable tint color for icon"
|
:no-icon-color? false ;; disable tint color for icon"
|
||||||
[{:keys [type size icon text-color icon-color no-icon-color? style]} message]
|
[{:keys [type size icon text-color icon-color no-icon-color? style]} message]
|
||||||
(let [weight (if (= size :default) :regular :medium)
|
(let [weight (if (= size :default) :regular :medium)
|
||||||
|
icon-size (if (= size :default) 16 12)
|
||||||
|
icon-margin-top (if (= size :default) 2 3)
|
||||||
size (if (= size :default) :paragraph-2 :label)
|
size (if (= size :default) :paragraph-2 :label)
|
||||||
text-color (or text-color (get-color type))
|
text-color (or text-color (get-color type))
|
||||||
icon-color (or icon-color text-color)]
|
icon-color (or icon-color text-color)]
|
||||||
|
@ -37,8 +39,8 @@
|
||||||
[quo2.icons/icon icon
|
[quo2.icons/icon icon
|
||||||
{:color icon-color
|
{:color icon-color
|
||||||
:no-color no-icon-color?
|
:no-color no-icon-color?
|
||||||
:size 12
|
:size icon-size
|
||||||
:container-style {:margin-top 3}}]
|
:container-style {:margin-top icon-margin-top}}]
|
||||||
[text/text
|
[text/text
|
||||||
{:size size
|
{:size size
|
||||||
:weight weight
|
:weight weight
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
quo2.components.banners.banner.view
|
quo2.components.banners.banner.view
|
||||||
quo2.components.buttons.button
|
quo2.components.buttons.button
|
||||||
quo2.components.buttons.dynamic-button
|
quo2.components.buttons.dynamic-button
|
||||||
|
quo2.components.buttons.predictive-keyboard.view
|
||||||
quo2.components.colors.color-picker.view
|
quo2.components.colors.color-picker.view
|
||||||
quo2.components.community.community-card-view
|
quo2.components.community.community-card-view
|
||||||
quo2.components.community.community-list-view
|
quo2.components.community.community-list-view
|
||||||
|
@ -83,8 +84,6 @@
|
||||||
quo2.components.tags.token-tag
|
quo2.components.tags.token-tag
|
||||||
quo2.components.text-combinations.title.view))
|
quo2.components.text-combinations.title.view))
|
||||||
|
|
||||||
(def button quo2.components.buttons.button/button)
|
|
||||||
(def dynamic-button quo2.components.buttons.dynamic-button/dynamic-button)
|
|
||||||
(def text quo2.components.markdown.text/text)
|
(def text quo2.components.markdown.text/text)
|
||||||
(def icon quo2.components.icon/icon)
|
(def icon quo2.components.icon/icon)
|
||||||
(def separator quo2.components.separator/separator)
|
(def separator quo2.components.separator/separator)
|
||||||
|
@ -120,6 +119,11 @@
|
||||||
;;;; BANNER
|
;;;; BANNER
|
||||||
(def banner quo2.components.banners.banner.view/banner)
|
(def banner quo2.components.banners.banner.view/banner)
|
||||||
|
|
||||||
|
;;;; BUTTONS
|
||||||
|
(def button quo2.components.buttons.button/button)
|
||||||
|
(def dynamic-button quo2.components.buttons.dynamic-button/dynamic-button)
|
||||||
|
(def predictive-keyboard quo2.components.buttons.predictive-keyboard.view/view)
|
||||||
|
|
||||||
;;;; CARDS
|
;;;; CARDS
|
||||||
(def small-option-card quo2.components.onboarding.small-option-card.view/small-option-card)
|
(def small-option-card quo2.components.onboarding.small-option-card.view/small-option-card)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
[quo2.components.avatars.user-avatar.component-spec]
|
[quo2.components.avatars.user-avatar.component-spec]
|
||||||
[quo2.components.banners.banner.component-spec]
|
[quo2.components.banners.banner.component-spec]
|
||||||
[quo2.components.buttons.--tests--.buttons-component-spec]
|
[quo2.components.buttons.--tests--.buttons-component-spec]
|
||||||
|
[quo2.components.buttons.predictive-keyboard.component-spec]
|
||||||
[quo2.components.colors.color-picker.component-spec]
|
[quo2.components.colors.color-picker.component-spec]
|
||||||
[quo2.components.counter.--tests--.counter-component-spec]
|
[quo2.components.counter.--tests--.counter-component-spec]
|
||||||
[quo2.components.counter.step.component-spec]
|
[quo2.components.counter.step.component-spec]
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
(ns status-im2.contexts.quo-preview.buttons.predictive-keyboard
|
||||||
|
(:require [quo2.core :as quo]
|
||||||
|
[quo2.foundations.colors :as colors]
|
||||||
|
[react-native.blur :as blur]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||||
|
|
||||||
|
(def descriptor
|
||||||
|
[{:label "Type"
|
||||||
|
:key :type
|
||||||
|
:type :select
|
||||||
|
:options [{:key :error :value "Error"}
|
||||||
|
{:key :empty :value "Empty"}
|
||||||
|
{:key :info :value "Info"}
|
||||||
|
{:key :words :value "Words"}]}
|
||||||
|
{:label "Text"
|
||||||
|
:key :text
|
||||||
|
:type :text}
|
||||||
|
{:label "Blur"
|
||||||
|
:key :blur?
|
||||||
|
:type :boolean}])
|
||||||
|
|
||||||
|
(defn cool-preview
|
||||||
|
[]
|
||||||
|
(let [state (reagent/atom {:type :info :text "Enter 12, 18 or 24 words separated by a space"})
|
||||||
|
blur? (reagent/cursor state [:blur?])]
|
||||||
|
(fn []
|
||||||
|
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||||
|
[rn/view {:padding-bottom 150}
|
||||||
|
[preview/customizer state descriptor]
|
||||||
|
[rn/view
|
||||||
|
(when @blur?
|
||||||
|
[blur/view
|
||||||
|
{:style {:position :absolute
|
||||||
|
:left 0
|
||||||
|
:right 0
|
||||||
|
:top 0
|
||||||
|
:bottom 0
|
||||||
|
:background-color colors/neutral-80-opa-70}
|
||||||
|
:overlay-color :transparent}])
|
||||||
|
[rn/view {:padding-vertical 60 :align-items :center}
|
||||||
|
[quo/predictive-keyboard
|
||||||
|
(merge @state
|
||||||
|
{:words ["label" "label" "labor" "ladder" "lady" "lake"]
|
||||||
|
:on-press #(js/alert (str "Pressed: " %))})]]]]])))
|
||||||
|
|
||||||
|
(defn preview-predictive-keyboard
|
||||||
|
[]
|
||||||
|
[rn/view
|
||||||
|
{:background-color (colors/theme-colors
|
||||||
|
colors/white
|
||||||
|
colors/neutral-95)
|
||||||
|
:flex 1}
|
||||||
|
[rn/flat-list
|
||||||
|
{:flex 1
|
||||||
|
:keyboard-should-persist-taps :always
|
||||||
|
:header [cool-preview]
|
||||||
|
:key-fn str}]])
|
|
@ -17,6 +17,7 @@
|
||||||
[status-im2.contexts.quo-preview.banners.banner :as banner]
|
[status-im2.contexts.quo-preview.banners.banner :as banner]
|
||||||
[status-im2.contexts.quo-preview.buttons.button :as button]
|
[status-im2.contexts.quo-preview.buttons.button :as button]
|
||||||
[status-im2.contexts.quo-preview.buttons.dynamic-button :as dynamic-button]
|
[status-im2.contexts.quo-preview.buttons.dynamic-button :as dynamic-button]
|
||||||
|
[status-im2.contexts.quo-preview.buttons.predictive-keyboard :as predictive-keyboard]
|
||||||
[status-im2.contexts.quo-preview.code.snippet :as code-snippet]
|
[status-im2.contexts.quo-preview.code.snippet :as code-snippet]
|
||||||
[status-im2.contexts.quo-preview.colors.color-picker :as color-picker]
|
[status-im2.contexts.quo-preview.colors.color-picker :as color-picker]
|
||||||
[status-im2.contexts.quo-preview.community.community-card-view :as community-card]
|
[status-im2.contexts.quo-preview.community.community-card-view :as community-card]
|
||||||
|
@ -124,7 +125,10 @@
|
||||||
:component button/preview-button}
|
:component button/preview-button}
|
||||||
{:name :dynamic-button
|
{:name :dynamic-button
|
||||||
:options {:topBar {:visible true}}
|
:options {:topBar {:visible true}}
|
||||||
:component dynamic-button/preview-dynamic-button}]
|
:component dynamic-button/preview-dynamic-button}
|
||||||
|
{:name :predictive-keyboard
|
||||||
|
:options {:topBar {:visible true}}
|
||||||
|
:component predictive-keyboard/preview-predictive-keyboard}]
|
||||||
:code [{:name :snippet
|
:code [{:name :snippet
|
||||||
:options {:topBar {:visible true}}
|
:options {:topBar {:visible true}}
|
||||||
:component code-snippet/preview-code-snippet}]
|
:component code-snippet/preview-code-snippet}]
|
||||||
|
|
Loading…
Reference in New Issue