diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs index a5ed1ce76b..8c4cad66b7 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs @@ -283,6 +283,11 @@ (into [] (comp (mapcat tt/shape-attr->token-attrs) (distinct)) (type->editable-attrs type)))) + ;; The `:text` read mode reads values from `attrs`, not from the + ;; editable attrs, so its token attrs must come from `attrs` too. + text-token-attrs + (into [] (comp (mapcat tt/shape-attr->token-attrs) (distinct)) attrs) + merge-attrs (fn [v1 v2] (cond @@ -311,8 +316,9 @@ merge-token-values (fn [acc token-attrs applied-tokens] - "Merges token values across all token attributes derived from the shape's - editable attributes." + "Merges token values across all `token-attrs`. Callers derive them from + the attributes the shape's read mode reads: the editable attributes for + `:shape`, the whole group attributes for `:text`." (let [no-tokens? (empty? applied-tokens) stable (deref stable-token-acc)] (if (and no-tokens? @@ -360,7 +366,7 @@ (merge-attrs shape-attrs) (merge-attrs content-attrs)) - new-token-acc (merge-token-values token-acc (type->token-attrs type) applied-tokens)] + new-token-acc (merge-token-values token-acc text-token-attrs applied-tokens)] [(conj ids id) new-values new-token-acc]) diff --git a/frontend/test/frontend_tests/ui/layout_container_multiple_test.cljs b/frontend/test/frontend_tests/ui/layout_container_multiple_test.cljs index 10b64d95b1..77bc263fa3 100644 --- a/frontend/test/frontend_tests/ui/layout_container_multiple_test.cljs +++ b/frontend/test/frontend_tests/ui/layout_container_multiple_test.cljs @@ -44,3 +44,41 @@ (t/is (= {:p1 10 :p2 20 :p3 10 :p4 20} (:layout-padding values))) (t/is (= :multiple (:layout-padding-type values))))) + +(defn- fill-tokens + [shapes] + (let [[_ids _values tokens] (multiple/get-attrs* shapes {} :fill)] + tokens)) + +(defn- text-shape + [id applied-tokens] + (cond-> {:id id :type :text :fills []} + applied-tokens (assoc :applied-tokens applied-tokens))) + +(defn- rect-shape + [id applied-tokens] + (cond-> {:id id :type :rect :fills []} + applied-tokens (assoc :applied-tokens applied-tokens))) + +(t/deftest multiple-text-selection-same-fill-token + (t/is (= {:fill "color.primary"} + (fill-tokens [(text-shape :text-1 {:fill "color.primary"}) + (text-shape :text-2 {:fill "color.primary"})])))) + +(t/deftest multiple-text-selection-different-fill-tokens + (t/is (= {:fill :multiple} + (fill-tokens [(text-shape :text-1 {:fill "color.primary"}) + (text-shape :text-2 {:fill "color.secondary"})])))) + +(t/deftest multiple-text-selection-token-and-no-token + (t/is (= {:fill :multiple} + (fill-tokens [(text-shape :text-1 {:fill "color.primary"}) + (text-shape :text-2 nil)])))) + +(t/deftest multiple-selection-rect-and-text-fill-tokens + (t/is (= {:fill "color.primary"} + (fill-tokens [(rect-shape :rect-1 {:fill "color.primary"}) + (text-shape :text-1 {:fill "color.primary"})]))) + (t/is (= {:fill :multiple} + (fill-tokens [(rect-shape :rect-1 {:fill "color.primary"}) + (text-shape :text-1 {:fill "color.secondary"})]))))