From f01b260f740bbdb3b4e14f874f6692f1f178868d Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 23 Oct 2026 20:01:22 +0200 Subject: [PATCH] :bug: Keep inherited root orientation through a variant switch Use the root's effective touched groups after the reference-chain merge when preserving its orientation. A near main may author the rotation while the selected copy remains untouched. Checking only the selected shape drops that inherited override during the switch. The portable regression fails before the fix and passes four assertions afterwards. Focused swap and generated checks pass 42 tests and 165 assertions. Benchmark vs Phase 1e: main 10/100/1000 0.56/0.58/0.67; levels 0.61; chain 0.57; library 0.53; many shapes 0.69; switch 0.70. No flags. AI-assisted-by: GPT-6 --- common/src/app/common/logic/variants.cljc | 3 ++- .../common_tests/logic/swap_group_test.cljc | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/common/src/app/common/logic/variants.cljc b/common/src/app/common/logic/variants.cljc index 16f077e0ac..7cc039984a 100644 --- a/common/src/app/common/logic/variants.cljc +++ b/common/src/app/common/logic/variants.cljc @@ -422,7 +422,8 @@ changes pairs) changes (cond-> changes - (ctk/touched-group? original-shape :geometry-group) + (some #(and (= (:id %) (:id original-shape)) + (ctk/touched-group? % :geometry-group)) orig-touched) (keep-orientation-override original-shape new-shape page (or (get-in libraries [(:component-file new-shape) :data]) ldata) (:component-id new-shape)))] diff --git a/common/test/common_tests/logic/swap_group_test.cljc b/common/test/common_tests/logic/swap_group_test.cljc index 9e50d71178..bae1db42a3 100644 --- a/common/test/common_tests/logic/swap_group_test.cljc +++ b/common/test/common_tests/logic/swap_group_test.cljc @@ -749,3 +749,23 @@ (t/is (ctk/touched-group? head :geometry-group)) (t/is (mth/close? 45 (:rotation head) 0.001)) (t/is (= (orientation file :card-star) (orientation full :card-star))))) + +(t/deftest switch-keeps-root-orientation-authored-in-a-near-main + (let [initial (reduce #(tm/apply-to %2 %1) (setups/empty-situation) + [(n/create-component "variant" setups/labeled-fill :size 100) + (n/make-variant-container "variants" + [["a" setups/labeled-fill] + ["b" setups/labeled-fill]] :size 100) + (n/make-nested-component-with-variant "variant" "variants" "a") + (n/make-nested-component "variant" 1)]) + source (n/nested-head-of "variant" 0) + target (n/nested-head-of "variant" 1) + before (-> initial (r/step (n/rotate source 45)) r/settle) + swapped (-> before (r/step (n/switch-variant target "b")) r/settle) + head (tm/shape-by-id swapped (target swapped)) + file (tm/file swapped) + full (:file (r/sync-cascade file {} (keys (get-in file [:data :components]))))] + (t/is (nil? (:touched (tm/shape-by-id before (target before))))) + (t/is (ctk/touched-group? head :geometry-group)) + (t/is (mth/close? 45 (:rotation head) 0.001)) + (t/is (gsh/close-attrs? :points (:points head) (:points (ths/get-shape-by-id full (:id head))) 0.001))))