remove quo lib (#17626)
This commit is contained in:
parent
ff2dfe1a2f
commit
27cd7d4edd
|
@ -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
|
||||
|
|
|
@ -700,7 +700,7 @@ SPEC CHECKSUMS:
|
|||
FBLazyVector: a8af91c2b5a0029d12ff6b32e428863d63c48991
|
||||
FBReactNativeSpec: 1b2309b096448a1dc9d0c43999216f8fda809ae8
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 166d178815c300e8126de9a7900101814eb16253
|
||||
glog: d93527a855523adb8c113837db4be68fb00e230d
|
||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
|
||||
|
|
|
@ -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.
|
|
@ -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])))
|
|
@ -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)))
|
|
@ -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]))
|
|
@ -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})
|
|
@ -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)))
|
|
@ -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)})
|
|
@ -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)))
|
|
@ -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]]])
|
|
@ -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)
|
|
@ -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"})
|
|
@ -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")})
|
|
@ -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)))
|
|
@ -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"))
|
|
@ -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}]]))
|
|
@ -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}]])
|
|
@ -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 %)}]]])))
|
|
@ -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}]])
|
|
@ -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]])])
|
|
@ -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}]])
|
|
@ -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}])
|
|
@ -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)))
|
|
@ -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"}]}])
|
|
@ -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}]])
|
|
@ -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}]])
|
|
@ -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}]])
|
|
@ -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)))
|
||||
|
||||
|
|
@ -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 [])))
|
|
@ -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}))
|
|
@ -1,4 +0,0 @@
|
|||
(ns quo.spec
|
||||
(:require [clojure.spec.alpha :as s]))
|
||||
|
||||
(s/def ::style (s/nilable map?))
|
|
@ -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))
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]))
|
||||
|
||||
|
|
|
@ -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]}]
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]))
|
|
@ -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]))
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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}]])]]]))
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -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
|
|
@ -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]
|
||||
|
|
|
@ -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])))
|
||||
|
|
|
@ -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)})
|
|
@ -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}]]])
|
|
@ -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]
|
||||
|
|
|
@ -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)
|
|
@ -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
|
||||
|
|
|
@ -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]))
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -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]))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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]))
|
||||
|
||||
|
|
|
@ -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]))
|
||||
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -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]))
|
||||
|
||||
|
|
|
@ -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]}]
|
|
@ -1,4 +1,4 @@
|
|||
(ns quo.design-system.spacing)
|
||||
(ns status-im.ui.components.spacing)
|
||||
|
||||
(def spacing
|
||||
{:x-tiny 4
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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]))
|
||||
|
|
@ -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"))))))
|
|
@ -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]))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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]))
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]))
|
||||
|
||||
|
|
|
@ -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"})
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
[]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue