migrating to react state. step 2 (#18905)
This commit is contained in:
parent
047e45d2a3
commit
b7bffb3bd3
|
@ -8,36 +8,36 @@
|
||||||
[quo.components.calendar.calendar.years-list.view :as years-list]
|
[quo.components.calendar.calendar.years-list.view :as years-list]
|
||||||
[quo.theme :as theme]
|
[quo.theme :as theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.number :as utils.number]))
|
[utils.number :as utils.number]))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[]
|
[{:keys [on-change start-date end-date]}]
|
||||||
(let [selected-year (reagent/atom (utils/current-year))
|
(let [theme (theme/use-theme-value)
|
||||||
selected-month (reagent/atom (utils/current-month))
|
[selected-year set-selected-year] (rn/use-state (utils/current-year))
|
||||||
on-change-year #(reset! selected-year %)
|
[selected-month set-selected-month] (rn/use-state (utils/current-month))
|
||||||
on-change-month (fn [new-date]
|
on-change-year (rn/use-callback #(set-selected-year %))
|
||||||
(reset! selected-year (utils.number/parse-int (:year new-date)))
|
on-change-month (rn/use-callback
|
||||||
(reset! selected-month (utils.number/parse-int (:month new-date))))]
|
(fn [new-date]
|
||||||
(fn [{:keys [on-change start-date end-date theme]}]
|
(set-selected-year
|
||||||
|
(utils.number/parse-int (:year new-date)))
|
||||||
|
(set-selected-month
|
||||||
|
(utils.number/parse-int (:month new-date)))))]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (style/container theme)}
|
{:style (style/container theme)}
|
||||||
[years-list/view
|
[years-list/view
|
||||||
{:on-change-year on-change-year
|
{:on-change-year on-change-year
|
||||||
:year @selected-year}]
|
:year selected-year}]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/container-main}
|
{:style style/container-main}
|
||||||
[month-picker/view
|
[month-picker/view
|
||||||
{:year @selected-year
|
{:year selected-year
|
||||||
:month @selected-month
|
:month selected-month
|
||||||
:on-change on-change-month}]
|
:on-change on-change-month}]
|
||||||
[weekdays-header/view]
|
[weekdays-header/view]
|
||||||
[days-grid/view
|
[days-grid/view
|
||||||
{:year @selected-year
|
{:year selected-year
|
||||||
:month @selected-month
|
:month selected-month
|
||||||
:start-date start-date
|
:start-date start-date
|
||||||
:end-date end-date
|
:end-date end-date
|
||||||
:on-change on-change
|
:on-change on-change
|
||||||
:customization-color :blue}]]])))
|
:customization-color :blue}]]]))
|
||||||
|
|
||||||
(def view (theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -3,13 +3,7 @@
|
||||||
[quo.components.colors.color.constants :as constants]
|
[quo.components.colors.color.constants :as constants]
|
||||||
[quo.components.colors.color.view :as color]
|
[quo.components.colors.color.view :as color]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- on-change-handler
|
|
||||||
[selected color-name on-change]
|
|
||||||
(reset! selected color-name)
|
|
||||||
(when on-change (on-change color-name)))
|
|
||||||
|
|
||||||
(defn get-item-layout
|
(defn get-item-layout
|
||||||
[_ index]
|
[_ index]
|
||||||
|
@ -18,15 +12,34 @@
|
||||||
:offset (* (+ constants/color-size 8) index)
|
:offset (* (+ constants/color-size 8) index)
|
||||||
:index index})
|
:index index})
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
"Options
|
"Options
|
||||||
- `default-selected` Default selected color name.
|
- `default-selected` Default selected color name.
|
||||||
- `on-change` Callback called when a color is selected `(fn [color-name])`.
|
- `on-change` Callback called when a color is selected `(fn [color-name])`.
|
||||||
- `blur?` Boolean to enable blur background support.}"
|
- `blur?` Boolean to enable blur background support.}"
|
||||||
[{:keys [default-selected blur? on-change feng-shui? container-style]}]
|
[{:keys [default-selected blur? on-change feng-shui? container-style]}]
|
||||||
(let [selected (reagent/atom default-selected)
|
(let [[selected set-selected] (rn/use-state default-selected)
|
||||||
{window-width :width} (rn/get-window)
|
{window-width :width} (rn/get-window)
|
||||||
ref (atom nil)]
|
ref (rn/use-ref-atom nil)
|
||||||
|
on-ref (rn/use-callback #(reset! ref %))
|
||||||
|
render-fn (rn/use-callback
|
||||||
|
(fn [color idx]
|
||||||
|
[color/view
|
||||||
|
{:selected? (= color selected)
|
||||||
|
:on-press (fn [color-name]
|
||||||
|
(.scrollToIndex ^js @ref
|
||||||
|
#js
|
||||||
|
{:animated true
|
||||||
|
:index idx
|
||||||
|
:viewPosition 0.5})
|
||||||
|
(set-selected color-name)
|
||||||
|
(when on-change (on-change color-name)))
|
||||||
|
:blur? blur?
|
||||||
|
:key color
|
||||||
|
:color color
|
||||||
|
:idx idx
|
||||||
|
:window-width window-width}])
|
||||||
|
[selected blur? on-change @ref])]
|
||||||
(rn/use-mount
|
(rn/use-mount
|
||||||
(fn []
|
(fn []
|
||||||
(js/setTimeout
|
(js/setTimeout
|
||||||
|
@ -40,32 +53,14 @@
|
||||||
:viewPosition 0.5})))))
|
:viewPosition 0.5})))))
|
||||||
50)))
|
50)))
|
||||||
[rn/flat-list
|
[rn/flat-list
|
||||||
{:ref #(reset! ref %)
|
{:ref on-ref
|
||||||
;; TODO: using :feng-shui? temporarily while b & w is being developed.
|
;; TODO: using :feng-shui? temporarily while b & w is being developed.
|
||||||
;; https://github.com/status-im/status-mobile/discussions/16676
|
;; https://github.com/status-im/status-mobile/discussions/16676
|
||||||
:data (if feng-shui?
|
:data (if feng-shui?
|
||||||
(conj colors/account-colors :feng-shui)
|
(conj colors/account-colors :feng-shui)
|
||||||
colors/account-colors)
|
colors/account-colors)
|
||||||
:render-fn (fn [color idx]
|
:render-fn render-fn
|
||||||
[color/view
|
|
||||||
{:selected? (= color @selected)
|
|
||||||
:on-press (fn [e]
|
|
||||||
(.scrollToIndex ^js @ref
|
|
||||||
#js
|
|
||||||
{:animated true
|
|
||||||
:index idx
|
|
||||||
:viewPosition 0.5})
|
|
||||||
(on-change-handler selected e on-change))
|
|
||||||
:blur? blur?
|
|
||||||
:key color
|
|
||||||
:color color
|
|
||||||
:idx idx
|
|
||||||
:window-width window-width}])
|
|
||||||
:get-item-layout get-item-layout
|
:get-item-layout get-item-layout
|
||||||
:horizontal true
|
:horizontal true
|
||||||
:shows-horizontal-scroll-indicator false
|
:shows-horizontal-scroll-indicator false
|
||||||
:content-container-style container-style}]))
|
:content-container-style container-style}]))
|
||||||
|
|
||||||
(defn view
|
|
||||||
[props]
|
|
||||||
[:f> view-internal props])
|
|
||||||
|
|
|
@ -35,12 +35,11 @@
|
||||||
(defn image
|
(defn image
|
||||||
"Same as rn/image but cache the image source in a js/Set, so the image won't
|
"Same as rn/image but cache the image source in a js/Set, so the image won't
|
||||||
flicker when re-render on android"
|
flicker when re-render on android"
|
||||||
[]
|
[props]
|
||||||
(let [loaded-source (reagent/atom nil)
|
(let [[loaded-source set-loaded-source] (rn/use-state nil)
|
||||||
on-source-loaded #(reset! loaded-source %)]
|
on-source-loaded (rn/use-callback #(set-loaded-source %))]
|
||||||
(fn [props]
|
|
||||||
(if platform/ios?
|
(if platform/ios?
|
||||||
[rn/image props]
|
[rn/image props]
|
||||||
[:<>
|
[:<>
|
||||||
[rn/image (assoc props :source @loaded-source)]
|
[rn/image (assoc props :source loaded-source)]
|
||||||
[caching-image props on-source-loaded]]))))
|
[caching-image props on-source-loaded]])))
|
||||||
|
|
|
@ -3,25 +3,23 @@
|
||||||
[quo.components.dropdowns.network-dropdown.style :as style]
|
[quo.components.dropdowns.network-dropdown.style :as style]
|
||||||
[quo.components.list-items.preview-list.view :as preview-list]
|
[quo.components.list-items.preview-list.view :as preview-list]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- internal-view
|
(defn view
|
||||||
[_ _]
|
|
||||||
(let [pressed? (reagent/atom false)]
|
|
||||||
(fn
|
|
||||||
[{:keys [on-press state] :as props} networks]
|
[{:keys [on-press state] :as props} networks]
|
||||||
|
(let [theme (quo.theme/use-theme-value)
|
||||||
|
[pressed? set-pressed] (rn/use-state false)
|
||||||
|
on-press-in (rn/use-callback #(set-pressed true))
|
||||||
|
on-press-out (rn/use-callback #(set-pressed false))]
|
||||||
[rn/pressable
|
[rn/pressable
|
||||||
{:style (style/dropdown-container (merge props {:pressed? @pressed?}))
|
{:style (style/dropdown-container (merge props {:pressed? pressed? :theme theme}))
|
||||||
:accessibility-label :network-dropdown
|
:accessibility-label :network-dropdown
|
||||||
:disabled (= state :disabled)
|
:disabled (= state :disabled)
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:on-press-in (fn [] (reset! pressed? true))
|
:on-press-in on-press-in
|
||||||
:on-press-out (fn [] (reset! pressed? false))}
|
:on-press-out on-press-out}
|
||||||
[preview-list/view
|
[preview-list/view
|
||||||
{:type :network
|
{:type :network
|
||||||
:list-size (count networks)
|
:list-size (count networks)
|
||||||
:size :size-20}
|
:size :size-20}
|
||||||
networks]])))
|
networks]]))
|
||||||
|
|
||||||
(def view (quo.theme/with-theme internal-view))
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
(def initial-spacing 56)
|
(def initial-spacing 56)
|
||||||
(def end-spacing 22)
|
(def end-spacing 22)
|
||||||
(def y-axis-label-width -33)
|
(def y-axis-label-width -33)
|
||||||
(def inspecting? (reagent/atom false))
|
|
||||||
|
|
||||||
(defn- pointer
|
(defn- pointer
|
||||||
[customization-color]
|
[customization-color]
|
||||||
|
@ -32,14 +31,9 @@
|
||||||
:pointer-color customization-color
|
:pointer-color customization-color
|
||||||
:pointer-strip-enable-gradient true})
|
:pointer-strip-enable-gradient true})
|
||||||
|
|
||||||
(defn- get-pointer-props
|
|
||||||
[pointer-props]
|
|
||||||
(let [pointer-index (.-pointerIndex ^js pointer-props)]
|
|
||||||
(reset! inspecting? (not= pointer-index -1))))
|
|
||||||
|
|
||||||
(defn- get-line-color
|
(defn- get-line-color
|
||||||
[state theme]
|
[state theme inspecting?]
|
||||||
(if @inspecting?
|
(if inspecting?
|
||||||
(colors/theme-colors colors/neutral-80-opa-40
|
(colors/theme-colors colors/neutral-80-opa-40
|
||||||
colors/white-opa-20
|
colors/white-opa-20
|
||||||
theme)
|
theme)
|
||||||
|
@ -51,11 +45,13 @@
|
||||||
colors/danger-60
|
colors/danger-60
|
||||||
theme))))
|
theme))))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[{:keys [data state customization-color theme reference-value reference-prefix decimal-separator]
|
[{:keys [data state customization-color reference-value reference-prefix decimal-separator]
|
||||||
:or {reference-prefix "$"
|
:or {reference-prefix "$"
|
||||||
decimal-separator :dot}}]
|
decimal-separator :dot}}]
|
||||||
(let [data (if (> (count data) max-data-points)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
|
[inspecting? set-inspecting] (rn/use-state false)
|
||||||
|
data (if (> (count data) max-data-points)
|
||||||
(utils/downsample-data data max-data-points)
|
(utils/downsample-data data max-data-points)
|
||||||
data)
|
data)
|
||||||
highest-value (utils/find-highest-value data)
|
highest-value (utils/find-highest-value data)
|
||||||
|
@ -64,7 +60,11 @@
|
||||||
max-value (- (utils/calculate-rounded-max highest-value) min-value)
|
max-value (- (utils/calculate-rounded-max highest-value) min-value)
|
||||||
step-value (/ max-value 4)
|
step-value (/ max-value 4)
|
||||||
width (:width (rn/get-window))
|
width (:width (rn/get-window))
|
||||||
line-color (get-line-color state theme)
|
line-color (get-line-color state theme inspecting?)
|
||||||
|
get-pointer-props (rn/use-callback
|
||||||
|
(fn [pointer-props]
|
||||||
|
(let [pointer-index (.-pointerIndex ^js pointer-props)]
|
||||||
|
(set-inspecting (not= pointer-index -1)))))
|
||||||
rules-color (colors/theme-colors colors/neutral-80-opa-10
|
rules-color (colors/theme-colors colors/neutral-80-opa-10
|
||||||
colors/white-opa-5
|
colors/white-opa-5
|
||||||
theme)
|
theme)
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
:show-strip-on-focus true
|
:show-strip-on-focus true
|
||||||
:reference-line-1-config {:color rules-color}
|
:reference-line-1-config {:color rules-color}
|
||||||
:reference-line-1-position 0
|
:reference-line-1-position 0
|
||||||
:show-reference-line-2 (and (not @inspecting?)
|
:show-reference-line-2 (and (not inspecting?)
|
||||||
(<= reference-value highest-value)
|
(<= reference-value highest-value)
|
||||||
(>= reference-value lowest-value))
|
(>= reference-value lowest-value))
|
||||||
:reference-line-2-config {:color y-axis-label-text-color
|
:reference-line-2-config {:color y-axis-label-text-color
|
||||||
|
@ -138,5 +138,3 @@
|
||||||
:x-axis-label-text-style (style/x-axis-label-text (/ width (count x-axis-label-texts))
|
:x-axis-label-text-style (style/x-axis-label-text (/ width (count x-axis-label-texts))
|
||||||
y-axis-label-text-color)
|
y-axis-label-text-color)
|
||||||
:x-axis-label-texts x-axis-label-texts}]]))
|
:x-axis-label-texts x-axis-label-texts}]]))
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
|
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
|
||||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||||
:placeholder-text-color
|
:placeholder-text-color
|
||||||
colors/neutral-40)))
|
colors/neutral-30)))
|
||||||
|
|
||||||
(h/test "on focus with blur? true"
|
(h/test "on focus with blur? true"
|
||||||
(with-redefs [clipboard/get-string #(% "")]
|
(with-redefs [clipboard/get-string #(% "")]
|
||||||
|
@ -30,27 +30,22 @@
|
||||||
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
|
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
|
||||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||||
:placeholder-text-color
|
:placeholder-text-color
|
||||||
colors/neutral-80-opa-40)))
|
colors/neutral-80-opa-20)))
|
||||||
|
|
||||||
(h/test "scanned value is properly set"
|
(h/test "default value is properly set"
|
||||||
(let [on-change-text (h/mock-fn)
|
(let [default-value "default-value"]
|
||||||
scanned-value "scanned-value"]
|
|
||||||
(with-redefs [clipboard/get-string #(% "")]
|
(with-redefs [clipboard/get-string #(% "")]
|
||||||
(h/render [address-input/address-input
|
(h/render [address-input/address-input
|
||||||
{:scanned-value scanned-value
|
{:default-value default-value
|
||||||
:on-change-text on-change-text
|
|
||||||
:ens-regex ens-regex}])
|
:ens-regex ens-regex}])
|
||||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
|
||||||
(.then (fn []
|
|
||||||
(h/was-called-with on-change-text scanned-value)
|
|
||||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||||
:default-value
|
:value
|
||||||
scanned-value)))))))
|
default-value))))
|
||||||
|
|
||||||
(h/test "clear icon is shown when input has text"
|
(h/test "clear icon is shown when input has text"
|
||||||
(with-redefs [clipboard/get-string #(% "")]
|
(with-redefs [clipboard/get-string #(% "")]
|
||||||
(h/render [address-input/address-input
|
(h/render [address-input/address-input
|
||||||
{:scanned-value "scanned value"
|
{:default-value "default value"
|
||||||
:ens-regex ens-regex}])
|
:ens-regex ens-regex}])
|
||||||
(-> (h/wait-for #(h/get-by-label-text :clear-button-container))
|
(-> (h/wait-for #(h/get-by-label-text :clear-button-container))
|
||||||
(.then #(h/is-truthy (h/get-by-label-text :clear-button))))))
|
(.then #(h/is-truthy (h/get-by-label-text :clear-button))))))
|
||||||
|
@ -58,7 +53,7 @@
|
||||||
(h/test "on blur with text and blur? false"
|
(h/test "on blur with text and blur? false"
|
||||||
(with-redefs [clipboard/get-string #(% "")]
|
(with-redefs [clipboard/get-string #(% "")]
|
||||||
(h/render [address-input/address-input
|
(h/render [address-input/address-input
|
||||||
{:scanned-value "scanned value"
|
{:default-value "default value"
|
||||||
:ens-regex ens-regex}])
|
:ens-regex ens-regex}])
|
||||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||||
(.then (fn []
|
(.then (fn []
|
||||||
|
@ -71,7 +66,7 @@
|
||||||
(h/test "on blur with text blur? true"
|
(h/test "on blur with text blur? true"
|
||||||
(with-redefs [clipboard/get-string #(% "")]
|
(with-redefs [clipboard/get-string #(% "")]
|
||||||
(h/render [address-input/address-input
|
(h/render [address-input/address-input
|
||||||
{:scanned-value "scanned value"
|
{:default-value "default value"
|
||||||
:blur? true
|
:blur? true
|
||||||
:ens-regex ens-regex}])
|
:ens-regex ens-regex}])
|
||||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||||
|
@ -106,7 +101,7 @@
|
||||||
(let [on-clear (h/mock-fn)]
|
(let [on-clear (h/mock-fn)]
|
||||||
(with-redefs [clipboard/get-string #(% "")]
|
(with-redefs [clipboard/get-string #(% "")]
|
||||||
(h/render [address-input/address-input
|
(h/render [address-input/address-input
|
||||||
{:scanned-value "scanned value"
|
{:default-value "default value"
|
||||||
:on-clear on-clear
|
:on-clear on-clear
|
||||||
:ens-regex ens-regex}])
|
:ens-regex ens-regex}])
|
||||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||||
|
@ -148,7 +143,7 @@
|
||||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||||
(.then (fn []
|
(.then (fn []
|
||||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||||
:default-value
|
:value
|
||||||
clipboard)))))))
|
clipboard)))))))
|
||||||
|
|
||||||
(h/test "ENS loading state and call on-detect-ens"
|
(h/test "ENS loading state and call on-detect-ens"
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
[react-native.clipboard :as clipboard]
|
[react-native.clipboard :as clipboard]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
(defn- icon-color
|
(defn- icon-color
|
||||||
|
@ -55,73 +54,90 @@
|
||||||
(and (not= status :default) (not blur?))
|
(and (not= status :default) (not blur?))
|
||||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)))
|
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)))
|
||||||
|
|
||||||
(defn- f-address-input-internal
|
(defn address-input
|
||||||
[]
|
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan
|
||||||
(let [status (reagent/atom :default)
|
|
||||||
value (reagent/atom "")
|
|
||||||
focused? (atom false)]
|
|
||||||
(fn [{:keys [scanned-value theme blur? on-change-text on-blur on-focus on-clear on-scan
|
|
||||||
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
|
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
|
||||||
valid-ens-or-address? container-style]}]
|
valid-ens-or-address? container-style]}]
|
||||||
(let [on-change (fn [text]
|
(let [theme (quo.theme/use-theme-value)
|
||||||
(when (not= @value text)
|
[status set-status] (rn/use-state :default)
|
||||||
|
value (rn/use-ref-atom nil)
|
||||||
|
[_ trigger-render-value] (rn/use-state @value)
|
||||||
|
[focused? set-focused] (rn/use-state false)
|
||||||
|
on-change (rn/use-callback
|
||||||
|
(fn [text]
|
||||||
(let [address? (when address-regex
|
(let [address? (when address-regex
|
||||||
(boolean (re-matches address-regex text)))
|
(boolean (re-matches address-regex text)))
|
||||||
ens? (when ens-regex
|
ens? (when ens-regex
|
||||||
(boolean (re-matches ens-regex text)))]
|
(boolean (re-matches ens-regex text)))]
|
||||||
(if (> (count text) 0)
|
|
||||||
(reset! status :typing)
|
|
||||||
(reset! status :active))
|
|
||||||
(reset! value text)
|
(reset! value text)
|
||||||
|
(if (> (count text) 0)
|
||||||
|
(set-status :typing)
|
||||||
|
(set-status :active))
|
||||||
(when on-change-text
|
(when on-change-text
|
||||||
(on-change-text text))
|
(on-change-text text))
|
||||||
(when (and on-detect-ens ens?)
|
(when (and on-detect-ens ens?)
|
||||||
(reset! status :loading)
|
(set-status :loading)
|
||||||
(on-detect-ens text #(reset! status :typing)))
|
(on-detect-ens text #(set-status :typing)))
|
||||||
(when (and address? on-detect-address)
|
(when (and address? on-detect-address)
|
||||||
(reset! status :loading)
|
(set-status :loading)
|
||||||
(on-detect-address text))
|
(on-detect-address text))
|
||||||
(when (and (not address?)
|
(when (and (not address?)
|
||||||
(not ens?)
|
(not ens?)
|
||||||
on-detect-unclassified)
|
on-detect-unclassified)
|
||||||
(on-detect-unclassified text)))))
|
(on-detect-unclassified text)))))
|
||||||
on-paste (fn []
|
set-value (rn/use-callback
|
||||||
|
(fn [new-value]
|
||||||
|
(reset! value new-value)
|
||||||
|
(on-change new-value)
|
||||||
|
(trigger-render-value new-value)))
|
||||||
|
on-paste (rn/use-callback
|
||||||
|
(fn []
|
||||||
(clipboard/get-string
|
(clipboard/get-string
|
||||||
(fn [clipboard]
|
(fn [clipboard]
|
||||||
(when-not (empty? clipboard)
|
(when-not (empty? clipboard)
|
||||||
(on-change clipboard)
|
(set-value clipboard))))))
|
||||||
(reset! value clipboard)))))
|
on-clear (rn/use-callback
|
||||||
on-clear (fn []
|
(fn []
|
||||||
(reset! value "")
|
(set-value "")
|
||||||
(reset! status (if @focused? :active :default))
|
(set-status (if focused? :active :default))
|
||||||
(when on-change-text
|
(when on-change-text
|
||||||
(on-change-text ""))
|
(on-change-text ""))
|
||||||
(when on-clear
|
(when on-clear
|
||||||
(on-clear)))
|
(on-clear)))
|
||||||
on-scan #(when on-scan
|
[focused?])
|
||||||
(on-scan))
|
on-clear (rn/use-callback
|
||||||
on-focus (fn []
|
(fn []
|
||||||
|
(set-value "")
|
||||||
|
(set-status (if focused? :active :default))
|
||||||
|
(when on-change-text
|
||||||
|
(on-change-text ""))
|
||||||
|
(when on-clear
|
||||||
|
(on-clear)))
|
||||||
|
[focused?])
|
||||||
|
on-scan (when on-scan (rn/use-callback #(on-scan set-value)))
|
||||||
|
on-focus (rn/use-callback
|
||||||
|
(fn []
|
||||||
(when (= (count @value) 0)
|
(when (= (count @value) 0)
|
||||||
(reset! status :active))
|
(set-status :active))
|
||||||
(reset! focused? true)
|
(set-focused true)
|
||||||
(when on-focus (on-focus)))
|
(when on-focus (on-focus))))
|
||||||
on-blur (fn []
|
on-blur (rn/use-callback
|
||||||
(when (= @status :active)
|
(fn []
|
||||||
(reset! status :default))
|
(when (= status :active)
|
||||||
(reset! focused? false)
|
(set-status :default))
|
||||||
|
(set-focused false)
|
||||||
(when on-blur (on-blur)))
|
(when on-blur (on-blur)))
|
||||||
placeholder-text-color (get-placeholder-text-color @status theme blur?)]
|
[status])
|
||||||
(rn/use-effect (fn []
|
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
|
||||||
(when-not (empty? scanned-value)
|
[status theme blur?])]
|
||||||
(on-change scanned-value)))
|
(rn/use-mount #(on-change (or default-value "")))
|
||||||
[scanned-value])
|
|
||||||
[rn/view {:style (style/container container-style)}
|
[rn/view {:style (style/container container-style)}
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
{:accessibility-label :address-text-input
|
{:accessibility-label :address-text-input
|
||||||
:style (style/input-text theme)
|
:style (style/input-text theme)
|
||||||
:placeholder (i18n/label :t/name-ens-or-address)
|
:placeholder (i18n/label :t/name-ens-or-address)
|
||||||
:placeholder-text-color placeholder-text-color
|
:placeholder-text-color placeholder-text-color
|
||||||
:default-value @value
|
:value @value
|
||||||
:auto-complete (when platform/ios? :off)
|
:auto-complete (when platform/ios? :off)
|
||||||
:auto-capitalize :none
|
:auto-capitalize :none
|
||||||
:auto-correct false
|
:auto-correct false
|
||||||
|
@ -130,8 +146,8 @@
|
||||||
:on-focus on-focus
|
:on-focus on-focus
|
||||||
:on-blur on-blur
|
:on-blur on-blur
|
||||||
:on-change-text on-change}]
|
:on-change-text on-change}]
|
||||||
(when (or (= @status :default)
|
(when (or (= status :default)
|
||||||
(= @status :active))
|
(= status :active))
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/buttons-container
|
{:style style/buttons-container
|
||||||
:accessibility-label :paste-scan-buttons-container}
|
:accessibility-label :paste-scan-buttons-container}
|
||||||
|
@ -143,6 +159,7 @@
|
||||||
:inner-style (style/accessory-button blur? theme)
|
:inner-style (style/accessory-button blur? theme)
|
||||||
:on-press on-paste}
|
:on-press on-paste}
|
||||||
(i18n/label :t/paste)]
|
(i18n/label :t/paste)]
|
||||||
|
(when on-scan
|
||||||
[button/button
|
[button/button
|
||||||
{:accessibility-label :scan-button
|
{:accessibility-label :scan-button
|
||||||
:icon-only? true
|
:icon-only? true
|
||||||
|
@ -150,8 +167,8 @@
|
||||||
:size 24
|
:size 24
|
||||||
:inner-style (style/accessory-button blur? theme)
|
:inner-style (style/accessory-button blur? theme)
|
||||||
:on-press on-scan}
|
:on-press on-scan}
|
||||||
:main-icons/scan]])
|
:main-icons/scan])])
|
||||||
(when (= @status :typing)
|
(when (= status :typing)
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/buttons-container
|
{:style style/buttons-container
|
||||||
:accessibility-label :clear-button-container}
|
:accessibility-label :clear-button-container}
|
||||||
|
@ -159,20 +176,13 @@
|
||||||
{:on-press on-clear
|
{:on-press on-clear
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:theme theme}]])
|
:theme theme}]])
|
||||||
(when (and (= @status :loading) (not valid-ens-or-address?))
|
(when (and (= status :loading) (not valid-ens-or-address?))
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/buttons-container
|
{:style style/buttons-container
|
||||||
:accessibility-label :loading-button-container}
|
:accessibility-label :loading-button-container}
|
||||||
[loading-icon blur? theme]])
|
[loading-icon blur? theme]])
|
||||||
(when (and (= @status :loading) valid-ens-or-address?)
|
(when (and (= status :loading) valid-ens-or-address?)
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/buttons-container
|
{:style style/buttons-container
|
||||||
:accessibility-label :positive-button-container}
|
:accessibility-label :positive-button-container}
|
||||||
[positive-state-icon theme]])]))))
|
[positive-state-icon theme]])]))
|
||||||
|
|
||||||
(defn address-input-internal
|
|
||||||
[props]
|
|
||||||
[:f> f-address-input-internal props])
|
|
||||||
|
|
||||||
(def address-input
|
|
||||||
(quo.theme/with-theme address-input-internal))
|
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- label-&-counter
|
(defn- label-&-counter
|
||||||
[{:keys [label current-chars char-limit variant-colors]}]
|
[{:keys [label current-chars char-limit variant-colors]}]
|
||||||
|
@ -61,31 +60,36 @@
|
||||||
:container-style])
|
:container-style])
|
||||||
|
|
||||||
(defn- base-input
|
(defn- base-input
|
||||||
[{:keys [on-change-text on-char-limit-reach weight default-value]}]
|
[{:keys [blur? theme error? right-icon left-icon disabled? small? button
|
||||||
(let [status (reagent/atom :default)
|
label char-limit multiline? clearable? on-focus on-blur container-style
|
||||||
internal-on-focus #(reset! status :focus)
|
on-change-text on-char-limit-reach weight default-value]
|
||||||
internal-on-blur #(reset! status :default)
|
:as props}]
|
||||||
multiple-lines? (reagent/atom false)
|
(let [[status set-status] (rn/use-state :default)
|
||||||
set-multiple-lines! #(let [height (oops/oget % "nativeEvent.contentSize.height")
|
internal-on-focus (rn/use-callback #(set-status :focus))
|
||||||
|
internal-on-blur (rn/use-callback #(set-status :default))
|
||||||
|
[multiple-lines?
|
||||||
|
set-multiple-lines] (rn/use-state false)
|
||||||
|
on-content-size-change (rn/use-callback
|
||||||
|
(fn [event]
|
||||||
|
(let [height (oops/oget event "nativeEvent.contentSize.height")
|
||||||
;; In Android height comes with padding
|
;; In Android height comes with padding
|
||||||
min-height (if platform/android? 40 22)]
|
min-height (if platform/android? 40 22)]
|
||||||
(if (> height min-height)
|
(if (> height min-height)
|
||||||
(reset! multiple-lines? true)
|
(set-multiple-lines true)
|
||||||
(reset! multiple-lines? false)))
|
(set-multiple-lines false)))))
|
||||||
char-count (reagent/atom (count default-value))
|
[char-count
|
||||||
update-char-limit! (fn [new-text char-limit]
|
set-char-count] (rn/use-state (count default-value))
|
||||||
|
on-change-text (rn/use-callback
|
||||||
|
(fn [new-text]
|
||||||
(when on-change-text (on-change-text new-text))
|
(when on-change-text (on-change-text new-text))
|
||||||
(let [amount-chars (count new-text)]
|
(let [amount-chars (count new-text)]
|
||||||
(reset! char-count amount-chars)
|
(set-char-count amount-chars)
|
||||||
(when (and (>= amount-chars char-limit) on-char-limit-reach)
|
(when (and (>= amount-chars char-limit) on-char-limit-reach)
|
||||||
(on-char-limit-reach amount-chars))))]
|
(on-char-limit-reach amount-chars)))))
|
||||||
(fn [{:keys [blur? theme error? right-icon left-icon disabled? small? button
|
status-kw (cond
|
||||||
label char-limit multiline? clearable? on-focus on-blur container-style]
|
|
||||||
:as props}]
|
|
||||||
(let [status-kw (cond
|
|
||||||
disabled? :disabled
|
disabled? :disabled
|
||||||
error? :error
|
error? :error
|
||||||
:else @status)
|
:else status)
|
||||||
colors-by-status (style/status-colors status-kw blur? theme)
|
colors-by-status (style/status-colors status-kw blur? theme)
|
||||||
variant-colors (style/variants-colors blur? theme)
|
variant-colors (style/variants-colors blur? theme)
|
||||||
clean-props (apply dissoc props custom-props)]
|
clean-props (apply dissoc props custom-props)]
|
||||||
|
@ -94,7 +98,7 @@
|
||||||
[label-&-counter
|
[label-&-counter
|
||||||
{:variant-colors variant-colors
|
{:variant-colors variant-colors
|
||||||
:label label
|
:label label
|
||||||
:current-chars @char-count
|
:current-chars char-count
|
||||||
:char-limit char-limit}])
|
:char-limit char-limit}])
|
||||||
[rn/view {:style (style/input-container colors-by-status small? disabled?)}
|
[rn/view {:style (style/input-container colors-by-status small? disabled?)}
|
||||||
(when-let [{:keys [icon-name]} left-icon]
|
(when-let [{:keys [icon-name]} left-icon]
|
||||||
|
@ -103,7 +107,7 @@
|
||||||
:small? small?
|
:small? small?
|
||||||
:icon-name icon-name}])
|
:icon-name icon-name}])
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
(cond-> {:style (style/input colors-by-status small? @multiple-lines? weight)
|
(cond-> {:style (style/input colors-by-status small? multiple-lines? weight)
|
||||||
:accessibility-label :input
|
:accessibility-label :input
|
||||||
:placeholder-text-color (:placeholder colors-by-status)
|
:placeholder-text-color (:placeholder colors-by-status)
|
||||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||||
|
@ -117,8 +121,8 @@
|
||||||
(internal-on-blur))}
|
(internal-on-blur))}
|
||||||
:always (merge clean-props)
|
:always (merge clean-props)
|
||||||
multiline? (assoc :multiline true
|
multiline? (assoc :multiline true
|
||||||
:on-content-size-change set-multiple-lines!)
|
:on-content-size-change on-content-size-change)
|
||||||
char-limit (assoc :on-change-text #(update-char-limit! % char-limit)))]
|
char-limit (assoc :on-change-text on-change-text))]
|
||||||
(when-let [{:keys [on-press icon-name style-fn]} right-icon]
|
(when-let [{:keys [on-press icon-name style-fn]} right-icon]
|
||||||
[right-accessory
|
[right-accessory
|
||||||
{:variant-colors variant-colors
|
{:variant-colors variant-colors
|
||||||
|
@ -127,7 +131,7 @@
|
||||||
:icon-style-fn style-fn
|
:icon-style-fn style-fn
|
||||||
:icon-name icon-name
|
:icon-name icon-name
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(when clearable? (reset! char-count 0))
|
(when clearable? (set-char-count 0))
|
||||||
(on-press))}])
|
(on-press))}])
|
||||||
(when-let [{:keys [on-press text]} button]
|
(when-let [{:keys [on-press text]} button]
|
||||||
[right-button
|
[right-button
|
||||||
|
@ -136,24 +140,24 @@
|
||||||
:small? small?
|
:small? small?
|
||||||
:disabled? disabled?
|
:disabled? disabled?
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:text text}])]]))))
|
:text text}])]]))
|
||||||
|
|
||||||
(defn- password-input
|
(defn- password-input
|
||||||
[{:keys [default-shown?]
|
[{:keys [default-shown?]
|
||||||
:or {default-shown? false}}]
|
:or {default-shown? false}
|
||||||
(let [password-shown? (reagent/atom default-shown?)]
|
:as props}]
|
||||||
(fn [props]
|
(let [[password-shown? set-password-shown] (rn/use-state default-shown?)]
|
||||||
[base-input
|
[base-input
|
||||||
(assoc props
|
(assoc props
|
||||||
:accessibility-label :password-input
|
:accessibility-label :password-input
|
||||||
:auto-capitalize :none
|
:auto-capitalize :none
|
||||||
:auto-complete :password
|
:auto-complete :password
|
||||||
:secure-text-entry (not @password-shown?)
|
:secure-text-entry (not password-shown?)
|
||||||
:right-icon {:style-fn style/password-icon
|
:right-icon {:style-fn style/password-icon
|
||||||
:icon-name (if @password-shown? :i/hide-password :i/reveal)
|
:icon-name (if password-shown? :i/hide-password :i/reveal)
|
||||||
:on-press #(swap! password-shown? not)})])))
|
:on-press #(set-password-shown (not password-shown?))})]))
|
||||||
|
|
||||||
(defn input-internal
|
(defn input
|
||||||
"This input supports the following properties:
|
"This input supports the following properties:
|
||||||
- :type - Can be `:text`(default) or `:password`.
|
- :type - Can be `:text`(default) or `:password`.
|
||||||
- :blur? - Boolean to set the blur color variant.
|
- :blur? - Boolean to set the blur color variant.
|
||||||
|
@ -177,7 +181,7 @@
|
||||||
- :on-change-text
|
- :on-change-text
|
||||||
...
|
...
|
||||||
"
|
"
|
||||||
[{:keys [type clearable? on-clear on-change-text icon-name]
|
[{:keys [type clearable? on-clear icon-name]
|
||||||
:or {type :text}
|
:or {type :text}
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [base-props (cond-> props
|
(let [base-props (cond-> props
|
||||||
|
@ -185,13 +189,7 @@
|
||||||
clearable? (assoc :right-icon
|
clearable? (assoc :right-icon
|
||||||
{:style-fn style/clear-icon
|
{:style-fn style/clear-icon
|
||||||
:icon-name :i/clear
|
:icon-name :i/clear
|
||||||
:on-press #(when on-clear (on-clear))})
|
:on-press #(when on-clear (on-clear))}))]
|
||||||
on-change-text (assoc :on-change-text
|
|
||||||
(fn [new-text]
|
|
||||||
(on-change-text new-text)
|
|
||||||
(reagent/flush))))]
|
|
||||||
(if (= type :password)
|
(if (= type :password)
|
||||||
[password-input base-props]
|
[password-input base-props]
|
||||||
[base-input base-props])))
|
[base-input base-props])))
|
||||||
|
|
||||||
(def input (quo.theme/with-theme input-internal))
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[quo.components.inputs.recovery-phrase.style :as style]
|
[quo.components.inputs.recovery-phrase.style :as style]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(def ^:private custom-props
|
(def ^:private custom-props
|
||||||
[:customization-color :theme :blur? :cursor-color :multiline :on-focus :on-blur
|
[:customization-color :theme :blur? :cursor-color :multiline :on-focus :on-blur
|
||||||
|
@ -38,12 +37,8 @@
|
||||||
:idx 0})
|
:idx 0})
|
||||||
:result)))
|
:result)))
|
||||||
|
|
||||||
(defn recovery-phrase-input-internal
|
(defn recovery-phrase-input
|
||||||
[_ _]
|
[{:keys [customization-color blur? on-focus on-blur mark-errors?
|
||||||
(let [state (reagent/atom :default)
|
|
||||||
set-focused #(reset! state :focused)
|
|
||||||
set-default #(reset! state :default)]
|
|
||||||
(fn [{:keys [customization-color theme blur? on-focus on-blur mark-errors?
|
|
||||||
error-pred-current-word error-pred-written-words word-limit
|
error-pred-current-word error-pred-written-words word-limit
|
||||||
container-style]
|
container-style]
|
||||||
:or {customization-color :blue
|
:or {customization-color :blue
|
||||||
|
@ -52,21 +47,27 @@
|
||||||
error-pred-written-words (constantly false)}
|
error-pred-written-words (constantly false)}
|
||||||
:as props}
|
:as props}
|
||||||
text]
|
text]
|
||||||
(let [extra-props (apply dissoc props custom-props)]
|
(let [theme (quo.theme/use-theme-value)
|
||||||
|
[state set-state] (rn/use-state :default)
|
||||||
|
on-focus (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-state :focused)
|
||||||
|
(when on-focus (on-focus))))
|
||||||
|
on-blur (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-state :default)
|
||||||
|
(when on-blur (on-blur))))
|
||||||
|
extra-props (apply dissoc props custom-props)]
|
||||||
[rn/view {:style (style/container container-style)}
|
[rn/view {:style (style/container container-style)}
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
(merge {:accessibility-label :recovery-phrase-input
|
(merge {:accessibility-label :recovery-phrase-input
|
||||||
:style (style/input)
|
:style (style/input)
|
||||||
:placeholder-text-color (style/placeholder-color @state theme blur?)
|
:placeholder-text-color (style/placeholder-color state theme blur?)
|
||||||
:cursor-color (style/cursor-color customization-color theme)
|
:cursor-color (style/cursor-color customization-color theme)
|
||||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||||
:multiline true
|
:multiline true
|
||||||
:on-focus (fn []
|
:on-focus on-focus
|
||||||
(set-focused)
|
:on-blur on-blur}
|
||||||
(when on-focus (on-focus)))
|
|
||||||
:on-blur (fn []
|
|
||||||
(set-default)
|
|
||||||
(when on-blur (on-blur)))}
|
|
||||||
extra-props)
|
extra-props)
|
||||||
(if mark-errors?
|
(if mark-errors?
|
||||||
(mark-error-words {:pred-last-word error-pred-current-word
|
(mark-error-words {:pred-last-word error-pred-current-word
|
||||||
|
@ -74,6 +75,4 @@
|
||||||
:text text
|
:text text
|
||||||
:word-limit word-limit
|
:word-limit word-limit
|
||||||
:theme theme})
|
:theme theme})
|
||||||
text)]]))))
|
text)]]))
|
||||||
|
|
||||||
(def recovery-phrase-input (quo.theme/with-theme recovery-phrase-input-internal))
|
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
[quo.components.icon :as icon]
|
[quo.components.icon :as icon]
|
||||||
[quo.components.inputs.search-input.style :as style]
|
[quo.components.inputs.search-input.style :as style]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(def ^:private tag-separator [rn/view {:style style/tag-separator}])
|
(def ^:private tag-separator [rn/view {:style style/tag-separator}])
|
||||||
|
|
||||||
|
@ -41,54 +40,52 @@
|
||||||
text-input))
|
text-input))
|
||||||
|
|
||||||
(defn search-input
|
(defn search-input
|
||||||
[{:keys [value]}]
|
[{:keys [value tags disabled? blur? on-change-text customization-color
|
||||||
(let [state (reagent/atom :default)
|
|
||||||
set-active #(reset! state :active)
|
|
||||||
set-default #(reset! state :default)
|
|
||||||
scroll-view-ref (atom nil)
|
|
||||||
use-value? (boolean value)]
|
|
||||||
(fn [{:keys [value tags disabled? blur? on-change-text customization-color
|
|
||||||
on-clear on-focus on-blur override-theme container-style]
|
on-clear on-focus on-blur override-theme container-style]
|
||||||
:or {customization-color :blue}
|
:or {customization-color :blue}
|
||||||
:as props}
|
:as props}
|
||||||
& children]
|
& children]
|
||||||
(let [clean-props (apply dissoc props props-to-remove)]
|
(let [[state set-state] (rn/use-state :default)
|
||||||
|
on-focus (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-state :active)
|
||||||
|
(when on-focus (on-focus))))
|
||||||
|
on-blur (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(set-state :default)
|
||||||
|
(when on-blur (on-blur))))
|
||||||
|
scroll-view-ref (rn/use-ref-atom nil)
|
||||||
|
on-scroll-view-ref (rn/use-callback #(reset! scroll-view-ref %))
|
||||||
|
on-key-press (rn/use-callback #(handle-backspace % @scroll-view-ref))
|
||||||
|
use-value? (boolean value)
|
||||||
|
clean-props (apply dissoc props props-to-remove)]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:accessibility-label :search-input
|
{:accessibility-label :search-input
|
||||||
:style (style/container container-style)}
|
:style (style/container container-style)}
|
||||||
[rn/scroll-view
|
[rn/scroll-view
|
||||||
{:ref #(reset! scroll-view-ref %)
|
{:ref on-scroll-view-ref
|
||||||
:style style/scroll-container
|
:style style/scroll-container
|
||||||
:content-container-style style/scroll-content
|
:content-container-style style/scroll-content
|
||||||
:horizontal true
|
:horizontal true
|
||||||
:shows-horizontal-scroll-indicator false}
|
:shows-horizontal-scroll-indicator false}
|
||||||
(when (seq tags)
|
(when (seq tags)
|
||||||
[inner-tags tags])
|
[inner-tags tags])
|
||||||
|
|
||||||
(add-children
|
(add-children
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
(cond-> {:style (style/input-text disabled?)
|
(cond-> {:style (style/input-text disabled?)
|
||||||
:cursor-color (style/cursor customization-color override-theme)
|
:cursor-color (style/cursor customization-color override-theme)
|
||||||
:placeholder-text-color (style/placeholder-color @state blur? override-theme)
|
:placeholder-text-color (style/placeholder-color state blur? override-theme)
|
||||||
:editable (not disabled?)
|
:editable (not disabled?)
|
||||||
:on-key-press #(handle-backspace % @scroll-view-ref)
|
:on-key-press on-key-press
|
||||||
:keyboard-appearance (colors/theme-colors :light :dark override-theme)
|
:keyboard-appearance (colors/theme-colors :light :dark override-theme)
|
||||||
:on-change-text (fn [new-text]
|
:on-change-text on-change-text
|
||||||
(when on-change-text
|
:on-focus on-focus
|
||||||
(on-change-text new-text))
|
:on-blur on-blur}
|
||||||
(reagent/flush))
|
|
||||||
:on-focus (fn []
|
|
||||||
(set-active)
|
|
||||||
(when on-focus (on-focus)))
|
|
||||||
:on-blur (fn []
|
|
||||||
(set-default)
|
|
||||||
(when on-blur (on-blur)))}
|
|
||||||
use-value? (assoc :value value)
|
use-value? (assoc :value value)
|
||||||
(seq clean-props) (merge clean-props))]
|
(seq clean-props) (merge clean-props))]
|
||||||
(when-not use-value? children))]
|
(when-not use-value? children))]
|
||||||
|
|
||||||
(when (or (seq value) (seq children))
|
(when (or (seq value) (seq children))
|
||||||
[clear-button
|
[clear-button
|
||||||
{:on-press on-clear
|
{:on-press on-clear
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:override-theme override-theme}])]))))
|
:override-theme override-theme}])]))
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
[quo.components.inputs.title-input.style :as style]
|
[quo.components.inputs.title-input.style :as style]
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- pad-0
|
(defn- pad-0
|
||||||
[value]
|
[value]
|
||||||
|
@ -13,36 +12,37 @@
|
||||||
(str 0 value)
|
(str 0 value)
|
||||||
value))
|
value))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[{:keys [blur?
|
[{:keys [blur? on-change-text auto-focus placeholder max-length default-value return-key-type
|
||||||
on-change-text
|
size on-focus on-blur container-style customization-color disabled?]
|
||||||
auto-focus
|
|
||||||
placeholder
|
|
||||||
max-length
|
|
||||||
default-value
|
|
||||||
return-key-type
|
|
||||||
size
|
|
||||||
theme
|
|
||||||
on-focus
|
|
||||||
on-blur
|
|
||||||
container-style]
|
|
||||||
:or {max-length 0
|
:or {max-length 0
|
||||||
auto-focus false
|
auto-focus false
|
||||||
default-value ""}}]
|
default-value ""}}]
|
||||||
(let [focused? (reagent/atom auto-focus)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
value (reagent/atom default-value)
|
[focused? set-focused] (rn/use-state auto-focus)
|
||||||
input-ref (atom nil)
|
[value set-value] (rn/use-state default-value)
|
||||||
on-change (fn [v]
|
input-ref (rn/use-ref-atom nil)
|
||||||
(reset! value v)
|
on-inpur-ref (rn/use-callback #(reset! input-ref %))
|
||||||
(when on-change-text
|
on-press (rn/use-callback
|
||||||
(on-change-text v)))]
|
#(when-not disabled? (.focus ^js @input-ref))
|
||||||
(fn [{:keys [customization-color disabled?]}]
|
[disabled?])
|
||||||
|
on-change (rn/use-callback
|
||||||
|
(fn [v]
|
||||||
|
(set-value v)
|
||||||
|
(when on-change-text (on-change-text v))))
|
||||||
|
on-focus (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(when (fn? on-focus) (on-focus))
|
||||||
|
(set-focused true)))
|
||||||
|
on-blur (rn/use-callback
|
||||||
|
(fn []
|
||||||
|
(when (fn? on-blur) (on-blur))
|
||||||
|
(set-focused false)))]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (merge (style/container disabled?) container-style)}
|
{:style (merge (style/container disabled?) container-style)}
|
||||||
[rn/view {:style style/text-input-container}
|
[rn/view {:style style/text-input-container}
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
{:style
|
{:style (text/text-style
|
||||||
(text/text-style
|
|
||||||
{:size (or size :heading-1)
|
{:size (or size :heading-1)
|
||||||
:weight :semi-bold
|
:weight :semi-bold
|
||||||
:style (style/title-text theme)})
|
:style (style/title-text theme)})
|
||||||
|
@ -50,44 +50,32 @@
|
||||||
:accessibility-label :profile-title-input
|
:accessibility-label :profile-title-input
|
||||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||||
:return-key-type return-key-type
|
:return-key-type return-key-type
|
||||||
:on-focus (fn []
|
:on-focus on-focus
|
||||||
(when (fn? on-focus)
|
:on-blur on-blur
|
||||||
(on-focus))
|
|
||||||
(reset! focused? true))
|
|
||||||
:on-blur (fn []
|
|
||||||
(when (fn? on-blur)
|
|
||||||
(on-blur))
|
|
||||||
(reset! focused? false))
|
|
||||||
:auto-focus auto-focus
|
:auto-focus auto-focus
|
||||||
:input-mode :text
|
:input-mode :text
|
||||||
:on-change-text on-change
|
:on-change-text on-change
|
||||||
:editable (not disabled?)
|
:editable (not disabled?)
|
||||||
:max-length max-length
|
:max-length max-length
|
||||||
:placeholder placeholder
|
:placeholder placeholder
|
||||||
:ref #(reset! input-ref %)
|
:ref on-inpur-ref
|
||||||
:selection-color (style/get-selection-color customization-color blur? theme)
|
:selection-color (style/get-selection-color customization-color blur? theme)
|
||||||
:placeholder-text-color (if @focused?
|
:placeholder-text-color (if focused?
|
||||||
(style/get-focused-placeholder-color blur? theme)
|
(style/get-focused-placeholder-color blur? theme)
|
||||||
(style/get-placeholder-color blur? theme))}]]
|
(style/get-placeholder-color blur? theme))}]]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (style/counter-container @focused?)}
|
{:style (style/counter-container focused?)}
|
||||||
(if @focused?
|
(if focused?
|
||||||
[text/text
|
[text/text
|
||||||
[text/text
|
[text/text
|
||||||
{:style (style/char-count blur? theme)
|
{:style (style/char-count blur? theme)
|
||||||
:size :paragraph-2}
|
:size :paragraph-2}
|
||||||
(pad-0
|
(pad-0
|
||||||
(str
|
(str
|
||||||
(count @value)))]
|
(count value)))]
|
||||||
[text/text
|
[text/text
|
||||||
{:style (style/char-count blur? theme)
|
{:style (style/char-count blur? theme)
|
||||||
:size :paragraph-2}
|
:size :paragraph-2}
|
||||||
(str "/"
|
(str "/" (pad-0 (str max-length)))]]
|
||||||
(pad-0
|
[rn/pressable {:on-press on-press}
|
||||||
(str max-length)))]]
|
[icon/icon :i/edit {:color (style/get-char-count-color blur? theme)}]])]]))
|
||||||
[rn/pressable
|
|
||||||
{:on-press #(when-not disabled?
|
|
||||||
(.focus ^js @input-ref))}
|
|
||||||
[icon/icon :i/edit {:color (style/get-char-count-color blur? theme)}]])]])))
|
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
:blur? (:blur? @state)
|
:blur? (:blur? @state)
|
||||||
:show-blur-background? true}
|
:show-blur-background? true}
|
||||||
[quo/address-input
|
[quo/address-input
|
||||||
(merge @state
|
(merge (dissoc @state :scanned-value)
|
||||||
{:on-scan #(js/alert "Not implemented yet")
|
{:on-scan (fn [on-result] (on-result (:scanned-value @state)))
|
||||||
:ens-regex constants/regx-ens
|
:ens-regex constants/regx-ens
|
||||||
:on-detect-ens (fn [_]
|
:on-detect-ens (fn [_]
|
||||||
(swap! state assoc :valid-ens-or-address? false)
|
(swap! state assoc :valid-ens-or-address? false)
|
||||||
|
|
|
@ -21,10 +21,14 @@
|
||||||
(h/fire-event :change-text
|
(h/fire-event :change-text
|
||||||
(h/get-by-label-text :add-address-to-watch)
|
(h/get-by-label-text :add-address-to-watch)
|
||||||
"0x12E838Ae1f769147b12956485dc56e57138f3AC8")
|
"0x12E838Ae1f769147b12956485dc56e57138f3AC8")
|
||||||
(h/is-truthy (h/get-by-translation-text :t/address-already-in-use)))
|
(-> (h/wait-for #(h/get-by-translation-text :t/address-already-in-use))
|
||||||
|
(.then (fn []
|
||||||
|
(h/is-truthy (h/get-by-translation-text :t/address-already-in-use))))))
|
||||||
|
|
||||||
(h/test "validation messages show for invalid address"
|
(h/test "validation messages show for invalid address"
|
||||||
(h/render [add-address-to-watch/view])
|
(h/render [add-address-to-watch/view])
|
||||||
(h/is-falsy (h/query-by-label-text :error-message))
|
(h/is-falsy (h/query-by-label-text :error-message))
|
||||||
(h/fire-event :change-text (h/get-by-label-text :add-address-to-watch) "0x12E838Ae1f769147b")
|
(h/fire-event :change-text (h/get-by-label-text :add-address-to-watch) "0x12E838Ae1f769147b")
|
||||||
(h/is-truthy (h/get-by-translation-text :t/invalid-address))))
|
(-> (h/wait-for #(h/get-by-translation-text :t/invalid-address))
|
||||||
|
(.then (fn []
|
||||||
|
(h/is-truthy (h/get-by-translation-text :t/invalid-address)))))))
|
||||||
|
|
Loading…
Reference in New Issue