0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-15 08:21:40 -05:00

Merge pull request #5719 from penpot/niwinz-fix-selected-colors

♻️ Add performance refactor for several components related to colors
This commit is contained in:
Andrey Antukh 2025-01-30 16:21:06 +01:00 committed by GitHub
commit 7cdb4719bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 269 additions and 291 deletions

View file

@ -29,7 +29,7 @@
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
[app.main.ui.icons :as i]
[app.main.ui.workspace.colorpicker.color-inputs :refer [color-inputs]]
[app.main.ui.workspace.colorpicker.gradients :refer [gradients]]
[app.main.ui.workspace.colorpicker.gradients :refer [gradients*]]
[app.main.ui.workspace.colorpicker.harmony :refer [harmony-selector]]
[app.main.ui.workspace.colorpicker.hsva :refer [hsva-selector]]
[app.main.ui.workspace.colorpicker.libraries :refer [libraries]]
@ -110,7 +110,7 @@
:linear :linear-gradient
:radial :radial-gradient)
:color))
active-color-tab (mf/use-state (dc/get-active-color-tab))
active-color-tab (mf/use-state #(dc/get-active-color-tab))
drag? (mf/use-state false)
type (if (= @active-color-tab "hsva") :hsv :rgb)
@ -436,7 +436,7 @@
i/picker])]
(when (= selected-mode :gradient)
[:& gradients
[:> gradients*
{:type (:type state)
:stops (:stops state)
:editing-stop (:editing-stop state)

View file

@ -17,7 +17,7 @@
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.formats :as fmt]
[app.main.ui.hooks :as h]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.dom :as dom]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
@ -34,10 +34,6 @@
(/ (.. event -nativeEvent -offsetX)
(-> event dom/get-current-target dom/get-bounding-rect :width)))
;; (defn- format-rgba
;; [{:keys [r g b alpha offset]}]
;; (str/ffmt "rgba(%1, %2, %3, %4) %5%%" r g b alpha (* offset 100)))
(defn- format-rgb
[{:keys [r g b offset]}]
(str/ffmt "rgb(%1, %2, %3) %4%%" r g b (* offset 100)))
@ -52,11 +48,11 @@
(str/join ", ")
(str/ffmt "linear-gradient(90deg, %1)")))
(mf/defc stop-input-row
(mf/defc stop-input-row*
{::mf/private true}
[{:keys [stop
index
is-selected
on-select-stop
on-change-stop
on-remove-stop
@ -65,7 +61,7 @@
on-blur-stop-offset
on-focus-stop-color
on-blur-stop-color]}]
(let [{:keys [color opacity offset]} stop
(let [offset (get stop :offset)
handle-change-stop-color
(mf/use-callback
@ -153,18 +149,17 @@
:on-focus handle-focus-stop-offset
:on-blur handle-blur-stop-offset}]]
[:& color-row
[:> color-row*
{:disable-gradient true
:disable-picker true
:color {:color color
:opacity opacity}
:color stop
:index index
:on-change handle-change-stop-color
:on-remove handle-remove-stop
:on-focus handle-focus-stop-color
:on-blur handle-blur-stop-color}]]))
(mf/defc gradients
(mf/defc gradients*
[{:keys [type
stops
editing-stop
@ -180,7 +175,7 @@
on-rotate-stops
on-reorder-stops]}]
(let [preview-state (mf/use-state {:hover? false :offset 0.5})
(let [preview-state (mf/use-state #(do {:hover? false :offset 0.5}))
dragging-ref (mf/use-ref false)
start-ref (mf/use-ref nil)
start-offset (mf/use-ref nil)
@ -350,7 +345,7 @@
[:div {:class (stl/css :gradient-stops-list)}
[:& h/sortable-container {}
(for [[index stop] (d/enumerate stops)]
[:& stop-input-row
[:> stop-input-row*
{:key index
:stop stop
:index index

View file

@ -116,7 +116,7 @@
:shared-libs shared-libs}]
(= 0 (count selected))
[:& page/options]
[:> page/options*]
(= 1 (count selected))
[:> shape-options*

View file

@ -8,15 +8,13 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.types.color :as ctc]
[app.common.uuid :as uuid]
[app.main.data.workspace.colors :as dc]
[app.main.data.workspace.selection :as dws]
[app.main.store :as st]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.hooks :as h]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
@ -37,20 +35,19 @@
(def xf:map-shape-id
(map :shape-id))
(mf/defc color-selection-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["shapes"]))]
::mf/wrap-props false}
[{:keys [shapes file-id shared-libs]}]
(mf/defc color-selection-menu*
{::mf/wrap [#(mf/memo' % (mf/check-props ["shapes"]))]}
[{:keys [shapes file-id libraries]}]
(let [{:keys [groups library-colors colors]}
(mf/with-memo [shapes file-id shared-libs]
(prepare-colors shapes file-id shared-libs))
(mf/with-memo [file-id shapes libraries]
(prepare-colors shapes file-id libraries))
state* (mf/use-state true)
open? (deref state*)
open* (mf/use-state true)
open? (deref open*)
has-colors? (or (some? (seq colors)) (some? (seq library-colors)))
toggle-content (mf/use-fn #(swap! state* not))
toggle-content (mf/use-fn #(swap! open* not))
expand-lib-color (mf/use-state false)
expand-color (mf/use-state false)
@ -58,16 +55,6 @@
groups-ref (h/use-ref-value groups)
prev-colors-ref (mf/use-ref nil)
initial-color-keys
(mf/use-memo
#(->> (concat colors library-colors)
(reduce
(fn [result color]
(assoc result color (dm/str (uuid/next))))
{})))
color-keys* (mf/use-var initial-color-keys)
on-change
(mf/use-fn
(fn [new-color old-color from-picker?]
@ -95,7 +82,6 @@
(mf/set-ref-val! prev-colors-ref
(conj prev-colors color))))
(swap! color-keys* assoc new-color (get @color-keys* old-color))
(st/emit! (dc/change-color-in-selected cops new-color old-color)))))
on-open
@ -139,8 +125,8 @@
(let [lib-colors (cond->> library-colors (not @expand-lib-color) (take 3))
lib-colors (concat lib-colors colors)]
(for [[index color] (d/enumerate lib-colors)]
[:& color-row
{:key (get @color-keys* color)
[:> color-row*
{:key index
:color color
:index index
:hidden (not (:id color))
@ -156,8 +142,8 @@
[:div {:class (stl/css :selected-color-group)}
(for [[index color] (d/enumerate (cond->> colors (not @expand-color) (take 3)))]
[:& color-row
{:key (get @color-keys* color)
[:> color-row*
{:key index
:color color
:index index
:select-only select-only

View file

@ -17,7 +17,7 @@
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.hooks :as h]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
@ -168,18 +168,18 @@
(seq fills)
[:& h/sortable-container {}
(for [[index value] (d/enumerate (:fills values []))]
[:& color-row {:color (ctc/fill->shape-color value)
:key index
:index index
:title (tr "workspace.options.fill")
:on-change (on-change index)
:on-reorder (on-reorder index)
:on-detach (on-detach index)
:on-remove (on-remove index)
:disable-drag disable-drag
:on-focus on-focus
:select-on-focus (not @disable-drag)
:on-blur on-blur}])])
[:> color-row* {:color (ctc/fill->shape-color value)
:key index
:index index
:title (tr "workspace.options.fill")
:on-change (on-change index)
:on-reorder (on-reorder index)
:on-detach (on-detach index)
:on-remove (on-remove index)
:disable-drag disable-drag
:on-focus on-focus
:select-on-focus (not @disable-drag)
:on-blur on-blur}])])
(when (or (= type :frame)
(and (= type :multiple) (some? (:hide-fill-on-export values))))

View file

@ -19,7 +19,7 @@
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l]
[rumext.v2 :as mf]))
@ -196,12 +196,12 @@
(when (= :square type)
[:div {:class (stl/css :square-row)}
[:div {:class (stl/css :advanced-row)}
[:& color-row {:color (:color params)
:title (tr "workspace.options.grid.params.color")
:disable-gradient true
:disable-image true
:on-change handle-change-color
:on-detach handle-detach-color}]
[:> color-row* {:color (:color params)
:title (tr "workspace.options.grid.params.color")
:disable-gradient true
:disable-image true
:on-change handle-change-color
:on-detach handle-detach-color}]
[:button {:class (stl/css-case :show-more-options true
:selected show-more-options?)
:on-click toggle-more-options}
@ -237,12 +237,12 @@
:on-change (handle-change :params :type)}]]
[:div {:class (stl/css :color-wrapper)}
[:& color-row {:color (:color params)
:title (tr "workspace.options.grid.params.color")
:disable-gradient true
:disable-image true
:on-change handle-change-color
:on-detach handle-detach-color}]]]
[:> color-row* {:color (:color params)
:title (tr "workspace.options.grid.params.color")
:disable-gradient true
:disable-image true
:on-change handle-change-color
:on-detach handle-detach-color}]]]
[:div {:class (stl/css :advanced-row)}
[:div {:class (stl/css :height)

View file

@ -10,7 +10,6 @@
[app.common.colors :as clr]
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.math :as mth]
[app.common.uuid :as uuid]
[app.main.data.workspace.colors :as dc]
[app.main.data.workspace.shapes :as dwsh]
@ -24,10 +23,8 @@
[app.main.ui.hooks :as h]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.util.dom :as dom]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l]
[rumext.v2 :as mf]))
(def shadow-attrs [:shadow])
@ -50,32 +47,18 @@
(filterv (fn [[idx _]] (not= idx index)))
(mapv second)))
(mf/defc shadow-entry
[{:keys [ids index value on-reorder disable-drag? on-blur open-state-ref]}]
(let [basic-offset-x-ref (mf/use-ref nil)
basic-offset-y-ref (mf/use-ref nil)
basic-blur-ref (mf/use-ref nil)
(mf/defc shadow-entry*
[{:keys [index shadow is-open
on-reorder
on-toggle-open
on-detach-color
on-update
on-remove
on-toggle-visibility]}]
(let [shadow-style (:style shadow)
shadow-id (:id shadow)
adv-offset-x-ref (mf/use-ref nil)
adv-offset-y-ref (mf/use-ref nil)
adv-blur-ref (mf/use-ref nil)
adv-spread-ref (mf/use-ref nil)
shadow-style (:style value)
shadow-id (:id value)
open-status-ref (mf/with-memo [open-state-ref shadow-id]
(-> (l/key shadow-id)
(l/derived open-state-ref)))
open-shadow (mf/deref open-status-ref)
hidden? (:hidden value)
on-remove-shadow
(mf/use-fn
(mf/deps ids index)
(fn []
(st/emit! (dwsh/update-shapes ids #(update % :shadow remove-shadow-by-index index)))))
hidden? (:hidden shadow)
on-drop
(mf/use-fn
@ -87,68 +70,53 @@
(h/use-sortable
:data-type "penpot/shadow-entry"
:on-drop on-drop
:disabled disable-drag?
:detect-center? false
:data {:id (dm/str "shadow-" index)
:index index
:name (dm/str "Border row" index)})
;; FIXME: this function causes the numeric-input rerender
;; ALWAYS, this is causes because numeric-input design makes
;; imposible implement efficiently any component that uses it;
;; it should be refactored
update-attr
(fn update-attr
([index attr]
(update-attr index attr nil))
([index attr update-ref]
(fn [value]
(when (mth/finite? value)
(st/emit! (dwsh/update-shapes ids #(assoc-in % [:shadow index attr] value)))
(when-let [update-node (and update-ref (mf/ref-val update-ref))]
(dom/set-value! update-node value))))))
on-remove
(mf/use-fn (mf/deps index) #(on-remove index))
update-color
on-update-offset-x
(mf/use-fn (mf/deps index) #(on-update index :offset-x %))
on-update-offset-y
(mf/use-fn (mf/deps index) #(on-update index :offset-y %))
on-update-spread
(mf/use-fn (mf/deps index) #(on-update index :spread %))
on-update-blur
(mf/use-fn (mf/deps index) #(on-update index :blur %))
on-update-color
(mf/use-fn (mf/deps index) #(on-update index :color (d/without-nils %)))
on-detach-color
(mf/use-fn (mf/deps index) #(on-detach-color index))
on-style-change
(mf/use-fn (mf/deps index) #(on-update index :style (keyword %)))
on-toggle-visibility
(mf/use-fn (mf/deps index) #(on-toggle-visibility index))
on-toggle-open
(mf/use-fn
(mf/deps ids index)
(fn [color]
(st/emit! (dwsh/update-shapes
ids
#(assoc-in % [:shadow index :color] (d/without-nils color))))))
(mf/deps shadow-id on-toggle-open)
#(on-toggle-open shadow-id))
detach-color
(mf/use-fn
(mf/deps ids index value)
(fn [_color _opacity]
(when-not (string? (:color value))
(st/emit! (dwsh/update-shapes
ids
#(assoc-in % [:shadow index :color]
(dissoc (:color value) :id :file-id)))))))
type-options
(mf/with-memo []
[{:value "drop-shadow" :label (tr "workspace.options.shadow-options.drop-shadow")}
{:value "inner-shadow" :label (tr "workspace.options.shadow-options.inner-shadow")}])
toggle-visibility
(mf/use-fn
(mf/deps ids index)
(fn []
(st/emit! (dwsh/update-shapes ids #(update-in % [:shadow index :hidden] not)))))
on-toggle-open-shadow
(fn []
(swap! open-state-ref update shadow-id not))
on-type-change
(mf/use-fn
(mf/deps ids index)
(fn [event]
(let [value (keyword event)]
(st/emit! (dwsh/update-shapes ids #(assoc-in % [:shadow index :style] value))))))
type-options [{:value "drop-shadow" :label (tr "workspace.options.shadow-options.drop-shadow")}
{:value "inner-shadow" :label (tr "workspace.options.shadow-options.inner-shadow")}]
manage-on-open #(st/emit! (dwu/start-undo-transaction :color-row))
manage-on-close #(st/emit! (dwu/commit-undo-transaction :color-row))]
on-open-row
(mf/use-fn #(st/emit! (dwu/start-undo-transaction :color-row)))
on-close-row
(mf/use-fn #(st/emit! (dwu/commit-undo-transaction :color-row)))]
[:div {:class (stl/css-case :global/shadow-option true
:shadow-element true
@ -162,137 +130,156 @@
[:div {:class (stl/css-case :shadow-info true
:hidden hidden?)}
[:button {:class (stl/css-case :more-options true
:selected open-shadow)
:on-click on-toggle-open-shadow}
:selected is-open)
:on-click on-toggle-open}
i/menu]
[:div {:class (stl/css :type-select)}
[:& select
{:class (stl/css :shadow-type-select)
:default-value (d/name shadow-style)
:options type-options
:on-change on-type-change}]]]
:on-change on-style-change}]]]
[:div {:class (stl/css :actions)}
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.shadow-options.toggle-shadow")
:on-click toggle-visibility
:on-click on-toggle-visibility
:icon (if hidden? "hide" "shown")}]
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.options.shadow-options.remove-shadow")
:on-click on-remove-shadow
:on-click on-remove
:icon "remove"}]]]
(when open-shadow
(when is-open
[:& advanced-options {:class (stl/css :shadow-advanced-options)
:visible? open-shadow
:on-close on-toggle-open-shadow}
:visible? is-open
:on-close on-toggle-open}
[:div {:class (stl/css :first-row)}
[:div {:class (stl/css :offset-x-input)
:title (tr "workspace.options.shadow-options.offsetx")}
[:span {:class (stl/css :input-label)}
"X"]
[:> numeric-input* {:className (stl/css :numeric-input)
:ref adv-offset-x-ref
[:> numeric-input* {:class (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change (update-attr index :offset-x basic-offset-x-ref)
:on-blur on-blur
:value (:offset-x value)}]]
:on-change on-update-offset-x
:value (:offset-x shadow)}]]
[:div {:class (stl/css :blur-input)
:title (tr "workspace.options.shadow-options.blur")}
[:span {:class (stl/css :input-label)}
(tr "workspace.options.shadow-options.blur")]
[:> numeric-input* {:ref adv-blur-ref
:className (stl/css :numeric-input)
[:> numeric-input* {:class (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change (update-attr index :blur basic-blur-ref)
:on-blur on-blur
:on-change on-update-blur
:min 0
:value (:blur value)}]]
:value (:blur shadow)}]]
[:div {:class (stl/css :spread-input)
:title (tr "workspace.options.shadow-options.spread")}
[:span {:class (stl/css :input-label)}
(tr "workspace.options.shadow-options.spread")]
[:> numeric-input* {:ref adv-spread-ref
:className (stl/css :numeric-input)
[:> numeric-input* {:class (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change (update-attr index :spread)
:on-blur on-blur
:value (:spread value)}]]]
:on-change on-update-spread
:value (:spread shadow)}]]]
[:div {:class (stl/css :second-row)}
[:div {:class (stl/css :offset-y-input)
:title (tr "workspace.options.shadow-options.offsety")}
[:span {:class (stl/css :input-label)}
"Y"]
[:> numeric-input* {:ref adv-offset-y-ref
:className (stl/css :numeric-input)
[:> numeric-input* {:class (stl/css :numeric-input)
:no-validate true
:placeholder "--"
:on-change (update-attr index :offset-y basic-offset-y-ref)
:on-blur on-blur
:value (:offset-y value)}]]
[:& color-row {:color (if (string? (:color value))
;; Support for old format colors
{:color (:color value) :opacity (:opacity value)}
(:color value))
:title (tr "workspace.options.shadow-options.color")
:disable-gradient true
:disable-image true
:on-change update-color
:on-detach detach-color
:on-open manage-on-open
:on-close manage-on-close}]]])]]))
:on-change on-update-offset-y
:value (:offset-y shadow)}]]
(mf/defc shadow-menu
{::mf/wrap-props false}
[props]
(let [ids (unchecked-get props "ids")
type (unchecked-get props "type")
values (unchecked-get props "values")
[:> color-row* {:color (:color shadow)
:title (tr "workspace.options.shadow-options.color")
:disable-gradient true
:disable-image true
:on-change on-update-color
:on-detach on-detach-color
:on-open on-open-row
:on-close on-close-row}]]])]]))
shadows (:shadow values [])
open-state-ref (mf/with-memo [] (l/atom {}))
has-shadows? (or (= :multiple shadows) (some? (seq shadows)))
(def ^:private xf:add-index
(map-indexed (fn [index shadow]
(assoc shadow ::index index))))
state* (mf/use-state {:show-content true
:disable-drag false})
(mf/defc shadow-menu*
[{:keys [ids type values] :as props}]
(let [shadows (mf/with-memo [values]
(if (= :multiple values)
values
(not-empty (into [] xf:add-index values))))
state (deref state*)
open? (:show-content state)
disable-drag? (:disable-drag state)
ids-ref (h/use-update-ref ids)
open-state* (mf/use-state {})
open-state (deref open-state*)
has-shadows? (or (= :multiple shadows)
(some? (seq shadows)))
show-content* (mf/use-state true)
show-content? (deref show-content*)
toggle-content
(mf/use-fn #(swap! state* update :show-content not))
(mf/use-fn #(swap! show-content* not))
on-toggle-open
(mf/use-fn #(swap! open-state* update % not))
on-remove-all
(mf/use-fn
(mf/deps ids)
(fn []
(st/emit! (dwsh/update-shapes ids #(dissoc % :shadow)))))
(let [ids (mf/ref-val ids-ref)]
(st/emit! (dwsh/update-shapes ids #(dissoc % :shadow))))))
handle-reorder
(mf/use-fn
(mf/deps ids)
(fn [new-index index]
(st/emit! (dc/reorder-shadows ids index new-index))))
on-blur
(mf/use-fn
#(swap! state* assoc :disable-drag false))
(let [ids (mf/ref-val ids-ref)]
(st/emit! (dc/reorder-shadows ids index new-index)))))
on-add-shadow
(mf/use-fn
(mf/deps ids)
#(st/emit! (dc/add-shadow ids (create-shadow))))]
(fn []
(let [ids (mf/ref-val ids-ref)]
(st/emit! (dc/add-shadow ids (create-shadow))))))
on-detach-color
(mf/use-fn
(fn [index]
(let [ids (mf/ref-val ids-ref)
f #(update-in % [:shadow index :color] dissoc :id :file-id :ref-id :ref-file)]
(st/emit! (dwsh/update-shapes ids f)))))
on-toggle-visibility
(mf/use-fn
(fn [index]
(let [ids (mf/ref-val ids-ref)]
(st/emit! (dwsh/update-shapes ids #(update-in % [:shadow index :hidden] not))))))
on-remove
(mf/use-fn
(fn [index]
(let [ids (mf/ref-val ids-ref)]
(st/emit! (dwsh/update-shapes ids #(update % :shadow remove-shadow-by-index index))))))
on-update
(mf/use-fn
(fn [index attr value]
(let [ids (mf/ref-val ids-ref)]
(st/emit! (dwsh/update-shapes ids #(assoc-in % [:shadow index attr] value))))))]
[:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-title)}
[:& title-bar {:collapsable has-shadows?
:collapsed (not open?)
:collapsed (not show-content?)
:on-collapsed toggle-content
:title (case type
:multiple (tr "workspace.options.shadow-options.title.multiple")
@ -307,7 +294,7 @@
:icon "add"
:data-testid "add-shadow"}])]]
(when open?
(when show-content?
(cond
(= :multiple shadows)
[:div {:class (stl/css :element-set-content)}
@ -319,16 +306,18 @@
:on-click on-remove-all
:icon "remove"}]]]]
(seq shadows)
(some? shadows)
[:& h/sortable-container {}
[:div {:class (stl/css :element-set-content)}
(for [[index value] (d/enumerate shadows)]
[:& shadow-entry
{:key (dm/str "shadow-" index)
:ids ids
:value value
:on-reorder handle-reorder
:disable-drag? disable-drag?
:on-blur on-blur
(for [{:keys [::index id] :as shadow} shadows]
[:> shadow-entry*
{:key (dm/str index)
:index index
:open-state-ref open-state-ref}])]]))]))
:shadow shadow
:on-update on-update
:on-remove on-remove
:on-toggle-visibility on-toggle-visibility
:on-detach-color on-detach-color
:is-open (get open-state id)
:on-reorder handle-reorder
:on-toggle-open on-toggle-open}])]]))]))

View file

@ -15,7 +15,7 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l]
[rumext.v2 :as mf]))
@ -24,27 +24,31 @@
(-> (l/key :background)
(l/derived refs/workspace-page)))
(mf/defc options
{::mf/wrap [mf/memo]
::mf/wrap-props false}
(mf/defc options*
{::mf/wrap [mf/memo]}
[]
(let [background (mf/deref ref:background-color)
on-change (mf/use-fn #(st/emit! (dw/change-canvas-color %)))
on-open (mf/use-fn #(st/emit! (dwu/start-undo-transaction :options)))
on-close (mf/use-fn #(st/emit! (dwu/commit-undo-transaction :options)))]
on-close (mf/use-fn #(st/emit! (dwu/commit-undo-transaction :options)))
color (mf/with-memo [background]
{:color (d/nilv background clr/canvas)
:opacity 1})]
[:div {:class (stl/css :element-set)}
[:div {:class (stl/css :element-title)}
[:& title-bar {:collapsable false
:title (tr "workspace.options.canvas-background")
:class (stl/css :title-spacing-page)}]]
[:div {:class (stl/css :element-content)}
[:& color-row
[:> color-row*
{:disable-gradient true
:disable-opacity true
:disable-image true
:title (tr "workspace.options.canvas-background")
:color {:color (d/nilv background clr/canvas)
:opacity 1}
:color color
:on-change on-change
:on-open on-open
:on-close on-close}]]]))

View file

@ -44,7 +44,7 @@
[v]
(if (= v :multiple) nil v))
(mf/defc color-row
(mf/defc color-row*
[{:keys [index color disable-gradient disable-opacity disable-image disable-picker hidden
on-change on-reorder on-detach on-open on-close on-remove
disable-drag on-focus on-blur select-only select-on-focus]}]

View file

@ -14,7 +14,7 @@
[app.main.ui.components.select :refer [select]]
[app.main.ui.hooks :as h]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row*]]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
@ -148,16 +148,17 @@
[:& reorder-handler {:ref dref}])
;; Stroke Color
[:& color-row {:color (ctc/stroke->shape-color stroke)
:index index
:title title
:on-change on-color-change-refactor
:on-detach on-color-detach
:on-remove on-remove
:disable-drag disable-drag
:on-focus on-focus
:select-on-focus select-on-focus
:on-blur on-blur}]
;; FIXME: memorize stroke color
[:> color-row* {:color (ctc/stroke->shape-color stroke)
:index index
:title title
:on-change on-color-change-refactor
:on-detach on-color-detach
:on-remove on-remove
:disable-drag disable-drag
:on-focus on-focus
:select-on-focus select-on-focus
:on-blur on-blur}]
;; Stroke Width, Alignment & Style
[:div {:class (stl/css :stroke-options)}

View file

@ -17,7 +17,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[rumext.v2 :as mf]))
@ -88,7 +88,7 @@
:type type
:show-caps true
:values stroke-values}]
[:& shadow-menu {:ids ids
:values (select-keys shape [:shadow])}]
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
[:& blur-menu {:ids ids
:values (select-keys shape [:blur])}]]))

View file

@ -17,7 +17,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[rumext.v2 :as mf]))
@ -89,8 +89,7 @@
[:& stroke-menu {:ids ids
:type type
:values stroke-values}]
[:& shadow-menu {:ids ids
:values (select-keys shape [:shadow])}]
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
[:& blur-menu {:ids ids
:values (select-keys shape [:blur])}]
[:& svg-attrs-menu {:ids ids

View file

@ -10,7 +10,7 @@
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu*]]
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs-shape fill-menu]]
@ -20,7 +20,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[rumext.v2 :as mf]))
@ -113,12 +113,11 @@
[:& stroke-menu {:ids ids
:type shape-type
:values stroke-values}]
[:& color-selection-menu {:type shape-type
:shapes shapes-with-children
:file-id file-id
:shared-libs shared-libs}]
[:& shadow-menu {:ids ids
:values (select-keys shape [:shadow])}]
[:> color-selection-menu* {:type shape-type
:shapes shapes-with-children
:file-id file-id
:libraries shared-libs}]
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
[:& blur-menu {:ids ids
:values (select-keys shape [:blur])}]
[:& frame-grid {:shape shape}]]))

View file

@ -12,7 +12,7 @@
[app.main.refs :as refs]
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu*]]
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu]]
@ -21,7 +21,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[app.main.ui.workspace.sidebar.options.menus.text :as ot]
@ -102,13 +102,14 @@
(when-not (empty? stroke-ids)
[:& stroke-menu {:type type :ids stroke-ids :values stroke-values}])
[:& color-selection-menu {:type type
:shapes (vals objects)
:file-id file-id
:shared-libs shared-libs}]
[:> color-selection-menu*
{:type type
:shapes (vals objects)
:file-id file-id
:libraries shared-libs}]
(when-not (empty? shadow-ids)
[:& shadow-menu {:type type :ids ids :values (select-keys shape [:shadow])}])
[:> shadow-menu* {:ids ids :values (get shape :shadow) :type type}])
(when-not (empty? blur-ids)
[:& blur-menu {:type type :ids blur-ids :values blur-values}])

View file

@ -17,7 +17,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[rumext.v2 :as mf]))
@ -91,8 +91,7 @@
:type type
:values stroke-values}]
[:& shadow-menu {:ids ids
:values (select-keys shape [:shadow])}]
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
[:& blur-menu {:ids ids
:values (select-keys shape [:blur])}]]))

View file

@ -17,7 +17,7 @@
[app.main.refs :as refs]
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-attrs blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu*]]
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-attrs exports-menu]]
@ -26,7 +26,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.text :as ot]
[rumext.v2 :as mf]))
@ -394,10 +394,16 @@
:disable-stroke-style has-text?}])
(when-not (empty? shapes)
[:& color-selection-menu {:file-id file-id :type type :shapes (vals objects-no-measures) :shared-libs shared-libs}])
[:> color-selection-menu*
{:file-id file-id
:type type
:shapes (vals objects-no-measures)
:libraries shared-libs}])
(when-not (empty? shadow-ids)
[:& shadow-menu {:type type :ids shadow-ids :values shadow-values}])
[:> shadow-menu* {:type type
:ids shadow-ids
:values (get shadow-values :shadow)}])
(when-not (empty? blur-ids)
[:& blur-menu {:type type :ids blur-ids :values blur-values}])

View file

@ -17,7 +17,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[rumext.v2 :as mf]))
@ -89,8 +89,7 @@
:type type
:show-caps true
:values stroke-values}]
[:& shadow-menu {:ids ids
:values (select-keys shape [:shadow])}]
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
[:& blur-menu {:ids ids
:values (select-keys shape [:blur])}]
[:& svg-attrs-menu {:ids ids

View file

@ -17,7 +17,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [select-measure-keys measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[rumext.v2 :as mf]))
@ -93,8 +93,7 @@
:type type
:values stroke-values}]
[:& shadow-menu {:ids ids
:values (select-keys shape [:shadow])}]
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
[:& blur-menu {:ids ids
:values (select-keys shape [:blur])}]

View file

@ -18,7 +18,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[cuerdas.core :as str]
@ -162,8 +162,7 @@
:type type
:values stroke-values}]
[:& shadow-menu {:ids ids
:values (select-keys shape [:shadow])}]
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
[:& blur-menu {:ids ids
:values (select-keys shape [:blur])}]

View file

@ -15,7 +15,7 @@
[app.main.store :as st]
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu*]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu fill-attrs]]
[app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell]
@ -23,7 +23,7 @@
[app.main.ui.workspace.sidebar.options.menus.layout-container :refer [layout-container-flex-attrs layout-container-menu]]
[app.main.ui.workspace.sidebar.options.menus.layout-item :refer [layout-item-attrs layout-item-menu]]
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu*]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu*]]
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu]]
[rumext.v2 :as mf]))
@ -146,11 +146,13 @@
:disable-stroke-style true}]
(when (= :multiple (:fills fill-values))
[:& color-selection-menu {:type type :shapes [shape] :file-id file-id :shared-libs shared-libs}])
[:> color-selection-menu*
{:type type
:shapes [shape]
:file-id file-id
:libraries shared-libs}])
[:& shadow-menu
{:ids ids
:values (select-keys shape [:shadow])}]
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
[:& blur-menu
{:ids ids