mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
🐛 Take the first equally near variant on a switch
A switch picks the variant whose properties are nearest the wanted ones; between equally near ones it took the last child of the variant container. Since combine as variants keeps the order of the components it combines, that is the last of them: switching an empty variant to "primary" gave primary/icon+test where the QA case (PENPOT-2446) expects primary/hover, the first primary variant. It now takes the first child among the equally near ones. variants-switch-target-test: two variants one value away, in both orders of the container's children. Benchmark against the 1e baseline (lower quantile, ms): world baseline now ratio deepest-edit-through-three-levels 35.215 16.810 0.48 edit-through-a-chain-of-dependents 68.931 32.765 0.48 library-update-into-copies 83.083 39.232 0.47 main-edit-among-many-shapes 4.837 2.277 0.47 main-edit-into-10-copies 1.790 0.807 0.45 main-edit-into-100-copies 15.415 8.054 0.52 main-edit-into-1000-copies 153.086 81.186 0.53 variant-switch-into-copies 32.052 17.933 0.56 AI-assisted-by: claude-opus-5-5
This commit is contained in:
parent
86e622ed44
commit
37e233f6e1
@ -435,8 +435,9 @@
|
||||
"The variant component that the variant copy head `shape` switches to when
|
||||
its property at position `pos` takes the value `val`: among the other
|
||||
variants with that value, the one whose properties are nearest to the
|
||||
current ones. Nil when the property already has that value or no variant
|
||||
has it."
|
||||
current ones; between equally near ones, the first among the children of
|
||||
the variant container. Nil when the property already has that value or no
|
||||
variant has it."
|
||||
[libraries shape pos val]
|
||||
(let [component-id (:component-id shape)
|
||||
component (ctf/get-component libraries (:component-file shape) component-id
|
||||
@ -446,12 +447,16 @@
|
||||
objects (-> (ctf/get-component-page ldata component) :objects)
|
||||
target-props (-> (:variant-properties component)
|
||||
(update pos assoc :value val))
|
||||
distance #(ctv/distance target-props (:variant-properties %))
|
||||
;; in the order of the container's children
|
||||
candidates (->> (cfv/find-variant-components ldata objects (:variant-id component))
|
||||
(remove #(= (:id %) component-id))
|
||||
(filter #(= (get-in % [:variant-properties pos :value]) val))
|
||||
(reverse))]
|
||||
(when (seq candidates)
|
||||
(apply min-key #(ctv/distance target-props (:variant-properties %)) candidates))))))
|
||||
(reduce (fn [nearest candidate]
|
||||
(if (< (distance candidate) (distance nearest)) candidate nearest))
|
||||
(first candidates)
|
||||
(rest candidates))))))
|
||||
|
||||
(defn valid-switch?
|
||||
"Whether the variant copy head `shape` can switch its property at position
|
||||
|
||||
@ -66,6 +66,25 @@
|
||||
target (clv/find-switch-target (libraries file) (ths/get-shape file :copy01) 0 "p1v2")]
|
||||
(t/is (= (thi/id :c03) (:id target)))))
|
||||
|
||||
(t/deftest switch-target-between-equally-near-variants-is-the-first-of-the-container
|
||||
;; From p1v1, p2v1, setting Property 1 to p1v2 can give c02 (p1v2, p2v2) or
|
||||
;; c03 (p1v2, p2v3), both one value away; the one placed first among the
|
||||
;; container's children wins.
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(thv/add-variant-two-properties :v01 :c01 :m01 :c02 :m02)
|
||||
(ths/add-sample-shape :m03 :type :frame :parent-label :v01
|
||||
:variant-id (thi/id :v01) :variant-name "p1v2, p2v3")
|
||||
(thc/make-component :c03 :m03)
|
||||
(thc/update-component :c03 {:variant-id (thi/id :v01)
|
||||
:variant-properties [{:name "Property 1" :value "p1v2"}
|
||||
{:name "Property 2" :value "p2v3"}]})
|
||||
(thc/instantiate-component :c01 :copy01))
|
||||
target (fn [order]
|
||||
(let [file (ths/update-shape file :v01 :shapes (mapv thi/id order))]
|
||||
(:id (clv/find-switch-target (libraries file) (ths/get-shape file :copy01) 0 "p1v2"))))]
|
||||
(t/is (= (thi/id :c02) (target [:m01 :m02 :m03])))
|
||||
(t/is (= (thi/id :c03) (target [:m01 :m03 :m02])))))
|
||||
|
||||
(t/deftest switch-into-own-main-is-a-nesting-loop
|
||||
(let [file (-> (thf/sample-file :file1)
|
||||
(thv/add-variant :v01 :c01 :m01 :c02 :m02)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user