Add efficiency improvements to workspace components (refactor part 1) (#8887)

* ♻️ Convert snap-points components to modern rumext format

Migrate snap-point, snap-line, snap-feedback, and snap-points from
legacy mf/defc format to modern * suffix format. This enables
optimized props handling by the rumext macro, eliminating implicit
JS object wrapping overhead on each render. All internal and
external call sites updated to use [:> component* props] syntax.

* ♻️ Convert frame-title to modern rumext format

Migrate frame-title from legacy mf/defc format to modern * suffix
format. The component was using legacy implicit props wrapping without
::mf/wrap-props false or ::mf/props :obj, causing unnecessary JS
object conversion overhead on each render. The parent frame-titles*
call site updated to use [:> frame-title* props] syntax.

* ♻️ Convert interactions components to modern rumext format

Migrate interaction-marker, interaction-path, interaction-handle,
overlay-marker, and interactions from legacy mf/defc format to modern
* suffix format. These five components had zero props optimization
applied, causing implicit JS object wrapping on every render. All
internal and external call sites updated to use [:> component* props]
syntax.

* ♻️ Convert rulers components to modern rumext format

Migrate rulers-text, viewport-frame, and selection-area from legacy
mf/defc format to modern * suffix format. These three components in
the always-visible rulers layer had zero props optimization applied.
Internal call sites in the parent rulers component updated to use
[:> component* props] syntax.

* ♻️ Convert frame-grid components to modern rumext format

Migrate square-grid, layout-grid, grid-display-frame, and frame-grid
from legacy mf/defc format to modern * suffix format. These four
components render grid patterns per-frame with zero props optimization.
All internal and external call sites updated to use [:> component* props]
syntax.

* ♻️ Convert gradient handler components to modern rumext format

Migrate shadow, gradient-color-handler, and gradient-handler-transformed
from legacy mf/defc format to modern * suffix format. These components
are rendered during gradient editing with zero props optimization applied.
Internal call sites in gradient-handler-transformed and
gradient-handlers-impl updated to use [:> component* props] syntax.

* ♻️ Rename ?-ending props in modernized workspace viewport components

Apply prop naming rules to all * components migrated in the previous batch:
- remove-snap? -> remove-snap in snap-feedback* (and get-snap helper)
- selected? -> is-selected in interaction-path*
- hover-disabled? -> is-hover-disabled in overlay-marker* and interactions*
- show-rulers? -> show-rulers in viewport-frame*

Update all internal and external call sites consistently.

* 🐛 Fix get-snap call in snap-feedback* using JS props object

Modern rumext *-suffix components receive props as JS objects, not
Clojure maps. snap-feedback* was pushing the raw props object into the
rx/subject and get-snap was destructuring it as a Clojure map, causing
all keys to resolve to nil.

Fix by:
- Changing get-snap to take positional arguments (coord, shapes,
  page-id, remove-snap, zoom) instead of a map-destructured opts arg
- Building an explicit Clojure map from the bound locals before pushing
  to the subject
- Destructuring that map inside the rx/switch-map callback and calling
  get-snap with positional args

Also mark get-snap and add-point-to-snaps as private (defn-), consistent
with the other helpers in the namespace — none are referenced externally.
This commit is contained in:
Andrey Antukh 2026-04-14 19:48:59 +02:00 committed by GitHub
parent 3264bc746f
commit f07b954b7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 163 additions and 160 deletions

View File

@ -577,7 +577,7 @@
:tool drawing-tool}])
(when show-grids?
[:& frame-grid/frame-grid
[:> frame-grid/frame-grid*
{:zoom zoom
:selected selected
:transform transform
@ -588,7 +588,7 @@
:zoom zoom}])
(when show-snap-points?
[:& snap-points/snap-points
[:> snap-points/snap-points*
{:layout layout
:transform transform
:drawing drawing-obj
@ -689,13 +689,13 @@
:disabled (or drawing-tool @space?)}])))
(when show-prototypes?
[:& interactions/interactions
[:> interactions/interactions*
{:selected selected
:page-id page-id
:zoom zoom
:objects objects-modified
:current-transform transform
:hover-disabled? hover-disabled?}])])
:is-hover-disabled hover-disabled?}])])
(when show-gradient-handlers?
[:> gradients/gradient-handlers*

View File

@ -17,7 +17,7 @@
[app.main.refs :as refs]
[rumext.v2 :as mf]))
(mf/defc square-grid [{:keys [frame zoom grid] :as props}]
(mf/defc square-grid* [{:keys [frame zoom grid]}]
(let [grid-id (mf/use-memo #(uuid/next))
{:keys [size] :as params} (-> grid :params)
{color-value :color color-opacity :opacity} (-> grid :params :color)
@ -45,7 +45,7 @@
:height (:height frame)
:fill (str "url(#" grid-id ")")}]]))
(mf/defc layout-grid
(mf/defc layout-grid*
[{:keys [key frame grid zoom]}]
(let [{color-value :color color-opacity :opacity} (-> grid :params :color)
;; Support for old color format
@ -124,7 +124,7 @@
selrect
parents))
(mf/defc grid-display-frame
(mf/defc grid-display-frame*
{::mf/wrap [mf/memo]}
[{:keys [frame zoom transforming]}]
(let [frame-id (:id frame)
@ -154,16 +154,16 @@
:zoom zoom
:grid grid}]
(case (:type grid)
:square [:> square-grid props]
:column [:> layout-grid props]
:row [:> layout-grid props])))])))
:square [:> square-grid* props]
:column [:> layout-grid* props]
:row [:> layout-grid* props])))])))
(defn has-grid?
[{:keys [grids]}]
(and (some? grids)
(d/not-empty? (->> grids (filter :display)))))
(mf/defc frame-grid
(mf/defc frame-grid*
{::mf/wrap [mf/memo]}
[{:keys [zoom transform selected focus]}]
(let [frames (->> (mf/deref refs/workspace-frames)
@ -175,7 +175,7 @@
(when (and #_(not (is-transform? frame))
(not (ctst/rotated-frame? frame))
(or (empty? focus) (contains? focus (:id frame))))
[:& grid-display-frame {:key (str "grid-" (:id frame))
:zoom zoom
:frame frame
:transforming transforming}]))]))
[:> grid-display-frame* {:key (str "grid-" (:id frame))
:zoom zoom
:frame frame
:transforming transforming}]))]))

View File

@ -43,7 +43,7 @@
(def gradient-endpoint-radius-selected 6)
(def gradient-endpoint-radius-handler 20)
(mf/defc shadow [{:keys [id offset]}]
(mf/defc shadow* [{:keys [id offset]}]
[:filter {:id id
:x "-10%"
:y "-10%"
@ -61,7 +61,7 @@
(def checkerboard "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAIAAAC0tAIdAAACvUlEQVQoFQGyAk39AeLi4gAAAAAAAB0dHQAAAAAAAOPj4wAAAAAAAB0dHQAAAAAAAOPj4wAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB////AAAAAAAA4+PjAAAAAAAAHR0dAAAAAAAA4+PjAAAAAAAAHR0dAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATj4+MAAAAAAAAdHR0AAAAAAADj4+MAAAAAAAAdHR0AAAAAAADj4+MAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjScaa0cU7nIAAAAASUVORK5CYII=")
(mf/defc gradient-color-handler
(mf/defc gradient-color-handler*
[{:keys [zoom point color angle selected index
on-click on-pointer-down on-pointer-up on-pointer-move on-lost-pointer-capture]}]
[:g {:filter "url(#gradient-drop-shadow)"
@ -118,7 +118,7 @@
:r (/ 2 zoom)
:fill "var(--app-white)"}]])
(mf/defc gradient-handler-transformed
(mf/defc gradient-handler-transformed*
[{:keys [from-p
to-p
width-p
@ -270,7 +270,7 @@
[:g.gradient-handlers {:pointer-events "none"}
[:defs
[:& shadow {:id "gradient-drop-shadow" :offset (/ 2 zoom)}]]
[:> shadow* {:id "gradient-drop-shadow" :offset (/ 2 zoom)}]]
(let [lv (-> (gpt/to-vec from-p to-p)
(gpt/unit))
@ -425,7 +425,7 @@
(-> (gpt/to-vec from-p to-p)
(gpt/scale (:offset stop))))]
[:& gradient-color-handler
[:> gradient-color-handler*
{:key index
:selected (= editing index)
:zoom zoom
@ -505,7 +505,7 @@
(when (and norm-dist (d/num? norm-dist))
(change! {:width norm-dist})))))]
[:& gradient-handler-transformed
[:> gradient-handler-transformed*
{:editing editing
:from-p from-p
:to-p to-p

View File

@ -96,8 +96,8 @@
[orig-pos orig-x orig-y dest-pos dest-x dest-y]))
(mf/defc interaction-marker
[{:keys [x y stroke action-type arrow-dir zoom] :as props}]
(mf/defc interaction-marker*
[{:keys [x y stroke action-type arrow-dir zoom]}]
(let [icon-pdata (case action-type
:navigate (case arrow-dir
:right "M -6.5 0 L 5.5 0 M 6.715 0.715 L -0.5 -6.5 M 6.715 -0.715 L -0.365 6.635"
@ -138,8 +138,8 @@
"translate(" (* zoom x) ", " (* zoom y) ")")}])]))
(mf/defc interaction-path
[{:keys [index level orig-shape dest-shape dest-point selected? action-type zoom] :as props}]
(mf/defc interaction-path*
[{:keys [index level orig-shape dest-shape dest-point is-selected action-type zoom]}]
(let [[orig-pos orig-x orig-y dest-pos dest-x dest-y]
(cond
dest-shape
@ -162,7 +162,7 @@
arrow-dir (if (= dest-pos :left) :right :left)]
(if-not selected?
(if-not is-selected
[:g {:on-pointer-down #(on-pointer-down % index orig-shape)}
[:path {:stroke "var(--df-secondary)"
:fill "none"
@ -170,13 +170,13 @@
:stroke-width (/ 2 zoom)
:d pdata}]
(when (not dest-shape)
[:& interaction-marker {:index index
:x dest-x
:y dest-y
:stroke "var(--df-secondary)"
:action-type action-type
:arrow-dir arrow-dir
:zoom zoom}])]
[:> interaction-marker* {:index index
:x dest-x
:y dest-y
:stroke "var(--df-secondary)"
:action-type action-type
:arrow-dir arrow-dir
:zoom zoom}])]
[:g {:on-pointer-down #(on-pointer-down % index orig-shape)}
[:path {:stroke "var(--color-accent-tertiary)"
@ -190,36 +190,36 @@
:shape dest-shape
:color "var(--color-accent-tertiary)"}])
[:& interaction-marker {:index index
:x orig-x
:y orig-y
:stroke "var(--color-accent-tertiary)"
:zoom zoom}]
[:& interaction-marker {:index index
:x dest-x
:y dest-y
:stroke "var(--color-accent-tertiary)"
:action-type action-type
:arrow-dir arrow-dir
:zoom zoom}]])))
[:> interaction-marker* {:index index
:x orig-x
:y orig-y
:stroke "var(--color-accent-tertiary)"
:zoom zoom}]
[:> interaction-marker* {:index index
:x dest-x
:y dest-y
:stroke "var(--color-accent-tertiary)"
:action-type action-type
:arrow-dir arrow-dir
:zoom zoom}]])))
(mf/defc interaction-handle
[{:keys [index shape zoom] :as props}]
(mf/defc interaction-handle*
[{:keys [index shape zoom]}]
(let [shape-rect (:selrect shape)
handle-x (+ (:x shape-rect) (:width shape-rect))
handle-y (+ (:y shape-rect) (/ (:height shape-rect) 2))]
[:g {:on-pointer-down #(on-pointer-down % index shape)}
[:& interaction-marker {:x handle-x
:y handle-y
:stroke "var(--color-accent-tertiary)"
:action-type :navigate
:arrow-dir :right
:zoom zoom}]]))
[:> interaction-marker* {:x handle-x
:y handle-y
:stroke "var(--color-accent-tertiary)"
:action-type :navigate
:arrow-dir :right
:zoom zoom}]]))
(mf/defc overlay-marker
[{:keys [page-id index orig-shape dest-shape position objects hover-disabled?] :as props}]
(mf/defc overlay-marker*
[{:keys [page-id index orig-shape dest-shape position objects is-hover-disabled]}]
(let [start-move-position
(fn [_]
(st/emit! (dw/start-move-overlay-pos index)))]
@ -250,8 +250,8 @@
(some? thumbnail-data)
(assoc :thumbnail thumbnail-data))]
[:g {:on-pointer-down start-move-position
:on-pointer-enter #(reset! hover-disabled? true)
:on-pointer-leave #(reset! hover-disabled? false)}
:on-pointer-enter #(reset! is-hover-disabled true)
:on-pointer-leave #(reset! is-hover-disabled false)}
[:g {:transform (gmt/translate-matrix (gpt/point (- marker-x dest-x) (- marker-y dest-y)))}
[:& (mf/provider muc/render-thumbnails) {:value true}
[:& (mf/provider embed/context) {:value false}
@ -273,8 +273,8 @@
:r 8
:fill "var(--color-accent-tertiary)"}]]))))
(mf/defc interactions
[{:keys [current-transform objects zoom selected hover-disabled? page-id] :as props}]
(mf/defc interactions*
[{:keys [current-transform objects zoom selected is-hover-disabled page-id]}]
(let [active-shapes (into []
(comp (filter #(seq (:interactions %))))
(vals objects))
@ -305,26 +305,26 @@
selected? (contains? selected (:id shape))
level (calc-level index (:interactions shape))]
(when-not selected?
[:& interaction-path {:key (dm/str "non-selected-" (:id shape) "-" index)
:index index
:level level
:orig-shape shape
:dest-shape dest-shape
:selected selected
:selected? false
:action-type (:action-type interaction)
:zoom zoom}]))))]
[:> interaction-path* {:key (dm/str "non-selected-" (:id shape) "-" index)
:index index
:level level
:orig-shape shape
:dest-shape dest-shape
:selected selected
:is-selected false
:action-type (:action-type interaction)
:zoom zoom}]))))]
[:g.selected
(when (and draw-interaction-to first-selected)
[:& interaction-path {:key "interactive"
:index nil
:orig-shape first-selected
:dest-point draw-interaction-to
:dest-shape draw-interaction-to-frame
:selected? true
:action-type :navigate
:zoom zoom}])
[:> interaction-path* {:key "interactive"
:index nil
:orig-shape first-selected
:dest-point draw-interaction-to
:dest-shape draw-interaction-to-frame
:is-selected true
:action-type :navigate
:zoom zoom}])
(for [shape selected-shapes]
(if (seq (:interactions shape))
(for [[index interaction] (d/enumerate (:interactions shape))]
@ -333,38 +333,38 @@
(get objects (:destination interaction)))
level (calc-level index (:interactions shape))]
[:g {:key (dm/str "interaction-path-" (:id shape) "-" index)}
[:& interaction-path {:index index
:level level
:orig-shape shape
:dest-shape dest-shape
:selected selected
:selected? true
:action-type (:action-type interaction)
:zoom zoom}]
[:> interaction-path* {:index index
:level level
:orig-shape shape
:dest-shape dest-shape
:selected selected
:is-selected true
:action-type (:action-type interaction)
:zoom zoom}]
(when (and (or (= (:action-type interaction) :open-overlay)
(= (:action-type interaction) :toggle-overlay))
(= (:overlay-pos-type interaction) :manual))
(if (and (some? move-overlay-to)
(= move-overlay-index index))
[:& overlay-marker {:page-id page-id
:index index
:orig-shape shape
:dest-shape dest-shape
:position move-overlay-to
:objects objects
:hover-disabled? hover-disabled?}]
[:& overlay-marker {:page-id page-id
:index index
:orig-shape shape
:dest-shape dest-shape
:position (:overlay-position interaction)
:objects objects
:hover-disabled? hover-disabled?}]))])))
[:> overlay-marker* {:page-id page-id
:index index
:orig-shape shape
:dest-shape dest-shape
:position move-overlay-to
:objects objects
:is-hover-disabled is-hover-disabled}]
[:> overlay-marker* {:page-id page-id
:index index
:orig-shape shape
:dest-shape dest-shape
:position (:overlay-position interaction)
:objects objects
:is-hover-disabled is-hover-disabled}]))])))
(when (and shape
(not (cfh/unframed-shape? shape))
(not (#{:move :rotate} current-transform)))
[:& interaction-handle {:key (:id shape)
:index nil
:shape shape
:selected selected
:zoom zoom}])))]]))
[:> interaction-handle* {:key (:id shape)
:index nil
:shape shape
:selected selected
:zoom zoom}])))]]))

View File

@ -142,7 +142,7 @@
"Z"))
(mf/defc rulers-text
(mf/defc rulers-text*
"Draws the text for the rulers in a specific axis"
[{:keys [vbox step offset axis zoom-inverse]}]
(let [clip-id (str "clip-ruler-" (d/name axis))
@ -186,13 +186,13 @@
:style {:stroke font-color
:stroke-width rulers-width}}]]))]))
(mf/defc viewport-frame
[{:keys [show-rulers? zoom zoom-inverse vbox offset-x offset-y]}]
(mf/defc viewport-frame*
[{:keys [show-rulers zoom zoom-inverse vbox offset-x offset-y]}]
(let [{:keys [width height] x1 :x y1 :y} vbox
x2 (+ x1 width)
y2 (+ y1 height)
bw (if show-rulers? (* ruler-area-size zoom-inverse) 0)
bw (if show-rulers (* ruler-area-size zoom-inverse) 0)
br (/ canvas-border-radius zoom)
bs (* 4 zoom-inverse)]
[:*
@ -214,13 +214,13 @@
:fill-rule "evenodd"
:fill rulers-background}]]
(when show-rulers?
(when show-rulers
(let [step (calculate-step-size zoom)]
[:g.viewport-frame-rulers
[:& rulers-text {:vbox vbox :offset offset-x :step step :zoom-inverse zoom-inverse :axis :x}]
[:& rulers-text {:vbox vbox :offset offset-y :step step :zoom-inverse zoom-inverse :axis :y}]]))]))
[:> rulers-text* {:vbox vbox :offset offset-x :step step :zoom-inverse zoom-inverse :axis :x}]
[:> rulers-text* {:vbox vbox :offset offset-y :step step :zoom-inverse zoom-inverse :axis :y}]]))]))
(mf/defc selection-area
(mf/defc selection-area*
[{:keys [vbox zoom-inverse selection-rect offset-x offset-y]}]
;; When using the format-number callls we consider if the guide is associated to a frame and we show the position relative to it with the offset
[:g.selection-area
@ -332,8 +332,8 @@
(when (some? vbox)
[:g.viewport-frame {:pointer-events "none"}
[:& viewport-frame
{:show-rulers? show-rulers?
[:> viewport-frame*
{:show-rulers show-rulers?
:zoom zoom
:zoom-inverse zoom-inverse
:vbox vbox
@ -341,7 +341,7 @@
:offset-y offset-y}]
(when (and show-rulers? (some? selection-rect))
[:& selection-area
[:> selection-area*
{:zoom zoom
:zoom-inverse zoom-inverse
:vbox vbox

View File

@ -25,7 +25,7 @@
;; (def ^:private line-opacity 1 )
;; (def ^:private line-width 2)
(mf/defc snap-point
(mf/defc snap-point*
[{:keys [point zoom]}]
(let [{:keys [x y]} point
cross-width (/ 3 zoom)]
@ -41,7 +41,7 @@
:y2 (- y cross-width)
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}}]]))
(mf/defc snap-line
(mf/defc snap-line*
[{:keys [snap point zoom]}]
[:line {:x1 (:x snap)
:y1 (:y snap)
@ -50,8 +50,8 @@
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}
:opacity line-opacity}])
(defn get-snap
[coord {:keys [shapes page-id remove-snap? zoom]}]
(defn- get-snap
[coord shapes page-id remove-snap zoom]
(let [bounds (gsh/shapes->rect shapes)
frame-id (snap/snap-frame-id shapes)]
@ -63,7 +63,7 @@
(rx/merge-map
(fn [[frame-id point]]
(->> (snap/get-snap-points page-id frame-id remove-snap? zoom point coord)
(->> (snap/get-snap-points page-id frame-id remove-snap zoom point coord)
(rx/map #(mapcat second %))
(rx/map #(map :pt %))
(rx/map #(vector point % coord)))))
@ -74,7 +74,7 @@
[coord]
(if (= coord :x) :y :x))
(defn add-point-to-snaps
(defn- add-point-to-snaps
[[point snaps coord]]
(let [normalize-coord #(assoc % coord (get point coord))]
(cons point (map normalize-coord snaps))))
@ -100,8 +100,8 @@
(map (fn [[fixedv [minv maxv]]] [(hash-map coord fixedv (flip coord) minv)
(hash-map coord fixedv (flip coord) maxv)]))))
(mf/defc snap-feedback
[{:keys [shapes remove-snap? zoom modifiers] :as props}]
(mf/defc snap-feedback*
[{:keys [shapes remove-snap zoom modifiers page-id]}]
(let [state (mf/use-state [])
subject (mf/use-memo #(rx/subject))
@ -116,9 +116,9 @@
(fn []
(let [sub (->> subject
(rx/switch-map
(fn [props]
(->> (get-snap :y props)
(rx/combine-latest (get-snap :x props)))))
(fn [{:keys [shapes page-id remove-snap zoom]}]
(->> (get-snap :y shapes page-id remove-snap zoom)
(rx/combine-latest (get-snap :x shapes page-id remove-snap zoom)))))
(rx/map
(fn [result]
@ -133,28 +133,31 @@
#(rx/dispose! sub))))
(mf/use-effect
(mf/deps shapes remove-snap? modifiers)
(mf/deps shapes remove-snap modifiers)
(fn []
(rx/push! subject props)))
(rx/push! subject {:shapes shapes
:page-id page-id
:remove-snap remove-snap
:zoom zoom})))
[:g.snap-feedback
(for [[from-point to-point] snap-lines]
[:& snap-line {:key (str "line-" (:x from-point)
"-" (:y from-point)
"-" (:x to-point)
"-" (:y to-point) "-")
:snap from-point
:point to-point
:zoom zoom}])
[:> snap-line* {:key (str "line-" (:x from-point)
"-" (:y from-point)
"-" (:x to-point)
"-" (:y to-point) "-")
:snap from-point
:point to-point
:zoom zoom}])
(for [point snap-points]
[:& snap-point {:key (str "point-" (:x point)
"-" (:y point))
:point point
:zoom zoom}])]))
[:> snap-point* {:key (str "point-" (:x point)
"-" (:y point))
:point point
:zoom zoom}])]))
(mf/defc snap-points
(mf/defc snap-points*
{::mf/wrap [mf/memo]}
[{:keys [layout zoom objects selected page-id drawing focus] :as props}]
[{:keys [layout zoom objects selected page-id drawing focus]}]
(dm/assert! (set? selected))
(let [shapes (into [] (keep (d/getf objects)) selected)
@ -165,7 +168,7 @@
(mf/with-memo [layout filter-shapes objects focus]
(snap/make-remove-snap layout filter-shapes objects focus))
remove-snap?
remove-snap
(mf/use-callback
(mf/deps remove-snap-base?)
(fn [{:keys [type grid] :as snap}]
@ -176,8 +179,8 @@
shapes (if drawing [drawing] shapes)
frame-id (snap/snap-frame-id shapes)]
(when-not (ctl/any-layout? objects frame-id)
[:& snap-feedback {:shapes shapes
:page-id page-id
:remove-snap? remove-snap?
:zoom zoom}])))
[:> snap-feedback* {:shapes shapes
:page-id page-id
:remove-snap remove-snap
:zoom zoom}])))

View File

@ -78,7 +78,7 @@
:stroke-width (/ 1 zoom)}}]))
(mf/defc frame-title
(mf/defc frame-title*
{::mf/wrap [mf/memo
#(mf/deferred % ts/raf)]
::mf/forward-ref true}
@ -261,16 +261,16 @@
(not= id uuid/zero)
(or (dbg/enabled? :shape-titles) (= parent-id uuid/zero))
(or (empty? focus) (contains? focus id)))
[:& frame-title {:key (dm/str "frame-title-" id)
:frame shape
:zoom zoom
:is-selected (contains? selected id)
:is-show-artboard-names is-show-artboard-names
:is-show-id (dbg/enabled? :shape-titles)
:is-grid-edition (and (= id edition) grid-edition?)
:on-frame-enter on-frame-enter
:on-frame-leave on-frame-leave
:on-frame-select on-frame-select}]))]))
[:> frame-title* {:key (dm/str "frame-title-" id)
:frame shape
:zoom zoom
:is-selected (contains? selected id)
:is-show-artboard-names is-show-artboard-names
:is-show-id (dbg/enabled? :shape-titles)
:is-grid-edition (and (= id edition) grid-edition?)
:on-frame-enter on-frame-enter
:on-frame-leave on-frame-leave
:on-frame-select on-frame-select}]))]))
(mf/defc frame-flow*
[{:keys [flow frame is-selected zoom on-frame-enter on-frame-leave on-frame-select]}]

View File

@ -636,7 +636,7 @@
:tool drawing-tool}])
(when show-grids?
[:& frame-grid/frame-grid
[:> frame-grid/frame-grid*
{:zoom zoom
:selected selected
:transform transform
@ -647,7 +647,7 @@
:zoom zoom}])
(when show-snap-points?
[:& snap-points/snap-points
[:> snap-points/snap-points*
{:layout layout
:transform transform
:drawing drawing-obj
@ -749,13 +749,13 @@
:disabled (or drawing-tool @space?)}])))
(when show-prototypes?
[:& interactions/interactions
[:> interactions/interactions*
{:selected selected
:page-id page-id
:zoom zoom
:objects objects-modified
:current-transform transform
:hover-disabled? hover-disabled?}])])
:is-hover-disabled hover-disabled?}])])
(when show-gradient-handlers?
[:> gradients/gradient-handlers*