Quo2: Color picker (#17405)

* Quo2: color picker
This commit is contained in:
Omar Basem 2023-09-27 15:34:16 +04:00 committed by GitHub
parent 79f7b6c6ba
commit 77733b3a65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 183 additions and 144 deletions

View File

@ -0,0 +1,54 @@
(ns quo2.components.colors.color.style
(:require [quo2.foundations.colors :as colors]))
(def color-button-common
{:width 48
:height 48
:border-width 4
:border-radius 24
:margin-horizontal 4
:transform [{:rotate "45deg"}]
:border-color :transparent})
(defn color-button
[color selected?]
(merge color-button-common
(when selected?
{:border-top-color (colors/alpha color 0.4)
:border-end-color (colors/alpha color 0.4)
:border-bottom-color (colors/alpha color 0.2)
:border-start-color (colors/alpha color 0.2)})))
(defn color-circle
[color border?]
{:width 40
:height 40
:transform [{:rotate "-45deg"}]
:background-color color
:justify-content :center
:align-items :center
:border-color color
:border-width (if border? 2 0)
:overflow :hidden
:border-radius 20})
(defn feng-shui
[theme]
{:width 40
:height 40
:transform [{:rotate "45deg"}]
:overflow :hidden
:border-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-width 2
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-radius 20})
(defn left-half
[theme]
{:flex 1
:background-color (colors/theme-colors colors/white colors/neutral-100 theme)})
(defn right-half
[theme]
{:flex 1
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)})

View File

@ -0,0 +1,50 @@
(ns quo2.components.colors.color.view
(:require
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.colors.color.style :as style]))
(defn- feng-shui
[{:keys [color theme]}]
[rn/view
{:accessibility-label color
:style (style/feng-shui theme)}
[rn/view {:style (style/left-half theme)}]
[rn/view {:style (style/right-half theme)}]])
(defn- view-internal
[{:keys [color
selected?
on-press
blur?
theme]
:as props}]
(let [border? (and (not blur?) (not selected?))
hex-color (if (= :feng-shui color)
(colors/theme-colors colors/neutral-100 colors/white theme)
(colors/theme-colors (colors/custom-color color 50)
(colors/custom-color color 60)
theme))]
[rn/pressable
{:style (style/color-button hex-color selected?)
:accessibility-label :color-picker-item
:on-press #(on-press color)}
(if (and (= :feng-shui color) (not selected?))
[feng-shui
(assoc props
:hex-color hex-color
:border? border?)]
[rn/view
{:accessibility-label color
:style (style/color-circle hex-color border?)}
(when selected?
[icon/icon :i/check
{:size 20
:color (if (= :feng-shui color)
(colors/theme-colors colors/white colors/neutral-100 theme)
colors/white)}])])]))
(def view (quo.theme/with-theme view-internal))

View File

@ -3,8 +3,6 @@
[reagent.core :as reagent]
[test-helpers.component :as h]))
(def color-list [:blue :yellow :turquoise :copper :sky :camel :orange :army :pink :purple :magenta])
(h/describe "color-picker"
(h/test "color picker rendered"
(h/render [color-picker/view])
@ -26,6 +24,6 @@
(h/render [color-picker/view])
(js/Promise.all (map (fn [color]
(h/is-truthy (h/get-all-by-label-text color)))
color-list))))
color-picker/color-list))))

View File

@ -1,50 +0,0 @@
(ns quo2.components.colors.color-picker.style
(:require [quo2.foundations.colors :as colors]))
(def color-picker-container
{:flex-direction :row
:flex-wrap :wrap
:justify-content :space-between})
(def flex-break
{:flex-basis "100%"
:height 10})
(def color-button-common
{:width 48
:height 48
:border-width 4
:border-radius 24
:transform [{:rotate "45deg"}]
:border-color :transparent})
(defn color-button
[color selected?]
(merge color-button-common
(when selected?
{:border-top-color (colors/alpha color 0.4)
:border-end-color (colors/alpha color 0.4)
:border-bottom-color (colors/alpha color 0.2)
:border-start-color (colors/alpha color 0.2)})))
(defn color-circle
[color border?]
{:width 40
:height 40
:transform [{:rotate "-45deg"}]
:background-color color
:justify-content :center
:align-items :center
:border-color color
:border-width (if border? 2 0)
:overflow :hidden
:border-radius 20})
(defn secondary-overlay
[secondary-color border?]
{:width (if border? 18 20)
:height 40
:position :absolute
:right 0
:background-color secondary-color})

View File

@ -1,77 +1,34 @@
(ns quo2.components.colors.color-picker.view
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icon]
[reagent.core :as reagent]
[quo2.components.colors.color-picker.style :as style]))
[quo2.components.colors.color.view :as color]))
;; TODO: using :no-color this to keep alignment of colors correct while b & w is being developed.
;; https://github.com/status-im/status-mobile/issues/15442
(def color-list
[:blue :yellow :turquoise :copper :sky :camel :orange :army :pink :purple :magenta :no-color])
(defn picker-colors
[blur?]
(map (fn [color]
{:name color
:color (colors/custom-color-by-theme color (if blur? 60 50) 60)})
color-list))
[:blue :yellow :purple :turquoise :magenta :sky :orange :army :flamingo :camel :copper])
(defn- on-change-handler
[selected color-name on-change]
(reset! selected color-name)
(when on-change (on-change color-name)))
(defn empty-color-item
[]
[rn/view {:style style/color-button-common}])
(defn- color-item
[{:keys [name
color
secondary-color
selected?
on-press
blur?]}]
(let [border? (and (not blur?) (and secondary-color (not selected?)))]
(if (= :no-color name)
[empty-color-item]
[rn/touchable-opacity
{:style (style/color-button color selected?)
:accessibility-label :color-picker-item
:on-press #(on-press name)}
[rn/view
{:accessibile true
:accessibility-label name
:style (style/color-circle color border?)}
(when (and secondary-color (not selected?))
[rn/view
{:style (style/secondary-overlay secondary-color border?)}])
(when selected?
[icon/icon :i/check
{:size 20
:color (or secondary-color
colors/white)}])]])))
(defn view
"Options
- `default-selected?` Default selected color name.
- `selected` Selected color name.
- `default-selected` Default selected color name.
- `on-change` Callback called when a color is selected `(fn [color-name])`.
- `blur?` Boolean to enable blur background support.}"
[{:keys [default-selected?]}]
(let [internal-selected (reagent/atom default-selected?)]
(fn [{:keys [blur? on-change selected]}]
(when (and (not (nil? selected)) (not= @internal-selected selected))
(reset! internal-selected selected))
[rn/view {:style style/color-picker-container}
(doall (map-indexed (fn [index color]
[:<> {:key (color :name)}
[color-item
(merge color
{:selected? (= (color :name) @internal-selected)
:on-press #(on-change-handler internal-selected % on-change)
:blur? blur?})]
(when (= index 5) [rn/view {:style style/flex-break}])])
(picker-colors blur?)))])))
[{:keys [default-selected]}]
(let [selected (reagent/atom default-selected)]
(fn [{:keys [blur? on-change feng-shui?]}]
[rn/scroll-view
{:horizontal true
:shows-horizontal-scroll-indicator false}
(doall (map (fn [color]
[color/view
{:selected? (= color @selected)
:on-press #(on-change-handler selected % on-change)
:blur? blur?
:key color
:color color}])
;; TODO: using :feng-shui? temporarily while b & w is being developed.
;; https://github.com/status-im/status-mobile/discussions/16676
(if feng-shui? (conj color-list :feng-shui) color-list)))])))

View File

@ -21,6 +21,7 @@
quo2.components.calendar.calendar-year.view
quo2.components.code.snippet.view
quo2.components.code.snippet-preview.view
quo2.components.colors.color.view
quo2.components.colors.color-picker.view
quo2.components.common.notification-dot.view
quo2.components.common.separator.view
@ -176,7 +177,7 @@
;;;; Colors
(def color-picker quo2.components.colors.color-picker.view/view)
(def picker-colors quo2.components.colors.color-picker.view/picker-colors)
(def color quo2.components.colors.color.view/view)
;;;; Community
(def community-card-view-item quo2.components.community.community-card-view/view)

View File

@ -215,7 +215,7 @@
60 "#CC6438"}
:army {50 "#216266"
60 "#1A4E52"}
:pink {50 "#F66F8F"
:flamingo {50 "#F66F8F"
60 "#C55972"}
:purple {50 "#7140FD"
60 "#5A33CA"}

View File

@ -199,10 +199,9 @@
:style style/color-title}
(i18n/label :t/accent-colour)]
[quo/color-picker
{:blur? true
:default-selected? :blue
:selected @custom-color
:on-change on-change}]]]]]
{:blur? true
:default-selected :blue
:on-change on-change}]]]]]
[rn/keyboard-avoiding-view
{:style {:position :absolute

View File

@ -0,0 +1,27 @@
(ns status-im2.contexts.quo-preview.colors.color
(:require
[quo2.core :as quo]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[(preview/customization-color-option {:feng-shui? true})
{:key :selected?
:type :boolean}
{:key :blur?
:type :boolean}])
(defn view
[]
(let [state (reagent/atom {:selected? false
:customization-color :blue
:blur? false
:on-press #(js/alert "pressed")})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (:blur? @state)
:show-blur-background? true
:blur-dark-only? true}
[quo/color (assoc @state :color (:customization-color @state))]])))

View File

@ -1,26 +1,32 @@
(ns status-im2.contexts.quo-preview.colors.color-picker
(:require [quo2.core :as quo]
[reagent.core :as reagent]
[react-native.core :as rn]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:key :selected
:type :select
:options (map (fn [color]
(let [k (get color :name)]
{:key k :value k}))
(quo/picker-colors))}
{:key :blur?
[{:key :blur?
:type :boolean}])
(defn view
[]
(let [state (reagent/atom {:selected :orange
:blur? false})]
(let [default-selected :blue
selected (reagent/atom default-selected)
on-change #(reset! selected %)
state (reagent/atom {:customization-color :blue
:blur? false
:feng-shui? true})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (:blur? @state)
:show-blur-background? true}
[quo/color-picker (assoc @state :on-change #(swap! state assoc :selected %))]])))
:show-blur-background? true
:blur-dark-only? true}
[rn/view {:style {:padding-bottom 20}}
[quo/text (str "Selected color: " (name @selected))]]
[quo/color-picker
(assoc @state
:default-selected default-selected
:on-change on-change
:color (:customization-color @state))]])))

View File

@ -31,6 +31,7 @@
[status-im2.contexts.quo-preview.graph.interactive-graph :as interactive-graph]
[status-im2.contexts.quo-preview.graph.wallet-graph :as wallet-graph]
[status-im2.contexts.quo-preview.colors.color-picker :as color-picker]
[status-im2.contexts.quo-preview.colors.color :as color]
[status-im2.contexts.quo-preview.community.community-card-view :as community-card]
[status-im2.contexts.quo-preview.community.community-membership-list-view :as
community-membership-list-view]
@ -183,7 +184,9 @@
{:name :snippet-preview
:component code-snippet-preview/view}]
:colors [{:name :color-picker
:component color-picker/view}]
:component color-picker/view}
{:name :color
:component color/view}]
:community [{:name :community-card-view
:component community-card/view}
{:name :community-membership-list-view

View File

@ -190,10 +190,10 @@
(defn customization-color-option
([]
(customization-color-option {}))
([opts]
([{:keys [feng-shui?] :as opts}]
(merge {:key :customization-color
:type :select
:options (->> colors/customization
:options (->> (merge colors/customization (when feng-shui? {:feng-shui nil}))
keys
sort
(map (fn [k]

View File

@ -37,13 +37,7 @@
{:label "Account name"
:key :account-name
:type :text}
{:label "Customization color:"
:key :customization-color
:type :select
:options (map (fn [color]
(let [k (get color :name)]
{:key k :value k}))
(quo/picker-colors))}
(preview/customization-color-option)
{:label "Account"
:key :account
:type :select

View File

@ -65,8 +65,8 @@
:style (style/color-label theme)}
(i18n/label :t/colour)]
[quo/color-picker
{:selected @account-color
:on-change #(reset! account-color %)}]]
{:default-selected @account-color
:on-change #(reset! account-color %)}]]
[rn/view {:style (style/divider-line theme)}]
[quo/category
{:list-type :settings