From 67b3040327c2a32662bd4df9a96dd87284e8ec69 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 10 Jan 2024 10:44:31 +0100 Subject: [PATCH] :bug: Fix problem with text content and multiple selection --- common/src/app/common/attrs.cljc | 15 +++- common/src/app/common/text.cljc | 65 +++++++++++++++- .../src/app/main/data/workspace/colors.cljs | 3 +- .../main/data/workspace/text/shortcuts.cljs | 7 +- .../src/app/main/data/workspace/texts.cljs | 74 ++----------------- .../workspace/sidebar/options/menus/text.cljs | 8 +- .../sidebar/options/shapes/multiple.cljs | 52 +++++++------ .../sidebar/options/shapes/text.cljs | 11 +-- 8 files changed, 129 insertions(+), 106 deletions(-) diff --git a/common/src/app/common/attrs.cljc b/common/src/app/common/attrs.cljc index d414628be..0c2533178 100644 --- a/common/src/app/common/attrs.cljc +++ b/common/src/app/common/attrs.cljc @@ -7,7 +7,8 @@ (ns app.common.attrs (:require [app.common.geom.shapes :as gsh] - [app.common.math :as mth])) + [app.common.math :as mth] + [app.common.text :as txt])) (defn- get-attr [obj attr] @@ -113,3 +114,15 @@ (persistent! result))))) +(defn get-text-attrs-multi + "Gets the multi attributes for a text shape. Splits the content by type and gets the attributes depending + on the node type" + [{:keys [content]} defaults attrs] + (let [root-attrs (->> attrs (filter (set txt/root-attrs))) + paragraph-attrs (->> attrs (filter (set txt/paragraph-attrs))) + text-node-attrs (->> attrs (filter (set txt/text-node-attrs)))] + (merge + defaults + (get-attrs-multi (->> (txt/node-seq txt/is-root-node? content)) root-attrs) + (get-attrs-multi (->> (txt/node-seq txt/is-paragraph-node? content)) paragraph-attrs) + (get-attrs-multi (->> (txt/node-seq txt/is-text-node? content)) text-node-attrs)))) diff --git a/common/src/app/common/text.cljc b/common/src/app/common/text.cljc index 35e220ab5..b5b12c5d5 100644 --- a/common/src/app/common/text.cljc +++ b/common/src/app/common/text.cljc @@ -13,6 +13,67 @@ [clojure.walk :as walk] [cuerdas.core :as str])) +;; -- Attrs + +(def text-typography-attrs + [:typography-ref-id + :typography-ref-file]) + +(def text-fill-attrs + [:fill-color + :fill-opacity + :fill-color-ref-id + :fill-color-ref-file + :fill-color-gradient]) + +(def text-font-attrs + [:font-id + :font-family + :font-variant-id + :font-size + :font-weight + :font-style]) + +(def text-align-attrs + [:text-align]) + +(def text-direction-attrs + [:text-direction]) + +(def text-spacing-attrs + [:line-height + :letter-spacing]) + +(def text-valign-attrs + [:vertical-align]) + +(def text-decoration-attrs + [:text-decoration]) + +(def text-transform-attrs + [:text-transform]) + +(def shape-attrs + [:grow-type]) + +(def root-attrs + text-valign-attrs) + +(def paragraph-attrs + (d/concat-vec + text-align-attrs + text-direction-attrs)) + +(def text-node-attrs + (d/concat-vec + text-typography-attrs + text-font-attrs + text-spacing-attrs + text-decoration-attrs + text-transform-attrs)) + +(def text-all-attrs (d/concat-set shape-attrs root-attrs paragraph-attrs text-node-attrs)) + (def default-text-attrs {:typography-ref-file nil :typography-ref-id nil @@ -30,8 +91,6 @@ :fills [{:fill-color clr/black :fill-opacity 1}]}) -(def text-attrs (keys default-text-attrs)) - (def typography-fields [:font-id :font-family @@ -274,7 +333,7 @@ [node] (letfn [(rec-style-text-map [acc node style] - (let [node-style (merge style (select-keys node text-attrs)) + (let [node-style (merge style (select-keys node text-all-attrs)) head (or (-> acc first) [{} ""]) [head-style head-text] head diff --git a/frontend/src/app/main/data/workspace/colors.cljs b/frontend/src/app/main/data/workspace/colors.cljs index 61ec72a63..e20b9019b 100644 --- a/frontend/src/app/main/data/workspace/colors.cljs +++ b/frontend/src/app/main/data/workspace/colors.cljs @@ -11,6 +11,7 @@ [app.common.data.macros :as dm] [app.common.files.helpers :as cfh] [app.common.schema :as sm] + [app.common.text :as txt] [app.common.types.component :as ctk] [app.main.broadcast :as mbc] [app.main.data.events :as ev] @@ -673,7 +674,7 @@ (:fills (dwt/current-text-values {:editor-state (dm/get-in state [:workspace-editor-state (:id shape)]) :shape shape - :attrs (conj dwt/text-fill-attrs :fills)})) + :attrs (conj txt/text-fill-attrs :fills)})) (:fills shape)) fill (first fills) single? (and (= 1 (count selected)) diff --git a/frontend/src/app/main/data/workspace/text/shortcuts.cljs b/frontend/src/app/main/data/workspace/text/shortcuts.cljs index cd280aba2..80d7005fb 100644 --- a/frontend/src/app/main/data/workspace/text/shortcuts.cljs +++ b/frontend/src/app/main/data/workspace/text/shortcuts.cljs @@ -7,6 +7,7 @@ (ns app.main.data.workspace.text.shortcuts (:require [app.common.data :as d] + [app.common.text :as txt] [app.main.data.shortcuts :as ds] [app.main.data.workspace.texts :as dwt] [app.main.data.workspace.undo :as dwu] @@ -116,15 +117,15 @@ (d/merge (dwt/current-root-values {:shape shape - :attrs dwt/root-attrs}) + :attrs txt/root-attrs}) (dwt/current-paragraph-values {:editor-state editor-state :shape shape - :attrs dwt/paragraph-attrs}) + :attrs txt/paragraph-attrs}) (dwt/current-text-values {:editor-state editor-state :shape shape - :attrs dwt/text-attrs})))) + :attrs txt/text-node-attrs})))) (defn- update-attrs [shape props] (let [text-values (calculate-text-values shape) diff --git a/frontend/src/app/main/data/workspace/texts.cljs b/frontend/src/app/main/data/workspace/texts.cljs index c741a4e62..5f7bfb499 100644 --- a/frontend/src/app/main/data/workspace/texts.cljs +++ b/frontend/src/app/main/data/workspace/texts.cljs @@ -33,66 +33,6 @@ [cuerdas.core :as str] [potok.v2.core :as ptk])) -;; -- Attrs - -(def text-typography-attrs - [:typography-ref-id - :typography-ref-file]) - -(def text-fill-attrs - [:fill-color - :fill-opacity - :fill-color-ref-id - :fill-color-ref-file - :fill-color-gradient]) - -(def text-font-attrs - [:font-id - :font-family - :font-variant-id - :font-size - :font-weight - :font-style]) - -(def text-align-attrs - [:text-align]) - -(def text-direction-attrs - [:text-direction]) - -(def text-spacing-attrs - [:line-height - :letter-spacing]) - -(def text-valign-attrs - [:vertical-align]) - -(def text-decoration-attrs - [:text-decoration]) - -(def text-transform-attrs - [:text-transform]) - -(def shape-attrs - [:grow-type]) - -(def root-attrs text-valign-attrs) - -(def paragraph-attrs - (d/concat-vec - text-align-attrs - text-direction-attrs)) - -(def text-attrs - (d/concat-vec - text-typography-attrs - text-font-attrs - text-spacing-attrs - text-decoration-attrs - text-transform-attrs)) - -(def attrs (d/concat-set shape-attrs root-attrs paragraph-attrs text-attrs)) - ;; -- Editor (defn update-editor @@ -611,17 +551,17 @@ ptk/WatchEvent (watch [_ _ _] (rx/concat - (let [attrs (select-keys attrs root-attrs)] + (let [attrs (select-keys attrs txt/root-attrs)] (if-not (empty? attrs) (rx/of (update-root-attrs {:id id :attrs attrs})) (rx/empty))) - (let [attrs (select-keys attrs paragraph-attrs)] + (let [attrs (select-keys attrs txt/paragraph-attrs)] (if-not (empty? attrs) (rx/of (update-paragraph-attrs {:id id :attrs attrs})) (rx/empty))) - (let [attrs (select-keys attrs text-attrs)] + (let [attrs (select-keys attrs txt/text-node-attrs)] (if-not (empty? attrs) (rx/of (update-text-attrs {:id id :attrs attrs})) (rx/empty))))))) @@ -683,7 +623,7 @@ values (current-text-values {:editor-state (dm/get-in state [:workspace-editor-state (:id shape)]) :shape shape - :attrs text-attrs}) + :attrs txt/text-node-attrs}) multiple? (or (> 1 (count shapes)) (d/seek (partial = :multiple) @@ -691,9 +631,9 @@ values (-> (d/without-nils values) (select-keys - (d/concat-vec text-font-attrs - text-spacing-attrs - text-transform-attrs))) + (d/concat-vec txt/text-font-attrs + txt/text-spacing-attrs + txt/text-transform-attrs))) typ-id (uuid/next) typ (-> (if multiple? diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs index 882eb4aee..74496773a 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs @@ -212,7 +212,7 @@ (mf/deps values) (fn [ids attrs] (st/emit! (dwt/save-font (-> (merge txt/default-text-attrs values attrs) - (select-keys dwt/text-attrs))) + (select-keys txt/text-node-attrs))) (dwt/update-all-attrs ids attrs)))) on-change @@ -242,9 +242,9 @@ (fn [_] (let [set-values (-> (d/without-nils values) (select-keys - (d/concat-vec dwt/text-font-attrs - dwt/text-spacing-attrs - dwt/text-transform-attrs))) + (d/concat-vec txt/text-font-attrs + txt/text-spacing-attrs + txt/text-transform-attrs))) typography (merge txt/default-typography set-values) typography (dwt/generate-typography-name typography) id (uuid/next)] 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 736a71c30..f669bc4d9 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 @@ -14,7 +14,6 @@ [app.common.types.component :as ctk] [app.common.types.shape.attrs :refer [editable-attrs]] [app.common.types.shape.layout :as ctl] - [app.main.data.workspace.texts :as dwt] [app.main.refs :as refs] [app.main.ui.hooks :as hooks] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-attrs blur-menu]] @@ -163,7 +162,7 @@ :shadow shadow-attrs :blur blur-attrs :stroke stroke-attrs - :text dwt/attrs + :text txt/text-all-attrs :exports exports-attrs :layout-container layout-container-flex-attrs :layout-item layout-item-attrs}) @@ -211,32 +210,41 @@ :else (attrs/get-attrs-multi [v1 v2] attrs))) extract-attrs - (fn [[ids values] {:keys [id type content] :as shape}] + (fn [[ids values] {:keys [id type] :as shape}] (let [read-mode (get-in type->read-mode [type attr-group]) editable-attrs (filter (get editable-attrs (:type shape)) attrs)] (case read-mode - :ignore [ids values] + :ignore + [ids values] - :shape (let [;; Get the editable attrs from the shape, ensuring that all attributes - ;; are present, with value nil if they are not present in the shape. - shape-values (merge - (into {} (map #(vector % nil)) editable-attrs) - (cond - (= attr-group :measure) (select-measure-keys shape) - :else (select-keys shape editable-attrs)))] - [(conj ids id) - (merge-attrs values shape-values)]) + :shape + (let [;; Get the editable attrs from the shape, ensuring that all attributes + ;; are present, with value nil if they are not present in the shape. + shape-values (merge + (into {} (map #(vector % nil)) editable-attrs) + (cond + (= attr-group :measure) (select-measure-keys shape) + :else (select-keys shape editable-attrs)))] + [(conj ids id) + (merge-attrs values shape-values)]) - :text [(conj ids id) - (-> values - (merge-attrs (select-keys shape attrs)) - (merge-attrs (merge - (select-keys txt/default-text-attrs attrs) - (attrs/get-attrs-multi (txt/node-seq content) attrs))))] + :text + (let [shape-attrs (select-keys shape attrs) - :children (let [children (->> (:shapes shape []) (map #(get objects %))) - [new-ids new-values] (get-attrs* children objects attr-group)] - [(d/concat-vec ids new-ids) (merge-attrs values new-values)]) + content-attrs + (attrs/get-text-attrs-multi shape txt/default-text-attrs attrs) + + new-values + (-> values + (merge-attrs shape-attrs) + (merge-attrs content-attrs))] + [(conj ids id) + new-values]) + + :children + (let [children (->> (:shapes shape []) (map #(get objects %))) + [new-ids new-values] (get-attrs* children objects attr-group)] + [(d/concat-vec ids new-ids) (merge-attrs values new-values)]) [])))] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs index 990c8bfe7..955db7652 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs @@ -7,8 +7,9 @@ (ns app.main.ui.workspace.sidebar.options.shapes.text (:require [app.common.data :as d] + [app.common.text :as txt] [app.common.types.shape.layout :as ctl] - [app.main.data.workspace.texts :as dwt :refer [text-fill-attrs root-attrs paragraph-attrs text-attrs]] + [app.main.data.workspace.texts :as dwt] [app.main.refs :as refs] [app.main.ui.hooks :as hooks] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] @@ -56,7 +57,7 @@ fill-values (-> (dwt/current-text-values {:editor-state editor-state :shape shape - :attrs (conj text-fill-attrs :fills)}) + :attrs (conj txt/text-fill-attrs :fills)}) (d/update-in-when [:fill-color-gradient :type] keyword)) fill-values (if (not (contains? fill-values :fills)) @@ -71,15 +72,15 @@ (select-keys shape fill-attrs) (dwt/current-root-values {:shape shape - :attrs root-attrs}) + :attrs txt/root-attrs}) (dwt/current-paragraph-values {:editor-state editor-state :shape shape - :attrs paragraph-attrs}) + :attrs txt/paragraph-attrs}) (dwt/current-text-values {:editor-state editor-state :shape shape - :attrs text-attrs})) + :attrs txt/text-node-attrs})) layout-item-values (select-keys shape layout-item-attrs)] [:*