🐛 Fix persist per side toggle state in profile

This commit is contained in:
Luis de Dios 2026-09-18 11:13:57 +02:00
parent 2b96a220bd
commit 7fd1b6d864
9 changed files with 34 additions and 63 deletions

View File

@ -75,7 +75,8 @@
[:workspace-visited {:optional true} ::sm/boolean]
[:custom-shortcuts {:optional true}
[:map-of {:gen/max 10} :keyword [:map-of :keyword :string]]]
[:nudge {:optional true} schema:nudge]])
[:nudge {:optional true} schema:nudge]
[:stroke-per-side {:optional true} ::sm/boolean]])
(def schema:props-writeable
"Props schema for user-writable fields (excludes system-managed keys)."

View File

@ -85,13 +85,12 @@
;; Per-side widths (rects/frames). Sides falling back to the
;; uniform width; skipped when all sides end up equal, so the
;; renderer keeps the uniform path (with dash/dot support).
(when (:stroke-per-side stroke)
(let [top (or (:stroke-width-top stroke) width)
right (or (:stroke-width-right stroke) width)
bottom (or (:stroke-width-bottom stroke) width)
left (or (:stroke-width-left stroke) width)]
(when-not (= top right bottom left)
(h/call wasm/internal-module "_set_shape_stroke_sides" top right bottom left))))
(let [top (or (:stroke-width-top stroke) width)
right (or (:stroke-width-right stroke) width)
bottom (or (:stroke-width-bottom stroke) width)
left (or (:stroke-width-left stroke) width)]
(when-not (= top right bottom left)
(h/call wasm/internal-module "_set_shape_stroke_sides" top right bottom left)))
(cond
(some? gradient)

View File

@ -248,12 +248,14 @@
cap-end (-> stroke :stroke-cap-end sr/translate-stroke-cap)
dash (or (:stroke-dash stroke) -1)
gap (or (:stroke-gap stroke) -1)
per-side? (boolean (:stroke-per-side stroke))
top (or (:stroke-width-top stroke) width)
right (or (:stroke-width-right stroke) width)
bottom (or (:stroke-width-bottom stroke) width)
left (or (:stroke-width-left stroke) width)
has-sides? (and per-side? (not= top right bottom left))]
has-sides? (not= top right bottom left)]
(buf/write-f32 dview offset width)
(buf/write-u8 dview (+ offset 4) style)
(buf/write-u8 dview (+ offset 5) align)

View File

@ -139,8 +139,6 @@
[:stroke-style {:optional true}
[::sm/one-of #{:solid :dotted :dashed :mixed}]]
[:stroke-width {:optional true} ::sm/safe-number]
;; wasm-render only, backwards compatible
[:stroke-per-side {:optional true} :boolean]
[:stroke-width-top {:optional true} ::sm/safe-number]
[:stroke-width-right {:optional true} ::sm/safe-number]
[:stroke-width-bottom {:optional true} ::sm/safe-number]

View File

@ -335,7 +335,6 @@
:stroke-width
:stroke-dash
:stroke-gap
:stroke-per-side
:stroke-width-top
:stroke-width-right
:stroke-width-bottom

View File

@ -36,6 +36,9 @@
(def custom-shortcuts
(l/derived (fn [state] (get-in state [:profile :props :custom-shortcuts])) st/state))
(def stroke-per-side
(l/derived (fn [state] (get-in state [:profile :props :stroke-per-side])) st/state))
(def current-page-id
(l/derived (l/key :current-page-id) st/state))

View File

@ -148,29 +148,6 @@
per-side-disabled?
(not wasm-render?)
on-stroke-per-side-toggle
(fn [index]
(let [stroke (get-in values [:strokes index])
active? (:stroke-per-side stroke)
width (:stroke-width stroke)
width (if (number? width) width 1)]
(st/emit! (udw/trigger-bounding-box-cloaking ids))
(if active?
(st/emit! (dc/change-stroke-attrs ids {:stroke-per-side false} index))
;; Entering per-side mode seeds any missing side from the
;; uniform width, so previous per-side edits are preserved.
;; The top value doubles as the global :stroke-width.
(let [top (d/nilv (:stroke-width-top stroke) width)]
(st/emit! (dc/change-stroke-attrs
ids
{:stroke-per-side true
:stroke-width top
:stroke-width-top top
:stroke-width-right (d/nilv (:stroke-width-right stroke) width)
:stroke-width-bottom (d/nilv (:stroke-width-bottom stroke) width)
:stroke-width-left (d/nilv (:stroke-width-left stroke) width)}
index))))))
on-stroke-width-side-change
(fn [index attr value]
(when (number? value)
@ -288,7 +265,6 @@
:on-stroke-width-change on-stroke-width-change
:per-side-available per-side-available?
:per-side-disabled per-side-disabled?
:on-stroke-per-side-toggle on-stroke-per-side-toggle
:on-stroke-width-side-change on-stroke-width-side-change
:on-stroke-dash-change on-stroke-dash-change
:on-stroke-gap-change on-stroke-gap-change

View File

@ -10,9 +10,11 @@
[app.common.data :as d]
[app.common.types.color :as ctc]
[app.common.types.token :as ctt]
[app.main.data.profile :as du]
[app.main.data.workspace.colors :as dc]
[app.main.data.workspace.tokens.application :as dwta]
[app.main.features :as features]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.numeric-input :as deprecated-input]
[app.main.ui.components.reorder-handler :refer [reorder-handler*]]
@ -39,7 +41,6 @@
on-stroke-width-change
per-side-available
per-side-disabled
on-stroke-per-side-toggle
on-stroke-width-side-change
on-stroke-dash-change
on-stroke-gap-change
@ -104,12 +105,10 @@
stroke-width (:stroke-width stroke)
per-side-enabled (mf/deref refs/stroke-per-side)
per-side? (and per-side-available
(not per-side-disabled)
(true? (:stroke-per-side stroke)))
per-side-expanded* (mf/use-state false)
per-side-expanded? (deref per-side-expanded*)
(true? per-side-enabled))
all-sides-equal?
(mf/with-memo [stroke]
@ -120,7 +119,7 @@
left (d/nilv (:stroke-width-left stroke) width)]
(= top right bottom left)))
show-multiple-placeholder? (or per-side-expanded? (not all-sides-equal?))
show-multiple-placeholder? (or per-side? (not all-sides-equal?))
applied-token-width
(mf/with-memo [applied-tokens]
@ -148,14 +147,9 @@
on-per-side-toggle
(mf/use-fn
(mf/deps per-side? on-stroke-per-side-toggle index)
(mf/deps per-side?)
(fn []
(if per-side?
(swap! per-side-expanded* not)
(do
(when on-stroke-per-side-toggle
(on-stroke-per-side-toggle index))
(reset! per-side-expanded* true)))))
(st/emit! (du/update-profile-props {:stroke-per-side (not per-side?)}))))
on-width-top-change
(mf/use-fn
@ -432,7 +426,7 @@
:on-change on-style-change}])
(when per-side-available
[:> icon-button* {:variant "ghost"
:aria-pressed per-side-expanded?
:aria-pressed per-side?
:aria-label per-side-toggle-label
:disabled per-side-disabled
:on-click on-per-side-toggle
@ -472,14 +466,14 @@
:on-change on-style-change}]])
(when per-side-available
[:> icon-button* {:variant "ghost"
:aria-pressed per-side-expanded?
:aria-pressed per-side?
:aria-label per-side-toggle-label
:disabled per-side-disabled
:on-click on-per-side-toggle
:icon i/stroke-extended
:data-testid "stroke.per-side-toggle"}])])
(when per-side-expanded?
(when per-side?
[:div {:class (stl/css :stroke-sides-options)
:data-testid "stroke.per-side-options"}
[:> numeric-input-wrapper* {:on-change on-width-top-change

View File

@ -214,17 +214,16 @@
(fill->color (first fills)))))
(defn stroke-per-side-widths
"Returns [top right bottom left] when the stroke has per-side widths
enabled and the sides actually differ; nil otherwise."
"Returns [top right bottom left] when the stroke sides actually
differ; nil otherwise."
[stroke]
(when (:stroke-per-side stroke)
(let [width (:stroke-width stroke)
top (d/nilv (:stroke-width-top stroke) width)
right (d/nilv (:stroke-width-right stroke) width)
bottom (d/nilv (:stroke-width-bottom stroke) width)
left (d/nilv (:stroke-width-left stroke) width)]
(when-not (= top right bottom left)
[top right bottom left]))))
(let [width (:stroke-width stroke)
top (d/nilv (:stroke-width-top stroke) width)
right (d/nilv (:stroke-width-right stroke) width)
bottom (d/nilv (:stroke-width-bottom stroke) width)
left (d/nilv (:stroke-width-left stroke) width)]
(when-not (= top right bottom left)
[top right bottom left])))
(defn- get-border
[shape]