mirror of
https://github.com/penpot/penpot.git
synced 2025-07-26 02:37:22 +02:00
♻️ Refactor state management of shadow menu
This commit is contained in:
parent
c2fae0fef2
commit
b449074425
1 changed files with 62 additions and 66 deletions
|
@ -27,7 +27,6 @@
|
||||||
[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.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[okulary.core :as l]
|
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def shadow-attrs [:shadow])
|
(def shadow-attrs [:shadow])
|
||||||
|
@ -50,8 +49,8 @@
|
||||||
(filterv (fn [[idx _]] (not= idx index)))
|
(filterv (fn [[idx _]] (not= idx index)))
|
||||||
(mapv second)))
|
(mapv second)))
|
||||||
|
|
||||||
(mf/defc shadow-entry
|
(mf/defc shadow-entry*
|
||||||
[{:keys [ids index value on-reorder disable-drag? on-blur open-state-ref]}]
|
[{:keys [ids index shadow on-reorder is-open on-toggle-open]}]
|
||||||
(let [basic-offset-x-ref (mf/use-ref nil)
|
(let [basic-offset-x-ref (mf/use-ref nil)
|
||||||
basic-offset-y-ref (mf/use-ref nil)
|
basic-offset-y-ref (mf/use-ref nil)
|
||||||
basic-blur-ref (mf/use-ref nil)
|
basic-blur-ref (mf/use-ref nil)
|
||||||
|
@ -61,16 +60,12 @@
|
||||||
adv-blur-ref (mf/use-ref nil)
|
adv-blur-ref (mf/use-ref nil)
|
||||||
adv-spread-ref (mf/use-ref nil)
|
adv-spread-ref (mf/use-ref nil)
|
||||||
|
|
||||||
shadow-style (:style value)
|
shadow-style (:style shadow)
|
||||||
|
shadow-id (:id shadow)
|
||||||
|
|
||||||
shadow-id (:id value)
|
hidden? (:hidden shadow)
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
;; FIXME: move to parent
|
||||||
on-remove-shadow
|
on-remove-shadow
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps ids index)
|
(mf/deps ids index)
|
||||||
|
@ -87,7 +82,6 @@
|
||||||
(h/use-sortable
|
(h/use-sortable
|
||||||
:data-type "penpot/shadow-entry"
|
:data-type "penpot/shadow-entry"
|
||||||
:on-drop on-drop
|
:on-drop on-drop
|
||||||
:disabled disable-drag?
|
|
||||||
:detect-center? false
|
:detect-center? false
|
||||||
:data {:id (dm/str "shadow-" index)
|
:data {:id (dm/str "shadow-" index)
|
||||||
:index index
|
:index index
|
||||||
|
@ -118,13 +112,13 @@
|
||||||
|
|
||||||
detach-color
|
detach-color
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps ids index value)
|
(mf/deps ids index shadow)
|
||||||
(fn [_color _opacity]
|
(fn [_color _opacity]
|
||||||
(when-not (string? (:color value))
|
(when-not (string? (:color shadow))
|
||||||
(st/emit! (dwsh/update-shapes
|
(st/emit! (dwsh/update-shapes
|
||||||
ids
|
ids
|
||||||
#(assoc-in % [:shadow index :color]
|
#(assoc-in % [:shadow index :color]
|
||||||
(dissoc (:color value) :id :file-id)))))))
|
(dissoc (:color shadow) :id :file-id)))))))
|
||||||
|
|
||||||
toggle-visibility
|
toggle-visibility
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -132,9 +126,10 @@
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (dwsh/update-shapes ids #(update-in % [:shadow index :hidden] not)))))
|
(st/emit! (dwsh/update-shapes ids #(update-in % [:shadow index :hidden] not)))))
|
||||||
|
|
||||||
on-toggle-open-shadow
|
on-toggle-open
|
||||||
(fn []
|
(mf/use-fn
|
||||||
(swap! open-state-ref update shadow-id not))
|
(mf/deps shadow-id on-toggle-open)
|
||||||
|
#(on-toggle-open shadow-id))
|
||||||
|
|
||||||
on-type-change
|
on-type-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -143,12 +138,16 @@
|
||||||
(let [value (keyword event)]
|
(let [value (keyword event)]
|
||||||
(st/emit! (dwsh/update-shapes ids #(assoc-in % [:shadow index :style] value))))))
|
(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")}
|
type-options
|
||||||
{:value "inner-shadow" :label (tr "workspace.options.shadow-options.inner-shadow")}]
|
(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")}])
|
||||||
|
|
||||||
manage-on-open #(st/emit! (dwu/start-undo-transaction :color-row))
|
manage-on-open
|
||||||
manage-on-close #(st/emit! (dwu/commit-undo-transaction :color-row))]
|
(mf/use-fn #(st/emit! (dwu/start-undo-transaction :color-row)))
|
||||||
|
|
||||||
|
manage-on-close
|
||||||
|
(mf/use-fn #(st/emit! (dwu/commit-undo-transaction :color-row)))]
|
||||||
|
|
||||||
[:div {:class (stl/css-case :global/shadow-option true
|
[:div {:class (stl/css-case :global/shadow-option true
|
||||||
:shadow-element true
|
:shadow-element true
|
||||||
|
@ -162,8 +161,8 @@
|
||||||
[:div {:class (stl/css-case :shadow-info true
|
[:div {:class (stl/css-case :shadow-info true
|
||||||
:hidden hidden?)}
|
:hidden hidden?)}
|
||||||
[:button {:class (stl/css-case :more-options true
|
[:button {:class (stl/css-case :more-options true
|
||||||
:selected open-shadow)
|
:selected is-open)
|
||||||
:on-click on-toggle-open-shadow}
|
:on-click on-toggle-open}
|
||||||
i/menu]
|
i/menu]
|
||||||
[:div {:class (stl/css :type-select)}
|
[:div {:class (stl/css :type-select)}
|
||||||
[:& select
|
[:& select
|
||||||
|
@ -180,10 +179,10 @@
|
||||||
:aria-label (tr "workspace.options.shadow-options.remove-shadow")
|
:aria-label (tr "workspace.options.shadow-options.remove-shadow")
|
||||||
:on-click on-remove-shadow
|
:on-click on-remove-shadow
|
||||||
:icon "remove"}]]]
|
:icon "remove"}]]]
|
||||||
(when open-shadow
|
(when is-open
|
||||||
[:& advanced-options {:class (stl/css :shadow-advanced-options)
|
[:& advanced-options {:class (stl/css :shadow-advanced-options)
|
||||||
:visible? open-shadow
|
:visible? is-open
|
||||||
:on-close on-toggle-open-shadow}
|
:on-close on-toggle-open}
|
||||||
|
|
||||||
[:div {:class (stl/css :first-row)}
|
[:div {:class (stl/css :first-row)}
|
||||||
[:div {:class (stl/css :offset-x-input)
|
[:div {:class (stl/css :offset-x-input)
|
||||||
|
@ -195,8 +194,7 @@
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-change (update-attr index :offset-x basic-offset-x-ref)
|
:on-change (update-attr index :offset-x basic-offset-x-ref)
|
||||||
:on-blur on-blur
|
:value (:offset-x shadow)}]]
|
||||||
:value (:offset-x value)}]]
|
|
||||||
|
|
||||||
[:div {:class (stl/css :blur-input)
|
[:div {:class (stl/css :blur-input)
|
||||||
:title (tr "workspace.options.shadow-options.blur")}
|
:title (tr "workspace.options.shadow-options.blur")}
|
||||||
|
@ -207,9 +205,8 @@
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-change (update-attr index :blur basic-blur-ref)
|
:on-change (update-attr index :blur basic-blur-ref)
|
||||||
:on-blur on-blur
|
|
||||||
:min 0
|
:min 0
|
||||||
:value (:blur value)}]]
|
:value (:blur shadow)}]]
|
||||||
|
|
||||||
[:div {:class (stl/css :spread-input)
|
[:div {:class (stl/css :spread-input)
|
||||||
:title (tr "workspace.options.shadow-options.spread")}
|
:title (tr "workspace.options.shadow-options.spread")}
|
||||||
|
@ -220,8 +217,7 @@
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-change (update-attr index :spread)
|
:on-change (update-attr index :spread)
|
||||||
:on-blur on-blur
|
:value (:spread shadow)}]]]
|
||||||
:value (:spread value)}]]]
|
|
||||||
|
|
||||||
[:div {:class (stl/css :second-row)}
|
[:div {:class (stl/css :second-row)}
|
||||||
[:div {:class (stl/css :offset-y-input)
|
[:div {:class (stl/css :offset-y-input)
|
||||||
|
@ -233,14 +229,9 @@
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-change (update-attr index :offset-y basic-offset-y-ref)
|
:on-change (update-attr index :offset-y basic-offset-y-ref)
|
||||||
:on-blur on-blur
|
:value (:offset-y shadow)}]]
|
||||||
:value (:offset-y value)}]]
|
|
||||||
|
|
||||||
;; FIXME: memoize color
|
[:> color-row* {:color (:color shadow)
|
||||||
[:> 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")
|
:title (tr "workspace.options.shadow-options.color")
|
||||||
:disable-gradient true
|
:disable-gradient true
|
||||||
:disable-image true
|
:disable-image true
|
||||||
|
@ -249,26 +240,36 @@
|
||||||
:on-open manage-on-open
|
:on-open manage-on-open
|
||||||
:on-close manage-on-close}]]])]]))
|
:on-close manage-on-close}]]])]]))
|
||||||
|
|
||||||
|
(def ^:private xf:add-index
|
||||||
|
(map-indexed (fn [index shadow]
|
||||||
|
(assoc shadow ::index index))))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc shadow-menu
|
(mf/defc shadow-menu
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[props]
|
[{:keys [ids type values]}]
|
||||||
(let [ids (unchecked-get props "ids")
|
|
||||||
type (unchecked-get props "type")
|
|
||||||
values (unchecked-get props "values")
|
|
||||||
|
|
||||||
shadows (:shadow values [])
|
(let [shadows (get values :shadow [])
|
||||||
open-state-ref (mf/with-memo [] (l/atom {}))
|
shadows (mf/with-memo [shadows]
|
||||||
has-shadows? (or (= :multiple shadows) (some? (seq shadows)))
|
(if (= :multiple shadows)
|
||||||
|
shadows
|
||||||
|
(into [] xf:add-index shadows)))
|
||||||
|
|
||||||
state* (mf/use-state {:show-content true
|
open-state* (mf/use-state {})
|
||||||
:disable-drag false})
|
open-state (deref open-state*)
|
||||||
|
|
||||||
state (deref state*)
|
has-shadows? (or (= :multiple shadows)
|
||||||
open? (:show-content state)
|
(some? (seq shadows)))
|
||||||
disable-drag? (:disable-drag state)
|
|
||||||
|
show-content* (mf/use-state true)
|
||||||
|
show-content? (deref show-content*)
|
||||||
|
|
||||||
toggle-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
|
||||||
|
(fn [shadow-id] (swap! open-state* update shadow-id not)))
|
||||||
|
|
||||||
on-remove-all
|
on-remove-all
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -282,10 +283,6 @@
|
||||||
(fn [new-index index]
|
(fn [new-index index]
|
||||||
(st/emit! (dc/reorder-shadows ids index new-index))))
|
(st/emit! (dc/reorder-shadows ids index new-index))))
|
||||||
|
|
||||||
on-blur
|
|
||||||
(mf/use-fn
|
|
||||||
#(swap! state* assoc :disable-drag false))
|
|
||||||
|
|
||||||
on-add-shadow
|
on-add-shadow
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps ids)
|
(mf/deps ids)
|
||||||
|
@ -294,7 +291,7 @@
|
||||||
[:div {:class (stl/css :element-set)}
|
[:div {:class (stl/css :element-set)}
|
||||||
[:div {:class (stl/css :element-title)}
|
[:div {:class (stl/css :element-title)}
|
||||||
[:& title-bar {:collapsable has-shadows?
|
[:& title-bar {:collapsable has-shadows?
|
||||||
:collapsed (not open?)
|
:collapsed (not show-content?)
|
||||||
:on-collapsed toggle-content
|
:on-collapsed toggle-content
|
||||||
:title (case type
|
:title (case type
|
||||||
:multiple (tr "workspace.options.shadow-options.title.multiple")
|
:multiple (tr "workspace.options.shadow-options.title.multiple")
|
||||||
|
@ -309,7 +306,7 @@
|
||||||
:icon "add"
|
:icon "add"
|
||||||
:data-testid "add-shadow"}])]]
|
:data-testid "add-shadow"}])]]
|
||||||
|
|
||||||
(when open?
|
(when show-content?
|
||||||
(cond
|
(cond
|
||||||
(= :multiple shadows)
|
(= :multiple shadows)
|
||||||
[:div {:class (stl/css :element-set-content)}
|
[:div {:class (stl/css :element-set-content)}
|
||||||
|
@ -324,13 +321,12 @@
|
||||||
(seq shadows)
|
(seq shadows)
|
||||||
[:& h/sortable-container {}
|
[:& h/sortable-container {}
|
||||||
[:div {:class (stl/css :element-set-content)}
|
[:div {:class (stl/css :element-set-content)}
|
||||||
(for [[index value] (d/enumerate shadows)]
|
(for [{:keys [::index id] :as shadow} shadows]
|
||||||
[:& shadow-entry
|
[:> shadow-entry*
|
||||||
{:key (dm/str "shadow-" index)
|
{:key (dm/str "shadow-" index)
|
||||||
:ids ids
|
:ids ids
|
||||||
:value value
|
:shadow shadow
|
||||||
|
:is-open (get open-state id)
|
||||||
:on-reorder handle-reorder
|
:on-reorder handle-reorder
|
||||||
:disable-drag? disable-drag?
|
:on-toggle-open on-toggle-open
|
||||||
:on-blur on-blur
|
:index index}])]]))]))
|
||||||
:index index
|
|
||||||
:open-state-ref open-state-ref}])]]))]))
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue