diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc
index 10051ee759..cd53eea6ce 100644
--- a/common/src/app/common/types/shape/layout.cljc
+++ b/common/src/app/common/types/shape/layout.cljc
@@ -517,7 +517,7 @@
([objects id]
(item-absolute? (get objects id)))
([shape]
- (true? (:layout-item-absolute shape))))
+ (true? (get shape :layout-item-absolute))))
(defn position-absolute?
([objects id]
diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs
index 4e97749e9a..57672d4f14 100644
--- a/frontend/src/app/main/ui/context.cljs
+++ b/frontend/src/app/main/ui/context.cljs
@@ -30,7 +30,20 @@
(def workspace-read-only? (mf/create-context nil))
(def is-component? (mf/create-context false))
-(def sidebar (mf/create-context nil))
+
+(def sidebar
+ "A context that intends to store the current sidebar position,
+ usefull for components that behaves distinctly if they are showed in
+ right sidebar or left sidebar.
+
+ Possible values: `:right:` and `:left`."
+ (mf/create-context nil))
(def permissions (mf/create-context nil))
(def can-edit? (mf/create-context nil))
+
+(def active-tokens-by-type
+ "Active tokens by type, used mainly for provide tokens data to the
+ right sidebar menu options components."
+ (mf/create-context nil))
+
diff --git a/frontend/src/app/main/ui/ds/controls/numeric_input.cljs b/frontend/src/app/main/ui/ds/controls/numeric_input.cljs
index 38a55ef1da..c78248e145 100644
--- a/frontend/src/app/main/ui/ds/controls/numeric_input.cljs
+++ b/frontend/src/app/main/ui/ds/controls/numeric_input.cljs
@@ -65,14 +65,17 @@
(defn- get-option-by-name
[options name]
- (d/seek #(= name (get % :name)) options))
+ (let [options (if (delay? options) (deref options) options)]
+ (d/seek #(= name (get % :name)) options)))
(defn- get-token-op
[tokens name]
- (->> tokens
- vals
- (apply concat)
- (some #(when (= (:name %) name) %))))
+ (let [tokens (if (delay? tokens) @tokens tokens)
+ xform (filter #(= (:name %) name))]
+ (reduce-kv (fn [result _ tokens]
+ (into result xform tokens))
+ []
+ tokens)))
(defn- clean-token-name
[s]
@@ -114,14 +117,14 @@
(subs s (inc start))))
(defn- filter-token-groups-by-name
- [tokens-by-type filter-text]
+ [tokens filter-text]
(let [lc-filter (str/lower filter-text)]
(into {}
(keep (fn [[group tokens]]
(let [filtered (filter #(str/includes? (str/lower (:name %)) lc-filter) tokens)]
(when (seq filtered)
[group filtered]))))
- tokens-by-type)))
+ tokens)))
(defn- focusable-option?
[option]
@@ -183,7 +186,9 @@
is-selected-on-focus nillable
tokens applied-token empty-to-end
on-change on-blur on-focus on-detach
- property align ref] :rest props}]
+ property align ref]
+ :rest props}]
+
(let [;; NOTE: we use mfu/bean here for transparently handle
;; options provide as clojure data structures or javascript
;; plain objects and lists.
@@ -253,12 +258,14 @@
dropdown-options
(mf/with-memo [tokens filter-id]
- (let [partial (extract-partial-brace-text filter-id)
- options (if (seq partial)
- (filter-token-groups-by-name tokens partial)
- tokens)
- no-sets? (nil? tokens)]
- (generate-dropdown-options options no-sets?)))
+ (delay
+ (let [tokens (if (delay? tokens) @tokens tokens)
+ partial (extract-partial-brace-text filter-id)
+ options (if (seq partial)
+ (filter-token-groups-by-name tokens partial)
+ tokens)
+ no-sets? (nil? tokens)]
+ (generate-dropdown-options options no-sets?))))
selected-id*
(mf/use-state (fn []
@@ -351,23 +358,27 @@
on-option-click
(mf/use-fn
- (mf/deps dropdown-options on-token-apply)
+ (mf/deps on-token-apply)
(fn [event]
- (let [node (dom/get-current-target event)
- id (dom/get-data node "id")
- option (get-option dropdown-options id)
- value (get option :resolved-value)
- name (get option :name)]
+ (let [node (dom/get-current-target event)
+ id (dom/get-data node "id")
+ options (mf/ref-val options-ref)
+ options (if (delay? options) @options options)
+ option (get-option options id)
+ value (get option :resolved-value)
+ name (get option :name)]
(on-token-apply id value name)
(reset! filter-id* ""))))
on-option-enter
(mf/use-fn
- (mf/deps dropdown-options focused-id on-token-apply)
+ (mf/deps focused-id on-token-apply)
(fn [_]
- (let [option (get-option dropdown-options focused-id)
- value (get option :resolved-value)
- name (get option :name)]
+ (let [options (mf/ref-val options-ref)
+ options (if (delay? options) @options options)
+ option (get-option options focused-id)
+ value (get option :resolved-value)
+ name (get option :name)]
(on-token-apply focused-id value name)
(reset! filter-id* ""))))
@@ -386,9 +397,9 @@
(when (fn? on-blur)
(on-blur event)))))
- handle-key-down
+ on-key-down
(mf/use-fn
- (mf/deps dropdown-options is-open apply-value update-input is-open focused-id handle-focus-change)
+ (mf/deps is-open apply-value update-input is-open focused-id handle-focus-change)
(fn [event]
(mf/set-ref-val! dirty-ref true)
(let [up? (kbd/up-arrow? event)
@@ -398,7 +409,8 @@
node (mf/ref-val ref)
open-tokens (kbd/is-key? event "{")
close-tokens (kbd/is-key? event "}")
- options (mf/ref-val options-ref)]
+ options (mf/ref-val options-ref)
+ options (if (delay? options) @options options)]
(cond
(and (some? options) open-tokens)
@@ -418,8 +430,8 @@
(dom/prevent-default event)
(if focused-id
(on-option-enter event)
- (let [option-id (first-focusable-id dropdown-options)
- option (get-option dropdown-options option-id)
+ (let [option-id (first-focusable-id options)
+ option (get-option options option-id)
value (get option :resolved-value)
name (get option :name)]
(on-token-apply option-id value name)
@@ -461,7 +473,7 @@
(update-input (fmt/format-number new-val))
(apply-value (dm/str new-val))))))))
- handle-focus
+ on-focus
(mf/use-fn
(mf/deps on-focus select-on-focus)
(fn [event]
@@ -473,7 +485,7 @@
;; In webkit browsers the mouseup event will be called after the on-focus causing and unselect
(.addEventListener target "mouseup" dom/prevent-default #js {:once true})))))
- handle-mouse-wheel
+ on-mouse-wheel
(mf/use-fn
(mf/deps apply-value parse-value min max nillable ref default step min max)
(fn [event]
@@ -580,8 +592,8 @@
placeholder)
:default-value (or (mf/ref-val last-value*) (fmt/format-number value))
:on-blur on-blur
- :on-key-down handle-key-down
- :on-focus handle-focus
+ :on-key-down on-key-down
+ :on-focus on-focus
:on-change store-raw-value
:disabled disabled
:slot-start (when icon
@@ -603,11 +615,12 @@
token-props
(when (and token-applied (not= :multiple token-applied))
- (let [token (get-option-by-name dropdown-options token-applied)
- id (get token :id)
- label (get token :name)
+ (let [token (get-option-by-name dropdown-options token-applied)
+ id (get token :id)
+ label (get token :name)
token-value (or (get token :resolved-value)
- (or (mf/ref-val last-value*) (fmt/format-number value)))]
+ (or (mf/ref-val last-value*)
+ (fmt/format-number value)))]
(mf/spread-props props
{:id id
:label label
@@ -649,9 +662,9 @@
(when-let [node (mf/ref-val ref)]
(dom/set-value! node value'))))
- (mf/with-layout-effect [handle-mouse-wheel]
+ (mf/with-layout-effect [on-mouse-wheel]
(when-let [node (mf/ref-val ref)]
- (let [key (events/listen node "wheel" handle-mouse-wheel #js {:passive false})]
+ (let [key (events/listen node "wheel" on-mouse-wheel #js {:passive false})]
#(events/unlistenByKey key))))
(mf/with-effect [dropdown-options]
@@ -666,11 +679,12 @@
[:> input-field* input-props])
(when ^boolean is-open
- [:> options-dropdown* {:on-click on-option-click
- :id listbox-id
- :options dropdown-options
- :selected selected-id
- :focused focused-id
- :align align
- :empty-to-end empty-to-end
- :ref set-option-ref}])]))
+ (let [options (if (delay? dropdown-options) @dropdown-options dropdown-options)]
+ [:> options-dropdown* {:on-click on-option-click
+ :id listbox-id
+ :options options
+ :selected selected-id
+ :focused focused-id
+ :align align
+ :empty-to-end empty-to-end
+ :ref set-option-ref}]))]))
diff --git a/frontend/src/app/main/ui/ds/controls/select.cljs b/frontend/src/app/main/ui/ds/controls/select.cljs
index d5c91a3b81..0e31fe390d 100644
--- a/frontend/src/app/main/ui/ds/controls/select.cljs
+++ b/frontend/src/app/main/ui/ds/controls/select.cljs
@@ -20,8 +20,9 @@
(defn get-option
[options id]
- (or (d/seek #(= id (get % :id)) options)
- (nth options 0)))
+ (let [options (if (delay? options) @options options)]
+ (or (d/seek #(= id (get % :id)) options)
+ (nth options 0))))
(defn- get-selected-option-id
[options default]
diff --git a/frontend/src/app/main/ui/ds/layout/tab_switcher.stories.jsx b/frontend/src/app/main/ui/ds/layout/tab_switcher.stories.jsx
index 33840f8802..f5b1e2e83f 100644
--- a/frontend/src/app/main/ui/ds/layout/tab_switcher.stories.jsx
+++ b/frontend/src/app/main/ui/ds/layout/tab_switcher.stories.jsx
@@ -13,8 +13,8 @@ const Padded = ({ children }) => (
{children}
);
-const TabSwitcherWrapper = ({tabs, ...props}) => {
- const navTabs = tabs.map(({content, ...item}) => {
+const TabSwitcherWrapper = ({ tabs, ...props }) => {
+ const navTabs = tabs.map(({ content, ...item }) => {
return item;
});
@@ -28,7 +28,12 @@ const TabSwitcherWrapper = ({tabs, ...props}) => {
}, {});
return (
-
+
{content[selected]}
);
@@ -77,12 +82,7 @@ export default {
},
parameters: {
controls: {
- exclude: [
- "tabs",
- "actionButton",
- "default",
- "actionButtonPosition",
- ],
+ exclude: ["tabs", "actionButton", "default", "actionButtonPosition"],
},
},
render: ({ ...args }) => ,
diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs
index 39995ab816..ac89d1fe24 100644
--- a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs
+++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs
@@ -160,11 +160,7 @@
tooltip-brect (assoc tooltip-brect :height (or saved-height (:height tooltip-brect)) :width (or saved-width (:width tooltip-brect)))
window-size (dom/get-window-size)]
(when-let [[placement placement-rect] (find-matching-placement placement tooltip-brect origin-brect window-size offset)]
- (let [height (if (or (= placement "right") (= placement "left"))
- (- (:height placement-rect) arrow-height)
- (:height placement-rect))]
- (dom/set-data! tooltip "height" (:height tooltip-brect))
- (dom/set-data! tooltip "width" (:width tooltip-brect))
+ (let [height (:height placement-rect)]
(dom/set-css-property! tooltip "block-size" (dm/str height "px"))
(dom/set-css-property! tooltip "inset-block-start" (dm/str (:top placement-rect) "px"))
(dom/set-css-property! tooltip "inset-inline-start" (dm/str (:left placement-rect) "px")))
@@ -253,7 +249,7 @@
:on-focus on-show
:on-blur on-hide
:on-key-down handle-key-down
- :class (stl/css :tooltip-trigger)
+ :class [class (stl/css :tooltip-trigger)]
:aria-describedby id})
content
(if (fn? content)
@@ -262,7 +258,7 @@
[:> :div props
children
- [:div {:class [class (stl/css :tooltip)]
+ [:div {:class (stl/css :tooltip)
:id id
:popover "auto"
:role "tooltip"}
diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs
index b2c0b1192f..4125e47b99 100644
--- a/frontend/src/app/main/ui/workspace.cljs
+++ b/frontend/src/app/main/ui/workspace.cljs
@@ -29,8 +29,7 @@
[app.main.ui.workspace.nudge]
[app.main.ui.workspace.palette :refer [palette]]
[app.main.ui.workspace.plugins]
- [app.main.ui.workspace.sidebar :refer [left-sidebar* right-sidebar*]]
- [app.main.ui.workspace.sidebar.collapsable-button :refer [collapsed-button]]
+ [app.main.ui.workspace.sidebar :refer [sidebar*]]
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
[app.main.ui.workspace.tokens.export]
[app.main.ui.workspace.tokens.export.modal]
@@ -114,18 +113,14 @@
@palete-size)}]]]
(when-not hide-ui?
- [:*
- (if (:collapse-left-sidebar layout)
- [:& collapsed-button]
- [:> left-sidebar* {:layout layout
- :file file
- :page-id page-id}])
- [:> right-sidebar* {:section options-mode
- :selected selected
- :drawing-tool (get drawing :tool)
- :layout layout
- :file file
- :page-id page-id}]])]))
+ [:> sidebar* {:layout layout
+ ;; FIXME
+ :file-id (get file :id)
+ :page-id page-id
+ :file file
+ :selected selected
+ :section options-mode
+ :drawing-tool (get drawing :tool)}])]))
(mf/defc workspace-loader*
{::mf/private true}
diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs
index 11ce398f89..a64fa30b7b 100644
--- a/frontend/src/app/main/ui/workspace/sidebar.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar.cljs
@@ -8,9 +8,11 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
+ [app.common.types.tokens-lib :as ctob]
[app.main.constants :refer [sidebar-default-width sidebar-default-max-width]]
[app.main.data.common :as dcm]
[app.main.data.event :as ev]
+ [app.main.data.style-dictionary :as sd]
[app.main.data.workspace :as dw]
[app.main.features :as features]
[app.main.refs :as refs]
@@ -25,6 +27,7 @@
[app.main.ui.workspace.left-header :refer [left-header*]]
[app.main.ui.workspace.right-header :refer [right-header*]]
[app.main.ui.workspace.sidebar.assets :refer [assets-toolbox*]]
+ [app.main.ui.workspace.sidebar.collapsable-button :refer [collapsed-button*]]
[app.main.ui.workspace.sidebar.debug :refer [debug-panel*]]
[app.main.ui.workspace.sidebar.debug-shape-info :refer [debug-shape-info*]]
[app.main.ui.workspace.sidebar.history :refer [history-toolbox*]]
@@ -96,7 +99,7 @@
(mf/defc left-sidebar*
{::mf/memo true}
- [{:keys [layout file page-id] :as props}]
+ [{:keys [layout file page-id tokens-lib active-tokens resolved-active-tokens]}]
(let [options-mode (mf/deref refs/options-mode-global)
project (mf/deref refs/project)
file-id (get file :id)
@@ -147,7 +150,7 @@
:left-settings-bar true
:global/two-row (<= width 300)
:global/three-row (and (> width 300) (<= width 400))
- :global/four-row (> width 400))
+ :global/four-row (> width 400))
tabs-action-button
(mf/with-memo []
@@ -197,7 +200,10 @@
:file-id file-id}]
:tokens
- [:> tokens-sidebar-tab*]
+ [:> tokens-sidebar-tab*
+ {:tokens-lib tokens-lib
+ :active-tokens active-tokens
+ :resolved-active-tokens resolved-active-tokens}]
:layers
[:> layers-content*
@@ -255,8 +261,7 @@
[:> history-toolbox*]])]))
(mf/defc right-sidebar*
- {::mf/memo true}
- [{:keys [layout section file page-id drawing-tool] :as props}]
+ [{:keys [layout section file page-id drawing-tool active-tokens] :as props}]
(let [is-comments? (= drawing-tool :comments)
is-history? (contains? layout :document-history)
is-inspect? (= section :inspect)
@@ -289,45 +294,84 @@
(fn []
(set-width (if (> width sidebar-default-width)
sidebar-default-width
- sidebar-default-max-width))))]
+ sidebar-default-max-width))))
+
+ active-tokens-by-type
+ (mf/with-memo [active-tokens]
+ (delay (ctob/group-by-type active-tokens)))]
[:> (mf/provider muc/sidebar) {:value :right}
- [:aside
- {:class (stl/css-case :right-settings-bar true
- :not-expand (not can-be-expanded?)
- :expanded (> width sidebar-default-width))
+ [:> (mf/provider muc/active-tokens-by-type) {:value active-tokens-by-type}
- :id "right-sidebar-aside"
- :data-testid "right-sidebar"
- :data-size (str width)
- :style {:--width (if can-be-expanded?
- (dm/str width "px")
- (dm/str sidebar-default-width "px"))}}
+ [:aside
+ {:class (stl/css-case :right-settings-bar true
+ :not-expand (not can-be-expanded?)
+ :expanded (> width sidebar-default-width))
- (when can-be-expanded?
- [:div {:class (stl/css :resize-area)
- :on-pointer-down on-pointer-down
- :on-lost-pointer-capture on-lost-pointer-capture
- :on-pointer-move on-pointer-move}])
+ :id "right-sidebar-aside"
+ :data-testid "right-sidebar"
+ :data-size (str width)
+ :style {:--width (if can-be-expanded?
+ (dm/str width "px")
+ (dm/str sidebar-default-width "px"))}}
- [:> right-header*
- {:file file
- :layout layout
- :page-id page-id}]
+ (when can-be-expanded?
+ [:div {:class (stl/css :resize-area)
+ :on-pointer-down on-pointer-down
+ :on-lost-pointer-capture on-lost-pointer-capture
+ :on-pointer-move on-pointer-move}])
- [:div {:class (stl/css :settings-bar-inside)}
- (cond
- dbg-shape-panel?
- [:> debug-shape-info*]
+ [:> right-header*
+ {:file file
+ :layout layout
+ :page-id page-id}]
- is-comments?
- [:> comments-sidebar* {}]
+ [:div {:class (stl/css :settings-bar-inside)}
+ (cond
+ dbg-shape-panel?
+ [:> debug-shape-info*]
- is-history?
- [:> history-content* {}]
+ is-comments?
+ [:> comments-sidebar* {}]
- :else
- (let [props (mf/spread-props props
- {:on-change-section on-change-section
- :on-expand on-expand})]
- [:> options-toolbox* props]))]]]))
+ is-history?
+ [:> history-content* {}]
+
+ :else
+ (let [props (mf/spread-props props
+ {:on-change-section on-change-section
+ :on-expand on-expand})]
+ [:> options-toolbox* props]))]]]]))
+
+(mf/defc sidebar*
+ [{:keys [layout file file-id page-id section drawing-tool selected]}]
+ (let [tokens-lib
+ (mf/deref refs/tokens-lib)
+
+ active-tokens
+ (mf/with-memo [tokens-lib]
+ (if tokens-lib
+ (ctob/get-tokens-in-active-sets tokens-lib)
+ {}))
+
+ resolved-active-tokens
+ (sd/use-resolved-tokens* active-tokens)]
+
+ [:*
+ (if (:collapse-left-sidebar layout)
+ [:> collapsed-button*]
+ [:> left-sidebar* {:layout layout
+ :file file
+ :page-id page-id
+ :tokens-lib tokens-lib
+ :active-tokens active-tokens
+ :resolved-active-tokens resolved-active-tokens}])
+ [:> right-sidebar* {:section section
+ :selected selected
+ :drawing-tool drawing-tool
+ :layout layout
+ :file file
+ :file-id file-id
+ :page-id page-id
+ :tokens-lib tokens-lib
+ :active-tokens resolved-active-tokens}]]))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.cljs b/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.cljs
index 3f74853818..074e8e14b0 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/collapsable_button.cljs
@@ -13,8 +13,8 @@
[app.util.i18n :refer [tr]]
[rumext.v2 :as mf]))
-(mf/defc collapsed-button
- {::mf/wrap-props false}
+(mf/defc collapsed-button*
+ {::mf/memo true}
[]
(let [on-click (mf/use-fn #(st/emit! (dw/toggle-layout-flag :collapse-left-sidebar)))]
[:div {:id "left-sidebar-aside"
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs
index 5c16891da1..d88d29b019 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs
@@ -20,8 +20,8 @@
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
[app.main.ui.inspect.right-sidebar :as hrs]
[app.main.ui.workspace.sidebar.options.drawing :as drawing]
- [app.main.ui.workspace.sidebar.options.menus.align :refer [align-options]]
- [app.main.ui.workspace.sidebar.options.menus.bool :refer [bool-options]]
+ [app.main.ui.workspace.sidebar.options.menus.align :refer [align-options*]]
+ [app.main.ui.workspace.sidebar.options.menus.bool :refer [bool-options*]]
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]]
[app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu]]
[app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell]
@@ -32,7 +32,6 @@
[app.main.ui.workspace.sidebar.options.shapes.circle :as circle]
[app.main.ui.workspace.sidebar.options.shapes.frame :as frame]
[app.main.ui.workspace.sidebar.options.shapes.group :as group]
- [app.main.ui.workspace.sidebar.options.shapes.image :as image]
[app.main.ui.workspace.sidebar.options.shapes.multiple :as multiple]
[app.main.ui.workspace.sidebar.options.shapes.path :as path]
[app.main.ui.workspace.sidebar.options.shapes.rect :as rect]
@@ -57,14 +56,13 @@
[:*
(case shape-type
:frame [:> frame/options* props]
- :group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :libraries libraries}]
- :text [:& text/options {:shape shape :file-id file-id :libraries libraries}]
- :rect [:& rect/options {:shape shape}]
- :circle [:& circle/options {:shape shape}]
- :path [:& path/options {:shape shape}]
- :image [:& image/options {:shape shape}]
- :svg-raw [:& svg-raw/options {:shape shape}]
- :bool [:& bool/options {:shape shape}]
+ :group [:> group/options* {:shape shape :shape-with-children shapes-with-children :file-id file-id :libraries libraries}]
+ :text [:> text/options* {:shape shape :file-id file-id :libraries libraries}]
+ :rect [:> rect/options* {:shape shape}]
+ :circle [:> circle/options* {:shape shape}]
+ :path [:> path/options* {:shape shape}]
+ :svg-raw [:> svg-raw/options* {:shape shape}]
+ :bool [:> bool/options* {:shape shape}]
nil)
[:& exports-menu
{:ids [(:id shape)]
@@ -73,7 +71,7 @@
:page-id page-id
:file-id file-id}]]))
-(mf/defc specialized-panel
+(mf/defc specialized-panel*
{::mf/wrap [mf/memo]}
[{:keys [panel]}]
(when (= (:type panel) :component-swap)
@@ -92,8 +90,8 @@
(map #(dm/get-in objects [edition :layout-grid-cells %])))]
[:div {:class (stl/css :element-options :design-options)}
- [:& align-options]
- [:& bool-options]
+ [:> align-options*]
+ [:> bool-options*]
(cond
(and edit-grid? (d/not-empty? selected-cells))
@@ -107,7 +105,7 @@
:values (get objects edition)}]
(not (nil? sp-panel))
- [:& specialized-panel {:panel sp-panel}]
+ [:> specialized-panel* {:panel sp-panel}]
(d/not-empty? drawing)
[:> drawing/drawing-options*
@@ -125,7 +123,7 @@
:shapes-with-children shapes-with-children}]
:else
- [:& multiple/options
+ [:> multiple/options*
{:shapes-with-children shapes-with-children
:shapes selected-shapes
:page-id page-id
@@ -210,12 +208,9 @@
(mf/defc options-toolbox*
{::mf/memo true}
- [{:keys [section selected on-change-section on-expand]}]
- (let [page-id (mf/use-ctx ctx/current-page-id)
- file-id (mf/use-ctx ctx/current-file-id)
- shapes (mf/deref refs/selected-objects)
+ [{:keys [page-id file-id section selected on-change-section on-expand]}]
+ (let [shapes (mf/deref refs/selected-objects)
shapes-with-children (mf/deref refs/selected-shapes-with-children)]
-
[:> options-content* {:shapes shapes
:selected selected
:shapes-with-children shapes-with-children
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.cljs
index c34e757e50..b4f97f78ec 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/align.cljs
@@ -16,7 +16,8 @@
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
-(mf/defc align-options
+(mf/defc align-options*
+ {::mf/memo true}
[]
(let [selected (mf/deref refs/selected-shapes)
;; don't need to watch objects, only read the value
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs
index 7c6c620dc2..5d6359a082 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs
@@ -22,7 +22,8 @@
(def ^:private flatten-icon
(i/icon-xref :boolean-flatten (stl/css :flatten-icon)))
-(mf/defc bool-options
+(mf/defc bool-options*
+ {::mf/memo true}
[]
(let [selected (mf/deref refs/selected-objects)
head (first selected)
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
index bfb460c624..5712d0977b 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
@@ -8,6 +8,8 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
+ [app.common.data.macros :as dm]
+ [app.common.geom.rect :as grc]
[app.common.geom.shapes :as gsh]
[app.common.logic.shapes :as cls]
[app.common.types.shape :as cts]
@@ -25,7 +27,6 @@
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as ds-i]
- [app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.options.menus.border-radius :refer [border-radius-menu*]]
[app.util.dom :as dom]
@@ -61,7 +62,6 @@
:circle generic-options
:frame frame-options
:group generic-options
- :image rect-options
:path generic-options
:rect rect-options
:svg-raw generic-options
@@ -87,92 +87,139 @@
shape)]
(select-keys shape measure-attrs)))
+(def ^:private xf:map-type (map :type))
+(def ^:private xf:mapcat-type-to-options (mapcat type->options))
+
(mf/defc measures-menu*
- {::mf/props :obj
- ::mf/wrap [mf/memo]}
- [{:keys [ids ids-with-children values type all-types shape]}]
- (let [options
+ {::mf/memo true}
+ [{:keys [ids ids-with-children values type shapes]}]
+ (let [all-types
+ (mf/with-memo [type shapes]
+ ;; We only need this when multiple type is used
+ (when (= type :multiple)
+ (into #{} xf:map-type shapes)))
+
+ options
(mf/with-memo [type all-types]
(if (= type :multiple)
- (into #{} (mapcat type->options) all-types)
+ (into #{} xf:mapcat-type-to-options all-types)
(type->options type)))
ids-with-children
- (or ids-with-children ids)
-
- old-shapes
- (if (= type :multiple)
- (deref (refs/objects-by-id ids))
- [shape])
+ (d/nilv ids-with-children ids)
frames
- (map #(deref (refs/object-by-id (:frame-id %))) old-shapes)
+ (mf/with-memo [shapes]
+ (let [objects (deref refs/workspace-page-objects)]
+ (into [] (comp (keep :frame-id)
+ (map (d/getf objects)))
+ shapes)))
- ids (hooks/use-equal-memo ids)
+ selection-parents-ref
+ (mf/with-memo [ids]
+ (refs/parents-by-ids ids))
- selection-parents-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- selection-parents (mf/deref selection-parents-ref)
+ selection-parents
+ (mf/deref selection-parents-ref)
- flex-child? (->> selection-parents (some ctl/flex-layout?))
- absolute? (ctl/item-absolute? shape)
- flex-container? (ctl/flex-layout? shape)
- flex-auto-width? (ctl/auto-width? shape)
- flex-fill-width? (ctl/fill-width? shape)
- flex-auto-height? (ctl/auto-height? shape)
- flex-fill-height? (ctl/fill-height? shape)
+ shape
+ (first shapes)
- disabled-position-x? (and flex-child? (not absolute?))
- disabled-position-y? (and flex-child? (not absolute?))
- disabled-width-sizing? (and (or flex-child? flex-container?)
- (or flex-auto-width? flex-fill-width?)
- (not absolute?))
- disabled-height-sizing? (and (or flex-child? flex-container?)
- (or flex-auto-height? flex-fill-height?)
- (not absolute?))
+ flex-child?
+ (some ctl/flex-layout? selection-parents)
+
+ absolute?
+ (ctl/item-absolute? shape)
+
+ flex-container?
+ (ctl/flex-layout? shape)
+
+ flex-auto-width?
+ (ctl/auto-width? shape)
+
+ flex-fill-width?
+ (ctl/fill-width? shape)
+
+ flex-auto-height?
+ (ctl/auto-height? shape)
+
+ flex-fill-height?
+ (ctl/fill-height? shape)
+
+ disabled-position?
+ (and flex-child? (not absolute?))
+
+ disabled-width-sizing?
+ (and (or flex-child? flex-container?)
+ (or flex-auto-width? flex-fill-width?)
+ (not absolute?))
+
+ disabled-height-sizing?
+ (and (or flex-child? flex-container?)
+ (or flex-auto-height? flex-fill-height?)
+ (not absolute?))
;; To show interactively the measures while the user is manipulating
;; the shape with the mouse, generate a copy of the shapes applying
;; the transient transformations.
- shapes (as-> old-shapes $
- (map gsh/translate-to-frame $ frames))
+ shapes
+ (mf/with-memo [shapes frames]
+ (map gsh/translate-to-frame shapes frames))
+
+ ;; We repeatedly obtain the first shape after the
+ ;; transformation.
+ shape
+ (first shapes)
;; For rotated or stretched shapes, the origin point we show in the menu
;; is not the (:x :y) shape attribute, but the top left coordinate of the
;; wrapping rectangle.
- values (let [{:keys [x y]} (gsh/shapes->rect [(first shapes)])]
- (cond-> values
- (not= (:x values) :multiple) (assoc :x x)
- (not= (:y values) :multiple) (assoc :y y)
- ;; In case of multiple selection, the origin point has been already
- ;; calculated and given in the fake :ox and :oy attributes. See
- ;; common/src/app/common/attrs.cljc
- (and (= (:x values) :multiple)
- (some? (:ox values))) (assoc :x (:ox values))
- (and (= (:y values) :multiple)
- (some? (:oy values))) (assoc :y (:oy values))))
+ values
+ (let [rect (-> (get shape :points)
+ (grc/points->rect))
+ val-x (get values :x)
+ val-y (get values :y)]
+ (cond-> values
+ (not= val-x :multiple) (assoc :x (dm/get-prop rect :x))
+ (not= val-y :multiple) (assoc :y (dm/get-prop rect :y))
+ ;; In case of multiple selection, the origin point has been already
+ ;; calculated and given in the fake :ox and :oy attributes. See
+ ;; common/src/app/common/attrs.cljc
+ (and (= val-x :multiple)
+ (some? (:ox values)))
+ (assoc :x (:ox values))
+
+ (and (= val-y :multiple)
+ (some? (:oy values)))
+ (assoc :y (:oy values))))
;; For :height and :width we take those in the :selrect attribute, because
;; not all shapes have an own :width and :height (e. g. paths). Here the
;; rotation is ignored (selrect always has the original size excluding
;; transforms).
- values (let [{:keys [width height]} (-> shapes first :selrect)]
- (cond-> values
- (not= (:width values) :multiple) (assoc :width width)
- (not= (:height values) :multiple) (assoc :height height)))
+ values
+ (let [selrect (get shape :selrect)
+ rotation (get shape :rotation 0)]
+ (cond-> values
+ (not= (:width values) :multiple) (assoc :width (dm/get-prop selrect :width))
+ (not= (:height values) :multiple) (assoc :height (dm/get-prop selrect :height))
+ (not= (:rotation values) :multiple) (assoc :rotation rotation)))
- ;; The :rotation, however, does use the transforms.
- values (let [{:keys [rotation] :or {rotation 0}} (-> shapes first)]
- (cond-> values
- (not= (:rotation values) :multiple) (assoc :rotation rotation)))
+ proportion-lock
+ (get values :proportion-lock)
- proportion-lock (:proportion-lock values)
+ clip-content-ref
+ (mf/use-ref nil)
- clip-content-ref (mf/use-ref nil)
- show-in-viewer-ref (mf/use-ref nil)
+ show-in-viewer-ref
+ (mf/use-ref nil)
;; PRESETS
- preset-state* (mf/use-state false)
- show-presets-dropdown? (deref preset-state*)
+ preset-state*
+ (mf/use-state false)
+
+ show-presets-dropdown?
+ (deref preset-state*)
open-presets
(mf/use-fn
@@ -254,10 +301,17 @@
(st/emit! (udw/trigger-bounding-box-cloaking ids)
(udw/increase-rotation ids value)))))
- on-width-change #(on-size-change % :width)
- on-height-change #(on-size-change % :height)
- on-pos-x-change #(on-position-change % :x)
- on-pos-y-change #(on-position-change % :y)
+ on-width-change
+ (mf/use-fn (mf/deps on-size-change) #(on-size-change % :width))
+
+ on-height-change
+ (mf/use-fn (mf/deps on-size-change) #(on-size-change % :height))
+
+ on-pos-x-change
+ (mf/use-fn (mf/deps on-position-change) #(on-position-change % :x))
+
+ on-pos-y-change
+ (mf/use-fn (mf/deps on-position-change) #(on-position-change % :y))
;; CLIP CONTENT AND SHOW IN VIEWER
on-change-clip-content
@@ -277,9 +331,9 @@
(dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape (not value)))))
(when-not value
- ;; when a frame is no longer shown in view mode, cannot have
- ;; interactions that navigate to it.
- (apply st/emit! (map #(dwi/remove-all-interactions-nav-to %) ids)))
+ ;; when a frame is no longer shown in view mode, cannot
+ ;; have interactions that navigate to it.
+ (run! st/emit! (map #(dwi/remove-all-interactions-nav-to %) ids)))
(st/emit! (dwu/commit-undo-transaction undo-id)))))
@@ -373,27 +427,28 @@
(when (options :position)
[:div {:class (stl/css :position)}
[:div {:class (stl/css-case :x-position true
- :disabled disabled-position-x?)
+ :disabled disabled-position?)
:title (tr "workspace.options.x")}
[:span {:class (stl/css :icon-text)} "X"]
[:> numeric-input* {:no-validate true
:placeholder (if (= :multiple (:x values)) (tr "settings.multiple") "--")
:on-change on-pos-x-change
- :disabled disabled-position-x?
+ :disabled disabled-position?
:class (stl/css :numeric-input)
:value (:x values)}]]
[:div {:class (stl/css-case :y-position true
- :disabled disabled-position-y?)
+ :disabled disabled-position?)
:title (tr "workspace.options.y")}
[:span {:class (stl/css :icon-text)} "Y"]
[:> numeric-input* {:no-validate true
:placeholder (if (= :multiple (:y values)) (tr "settings.multiple") "--")
- :disabled disabled-position-y?
+ :disabled disabled-position?
:on-change on-pos-y-change
:class (stl/css :numeric-input)
:value (:y values)}]]])
- (when (or (options :rotation) (options :radius))
+ (when (or (options :rotation)
+ (options :radius))
[:div {:class (stl/css :rotation-radius)}
(when (options :rotation)
[:div {:class (stl/css :rotation)
@@ -409,7 +464,11 @@
:class (stl/css :numeric-input)
:value (:rotation values)}]])
(when (options :radius)
- [:> border-radius-menu* {:class (stl/css :border-radius) :ids ids :ids-with-children ids-with-children :values values :shape shape}])])
+ [:> border-radius-menu* {:class (stl/css :border-radius)
+ :ids ids
+ :ids-with-children ids-with-children
+ :values values
+ :shape shape}])])
(when (or (options :clip-content) (options :show-in-viewer))
[:div {:class (stl/css :clip-show)}
(when (options :clip-content)
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs
index 1b8626b222..5fb56162b2 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/bool.cljs
@@ -6,9 +6,9 @@
(ns app.main.ui.workspace.sidebar.options.shapes.bool
(:require
+ [app.common.data.macros :as dm]
[app.common.types.shape.layout :as ctl]
[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.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :as fill]
@@ -21,31 +21,61 @@
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
[rumext.v2 :as mf]))
-(mf/defc options
+(mf/defc options*
[{:keys [shape] :as props}]
- (let [ids [(:id shape)]
- type (:type shape)
- measure-values (select-keys shape measure-attrs)
- stroke-values (select-keys shape stroke-attrs)
- layer-values (select-keys shape layer-attrs)
- constraint-values (select-keys shape constraint-attrs)
- layout-item-values (select-keys shape layout-item-attrs)
- layout-container-values (select-keys shape layout-container-flex-attrs)
+ (let [id (dm/get-prop shape :id)
+ type (dm/get-prop shape :type)
+ ids (mf/with-memo [id] [id])
+ shapes (mf/with-memo [shape] [shape])
- is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child-ref)
+ measure-values
+ (select-keys shape measure-attrs)
- is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent-ref)
+ stroke-values
+ (select-keys shape stroke-attrs)
- is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent-ref)
+ layer-values
+ (select-keys shape layer-attrs)
- is-layout-child-absolute? (ctl/item-absolute? shape)
+ constraint-values
+ (select-keys shape constraint-attrs)
- ids (hooks/use-equal-memo ids)
- parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- parents (mf/deref parents-by-ids-ref)]
+ layout-item-values
+ (select-keys shape layout-item-attrs)
+
+ layout-container-values
+ (select-keys shape layout-container-flex-attrs)
+
+ is-layout-child-ref
+ (mf/with-memo [ids]
+ (refs/is-layout-child? ids))
+
+ is-layout-child?
+ (mf/deref is-layout-child-ref)
+
+ is-flex-parent-ref
+ (mf/with-memo [ids]
+ (refs/flex-layout-child? ids))
+
+ is-flex-parent?
+ (mf/deref is-flex-parent-ref)
+
+ is-grid-parent-ref
+ (mf/with-memo [ids]
+ (refs/grid-layout-child? ids))
+
+ is-grid-parent?
+ (mf/deref is-grid-parent-ref)
+
+ is-layout-child-absolute?
+ (ctl/item-absolute? shape)
+
+ parents-by-ids-ref
+ (mf/with-memo [ids]
+ (refs/parents-by-ids ids))
+
+ parents
+ (mf/deref parents-by-ids-ref)]
[:*
[:& layer-menu {:ids ids
@@ -55,7 +85,7 @@
[:> measures-menu* {:ids ids
:type type
:values measure-values
- :shape shape}]
+ :shapes shapes}]
[:& layout-container-menu
{:type type
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs
index e3f856541c..de2524a82e 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/circle.cljs
@@ -6,9 +6,9 @@
(ns app.main.ui.workspace.sidebar.options.shapes.circle
(:require
+ [app.common.data.macros :as dm]
[app.common.types.shape.layout :as ctl]
[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.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :as fill]
@@ -22,32 +22,61 @@
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[rumext.v2 :as mf]))
-(mf/defc options
+(mf/defc options*
[{:keys [shape] :as props}]
- (let [ids [(:id shape)]
- type (:type shape)
+ (let [id (dm/get-prop shape :id)
+ type (dm/get-prop shape :type)
+ ids (mf/with-memo [id] [id])
+ shapes (mf/with-memo [shape] [shape])
- measure-values (select-keys shape measure-attrs)
- stroke-values (select-keys shape stroke-attrs)
- layer-values (select-keys shape layer-attrs)
- constraint-values (select-keys shape constraint-attrs)
- layout-item-values (select-keys shape layout-item-attrs)
- layout-container-values (select-keys shape layout-container-flex-attrs)
+ measure-values
+ (select-keys shape measure-attrs)
- is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child-ref)
+ stroke-values
+ (select-keys shape stroke-attrs)
- is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent-ref)
+ layer-values
+ (select-keys shape layer-attrs)
- is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent-ref)
+ constraint-values
+ (select-keys shape constraint-attrs)
- is-layout-child-absolute? (ctl/item-absolute? shape)
+ layout-item-values
+ (select-keys shape layout-item-attrs)
- ids (hooks/use-equal-memo ids)
- parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- parents (mf/deref parents-by-ids-ref)]
+ layout-container-values
+ (select-keys shape layout-container-flex-attrs)
+
+ is-layout-child-ref
+ (mf/with-memo [ids]
+ (refs/is-layout-child? ids))
+
+ is-layout-child?
+ (mf/deref is-layout-child-ref)
+
+ is-flex-parent-ref
+ (mf/with-memo [ids]
+ (refs/flex-layout-child? ids))
+
+ is-flex-parent?
+ (mf/deref is-flex-parent-ref)
+
+ is-grid-parent-ref
+ (mf/with-memo [ids]
+ (refs/grid-layout-child? ids))
+
+ is-grid-parent?
+ (mf/deref is-grid-parent-ref)
+
+ is-layout-child-absolute?
+ (ctl/item-absolute? shape)
+
+ parents-by-ids-ref
+ (mf/with-memo [ids]
+ (refs/parents-by-ids ids))
+
+ parents
+ (mf/deref parents-by-ids-ref)]
[:*
[:& layer-menu {:ids ids
:type type
@@ -56,7 +85,7 @@
[:> measures-menu* {:ids ids
:type type
:values measure-values
- :shape shape}]
+ :shapes shapes}]
[:& layout-container-menu
{:type type
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs
index 2319e89036..29d51767dd 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs
@@ -31,49 +31,77 @@
(let [shape-id (dm/get-prop shape :id)
shape-type (dm/get-prop shape :type)
- ids (mf/with-memo [shape-id]
- [shape-id])
+ ids
+ (mf/with-memo [shape-id]
+ [shape-id])
- shapes (mf/with-memo [shape]
- [shape])
+ shapes
+ (mf/with-memo [shape]
+ [shape])
- stroke-values (select-keys shape stroke-attrs)
- layer-values (select-keys shape layer-attrs)
- measure-values (select-measure-keys shape)
- constraint-values (select-keys shape constraint-attrs)
- layout-container-values (select-keys shape layout-container-flex-attrs)
- layout-item-values (select-keys shape layout-item-attrs)
+ stroke-values
+ (select-keys shape stroke-attrs)
+
+ layer-values
+ (select-keys shape layer-attrs)
+
+ measure-values
+ (select-measure-keys shape)
+
+ constraint-values
+ (select-keys shape constraint-attrs)
+
+ layout-container-values
+ (select-keys shape layout-container-flex-attrs)
+
+ layout-item-values
+ (select-keys shape layout-item-attrs)
is-layout-child-ref
(mf/with-memo [ids]
(refs/is-layout-child? ids))
+
is-layout-child?
(mf/deref is-layout-child-ref)
is-flex-parent-ref
(mf/with-memo [ids]
(refs/flex-layout-child? ids))
+
is-flex-parent?
(mf/deref is-flex-parent-ref)
is-grid-parent-ref
(mf/with-memo [ids]
(refs/grid-layout-child? ids))
+
is-grid-parent?
(mf/deref is-grid-parent-ref)
parents-by-ids-ref
(mf/with-memo [ids]
(refs/parents-by-ids ids))
+
parents
(mf/deref parents-by-ids-ref)
- is-layout-container? (ctl/any-layout? shape)
- is-flex-layout? (ctl/flex-layout? shape)
- is-grid-layout? (ctl/grid-layout? shape)
- is-layout-child-absolute? (ctl/item-absolute? shape)
- variants? (features/use-feature "variants/v1")
- is-variant? (when variants? (ctk/is-variant-container? shape))]
+ is-layout-container?
+ (ctl/any-layout? shape)
+
+ is-flex-layout?
+ (ctl/flex-layout? shape)
+
+ is-grid-layout?
+ (ctl/grid-layout? shape)
+
+ is-layout-child-absolute?
+ (ctl/item-absolute? shape)
+
+ variants?
+ (features/use-feature "variants/v1")
+
+ is-variant?
+ (when variants? (ctk/is-variant-container? shape))]
[:*
[:& layer-menu {:ids ids
@@ -82,7 +110,7 @@
[:> measures-menu* {:ids ids
:values measure-values
:type shape-type
- :shape shape}]
+ :shapes shapes}]
[:& component-menu {:shapes shapes}]
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs
index a4ca975316..a7adc2aeda 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/group.cljs
@@ -8,9 +8,9 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
+ [app.common.data.macros :as dm]
[app.common.types.shape.layout :as ctl]
[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.constraints :refer [constraints-menu]]
@@ -27,48 +27,89 @@
[app.main.ui.workspace.sidebar.options.shapes.multiple :refer [get-attrs]]
[rumext.v2 :as mf]))
-(mf/defc options
- {::mf/wrap [mf/memo]
- ::mf/wrap-props false}
- [props]
- (let [shape (unchecked-get props "shape")
- shape-with-children (unchecked-get props "shape-with-children")
- libraries (unchecked-get props "libraries")
- objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
- file-id (unchecked-get props "file-id")
- layout-container-values (select-keys shape layout-container-flex-attrs)
- ids [(:id shape)]
- is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child-ref)
+(mf/defc options*
+ {::mf/wrap [mf/memo]}
+ [{:keys [shape shapes-with-children libraries file-id] :as props}]
- is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent-ref)
+ (let [id (dm/get-prop shape :id)
+ type (dm/get-prop shape :type)
+ ids (mf/with-memo [id] [id])
+ shapes (mf/with-memo [shape] [shape])
- is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent-ref)
+ objects
+ (mf/with-memo [shapes-with-children]
+ (d/index-by :id shapes-with-children))
- is-layout-child-absolute? (ctl/item-absolute? shape)
+ layout-container-values
+ (select-keys shape layout-container-flex-attrs)
- ids (hooks/use-equal-memo ids)
- parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- parents (mf/deref parents-by-ids-ref)
+ svg-values
+ (select-keys shape [:svg-attrs])
- type :group
- [measure-ids measure-values] (get-attrs [shape] objects :measure)
- [layer-ids layer-values] (get-attrs [shape] objects :layer)
- [constraint-ids constraint-values] (get-attrs [shape] objects :constraint)
- [fill-ids fill-values] (get-attrs [shape] objects :fill)
- [shadow-ids _] (get-attrs [shape] objects :shadow)
- [blur-ids blur-values] (get-attrs [shape] objects :blur)
- [stroke-ids stroke-values] (get-attrs [shape] objects :stroke)
- [text-ids text-values] (get-attrs [shape] objects :text)
- [svg-ids svg-values] [[(:id shape)] (select-keys shape [:svg-attrs])]
- [layout-item-ids layout-item-values] (get-attrs [shape] objects :layout-item)]
+ is-layout-child-ref
+ (mf/with-memo [ids]
+ (refs/is-layout-child? ids))
+ is-layout-child?
+ (mf/deref is-layout-child-ref)
+
+ is-flex-parent-ref
+ (mf/with-memo [ids]
+ (refs/flex-layout-child? ids))
+
+ is-flex-parent?
+ (mf/deref is-flex-parent-ref)
+
+ is-grid-parent-ref
+ (mf/with-memo [ids]
+ (refs/grid-layout-child? ids))
+
+ is-grid-parent?
+ (mf/deref is-grid-parent-ref)
+
+ is-layout-child-absolute?
+ (ctl/item-absolute? shape)
+
+ parents-by-ids-ref
+ (mf/with-memo [ids]
+ (refs/parents-by-ids ids))
+
+ parents
+ (mf/deref parents-by-ids-ref)
+
+ [measure-ids measure-values]
+ (get-attrs shapes objects :measure)
+
+ [layer-ids layer-values]
+ (get-attrs shapes objects :layer)
+
+ [constraint-ids constraint-values]
+ (get-attrs shapes objects :constraint)
+
+ [fill-ids fill-values]
+ (get-attrs shapes objects :fill)
+
+ [shadow-ids]
+ (get-attrs shapes objects :shadow)
+
+ [blur-ids blur-values]
+ (get-attrs shapes objects :blur)
+
+ [stroke-ids stroke-values]
+ (get-attrs shapes objects :stroke)
+
+ [text-ids text-values]
+ (get-attrs shapes objects :text)
+
+ [layout-item-ids layout-item-values]
+ (get-attrs shapes objects :layout-item)]
[:div {:class (stl/css :options)}
[:& layer-menu {:type type :ids layer-ids :values layer-values}]
- [:> measures-menu* {:type type :ids measure-ids :values measure-values :shape shape}]
+ [:> measures-menu* {:type type
+ :ids measure-ids
+ :values measure-values
+ :shapes shapes}]
[:& layout-container-menu
{:type type
@@ -116,7 +157,6 @@
[:& ot/text-menu {:type type :ids text-ids :values text-values}])
(when-not (empty? svg-values)
- [:& svg-attrs-menu {:ids svg-ids
- :values svg-values}])]))
+ [:& svg-attrs-menu {:ids ids :values svg-values}])]))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs
deleted file mode 100644
index 8dc58b05d9..0000000000
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/image.cljs
+++ /dev/null
@@ -1,97 +0,0 @@
-;; This Source Code Form is subject to the terms of the Mozilla Public
-;; License, v. 2.0. If a copy of the MPL was not distributed with this
-;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;;
-;; Copyright (c) KALEIDOS INC
-
-(ns app.main.ui.workspace.sidebar.options.shapes.image
- (:require
- [app.common.types.shape.layout :as ctl]
- [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.constraints :refer [constraint-attrs constraints-menu]]
- [app.main.ui.workspace.sidebar.options.menus.fill :as fill]
- [app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell]
- [app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
- [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.stroke :refer [stroke-attrs stroke-menu]]
- [rumext.v2 :as mf]))
-
-(mf/defc options
- [{:keys [shape] :as props}]
- (let [ids [(:id shape)]
- type (:type shape)
-
- measure-values (select-keys shape measure-attrs)
- layer-values (select-keys shape layer-attrs)
- constraint-values (select-keys shape constraint-attrs)
- stroke-values (select-keys shape stroke-attrs)
- layout-item-values (select-keys shape layout-item-attrs)
- layout-container-values (select-keys shape layout-container-flex-attrs)
-
- is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child-ref)
-
- is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent-ref)
-
- is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent-ref)
-
- is-layout-child-absolute? (ctl/item-absolute? shape)
-
- ids (hooks/use-equal-memo ids)
- parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- parents (mf/deref parents-by-ids-ref)]
- [:*
- [:& layer-menu {:ids ids
- :type type
- :values layer-values}]
-
- [:> measures-menu* {:ids ids
- :type type
- :values measure-values
- :shape shape}]
-
- [:& layout-container-menu
- {:type type
- :ids [(:id shape)]
- :values layout-container-values
- :multiple false}]
-
- (when (and (= (count ids) 1) is-layout-child? is-grid-parent?)
- [:& grid-cell/options
- {:shape (first parents)
- :cell (ctl/get-cell-by-shape-id (first parents) (first ids))}])
-
- (when is-layout-child?
- [:& layout-item-menu
- {:ids ids
- :type type
- :values layout-item-values
- :is-layout-child? true
- :is-flex-parent? is-flex-parent?
- :is-grid-parent? is-grid-parent?
- :shape shape}])
-
- (when (or (not ^boolean is-layout-child?) ^boolean is-layout-child-absolute?)
- [:& constraints-menu {:ids ids
- :values constraint-values}])
-
- [:> fill/fill-menu*
- {:ids ids
- :type type
- :values shape}]
-
- [:& stroke-menu {:ids ids
- :type type
- :values stroke-values}]
-
- [:> shadow-menu* {:ids ids :values (get shape :shadow)}]
-
- [:& blur-menu {:ids ids
- :values (select-keys shape [:blur])}]]))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs
index 2429021307..ae6295f6dc 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs
@@ -9,14 +9,16 @@
(:require
[app.common.attrs :as attrs]
[app.common.data :as d]
+ [app.common.data.macros :as dm]
+ [app.common.files.helpers :as cfh]
[app.common.geom.shapes :as gsh]
[app.common.types.component :as ctk]
[app.common.types.path :as path]
[app.common.types.shape.attrs :refer [editable-attrs]]
[app.common.types.shape.layout :as ctl]
[app.common.types.text :as txt]
+ [app.common.weak :as weak]
[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.component :refer [component-menu]]
@@ -202,10 +204,6 @@
applies (some of them ignore some attributes)"
[shapes objects attr-group]
(let [attrs (group->attrs attr-group)
-
- default-text-attrs
- (txt/get-default-text-attrs)
-
merge-attrs
(fn [v1 v2]
(cond
@@ -213,8 +211,21 @@
(= attr-group :blur) (attrs/get-attrs-multi [v1 v2] attrs blur-eq blur-sel)
:else (attrs/get-attrs-multi [v1 v2] attrs)))
+ merge-token-values
+ (fn [acc keys attrs]
+ (reduce
+ (fn [accum key]
+ (let [new-val (get attrs key)
+ existing (get accum key ::not-found)]
+ (cond
+ (= existing ::not-found) (assoc accum key new-val)
+ (= existing new-val) accum
+ :else (assoc accum key :multiple))))
+ acc
+ keys))
+
extract-attrs
- (fn [[ids values] {:keys [id type] :as shape}]
+ (fn [[ids values token-acc] {:keys [id type applied-tokens] :as shape}]
(let [read-mode (get-in type->read-mode [type attr-group])
editable-attrs (filter (get editable-attrs (:type shape)) attrs)]
(case read-mode
@@ -228,144 +239,192 @@
(into {} (map #(vector % nil)) editable-attrs)
(cond
(= attr-group :measure) (select-measure-keys shape)
- :else (select-keys shape editable-attrs)))]
+ :else (select-keys shape editable-attrs)))
+ new-token-acc (merge-token-values token-acc editable-attrs applied-tokens)]
[(conj ids id)
- (merge-attrs values shape-values)])
+ (merge-attrs values shape-values)
+ new-token-acc])
:text
(let [shape-attrs (select-keys shape attrs)
content-attrs
- (attrs/get-text-attrs-multi shape default-text-attrs attrs)
+ (attrs/get-text-attrs-multi shape txt/default-text-attrs attrs)
new-values
(-> values
(merge-attrs shape-attrs)
- (merge-attrs content-attrs))]
+ (merge-attrs content-attrs))
+
+ new-token-acc (merge-token-values token-acc content-attrs applied-tokens)]
[(conj ids id)
- new-values])
+ new-values
+ new-token-acc])
:children
(let [children (->> (:shapes shape []) (map #(get objects %)))
[new-ids new-values] (get-attrs* children objects attr-group)]
- [(d/concat-vec ids new-ids) (merge-attrs values new-values)])
+ [(d/concat-vec ids new-ids) (merge-attrs values new-values) {}])
[])))]
- (reduce extract-attrs [[] []] shapes)))
+ (reduce extract-attrs [[] {} {}] shapes)))
-(def get-attrs (memoize get-attrs*))
-
-(defn basic-shape [_ shape]
- (cond-> shape
- :always
- (dissoc :selrect :points :x :y :width :height :transform :transform-inverse :rotation :svg-transform :svg-viewbox :thumbnail)
-
- (= (:type shape) :path)
- (dissoc :content)))
+(def get-attrs
+ (weak/memoize get-attrs*))
(defn- is-bool-descendant?
- [[_ shape] objects selected-shape-ids]
+ [objects selected-shape-ids shape]
(let [parent-id (:parent-id shape)
parent (get objects parent-id)]
(cond
- (nil? shape) false ;; failsafe
- (contains? selected-shape-ids (:id shape)) false ;; if it is one of the selected shapes, it is considerer not a bool descendant
- (= :bool (:type parent)) true ;; if its parent is of type bool, it is a bool descendant
+ (nil? shape) false ;; failsafe
+ (contains? selected-shape-ids (:id shape)) false ;; if it is one of the selected shapes, it is considerer not a bool descendant
+ (= :bool (:type parent)) true ;; if its parent is of type bool, it is a bool descendant
:else (recur [parent-id parent] objects selected-shape-ids)))) ;; else, check its parent
-(mf/defc options
- {::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "shapes-with-children" "page-id" "file-id"]))]
- ::mf/wrap-props false}
- [props]
- (let [shapes (unchecked-get props "shapes")
- shapes-with-children (unchecked-get props "shapes-with-children")
+(defn- check-options-props
+ [new-props old-props]
+ (and (= (unchecked-get new-props "shapes")
+ (unchecked-get old-props "shapes"))
+ (= (unchecked-get new-props "shapesWithChildren")
+ (unchecked-get old-props "shapesWithChildren"))
+ (= (unchecked-get new-props "pageId")
+ (unchecked-get old-props "pageId"))
+ (= (unchecked-get new-props "fileId")
+ (unchecked-get old-props "fileId"))))
- ;; remove children from bool shapes
- shape-ids (into #{} (map :id) shapes)
+(mf/defc options*
+ {::mf/wrap [#(mf/memo' % check-options-props)]}
+ [{:keys [shapes shapes-with-children page-id file-id libraries] :as props}]
+ (let [shape-ids
+ (mf/with-memo [shapes]
+ (into #{} d/xf:map-id shapes))
+
+ is-layout-child-ref
+ (mf/with-memo [shape-ids]
+ (refs/is-layout-child? shape-ids))
+
+ is-layout-child?
+ (mf/deref is-layout-child-ref)
+
+ is-flex-parent-ref
+ (mf/with-memo [shape-ids]
+ (refs/flex-layout-child? shape-ids))
+
+ is-flex-parent?
+ (mf/deref is-flex-parent-ref)
+
+ is-grid-parent-ref
+ (mf/with-memo [shape-ids]
+ (refs/grid-layout-child? shape-ids))
+
+ is-grid-parent?
+ (mf/deref is-grid-parent-ref)
+
+ has-flex-layout-container?
+ (some ctl/flex-layout? shapes)
+
+ all-layout-child-ref
+ (mf/with-memo [shape-ids]
+ (refs/all-layout-child? shape-ids))
+
+ all-layout-child?
+ (mf/deref all-layout-child-ref)
+
+ all-flex-layout-container?
+ (mf/with-memo [shapes]
+ (every? ctl/flex-layout? shapes))
+
+ show-caps?
+ (mf/with-memo [shapes]
+ (some #(and (cfh/path-shape? %)
+ (path/shape-with-open-path? %))
+ shapes))
+
+ has-text?
+ (mf/with-memo [shapes]
+ (some cfh/text-shape? shapes))
- objects (->> shapes-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
objects
- (into {}
- (filter #(not (is-bool-descendant? % objects shape-ids)))
- objects)
+ (mf/with-memo [shapes-with-children]
+ (let [objects (d/index-by :id shapes-with-children)]
+ (reduce-kv (fn [objects id object]
+ (if (is-bool-descendant? objects shape-ids object)
+ (dissoc objects id)
+ objects))
+ objects
+ objects)))
- workspace-modifiers (mf/deref refs/workspace-modifiers)
- shapes (map #(gsh/transform-shape % (get-in workspace-modifiers [(:id %) :modifiers])) shapes)
+ [layer-ids layer-values]
+ (get-attrs shapes objects :layer)
- page-id (unchecked-get props "page-id")
- file-id (unchecked-get props "file-id")
- shared-libs (unchecked-get props "libraries")
+ [text-ids text-values]
+ (get-attrs shapes objects :text)
- show-caps (some #(and (= :path (:type %)) (path/shape-with-open-path? %)) shapes)
+ [constraint-ids constraint-values]
+ (get-attrs shapes objects :constraint)
- ;; Selrect/points only used for measures and it's the one that changes the most. We separate it
- ;; so we can memoize it
- objects-no-measures (->> objects (d/mapm basic-shape))
- objects-no-measures (hooks/use-equal-memo objects-no-measures)
+ [fill-ids fill-values]
+ (get-attrs shapes objects :fill)
+
+ [shadow-ids shadow-values]
+ (get-attrs shapes objects :shadow)
+
+ [blur-ids blur-values]
+ (get-attrs shapes objects :blur)
+
+ [stroke-ids stroke-values]
+ (get-attrs shapes objects :stroke)
+
+ [exports-ids exports-values]
+ (get-attrs shapes objects :exports)
+
+ [layout-container-ids layout-container-values]
+ (get-attrs shapes objects :layout-container)
+
+ [layout-item-ids layout-item-values {}]
+ (get-attrs shapes objects :layout-item)
+
+ components
+ (mf/with-memo [shapes]
+ (not-empty (filter ctk/instance-head? shapes)))
+
+ workspace-modifiers
+ (mf/deref refs/workspace-modifiers)
+
+ shapes
+ (mf/with-memo [workspace-modifiers shapes]
+ (into []
+ (map (fn [shape]
+ (let [shape-id (dm/get-prop shape :id)
+ modifiers (dm/get-in workspace-modifiers [shape-id :modifiers])]
+ (gsh/transform-shape shape modifiers))))
+ shapes))
type :multiple
- all-types (into #{} (map :type shapes))
- ids (->> shapes (map :id))
- is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child-ref)
-
- is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent-ref)
-
- is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent-ref)
-
- has-text? (contains? all-types :text)
-
- has-flex-layout-container? (->> shapes (some ctl/flex-layout?))
-
- all-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/all-layout-child? ids))
- all-layout-child? (mf/deref all-layout-child-ref)
-
- all-flex-layout-container? (->> shapes (every? ctl/flex-layout?))
-
- [measure-ids measure-values] (get-attrs shapes objects :measure)
-
- [layer-ids layer-values
- text-ids text-values
- constraint-ids constraint-values
- fill-ids fill-values
- shadow-ids shadow-values
- blur-ids blur-values
- stroke-ids stroke-values
- exports-ids exports-values
- layout-container-ids layout-container-values
- layout-item-ids layout-item-values]
- (mf/use-memo
- (mf/deps shapes objects-no-measures)
- (fn []
- (into
- []
- (mapcat identity)
- [(get-attrs shapes objects-no-measures :layer)
- (get-attrs shapes objects-no-measures :text)
- (get-attrs shapes objects-no-measures :constraint)
- (get-attrs shapes objects-no-measures :fill)
- (get-attrs shapes objects-no-measures :shadow)
- (get-attrs shapes objects-no-measures :blur)
- (get-attrs shapes objects-no-measures :stroke)
- (get-attrs shapes objects-no-measures :exports)
- (get-attrs shapes objects-no-measures :layout-container)
- (get-attrs shapes objects-no-measures :layout-item)])))
-
- components (filter ctk/instance-head? shapes)]
+ ;; NOTE: we only need transformed shapes for the measure menu,
+ ;; the rest of menus can live with shapes not transformed; we
+ ;; also don't use the memoized version of get-attrs because it
+ ;; makes no sense because the shapes object are changed on
+ ;; each rerender.
+ [measure-ids measure-values]
+ (get-attrs* shapes objects :measure)]
[:div {:class (stl/css :options)}
(when-not (empty? layer-ids)
[:& layer-menu {:type type :ids layer-ids :values layer-values}])
(when-not (empty? measure-ids)
- [:> measures-menu* {:type type :all-types all-types :ids measure-ids :values measure-values :shape shapes}])
+ [:> measures-menu*
+ {:type type
+ :ids measure-ids
+ :values measure-values
+ :shapes shapes}])
- (when-not (empty? components)
+ (when (some? components)
[:& component-menu {:shapes components}])
[:& layout-container-menu
@@ -394,15 +453,18 @@
[:> fill/fill-menu* {:type type :ids fill-ids :values fill-values}])
(when-not (empty? stroke-ids)
- [:& stroke-menu {:type type :ids stroke-ids :show-caps show-caps :values stroke-values
+ [:& stroke-menu {:type type
+ :ids stroke-ids
+ :show-caps show-caps?
+ :values stroke-values
:disable-stroke-style has-text?}])
(when-not (empty? shapes)
[:> color-selection-menu*
{:file-id file-id
:type type
- :shapes (vals objects-no-measures)
- :libraries shared-libs}])
+ :shapes shapes
+ :libraries libraries}])
(when-not (empty? shadow-ids)
[:> shadow-menu* {:type type
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs
index 5c2e418f7b..8ad6e802ea 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/path.cljs
@@ -6,9 +6,9 @@
(ns app.main.ui.workspace.sidebar.options.shapes.path
(:require
+ [app.common.data.macros :as dm]
[app.common.types.shape.layout :as ctl]
[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.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :as fill]
@@ -22,32 +22,68 @@
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
[rumext.v2 :as mf]))
-(mf/defc options
+(mf/defc options*
[{:keys [shape] :as props}]
- (let [ids [(:id shape)]
- type (:type shape)
+ (let [ids
+ (mf/with-memo [shape]
+ [(dm/get-prop shape :id)])
- measure-values (select-keys shape measure-attrs)
- stroke-values (select-keys shape stroke-attrs)
- layer-values (select-keys shape layer-attrs)
- constraint-values (select-keys shape constraint-attrs)
- layout-item-values (select-keys shape layout-item-attrs)
- layout-container-values (select-keys shape layout-container-flex-attrs)
+ shapes
+ (mf/with-memo [shape]
+ [shape])
- is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child-ref)
+ type
+ (dm/get-prop shape :type)
- is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent-ref)
+ measure-values
+ (select-keys shape measure-attrs)
- is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent-ref)
+ stroke-values
+ (select-keys shape stroke-attrs)
- is-layout-child-absolute? (ctl/item-absolute? shape)
+ layer-values
+ (select-keys shape layer-attrs)
+
+ constraint-values
+ (select-keys shape constraint-attrs)
+
+ layout-item-values
+ (select-keys shape layout-item-attrs)
+
+ layout-container-values
+ (select-keys shape layout-container-flex-attrs)
+
+ is-layout-child-ref
+ (mf/with-memo [ids]
+ (refs/is-layout-child? ids))
+
+ is-layout-child?
+ (mf/deref is-layout-child-ref)
+
+ is-flex-parent-ref
+ (mf/with-memo [ids]
+ (refs/flex-layout-child? ids))
+
+ is-flex-parent?
+ (mf/deref is-flex-parent-ref)
+
+ is-grid-parent-ref
+ (mf/with-memo [ids]
+ (refs/grid-layout-child? ids))
+
+ is-grid-parent?
+ (mf/deref is-grid-parent-ref)
+
+ is-layout-child-absolute?
+ (ctl/item-absolute? shape)
+
+ parents-by-ids-ref
+ (mf/with-memo [ids]
+ (refs/parents-by-ids ids))
+
+ parents
+ (mf/deref parents-by-ids-ref)]
- ids (hooks/use-equal-memo ids)
- parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- parents (mf/deref parents-by-ids-ref)]
[:*
[:& layer-menu {:ids ids
:type type
@@ -55,7 +91,7 @@
[:> measures-menu* {:ids ids
:type type
:values measure-values
- :shape shape}]
+ :shapes shapes}]
[:& layout-container-menu
{:type type
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs
index 69a082a82d..75d67efe29 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/rect.cljs
@@ -6,9 +6,9 @@
(ns app.main.ui.workspace.sidebar.options.shapes.rect
(:require
+ [app.common.data.macros :as dm]
[app.common.types.shape.layout :as ctl]
[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.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :as fill]
@@ -16,39 +16,67 @@
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
[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.measures :refer [measure-attrs measures-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]))
-(mf/defc options
- {::mf/wrap [mf/memo]
- ::mf/wrap-props false}
+(mf/defc options*
[{:keys [shape]}]
- (let [shape-id (:id shape)
- ids (hooks/use-equal-memo [shape-id])
- type (:type shape)
- measure-values (select-measure-keys shape)
- layer-values (select-keys shape layer-attrs)
- constraint-values (select-keys shape constraint-attrs)
- stroke-values (select-keys shape stroke-attrs)
- layout-item-values (select-keys shape layout-item-attrs)
- layout-container-values (select-keys shape layout-container-flex-attrs)
+ (let [id (dm/get-prop shape :id)
+ type (dm/get-prop shape :type)
+ ids (mf/with-memo [id] [id])
+ shapes (mf/with-memo [shape] [shape])
- is-layout-child* (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child*)
+ measure-values
+ (select-keys shape measure-attrs)
- is-flex-parent* (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent*)
+ stroke-values
+ (select-keys shape stroke-attrs)
- is-grid-parent* (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent*)
+ layer-values
+ (select-keys shape layer-attrs)
- is-layout-child-absolute? (ctl/item-absolute? shape)
+ constraint-values
+ (select-keys shape constraint-attrs)
- parents-by-ids* (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- parents (mf/deref parents-by-ids*)]
+ layout-item-values
+ (select-keys shape layout-item-attrs)
+
+ layout-container-values
+ (select-keys shape layout-container-flex-attrs)
+
+ is-layout-child-ref
+ (mf/with-memo [ids]
+ (refs/is-layout-child? ids))
+
+ is-layout-child?
+ (mf/deref is-layout-child-ref)
+
+ is-flex-parent-ref
+ (mf/with-memo [ids]
+ (refs/flex-layout-child? ids))
+
+ is-flex-parent?
+ (mf/deref is-flex-parent-ref)
+
+ is-grid-parent-ref
+ (mf/with-memo [ids]
+ (refs/grid-layout-child? ids))
+
+ is-grid-parent?
+ (mf/deref is-grid-parent-ref)
+
+ is-layout-child-absolute?
+ (ctl/item-absolute? shape)
+
+ parents-by-ids-ref
+ (mf/with-memo [ids]
+ (refs/parents-by-ids ids))
+
+ parents
+ (mf/deref parents-by-ids-ref)]
[:*
[:& layer-menu {:ids ids
@@ -57,7 +85,7 @@
[:> measures-menu* {:ids ids
:type type
:values measure-values
- :shape shape}]
+ :shapes shapes}]
[:& layout-container-menu
{:type type
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs
index 66dc19614f..e0af0d6d07 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/svg_raw.cljs
@@ -7,10 +7,10 @@
(ns app.main.ui.workspace.sidebar.options.shapes.svg-raw
(:require
[app.common.data :as d]
+ [app.common.data.macros :as dm]
[app.common.types.color :as cc]
[app.common.types.shape.layout :as ctl]
[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.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :as fill]
@@ -26,15 +26,10 @@
;; This is a list of svg tags that can be grouped in shape-container
;; this allows them to have gradients, shadows and masks
-(def svg-elements #{:svg :g :circle :ellipse :image :line :path :polygon :polyline :rect :symbol :text :textPath})
+(def ^:private svg-elements
+ #{:svg :g :circle :ellipse :image :line :path :polygon :polyline :rect :symbol :text :textPath})
-(defn hex->number [_] 1)
-
-(defn shorthex->longhex [hex]
- (let [[_ r g b] hex]
- (str "#" r r g g b b)))
-
-(defn parse-color [color]
+(defn- parse-color [color]
(try
(cond
(or (not color) (= color "none")) nil
@@ -51,8 +46,7 @@
(.error js/console "Error parsing color" e)
nil)))
-
-(defn get-fill-values [shape]
+(defn- get-fill-values [shape]
(let [fill-values (select-keys shape fill/fill-attrs)
color (-> (or (get-in shape [:content :attrs :fill])
(get-in shape [:content :attrs :style :fill]))
@@ -64,7 +58,7 @@
fill-values)]
fill-values))
-(defn get-stroke-values [shape]
+(defn- get-stroke-values [shape]
(let [stroke-values (select-keys shape stroke-attrs)
color (-> (or (get-in shape [:content :attrs :stroke])
(get-in shape [:content :attrs :style :stroke]))
@@ -92,42 +86,75 @@
stroke-values)]
stroke-values))
-(mf/defc options
+(mf/defc options*
{::mf/wrap [mf/memo]}
[{:keys [shape] :as props}]
- (let [ids [(:id shape)]
- type (:type shape)
+ (let [id (dm/get-prop shape :id)
+ type (dm/get-prop shape :type)
+ ids (mf/with-memo [id] [id])
+ shapes (mf/with-memo [shape] [shape])
- {:keys [tag] :as content} (:content shape)
- measure-values (select-keys shape measure-attrs)
- constraint-values (select-keys shape constraint-attrs)
- fill-values (get-fill-values shape)
- stroke-values (get-stroke-values shape)
- layout-item-values (select-keys shape layout-item-attrs)
- layout-container-values (select-keys shape layout-container-flex-attrs)
+ {:keys [tag] :as content}
+ (get shape :content)
- is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child-ref)
+ fill-values
+ (mf/with-memo [shape]
+ (get-fill-values shape))
- is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent-ref)
+ stroke-values
+ (mf/with-memo [shape]
+ (get-stroke-values shape))
- is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent-ref)
+ measure-values
+ (select-keys shape measure-attrs)
- is-layout-child-absolute? (ctl/item-absolute? shape)
+ constraint-values
+ (select-keys shape constraint-attrs)
- ids (hooks/use-equal-memo ids)
- parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- parents (mf/deref parents-by-ids-ref)]
+ layout-item-values
+ (select-keys shape layout-item-attrs)
+
+ layout-container-values
+ (select-keys shape layout-container-flex-attrs)
+
+ is-layout-child-ref
+ (mf/with-memo [ids]
+ (refs/is-layout-child? ids))
+
+ is-layout-child?
+ (mf/deref is-layout-child-ref)
+
+ is-flex-parent-ref
+ (mf/with-memo [ids]
+ (refs/flex-layout-child? ids))
+
+ is-flex-parent?
+ (mf/deref is-flex-parent-ref)
+
+ is-grid-parent-ref
+ (mf/with-memo [ids]
+ (refs/grid-layout-child? ids))
+
+ is-grid-parent?
+ (mf/deref is-grid-parent-ref)
+
+ is-layout-child-absolute?
+ (ctl/item-absolute? shape)
+
+ parents-by-ids-ref
+ (mf/with-memo [ids]
+ (refs/parents-by-ids ids))
+
+ parents
+ (mf/deref parents-by-ids-ref)]
(when (contains? svg-elements tag)
[:*
[:> measures-menu* {:ids ids
:type type
:values measure-values
- :shape shape}]
+ :shapes shapes}]
[:& layout-container-menu
{:type type
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs
index 4cc88c624b..8e344ad41d 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs
@@ -6,14 +6,13 @@
(ns app.main.ui.workspace.sidebar.options.shapes.text
(:require
- [app.common.data :as d]
+ [app.common.data.macros :as dm]
[app.common.types.shape.layout :as ctl]
[app.common.types.text :as txt]
[app.main.data.workspace.texts :as dwt]
[app.main.features :as features]
[app.main.refs :as refs]
[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.constraints :refer [constraint-attrs constraints-menu]]
@@ -28,68 +27,102 @@
[app.main.ui.workspace.sidebar.options.menus.text :refer [text-menu]]
[rumext.v2 :as mf]))
-(mf/defc options
+(mf/defc options*
[{:keys [shape file-id libraries] :as props}]
- (let [ids [(:id shape)]
- type (:type shape)
+ (let [id (dm/get-prop shape :id)
+ type (dm/get-prop shape :type)
+ ids (mf/with-memo [id] [id])
+ shapes (mf/with-memo [shape] [shape])
- is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
- is-layout-child? (mf/deref is-layout-child-ref)
+ measure-values
+ (select-keys shape measure-attrs)
- is-flex-parent-ref (mf/use-memo (mf/deps ids) #(refs/flex-layout-child? ids))
- is-flex-parent? (mf/deref is-flex-parent-ref)
+ stroke-values
+ (select-keys shape stroke-attrs)
- is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
- is-grid-parent? (mf/deref is-grid-parent-ref)
+ layer-values
+ (select-keys shape layer-attrs)
- layout-container-values (select-keys shape layout-container-flex-attrs)
- is-layout-child-absolute? (ctl/item-absolute? shape)
+ layout-item-values
+ (select-keys shape layout-item-attrs)
- ids (hooks/use-equal-memo ids)
- parents-by-ids-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
- parents (mf/deref parents-by-ids-ref)
+ layout-container-values
+ (select-keys shape layout-container-flex-attrs)
- state-map (if (features/active-feature? @st/state "text-editor/v2")
- (mf/deref refs/workspace-v2-editor-state)
- (mf/deref refs/workspace-editor-state))
+ is-layout-child-ref
+ (mf/with-memo [ids]
+ (refs/is-layout-child? ids))
- editor-state (when (not (features/active-feature? @st/state "text-editor/v2"))
- (get state-map (:id shape)))
+ is-layout-child?
+ (mf/deref is-layout-child-ref)
- layer-values (select-keys shape layer-attrs)
- editor-instance (when (features/active-feature? @st/state "text-editor/v2")
- (mf/deref refs/workspace-editor))
+ is-flex-parent-ref
+ (mf/with-memo [ids]
+ (refs/flex-layout-child? ids))
- fill-values (dwt/current-text-values
- {:editor-state editor-state
- :editor-instance editor-instance
- :shape shape
- :attrs (conj txt/text-fill-attrs :fills)})
+ is-flex-parent?
+ (mf/deref is-flex-parent-ref)
- fill-values (if (not (contains? fill-values :fills))
- ;; Old fill format
- {:fills [fill-values]}
- fill-values)
+ is-grid-parent-ref
+ (mf/with-memo [ids]
+ (refs/grid-layout-child? ids))
- stroke-values (select-keys shape stroke-attrs)
+ is-grid-parent?
+ (mf/deref is-grid-parent-ref)
- text-values (d/merge
- (select-keys shape [:grow-type])
- (select-keys shape fill/fill-attrs)
- (dwt/current-root-values
- {:shape shape
- :attrs txt/root-attrs})
- (dwt/current-paragraph-values
- {:editor-state editor-state
- :editor-instance editor-instance
- :shape shape
- :attrs txt/paragraph-attrs})
- (dwt/current-text-values
- {:editor-state editor-state
- :editor-instance editor-instance
- :shape shape
- :attrs txt/text-node-attrs}))
- layout-item-values (select-keys shape layout-item-attrs)]
+ is-layout-child-absolute?
+ (ctl/item-absolute? shape)
+
+ parents-by-ids-ref
+ (mf/with-memo [ids]
+ (refs/parents-by-ids ids))
+
+ parents
+ (mf/deref parents-by-ids-ref)
+
+ state-map
+ (if (features/active-feature? @st/state "text-editor/v2")
+ (mf/deref refs/workspace-v2-editor-state)
+ (mf/deref refs/workspace-editor-state))
+
+ editor-state
+ (when (not (features/active-feature? @st/state "text-editor/v2"))
+ (get state-map id))
+
+ editor-instance
+ (when (features/active-feature? @st/state "text-editor/v2")
+ (mf/deref refs/workspace-editor))
+
+ fill-values
+ (dwt/current-text-values
+ {:editor-state editor-state
+ :editor-instance editor-instance
+ :shape shape
+ :attrs (conj txt/text-fill-attrs :fills)})
+
+ fill-values
+ (if (not (contains? fill-values :fills))
+ ;; Old fill format
+ {:fills [fill-values]}
+ fill-values)
+
+ text-values
+ (merge
+ (select-keys shape [:grow-type])
+ (select-keys shape fill/fill-attrs)
+ (dwt/current-root-values
+ {:shape shape
+ :attrs txt/root-attrs})
+ (dwt/current-paragraph-values
+ {:editor-state editor-state
+ :editor-instance editor-instance
+ :shape shape
+ :attrs txt/paragraph-attrs})
+ (dwt/current-text-values
+ {:editor-state editor-state
+ :editor-instance editor-instance
+ :shape shape
+ :attrs txt/text-node-attrs}))]
[:*
[:& layer-menu {:ids ids
@@ -98,12 +131,12 @@
[:> measures-menu*
{:ids ids
:type type
- :values (select-keys shape measure-attrs)
- :shape shape}]
+ :values measure-values
+ :shapes shapes}]
[:& layout-container-menu
{:type type
- :ids [(:id shape)]
+ :ids ids
:values layout-container-values
:multiple false}]
@@ -145,7 +178,7 @@
(when (= :multiple (:fills fill-values))
[:> color-selection-menu*
{:type type
- :shapes [shape]
+ :shapes shapes
:file-id file-id
:libraries libraries}])
diff --git a/frontend/src/app/main/ui/workspace/tokens/management.cljs b/frontend/src/app/main/ui/workspace/tokens/management.cljs
index 19d606c955..2ec2464359 100644
--- a/frontend/src/app/main/ui/workspace/tokens/management.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/management.cljs
@@ -53,7 +53,7 @@
(mf/defc tokens-section*
{::mf/private true}
- [{:keys [tokens-lib]}]
+ [{:keys [tokens-lib active-tokens resolved-active-tokens]}]
(let [objects (mf/deref refs/workspace-page-objects)
selected (mf/deref refs/selected-shapes)
open-status (mf/deref ref:token-type-open-status)
@@ -66,18 +66,9 @@
(mf/with-memo [selected-shapes objects]
(some #(ctsl/any-layout-immediate-child? objects %) selected-shapes))
- active-theme-tokens
- (mf/with-memo [tokens-lib]
- (if tokens-lib
- (ctob/get-tokens-in-active-sets tokens-lib)
- {}))
-
- ;; Resolve tokens as second step
- active-theme-tokens'
- (sd/use-resolved-tokens* active-theme-tokens)
-
;; This only checks for the currently explicitly selected set
;; name, it is ephimeral and can be nil
+ ;; FIXME: this is a repeated deref for the same `:workspace-tokens` state
selected-token-set-name
(mf/deref refs/selected-token-set-name)
@@ -92,8 +83,8 @@
(ctob/get-tokens-map selected-token-set))
tokens
- (mf/with-memo [active-theme-tokens selected-token-set-tokens]
- (merge active-theme-tokens selected-token-set-tokens))
+ (mf/with-memo [active-tokens selected-token-set-tokens]
+ (merge active-tokens selected-token-set-tokens))
tokens
(sd/use-resolved-tokens* tokens)
@@ -154,7 +145,7 @@
:type type
:selected-shapes selected-shapes
:is-selected-inside-layout is-selected-inside-layout
- :active-theme-tokens active-theme-tokens'
+ :active-theme-tokens resolved-active-tokens
:tokens tokens}]))
(for [type empty-group]
@@ -162,5 +153,5 @@
:type type
:selected-shapes selected-shapes
:is-selected-inside-layout :is-selected-inside-layout
- :active-theme-tokens active-theme-tokens'
+ :active-theme-tokens resolved-active-tokens
:tokens []}])]))
diff --git a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs
index ac31db6008..e00b09286f 100644
--- a/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/sidebar.cljs
@@ -144,16 +144,12 @@
:on-click open-settings-modal}])]))
(mf/defc tokens-sidebar-tab*
- {::mf/wrap [mf/memo]}
- []
+ [{:keys [tokens-lib] :as props}]
(let [{on-pointer-down-pages :on-pointer-down
on-lost-pointer-capture-pages :on-lost-pointer-capture
on-pointer-move-pages :on-pointer-move
size-pages-opened :size}
- (use-resize-hook :tokens 200 38 "0.6" :y false nil)
-
- tokens-lib
- (mf/deref refs/tokens-lib)]
+ (use-resize-hook :tokens 200 38 "0.6" :y false nil)]
[:div {:class (stl/css :sidebar-wrapper)}
[:> token-management-section*
@@ -166,5 +162,5 @@
:on-lost-pointer-capture on-lost-pointer-capture-pages
:on-pointer-move on-pointer-move-pages}
[:div {:class (stl/css :resize-handle-horiz)}]]
- [:> tokens-section* {:tokens-lib tokens-lib}]]
+ [:> tokens-section* props]]
[:> import-export-button*]]))