♻️ Refactor in color picker and options

This commit is contained in:
alonso.torres 2020-05-20 11:46:28 +02:00
parent fe08810340
commit fd18a6a6d0
9 changed files with 95 additions and 247 deletions

View file

@ -317,7 +317,7 @@
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
& .sketch-picker { & .sketch-picker, .chrome-picker {
box-shadow: none !important; box-shadow: none !important;
border: 1px solid $color-gray-10 !important; border: 1px solid $color-gray-10 !important;
border-radius: 0 !important; border-radius: 0 !important;

View file

@ -21,7 +21,7 @@
(defonce ^:private default-square-params (defonce ^:private default-square-params
{:size 16 {:size 16
:color {:value "#59B9E2" :color {:value "#59B9E2"
:opacity 0.9}}) :opacity 0.2}})
(defonce ^:private default-layout-params (defonce ^:private default-layout-params
{:size 12 {:size 12

View file

@ -10,19 +10,23 @@
[uxbox.main.store :as st] [uxbox.main.store :as st]
[goog.object :as gobj] [goog.object :as gobj]
[rumext.alpha :as mf] [rumext.alpha :as mf]
["react-color/lib/components/sketch/Sketch" :as sketch])) [uxbox.util.color :refer [hex->rgb]]
["react-color/lib/components/chrome/Chrome" :as pickerskin]))
(mf/defc colorpicker (mf/defc colorpicker
[{:keys [on-change value colors] :as props}] [{:keys [on-change value opacity colors] :as props}]
(let [local-value (mf/use-state value) (let [hex-value (mf/use-state (or value "#FFFFFF"))
on-change-complete #(do alpha-value (mf/use-state (or opacity 1))
(reset! local-value %) [r g b] (hex->rgb @hex-value)
(on-change (gobj/get % "hex")))] on-change-complete #(let [hex (gobj/get % "hex")
opacity (-> % (gobj/get "rgb") (gobj/get "a"))]
(reset! hex-value hex)
(reset! alpha-value opacity)
(on-change hex opacity))]
[:> sketch/default {:color @local-value [:> pickerskin/default {:color #js { :r r :g g :b b :a @alpha-value}
:disableAlpha true
:presetColors colors :presetColors colors
:onChangeComplete on-change-complete :onChange on-change-complete
:style {:box-shadow "none"}}])) :style {:box-shadow "none"}}]))
(def most-used-colors (def most-used-colors

View file

@ -14,11 +14,12 @@
;; --- Color Picker Modal ;; --- Color Picker Modal
(mf/defc colorpicker-modal (mf/defc colorpicker-modal
[{:keys [x y default value page on-change] :as props}] [{:keys [x y default value opacity page on-change] :as props}]
[:div.colorpicker-tooltip [:div.colorpicker-tooltip
{:style {:left (str (- x 260) "px") {:style {:left (str (- x 260) "px")
:top (str (- y 50) "px")}} :top (str (- y 50) "px")}}
[:& cp/colorpicker {:value (or value default) [:& cp/colorpicker {:value (or value default)
:opacity (or opacity 1)
:colors (into-array @cp/most-used-colors) :colors (into-array @cp/most-used-colors)
:on-change on-change}]]) :on-change on-change}]])

View file

@ -10,15 +10,10 @@
(ns uxbox.main.ui.workspace.sidebar.options.fill (ns uxbox.main.ui.workspace.sidebar.options.fill
(:require (:require
[rumext.alpha :as mf] [rumext.alpha :as mf]
[uxbox.main.ui.icons :as i]
[uxbox.common.data :as d]
[uxbox.main.data.workspace :as udw] [uxbox.main.data.workspace :as udw]
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.ui.modal :as modal] [uxbox.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]]
[uxbox.util.dom :as dom]
[uxbox.util.object :as obj] [uxbox.util.object :as obj]
[uxbox.util.math :as math]
[uxbox.util.i18n :as i18n :refer [tr t]])) [uxbox.util.i18n :as i18n :refer [tr t]]))
(defn- fill-menu-memo-equals? (defn- fill-menu-memo-equals?
@ -36,70 +31,14 @@
{::mf/wrap [#(mf/memo' % fill-menu-memo-equals?)]} {::mf/wrap [#(mf/memo' % fill-menu-memo-equals?)]}
[{:keys [shape] :as props}] [{:keys [shape] :as props}]
(let [locale (i18n/use-locale) (let [locale (i18n/use-locale)
color {:value (:fill-color shape)
on-color-change :opacity (:fill-opacity shape)}
(fn [color] handle-change-color (fn [value opacity]
(st/emit! (udw/update-shape (:id shape) {:fill-color color}))) (let [change {:fill-color value
:fill-opacity opacity}]
on-color-input-change (st/emit! (udw/update-shape (:id shape) change))))]
(fn [event]
(let [input (dom/get-target event)
value (dom/get-value input)]
(when (dom/valid? input)
(on-color-change value))))
on-opacity-change
(fn [event]
(let [value (-> (dom/get-target event)
(dom/get-value)
(d/parse-integer 1)
(/ 100))]
(st/emit! (udw/update-shape (:id shape) {:fill-opacity value}))))
show-color-picker
(fn [event]
(let [x (.-clientX event)
y (.-clientY event)
props {:x x :y y
:on-change on-color-change
:default "#ffffff"
:value (:fill-color shape)
:transparent? true}]
(modal/show! colorpicker-modal props)))]
[:div.element-set [:div.element-set
[:div.element-set-title (t locale "workspace.options.fill")] [:div.element-set-title (t locale "workspace.options.fill")]
[:div.element-set-content [:div.element-set-content
[:& color-row {:value color
[:div.row-flex.color-data :on-change handle-change-color}]]]))
[:span.color-th
{:style {:background-color (:fill-color shape)}
:on-click show-color-picker}]
[:div.color-info
[:input {:default-value (:fill-color shape)
:ref (fn [el]
(when el
(set! (.-value el) (:fill-color shape))))
:pattern "^#(?:[0-9a-fA-F]{3}){1,2}$"
:on-change on-color-input-change}]]
[:div.input-element.percentail
[:input.input-text {:type "number"
:value (str (-> (:fill-opacity shape)
(d/coalesce 1)
(* 100)
(math/round)))
:on-change on-opacity-change
:min "0"
:max "100"}]]
[:input.slidebar {:type "range"
:min "0"
:max "100"
:value (str (-> (:fill-opacity shape)
(d/coalesce 1)
(* 100)
(math/round)))
:step "1"
:on-change on-opacity-change}]]]]))

View file

@ -102,6 +102,12 @@
(assoc-in [:params :size] size) (assoc-in [:params :size] size)
(assoc-in [:params :item-length] item-length))))) (assoc-in [:params :item-length] item-length)))))
handle-change-color
(fn [value opacity]
(emit-changes! #(-> %
(assoc-in [:params :color :value] value)
(assoc-in [:params :color :opacity] opacity))))
handle-use-default handle-use-default
(fn [] (fn []
(emit-changes! #(hash-map :params ((:type grid) default-grid-params)))) (emit-changes! #(hash-map :params ((:type grid) default-grid-params))))
@ -200,7 +206,7 @@
:on-change (handle-change :params :margin)}]]) :on-change (handle-change :params :margin)}]])
[:& color-row {:value (:color params) [:& color-row {:value (:color params)
:on-change (handle-change :params :color)}] :on-change handle-change-color}]
[:div.row-flex [:div.row-flex
[:button.btn-options {:disabled is-default [:button.btn-options {:disabled is-default
:on-click handle-use-default} (t locale "workspace.options.grid.params.use-default")] :on-click handle-use-default} (t locale "workspace.options.grid.params.use-default")]

View file

@ -24,41 +24,53 @@
:y y :y y
:on-change handle-change-color :on-change handle-change-color
:value (:value color) :value (:value color)
:opacity (:opacity color)
:transparent? true}] :transparent? true}]
(modal/show! colorpicker-modal props)))) (modal/show! colorpicker-modal props))))
(defn opacity->string [opacity] (defn opacity->string [opacity]
(str (-> opacity (if (and opacity (not= opacity ""))
(d/coalesce 1) (str (-> opacity
(* 100) (d/coalesce 1)
(math/round)))) (* 100)
(math/round)))
""))
(defn string->opacity [opacity-str] (defn string->opacity [opacity-str]
(-> opacity-str (when (and opacity-str (not= "" opacity-str))
(d/parse-integer 1) (-> opacity-str
(/ 100))) (d/parse-integer 1)
(/ 100))))
(mf/defc color-row [{:keys [value on-change]}] (mf/defc color-row [{:keys [value on-change]}]
(let [value (or value {:value "#FFFFFF" :opacity 1}) (let [default-value {:value "#000000" :opacity 1}
state (mf/use-state value)
change-color (fn [color]
(let [update-color (fn [state] (assoc state :value color))]
(swap! state update-color)
(when on-change (on-change (update-color @state)))))
change-opacity (fn [opacity] parse-value (fn [value]
(let [update-opacity (fn [state] (assoc state :opacity opacity))] (-> (merge default-value value)
(swap! state update-opacity) (update :value #(or % "#000000"))
(when on-change (on-change (update-opacity @state))))) (update :opacity #(or % 1))))
handle-pick-color (fn [color] state (mf/use-state (parse-value value))
(change-color color))
change-color (fn [new-value]
(let [{:keys [value opacity]} @state]
(swap! state assoc :value new-value)
(when on-change (on-change new-value opacity))))
change-opacity (fn [new-opacity]
(let [{:keys [value opacity]} @state]
(swap! state assoc :opacity new-opacity)
(when (and new-opacity on-change) (on-change value new-opacity))))
handle-pick-color (fn [color opacity]
(reset! state {:value color :opacity opacity})
(when on-change (on-change color opacity)))
handle-input-color-change (fn [event] handle-input-color-change (fn [event]
(let [target (dom/get-target event) (let [target (dom/get-target event)
value (dom/get-value target)] value (dom/get-value target)]
(when (dom/valid? target) (when (dom/valid? target)
(change-color value)))) (change-color (str "#" value)))))
handle-opacity-change (fn [event] handle-opacity-change (fn [event]
(-> event (-> event
dom/get-target dom/get-target
@ -68,7 +80,7 @@
(mf/use-effect (mf/use-effect
(mf/deps value) (mf/deps value)
#(reset! state value)) #(reset! state (parse-value value)))
[:div.row-flex.color-data [:div.row-flex.color-data
[:span.color-th [:span.color-th
@ -76,8 +88,8 @@
:on-click (color-picker-callback @state handle-pick-color)}] :on-click (color-picker-callback @state handle-pick-color)}]
[:div.color-info [:div.color-info
[:input {:value (-> @state :value) [:input {:value (-> @state :value (subs 1))
:pattern "^#(?:[0-9a-fA-F]{3}){1,2}$" :pattern "^[0-9a-fA-F]{0,6}$"
:on-change handle-input-color-change}]] :on-change handle-input-color-change}]]
[:div.input-element.percentail [:div.input-element.percentail
@ -87,7 +99,7 @@
:min "0" :min "0"
:max "100"}]] :max "100"}]]
[:input.slidebar {:type "range" #_[:input.slidebar {:type "range"
:min "0" :min "0"
:max "100" :max "100"
:value (-> @state :opacity opacity->string) :value (-> @state :opacity opacity->string)

View file

@ -19,7 +19,8 @@
[uxbox.util.dom :as dom] [uxbox.util.dom :as dom]
[uxbox.util.object :as obj] [uxbox.util.object :as obj]
[uxbox.util.i18n :as i18n :refer [tr t]] [uxbox.util.i18n :as i18n :refer [tr t]]
[uxbox.util.math :as math])) [uxbox.util.math :as math]
[uxbox.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]))
(defn- stroke-menu-memo-equals? (defn- stroke-menu-memo-equals?
[np op] [np op]
@ -75,35 +76,13 @@
(fn [event] (fn [event]
(st/emit! (udw/update-shape (:id shape) {:stroke-style :none}))) (st/emit! (udw/update-shape (:id shape) {:stroke-style :none})))
on-stroke-opacity-change current-stroke-color {:value (:stroke-color shape)
(fn [event] :opacity (:stroke-opacity shape)}
(let [value (-> (dom/get-target event)
(dom/get-value)
(d/parse-integer 0)
(/ 100))]
(st/emit! (udw/update-shape (:id shape) {:stroke-opacity value}))))
on-color-change handle-change-stroke-color
(fn [color] (fn [value opacity]
(st/emit! (udw/update-shape (:id shape) {:stroke-color color}))) (st/emit! (udw/update-shape (:id shape) {:stroke-color value
:stroke-opacity opacity})))]
on-color-input-change
(fn [event]
(let [input (dom/get-target event)
value (dom/get-value input)]
(when (dom/valid? input)
(on-color-change value))))
show-color-picker
(fn [event]
(let [x (.-clientX event)
y (.-clientY event)
props {:x x :y y
:default "#ffffff"
:value (:stroke-color shape)
:on-change on-color-change
:transparent? true}]
(modal/show! colorpicker-modal props)))]
(if (not= :none (:stroke-style shape :none)) (if (not= :none (:stroke-style shape :none))
[:div.element-set [:div.element-set
@ -112,39 +91,9 @@
[:div.add-page {:on-click on-del-stroke} i/minus]] [:div.add-page {:on-click on-del-stroke} i/minus]]
[:div.element-set-content [:div.element-set-content
;; Stroke Color ;; Stroke Color
[:div.row-flex.color-data [:& color-row {:value current-stroke-color
[:span.color-th {:style {:background-color (:stroke-color shape)} :on-change handle-change-stroke-color}]
:on-click show-color-picker}]
[:div.color-info
[:input {:default-value (:stroke-color shape)
:ref (fn [el]
(when el
(set! (.-value el) (:stroke-color shape))))
:pattern "^#(?:[0-9a-fA-F]{3}){1,2}$"
:on-change on-color-input-change}]]
[:div.input-element.percentail
[:input.input-text {:placeholder ""
:value (str (-> (:stroke-opacity shape)
(d/coalesce 1)
(* 100)
(math/round)))
:type "number"
:on-change on-stroke-opacity-change
:min "0"
:max "100"}]]
[:input.slidebar {:type "range"
:min "0"
:max "100"
:value (str (-> (:stroke-opacity shape)
(d/coalesce 1)
(* 100)
(math/round)))
:step "1"
:on-change on-stroke-opacity-change}]]
;; Stroke Width, Alignment & Style ;; Stroke Width, Alignment & Style
[:div.row-flex [:div.row-flex

View file

@ -18,12 +18,10 @@
[uxbox.main.data.workspace.texts :as dwt] [uxbox.main.data.workspace.texts :as dwt]
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.refs :as refs] [uxbox.main.refs :as refs]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]]
[uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]] [uxbox.main.ui.workspace.sidebar.options.measures :refer [measures-menu]]
[uxbox.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[uxbox.util.dom :as dom] [uxbox.util.dom :as dom]
[uxbox.main.fonts :as fonts] [uxbox.main.fonts :as fonts]
[uxbox.util.math :as math]
[uxbox.util.i18n :as i18n :refer [tr t]] [uxbox.util.i18n :as i18n :refer [tr t]]
["slate" :refer [Transforms]])) ["slate" :refer [Transforms]]))
@ -186,85 +184,24 @@
(mf/defc text-fill-options (mf/defc text-fill-options
[{:keys [editor shape] :as props}] [{:keys [editor shape] :as props}]
(let [{:keys [fill opacity] (let [text-color (dwt/current-text-values
:or {fill "#000000" {:editor editor
opacity 1}} :shape shape
(dwt/current-text-values :attrs [:fill :opacity]})
{:editor editor
:shape shape
:attrs [:fill :opacity]})
opacity (math/round (* opacity 100)) current-color {:value (:fill text-color)
:opacity (:opacity text-color)}
on-color-change handle-change-color
(fn [color] (fn [value opacity]
(st/emit! (dwt/update-text-attrs (st/emit! (dwt/update-text-attrs {:id (:id shape)
{:id (:id shape) :editor editor
:editor editor :attrs {:fill value
:attrs {:fill color}}))) :opacity opacity}})))]
on-color-input-change [:& color-row {:value current-color
(fn [event] :on-change handle-change-color}]
(let [input (dom/get-target event) ))
value (dom/get-value input)]
(when (dom/valid? input)
(on-color-change value))))
on-opacity-change
(fn [event]
(let [value (-> (dom/get-target event)
(dom/get-value))]
(when (str/numeric? value)
(let [value (-> (d/parse-integer value 1)
(/ 100))]
(st/emit! (dwt/update-text-attrs
{:id (:id shape)
:editor editor
:attrs {:opacity value}}))))))
show-color-picker
(fn [event]
(let [x (.-clientX event)
y (.-clientY event)
props {:x x :y y
:on-change on-color-change
:default "#ffffff"
:value fill
:transparent? true}]
(modal/show! colorpicker-modal props)))]
[:div.row-flex.color-data
[:span.color-th
{:style {:background-color fill}
:on-click show-color-picker
}]
[:div.color-info
[:input {:default-value fill
:pattern "^#(?:[0-9a-fA-F]{3}){1,2}$"
:ref (fn [el]
(when el
(set! (.-value el) fill)))
:on-change on-color-input-change
}]]
[:div.input-element.percentail
[:input.input-text {:type "number"
:ref (fn [el]
(when el
(set! (.-value el) opacity)))
:default-value opacity
:on-change on-opacity-change
:min "0"
:max "100"}]]
[:input.slidebar {:type "range"
:min "0"
:max "100"
:value opacity
:step "1"
:on-change on-opacity-change
}]]))
(mf/defc spacing-options (mf/defc spacing-options
[{:keys [editor shape locale] :as props}] [{:keys [editor shape locale] :as props}]