Skip to content

Commit

Permalink
Merge branch 'develop' into feature/15702-mention-styles
Browse files Browse the repository at this point in the history
  • Loading branch information
cammellos authored Apr 25, 2023
2 parents 904c1e7 + 1e4a49f commit f36ddad
Show file tree
Hide file tree
Showing 58 changed files with 1,666 additions and 81 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# Xcode
#
/ios/.xcode.env.local
/component-spec
result/
build/
Expand Down
79 changes: 75 additions & 4 deletions doc/new-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,50 @@ Pay special attention to:

## Dos and don'ts

### Hiccup

Never use anonymous inline function in hiccup, this will lead to reinitialization of component on each render of parent component

```clojure
;; bad
(defn checkbox-view
[{:keys [size]}]
[rn/view
[(fn [] [rn/view])]])

;; good
(defn comp []
[rn/view])

(defn checkbox-view
[{:keys [size]}]
[rn/view
[comp]])
```

This mistake mostly happens with functional components

```clojure
;; bad
(fn []
(let [atom (rf/sub [:sub])]
(fn []
[:f>
(fn []
[rn/text atom]

;; good
(defn f-comp [atom]
[rn/text atom])

(fn []
(let [atom (rf/sub [:sub])]
(fn []
[:f> f-comp atom])))
```

it's important to name functional components with `f-` prefix

### Component styles

Prefer to define styles in a separate file named `style.cljs`, colocated with
Expand Down Expand Up @@ -90,11 +134,38 @@ their styles in the top-level of the properties map, prefer to add them inside t
]
```

### Always apply animated styles in the style file
Also its fine to keep one liner styles in view

```clojure
;; ok
[rn/view {:style {:flex 1 :padding-top 5}}]
```

### Don't define properties in styles ns

Properties must be set on view level

```clojure
;; bad
{:style {:position :absolute
:left 0
:right 0
:bottom 0}
:blur-amount 30
:blur-radius 25
:blur-type :transparent
:overlay-color :transparent}

;; good
{:position :absolute
:left 0
:right 0
:bottom 0}
```


### Apply animated styles in the style file

When implementing styles for reanimated views, we should always define
them in the style file and apply animations with reanimated/apply-animations-to-style
in the style definition.

```clojure
;; bad
Expand Down
Binary file modified resources/images/icons2/20x20/audio@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/audio@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/camera@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/camera@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/format@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/format@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/image@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/image@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/reaction@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/images/icons2/20x20/reaction@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/mocks/js_dependencies.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
{:ClipPath #js {:render identity}
:Circle #js {:render identity}
:Defs #js {:render identity}
:G #js {:render identity}
:Path #js {:render identity}
:Rect #js {:render identity}
:SvgUri #js {:render identity}
Expand Down
40 changes: 27 additions & 13 deletions src/quo2/components/icon.cljs
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
(ns quo2.components.icon
(:require [clojure.string :as string]
[quo2.components.icons.icons :as icons]
[quo2.components.icons.svg :as icons.svg]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))

(defn- valid-color?
[color]
(or (keyword? color)
(and (string? color)
(not (string/blank? color)))))

(defn memo-icon-fn
([icon-name] (memo-icon-fn icon-name nil))
([icon-name
{:keys [color container-style size
accessibility-label no-color]
{:keys [color color-2 no-color
container-style size accessibility-label]
:or {accessibility-label :icon}}]
(let [size (or size 20)]
^{:key icon-name}
[rn/image
{:style
(merge {:width size
:height size}
(if-let [svg-icon (icons.svg/get-icon icon-name size)]
[svg-icon
{:size size
:color (when (valid-color? color) color)
:color-2 (when (valid-color? color-2) color-2)
:accessibility-label accessibility-label
:style container-style}]
[rn/image
{:style
(merge {:width size
:height size}

(when (not no-color)
{:tint-color (if (and (string? color) (not (string/blank? color)))
color
(colors/theme-colors colors/neutral-100 colors/white))})
(when (not no-color)
{:tint-color (if (and (string? color) (not (string/blank? color)))
color
(colors/theme-colors colors/neutral-100 colors/white))})

container-style)
:accessibility-label accessibility-label
:source (icons/icon-source (str (name icon-name) size))}])))
container-style)
:accessibility-label accessibility-label
:source (icons/icon-source (str (name icon-name) size))}]))))

(def icon (memoize memo-icon-fn))
8 changes: 4 additions & 4 deletions src/quo2/components/icons/icons.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
(:require [clojure.java.io :as io]
[clojure.string :as string]))

(def icon-path "./resources/images/icons2/")
(def ^:private icon-path "./resources/images/icons2/")

(defn require-icon
(defn- require-icon
[size path]
(fn [el]
(let [s (str "." path el ".png")
Expand All @@ -15,15 +15,15 @@
(str size))]
[k `(js/require ~s)])))

(defn get-files
(defn- get-files
[path]
(->> (io/file path)
file-seq
(filter #(string/ends-with? % "png"))
(map #(first (string/split (.getName %) #"@")))
distinct))

(defn get-icons
(defn- get-icons
[size]
(let [path (str icon-path size "x" size "/")]
(into {} (map (require-icon size path) (get-files path)))))
Expand Down
2 changes: 1 addition & 1 deletion src/quo2/components/icons/icons.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
(:require-macros [quo2.components.icons.icons :as icons])
(:require [taoensso.timbre :as log]))

(def icons (icons/resolve-icons))
(def ^:private icons (icons/resolve-icons))

(defn icon-source
[icon]
Expand Down
48 changes: 48 additions & 0 deletions src/quo2/components/icons/svg.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
(ns quo2.components.icons.svg
"Declare icons in this namespace when they have two possible colors, because the
ReactNative `:tint-color` prop affects all non-transparent pixels of PNGs. If
the icon has only one color, prefer a PNG.
Keep all SVG components private and expose them by name in the `icons` var."
(:require [react-native.svg :as svg]
[quo2.foundations.colors :as colors]))

(defn- container
[{:keys [size accessibility-label style]
:or {size 20}}
& children]
(into [svg/svg
{:accessibility-label accessibility-label
:style style
:width size
:height size
:view-box (str "0 0 " size " " size)
:fill :none}]
children))

(defn- clear-20
[{:keys [color color-2] :as props}]
(let [color (or color colors/neutral-100)
color-2 (or color-2 colors/white)]
[container props
[svg/path
{:d
"M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z"
:fill color}]
[svg/path
{:d
"M9.15142 9.99998L7.07566 12.0757L7.9242 12.9243L9.99994 10.8485L12.0757 12.9242L12.9242 12.0757L10.8485 9.99998L12.9242 7.92421L12.0757 7.07568L9.99994 9.15145L7.92421 7.07572L7.07568 7.92425L9.15142 9.99998Z"
:fill color-2}]]))

(def ^:private icons
{:i/clear-20 clear-20})

(defn- append-to-keyword
[k & xs]
(keyword (apply str
(subs (str k) 1)
xs)))

(defn get-icon
[icon-name size]
(get icons (append-to-keyword icon-name "-" size)))
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(ns quo2.components.inputs.recovery-phrase.component-spec
(:require [quo2.components.inputs.recovery-phrase.view :as recovery-phrase]
[test-helpers.component :as h]))

(h/describe "Recovery phrase input"
(h/test "Default render"
(h/render [recovery-phrase/recovery-phrase-input {}])
(h/is-truthy (h/get-by-label-text :recovery-phrase-input))))
45 changes: 45 additions & 0 deletions src/quo2/components/inputs/recovery_phrase/style.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
(ns quo2.components.inputs.recovery-phrase.style
(:require [quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))

(def container
{:min-height 40
:flex 1
:padding-vertical 4
:padding-horizontal 20})

(defn input
[]
(assoc (text/text-style {})
:height 32
:flex-grow 1
:padding-vertical 5
:text-align-vertical :top))

(defn placeholder-color
[input-state override-theme blur?]
(cond
(and (= input-state :focused) blur?)
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 override-theme)

(= input-state :focused) ; Not blur
(colors/theme-colors colors/neutral-30 colors/neutral-60 override-theme)

blur? ; :default & blur
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 override-theme)

:else ; :default & not blur
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))

(defn cursor-color
[customization-color override-theme]
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
override-theme))

(defn error-word
[]
{:height 22
:padding-horizontal 20
:background-color colors/danger-50-opa-10
:color (colors/theme-colors colors/danger-50 colors/danger-60)})
54 changes: 54 additions & 0 deletions src/quo2/components/inputs/recovery_phrase/view.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
(ns quo2.components.inputs.recovery-phrase.view
(:require [clojure.string :as string]
[quo2.components.inputs.recovery-phrase.style :as style]
[react-native.core :as rn]
[reagent.core :as reagent]))

(def ^:private custom-props
[:customization-color :override-theme :blur? :cursor-color :multiline :on-focus :on-blur
:placeholder-text-color :mark-errors? :error-pred :word-limit])

(defn- error-word
[text]
[rn/text {:style (style/error-word)}
text])

(defn- mark-error-words
[pred text word-limit]
(let [word-limit (or word-limit ##Inf)]
(into [:<>]
(comp (map-indexed (fn [idx word]
(if (or (pred word) (>= idx word-limit))
[error-word word]
word)))
(interpose " "))
(string/split text #" "))))

(defn recovery-phrase-input
[_ _]
(let [state (reagent/atom :default)
set-focused #(reset! state :focused)
set-default #(reset! state :default)]
(fn [{:keys [customization-color override-theme blur? on-focus on-blur mark-errors?
error-pred word-limit]
:or {customization-color :blue}
:as props}
text]
(let [extra-props (apply dissoc props custom-props)]
[rn/view {:style style/container}
[rn/text-input
(merge {:accessibility-label :recovery-phrase-input
:style (style/input)
:placeholder-text-color (style/placeholder-color @state override-theme blur?)
:cursor-color (style/cursor-color customization-color override-theme)
:multiline true
:on-focus (fn []
(set-focused)
(when on-focus (on-focus)))
:on-blur (fn []
(set-default)
(when on-blur (on-blur)))}
extra-props)
(if mark-errors?
(mark-error-words error-pred text word-limit)
text)]]))))
2 changes: 1 addition & 1 deletion src/quo2/components/inputs/search_input/style.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
[blur? override-theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
(colors/theme-colors colors/neutral-40 colors/neutral-60 override-theme)))

(defn cursor
[customization-color override-theme]
Expand Down
4 changes: 0 additions & 4 deletions src/quo2/components/links/url_preview/style.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@
{:text-transform :lowercase
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)})

(def clear-button
{:border-color colors/danger-50
:border-width 1})

(def clear-button-container
{:width 20
:height 20
Expand Down
5 changes: 2 additions & 3 deletions src/quo2/components/links/url_preview/view.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@
:hit-slop {:top 3 :right 3 :bottom 3 :left 3}
:accessibility-label :button-clear-preview}
[icon/icon :i/clear
{:size 20
:container-style style/clear-button
:color (colors/theme-colors colors/neutral-50 colors/neutral-60)}]])
{:size 20
:color (colors/theme-colors colors/neutral-50 colors/neutral-60)}]])

(defn view
[{:keys [title body logo on-clear loading? loading-message container-style]}]
Expand Down
Loading

0 comments on commit f36ddad

Please sign in to comment.