Add control components to Quo

Add new switch component

Add all controls components

Use controls in list items

Delete leftover file

Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
This commit is contained in:
Gheorghe Pinzaru 2020-06-24 13:46:26 +03:00
parent 4541f6d59d
commit 1733d4dc83
No known key found for this signature in database
GPG Key ID: C9A094959935A952
9 changed files with 207 additions and 14 deletions

View File

@ -51,8 +51,9 @@
(def bezier (.-bezier ^js Easing))
(def linear (.-linear ^js Easing))
(def easings {:ease-in (bezier 0.42 0 1 1)
:ease-out (bezier 0 0 0.58 1)})
(def easings {:ease-in (bezier 0.42 0 1 1)
:ease-out (bezier 0 0 0.58 1)
:ease-in-out (bezier 0.42 0 0.58 1)})
(defn set-value [anim val]
(ocall anim "setValue" val))
@ -143,6 +144,12 @@
(defn with-timing-transition [val config]
(.withTimingTransition ^js redash val (clj->js config)))
(defn use-spring-transition [val config]
(.withSpringTransition ^js redash val (clj->js config)))
(defn use-timing-transition [val config]
(.withTimingTransition ^js redash val (clj->js config)))
(defn re-timing [config]
(.timing ^js redash (clj->js config)))
@ -160,6 +167,9 @@
(defn mix [anim-value a b]
(.mix ^js redash anim-value a b))
(defn mix-color [anim-value a b]
(.mixColor ^js redash anim-value a b))
(defn loop* [opts]
(ocall redash "loop" (clj->js opts)))

View File

@ -0,0 +1,61 @@
(ns quo.components.controls.styles
(:require [quo.animated :as animated]
[quo.design-system.colors :as colors]))
(defn switch-style [state]
{:width 52
:height 28
:border-radius 14
:padding 4
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(:interactive-01 @colors/theme))})
(defn switch-bullet-style [state hold]
{:width 20
:height 20
:border-radius 10
:opacity (animated/mix hold 1 0.6)
:transform [{:translateX (animated/mix state 0 24)}]
:background-color colors/white
:elevation 4
:shadow-opacity 1
:shadow-radius 16
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn radio-style [state]
{:width 20
:height 20
:border-radius 10
:padding 4
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(:interactive-01 @colors/theme))})
(defn radio-bullet-style [state hold]
{:width 12
:height 12
:border-radius 6
:opacity (animated/mix hold 1 0.6)
:transform [{:scale (animated/mix state 0.0001 1)}]
:background-color colors/white
:elevation 4
:shadow-opacity 1
:shadow-radius 16
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn checkbox-style [state]
{:width 18
:height 18
:border-radius 4
:justify-content :center
:align-items :center
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(:interactive-01 @colors/theme))})
(defn check-icon-style [state hold]
{:opacity (animated/mix hold 1 0.6)
:transform [{:scale (animated/mix state 0.0001 1)}]})

View File

@ -0,0 +1,71 @@
(ns quo.components.controls.view
(:require [reagent.core :as reagent]
[cljs-bean.core :as bean]
[quo.react :as react]
[quo.animated :as animated]
[quo.gesture-handler :as gh]
[quo.design-system.colors :as colors]
[quo.components.controls.styles :as styles]
[status-im.ui.components.icons.vector-icons :as icons]))
(def spring-config {:damping 50
:mass 0.3
:stiffness 120
:overshootClamping true
:bouncyFactor 1})
(defn control-builder [component]
(fn [props]
(let [{:keys [value onChange disabled]}
(bean/bean props)
state (animated/use-value 0)
tap-state (animated/use-value (:undetermined gh/states))
tap-handler (animated/on-gesture {:state tap-state})
hold (react/use-memo
(fn []
(animated/with-timing-transition
(animated/eq tap-state (:began gh/states))
{}))
[])
transition (react/use-memo
(fn []
(animated/with-spring-transition state spring-config))
[])
press-end (fn []
(when (and (not disabled) onChange)
(onChange (not value))))]
(animated/code!
(fn []
(animated/cond* (animated/eq tap-state (:end gh/states))
[(animated/set state (animated/not* state))
(animated/set tap-state (:undetermined gh/states))
(animated/call* [] press-end)]))
[press-end])
(animated/code!
(fn []
(animated/set state (if (true? value) 1 0)))
[value])
(reagent/as-element
[gh/tap-gesture-handler (merge tap-handler
{:shouldCancelWhenOutside true
:enabled (not disabled)})
[animated/view
[component {:transition transition
:hold hold}]]]))))
(defn switch-view [{:keys [transition hold]}]
[animated/view {:style (styles/switch-style transition)}
[animated/view {:style (styles/switch-bullet-style transition hold)}]])
(defn radio-view [{:keys [transition hold]}]
[animated/view {:style (styles/radio-style transition)}
[animated/view {:style (styles/radio-bullet-style transition hold)}]])
(defn checkbox-view [{:keys [transition hold]}]
[animated/view {:style (styles/checkbox-style transition)}
[animated/view {:style (styles/check-icon-style transition hold)}
[icons/tiny-icon :tiny-icons/tiny-check {:color colors/white}]]])
(def switch (reagent/adapt-react-class (control-builder switch-view)))
(def radio (reagent/adapt-react-class (control-builder radio-view)))
(def checkbox (reagent/adapt-react-class (control-builder checkbox-view)))

View File

@ -4,9 +4,8 @@
[quo.design-system.spacing :as spacing]
[quo.design-system.colors :as colors]
[quo.components.text :as text]
[quo.components.controls.view :as controls]
;; FIXME:
[status-im.ui.components.radio :as radio]
[status-im.ui.components.checkbox.view :as checkbox]
[status-im.ui.components.icons.vector-icons :as icons]
[quo.components.animated.pressable :as animated]))
@ -113,12 +112,12 @@
:flex-direction :row}}
[rn/view {:style (:tiny spacing/padding-horizontal)}
(case accessory
:radio [radio/radio active]
:checkbox [checkbox/checkbox {:checked? active}]
:switch [rn/switch {:value active
:track-color #js {:true (:interactive-01 @colors/theme)
:false nil}
:on-value-change on-press}]
:radio [controls/radio {:value active
:on-change on-press}]
:checkbox [controls/checkbox {:value active
:on-change on-press}]
:switch [controls/switch {:value active
:on-change on-press}]
:text [text/text {:color :secondary
:number-of-lines 1}
accessory-text]

View File

@ -9,6 +9,7 @@
[quo.components.list.header :as list-header]
[quo.components.list.footer :as list-footer]
[quo.components.list.item :as list-item]
[quo.components.controls.view :as controls]
[quo.components.bottom-sheet.view :as bottom-sheet]))
(def text text/text)
@ -21,6 +22,9 @@
(def list-footer list-footer/footer)
(def list-item list-item/list-item)
(def bottom-sheet bottom-sheet/bottom-sheet)
(def switch controls/switch)
(def radio controls/radio)
(def checkbox controls/checkbox)
(def safe-area-provider safe-area/provider)
(def safe-area-consumer safe-area/consumer)
(def safe-area-view safe-area/view)

View File

@ -0,0 +1,44 @@
(ns quo.previews.controls
(:require [reagent.core :as reagent]
[quo.core :as quo]
[quo.react-native :as rn]
[quo.design-system.colors :as colors]))
(defn preview []
(let [switch-state (reagent/atom true)
radio-state (reagent/atom true)
checkbox-state (reagent/atom true)]
(fn []
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/view {:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity {:style {:margin-vertical 10
:padding 10}
:on-press #(swap! switch-state not)}
[quo/text (str "Switch state: " @switch-state)]]
[quo/switch {:value @switch-state
:on-change #(reset! switch-state %)}]]
[rn/view {:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity {:style {:margin-vertical 10
:padding 10}
:on-press #(swap! radio-state not)}
[quo/text (str "Radio state: " @radio-state)]]
[quo/radio {:value @radio-state
:on-change #(reset! radio-state %)}]]
[rn/view {:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity {:style {:margin-vertical 10
:padding 10}
:on-press #(swap! checkbox-state not)}
[quo/text (str "Checkbox state: " @checkbox-state)]]
[quo/checkbox {:value @checkbox-state
:on-change #(reset! checkbox-state %)}]]])))

View File

@ -6,6 +6,7 @@
[quo.previews.button :as button]
[quo.previews.lists :as lists]
[quo.previews.bottom-sheet :as bottom-sheet]
[quo.previews.controls :as controls]
[quo.react-native :as rn]
[quo.core :as quo]
[reagent.core :as reagent]
@ -33,7 +34,10 @@
:component lists/preview}
{:name :bottom-sheet
:insets {:top false}
:component bottom-sheet/preview}])
:component bottom-sheet/preview}
{:name :controls
:insets {:top false}
:component controls/preview}])
(defn theme-switcher []
[rn/view {:style {:flex-direction :row

View File

@ -112,13 +112,15 @@
(react/useCallback f (maybe-js-deps @prev-deps*))
deps)))
(defn memo
(defn use-memo
([f] (react/useMemo f))
([f deps]
(with-deps-check [prev-deps*]
(react/useMemo f (maybe-js-deps @prev-deps*))
deps)))
(def memo react/memo)
(defn get-children [^js children]
(->> children
(react/Children.toArray)

View File

@ -32,8 +32,6 @@
:linear (-> ^js layout-animation .-Presets .-linear)
:spring (-> ^js layout-animation .-Presets .-spring)})
(def switch (reagent/adapt-react-class (.-Switch ^js rn)))
(def activity-indicator-class (reagent/adapt-react-class (.-ActivityIndicator ^js rn)))
(defn activity-indicator [props]