Fix & optimize shadows foundation (#16553)
Rewrite the shadows foundation API: - Fix (implementation & usages): theme changes were not causing shadows to be reevaluated. - Optimization: define all possible shadow values at compile time. Good to reduce cycles on garbage collection since recreating the shadow map all the time is unnecessary and also to save cycles on computing colors since calls to colors/alpha are not memoized. - API redesign: unify access to Design System shadows in a single function. None of the actual shadow values changed. Fixes https://github.com/status-im/status-mobile/issues/16526 API rationale ============= The quo2.foundations.shadows namespace reflects what's in the Design System > Foundations > Shadows https://www.figma.com/file/v98g9ZiaSHYUdKWrbFg9eM/Foundations?type=design&node-id=624-965&mode=design&t=CvIotdjbHKHcHjpd-0). Figma users see these shadows in other components as "Shadow/Normal/Light/03". Notice the shadow's weight is shown as a number (not the semantic name in Figma, e.g. "intense", "strong"): So to make things as easy as possible, I opted for exposing a single public function named "get", which receives arguments in order of frequency of usage and which expects shadow weights as numbers so that devs don't need to mentally translate 1 to "soft", or 3 to "intense".
This commit is contained in:
parent
6170686e34
commit
6c28e9349f
|
@ -62,4 +62,4 @@
|
|||
(and pressed? (= type :discover))
|
||||
(colors/theme-colors colors/white :transparent theme))}
|
||||
(when (and (= type :discover) (not pressed?))
|
||||
(:shadow-3 shadows/normal-scale))))
|
||||
(shadows/get 3))))
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
:background-color :transparent})
|
||||
|
||||
(defn content-container
|
||||
[override-theme]
|
||||
[theme]
|
||||
(merge
|
||||
(:shadow-1 shadows/normal-scale)
|
||||
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
|
||||
(shadows/get 1 theme)
|
||||
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
:flex-direction :row
|
||||
:padding-vertical 8
|
||||
:padding-horizontal 12}))
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
:background-color :transparent})
|
||||
|
||||
(defn content-container
|
||||
[override-theme]
|
||||
[theme]
|
||||
(merge
|
||||
(:shadow-1 shadows/normal-scale)
|
||||
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
|
||||
(shadows/get 1 theme)
|
||||
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical 8
|
||||
|
|
|
@ -1,66 +1,77 @@
|
|||
(ns quo2.foundations.shadows
|
||||
(:refer-clojure :exclude [get])
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]))
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn- get-inverted
|
||||
[inverted? number]
|
||||
(if inverted? (* -1 number) number))
|
||||
|
||||
(defn- get-scales
|
||||
[inverted?]
|
||||
(if (theme/dark?)
|
||||
{:shadow-1 {:shadow-color (colors/alpha colors/neutral-100 0.5)
|
||||
:shadow-offset {:width 0
|
||||
:height (get-inverted inverted? 4)}
|
||||
(def ^:private shadows
|
||||
(let [dark-normal {1 {:shadow-color (colors/alpha colors/neutral-100 0.5)
|
||||
:shadow-offset {:width 0 :height 4}
|
||||
:elevation 3
|
||||
:shadow-opacity 1
|
||||
:shadow-radius 20}
|
||||
:shadow-2 {:shadow-color (colors/alpha colors/neutral-100 0.64)
|
||||
:shadow-offset {:width 0
|
||||
:height (get-inverted inverted? 4)}
|
||||
2 {:shadow-color (colors/alpha colors/neutral-100 0.64)
|
||||
:shadow-offset {:width 0 :height 4}
|
||||
:elevation 4
|
||||
:shadow-opacity 1
|
||||
:shadow-radius 20}
|
||||
:shadow-3 {:shadow-color (colors/alpha colors/neutral-100 0.64)
|
||||
:shadow-offset {:width 0
|
||||
:height (get-inverted inverted? 12)}
|
||||
3 {:shadow-color (colors/alpha colors/neutral-100 0.64)
|
||||
:shadow-offset {:width 0 :height 12}
|
||||
:elevation 8
|
||||
:shadow-opacity 1
|
||||
:shadow-radius 20}
|
||||
:shadow-4 {:shadow-color (colors/alpha colors/neutral-100 0.72)
|
||||
:shadow-offset {:width 0
|
||||
:height (get-inverted inverted? 16)}
|
||||
4 {:shadow-color (colors/alpha colors/neutral-100 0.72)
|
||||
:shadow-offset {:width 0 :height 16}
|
||||
:shadow-opacity 1
|
||||
:shadow-radius 20
|
||||
:elevation 15}}
|
||||
{:shadow-1 {:shadow-color (colors/alpha colors/neutral-100 0.04)
|
||||
:shadow-offset {:width 0
|
||||
:height (get-inverted inverted? 4)}
|
||||
dark-normal-inverted (-> dark-normal
|
||||
(update-in [:soft :shadow-offset :height] -)
|
||||
(update-in [:medium :shadow-offset :height] -)
|
||||
(update-in [:intense :shadow-offset :height] -)
|
||||
(update-in [:strong :shadow-offset :height] -))
|
||||
light-normal {1 {:shadow-color (colors/alpha colors/neutral-100 0.04)
|
||||
:shadow-offset {:width 0 :height 4}
|
||||
:elevation 1
|
||||
:shadow-opacity 1
|
||||
:shadow-radius 16}
|
||||
:shadow-2 {:shadow-color (colors/alpha colors/neutral-100 0.08)
|
||||
:shadow-offset {:width 0
|
||||
:height (get-inverted inverted? 4)}
|
||||
2 {:shadow-color (colors/alpha colors/neutral-100 0.08)
|
||||
:shadow-offset {:width 0 :height 4}
|
||||
:elevation 2
|
||||
:shadow-opacity 1
|
||||
:shadow-radius 16}
|
||||
:shadow-3 {:shadow-color (colors/alpha colors/neutral-100 0.12)
|
||||
:shadow-offset {:width 0
|
||||
:height (get-inverted inverted? 12)}
|
||||
3 {:shadow-color (colors/alpha colors/neutral-100 0.12)
|
||||
:shadow-offset {:width 0 :height 12}
|
||||
:elevation 5
|
||||
:shadow-opacity 1
|
||||
:shadow-radius 16}
|
||||
:shadow-4 {:shadow-color (colors/alpha colors/neutral-100 0.16)
|
||||
:shadow-offset {:width 0
|
||||
:height (get-inverted inverted? 16)}
|
||||
4 {:shadow-color (colors/alpha colors/neutral-100 0.16)
|
||||
:shadow-offset {:width 0 :height 16}
|
||||
:shadow-opacity 1
|
||||
:shadow-radius 16
|
||||
:elevation 13}}))
|
||||
:elevation 13}}
|
||||
light-normal-inverted (-> light-normal
|
||||
(update-in [:soft :shadow-offset :height] -)
|
||||
(update-in [:medium :shadow-offset :height] -)
|
||||
(update-in [:intense :shadow-offset :height] -)
|
||||
(update-in [:strong :shadow-offset :height] -))]
|
||||
{:dark {:normal dark-normal :inverted dark-normal-inverted}
|
||||
:light {:normal light-normal :inverted light-normal-inverted}}))
|
||||
|
||||
(def normal-scale (get-scales false))
|
||||
(defn get
|
||||
"Get the appropriate shadow map for a given shadow `weight`, `theme`, and `scale-type`.
|
||||
|
||||
(def inverted-scale (get-scales true))
|
||||
Return nil if no shadow is found.
|
||||
|
||||
`weight` - int (required) from 1 to 4.
|
||||
`theme` - :light/:dark (optional).
|
||||
`scale-type` - :normal/:inverted (optional).
|
||||
"
|
||||
([weight]
|
||||
(get weight (quo.theme/get-theme)))
|
||||
([weight theme]
|
||||
(get weight theme :normal))
|
||||
([weight theme scale-type]
|
||||
(get-in shadows [theme scale-type weight])))
|
||||
|
||||
(def inner-shadow
|
||||
{:shadow-color (colors/alpha colors/neutral-100 0.08)
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
[last-item?]
|
||||
;; This part needs to be improved, inverted shadow is not supported in android
|
||||
;; https://reactnative.dev/docs/shadow-props#shadowoffset-ios
|
||||
;; (merge
|
||||
;; (:shadow-1 (shadows/get-scales true :dark))
|
||||
;;
|
||||
;; (merge (shadows/get 1 :dark :inverted) ...)
|
||||
;;
|
||||
{:padding-horizontal 20
|
||||
:margin-bottom (when-not last-item? -24)})
|
||||
|
||||
|
|
|
@ -1,65 +1,65 @@
|
|||
(ns status-im2.contexts.quo-preview.foundations.shadows
|
||||
(:require
|
||||
[quo2.foundations.shadows :as shadows]
|
||||
(:require [quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.shadows :as shadows]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(defn demo-box
|
||||
[shadow-on? name shadow-style]
|
||||
[shadow? description shadow-style]
|
||||
[rn/view
|
||||
{:margin-left :auto
|
||||
{:style {:margin-left :auto
|
||||
:margin-right :auto
|
||||
:margin-top 8
|
||||
:margin-bottom 8
|
||||
:align-items :center}
|
||||
[quo/text {} name]
|
||||
:align-items :center}}
|
||||
[quo/text {} description]
|
||||
[rn/view
|
||||
{:style (merge {:width 60
|
||||
:height 60
|
||||
:border-radius 16
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-90)}
|
||||
(when shadow-on? shadow-style))}]])
|
||||
(when shadow? shadow-style))}]])
|
||||
|
||||
(def descriptor
|
||||
[{:label "Shadow on?"
|
||||
:key :shadow-on?
|
||||
[{:label "Shadows enabled?"
|
||||
:key :shadow?
|
||||
:type :boolean}])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:shadow-on? true})]
|
||||
(let [state (reagent/atom {:shadow? true})
|
||||
shadow? (reagent/cursor state [:shadow?])]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view {:padding-bottom 150}
|
||||
[rn/view {:style {:padding-bottom 150}}
|
||||
[preview/customizer state descriptor]
|
||||
[:<>
|
||||
[quo/text
|
||||
{:style {:margin-left :auto
|
||||
:margin-right :auto
|
||||
:align-items :center}}
|
||||
"Normal Scales"]
|
||||
[demo-box (:shadow-on? @state) "shadow 1" (:shadow-1 shadows/normal-scale)]
|
||||
[demo-box (:shadow-on? @state) "shadow 2" (:shadow-2 shadows/normal-scale)]
|
||||
[demo-box (:shadow-on? @state) "shadow 3" (:shadow-3 shadows/normal-scale)]
|
||||
[demo-box (:shadow-on? @state) "shadow 4" (:shadow-4 shadows/normal-scale)]
|
||||
[demo-box @shadow? "Shadow 1" (shadows/get 1)]
|
||||
[demo-box @shadow? "Shadow 2" (shadows/get 2)]
|
||||
[demo-box @shadow? "Shadow 3" (shadows/get 3)]
|
||||
[demo-box @shadow? "Shadow 4" (shadows/get 4)]
|
||||
[quo/text
|
||||
{:style {:margin-left :auto
|
||||
:margin-right :auto
|
||||
:align-items :center}}
|
||||
"Inverted Scales"]
|
||||
[demo-box (:shadow-on? @state) "shadow 1" (:shadow-1 shadows/inverted-scale)]
|
||||
[demo-box (:shadow-on? @state) "shadow 2" (:shadow-2 shadows/inverted-scale)]
|
||||
[demo-box (:shadow-on? @state) "shadow 3" (:shadow-3 shadows/inverted-scale)]
|
||||
[demo-box (:shadow-on? @state) "shadow 4" (:shadow-4 shadows/inverted-scale)]
|
||||
[demo-box @shadow? "Shadow 1" (shadows/get 1 (quo.theme/get-theme) :inverted)]
|
||||
[demo-box @shadow? "Shadow 2" (shadows/get 2 (quo.theme/get-theme) :inverted)]
|
||||
[demo-box @shadow? "Shadow 3" (shadows/get 3 (quo.theme/get-theme) :inverted)]
|
||||
[demo-box @shadow? "Shadow 4" (shadows/get 4 (quo.theme/get-theme) :inverted)]
|
||||
[quo/text
|
||||
{:style {:margin-left :auto
|
||||
:margin-right :auto
|
||||
:align-items :center}}
|
||||
"Inverted Scales"]
|
||||
[demo-box (:shadow-on? @state) "Inner Shadow" shadows/inner-shadow]]]])))
|
||||
[demo-box @shadow? "Inner Shadow" shadows/inner-shadow]]])))
|
||||
|
||||
(defn preview-shadows
|
||||
[]
|
||||
|
|
Loading…
Reference in New Issue