remove quo lib (#17626)

This commit is contained in:
flexsurfer 2023-10-16 18:34:00 +02:00 committed by GitHub
parent ff2dfe1a2f
commit 27cd7d4edd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
230 changed files with 1114 additions and 3570 deletions

View File

@ -50,13 +50,6 @@ status-im2.config/rpc-networks-only?
status-im2.config/waku-enabled?
status-im.utils.pairing/has-paired-installations?
status-im.tribute-to-talk.core-test/user-cofx
quo.gesture-handler/tap-gesture-handler
quo.gesture-handler/pan-gesture-handler
quo.gesture-handler/long-press-gesture-handler
quo.gesture-handler/pure-native-button
quo.gesture-handler/createNativeWrapper
quo.gesture-handler/animated-raw-button
quo.gesture-handler/states
mocks.js-dependencies/action-button
mocks.js-dependencies/camera
mocks.js-dependencies/dismiss-keyboard
@ -100,46 +93,13 @@ react-native.fs/read-dir
react-native.fs/mkdir
react-native.fs/unlink
react-native.fs/file-exists?
quo.animated/code
quo.animated/eq
quo.animated/neq
quo.animated/greater-or-eq
quo.animated/not*
quo.animated/or*
quo.animated/and*
quo.animated/add
quo.animated/sub
quo.animated/multiply
quo.animated/abs
quo.animated/min*
quo.animated/max*
quo.animated/set
quo.animated/start-clock
quo.animated/stop-clock
quo.animated/bezier
quo.animated/linear
quo.animated/set-value
quo.animated/clock
quo.animated/debug
quo.animated/log
quo.animated/event
quo.animated/on-change
quo.animated/cond*
quo.animated/block
quo.animated/call*
quo.animated/timing
quo.animated/spring
quo.animated/clamp
quo.animated/with-spring
quo.animated/with-timing
quo.animated/re-timing
quo.design-system.colors/white
quo.design-system.colors/black
status-im.ui.components.colors/white
status-im.ui.components.colors/black
status-im.transport.core-test/messages
quo.core/animated-header
quo.core/safe-area-provider
quo.core/safe-area-consumer
quo.core/safe-area-view
status-im.ui.components.core/animated-header
status-im.ui.components.core/safe-area-provider
status-im.ui.components.core/safe-area-consumer
status-im.ui.components.core/safe-area-view
status-im.utils.universal-links.core/open!
status-im.transport.filters.core-test/member-2
status-im.ui.screens.chat.ttt/one-to-one-chat-description-container
@ -189,7 +149,7 @@ status-im.utils.async/async-periodic-run!
status-im.desktop.core/app-root
status-im.desktop.core/init
status-im.chat.models-test/test-db
quo.design-system.spacing/padding-vertical
status-im.ui.components.spacing/padding-vertical
status-im.utils.money/percent-change
utils.debounce/clear-all
status-im.transport.db/create-chat
@ -206,7 +166,6 @@ status-im.ui.components.animation/add
status-im.ui.components.animation/subtract
status-im.ui.components.animation/get-layout
status-im.wallet.transactions-test/uri-query-data
quo.react-native/touchable-highlight
status-im.utils.name/shortened-name
status-im.ui.components.button.haptic/trigger
status-im.contact.db/filter-dapps

View File

@ -700,7 +700,7 @@ SPEC CHECKSUMS:
FBLazyVector: a8af91c2b5a0029d12ff6b32e428863d63c48991
FBReactNativeSpec: 1b2309b096448a1dc9d0c43999216f8fda809ae8
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 166d178815c300e8126de9a7900101814eb16253
glog: d93527a855523adb8c113837db4be68fb00e230d
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef

View File

@ -1,49 +0,0 @@
# Status Quo Components
All components in **Quo** should be independent of the app state. They should be _pure_
and _easy to reason about_. Avoiding the app state is also required to make the library
independent and easy to be pulled off as a separate repository when needed.
To avoid high coupling and direct use of internal styling, the components should be
exported via namespace `quo.core` and used by the Status app only from there. This will
allow a more flexible way to update components without possible breakages into the
app style.
**Quo** components should not have any dependency on the Status app, this
will avoid circular dependency and also benefit the independence of the components.
All components are stored inside `components` namespaces. They are stateless and do
not dispatch and subscribe to re-frame database. All state should be passed by props
and all events can be passed as functions. Avoiding direct connection with re-frame
will allow components to grow and be reused in different places without the
conditionals hell.
All style system constants are stored inside `design-system` namespaces. They are used
to build components and can be directly required by the status app. Avoid
duplication of these vars and do not use them in code directly as a value.
For each component introduced, add previews of all possible states.
Do not introduce components for slightly modified existing components, if they are
not a part of the design system. In case they are required in one place in the app,
use style override.
# Code style
Ensure that your changes match the style of the rest of the code.
This library uses Clojure Community code style [The Clojure Style Guide](https://github.com/bbatsov/clojure-style-guide).
To ensure consistency, run `make lint`, which uses the [clj-kondo linter](https://github.com/borkdude/clj-kondo).
# Best practices
- Design components atomically and compose them into bigger components.
- Do not export individual atoms, only components. This way we can limit design
system to be used in too many way which can creating disjointed experiences.
- Avoid external margins for atom components, it can be added on the wrapper
where they are used but can't be removed without overriding.
[Max Stoiber article on margins](https://mxstbr.com/thoughts/margin)
- Design reusable components into [Layout Isolated Components](https://visly.app/blogposts/layout-isolated-components)
(Article more relates to web, but ideas fits also to mobile development)
- Explicit is better than implicit, do not rely on platform default, if you expect
a specific value, then override it
**TBD:**
- Components documentation
- Check props using spec in pre conditions.

View File

@ -1,272 +0,0 @@
(ns quo.animated
(:refer-clojure :exclude [abs set delay divide])
(:require ["react-native-reanimated" :default animated :refer (clockRunning EasingNode)]
["react-native-redash/lib/module/v1" :as redash]
[oops.core :refer [ocall oget]]
[quo.gesture-handler :as gh]
quo.react
[quo.react-native :as rn]
[reagent.core :as reagent])
(:require-macros [quo.react :refer [maybe-js-deps]]))
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent animated)))
(def view (reagent/adapt-react-class (.-View animated)))
(def text (reagent/adapt-react-class (.-Text animated)))
(def scroll-view (reagent/adapt-react-class (.-ScrollView animated)))
(def code (reagent/adapt-react-class (.-Code animated)))
(def animated-flat-list (create-animated-component gh/flat-list-raw))
(defn flat-list
[props]
[animated-flat-list (rn/base-list-props props)])
(def useCode (.-useCode animated))
(defn code!
([setup-fn]
(useCode
(fn [] (setup-fn))))
([setup-fn deps]
(useCode
(fn [] (setup-fn))
(maybe-js-deps deps))))
(def eq (oget animated "eq"))
(def neq (oget animated "neq"))
(def greater (oget animated "greaterThan"))
(def greater-or-eq (oget animated "greaterOrEq"))
(def less (oget animated "lessThan"))
(def less-or-eq (oget animated "lessOrEq"))
(def not* (oget animated "not"))
(def or* (oget animated "or"))
(def and* (oget animated "and"))
(def diff (oget animated "diff"))
(def add (oget animated "add"))
(def sub (oget animated "sub"))
(def multiply (oget animated "multiply"))
(def divide (oget animated "divide"))
(def abs (oget animated "abs"))
(def min* (oget animated "min"))
(def max* (oget animated "max"))
(def set (oget animated "set"))
(def start-clock (oget animated "startClock"))
(def stop-clock (oget animated "stopClock"))
(def clock-running clockRunning)
(def bezier (.-bezier ^js EasingNode))
(def linear (.-linear ^js EasingNode))
(def easings
{:linear linear
: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)
:cubic (bezier 0.55 0.055 0.675 0.19)
:keyboard (bezier 0.17 0.59 0.4 0.77)})
(def springs
{:lazy {:damping 50
:mass 0.3
:stiffness 120
:overshootClamping true
:bouncyFactor 1}
:jump {:damping 13
:mass 0.5
:stiffness 170
:overshootClamping false
:bouncyFactor 1
:restSpeedThreshold 0.001
:restDisplacementThreshold 0.001}})
(defn set-value
[anim v]
(ocall anim "setValue" v))
(def Value (oget animated "Value"))
(defn value
[x]
(new Value x))
(def Clock (oget animated "Clock"))
(defn clock
[]
(new Clock))
(def debug (oget animated "debug"))
(def log (oget animated "log"))
(defn event
([config]
(event config {}))
([config options]
(ocall animated "event" (clj->js config) (clj->js options))))
(defn on-change
[state node]
(ocall animated
"onChange"
state
(if (vector? node)
(clj->js node)
node)))
(defn cond*
([condition node]
(.cond ^js animated
condition
(if (vector? node)
(clj->js node)
node)))
([condition if-node else-node]
(.cond ^js animated
condition
(if (vector? if-node)
(clj->js if-node)
if-node)
(if (vector? else-node)
(clj->js else-node)
else-node))))
(defn block
[opts]
(.block ^js animated (to-array opts)))
(defn interpolate
[anim-value config]
(.interpolateNode ^js animated anim-value (clj->js config)))
(defn call*
[args callback]
(.call ^js animated (to-array args) callback))
(defn timing
[clock-value opts config]
(.timing ^js animated
clock-value
(clj->js opts)
(clj->js config)))
(defn spring
[clock-value opts config]
(.spring ^js animated
clock-value
(clj->js opts)
(clj->js config)))
(def extrapolate {:clamp (oget animated "Extrapolate" "CLAMP")})
;; utilities
(def clamp (oget redash "clamp"))
(def diff-clamp (.-diffClamp ^js redash))
(defn with-spring
[config]
(ocall redash "withSpring" (clj->js config)))
(defn with-decay
[config]
(.withDecay ^js redash (clj->js config)))
(defn with-offset
[config]
(.withOffset ^js redash (clj->js config)))
(defn with-spring-transition
[v config]
(.withSpringTransition ^js redash v (clj->js config)))
(defn with-timing-transition
[v config]
(.withTimingTransition ^js redash v (clj->js config)))
(defn use-spring-transition
[v config]
(.useSpringTransition ^js redash v (clj->js config)))
(defn use-timing-transition
[v config]
(.useTimingTransition ^js redash v (clj->js config)))
(defn re-timing
[config]
(.timing ^js redash (clj->js config)))
(defn re-spring
[config]
(.spring ^js redash (clj->js config)))
(defn on-scroll
[opts]
(ocall redash "onScrollEvent" (clj->js opts)))
(defn on-gesture
[opts]
(let [gesture-event (event #js [#js {:nativeEvent (clj->js opts)}])]
{:onHandlerStateChange gesture-event
:onGestureEvent gesture-event}))
(def mix (.-mix ^js redash))
(def mix-color (.-mixColor ^js redash))
(def delay (.-delay ^js redash))
(defn loop*
[opts]
(ocall redash "loop" (clj->js opts)))
(def use-value (.-useValue ^js redash))
(def use-clock (.-useClock ^js redash))
(defn use-gesture
[opts]
(let [gesture (.useGestureHandler ^js redash (clj->js opts))]
{:onHandlerStateChange (.-onHandlerStateChange ^js gesture)
:onGestureEvent (.-onGestureEvent ^js gesture)}))
(defn snap-point
[v velocity snap-points]
(.snapPoint ^js redash v velocity (to-array snap-points)))
(defn with-easing
[{v :value
:keys [snap-points velocity offset state easing duration
animation-over]
:or {duration 250
animation-over (value 1)
easing (:ease-out easings)}}]
(let [position (value 0)
c (clock)
interrupted (and* (eq state (:began gh/states))
(clock-running c))
vel (multiply velocity 1.5)
to (snap-point position vel snap-points)
finish-animation [(set offset position)
(stop-clock c)
(set animation-over 1)]]
(block
[(cond* interrupted finish-animation)
(cond* animation-over
(set position offset))
(cond* (neq state (:end gh/states))
[(set animation-over 0)
(set position (add offset v))])
(cond* (and* (eq state (:end gh/states))
(not* animation-over))
[(set position
(re-timing
{:clock c
:easing easing
:duration duration
:from position
:to to}))
(cond* (not* (clock-running c))
finish-animation)])
position])))

View File

@ -1,136 +0,0 @@
(ns quo.components.animated.pressable
(:require [cljs-bean.core :as bean]
[quo.animated :as animated]
[quo.gesture-handler :as gesture-handler]
[quo.react :as react]
[reagent.core :as reagent]))
(def long-press-duration 500)
(def scale-down-small 0.95)
(def scale-down-large 0.9)
(def opactiy 0.75)
(def time-in 100)
(def time-out 200)
(defmulti type->animation :type)
(defmethod type->animation :primary
[{:keys [animation]}]
{:background {:transform [{:scale (animated/mix animation 1 scale-down-small)}]
:opacity (animated/mix animation 1 opactiy)}
:foreground {:transform [{:scale (animated/mix animation 1 scale-down-small)}]
:opacity (animated/mix animation 1 opactiy)}})
(defmethod type->animation :secondary
[{:keys [animation]}]
{:background {:transform [{:scale (animated/mix animation scale-down-small 1)}]
:opacity (animated/mix animation 0 opactiy)}
:foreground {:transform [{:scale (animated/mix animation 1 scale-down-small)}]
:opacity (animated/mix animation 1 opactiy)}})
(defmethod type->animation :icon
[{:keys [animation]}]
{:background {:transform [{:scale (animated/mix animation scale-down-large 1)}]
:opacity (animated/mix animation 0 opactiy)}
:foreground {:transform [{:scale (animated/mix animation 1 scale-down-large)}]
:opacity (animated/mix animation 1 opactiy)}})
(defmethod type->animation :list-item
[{:keys [animation]}]
{:background {:opacity (animated/mix animation 0 opactiy)}
:foreground {:transform [{:scale (animated/mix animation 1 scale-down-small)}]
:opacity (animated/mix animation 1 opactiy)}})
(defmethod type->animation :scale
[{:keys [animation]}]
{:background {:opacity 0}
:foreground {:transform [{:scale (animated/mix animation 1 scale-down-small)}]
:opacity (animated/mix animation 1 opactiy)}})
(def absolute-fill
{:top 0
:bottom 0
:left 0
:right 0
:position :absolute})
(defn pressable-hooks
[props]
(let [{background-color :bgColor
border-radius :borderRadius
border-color :borderColor
border-width :borderWidth
type :type
disabled :disabled
on-press :onPress
on-long-press :onLongPress
on-press-start :onPressStart
accessibility-label :accessibilityLabel
children :children
:or {border-radius 0
type "primary"}}
(bean/bean props)
long-press-ref (react/create-ref)
state (animated/use-value (:undetermined gesture-handler/states))
active (animated/eq state (:began gesture-handler/states))
gesture-handler (animated/use-gesture {:state state})
animation (react/use-memo
(fn []
(animated/with-timing-transition active
{:duration (animated/cond* active time-in time-out)
:easing (:ease-in animated/easings)}))
[])
{:keys [background
foreground]}
(react/use-memo
(fn []
(type->animation {:type (keyword type)
:animation animation}))
[type])
handle-press (fn [] (when on-press (on-press)))
long-gesture-handler (react/callback
(fn [^js evt]
(let [gesture-state (-> evt .-nativeEvent .-state)]
(when (and on-press-start
(= gesture-state (:began gesture-handler/states)))
(on-press-start))
(when (and on-long-press
(= gesture-state (:active gesture-handler/states)))
(on-long-press)
(animated/set-value state (:undetermined gesture-handler/states)))))
[on-long-press on-press-start])]
(animated/code!
(fn []
(when on-press
(animated/cond* (animated/eq state (:end gesture-handler/states))
[(animated/set state (:undetermined gesture-handler/states))
(animated/call* [] handle-press)])))
[on-press])
(reagent/as-element
[gesture-handler/long-press-gesture-handler
{:enabled (boolean (and on-long-press (not disabled)))
:on-handler-state-change long-gesture-handler
:min-duration-ms long-press-duration
:max-dist 22
:ref long-press-ref}
[animated/view
{:accessible true
:accessibility-label accessibility-label}
[gesture-handler/tap-gesture-handler
(merge gesture-handler
{:shouldCancelWhenOutside true
:wait-for long-press-ref
:enabled (boolean (and (or on-press on-long-press on-press-start)
(not disabled)))})
[animated/view
[animated/view
{:style (merge absolute-fill
background
{:background-color background-color
:border-radius border-radius
:border-color border-color
:border-width border-width})}]
(into [animated/view {:style foreground}]
(react/get-children children))]]]])))
(def pressable (reagent/adapt-react-class (react/memo pressable-hooks)))

View File

@ -1,103 +0,0 @@
(ns quo.components.animated-header
(:require [oops.core :refer [oget]]
[quo.animated :as animated]
[quo.components.header :as header]
[quo.design-system.colors :as colors]
[quo.platform :as platform]
[reagent.core :as reagent]
[react-native.safe-area :as safe-area]))
(defn header-wrapper-style
[{:keys [value offset]}]
(merge
{:background-color (:ui-background @colors/theme)}
(when (and offset platform/android?)
{:elevation (animated/interpolate
value
{:inputRange [0 offset]
:outputRange [0 4]
:extrapolate (:clamp animated/extrapolate)})})
(when (and offset platform/ios?)
{:z-index 2
:shadow-opacity (animated/interpolate
value
{:inputRange [0 offset]
:outputRange [0 1]
:extrapolate (:clamp animated/extrapolate)})
:shadow-radius 16
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})))
(defn title-style
[layout]
{:flex 1
:justify-content :center
:padding-right (get-in layout [:right :width])})
(defn header-container
[]
(let [y (animated/value 0)
animation-value (animated/value 0)
animation (animated/with-timing-transition
animation-value
{:duration 250
:easing (:ease-in animated/easings)})
on-scroll (animated/on-scroll {:y y})
layout (reagent/atom {})
offset (reagent/atom 0)
on-layout (fn [evt]
(reset! offset (oget evt "nativeEvent" "layout" "height")))]
(fn [{:keys [extended-header refresh-control refreshing-sub refreshing-counter] :as props} children]
[animated/view
{:flex 1
:pointer-events :box-none}
[animated/code
{:key (str @offset)
:exec (animated/cond*
(animated/and* (animated/greater-or-eq y @offset)
(animated/greater-or-eq y 1))
(animated/set animation-value 1)
(animated/set animation-value 0))}]
[animated/view
{:pointer-events :box-none
:style (header-wrapper-style {:value y
:offset @offset})}
[header/header
(merge
{:get-layout (fn [el l] (swap! layout assoc el l))
:border-bottom false
:title-component [animated/view {:style (title-style @layout)}
[extended-header
{:value y
:animation animation
:minimized true
:offset @offset}]]
:title-align :left}
(dissoc props :extended-header))]]
(into [animated/scroll-view
{:on-scroll on-scroll
:refreshControl (when refresh-control
(refresh-control
(and @refreshing-sub
@refreshing-counter)))
:style {:z-index 1}
:scrollEventThrottle 16}
[animated/view {:pointer-events :box-none}
[animated/view
{:pointer-events :box-none
:on-layout on-layout}
[extended-header
{:value y
:animation animation
:offset @offset}]]]]
children)])))
(defn header
[{:keys [use-insets] :as props} & children]
(if use-insets
[header-container
(-> props
(dissoc :use-insets)
(assoc :insets (safe-area/get-insets)))
children]
[header-container props children]))

View File

@ -1,45 +0,0 @@
(ns quo.components.bottom-sheet.style
(:require [quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]))
(def border-radius 16)
(def vertical-padding (:tiny spacing/spacing))
(def margin-top 56)
(def container
{:position :absolute
:left 0
:top 0
:right 0
:bottom 0
:flex 1
:justify-content :flex-end})
(defn backdrop
[]
{:flex 1
:position :absolute
:left 0
:top 0
:right 0
:bottom 0})
(defn content-container
[window-height]
{:background-color (:ui-background @colors/theme)
:border-top-left-radius border-radius
:border-top-right-radius border-radius
:height (* window-height 2)})
(def content-header
{:height border-radius
:align-self :stretch
:justify-content :center
:align-items :center})
(def handle
{:width 31
:height 4
:background-color (:icon-02 @colors/theme)
:opacity 0.4
:border-radius 2})

View File

@ -1,233 +0,0 @@
(ns quo.components.bottom-sheet.view
(:require [cljs-bean.core :as bean]
[quo.animated :as animated]
[quo.components.bottom-sheet.style :as styles]
[quo.design-system.colors :as colors]
[quo.gesture-handler :as gesture-handler]
[quo.platform :as platform]
[quo.react :as react]
[quo.react-native :as rn]
[reagent.core :as reagent]
[react-native.safe-area :as safe-area]))
(def opacity-coeff 0.8)
(def close-duration 150)
(def spring-config
{:damping 15
:mass 0.7
:stiffness 150
:overshootClamping false
:restSpeedThreshold 0.1
:restDisplacementThreshold 0.1})
(defn bottom-sheet-hooks
[props]
(let [{on-cancel :onCancel
disable-drag? :disableDrag?
show-handle? :showHandle?
visible? :visible?
backdrop-dismiss? :backdropDismiss?
back-button-cancel :backButtonCancel
children :children
:or {show-handle? true
backdrop-dismiss? true
back-button-cancel true}}
(bean/bean props)
body-ref (react/create-ref)
master-ref (react/create-ref)
height (react/state 0)
{window-height :height} (rn/use-window-dimensions)
{:keys [keyboard-shown
keyboard-height]}
(rn/use-keyboard)
keyboard-height-android-delta
(if (and platform/android? keyboard-shown) (+ keyboard-height 20) 0)
safe-area (safe-area/get-insets)
window-height (- window-height
(if platform/android?
(+ 50 keyboard-height-android-delta) ;; TODO : remove 50 when
;; react-native-navigation v8 will be
;; implemented
;; https://github.com/wix/react-native-navigation/issues/7225
0))
min-height (+ (* styles/vertical-padding 2) (:bottom safe-area))
max-height (- window-height (:top safe-area))
visible (react/state false)
master-translation-y (animated/use-value 0)
master-velocity-y (animated/use-value (:undetermined gesture-handler/states))
master-state (animated/use-value (:undetermined gesture-handler/states))
tap-state (animated/use-value 0)
manual-open (animated/use-value 0)
manual-close (animated/use-value 0)
offset (animated/use-value 0)
drag-over (animated/use-value 1)
clock (animated/use-clock)
tap-gesture-handler (animated/use-gesture {:state tap-state})
on-master-event (animated/use-gesture
{:translationY master-translation-y
:state master-state
:velocityY master-velocity-y})
on-body-event on-master-event
sheet-height (min max-height
(+ styles/border-radius @height))
open-snap-point (animated/use-value 0)
close-snap-point 0
on-close (fn []
(when @visible
(reset! visible false)
(reset! height 0)
(when on-cancel
(on-cancel))))
close-sheet (fn []
(animated/set-value manual-close 1))
on-snap (fn [pos]
(when (= close-snap-point (aget pos 0))
(on-close)))
interrupted (animated/and* (animated/eq master-state (:began gesture-handler/states))
(animated/clock-running clock))
translate-y (react/use-memo
(fn []
(animated/with-easing
{:value (animated/cond* (animated/less-or-eq master-translation-y 0)
(animated/divide master-translation-y 2)
master-translation-y)
:velocity master-velocity-y
:offset offset
:state master-state
:animation-over drag-over
:snap-points [open-snap-point close-snap-point]}))
[])
opacity (react/use-memo
(fn []
(animated/cond*
open-snap-point
(animated/interpolate
translate-y
{:inputRange [(animated/multiply open-snap-point opacity-coeff) 0]
:outputRange [1 0]
:extrapolate (:clamp animated/extrapolate)})))
[])]
(animated/code!
(fn []
(animated/cond* (animated/and* (animated/eq master-state (:end gesture-handler/states))
(animated/not* drag-over))
(animated/call* [translate-y] on-snap)))
[on-snap])
(animated/code!
(fn []
(animated/block
[(animated/cond* (animated/and* interrupted manual-open)
[(animated/set manual-open 0)
(animated/set offset open-snap-point)
(animated/stop-clock clock)])
(animated/cond* (animated/and* manual-open
(animated/not* manual-close))
[(animated/set offset
(animated/re-spring {:from offset
:to open-snap-point
:clock clock
:config spring-config}))
(animated/cond* (animated/not* (animated/clock-running clock))
(animated/set manual-open 0))])]))
[])
(animated/code!
(fn []
(animated/block
[(animated/cond* (animated/and* interrupted manual-close)
[(animated/set manual-close 0)
(animated/set offset close-snap-point)
(animated/call* [] on-close)
(animated/stop-clock clock)])
(animated/cond* (animated/eq tap-state (:end gesture-handler/states))
[(animated/cond* (animated/and* (animated/not* manual-close))
[(animated/stop-clock clock)
(animated/set manual-close 1)])
(animated/set tap-state (:undetermined gesture-handler/states))])
(animated/cond* manual-close
[(animated/set offset
(animated/re-timing {:from offset
:to close-snap-point
:clock clock
:easing (:ease-out animated/easings)
:duration close-duration}))
(animated/cond* (animated/not* (animated/clock-running clock))
[(animated/set manual-close 0)
(animated/set manual-open 0)
(animated/call* [] on-close)])])]))
[on-cancel])
(animated/code!
(fn []
(animated/cond* (animated/and* (animated/not* manual-close)
(if @visible 1 0)
(if (> @height min-height) 1 0))
[(animated/stop-clock clock)
(animated/set open-snap-point (* -1 sheet-height))
(animated/set manual-open 1)]))
[@height @visible])
;; NOTE(Ferossgp): Remove me when RNGH will suport modal
(rn/use-back-handler
(fn []
(when back-button-cancel
(close-sheet))
@visible))
(react/effect!
(fn []
(cond
visible?
(do
(rn/dismiss-keyboard!)
(reset! visible visible?))
@visible
(close-sheet)))
[visible?])
(reagent/as-element
[rn/view
{:style styles/container
:pointer-events :box-none}
[gesture-handler/tap-gesture-handler
(merge {:enabled backdrop-dismiss?}
tap-gesture-handler)
[animated/view
{:style (merge (styles/backdrop)
(when platform/ios?
{:opacity opacity
:background-color (:backdrop @colors/theme)}))}]]
[animated/view
{:style (merge (styles/content-container window-height)
{:transform [{:translateY (if (= sheet-height max-height)
(animated/add translate-y
keyboard-height-android-delta)
translate-y)}
{:translateY (* window-height 2)}]})}
[gesture-handler/pan-gesture-handler
(merge on-master-event
{:ref master-ref
:wait-for body-ref
:enabled (not disable-drag?)})
[animated/view {:style styles/content-header}
(when show-handle?
[rn/view {:style styles/handle}])]]
[gesture-handler/pan-gesture-handler
(merge on-body-event
{:ref body-ref
:wait-for master-ref
:enabled (and (not disable-drag?)
(not= sheet-height max-height))})
[animated/view
{:height sheet-height
:flex 1}
[animated/view
{:style {:padding-top styles/vertical-padding
:padding-bottom (+ styles/vertical-padding
(if (and platform/ios? keyboard-shown)
keyboard-height
(:bottom safe-area)))}
:on-layout #(reset! height (.-nativeEvent.layout.height ^js %))}
(into [:<>]
(react/get-children children))]]]]])))
(def bottom-sheet (reagent/adapt-react-class (react/memo bottom-sheet-hooks)))

View File

@ -1,90 +0,0 @@
(ns quo.components.controls.styles
(:require [quo.animated :as animated]
[quo.design-system.colors :as colors]))
(defn switch-style
[state disabled]
{:width 52
:height 28
:border-radius 14
:padding 4
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(if disabled
(:interactive-04 @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-persist
:elevation 4
:shadow-opacity 1
:shadow-radius 16
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn radio-style
[state disabled]
{:width 20
:height 20
:border-radius 10
:padding 4
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(if disabled
(:interactive-04 @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-persist
:elevation 4
:shadow-opacity 1
:shadow-radius 16
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn animated-checkbox-style
[state disabled]
{:width 18
:height 18
:border-radius 4
:justify-content :center
:align-items :center
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(if disabled
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme)))})
(defn checkbox-style
[value disabled]
{:width 18
:height 18
:border-radius 4
:justify-content :center
:align-items :center
:background-color (if value
(if disabled
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme))
(:ui-01 @colors/theme))})
(defn animated-check-icon-style
[state hold]
{:opacity (animated/mix hold 1 0.6)
:transform [{:scale (animated/mix state 0.0001 1)}]})
(defn check-icon-style
[value]
{:opacity (if value 1 0)})

View File

@ -1,99 +0,0 @@
(ns quo.components.controls.view
(:require [cljs-bean.core :as bean]
[quo.animated :as animated]
[quo.components.controls.styles :as styles]
[quo.design-system.colors :as colors]
[quo.gesture-handler :as gh]
[quo.react :as react]
[quo.react-native :as rn]
[reagent.core :as reagent]
[status-im.ui.components.icons.icons :as icons]))
(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
(:lazy
animated/springs)))
[])
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 (boolean (and onChange (not disabled)))})
[animated/view
[component
{:transition transition
:hold hold
:disabled disabled}]]]))))
(defn switch-view
[{:keys [transition hold disabled value]}]
[animated/view
{:style (styles/switch-style transition disabled)
:accessibility-label (str "switch-" (if value "on" "off"))
:accessibility-role :switch}
[animated/view {:style (styles/switch-bullet-style transition hold)}]])
(defn radio-view
[{:keys [transition hold disabled value]}]
[animated/view
{:style (styles/radio-style transition disabled)
:accessibility-label (str "radio-" (if value "on" "off"))
:accessibility-role :radio}
[animated/view {:style (styles/radio-bullet-style transition hold)}]])
(defn checkbox-view
[props]
(let [{:keys [value onChange disabled]} (bean/bean props)]
(reagent/as-element
[rn/touchable-without-feedback
{:on-press (when (and onChange (not disabled)) onChange)}
[rn/view
{:style (styles/checkbox-style value disabled)
:accessibility-label (str "checkbox-" (if value "on" "off"))
:accessibility-role :checkbox}
[rn/view {:style (styles/check-icon-style value)}
[icons/tiny-icon :tiny-icons/tiny-check {:color colors/white}]]]])))
(defn animated-checkbox-view
[{:keys [transition hold disabled value]}]
[animated/view
{:style (styles/animated-checkbox-style transition disabled)
:accessibility-label (str "checkbox-" (if value "on" "off"))
:accessibility-role :checkbox}
[animated/view {:style (styles/animated-check-icon-style transition hold)}
[icons/tiny-icon :tiny-icons/tiny-check {:color colors/white}]]])
(def switch (reagent/adapt-react-class (react/memo (control-builder switch-view))))
(def radio (reagent/adapt-react-class (react/memo (control-builder radio-view))))
(def animated-checkbox
(reagent/adapt-react-class (react/memo (control-builder animated-checkbox-view))))
(def checkbox (reagent/adapt-react-class (react/memo checkbox-view)))

View File

@ -1,18 +0,0 @@
(ns quo.components.list.index
(:require [quo.components.text :as text]
[quo.design-system.colors :as colors]
[quo.react-native :as rn]))
(defn index
[{:keys [title]}]
[rn/view {:style {:padding-right 16}}
[rn/view
{:style {:border-top-width 1
:border-bottom-width 1
:border-right-width 1
:border-color (colors/get-color :border-01)
:padding-vertical 3
:padding-horizontal 16
:border-top-right-radius 16
:border-bottom-right-radius 16}}
[text/text title]]])

View File

@ -1,32 +0,0 @@
(ns quo.core
(:require [quo.components.animated-header :as animated-header]
[quo.components.bottom-sheet.view :as bottom-sheet]
[quo.components.button.view :as button]
[quo.components.controls.view :as controls]
[quo.components.header :as header]
[quo.components.list.footer :as list-footer]
[quo.components.list.header :as list-header]
[quo.components.list.index :as list-index]
[quo.components.list.item :as list-item]
[quo.components.separator :as separator]
[quo.components.text :as text]
[quo.components.text-input :as text-input]
[quo.components.tooltip :as tooltip]
[quo.design-system.colors :as colors]))
(def text text/text)
(def header header/header)
(def animated-header animated-header/header)
(def text-input text-input/text-input)
(def tooltip tooltip/tooltip)
(def button button/button)
(def list-header list-header/header)
(def list-footer list-footer/footer)
(def list-item list-item/list-item)
(def list-index list-index/index)
(def bottom-sheet bottom-sheet/bottom-sheet)
(def switch controls/switch)
(def radio controls/radio)
(def checkbox controls/checkbox)
(def separator separator/separator)
(def get-color colors/get-color)

View File

@ -1,39 +0,0 @@
(ns quo.design-system.typography)
(def tiny
{:font-size 10
:line-height 14})
(def x-small
{:font-size 12
:line-height 16})
(def small
{:font-size 13
:line-height 18})
(def base
{:font-size 15
:line-height 22})
(def large
{:font-size 17
:line-height 24})
(def x-large
{:font-size 22
:line-height 30})
(def xx-large
{:font-size 28
:line-height 38})
(def font-regular {:font-family "Inter-Regular"}) ; 400
(def font-medium {:font-family "Inter-Medium"}) ; 500 ff
(def font-semi-bold {:font-family "Inter-SemiBold"}) ; 600
(def font-bold {:font-family "Inter-Bold"}) ; 700
(def monospace {:font-family "InterStatus-Regular"})

View File

@ -1,60 +0,0 @@
(ns quo.gesture-handler
(:require ["react-native-gesture-handler" :refer
(TapGestureHandler PanGestureHandler
LongPressGestureHandler
TouchableWithoutFeedback
TouchableOpacity
TouchableHighlight
State
NativeViewGestureHandler
FlatList
ScrollView)]
[oops.core :refer [oget]]
[quo.design-system.colors :as colors]
[reagent.core :as reagent]))
(def flat-list-raw FlatList)
(def flat-list (reagent/adapt-react-class FlatList))
(def scroll-view (reagent/adapt-react-class ScrollView))
(def tap-gesture-handler
(reagent/adapt-react-class TapGestureHandler))
(def pan-gesture-handler
(reagent/adapt-react-class PanGestureHandler))
(def long-press-gesture-handler
(reagent/adapt-react-class LongPressGestureHandler))
;; NOTE - Touchables provided by react-native-gesture-handler has an issue,
;; if it is pressed rapidly it becomes unresponsive and ignores further on-press calls.
;; Issue: https://github.com/status-im/status-mobile/issues/14020
(def touchable-without-feedback-class TouchableWithoutFeedback)
(def touchable-without-feedback
(reagent/adapt-react-class touchable-without-feedback-class))
(def touchable-highlight-class (reagent/adapt-react-class TouchableHighlight))
(defn touchable-highlight
[props & children]
(into [touchable-highlight-class
(merge {:underlay-color (:interactive-02 @colors/theme)}
props)]
children))
(def touchable-opacity
(reagent/adapt-react-class TouchableOpacity))
(def native-view-gesture-handler (reagent/adapt-react-class NativeViewGestureHandler))
(def states
{:began (oget State "BEGAN")
:active (oget State "ACTIVE")
:cancelled (oget State "CANCELLED")
:end (oget State "END")
:failed (oget State "FAILED")
:undetermined (oget State "UNDETERMINED")})

View File

@ -1,25 +0,0 @@
(ns quo.haptic
(:require [react-native-haptic-feedback :default react-native-haptic-feedback]))
(def haptic-methods
{:selection "selection"
:impact-light "impactLight"
:impact-medium "impactMedium"
:impact-heavy "impactHeavy"
:notification-success "notificationSuccess"
:notification-warning "notificationWarning"
:notification-error "notificationError"
:clock-tick "clockTick" ; (Android only)
:context-click "contextClick" ; (Android only)
:keyboard-press "keyboardPress" ; (Android only)
:keyboard-release "keyboardRelease" ; (Android only)
:keyboard-tap "keyboardTap" ; (Android only)
:long-press "longPress" ; (Android only)
:text-handle-move "textHandleMove" ; (Android only)
:virtual-key "virtualKey" ; (Android only)
:virtual-key-release "virtualKeyRelease" ; (Android only)
})
(defn trigger
[method]
(.trigger ^js react-native-haptic-feedback (get haptic-methods method)))

View File

@ -1,9 +0,0 @@
(ns quo.platform
(:require ["react-native" :as rn]))
(def platform (.-Platform ^js rn))
(def os (when platform (.-OS platform)))
(def android? (= os "android"))
(def ios? (= os "ios"))

View File

@ -1,77 +0,0 @@
(ns quo.previews.bottom-sheet
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
[quo.react-native :as rn]
[reagent.core :as reagent]))
(def descriptor
[{:label "Show handle:"
:key :show-handle?
:type :boolean}
{:label "Backdrop dismiss:"
:key :backdrop-dismiss?
:type :boolean}
{:label "Disable drag:"
:key :disable-drag?
:type :boolean}
{:label "Android back cancel:"
:key :back-button-cancel
:type :boolean}
{:label "Scrollable:"
:key :scrollable
:type :boolean}])
(defn cool-preview
[]
(let [state (reagent/atom {:show-handle? true
:backdrop-dismiss? true
:disable-drag? false
:back-button-cancel true})
visible (reagent/atom false)
scrollable (reagent/cursor state [:scrollable])]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[preview/customizer state descriptor]
[:<>
[rn/view
{:style {:align-items :center
:padding 16}}
[rn/touchable-opacity {:on-press #(reset! visible true)}
[rn/view
{:style {:padding-horizontal 16
:padding-vertical 8
:border-radius 4
:background-color (:interactive-01 @colors/theme)}}
[quo/text {:color :secondary-inverse}
(str "Open sheet: " @visible)]]]]
[quo/bottom-sheet
(merge @state
{:visible? @visible
:on-cancel #(reset! visible false)})
[rn/view
{:style {:height (if @scrollable 1200 400)
:justify-content :center
:align-items :center}}
[rn/touchable-opacity {:on-press #(reset! visible false)}
[quo/text {:color :link} "Close"]]
[rn/touchable-opacity
{:on-press #(swap! scrollable not)
:style {:padding-vertical 16}}
[quo/text {:color :link} "Toggle size"]]
[quo/text "Hello world!"]]]]])))
(defn preview
[]
(fn []
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]]))

View File

@ -1,85 +0,0 @@
(ns quo.previews.button
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
[quo.react-native :as rn]
[reagent.core :as reagent]))
(def descriptor
[{:label "Type:"
:key :type
:type :select
:options [{:key :primary
:value "Primary"}
{:key :secondary
:value "Secondary"}
{:key :icon
:value "Icon"}]}
{:label "Theme:"
:key :theme
:type :select
:options [{:key :main
:value "Main"}
{:key :negative
:value "Negative"}
{:key :positive
:value "Positive"}
{:key :accent
:value "Accent"}]}
{:label "After icon:"
:key :after
:type :boolean}
{:label "Before icon:"
:key :before
:type :boolean}
{:label "Disabled:"
:key :disabled
:type :boolean}
{:label "Label"
:key :label
:type :text}])
(defn cool-preview
[]
(let [state (reagent/atom {:label "Press Me"
:type :primary
:theme :main
:icon :main-icons/share})
theme (reagent/cursor state [:theme])
label (reagent/cursor state [:label])
before (reagent/cursor state [:before])
after (reagent/cursor state [:after])]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[rn/view {:flex 1}
[preview/customizer state descriptor]]
[rn/view
{:padding-vertical 16
:flex-direction :row
:justify-content :center}
[quo/button
(merge (dissoc @state
:theme
:before
:after)
{:on-press #(println "Hello world!")}
(when @theme
{:theme @theme})
(when @before
{:before :main-icons/back})
(when @after
{:after :main-icons/next}))
@label]]])))
(defn preview-button
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -1,55 +0,0 @@
(ns quo.previews.controls
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.react-native :as rn]
[reagent.core :as reagent]))
(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

@ -1,51 +0,0 @@
(ns quo.previews.header
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.react-native :as rn])
(:require-macros [quo.previews.preview :as preview]))
(def accessories
[nil
[{:icon :main-icons/close
:on-press identity}]
[{:icon :main-icons/close
:on-press identity}
{:icon :main-icons/add
:on-press identity}]
[{:icon :main-icons/add
:on-press identity}
{:label "Text"
:on-press identity}]
[{:label "Text"
:on-press identity}]])
(def all-props
(preview/list-comp [left-accessories accessories
right-accessories accessories
title [nil "This is a title" "This is a very long super title"]
subtitle [nil "This is a subtitle"]
title-align [:left :center]]
{:left-accessories left-accessories
:right-accessories right-accessories
:title title
:subtitle subtitle
:title-align title-align}))
(defn render-item
[props]
[rn/view
{:border-bottom-color "#EEF2F5"
:border-bottom-width 2}
[quo/header props]])
(defn preview-header
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -1,14 +0,0 @@
(ns quo.previews.icons
(:require [quo.design-system.colors :as colors]
[quo.react-native :as rn]
[status-im.ui.components.icons.icons :as icons]))
(defn preview
[]
[rn/scroll-view
{:background-color (:ui-background @colors/theme)
:flex 1}
(for [i (keys icons/icons)]
[rn/view {:flex-direction :row}
[icons/icon (keyword i)]
[rn/text i]])])

View File

@ -1,121 +0,0 @@
(ns quo.previews.lists
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
[quo.react-native :as rn]
[reagent.core :as reagent]))
(def all-props (preview/list-comp [] {}))
(defn avatar
[]
[rn/view
{:border-radius 20
:width 40
:height 40
:justify-content :center
:align-items :center
:background-color :red}
[quo/text
{:weight :bold
:size :large}
"T"]])
(defn icon-element
[type]
(case type
:icon :main-icons/add-contact
:component [avatar]
nil))
(def descriptor
[{:label "Accessory:"
:key :accessory
:type :select
:options [{:key :radio
:value "Radio"}
{:key :checkbox
:value "Checkbox"}
{:key :switch
:value "Switch"}
{:key :text
:value "Text"}
{:key :default
:value "Default"}]}
{:label "Size:"
:key :size
:type :select
:options [{:key :small
:value "Small"}
{:key :default
:value "Default"}]}
{:label "Icon:"
:key :icon
:type :select
:options [{:key :icon
:value "Icon"}
{:key :component
:value "Component"}]}
{:label "Theme:"
:key :theme
:type :select
:options [{:key :main
:value "Main"}
{:key :accent
:value "Accent"}
{:key :negative
:value "Negative"}
{:key :positive
:value "Positive"}]}
{:label "Selectable"
:key :selectable
:type :boolean}
{:label "Chevron"
:key :chevron
:type :boolean}
{:label "Disabled:"
:key :disabled
:type :boolean}
{:label "Title"
:key :title
:type :text}
{:label "Subtitle"
:key :subtitle
:type :text}])
(defn render-item
[_]
[rn/view {:style {:padding-vertical 24}}])
(defn cool-preview
[]
(let [state (reagent/atom {:title "Title"
:active false})
icon (reagent/cursor state [:icon])
active (reagent/cursor state [:active])
selectable (reagent/cursor state [:selectable])]
(fn []
[rn/view {:margin-bottom 50}
[rn/view {:padding-horizontal 16}
[preview/customizer state descriptor]]
[rn/view {:padding-vertical 16}
[quo/list-item
(merge (dissoc @state :active :selectable)
(when @selectable
{:active @active
:on-press #(swap! active not)})
{:accessory-text "Accessory"
:icon (icon-element @icon)})]]])))
(defn preview
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -1,92 +0,0 @@
(ns quo.previews.main
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.bottom-sheet :as bottom-sheet]
[quo.previews.button :as button]
[quo.previews.controls :as controls]
[quo.previews.header :as header]
[quo.previews.icons :as icons]
[quo.previews.lists :as lists]
[quo.previews.text :as text]
[quo.previews.text-input :as text-input]
[quo.previews.tooltip :as tooltip]
[quo.react-native :as rn]
[quo.theme :as theme]
[re-frame.core :as re-frame]))
(def screens
[{:name :texts
:insets {:top false}
:component text/preview-text}
{:name :tooltip
:insets {:top false}
:component tooltip/preview-tooltip}
{:name :text-input
:insets {:top false}
:component text-input/preview-text}
{:name :headers
:insets {:top false}
:component header/preview-header}
{:name :button
:insets {:top false}
:component button/preview-button}
{:name :lists
:instes {:top false}
:component lists/preview}
{:name :bottom-sheet
:insets {:top false}
:component bottom-sheet/preview}
{:name :controls
:insets {:top false}
:component controls/preview}
{:name :icons
:insets {:top false}
:component icons/preview}])
(defn theme-switcher
[]
[rn/view
{:style {:flex-direction :row
:margin-vertical 8
:border-radius 4
:background-color (:ui-01 @colors/theme)
:border-width 1
:border-color (:ui-02 @colors/theme)}}
[rn/touchable-opacity
{:style {:padding 8
:flex 1
:justify-content :center
:align-items :center}
:on-press #(theme/set-theme :light)}
[quo/text "Set light theme"]]
[rn/view
{:width 1
:margin-vertical 4
:background-color (:ui-02 @colors/theme)}]
[rn/touchable-opacity
{:style {:padding 8
:flex 1
:justify-content :center
:align-items :center}
:on-press #(theme/set-theme :dark)}
[quo/text "Set dark theme"]]])
(defn main-screen
[]
[rn/scroll-view
{:flex 1
:padding-vertical 8
:padding-horizontal 16
:background-color (:ui-background @colors/theme)}
[theme-switcher]
[rn/view
(for [{:keys [name]} screens]
^{:key name}
[rn/touchable-opacity {:on-press #(re-frame/dispatch [:navigate-to name])}
[rn/view {:style {:padding-vertical 8}}
[quo/text (str "Preview " name)]]])]])
(def main-screens
[{:name :quo-preview
:insets {:top false}
:component main-screen}])

View File

@ -1,10 +0,0 @@
(ns quo.previews.preview)
(defmacro list-comp
[[the-binding seq-expr & bindings] body-expr]
(cond (not the-binding)
`(list ~body-expr)
:else
`(mapcat (fn [~the-binding] (list-comp ~bindings ~body-expr))
~seq-expr)))

View File

@ -1,199 +0,0 @@
(ns quo.previews.preview
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.react-native :as rn]
[reagent.core :as reagent])
(:require-macros quo.previews.preview))
(def container
{:flex-direction :row
:padding-vertical 8
:flex 1
:align-items :center})
(defn touchable-style
[]
{:flex 1
:align-items :center
:justify-content :center
:padding-horizontal 16
:height 44})
(defn select-style
[]
{:flex 1
:flex-direction :row
:align-items :center
:padding-horizontal 16
:height 44
:border-radius 4
:background-color (:ui-01 @colors/theme)
:border-width 1
:border-color (:ui-02 @colors/theme)})
(defn select-option-style
[selected]
(merge (select-style)
{:margin-vertical 8
:justify-content :center}
(if selected
{:background-color (:interactive-02 @colors/theme)}
{:background-color (:ui-01 @colors/theme)})))
(def label-style
{:flex 0.4
:padding-right 8})
(defn label-view
[state label]
[rn/view {:style label-style}
[quo/text
(when-let [label-color (:preview-label-color @state)]
{:style {:color label-color}})
label]])
(defn modal-container
[]
{:flex 1
:justify-content :center
:padding-horizontal 24
:background-color "rgba(0,0,0,0.4)"})
(defn modal-view
[]
{:padding-horizontal 16
:padding-vertical 8
:border-radius 8
:flex-direction :column
:background-color (:ui-background @colors/theme)})
(defn customizer-boolean
[{:keys [label state] :as args}]
(let [state* (reagent/cursor state [(:key args)])]
[rn/view {:style container}
[label-view state label]
[rn/view
{:style {:flex-direction :row
:flex 0.6
:border-radius 4
:background-color (:ui-01 @colors/theme)
:border-width 1
:border-color (:ui-02 @colors/theme)}}
[rn/touchable-opacity
{:style (touchable-style)
:on-press #(reset! state* true)}
[quo/text {:color (if @state* :link :secondary)}
"True"]]
[rn/view
{:width 1
:margin-vertical 4
:background-color (:ui-02 @colors/theme)}]
[rn/touchable-opacity
{:style (touchable-style)
:on-press #(reset! state* false)}
[quo/text {:color (if (not @state*) :link :secondary)}
"False"]]]]))
(defn customizer-text
[{:keys [label state] :as args}]
(let [state* (reagent/cursor state [(:key args)])]
[rn/view {:style container}
[label-view state label]
[rn/view {:style {:flex 0.6}}
[quo/text-input
{:value @state*
:show-cancel false
:style {:border-radius 4
:border-width 1
:border-color (:ui-02 @colors/theme)}
:on-change-text #(do
(reset! state* %)
(reagent/flush))}]]]))
(defn value-for-key
[id v]
(:value (first (filter #(= (:key %) id) v))))
(defn customizer-select
[]
(let [open (reagent/atom nil)]
(fn [{:keys [label state options] :as args}]
(let [state* (reagent/cursor state [(:key args)])
selected (value-for-key @state* options)]
[rn/view {:style container}
[label-view state label]
[rn/view {:style {:flex 0.6}}
[rn/modal
{:visible @open
:on-request-close #(reset! open false)
:statusBarTranslucent true
:transparent true
:animation :slide}
[rn/view {:style (modal-container)}
[rn/view {:style (modal-view)}
[rn/scroll-view
(doall
(for [{k :key v :value} options]
^{:key k}
[rn/touchable-opacity
{:style (select-option-style (= @state* k))
:on-press #(do
(reset! open false)
(reset! state* k))}
[quo/text {:color (if (= @state* k) :link :secondary)}
v]]))
[rn/view {:flex-direction :row}
[rn/touchable-opacity
{:style (select-option-style false)
:on-press #(do
(reset! state* nil)
(reset! open false))}
[quo/text "Clear"]]
[rn/view {:width 16}]
[rn/touchable-opacity
{:style (select-option-style false)
:on-press #(reset! open false)}
[quo/text "Close"]]]]]]]
[rn/touchable-opacity
{:style (select-style)
:on-press #(reset! open true)}
(if selected
[quo/text {:color :link} selected]
[quo/text "Select option"])
[rn/view
{:position :absolute
:right 16
:top 0
:bottom 0
:justify-content :center}
[quo/text "↓"]]]]]))))
(defn customizer
[state descriptors]
[rn/view
{:style {:flex 1}
:padding-horizontal 16}
(doall
(for [desc descriptors
:let [descriptor (merge desc {:state state})]]
^{:key (:key desc)}
[:<>
(case (:type desc)
:boolean [customizer-boolean descriptor]
:text [customizer-text descriptor]
:select [customizer-select descriptor]
nil)]))])
(comment
[{:label "Show error:"
:key :error
:type :boolean}
{:label "Label:"
:key :label
:type :text}
{:label "Type:"
:key :type
:type :select
:options [{:key :primary :value "Primary"}
{:key :secondary :value "Secondary"}]}])

View File

@ -1,99 +0,0 @@
(ns quo.previews.text
(:require [quo.animated :as animated]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
[quo.react-native :as rn]
[reagent.core :as reagent]))
(def all-props
(preview/list-comp [size [:tiny :small :base :large :x-large :xx-large]
weight [:regular :medium :semi-bold :bold :monospace]]
{:weight weight
:size size}))
(def descriptor
[{:label "Size:"
:key :size
:type :select
:options [{:key :tiny
:value "Tiny"}
{:key :small
:value "Small"}
{:key :base
:value "Base"}
{:key :large
:value "Large"}
{:key :x-large
:value "X-Large"}
{:key :xx-large
:value "XX-Large"}]}
{:label "Weight:"
:key :weight
:type :select
:options [{:key :regular
:value "Regular"}
{:key :medium
:value "Medium"}
{:key :semi-bold
:value "Semi-bold"}
{:key :bold
:value "Bold"}
{:key :monospace
:value "Monospace"}]}
{:label "Color:"
:key :color
:type :select
:options [{:key :main
:value "main"}
{:key :secondary
:value "secondary"}
{:key :secondary-inverse
:value "secondary-inverse"}
{:key :link
:value "link"}
{:key :negative
:value "negative"}
{:key :positive
:value "positive"}]}
{:label "Animated:"
:key :animated?
:type :boolean}])
(defn render-item
[props]
[rn/view
{:style {:padding-vertical 24
:padding-horizontal 16}}
[quo/text props
(str "Text size " props " number 0 1x2")]])
(defn cool-preview
[]
(let [state (reagent/atom {})
animation (animated/value 0)]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[animated/code {:exec (animated/set animation (animated/loop* {:duration 1000}))}]
[preview/customizer state descriptor]
[rn/view {:padding-vertical 16}
[quo/text
(merge @state
(when (:animated? @state)
{:opacity animation}))
"This is a demo text 1 2 0 2x2 0x0"]]])))
(defn preview-text
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -1,91 +0,0 @@
(ns quo.previews.text-input
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
[quo.react-native :as rn]
[reagent.core :as reagent]))
(def all-props
(preview/list-comp [multiline [false true]
label [nil "Input label"]
default-value [nil "Test initial value"]
placeholder [nil "Placeholder value"]
before [nil {:icon :main-icons/search}]
after [nil {:icon :main-icons/close}]
error [nil "Something went wrong!"]
secure [false true]
show-cancel [false true]]
{:label label
:default-value default-value
:placeholder placeholder
:multiline multiline
:before before
:after after
:error error
:show-cancel show-cancel
:secure-text-entry secure}))
(def descriptor
[{:label "Multiline:"
:key :multiline
:type :boolean}
{:label "Show cancel:"
:key :show-cancel
:type :boolean}
{:label "Secure:"
:key :secure-text-entry
:type :boolean}
{:label "After icon:"
:key :after
:type :boolean}
{:label "Before icon:"
:key :before
:type :boolean}
{:label "Show error:"
:key :error
:type :boolean}
{:label "Label"
:key :label
:type :text}])
(defn render-item
[props]
[rn/view
{:style {:padding-horizontal 16
:padding-vertical 24}}
[quo/text-input props]])
(defn cool-preview
[]
(let [state (reagent/atom {:secure false
:show-cancel false
:multiline false
:label "I'm a cool label"})
before (reagent/cursor state [:before])
after (reagent/cursor state [:after])
error (reagent/cursor state [:error])]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[preview/customizer state descriptor]
[quo/text-input
(merge @state
{:default-value nil
:placeholder "I'm a cool placeholder"
:before (when @before {:icon :main-icons/search})
:after (when @after {:icon :main-icons/close})
:error (when @error "Something went wrong!")})]])))
(defn preview-text
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -1,38 +0,0 @@
(ns quo.previews.tooltip
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.react-native :as rn])
(:require-macros [quo.previews.preview :as preview]))
(def all-props
(preview/list-comp
[child [[quo/text {:size :small} "Simple text"]
[quo/text
{:color :negative
:size :small}
"Error text"]
[rn/view {:width 100 :height 20 :background-color :red}]
[quo/text
"Just text, but long. Officia autem est repellendus ad quia exercitationem veniam."]]]
child))
(defn render-item
[children]
[rn/view {:margin-vertical 50}
[rn/view
{:height 20
:background-color "rgba(0,0,0,0.1)"}]
[quo/tooltip {}
children]])
(defn preview-tooltip
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -1,30 +0,0 @@
(ns quo.react)
(defmacro maybe-js-deps
[deps]
`(if ~deps (into-array ~deps) js/undefined))
(defmacro with-deps-check
[[prev-deps] f deps]
`(let [~prev-deps (quo.react/ref ~deps)]
(when (not= @~prev-deps ~deps)
(reset! ~prev-deps ~deps))
~f))
(defmacro with-effect
"Takes optional vector of dependencies and body to be executed in an effect."
[deps & body]
(let [[deps setup-fn] (if (vector? deps)
[deps body]
[nil (cons deps body)])]
`(effect! #(do ~@setup-fn) ~deps)))
(defmacro with-layout-effect
"Takes optional vector of dependencies and body to be executed in a layout effect."
[deps & body]
(let [[deps setup-fn] (if (vector? deps)
[deps body]
[nil (cons deps body)])]
`(layout-effect! #(do ~@setup-fn) ~deps)))

View File

@ -1,136 +0,0 @@
(ns quo.react
(:refer-clojure :exclude [ref])
(:require ["react" :as react]
[oops.core :refer [oget oset!]])
(:require-macros [quo.react :refer [with-deps-check maybe-js-deps]]))
(def create-ref react/createRef)
(defn current-ref
[ref]
(oget ref "current"))
;; Inspired from UIX, Rum and Rumext
(defn set-ref-val!
[ref v]
(oset! ref "current" v)
v)
(defn set-native-props
[^js ref ^js props]
(when-let [curr-ref ^js (current-ref ref)]
(.setNativeProps curr-ref props)))
(deftype StateHook [value set-value]
cljs.core/IHash
(-hash [o] (goog/getUid o))
cljs.core/IDeref
(-deref [_o]
value)
cljs.core/IReset
(-reset! [_o new-value]
(set-value new-value))
cljs.core/ISwap
(-swap! [_o f]
(set-value f))
(-swap! [_o f a]
(set-value #(f % a)))
(-swap! [_o f a b]
(set-value #(f % a b)))
(-swap! [_o f a b xs]
(set-value #(apply f % a b xs))))
(defn state
[value]
(let [[value set-value] (react/useState value)
sh (react/useMemo #(StateHook. value set-value) #js [])]
(react/useMemo (fn []
(set! (.-value sh) value)
(set! (.-set-value sh) set-value)
sh)
#js [value set-value])))
(defn use-ref
[v]
(let [ref (react/useRef v)]
(reify
cljs.core/IHash
(-hash [_] (goog/getUid ref))
cljs.core/IDeref
(-deref [_]
(current-ref ref))
cljs.core/IReset
(-reset! [_ new-value]
(set-ref-val! ref new-value))
cljs.core/ISwap
(-swap! [_ f]
(-reset! ref (f (current-ref ref))))
(-swap! [_ f a]
(-reset! ref (f (current-ref ref) a)))
(-swap! [_ f a b]
(-reset! ref (f (current-ref ref) a b)))
(-swap! [_ f a b xs]
(-reset! ref (apply f (current-ref ref) a b xs))))))
(defn ref
[value]
(let [vref (use-ref value)]
(react/useMemo (fn [] vref) #js [])))
(defn effect!
([setup-fn]
(react/useEffect
#(let [ret (setup-fn)]
(if (fn? ret) ret js/undefined))))
([setup-fn deps]
(with-deps-check [prev-deps*]
(react/useEffect
(fn []
(reset! prev-deps* deps)
(let [ret (setup-fn)]
(if (fn? ret) ret js/undefined)))
(maybe-js-deps @prev-deps*))
deps)))
(defn layout-effect!
([setup-fn]
(react/useLayoutEffect
#(let [ret (setup-fn)]
(if (fn? ret) ret js/undefined))))
([setup-fn deps]
(with-deps-check [prev-deps*]
(react/useLayoutEffect
(fn []
(reset! prev-deps* deps)
(let [ret (setup-fn)]
(if (fn? ret) ret js/undefined)))
(maybe-js-deps @prev-deps*))
deps)))
(defn callback
([f] (react/useCallback f))
([f deps]
(with-deps-check [prev-deps*]
(react/useCallback f (maybe-js-deps @prev-deps*))
deps)))
(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)
(into [])))

View File

@ -1,200 +0,0 @@
(ns quo.react-native
(:require ["@react-native-community/hooks" :as hooks]
["react-native" :as rn]
["react-native-draggable-flatlist" :default DraggableFlatList]
["react-native-hole-view" :refer (RNHoleView)]
["react-native-navigation" :refer (Navigation)]
["rn-emoji-keyboard" :refer (EmojiKeyboard)]
[cljs-bean.core :as bean]
[quo.platform :as platform]
[reagent.core :as reagent]))
(def hole-view (reagent/adapt-react-class RNHoleView))
(def rn-draggable-flatlist (reagent/adapt-react-class DraggableFlatList))
(def emoji-keyboard (reagent/adapt-react-class EmojiKeyboard))
(def app-registry (.-AppRegistry rn))
(def platform (.-Platform ^js rn))
(def find-node-handle (.-findNodeHandle ^js rn))
(def view (reagent/adapt-react-class (.-View ^js rn)))
(def image (reagent/adapt-react-class (.-Image rn)))
(def text (reagent/adapt-react-class (.-Text ^js rn)))
(defn resolve-asset-source
[uri]
(js->clj (.resolveAssetSource ^js (.-Image ^js rn) uri) :keywordize-keys true))
(def scroll-view (reagent/adapt-react-class (.-ScrollView ^js rn)))
(def modal (reagent/adapt-react-class (.-Modal ^js rn)))
(def refresh-control (reagent/adapt-react-class (.-RefreshControl ^js rn)))
(def touchable-opacity (reagent/adapt-react-class (.-TouchableOpacity ^js rn)))
(def touchable-highlight (reagent/adapt-react-class (.-TouchableHighlight ^js rn)))
(def touchable-without-feedback (reagent/adapt-react-class (.-TouchableWithoutFeedback ^js rn)))
(def text-input (reagent/adapt-react-class (.-TextInput ^js rn)))
(def keyboard-avoiding-view-class (reagent/adapt-react-class (.-KeyboardAvoidingView ^js rn)))
(def navigation-const (atom nil))
(.then (.constants Navigation)
(fn [^js consts]
(reset! navigation-const {:top-bar-height (.-topBarHeight consts)
:bottom-tabs-height (.-bottomTabsHeight consts)
:status-bar-height (.-statusBarHeight consts)})))
(defn keyboard-avoiding-view
[]
(let [this (reagent/current-component)
props (reagent/props this)]
(into [keyboard-avoiding-view-class
(merge (when platform/ios?
{:behavior :padding})
props
{:keyboardVerticalOffset (+ 44 (:status-bar-height @navigation-const))})]
(reagent/children this))))
(def status-bar (.-StatusBar ^js rn))
(def keyboard (.-Keyboard ^js rn))
(def dismiss-keyboard! #(.dismiss ^js keyboard))
(def dimensions (.-Dimensions ^js rn))
(def pan-responder (.-PanResponder ^js rn))
(defn create-pan-responder
[opts]
(.create ^js pan-responder (clj->js opts)))
(def animated (.-Animated rn))
(def subtract (.-subtract ^js animated))
(def animated-flat-list-class
(reagent/adapt-react-class (.-FlatList ^js animated)))
(def animated-view
(reagent/adapt-react-class (.-View ^js animated)))
(def ui-manager (.-UIManager ^js rn))
(def layout-animation (.-LayoutAnimation ^js rn))
(def configure-next (.-configureNext ^js layout-animation))
(def create-animation (.-create ^js layout-animation))
(def layout-animation-presets
{:ease-in-ease-out (-> ^js layout-animation .-Presets .-easeInEaseOut)
:linear (-> ^js layout-animation .-Presets .-linear)
:spring (-> ^js layout-animation .-Presets .-spring)})
(def layout-animation-types
{:spring (-> ^js layout-animation .-Types .-spring)
:linear (-> ^js layout-animation .-Types .-linear)
:ease-in-ease-out (-> ^js layout-animation .-Types .-easeInEaseOut)
:ease-in (-> ^js layout-animation .-Types .-easeIn)
:ease-out (-> ^js layout-animation .-Types .-easeOut)})
(def layout-animation-properties
{:opacity (-> ^js layout-animation .-Properties .-opacity)
:scale-x (-> ^js layout-animation .-Properties .-scaleX)
:scale-y (-> ^js layout-animation .-Properties .-scaleY)
:scale-xy (-> ^js layout-animation .-Properties .-scaleXY)})
(def custom-animations
{:ease-opacity-200 #js
{:duration 200
:create #js
{:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}
:update #js
{:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}
:delete #js
{:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}}})
(defonce enable-layout-animations
(when platform/android?
(.setLayoutAnimationEnabledExperimental ^js ui-manager true)))
(def activity-indicator (reagent/adapt-react-class (.-ActivityIndicator ^js rn)))
;; Flat-list
(def ^:private rn-flat-list (reagent/adapt-react-class (.-FlatList ^js rn)))
(defn- wrap-render-fn
[f render-data]
(fn [data]
(reagent/as-element [f (.-item ^js data) (.-index ^js data)
(.-separators ^js data) render-data
(.-isActive ^js data) (.-drag ^js data)])))
(defn- wrap-on-drag-end-fn
[f]
(fn [data]
(f (.-from ^js data) (.-to ^js data) (.-data ^js data))))
(defn- wrap-key-fn
[f]
(fn [data index]
{:post [(some? %)]}
(f data index)))
(defn base-list-props
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn]
:as props}]
(merge
{:data (to-array data)}
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
(when header {:ListHeaderComponent (reagent/as-element header)})
(when footer {:ListFooterComponent (reagent/as-element footer)})
(when on-drag-end-fn {:onDragEnd (wrap-on-drag-end-fn on-drag-end-fn)})
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn)))
(defn flat-list
[props]
[rn-flat-list (base-list-props props)])
(defn draggable-flat-list
[props]
[rn-draggable-flatlist (base-list-props props)])
(defn animated-flat-list
[props]
[animated-flat-list-class (base-list-props props)])
;; Hooks
(defn use-window-dimensions
[]
(let [window (rn/useWindowDimensions)]
{:font-scale (.-fontScale window)
:height (.-height ^js window)
:scale (.-scale ^js window)
:width (.-width ^js window)}))
(def use-back-handler (.-useBackHandler hooks))
(defn use-keyboard
[]
(let [kb (.useKeyboard hooks)]
{:keyboard-shown (.-keyboardShown ^js kb)
:keyboard-height (.-keyboardHeight ^js kb)}))
(defn use-layout
[]
(let [{:keys [onLayout x y height width]} (bean/bean (.useLayout hooks))]
{:on-layout onLayout
:x x
:y y
:height height
:width width}))

View File

@ -1,4 +0,0 @@
(ns quo.spec
(:require [clojure.spec.alpha :as s]))
(s/def ::style (s/nilable map?))

View File

@ -1,21 +0,0 @@
(ns quo.theme
(:require [quo.design-system.colors :as colors]
[reagent.core :as reagent]))
(def theme (reagent/atom nil))
(defn dark?
[]
(= :dark @theme))
(defn get-theme
[]
@theme)
(defn set-theme
[value]
(reset! theme value)
(reset! colors/theme (case value
:dark colors/dark-theme
colors/light-theme))
(colors/set-legacy-theme-type value))

View File

@ -1,11 +1,11 @@
(ns quo2.components.notifications.activity-log.view
(:require [clojure.string :as string]
[quo.core :as quo]
[quo2.components.buttons.button.view :as button]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.notifications.activity-log.style :as style]
[quo2.components.tags.status-tags :as status-tags]
[quo2.components.inputs.input.view :as input]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
@ -29,10 +29,7 @@
colors/neutral-40
colors/danger-60)}}
(str (count @reply-input) "/" max-reply-length)]]
[rn/view
;; TODO(@ilmotta): Replace with quo2 component when available.
;; https://github.com/status-im/status-mobile/issues/14364
[quo/text-input
[input/input
{:on-change-text #(do (reset! reply-input %)
(when on-update-reply
(on-update-reply %)))
@ -42,7 +39,7 @@
:placeholder (i18n/label :t/type-something)
:return-key-type :none
:multiline false
:auto-correct false}]]])
:auto-correct false}]])
(defn- activity-icon
[icon]

View File

@ -1,5 +1,5 @@
(ns quo2.components.settings.reorder-item.items.item-skeleton
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.components.settings.reorder-item.style :as style]))
(defn view

View File

@ -1,7 +1,7 @@
(ns quo2.components.settings.reorder-item.items.item-tabs
(:require [quo2.components.tabs.segmented-tab :as quo2]
[quo.react-native :as rn]
[quo.components.text :as text]
[react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.components.settings.reorder-item.style :as style]
[quo2.components.icon :as quo2-icons]))
@ -17,8 +17,8 @@
{:style style/tab-item-container}
tab-image
[text/text
{:style style/tab-item-label
:width :medium}
{:size :paragraph-1
:weight :medium}
(:label item)]]))
(defn transform-data

View File

@ -1,5 +1,5 @@
(ns quo2.components.switchers.base-card.view
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.components.buttons.button.view :as button]
[quo2.components.switchers.base-card.style :as style]))

View File

@ -1,7 +1,7 @@
(ns quo2.components.switchers.card-main-info.view
(:require [quo2.components.markdown.text :as text]
[quo2.components.switchers.card-main-info.style :as style]
[quo.react-native :as rn]))
[react-native.core :as rn]))
(defn view
[{:keys [title subtitle]}]

View File

@ -44,6 +44,7 @@
(def activity-indicator (reagent/adapt-react-class (.-ActivityIndicator ^js react-native)))
(def modal (reagent/adapt-react-class (.-Modal ^js react-native)))
(def refresh-control (reagent/adapt-react-class (.-RefreshControl ^js react-native)))
(def keyboard ^js (.-Keyboard ^js react-native))

View File

@ -1,6 +1,6 @@
(ns status-im.bottom-sheet.view
(:require [oops.core :refer [oget]]
[quo.react :as react]
[react-native.core :as react]
[status-im.bottom-sheet.styles :as styles]
[re-frame.core :as re-frame]
[react-native.background-timer :as timer]
@ -153,7 +153,7 @@
handle-comp [gesture/gesture-detector {:gesture bottom-sheet-gesture}
[handle-view window-width override-theme]]]
(react/effect! #(do
(react/use-effect #(do
(cond
(and
(nil? @show-bottom-sheet?)
@ -165,7 +165,7 @@
(and @show-bottom-sheet? (not visible?))
(close-bottom-sheet)))
[@show-bottom-sheet? @content-height visible?])
(react/effect! #(do
(react/use-effect #(do
(when @show-bottom-sheet?
(cond
keyboard-shown
@ -175,7 +175,7 @@
(and @keyboard-was-shown? (not keyboard-shown))
(reset! expanded? false))))
[@show-bottom-sheet? @keyboard-was-shown? keyboard-shown])
(react/effect! #(do
(react/use-effect #(do
(when-not @gesture-running?
(cond
@show-bottom-sheet?

View File

@ -2,7 +2,7 @@
(:require [clojure.set :as set]
[clojure.string :as string]
[clojure.walk :as walk]
[quo.design-system.colors :as colors]
[status-im.ui.components.colors :as colors]
[quo2.foundations.colors :as quo2.colors]
[re-frame.core :as re-frame]
[status-im.utils.deprecated-types :as types]

View File

@ -1,6 +1,6 @@
(ns status-im.multiaccounts.core
(:require [clojure.string :as string]
[quo.platform :as platform]
[react-native.platform :as platform]
[re-frame.core :as re-frame]
[status-im.bottom-sheet.events :as bottom-sheet]
[status-im.multiaccounts.update.core :as multiaccounts.update]

View File

@ -1,5 +1,5 @@
(ns status-im.multiaccounts.create.core
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[status-im2.constants :as constants]
[status-im.data-store.settings :as data-store.settings]

View File

View File

View File

View File

@ -1,5 +1,5 @@
(ns status-im.react-native.resources
(:require [quo.design-system.colors :as colors]))
(:require [status-im.ui.components.colors :as colors]))
(def ui
{:empty-chats-header (js/require "../resources/images/ui/empty-chats-header.png")

View File

@ -1,9 +1,9 @@
(ns status-im.ui.components.accordion
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[reagent.core :as reagent]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]))
[status-im.ui.components.react :as react]
[status-im.ui.components.list.item :as list.item]))
(defn drop-down-icon
[{:keys [opened? dropdown-margin-left]}]
@ -36,7 +36,7 @@
(merge {:padding-vertical padding-vertical}
(when @opened? open-container-style))
(if (string? title)
[quo/list-item
[list.item/list-item
{:title title
:icon icon
:on-press on-press

View File

@ -0,0 +1,68 @@
(ns status-im.ui.components.animated-header
(:require [oops.core :refer [oget]]
[status-im.ui.components.header :as header]
[status-im.ui.components.colors :as colors]
[react-native.platform :as platform]
[reagent.core :as reagent]
[react-native.safe-area :as safe-area]
[react-native.core :as rn]))
(defn header-wrapper-style
[{:keys [offset]}]
(merge
{:background-color (:ui-background @colors/theme)}
(when (and offset platform/ios?)
{:z-index 2
:shadow-radius 16
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})))
(defn title-style
[layout]
{:flex 1
:justify-content :center
:padding-right (get-in layout [:right :width])})
(defn header-container
[]
(let [layout (reagent/atom {})
offset (reagent/atom 0)
on-layout (fn [evt]
(reset! offset (oget evt "nativeEvent" "layout" "height")))]
(fn [{:keys [extended-header refresh-control refreshing-sub refreshing-counter] :as props} children]
[rn/view
{:flex 1
:pointer-events :box-none}
[rn/view
{:pointer-events :box-none
:style (header-wrapper-style {:offset @offset})}
[header/header
(merge
{:get-layout (fn [el l] (swap! layout assoc el l))
:border-bottom false
:title-align :left}
(dissoc props :extended-header))]]
(into [rn/scroll-view
{:refreshControl (when refresh-control
(refresh-control
(and @refreshing-sub
@refreshing-counter)))
:style {:z-index 1}
:scrollEventThrottle 16}
[rn/view {:pointer-events :box-none}
[rn/view
{:pointer-events :box-none
:on-layout on-layout}
[extended-header
{:offset @offset}]]]]
children)])))
(defn header
[{:keys [use-insets] :as props} & children]
(if use-insets
[header-container
(-> props
(dissoc :use-insets)
(assoc :insets (safe-area/get-insets)))
children]
[header-container props children]))

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.badge
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[utils.i18n :as i18n]
[status-im.ui.components.react :as react]))

View File

@ -1,6 +1,6 @@
(ns status-im.ui.components.bottom-panel.views
(:require ["react-native" :refer (BackHandler)]
[quo.design-system.colors :as colors]
[status-im.ui.components.colors :as colors]
[reagent.core :as reagent]
[status-im.ui.components.animation :as anim]
[status-im.ui.components.react :as react]

View File

@ -1,10 +1,8 @@
(ns quo.components.button.view
(:require [quo.components.animated.pressable :as animation]
[quo.components.text :as text] ;; FIXME:
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.haptic :as haptic]
[quo.react-native :as rn]
(ns status-im.ui.components.button.view
(:require [status-im.ui.components.text :as text]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.spacing :as spacing]
[react-native.core :as rn]
[status-im.ui.components.icons.icons :as icons]))
(defn style-container
@ -58,44 +56,31 @@
(defn button
[{:keys [on-press disabled type theme before after
haptic-feedback haptic-type on-long-press on-press-start
accessibility-label loading border-radius style test-ID]
on-long-press accessibility-label loading border-radius style test-ID]
:or {theme :main
type :primary
haptic-feedback true
border-radius 8
haptic-type :selection}}
border-radius 8}}
children]
(let [theme' (cond
disabled :disabled
:else theme)
{:keys [icon-color background-color text-color border-color]}
(themes theme')
optional-haptic (fn []
(when haptic-feedback
(haptic/trigger haptic-type)))]
[animation/pressable
(merge {:bg-color background-color
(themes theme')]
(println "theme" theme' background-color)
[rn/touchable-without-feedback
(merge (when on-press
{:on-press on-press})
(when on-long-press
{:on-long-press on-long-press}))
[rn/view
(merge {:background-color background-color
:border-radius border-radius
:type type
:disabled disabled
:accessibility-label accessibility-label}
(when border-color
{:border-color border-color
:border-width 1})
(when on-press
{:on-press (fn []
(optional-haptic)
(on-press))})
(when on-long-press
{:on-long-press (fn []
(optional-haptic)
(on-long-press))})
(when on-press-start
{:on-press-start (fn []
(optional-haptic)
(on-press-start))}))
:border-width 1}))
[rn/view {:test-ID test-ID :style (merge (style-container type) style)}
(when before
[rn/view
@ -122,4 +107,4 @@
children)]
(when after
[rn/view
[icons/icon after {:color icon-color}]])]]))
[icons/icon after {:color icon-color}]])]]]))

View File

@ -1,7 +1,7 @@
(ns status-im.ui.components.chat-icon.screen
(:require [clojure.string :as string]
[quo.design-system.colors :as colors]
[quo.react-native :as rn]
[status-im.ui.components.colors :as colors]
[react-native.core :as rn]
[quo2.components.avatars.user-avatar.style :as user-avatar.style]
[quo2.core :as quo]
[quo2.theme :as theme]

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.chat-icon.styles
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.emoji-thumbnail.utils :as emoji-utils]))
(defn default-chat-icon

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.checkbox.styles
(:require [quo.design-system.colors :as colors]))
(:require [status-im.ui.components.colors :as colors]))
(def wrapper
{:width 24 :height 24 :align-items :center :justify-content :center})

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.checkbox.view
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.checkbox.styles :as styles]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]))

View File

@ -1,4 +1,4 @@
(ns quo.design-system.colors
(ns status-im.ui.components.colors
(:require [clojure.string :as string]
[reagent.core :as reagent]))
@ -135,7 +135,7 @@
(def black (:text-01 light-theme)) ;; Used as the default text color
(def black-persist (:ui-background dark-theme)) ;; this doesn't with theme
(def black-transparent (:ui-02 light-theme)) ;; Used as background color for rounded button on dark background and as background
;; color for containers like "Backup recovery phrase"
;; color for containers like "Backup recovery phrase"
(def black-transparent-20 (:backdrop light-theme)) ; accounts divider
(def black-transparent-40 (:backdrop light-theme))
(def black-transparent-40-persist (:backdrop light-theme))
@ -145,7 +145,7 @@
;; DARK GREY
(def gray (:text-02 light-theme)) ;; Dark grey, used as a background for a light foreground and as
;; section header and secondary text color
;; section header and secondary text color
(def gray-transparent-10 (alpha gray 0.1))
(def gray-transparent-40 (alpha gray 0.4))
;; LIGHT GREY

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.common.styles
(:require [quo.design-system.colors :as colors]))
(:require [status-im.ui.components.colors :as colors]))
(defn logo-container
[size]

View File

@ -1,11 +1,12 @@
(ns status-im.ui.components.connectivity.view
(:require [clojure.string :as string]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[status-im.ui.components.core :as quo]
[status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.react :as react])
[status-im.ui.components.react :as react]
[status-im.ui.components.list.item :as list.item])
(:require-macros [status-im.utils.views :as views :refer [defview letsubs]]))
(defn easing
@ -93,14 +94,14 @@
[quo/header {:title (i18n/label :t/connection-status) :border-bottom false}]
[quo/list-header (i18n/label :t/peer-to-peer)]
(if (= peers :offline)
[quo/list-item
[list.item/list-item
{:title (i18n/label :t/not-connected-to-peers)
:accessibility-label "not-connected-to-peers"
:subtitle (i18n/label :t/unable-to-send-messages)
:subtitle-max-lines 2
:theme :negative
:icon :main-icons/network}]
[quo/list-item
[list.item/list-item
{:title (str (i18n/label :t/connected-to)
" " peers-count
" " (string/lower-case (i18n/label :t/peers)))
@ -112,40 +113,40 @@
[quo/list-header (i18n/label :t/history-nodes)]
(cond
(#{:error :offline} node)
[quo/list-item
[list.item/list-item
{:title (i18n/label :t/not-connected-nodes)
:accessibility-label "not-connected-nodes"
:subtitle (i18n/label :t/unable-to-fetch)
:theme :negative
:icon :main-icons/mailserver}]
(= node :disabled)
[quo/list-item
[list.item/list-item
{:title (i18n/label :t/nodes-disabled)
:accessibility-label "nodes-disabled"
:subtitle (i18n/label :t/unable-to-fetch)
:disabled true
:icon :main-icons/mailserver}]
(and mobile (not sync))
[quo/list-item
[list.item/list-item
{:title (i18n/label :t/waiting-wi-fi)
:accessibility-label "waiting-wi-fi"
:subtitle (i18n/label :t/unable-to-fetch)
:disabled true
:icon :main-icons/mailserver}]
(= node :connecting)
[quo/list-item
[list.item/list-item
{:title (i18n/label :t/connecting)
:accessibility-label "connecting"
:subtitle (i18n/label :t/unable-to-fetch)
:icon :main-icons/mailserver}]
(= node :online)
[quo/list-item
[list.item/list-item
{:title (str (i18n/label :t/connected-to) " " current-mailserver-name)
:accessibility-label "connected-to-mailserver"
:subtitle (i18n/label :t/you-can-fetch)
:theme :positive
:icon :main-icons/mailserver}])
[quo/list-item
[list.item/list-item
{:title (i18n/label :t/settings)
:accessibility-label "settings"
:theme :accent
@ -160,7 +161,7 @@
:align-items :center
:justify-content :center}
[react/text {:style {:color colors/gray}} (i18n/label :t/youre-on-mobile-network)]]
[quo/list-item
[list.item/list-item
{:title (i18n/label :t/mobile-network-use-mobile)
:accessibility-label "mobile-network-use-mobile"
:accessory :switch
@ -179,14 +180,3 @@
(if mobile
(if sync :main-icons/mobile-sync :main-icons/mobile-sync-off)
(when (#{:error :disabled} node) :main-icons/node-offline))))
(defview connectivity-button
[]
(letsubs [state [:connectivity/state]]
(when-let [icon (get-icon state)]
[quo/button
{:type :icon
:accessibility-label (str "conn-button-" (name icon))
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
{:content connectivity-sheet}])
:theme (if (= (:peers state) :offline) :negative :secondary)} icon])))

View File

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

View File

@ -0,0 +1,30 @@
(ns status-im.ui.components.controls.view
(:require [status-im.ui.components.controls.styles :as styles]
[status-im.ui.components.colors :as colors]
[react-native.core :as rn]
[status-im.ui.components.icons.icons :as icons]))
(defn switch
[{:keys [disabled value]}]
[rn/view
{:style (styles/switch-style value disabled)
:accessibility-label (str "switch-" (if value "on" "off"))
:accessibility-role :switch}
[rn/view {:style (styles/switch-bullet-style value false)}]])
(defn radio
[{:keys [disabled value]}]
[rn/view
{:style (styles/radio-style value disabled)
:accessibility-label (str "radio-" (if value "on" "off"))
:accessibility-role :radio}
[rn/view {:style (styles/radio-bullet-style value false)}]])
(defn checkbox
[{:keys [value disabled]}]
[rn/view
{:style (styles/checkbox-style value disabled)
:accessibility-label (str "checkbox-" (if value "on" "off"))
:accessibility-role :checkbox}
[rn/view {:style (styles/check-icon-style value)}
[icons/tiny-icon :tiny-icons/tiny-check {:color colors/white}]]])

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.copyable-text
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[reagent.core :as reagent]
[utils.i18n :as i18n]
[status-im.ui.components.animation :as animation]

View File

@ -0,0 +1,21 @@
(ns status-im.ui.components.core
(:require [status-im.ui.components.animated-header :as animated-header]
[status-im.ui.components.button.view :as button]
[status-im.ui.components.controls.view :as controls]
[status-im.ui.components.header :as header]
[status-im.ui.components.list.footer :as list-footer]
[status-im.ui.components.list.header :as list-header]
[status-im.ui.components.separator :as separator]
[status-im.ui.components.text :as text]
[status-im.ui.components.text-input :as text-input]))
(def text text/text)
(def header header/header)
(def animated-header animated-header/header)
(def text-input text-input/text-input)
(def button button/button)
(def list-header list-header/header)
(def list-footer list-footer/footer)
(def radio controls/radio)
(def separator separator/separator)

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.emoji-thumbnail.color-picker
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[status-im.ui.components.emoji-thumbnail.styles :as styles]))
(def emoji-picker-colors-row1

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.emoji-thumbnail.styles
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.emoji-thumbnail.utils :as emoji-utils]
[react-native.platform :as platform]))

View File

@ -1,11 +1,11 @@
(ns quo.components.header
(ns status-im.ui.components.header
(:require [oops.core :refer [oget]]
[quo.animated :as animated]
[quo.components.button.view :as button]
[quo.components.text :as text]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.react-native :as rn]
[react-native.reanimated :as animated]
[status-im.ui.components.button.view :as button]
[status-im.ui.components.text :as text]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.spacing :as spacing]
[react-native.core :as rn]
[reagent.core :as reagent]))
(def header-height 56)

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.icons.icons
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.react :as react])
(:refer-clojure :exclude [use])
(:require-macros [status-im.ui.components.icons.icons :as icons]))

View File

@ -1,7 +1,8 @@
(ns status-im.ui.components.invite.views
(:require [quo.core :as quo]
(:require [status-im.ui.components.core :as quo]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]))
[utils.i18n :as i18n]
[status-im.ui.components.list.item :as list.item]))
(defn button
[]
@ -12,7 +13,7 @@
(defn list-item
[{:keys [accessibility-label]}]
[quo/list-item
[list.item/list-item
{:theme :accent
:title (i18n/label :t/invite-friends)
:icon :main-icons/share

View File

@ -1,7 +1,7 @@
(ns quo.components.list.footer
(:require [quo.components.text :as text]
[quo.design-system.spacing :as spacing]
[quo.react-native :as rn]
(ns status-im.ui.components.list.footer
(:require [status-im.ui.components.text :as text]
[status-im.ui.components.spacing :as spacing]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn footer

View File

@ -1,7 +1,7 @@
(ns quo.components.list.header
(:require [quo.components.text :as text]
[quo.design-system.spacing :as spacing]
[quo.react-native :as rn]
(ns status-im.ui.components.list.header
(:require [status-im.ui.components.text :as text]
[status-im.ui.components.spacing :as spacing]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn header

View File

@ -1,14 +1,12 @@
(ns quo.components.list.item
(:require [quo.components.animated.pressable :as animated]
[quo.components.controls.view :as controls]
[quo.components.text :as text]
[quo.components.tooltip :as tooltip]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.haptic :as haptic]
[quo.platform :as platform]
[quo.react-native :as rn]
[status-im.ui.components.icons.icons :as icons]))
(ns status-im.ui.components.list.item
(:require [status-im.ui.components.controls.view :as controls]
[status-im.ui.components.text :as text]
[status-im.ui.components.tooltip :as tooltip]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.spacing :as spacing]
[status-im.ui.components.icons.icons :as icons]
[react-native.platform :as platform]
[react-native.core :as rn]))
(defn themes
[theme]
@ -174,7 +172,7 @@
[title-column props]])
(defn right-side
[{:keys [chevron active disabled accessory accessory-text accessory-style animated-accessory?]}]
[{:keys [chevron active disabled accessory accessory-text accessory-style]}]
(when (or chevron accessory)
[rn/view
{:style (merge {:align-items :center
@ -193,10 +191,7 @@
[rn/view {:style (:tiny spacing/padding-horizontal)}
(case accessory
:radio [controls/radio {:value active :disabled disabled}]
:checkbox [(if animated-accessory?
controls/animated-checkbox
controls/checkbox)
{:value active :disabled disabled}]
:checkbox [controls/checkbox {:value active :disabled disabled}]
:switch [controls/switch {:value active :disabled disabled}]
:text [text/text
{:color :secondary
@ -218,15 +213,12 @@
left-side-alignment icon-color icon-bg-color
title subtitle subtitle-secondary active on-press on-long-press chevron size text-size
accessory-text accessibility-label title-accessibility-label accessory-style
haptic-feedback haptic-type error animated animated-accessory? title-text-weight
error title-text-weight
container-style
active-background-enabled background-color]
:or {subtitle-max-lines 1
theme :main
haptic-feedback true
animated platform/ios?
active-background-enabled true
haptic-type :selection}}]
active-background-enabled true}}]
(let [theme (if disabled :disabled theme)
{:keys [text-color active-background passive-background]}
(themes theme)
@ -234,14 +226,10 @@
(:icon-color (themes theme)))
icon-bg-color (or icon-bg-color
(:icon-bg-color (themes theme)))
optional-haptic (fn []
(when haptic-feedback
(haptic/trigger haptic-type)))
component (cond
(and (not on-press)
(not on-long-press))
rn/view
animated animated/pressable
:else rn/touchable-highlight)]
[rn/view
{:background-color (cond (not= background-color nil)
@ -257,13 +245,9 @@
:accessibility-label accessibility-label
:underlay-color (:interactive-02 @colors/theme)}
(when on-press
{:on-press (fn []
(optional-haptic)
(on-press))})
{:on-press on-press})
(when on-long-press
{:on-long-press (fn []
(optional-haptic)
(on-long-press))}))
{:on-long-press on-long-press}))
[container {:size size :container-style container-style}
[left-side
{:icon-color icon-color
@ -289,7 +273,6 @@
:disabled disabled
:on-press on-press
:accessory-text accessory-text
:animated-accessory? animated-accessory?
:accessory-style accessory-style
:accessory accessory}]]]
(when error

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.list.styles
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.styles :as styles]))
(def item

View File

@ -1,6 +1,6 @@
(ns status-im.ui.components.plus-button
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [status-im.ui.components.core :as quo]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]))

View File

@ -1,9 +1,9 @@
(ns status-im.ui.components.profile-header.view
(:require [quo.animated :as animated]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.react-native :as rn]
(:require [react-native.reanimated :as animated]
[status-im.ui.components.core :as quo]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.spacing :as spacing]
[react-native.core :as rn]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.icons.icons :as icons]))

View File

@ -8,10 +8,10 @@
["react-native-image-crop-picker" :default image-picker]
["react-native-linear-gradient" :default LinearGradient]
["react-native-navigation" :refer (Navigation)]
[quo.design-system.colors :as colors]
[status-im.ui.components.colors :as colors]
[reagent.core :as reagent]
[utils.i18n :as i18n]
[status-im.ui.components.typography :as typography]
[status-im.ui.components.text-style :as typography]
[react-native.platform :as platform]
[status-im.utils.utils :as utils])
(:require-macros [status-im.utils.views :as views]))

View File

@ -1,6 +1,6 @@
(ns status-im.ui.components.search-input.view
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [status-im.ui.components.core :as quo]
[status-im.ui.components.colors :as colors]
[reagent.core :as reagent]
[utils.i18n :as i18n]))

View File

@ -1,6 +1,6 @@
(ns quo.components.separator
(:require [quo.design-system.colors :as colors]
[quo.react-native :as react]))
(ns status-im.ui.components.separator
(:require [status-im.ui.components.colors :as colors]
[react-native.core :as react]))
(defn separator
[{:keys [color style]}]

View File

@ -1,4 +1,4 @@
(ns quo.design-system.spacing)
(ns status-im.ui.components.spacing)
(def spacing
{:x-tiny 4

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.tabs
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.react :as react]))
(defn tab-title

View File

@ -1,8 +1,8 @@
(ns quo.components.text
(:require [quo.animated :as animated]
[quo.design-system.colors :as colors]
[quo.design-system.typography :as typography]
[quo.react-native :as rn]
(ns status-im.ui.components.text
(:require [react-native.reanimated :as animated]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.typography :as typography]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn text-style

View File

@ -1,13 +1,13 @@
(ns quo.components.text-input
(ns status-im.ui.components.text-input
(:require [clojure.spec.alpha :as s]
[oops.core :refer [ocall]]
[quo.components.text :as text]
[quo.components.tooltip :as tooltip]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.design-system.typography :as typography]
[quo.platform :as platform]
[quo.react-native :as rn] ;; TODO(Ferossgp): Move icon component to lib
[status-im.ui.components.text :as text]
[status-im.ui.components.tooltip :as tooltip]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.spacing :as spacing]
[status-im.ui.components.typography :as typography]
[react-native.platform :as platform]
[react-native.core :as rn] ;; TODO(Ferossgp): Move icon component to lib
[reagent.core :as reagent]
[status-im.ui.components.icons.icons :as icons]))

View File

@ -0,0 +1,71 @@
(ns status-im.ui.components.text-style
(:require [status-im.ui.components.colors :as colors]))
(def default-font-family "Inter")
(defn default-style
[]
{:color colors/black
:font-weight "400"
:font-size 15})
(def typography-styles
{:header {:font-weight "700"
:font-size 22}
:title-bold {:font-weight "700"
:font-size 17}
:title {:font-size 17}
:main-semibold {:font-weight "600"}
:main-medium {:font-weight "500"}
:caption {:font-size 12}
:timestamp {:font-size 10
:text-transform :uppercase}})
(defn get-style
[{:keys [typography] :as style}]
{:pre [(or (nil? typography) (contains? typography-styles typography))]}
(let [{:keys [font-weight font-style]
:as style}
(merge (default-style)
(get typography-styles
typography)
(dissoc style :typography :nested?))]
(-> style
(assoc :font-family
(str default-font-family
"-"
(case font-weight
"400" (when-not (= font-style :italic)
"Regular")
"500" "Medium"
"600" "SemiBold"
"700" "Bold")
(when (= font-style :italic)
"Italic")))
(dissoc :font-weight :font-style))))
(defn get-nested-style
[{:keys [typography] :as style}]
{:pre [(or (nil? typography) (contains? typography-styles typography))]}
(let [{:keys [font-weight font-style] :as style}
(merge (get typography-styles
typography)
(dissoc style :typography))]
(cond-> (dissoc style :font-weight :font-style)
(or font-weight font-style)
(assoc :font-family
(str default-font-family
"-"
(case font-weight
"500" "Medium"
"600" "SemiBold"
"700" "Bold"
(when-not (= font-style :italic)
"Regular"))
(when (= font-style :italic)
"Italic"))))))

View File

@ -1,6 +1,6 @@
(ns status-im.ui.components.toastable-highlight
"A wrapped touchable highlight that presents a toast when clicked"
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[reagent.core :as reagent]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.react :as react]))

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.toolbar
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.react :as react]))
(defn toolbar-container

View File

@ -1,17 +1,16 @@
(ns quo.components.tooltip
(ns status-im.ui.components.tooltip
(:require [oops.core :refer [oget]]
[quo.animated :as animated]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.platform :as platform] ;; FIXME(Ferossgp): Dependecy on status
[quo.react-native :as rn]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.spacing :as spacing]
[react-native.platform :as platform]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.ui.components.icons.icons :as icons]))
(def ^:private initial-height 22)
(defn tooltip-style
[{:keys [bottom-value animation]}]
[{:keys [bottom-value]}]
(merge
(:base spacing/padding-horizontal)
{:position :absolute
@ -19,8 +18,8 @@
:left 0
:right 0
:top (- bottom-value)
:opacity animation
:transform [{:translateY (animated/mix animation 10 0)}]}))
:opacity 1
:transform [{:translateY 10}]}))
(defn container-style
[]
@ -42,10 +41,6 @@
(defn tooltip
[]
(let [layout (reagent/atom {:height initial-height})
animation-v (animated/value 0)
animation (animated/with-timing-transition
animation-v
{:easing (:ease-in animated/easings)})
on-layout (fn [evt]
(let [width (oget evt "nativeEvent" "layout" "width")
height (oget evt "nativeEvent" "layout" "height")]
@ -53,15 +48,11 @@
:height height})))]
(fn [{:keys [bottom-value accessibility-label]} & children]
[:<>
[animated/code
{:exec (animated/cond* (animated/not* animation-v)
(animated/set animation-v 1))}]
[animated/view
[rn/view
{:style (tooltip-style {:bottom-value (- (get @layout :height)
bottom-value)
:animation animation})
bottom-value)})
:pointer-events :box-none}
[animated/view
[rn/view
{:style (container-style)
:pointer-events :box-none}
(into [rn/view

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.tooltip.styles
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im2.config :as config]
[status-im.utils.styles :as styles]))

View File

@ -1,5 +1,5 @@
(ns status-im.ui.components.tooltip.views
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]

View File

@ -1,6 +1,6 @@
(ns status-im.ui.components.topbar
(:require [re-frame.core :as re-frame]
[quo.core :as quo]
[status-im.ui.components.core :as quo]
[quo2.foundations.colors :as quo2.colors]
[react-native.safe-area :as safe-area]))

View File

@ -1,71 +1,39 @@
(ns status-im.ui.components.typography
(:require [quo.design-system.colors :as colors]))
(ns status-im.ui.components.typography)
(def default-font-family "Inter")
(defn default-style
[]
{:color colors/black
:font-weight "400"
:font-size 15})
(def tiny
{:font-size 10
:line-height 14})
(def typography-styles
{:header {:font-weight "700"
:font-size 22}
(def x-small
{:font-size 12
:line-height 16})
:title-bold {:font-weight "700"
:font-size 17}
(def small
{:font-size 13
:line-height 18})
:title {:font-size 17}
(def base
{:font-size 15
:line-height 22})
:main-semibold {:font-weight "600"}
(def large
{:font-size 17
:line-height 24})
:main-medium {:font-weight "500"}
(def x-large
{:font-size 22
:line-height 30})
:caption {:font-size 12}
(def xx-large
{:font-size 28
:line-height 38})
:timestamp {:font-size 10
:text-transform :uppercase}})
(def font-regular {:font-family "Inter-Regular"}) ; 400
(defn get-style
[{:keys [typography] :as style}]
{:pre [(or (nil? typography) (contains? typography-styles typography))]}
(let [{:keys [font-weight font-style]
:as style}
(merge (default-style)
(get typography-styles
typography)
(dissoc style :typography :nested?))]
(-> style
(assoc :font-family
(str default-font-family
"-"
(case font-weight
"400" (when-not (= font-style :italic)
"Regular")
"500" "Medium"
"600" "SemiBold"
"700" "Bold")
(when (= font-style :italic)
"Italic")))
(dissoc :font-weight :font-style))))
(def font-medium {:font-family "Inter-Medium"}) ; 500 ff
(defn get-nested-style
[{:keys [typography] :as style}]
{:pre [(or (nil? typography) (contains? typography-styles typography))]}
(let [{:keys [font-weight font-style] :as style}
(merge (get typography-styles
typography)
(dissoc style :typography))]
(cond-> (dissoc style :font-weight :font-style)
(or font-weight font-style)
(assoc :font-family
(str default-font-family
"-"
(case font-weight
"500" "Medium"
"600" "SemiBold"
"700" "Bold"
(when-not (= font-style :italic)
"Regular"))
(when (= font-style :italic)
"Italic"))))))
(def font-semi-bold {:font-family "Inter-SemiBold"}) ; 600
(def font-bold {:font-family "Inter-Bold"}) ; 700
(def monospace {:font-family "InterStatus-Regular"})

View File

@ -1,6 +1,5 @@
(ns status-im.ui.screens.about-app.views
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[status-im2.constants :refer
[principles-link privacy-policy-link terms-of-service-link]]
@ -8,7 +7,8 @@
[status-im.ui.components.copyable-text :as copyable-text]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.components.webview :refer [webview]])
[status-im.ui.components.webview :refer [webview]]
[status-im.ui.components.list.item :as list.item])
(:require-macros [status-im.utils.views :as views]))
(views/defview about-app
@ -17,14 +17,14 @@
commit-hash [:get-commit-hash]
node-version [:get-app-node-version]]
[react/scroll-view
[quo/list-item
[list.item/list-item
{:size :small
:title (i18n/label :t/privacy-policy)
:accessibility-label :privacy-policy
:on-press
#(re-frame/dispatch [:navigate-to :privacy-policy])
:chevron true}]
[quo/list-item
[list.item/list-item
{:size :small
:title (i18n/label :t/terms-of-service)
:accessibility-label :terms-of-service
@ -32,7 +32,7 @@
:chevron true}]
[copyable-text/copyable-text-view
{:copied-text app-version}
[quo/list-item
[list.item/list-item
{:size :small
:accessibility-label :app-version
:title (i18n/label :t/version)
@ -40,7 +40,7 @@
:accessory-text app-version}]]
[copyable-text/copyable-text-view
{:copied-text commit-hash}
[quo/list-item
[list.item/list-item
{:size :small
:accessibility-label :commit-hash
:title (i18n/label :t/app-commit)
@ -48,7 +48,7 @@
:accessory-text commit-hash}]]
[copyable-text/copyable-text-view
{:copied-text node-version}
[quo/list-item
[list.item/list-item
{:size :small
:accessibility-label :node-version
:title (i18n/label :t/node-version)

View File

@ -1,8 +1,9 @@
(ns status-im.ui.screens.advanced-settings.views
(:require [quo.core :as quo]
(:require [status-im.ui.components.core :as quo]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.ui.components.list.views :as list])
[status-im.ui.components.list.views :as list]
[status-im.ui.components.list.item :as list.item])
(:require-macros [status-im.utils.views :as views]))
(defn- normal-mode-settings-data
@ -111,7 +112,7 @@
[props]
(if (= (:type props) :section-header)
[quo/list-header (:title props)]
[quo/list-item props]))
[list.item/list-item props]))
(views/defview advanced-settings
[]

View File

@ -1,7 +1,7 @@
(ns status-im.ui.screens.appearance.views
(:require-macros [status-im.utils.views :as views])
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [status-im.ui.components.core :as quo]
[status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.react-native.resources :as resources]

View File

@ -1,11 +1,11 @@
(ns status-im.ui.screens.backup-settings.view
(:require-macros [status-im.utils.views :as views])
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.ui.components.react :as react]
[utils.datetime :as datetime]))
[utils.datetime :as datetime]
[status-im.ui.components.list.item :as list.item]))
(defn perform-backup!
[]
@ -36,7 +36,7 @@
performing-backup? [:backup/performing-backup]]
[:<>
[react/scroll-view
[quo/list-item
[list.item/list-item
{:size :small
:title (i18n/label :t/backup-through-waku)
:accessibility-label :backup-enabled
@ -46,7 +46,7 @@
[:multiaccounts.ui/switch-backup-enabled (not backup-enabled?)])
:accessory :switch
:active backup-enabled?}]
[quo/list-item
[list.item/list-item
{:size :small
:title (i18n/label :t/last-backup-performed)
:accessory :text

View File

@ -1,5 +1,5 @@
(ns status-im.ui.screens.bootnodes-settings.edit-bootnode.styles
(:require [quo.design-system.colors :as colors]
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.styles :as styles]))
(def edit-bootnode-view

View File

@ -1,6 +1,6 @@
(ns status-im.ui.screens.bootnodes-settings.edit-bootnode.views
(:require [clojure.string :as string]
[quo.core :as quo]
[status-im.ui.components.core :as quo]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.qr-scanner.core :as qr-scanner]

View File

@ -1,15 +1,15 @@
(ns status-im.ui.screens.browser.accounts
(:require [quo.core :as quo]
[re-frame.core :as re-frame]
(:require [re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.utils.utils :as utils]))
[status-im.utils.utils :as utils]
[status-im.ui.components.list.item :as list.item]))
(defn render-account
[account _ _ dapps-account]
[quo/list-item
[list.item/list-item
(merge {:accessory :radio
:active (= (:address dapps-account) (:address account))
:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]

View File

@ -1,7 +1,7 @@
(ns status-im.ui.screens.browser.bookmarks.views
(:require [clojure.string :as string]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[status-im.ui.components.core :as quo]
[status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[utils.i18n :as i18n]

View File

@ -1,13 +1,14 @@
(ns status-im.ui.screens.browser.eip3085.sheet
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [status-im.ui.components.core :as quo]
[status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.copyable-text :as copyable-text]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.screens.browser.styles :as styles])
[status-im.ui.screens.browser.styles :as styles]
[status-im.ui.components.list.item :as list.item])
(:require-macros [status-im.utils.views :as views]))
(views/defview permissions-panel
@ -42,7 +43,7 @@
[react/scroll-view
[copyable-text/copyable-text-view
{:copied-text (:name (:new-network params))}
[quo/list-item
[list.item/list-item
{:size :small
:accessibility-label :network-name
:title "Network Name"
@ -50,7 +51,7 @@
:accessory-text (:name (:new-network params))}]]
[copyable-text/copyable-text-view
{:copied-text (get-in params [:new-network :config :UpstreamConfig :URL])}
[quo/list-item
[list.item/list-item
{:size :small
:accessibility-label :network-url
:title "Network URL"
@ -58,7 +59,7 @@
:accessory-text (get-in params [:new-network :config :UpstreamConfig :URL])}]]
[copyable-text/copyable-text-view
{:copied-text (str (get-in params [:new-network :config :NetworkId]))}
[quo/list-item
[list.item/list-item
{:size :small
:accessibility-label :network-id
:title "Chain ID"

View File

@ -1,6 +1,6 @@
(ns status-im.ui.screens.browser.eip3326.sheet
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [status-im.ui.components.core :as quo]
[status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.network.core :as network]

View File

@ -1,5 +1,5 @@
(ns status-im.ui.screens.browser.empty-tab.styles
(:require [quo.design-system.colors :as colors]))
(:require [status-im.ui.components.colors :as colors]))
(def input
{:height 36

Some files were not shown because too many files have changed in this diff Show More