mirror of
https://github.com/penpot/penpot.git
synced 2025-02-01 11:59:17 -05:00
⚡ Add performance oriented refactor for color palette components
This commit is contained in:
parent
6d666c4926
commit
068dd5f4bc
6 changed files with 93 additions and 71 deletions
|
@ -115,6 +115,9 @@
|
|||
(sm/register! ::recent-color schema:recent-color)
|
||||
(sm/register! ::color-attrs schema:color-attrs)
|
||||
|
||||
(def valid-color?
|
||||
(sm/lazy-validator schema:color))
|
||||
|
||||
(def check-color!
|
||||
(sm/check-fn schema:color :hint "expected valid color struct"))
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
text-ids (filter is-text? ids)
|
||||
shape-ids (remove is-text? ids)
|
||||
|
||||
undo-id (js/Symbol)
|
||||
undo-id (js/Symbol)
|
||||
|
||||
attrs
|
||||
(cond-> {}
|
||||
|
@ -146,7 +146,8 @@
|
|||
(rx/of (dwsh/update-shapes shape-ids transform-attrs)))))))
|
||||
|
||||
(defn change-fill
|
||||
([ids color position] (change-fill ids color position nil))
|
||||
([ids color position]
|
||||
(change-fill ids color position nil))
|
||||
([ids color position options]
|
||||
(ptk/reify ::change-fill
|
||||
ptk/WatchEvent
|
||||
|
|
|
@ -8,19 +8,21 @@
|
|||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.workspace.colors :as mdc]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.color-bullet :as cb]
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.color :as uc]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.object :as obj]
|
||||
[okulary.core :as l]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
@ -48,25 +50,23 @@
|
|||
[:& cb/color-name {:color color :size size :origin :palette}]]))
|
||||
|
||||
(mf/defc palette*
|
||||
[{:keys [current-colors size width selected]}]
|
||||
(let [;; We had to do this due to a bug that leave some bugged colors
|
||||
current-colors (h/use-equal-memo (filter #(or (:gradient %) (:color %) (:image %)) current-colors))
|
||||
state (mf/use-state {:show-menu false})
|
||||
offset-step (cond
|
||||
(<= size 64) 40
|
||||
(<= size 80) 72
|
||||
:else 72)
|
||||
[{:keys [colors size width selected]}]
|
||||
(let [state (mf/use-state #(do {:show-menu false}))
|
||||
offset-step (cond
|
||||
(<= size 64) 40
|
||||
(<= size 80) 72
|
||||
:else 72)
|
||||
buttons-size (cond
|
||||
(<= size 64) 164
|
||||
:else 132)
|
||||
width (- width buttons-size)
|
||||
visible (int (/ width offset-step))
|
||||
show-arrows? (> (count current-colors) visible)
|
||||
show-arrows? (> (count colors) visible)
|
||||
visible (if show-arrows?
|
||||
(int (/ (- width 48) offset-step))
|
||||
visible)
|
||||
offset (:offset @state 0)
|
||||
max-offset (- (count current-colors)
|
||||
max-offset (- (count colors)
|
||||
visible)
|
||||
container (mf/use-ref nil)
|
||||
bullet-size (cond
|
||||
|
@ -79,7 +79,7 @@
|
|||
:else 64)
|
||||
|
||||
on-left-arrow-click
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps max-offset visible)
|
||||
(fn [_]
|
||||
(swap! state update :offset
|
||||
|
@ -89,7 +89,7 @@
|
|||
offset)))))
|
||||
|
||||
on-right-arrow-click
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps max-offset visible)
|
||||
(fn [_]
|
||||
(swap! state update :offset
|
||||
|
@ -99,7 +99,7 @@
|
|||
offset)))))
|
||||
|
||||
on-scroll
|
||||
(mf/use-callback
|
||||
(mf/use-fn
|
||||
(mf/deps max-offset)
|
||||
(fn [event]
|
||||
(let [event (dom/event->native-event event)
|
||||
|
@ -109,12 +109,12 @@
|
|||
(on-right-arrow-click event)
|
||||
(on-left-arrow-click event)))))]
|
||||
|
||||
(mf/use-layout-effect
|
||||
#(let [dom (mf/ref-val container)
|
||||
(mf/with-layout-effect []
|
||||
(let [dom (mf/ref-val container)
|
||||
width (obj/get dom "clientWidth")]
|
||||
(swap! state assoc :width width)))
|
||||
|
||||
(mf/with-effect [width current-colors]
|
||||
(mf/with-effect [width colors]
|
||||
(when (not= 0 (:offset @state))
|
||||
(swap! state assoc :offset 0)))
|
||||
|
||||
|
@ -126,10 +126,10 @@
|
|||
[:button {:class (stl/css :left-arrow)
|
||||
:disabled (= offset 0)
|
||||
:on-click on-left-arrow-click} i/arrow])
|
||||
[:div {:class (stl/css :color-palette-content)
|
||||
[:div {:class (stl/css :color-palette-content)
|
||||
:ref container
|
||||
:on-wheel on-scroll}
|
||||
(if (empty? current-colors)
|
||||
(if (empty? colors)
|
||||
[:div {:class (stl/css :color-palette-empty)
|
||||
:style {:position "absolute"
|
||||
:left "50%"
|
||||
|
@ -140,44 +140,61 @@
|
|||
:style {:position "relative"
|
||||
:max-width (str width "px")
|
||||
:right (str (* offset-step offset) "px")}}
|
||||
(for [[idx item] (map-indexed vector current-colors)]
|
||||
(for [[idx item] (map-indexed vector colors)]
|
||||
[:> palette-item* {:color item :key idx :size size :selected selected}])])]
|
||||
|
||||
(when show-arrows?
|
||||
[:button {:class (stl/css :right-arrow)
|
||||
:disabled (= offset max-offset)
|
||||
:on-click on-right-arrow-click} i/arrow])]))
|
||||
|
||||
(defn library->colors [shared-libs selected]
|
||||
(map #(merge % {:file-id selected})
|
||||
(-> shared-libs
|
||||
(get-in [selected :data :colors])
|
||||
(vals))))
|
||||
(mf/defc recent-colors-palette*
|
||||
{::mf/private true}
|
||||
[props]
|
||||
(let [colors (mf/deref refs/recent-colors)
|
||||
|
||||
(mf/defc color-palette
|
||||
colors (mf/with-memo [colors]
|
||||
(->> (reverse colors)
|
||||
(filter ctc/valid-color?)
|
||||
(vec)))
|
||||
|
||||
props (mf/spread-props props {:colors colors})]
|
||||
[:> palette* props]))
|
||||
|
||||
(defn- make-library-colors-ref
|
||||
[file-id]
|
||||
(l/derived (fn [libraries]
|
||||
(dm/get-in libraries [file-id :data :colors]))
|
||||
refs/libraries))
|
||||
|
||||
(mf/defc file-color-palette*
|
||||
{::mf/private true}
|
||||
[{:keys [file-id] :as props}]
|
||||
(let [colors-ref (mf/with-memo [file-id]
|
||||
(make-library-colors-ref file-id))
|
||||
colors (mf/deref colors-ref)
|
||||
colors (mf/with-memo [colors file-id]
|
||||
(->> (vals colors)
|
||||
(filter ctc/valid-color?)
|
||||
(map #(assoc % :file-id file-id))
|
||||
(sort-by :name)
|
||||
(vec)))
|
||||
props (mf/spread-props props {:colors colors})]
|
||||
|
||||
[:> palette* props]))
|
||||
|
||||
(mf/defc color-palette*
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [size width selected] :as props}]
|
||||
(let [recent-colors (mf/deref refs/recent-colors)
|
||||
file-colors (mf/deref refs/workspace-file-colors)
|
||||
shared-libs (mf/deref refs/libraries)
|
||||
colors (mf/use-state [])]
|
||||
[{:keys [selected] :as props}]
|
||||
(let [file-id (mf/use-ctx ctx/current-file-id)]
|
||||
(cond
|
||||
(= selected :recent)
|
||||
[:> recent-colors-palette* props]
|
||||
|
||||
(mf/with-effect [selected shared-libs]
|
||||
(let [colors' (cond
|
||||
(= selected :recent) (reverse recent-colors)
|
||||
(= selected :file) (->> (vals file-colors) (sort-by :name))
|
||||
:else (->> (library->colors shared-libs selected) (sort-by :name)))]
|
||||
(reset! colors (into [] colors'))))
|
||||
(= selected :file)
|
||||
(let [props (mf/spread-props props {:file-id file-id})]
|
||||
[:> file-color-palette* props])
|
||||
|
||||
(mf/with-effect [recent-colors selected]
|
||||
(when (= selected :recent)
|
||||
(reset! colors (reverse recent-colors))))
|
||||
|
||||
(mf/with-effect [file-colors selected]
|
||||
(when (= selected :file)
|
||||
(reset! colors (into [] (->> (vals file-colors)
|
||||
(sort-by :name))))))
|
||||
|
||||
[:> palette* {:current-colors @colors
|
||||
:size size
|
||||
:width width
|
||||
:selected selected}]))
|
||||
:else
|
||||
(let [props (mf/spread-props props {:file-id selected})]
|
||||
[:> file-color-palette* props]))))
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
|
||||
.color-palette-content {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.color-palette-inside {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.hooks.resize :as r]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.color-palette :refer [color-palette]]
|
||||
[app.main.ui.workspace.color-palette :refer [color-palette*]]
|
||||
[app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu]]
|
||||
[app.main.ui.workspace.text-palette :refer [text-palette]]
|
||||
[app.main.ui.workspace.text-palette-ctx-menu :refer [text-palette-ctx-menu]]
|
||||
|
@ -195,13 +195,14 @@
|
|||
:selected selected-text
|
||||
:width vport-width}]])
|
||||
(when color-palette?
|
||||
[:* [:& color-palette-ctx-menu {:show-menu? show-menu?
|
||||
:close-menu on-close-menu
|
||||
:on-select-palette on-select-palette
|
||||
:selected @selected}]
|
||||
[:& color-palette {:size size
|
||||
:selected @selected
|
||||
:width vport-width}]])]]
|
||||
[:*
|
||||
[:& color-palette-ctx-menu {:show-menu? show-menu?
|
||||
:close-menu on-close-menu
|
||||
:on-select-palette on-select-palette
|
||||
:selected @selected}]
|
||||
[:> color-palette* {:size size
|
||||
:selected @selected
|
||||
:width vport-width}]])]]
|
||||
[:div {:class (stl/css :handler)
|
||||
:on-click toggle-palettes
|
||||
:data-testid "toggle-palettes-visibility"}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
[app.main.ui.components.color-input :refer [color-input*]]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input*]]
|
||||
[app.main.ui.components.reorder-handler :refer [reorder-handler]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.main.ui.hooks :as h]
|
||||
|
@ -49,24 +48,23 @@
|
|||
[{:keys [index color disable-gradient disable-opacity disable-image disable-picker on-change
|
||||
on-reorder on-detach on-open on-close on-remove
|
||||
disable-drag on-focus on-blur select-only select-on-focus]}]
|
||||
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
shared-libs (mf/deref refs/libraries)
|
||||
hover-detach (mf/use-state false)
|
||||
on-change (h/use-ref-callback on-change)
|
||||
(let [shared-libs (mf/deref refs/libraries)
|
||||
hover-detach (mf/use-state false)
|
||||
on-change (h/use-ref-callback on-change)
|
||||
|
||||
src-colors (dm/get-in shared-libs [(:ref-file color) :data :colors])
|
||||
color-name (dm/get-in src-colors [(:ref-id color) :name])
|
||||
src-colors (dm/get-in shared-libs [(:ref-file color) :data :colors])
|
||||
color-name (dm/get-in src-colors [(:ref-id color) :name])
|
||||
|
||||
multiple-colors? (uc/multiple? color)
|
||||
library-color? (and (:ref-id color) color-name (not multiple-colors?))
|
||||
gradient-color? (and (not multiple-colors?)
|
||||
(:gradient color)
|
||||
(dm/get-in color [:gradient :type]))
|
||||
image-color? (and (not multiple-colors?)
|
||||
(:image color))
|
||||
image-color? (and (not multiple-colors?)
|
||||
(:image color))
|
||||
|
||||
editing-text* (mf/use-state false)
|
||||
editing-text? (deref editing-text*)
|
||||
editing-text* (mf/use-state false)
|
||||
editing-text? (deref editing-text*)
|
||||
|
||||
opacity?
|
||||
(and (not multiple-colors?)
|
||||
|
|
Loading…
Add table
Reference in a new issue