🐛 Fix number token applying rotation when line-height attr is specified (#8557)

* 💄 Removed forgotten print (#8594)

* 🐛 Fix number token applying rotation when line-height attr is specified

toggle-token always used the on-update-shape from token-properties,
which for :number tokens is unconditionally update-rotation. So calling
applyToken(token, ["line-height"]) on a :number token would correctly
set the line-height text attribute but also invoke update-rotation with
the token value, silently rotating the shape.

Added an :on-update-shape-per-attr map to the :number token properties
entry mapping each valid attribute subset to its correct update function.
toggle-token now resolves the update function from that map when explicit
attrs are provided, falling back to the default on-update-shape otherwise.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>

* ♻️ Centralise attr->update-fn map and use it generically in toggle-token

The attributes->shape-update map was only defined in propagation.cljs.
Move it to application.cljs (where all the update functions live) and
have propagation.cljs reference it via dwta/attributes->shape-update,
eliminating the duplication.

Build a private flattened attr->shape-update map (one entry per
individual keyword) from that same source of truth. toggle-token now
uses it to resolve the correct on-update-shape when explicit attrs are
passed, instead of always taking the default from token-properties.
This fixes the :number token side-effect without any per-type special
casing: any token type whose explicit attrs map to a different update
function than the type default will now dispatch correctly.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>

*  Backport obj/reify changes from develop

*  Add missing error handler on shape proxy on plugins objects

---------

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Alonso Torres <alonso.torres@kaleidos.net>
This commit is contained in:
Andrey Antukh 2026-03-12 12:51:26 +01:00 committed by GitHub
parent 0e0029bd56
commit 37cf099126
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 28 deletions

View File

@ -609,6 +609,46 @@
;; Events to apply / unapply tokens to shapes ------------------------------------------------------------
(def attributes->shape-update
"Maps each attribute-set to the update function that applies it to a shape.
Used both here (to resolve the correct update fn when explicit attrs are
passed to toggle-token) and in propagation.cljs (re-exported from there)."
{ctt/border-radius-keys update-shape-radius-for-corners
ctt/color-keys update-fill-stroke
ctt/stroke-width-keys update-stroke-width
ctt/sizing-keys apply-dimensions-token
ctt/opacity-keys update-opacity
ctt/rotation-keys update-rotation
;; Typography
ctt/font-family-keys update-font-family
ctt/font-size-keys update-font-size
ctt/font-weight-keys update-font-weight
ctt/letter-spacing-keys update-letter-spacing
ctt/text-case-keys update-text-case
ctt/text-decoration-keys update-text-decoration
ctt/typography-token-keys update-typography
ctt/shadow-keys update-shadow
ctt/line-height-keys update-line-height
;; Layout
#{:x :y} update-shape-position
#{:p1 :p2 :p3 :p4} update-layout-padding
#{:m1 :m2 :m3 :m4} update-layout-item-margin
#{:column-gap :row-gap} update-layout-gap
#{:width :height} apply-dimensions-token
#{:layout-item-min-w :layout-item-min-h
:layout-item-max-w :layout-item-max-h} update-layout-sizing-limits})
;; Flattened per-individual-key version of attributes->shape-update.
;; Allows O(1) lookup of the update function for any single attribute.
(def ^:private attr->shape-update
(reduce
(fn [acc [attr-set update-fn]]
(into acc (map (fn [k] [k update-fn]) attr-set)))
{}
attributes->shape-update))
(defn apply-token
"Apply `attributes` that match `token` for `shape-ids`.
@ -752,10 +792,16 @@
{:keys [attributes all-attributes on-update-shape]}
(get token-properties (:type token))
on-update-shape
(if (seq attrs)
(or (get attr->shape-update (first attrs)) on-update-shape)
on-update-shape)
unapply-tokens?
(cfo/shapes-token-applied? token shapes (or attrs all-attributes attributes))
shape-ids (map :id shapes)]
shape-ids
(map :id shapes)]
(if unapply-tokens?
(rx/of

View File

@ -53,32 +53,7 @@
(def ^:private filter-existing-values? false)
(def ^:private attributes->shape-update
{ctt/border-radius-keys dwta/update-shape-radius-for-corners
ctt/color-keys dwta/update-fill-stroke
ctt/stroke-width-keys dwta/update-stroke-width
ctt/sizing-keys dwta/apply-dimensions-token
ctt/opacity-keys dwta/update-opacity
ctt/rotation-keys dwta/update-rotation
;; Typography
ctt/font-family-keys dwta/update-font-family
ctt/font-size-keys dwta/update-font-size
ctt/font-weight-keys dwta/update-font-weight
ctt/letter-spacing-keys dwta/update-letter-spacing
ctt/text-case-keys dwta/update-text-case
ctt/text-decoration-keys dwta/update-text-decoration
ctt/typography-token-keys dwta/update-typography
ctt/shadow-keys dwta/update-shadow
#{:line-height} dwta/update-line-height
;; Layout
#{:x :y} dwta/update-shape-position
#{:p1 :p2 :p3 :p4} dwta/update-layout-padding
#{:m1 :m2 :m3 :m4} dwta/update-layout-item-margin
#{:column-gap :row-gap} dwta/update-layout-gap
#{:width :height} dwta/apply-dimensions-token
#{:layout-item-min-w :layout-item-min-h :layout-item-max-w :layout-item-max-h} dwta/update-layout-sizing-limits})
(def ^:private attributes->shape-update dwta/attributes->shape-update)
(def ^:private attribute-actions-map
(flatten-set-keyed-map attributes->shape-update {}))

View File

@ -192,7 +192,7 @@
(assert (uuid? id))
(let [data (u/locate-shape file-id page-id id)]
(-> (obj/reify {:name "ShapeProxy"}
(-> (obj/reify {:name "ShapeProxy" :on-error u/handle-error}
:$plugin {:enumerable false :get (fn [] plugin-id)}
:$id {:enumerable false :get (fn [] id)}
:$file {:enumerable false :get (fn [] file-id)}