🐛 Fix variants nesting loops (#7112)

* 🐛 Fix variants nesting loops

*  MR changes
This commit is contained in:
Pablo Alba
2025-08-14 08:08:31 +02:00
committed by GitHub
parent 54bb9ea755
commit 814ec43714
4 changed files with 41 additions and 15 deletions

View File

@@ -436,6 +436,24 @@
parent-components (into #{} xf-get-component-id parents)]
(seq (set/intersection child-components parent-components))))
(defn variants-nesting-loop?
"Check if a variants nesting loop would be created if the given shape is moved below the given parent"
[objects libraries shape-id parent-id]
(let [get-variant-id #(or (:variant-id %)
(when (:is-variant-container %) (:id %))
(when (:component-id %)
(dm/get-in libraries [(:component-file %)
:data
:components
(:component-id %)
:variant-id])))
child-variant-ids (into #{} (keep get-variant-id)
(get-children-with-self objects shape-id))
parent-variant-ids (into #{} (keep get-variant-id)
(get-parents-with-self objects parent-id))]
(seq (set/intersection child-variant-ids parent-variant-ids))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ALGORITHMS & TRANSFORMATIONS FOR SHAPES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@@ -456,7 +456,11 @@
parent-in-component? (in-any-component? objects parent)
comps-nesting-loop? (not (->> children
(map #(cfh/components-nesting-loop? objects (:id %) (:id parent)))
(every? nil?)))]
(every? nil?)))
variants-nesting-loop? (not (->> children
(map #(cfh/variants-nesting-loop? objects libraries (:id %) (:id parent)))
(every? nil?)))]
(or
;;We don't want to change the structure of component copies
(ctk/in-component-copy? parent)
@@ -465,7 +469,8 @@
(and selected-main-instance? parent-in-component?)
;; Avoid placing a shape as a direct or indirect child of itself,
;; or inside its main component if it's in a copy.
comps-nesting-loop?)))
comps-nesting-loop?
variants-nesting-loop?)))
(defn find-valid-parent-and-frame-ids
"Navigate trough the ancestors until find one that is valid. Returns [ parent-id frame-id ]"

View File

@@ -636,16 +636,17 @@
ptk/WatchEvent
(watch [_ state stream]
(let [prev-cell-data (volatile! nil)
page-id (:current-page-id state)
objects (dsh/lookup-page-objects state page-id)
selected (dsh/lookup-selected state {:omit-blocked? true})
ids (if (nil? ids) selected ids)
shapes (into []
(comp (map (d/getf objects))
(remove #(let [parent (get objects (:parent-id %))]
(and (ctk/in-component-copy? parent)
(ctl/any-layout? parent)))))
ids)
page-id (:current-page-id state)
libraries (dsh/lookup-libraries state)
objects (dsh/lookup-page-objects state page-id)
selected (dsh/lookup-selected state {:omit-blocked? true})
ids (if (nil? ids) selected ids)
shapes (into []
(comp (map (d/getf objects))
(remove #(let [parent (get objects (:parent-id %))]
(and (ctk/in-component-copy? parent)
(ctl/any-layout? parent)))))
ids)
duplicate-move-started? (get-in state [:workspace-local :duplicate-move-started?] false)
@@ -696,7 +697,7 @@
(let [position (gpt/add from-position move-vector)
exclude-frames (if mod? exclude-frames exclude-frames-siblings)
target-frame (ctst/top-nested-frame objects position exclude-frames)
[target-frame _] (ctn/find-valid-parent-and-frame-ids target-frame objects shapes)
[target-frame _] (ctn/find-valid-parent-and-frame-ids target-frame objects shapes false libraries)
flex-layout? (ctl/flex-layout? objects target-frame)
grid-layout? (ctl/grid-layout? objects target-frame)
drop-index (when flex-layout? (gslf/get-drop-index target-frame objects position))

View File

@@ -200,6 +200,7 @@
read-only? (mf/use-ctx ctx/workspace-read-only?)
parent-board? (and (cfh/frame-shape? item)
(= uuid/zero (:parent-id item)))
toggle-collapse
(mf/use-fn
(mf/deps expanded?)
@@ -285,7 +286,8 @@
(let [single? (= (count selected) 1)
same? (and single? (= (first selected) id))]
(when-not same?
(let [shape (get objects id)
(let [files (deref refs/files)
shape (get objects id)
parent-id
(cond
@@ -298,7 +300,7 @@
:else
(cfh/get-parent-id objects id))
[parent-id _] (ctn/find-valid-parent-and-frame-ids parent-id objects (map #(get objects %) selected))
[parent-id _] (ctn/find-valid-parent-and-frame-ids parent-id objects (map #(get objects %) selected) false files)
parent (get objects parent-id)