From 5f362f333f01302171629f98b1581349b7dc451c Mon Sep 17 00:00:00 2001 From: Ajay Sivan Date: Fri, 5 May 2023 20:41:57 +0530 Subject: [PATCH] quo2 predictive keyboard component (#15806) --- .../predictive_keyboard/component_spec.cljs | 20 ++++++ .../buttons/predictive_keyboard/style.cljs | 11 +++ .../buttons/predictive_keyboard/view.cljs | 71 +++++++++++++++++++ src/quo2/components/info/info_message.cljs | 18 ++--- src/quo2/core.cljs | 8 ++- src/quo2/core_spec.cljs | 1 + .../buttons/predictive_keyboard.cljs | 59 +++++++++++++++ src/status_im2/contexts/quo_preview/main.cljs | 6 +- 8 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 src/quo2/components/buttons/predictive_keyboard/component_spec.cljs create mode 100644 src/quo2/components/buttons/predictive_keyboard/style.cljs create mode 100644 src/quo2/components/buttons/predictive_keyboard/view.cljs create mode 100644 src/status_im2/contexts/quo_preview/buttons/predictive_keyboard.cljs diff --git a/src/quo2/components/buttons/predictive_keyboard/component_spec.cljs b/src/quo2/components/buttons/predictive_keyboard/component_spec.cljs new file mode 100644 index 0000000000..93f519a26e --- /dev/null +++ b/src/quo2/components/buttons/predictive_keyboard/component_spec.cljs @@ -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)))) diff --git a/src/quo2/components/buttons/predictive_keyboard/style.cljs b/src/quo2/components/buttons/predictive_keyboard/style.cljs new file mode 100644 index 0000000000..e8e4f9316c --- /dev/null +++ b/src/quo2/components/buttons/predictive_keyboard/style.cljs @@ -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}) diff --git a/src/quo2/components/buttons/predictive_keyboard/view.cljs b/src/quo2/components/buttons/predictive_keyboard/view.cljs new file mode 100644 index 0000000000..d75668c853 --- /dev/null +++ b/src/quo2/components/buttons/predictive_keyboard/view.cljs @@ -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)]]) diff --git a/src/quo2/components/info/info_message.cljs b/src/quo2/components/info/info_message.cljs index 65e9761887..2085f3be2e 100644 --- a/src/quo2/components/info/info_message.cljs +++ b/src/quo2/components/info/info_message.cljs @@ -6,10 +6,10 @@ [react-native.core :as rn])) (def themes - {:light {:default colors/neutral-40 + {:light {:default colors/neutral-50 :success colors/success-50 :error colors/danger-50} - :dark {:default colors/neutral-60 + :dark {:default colors/neutral-40 :success colors/success-60 :error colors/danger-60}}) @@ -27,18 +27,20 @@ :icon-color colors/white ;; icon color override :no-icon-color? false ;; disable tint color for icon" [{:keys [type size icon text-color icon-color no-icon-color? style]} message] - (let [weight (if (= size :default) :regular :medium) - size (if (= size :default) :paragraph-2 :label) - text-color (or text-color (get-color type)) - icon-color (or icon-color text-color)] + (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) + text-color (or text-color (get-color type)) + icon-color (or icon-color text-color)] [rn/view {:style (merge {:flex-direction :row} style)} [quo2.icons/icon icon {:color icon-color :no-color no-icon-color? - :size 12 - :container-style {:margin-top 3}}] + :size icon-size + :container-style {:margin-top icon-margin-top}}] [text/text {:size size :weight weight diff --git a/src/quo2/core.cljs b/src/quo2/core.cljs index 10eb110612..41454db17b 100644 --- a/src/quo2/core.cljs +++ b/src/quo2/core.cljs @@ -10,6 +10,7 @@ quo2.components.banners.banner.view quo2.components.buttons.button quo2.components.buttons.dynamic-button + quo2.components.buttons.predictive-keyboard.view quo2.components.colors.color-picker.view quo2.components.community.community-card-view quo2.components.community.community-list-view @@ -83,8 +84,6 @@ quo2.components.tags.token-tag 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 icon quo2.components.icon/icon) (def separator quo2.components.separator/separator) @@ -120,6 +119,11 @@ ;;;; 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 (def small-option-card quo2.components.onboarding.small-option-card.view/small-option-card) diff --git a/src/quo2/core_spec.cljs b/src/quo2/core_spec.cljs index c37286c5e5..2df2dd5b7e 100644 --- a/src/quo2/core_spec.cljs +++ b/src/quo2/core_spec.cljs @@ -3,6 +3,7 @@ [quo2.components.avatars.user-avatar.component-spec] [quo2.components.banners.banner.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.counter.--tests--.counter-component-spec] [quo2.components.counter.step.component-spec] diff --git a/src/status_im2/contexts/quo_preview/buttons/predictive_keyboard.cljs b/src/status_im2/contexts/quo_preview/buttons/predictive_keyboard.cljs new file mode 100644 index 0000000000..cc9a41c0fa --- /dev/null +++ b/src/status_im2/contexts/quo_preview/buttons/predictive_keyboard.cljs @@ -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}]]) diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index b584f4e1b9..350a7a5417 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -17,6 +17,7 @@ [status-im2.contexts.quo-preview.banners.banner :as banner] [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.predictive-keyboard :as predictive-keyboard] [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.community.community-card-view :as community-card] @@ -124,7 +125,10 @@ :component button/preview-button} {:name :dynamic-button :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 :options {:topBar {:visible true}} :component code-snippet/preview-code-snippet}]