From add9c98ba04755b0548783a1284df31a68a57df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Wed, 14 Feb 2024 12:05:26 +0100 Subject: [PATCH 01/17] :bug: Fix email tags not being shown in invite members modal --- frontend/src/app/main/ui/dashboard/team.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/app/main/ui/dashboard/team.scss b/frontend/src/app/main/ui/dashboard/team.scss index be1f9a613..51cd9ac4f 100644 --- a/frontend/src/app/main/ui/dashboard/team.scss +++ b/frontend/src/app/main/ui/dashboard/team.scss @@ -727,4 +727,5 @@ .email-input { @extend .input-base; + height: auto; } From 3212ed9bd1a25f52af1d339d074565f4d6a838f5 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 14 Feb 2024 17:33:34 +0100 Subject: [PATCH 02/17] :bug: Fix incorrect value passed on unhandled error --- frontend/src/app/main/errors.cljs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 2c70a31cd..a16bd93f0 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -90,8 +90,7 @@ (defmethod ptk/handle-error :default [error] - (when-let [cause (::instance error)] - (ts/schedule #(st/emit! (rt/assign-exception cause)))) + (st/async-emit! (rt/assign-exception error)) (print-group! "Unhandled Error" (fn [] (print-trace! error) From ba55d657a4cb334c8878c6fef610801b95894908 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 14 Feb 2024 17:34:50 +0100 Subject: [PATCH 03/17] :sparkles: Prevent adding object map to not loaded pointer-map containers --- backend/src/app/features/fdata.clj | 19 ++++++++++++++----- backend/src/app/util/pointer_map.clj | 4 ++-- common/src/app/common/data.cljc | 9 ++++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/backend/src/app/features/fdata.clj b/backend/src/app/features/fdata.clj index 8a57a1aa1..6f918bb53 100644 --- a/backend/src/app/features/fdata.clj +++ b/backend/src/app/features/fdata.clj @@ -22,12 +22,21 @@ (defn enable-objects-map [file] - (let [update-fn #(d/update-when % :objects omap/wrap)] + (let [update-container + (fn [container] + (if (and (pmap/pointer-map? container) + (not (pmap/loaded? container))) + container + (d/update-when container :objects omap/wrap))) + + update-data + (fn [fdata] + (-> fdata + (update :pages-index d/update-vals update-container) + (d/update-when :components d/update-vals update-container)))] + (-> file - (update :data (fn [fdata] - (-> fdata - (update :pages-index update-vals update-fn) - (d/update-when :components update-vals update-fn)))) + (update :data update-data) (update :features conj "fdata/objects-map")))) (defn process-objects diff --git a/backend/src/app/util/pointer_map.clj b/backend/src/app/util/pointer_map.clj index bb7b25293..f5933ecd6 100644 --- a/backend/src/app/util/pointer_map.clj +++ b/backend/src/app/util/pointer_map.clj @@ -68,6 +68,7 @@ (get-id [_]) (load! [_]) (modified? [_]) + (loaded? [_]) (clone [_])) (deftype PointerMap [id mdata @@ -90,6 +91,7 @@ (or odata {})) (modified? [_] modified?) + (loaded? [_] loaded?) (get-id [_] id) (clone [this] @@ -210,8 +212,6 @@ (defn create ([] (let [id (uuid/next) - - mdata (assoc *metadata* :created-at (dt/now)) pmap (PointerMap. id mdata {} true true)] (some-> *tracked* (swap! assoc id pmap)) diff --git a/common/src/app/common/data.cljc b/common/src/app/common/data.cljc index bcfd55648..0dcf23e7e 100644 --- a/common/src/app/common/data.cljc +++ b/common/src/app/common/data.cljc @@ -7,7 +7,7 @@ (ns app.common.data "A collection if helpers for working with data structures and other data resources." - (:refer-clojure :exclude [read-string hash-map merge name + (:refer-clojure :exclude [read-string hash-map merge name update-vals parse-double group-by iteration concat mapcat parse-uuid max min]) #?(:cljs @@ -403,6 +403,13 @@ [coll] (partial get coll)) +(defn update-vals + [m f] + (reduce-kv (fn [acc k v] + (assoc acc k (f v))) + m + m)) + (defn update-in-when [m key-seq f & args] (let [found (get-in m key-seq sentinel)] From 8981e57deb4126ea5e0515e3817888b56f23a94a Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 14 Feb 2024 17:36:13 +0100 Subject: [PATCH 04/17] :sparkles: Ensure connection on persisting pointers --- backend/src/app/features/fdata.clj | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/backend/src/app/features/fdata.clj b/backend/src/app/features/fdata.clj index 6f918bb53..4715c5bfb 100644 --- a/backend/src/app/features/fdata.clj +++ b/backend/src/app/features/fdata.clj @@ -81,14 +81,15 @@ "Given a database connection and the final file-id, persist all pointers to the underlying storage (the database)." [system file-id] - (doseq [[id item] @pmap/*tracked*] - (when (pmap/modified? item) - (l/trc :hint "persist pointer" :file-id (str file-id) :id (str id)) - (let [content (-> item deref blob/encode)] - (db/insert! system :file-data-fragment - {:id id - :file-id file-id - :content content}))))) + (let [conn (db/get-connection system)] + (doseq [[id item] @pmap/*tracked*] + (when (pmap/modified? item) + (l/trc :hint "persist pointer" :file-id (str file-id) :id (str id)) + (let [content (-> item deref blob/encode)] + (db/insert! conn :file-data-fragment + {:id id + :file-id file-id + :content content})))))) (defn process-pointers "Apply a function to all pointers on the file. Usuly used for From 29d48f0a981b19ea73afe956b75c01338c809bbf Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 14 Feb 2024 17:36:41 +0100 Subject: [PATCH 05/17] :sparkles: Add minor code cleaning on file-update ns --- backend/src/app/rpc/commands/files_update.clj | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/backend/src/app/rpc/commands/files_update.clj b/backend/src/app/rpc/commands/files_update.clj index cd7436742..9c7c5fb4b 100644 --- a/backend/src/app/rpc/commands/files_update.clj +++ b/backend/src/app/rpc/commands/files_update.clj @@ -30,7 +30,6 @@ [app.rpc.doc :as-alias doc] [app.rpc.helpers :as rph] [app.util.blob :as blob] - [app.util.objects-map :as omap] [app.util.pointer-map :as pmap] [app.util.services :as sv] [app.util.time :as dt] @@ -119,18 +118,11 @@ [f] (fn [cfg {:keys [id] :as file}] (binding [pmap/*tracked* (pmap/create-tracked) - pmap/*load-fn* (partial feat.fdata/load-pointer cfg id) - cfeat/*wrap-with-pointer-map-fn* pmap/wrap] + pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)] (let [result (f cfg file)] (feat.fdata/persist-pointers! cfg id) result)))) -(defn- wrap-with-objects-map-context - [f] - (fn [cfg file] - (binding [cfeat/*wrap-with-objects-map-fn* omap/wrap] - (f cfg file)))) - (declare get-lagged-changes) (declare send-notifications!) (declare update-file) @@ -199,10 +191,7 @@ update-fn (cond-> update-file* (contains? features "fdata/pointer-map") - (wrap-with-pointer-map-context) - - (contains? features "fdata/objects-map") - (wrap-with-objects-map-context)) + (wrap-with-pointer-map-context)) changes (if changes-with-metadata (->> changes-with-metadata (mapcat :changes) vec) @@ -328,6 +317,7 @@ ;; leeave it on lazy status (-> (files/get-file cfg id :migrate? false) (update :data feat.fdata/process-pointers deref) ; ensure all pointers resolved + (update :data feat.fdata/process-objects (partial into {})) (fmg/migrate-file)))))) (d/index-by :id))) From 63e74545ab9e962b16a367a5f0d693bc099656ce Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 14 Feb 2024 17:37:31 +0100 Subject: [PATCH 06/17] :paperclip: Add get-raw-file srepl helper --- backend/src/app/srepl/helpers.clj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/src/app/srepl/helpers.clj b/backend/src/app/srepl/helpers.clj index 9df761db0..07b89ab7c 100644 --- a/backend/src/app/srepl/helpers.clj +++ b/backend/src/app/srepl/helpers.clj @@ -85,6 +85,14 @@ {:id id}) team)) +(defn get-raw-file + "Get the migrated data of one file." + ([id] (get-raw-file (or *system* main/system) id)) + ([system id] + (db/run! system + (fn [system] + (files/get-file system id :migrate? false))))) + (defn reset-file-data! "Hardcode replace of the data of one file." [system id data] From ea2173bd300594253bba95dd505b8f9eb60ce066 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 14 Feb 2024 11:01:18 +0100 Subject: [PATCH 07/17] :sparkles: Add keep aspect ratio flag to image fills --- common/src/app/common/geom/proportions.cljc | 18 +++++++----- common/src/app/common/types/color.cljc | 3 +- .../src/app/main/data/workspace/media.cljs | 6 ++-- frontend/src/app/main/ui/shapes/fills.cljs | 3 +- frontend/src/app/main/ui/workspace.scss | 1 + .../app/main/ui/workspace/colorpicker.cljs | 29 +++++++++++++++++-- .../app/main/ui/workspace/colorpicker.scss | 5 ++++ .../main/ui/workspace/viewport/widgets.cljs | 16 +++++----- .../main/ui/workspace/viewport/widgets.scss | 6 ++++ frontend/translations/en.po | 3 ++ frontend/translations/es.po | 3 ++ 11 files changed, 71 insertions(+), 22 deletions(-) diff --git a/common/src/app/common/geom/proportions.cljc b/common/src/app/common/geom/proportions.cljc index 8294e4301..d6f37c216 100644 --- a/common/src/app/common/geom/proportions.cljc +++ b/common/src/app/common/geom/proportions.cljc @@ -22,8 +22,8 @@ :proportion (/ width height) :proportion-lock true))) -(defn setup-proportions-svg - [{:keys [width height] :as shape}] +(defn setup-proportions-size + [{{:keys [width height]} :selrect :as shape}] (assoc shape :proportion (/ width height) :proportion-lock true)) @@ -35,9 +35,11 @@ :proportion-lock false)) (defn setup-proportions - [shape] - (case (:type shape) - :svg-raw (setup-proportions-svg shape) - :image (setup-proportions-image shape) - :text shape - (setup-proportions-const shape))) + [{:keys [type] :as shape}] + (let [image-fill? (every? #(some? (:fill-image %)) (:fills shape))] + (cond + (= type :svg-raw) (setup-proportions-size shape) + (= type :image) (setup-proportions-image shape) + image-fill? (setup-proportions-size shape) + (= type :text) shape + :else (setup-proportions-const shape)))) diff --git a/common/src/app/common/types/color.cljc b/common/src/app/common/types/color.cljc index 3a726d77a..382530ac2 100644 --- a/common/src/app/common/types/color.cljc +++ b/common/src/app/common/types/color.cljc @@ -52,7 +52,8 @@ [:width :int] [:height :int] [:mtype {:optional true} [:maybe :string]] - [:id ::sm/uuid]]) + [:id ::sm/uuid] + [:keep-aspect-ratio {:optional true} :boolean]]) (sm/define! ::gradient [:map {:title "Gradient"} diff --git a/frontend/src/app/main/data/workspace/media.cljs b/frontend/src/app/main/data/workspace/media.cljs index c68dfe00a..3dc6c8d7a 100644 --- a/frontend/src/app/main/data/workspace/media.cljs +++ b/frontend/src/app/main/data/workspace/media.cljs @@ -72,7 +72,8 @@ :width width :height height :mtype mtype - :id id}}]}] + :id id + :keep-aspect-ratio true}}]}] (rx/of (dwsh/create-and-add-shape :rect x y shape)))))) (defn svg-uploaded @@ -358,7 +359,8 @@ :id id :width width :height height - :mtype mtype}}] + :mtype mtype + :keep-aspect-ratio true}}] :name name :frame-id (:id frame-shape) :parent-id (:id frame-shape)})] diff --git a/frontend/src/app/main/ui/shapes/fills.cljs b/frontend/src/app/main/ui/shapes/fills.cljs index e4cb1eee3..076a662c0 100644 --- a/frontend/src/app/main/ui/shapes/fills.cljs +++ b/frontend/src/app/main/ui/shapes/fills.cljs @@ -117,9 +117,10 @@ :style style}] (if (:fill-image value) (let [uri (cf/resolve-file-media (:fill-image value)) + keep-ar? (-> value :fill-image :keep-aspect-ratio) image-props #js {:id (dm/str "fill-image-" render-id "-" fill-index) :href (get uris uri uri) - :preserveAspectRatio "xMidYMid slice" + :preserveAspectRatio (if keep-ar? "xMidYMid slice" "none") :width width :height height :key (dm/str fill-index) diff --git a/frontend/src/app/main/ui/workspace.scss b/frontend/src/app/main/ui/workspace.scss index 0c7df3205..0cc517eae 100644 --- a/frontend/src/app/main/ui/workspace.scss +++ b/frontend/src/app/main/ui/workspace.scss @@ -29,6 +29,7 @@ grid-template-areas: "left-sidebar viewport right-sidebar"; grid-template-rows: 1fr; grid-template-columns: auto 1fr auto; + overflow: hidden; .workspace-loader { @include flexCenter; diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index e74f83525..9328a1144 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -84,7 +84,10 @@ on-fill-image-success (mf/use-fn (fn [image] - (st/emit! (dc/update-colorpicker-color {:image (select-keys image [:id :width :height :mtype :name])} (not @drag?))))) + (st/emit! (dc/update-colorpicker-color + {:image (-> (select-keys image [:id :width :height :mtype :name]) + (assoc :keep-aspect-ratio true))} + (not @drag?))))) on-fill-image-click (mf/use-callback #(dom/click (mf/ref-val fill-image-ref))) @@ -94,6 +97,16 @@ (fn [file] (st/emit! (dwm/upload-fill-image file on-fill-image-success)))) + handle-change-keep-aspect-ratio + (mf/use-fn + (mf/deps current-color) + (fn [] + (let [keep-aspect-ratio? (-> current-color :image :keep-aspect-ratio not)] + (st/emit! (dc/update-colorpicker-color + {:image (-> (:image current-color) + (assoc :keep-aspect-ratio keep-aspect-ratio?))} + true))))) + set-tab! (mf/use-fn (fn [event] @@ -248,11 +261,23 @@ :on-select-stop handle-change-stop}]) (if (= selected-mode :image) - (let [uri (cfg/resolve-file-media (:image current-color))] + (let [uri (cfg/resolve-file-media (:image current-color)) + keep-aspect-ratio? (-> current-color :image :keep-aspect-ratio)] [:div {:class (stl/css :select-image)} [:div {:class (stl/css :content)} (when (:image current-color) [:img {:src uri}])] + + [:div {:class (stl/css :checkbox-option)} + [:label {:for "keep-aspect-ratio" + :class (stl/css-case :global/checked keep-aspect-ratio?)} + [:span {:class (stl/css-case :global/checked keep-aspect-ratio?)} + (when keep-aspect-ratio? i/status-tick-refactor)] + (tr "media.keep-aspect-ratio") + [:input {:type "checkbox" + :id "keep-aspect-ratio" + :checked keep-aspect-ratio? + :on-change handle-change-keep-aspect-ratio}]]] [:button {:class (stl/css :choose-image) :title (tr "media.choose-image") diff --git a/frontend/src/app/main/ui/workspace/colorpicker.scss b/frontend/src/app/main/ui/workspace/colorpicker.scss index f3049f387..62a7e5527 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.scss +++ b/frontend/src/app/main/ui/workspace/colorpicker.scss @@ -166,3 +166,8 @@ margin-top: $s-12; height: $s-32; } + +.checkbox-option { + @extend .input-checkbox; + margin: $s-16 0 0 0; +} diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index 316cf6d0b..ab0b10777 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -166,16 +166,16 @@ :y -11 :width (max 0 (- text-width text-pos-x)) :height 20 - :class "workspace-frame-label" + :class (stl/css :workspace-frame-label-wrapper) :style {:fill color} - :visibility (if show-artboard-names? "visible" "hidden") - :on-pointer-down on-pointer-down - :on-double-click on-double-click - :on-context-menu on-context-menu - :on-pointer-enter on-pointer-enter - :on-pointer-leave on-pointer-leave} + :visibility (if show-artboard-names? "visible" "hidden")} [:div {:class (stl/css :workspace-frame-label) - :style {:color color}} + :style {:color color} + :on-pointer-down on-pointer-down + :on-double-click on-double-click + :on-context-menu on-context-menu + :on-pointer-enter on-pointer-enter + :on-pointer-leave on-pointer-leave} (if show-id? (dm/str (dm/str (:id frame)) " - " (:name frame)) (:name frame))]]]))) diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.scss b/frontend/src/app/main/ui/workspace/viewport/widgets.scss index 326057ce1..19d5e467f 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.scss +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.scss @@ -63,10 +63,16 @@ } } +.workspace-frame-label-wrapper { + pointer-events: none; +} + .workspace-frame-label { font-size: $fs-12; color: black; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; + max-width: fit-content; + pointer-events: all; } diff --git a/frontend/translations/en.po b/frontend/translations/en.po index f26593180..be4499c87 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -5074,6 +5074,9 @@ msgstr "Gradient" msgid "media.choose-image" msgstr "Choose image" +msgid "media.keep-aspect-ratio" +msgstr "Keep aspect ratio" + msgid "workspace.options.guides.title" msgstr "Guides" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 4fe0c535e..c121150b3 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -5158,6 +5158,9 @@ msgstr "Gradiente" msgid "media.choose-image" msgstr "Elegir imagen" +msgid "media.keep-aspect-ratio" +msgstr "Mantener la proporción" + msgid "workspace.options.guides.title" msgstr "Guías" From 86b4a9587597f8a7572f2701f8a2927fd01042a0 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 14 Feb 2024 17:37:01 +0100 Subject: [PATCH 08/17] :sparkles: Fix problem when importing zip files --- .../app/main/ui/workspace/colorpicker.cljs | 21 ++++++++++--------- frontend/src/app/worker/import.cljs | 10 +++++++-- frontend/src/app/worker/import/parser.cljs | 19 ++++++++++++----- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index 9328a1144..dbd0da26a 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -268,16 +268,17 @@ (when (:image current-color) [:img {:src uri}])] - [:div {:class (stl/css :checkbox-option)} - [:label {:for "keep-aspect-ratio" - :class (stl/css-case :global/checked keep-aspect-ratio?)} - [:span {:class (stl/css-case :global/checked keep-aspect-ratio?)} - (when keep-aspect-ratio? i/status-tick-refactor)] - (tr "media.keep-aspect-ratio") - [:input {:type "checkbox" - :id "keep-aspect-ratio" - :checked keep-aspect-ratio? - :on-change handle-change-keep-aspect-ratio}]]] + (when (some? (:image current-color)) + [:div {:class (stl/css :checkbox-option)} + [:label {:for "keep-aspect-ratio" + :class (stl/css-case :global/checked keep-aspect-ratio?)} + [:span {:class (stl/css-case :global/checked keep-aspect-ratio?)} + (when keep-aspect-ratio? i/status-tick-refactor)] + (tr "media.keep-aspect-ratio") + [:input {:type "checkbox" + :id "keep-aspect-ratio" + :checked keep-aspect-ratio? + :on-change handle-change-keep-aspect-ratio}]]]) [:button {:class (stl/css :choose-image) :title (tr "media.choose-image") diff --git a/frontend/src/app/worker/import.cljs b/frontend/src/app/worker/import.cljs index f43df1cf2..2130ff414 100644 --- a/frontend/src/app/worker/import.cljs +++ b/frontend/src/app/worker/import.cljs @@ -347,7 +347,12 @@ (->> (upload-media-files context file-id name (:href image-data)) (rx/catch #(do (.error js/console "Error uploading media: " name) (rx/of node))) - (rx/map #(vector (:id image-data) %))))) + (rx/map (fn [data] + (let [data + (cond-> data + (some? (:keep-aspect-ratio image-data)) + (assoc :keep-aspect-ratio (:keep-aspect-ratio image-data)))] + [(:id image-data) data])))))) (rx/reduce (fn [acc [id data]] (assoc acc id data)) {}) (rx/map (fn [images] @@ -360,7 +365,8 @@ (assoc-in [:attrs :penpot:media-width] (:width media)) (assoc-in [:attrs :penpot:media-height] (:height media)) (assoc-in [:attrs :penpot:media-mtype] (:mtype media)) - + (cond-> (some? (:keep-aspect-ratio media)) + (assoc-in [:attrs :penpot:media-keep-aspect-ratio] (:keep-aspect-ratio media))) (assoc-in [:attrs :penpot:fill-color] (:fill image-fill)) (assoc-in [:attrs :penpot:fill-color-ref-file] (:fill-color-ref-file image-fill)) (assoc-in [:attrs :penpot:fill-color-ref-id] (:fill-color-ref-id image-fill)) diff --git a/frontend/src/app/worker/import/parser.cljs b/frontend/src/app/worker/import/parser.cljs index 90ba834af..017a87710 100644 --- a/frontend/src/app/worker/import/parser.cljs +++ b/frontend/src/app/worker/import/parser.cljs @@ -195,15 +195,22 @@ (d/deep-mapm (fn [pair] (->> pair (mapv convert))))))) -(def search-data-node? #{:rect :image :path :circle}) +(def search-data-node? #{:rect :path :circle}) (defn get-svg-data [type node] - (let [node-attrs (add-attrs {} (:attrs node))] (cond (search-data-node? type) - (let [data-tags #{:ellipse :rect :path :text :foreignObject :image}] + (let [data-tags #{:ellipse :rect :path :text :foreignObject}] + (->> node + (node-seq) + (filter #(contains? data-tags (:tag %))) + (map #(:attrs %)) + (reduce add-attrs node-attrs))) + + (= type :image) + (let [data-tags #{:rect :image}] (->> node (node-seq) (filter #(contains? data-tags (:tag %))) @@ -523,7 +530,8 @@ (let [metadata {:id (get-meta node :media-id) :width (get-meta node :media-width) :height (get-meta node :media-height) - :mtype (get-meta node :media-mtype)}] + :mtype (get-meta node :media-mtype) + :keep-aspect-ratio (get-meta node :media-keep-aspect-ratio str->bool)}] (cond-> props (= type :image) (assoc :metadata metadata) @@ -881,7 +889,8 @@ (let [id (get-in fill-node [:attrs :penpot:fill-image-id]) image-node (->> node (node-seq) (find-node-by-id id))] {:id id - :href (get-in image-node [:attrs :href])}))) + :href (get-in image-node [:attrs :href]) + :keep-aspect-ratio (not= (get-in image-node [:attrs :preserveAspectRatio]) "none")}))) (filterv #(some? (:id %)))))) (defn has-fill-images? From 5cbb3f76c73f92ff89092529568a0f61035d40ed Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 9 Feb 2024 09:41:23 +0100 Subject: [PATCH 09/17] :bug: Fix cut/paste component inside a board --- .../data/workspace/libraries_helpers.cljs | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index 9f19e14e6..ada7e31af 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -254,36 +254,39 @@ (prepare-restore-component nil library-data component-id it page (gpt/point 0 0) nil nil nil))) ([changes library-data component-id it page delta old-id parent-id frame-id] - (let [component (ctkl/get-deleted-component library-data component-id) - parent (get-in page [:objects parent-id]) - main-inst (get-in component [:objects (:main-instance-id component)]) + (let [component (ctkl/get-deleted-component library-data component-id) + parent (get-in page [:objects parent-id]) + main-inst (get-in component [:objects (:main-instance-id component)]) inside-component? (some? (ctn/get-instance-root (:objects page) parent)) + origin-frame (get-in page [:objects (:frame-id main-inst)]) + ;; We are using a deleted component andit's coordenates are absolute, we must adjust them to its containing frame to adjust the delta + delta (gpt/subtract delta (-> origin-frame :selrect gpt/point)) + shapes (cfh/get-children-with-self (:objects component) (:main-instance-id component)) + shapes (map #(gsh/move % delta) shapes) - shapes (cfh/get-children-with-self (:objects component) (:main-instance-id component)) - shapes (map #(gsh/move % delta) shapes) - first-shape (cond-> (first shapes) - (not (nil? parent-id)) - (assoc :parent-id parent-id) - (not (nil? frame-id)) - (assoc :frame-id frame-id) - (and (nil? frame-id) parent (= :frame (:type parent))) - (assoc :frame-id parent-id) - (and (nil? frame-id) parent (not= :frame (:type parent))) - (assoc :frame-id (:frame-id parent)) - inside-component? - (dissoc :component-root) - (not inside-component?) - (assoc :component-root true)) + first-shape (cond-> (first shapes) + (not (nil? parent-id)) + (assoc :parent-id parent-id) + (not (nil? frame-id)) + (assoc :frame-id frame-id) + (and (nil? frame-id) parent (= :frame (:type parent))) + (assoc :frame-id parent-id) + (and (nil? frame-id) parent (not= :frame (:type parent))) + (assoc :frame-id (:frame-id parent)) + inside-component? + (dissoc :component-root) + (not inside-component?) + (assoc :component-root true)) - changes (-> (or changes (pcb/empty-changes it)) - (pcb/with-page page) - (pcb/with-objects (:objects page)) - (pcb/with-library-data library-data)) - changes (cond-> (pcb/add-object changes first-shape {:ignore-touched true}) - (some? old-id) (pcb/amend-last-change #(assoc % :old-id old-id))) ; on copy/paste old id is used later to reorder the paster layers - changes (reduce #(pcb/add-object %1 %2 {:ignore-touched true}) - changes - (rest shapes))] + changes (-> (or changes (pcb/empty-changes it)) + (pcb/with-page page) + (pcb/with-objects (:objects page)) + (pcb/with-library-data library-data)) + changes (cond-> (pcb/add-object changes first-shape {:ignore-touched true}) + (some? old-id) (pcb/amend-last-change #(assoc % :old-id old-id))) ; on copy/paste old id is used later to reorder the paster layers + changes (reduce #(pcb/add-object %1 %2 {:ignore-touched true}) + changes + (rest shapes))] {:changes (pcb/restore-component changes component-id (:id page) main-inst) :shape (first shapes)}))) From 9e527e4007fc3ecc402bdfc18da2987e2d0d0fe7 Mon Sep 17 00:00:00 2001 From: Xaviju Date: Wed, 14 Feb 2024 12:08:23 +0100 Subject: [PATCH 10/17] :bug: Fix detach button position --- .../sidebar/options/rows/color_row.cljs | 6 +- .../sidebar/options/rows/color_row.scss | 243 +++++++++--------- 2 files changed, 129 insertions(+), 120 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs index e3e2e874c..ae9be05ad 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs @@ -27,6 +27,10 @@ [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) + +(def ^:private detach-icon + (i/icon-xref :detach-refactor (stl/css :detach-icon))) + (defn opacity->string [opacity] (if (= opacity :multiple) @@ -218,7 +222,7 @@ :on-pointer-enter #(reset! hover-detach true) :on-pointer-leave #(reset! hover-detach false) :on-click detach-value} - i/detach-refactor])] + detach-icon])] ;; Rendering a gradient gradient-color? diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.scss b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.scss index ed7f7bc3a..f91d71b45 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.scss @@ -10,14 +10,16 @@ @include flexRow; &.dnd-over-top { - border-top: $s-1 solid var(--layer-row-foreground-color-drag); + border-block-start: $s-1 solid var(--layer-row-foreground-color-drag); } &.dnd-over-bot { - border-bottom: $s-1 solid var(--layer-row-foreground-color-drag); + border-block-end: $s-1 solid var(--layer-row-foreground-color-drag); } } .color-info { + --detach-icon-foreground-color: none; + display: flex; align-items: center; gap: $s-2; @@ -27,146 +29,149 @@ width: 100%; flex-grow: 1; - .color-name-wrapper { - @extend .input-element; - flex-grow: 1; - width: 100%; - border-radius: $br-8 0 0 $br-8; - padding: 0; - margin-right: 0; - gap: $s-4; - input { - padding: 0; - } - .color-bullet-wrapper { - height: $s-28; - padding: 0 $s-2 0 $s-8; - border-radius: $br-8 0 0 $br-8; + &:hover { + --detach-icon-foreground-color: var(--input-foreground-color-active); + + .detach-btn, + .select-btn { background-color: transparent; - &:hover { - background-color: transparent; - } } - .color-name { - @include titleTipography; - @include textEllipsis; - padding-inline: $s-6; + } +} + +.color-name-wrapper { + @extend .input-element; + flex-grow: 1; + width: 100%; + border-radius: $br-8 0 0 $br-8; + padding: 0; + margin-inline-end: 0; + gap: $s-4; + input { + padding: 0; + } + .color-bullet-wrapper { + height: $s-28; + padding: 0 $s-2 0 $s-8; + border-radius: $br-8 0 0 $br-8; + background-color: transparent; + &:hover { + background-color: transparent; + } + } + .color-name { + @include titleTipography; + @include textEllipsis; + padding-inline: $s-6; + border-radius: $br-8; + color: var(--input-foreground-color-active); + } + .detach-btn { + @extend .button-tertiary; + height: $s-28; + width: $s-28; + margin-inline-start: auto; + border-radius: 0 $br-8 $br-8 0; + display: none; + } + .detach-icon { + @extend .button-icon; + stroke: var(--detach-icon-foreground-color); + } + .color-input-wrapper { + @include titleTipography; + display: flex; + align-items: center; + height: $s-28; + padding: 0 $s-0; + width: 100%; + margin: 0; + flex-grow: 1; + background-color: var(--input-background-color); + color: var(--input-foreground-color); + border-radius: $br-0; + } + &.no-opacity { + border-radius: $br-8; + .color-input-wrapper { border-radius: $br-8; - color: var(--input-foreground-color-active); + } + } + &:hover { + --detach-icon-foreground-color: var(--input-foreground-color-active); + + background-color: var(--input-background-color-hover); + border: $s-1 solid var(--input-border-color-hover); + .color-bullet-wrapper, + .color-name, + .detach-btn, + .color-input-wrapper { + background-color: var(--input-background-color-hover); } .detach-btn { - @extend .button-tertiary; - height: $s-28; - width: $s-28; - border-radius: 0 $br-8 $br-8 0; - display: none; - svg { - @extend .button-icon; - } - } - .color-input-wrapper { - @include titleTipography; display: flex; - align-items: center; - height: $s-28; - padding: 0 $s-0; - width: 100%; - margin: 0; - flex-grow: 1; - background-color: var(--input-background-color); - color: var(--input-foreground-color); - border-radius: $br-0; } - &.no-opacity { - border-radius: $br-8; - .color-input-wrapper { - border-radius: $br-8; - } - } - &:hover { - background-color: var(--input-background-color-hover); - border: $s-1 solid var(--input-border-color-hover); + &.editing { + background-color: var(--input-background-color-active); .color-bullet-wrapper, .color-name, .detach-btn, .color-input-wrapper { - background-color: var(--input-background-color-hover); - } - .detach-btn { - display: flex; - svg { - stroke: var(--input-foreground-color-active); - } - } - &.editing { background-color: var(--input-background-color-active); - .color-bullet-wrapper, - .color-name, - .detach-btn, - .color-input-wrapper { - background-color: var(--input-background-color-active); - } - } - &:focus, - &:focus-within { - background-color: var(--input-background-color-focus); - border: $s-1 solid var(--input-border-color-focus); } } - &:focus, &:focus-within { background-color: var(--input-background-color-focus); border: $s-1 solid var(--input-border-color-focus); - &:hover { - background-color: var(--input-background-color-hover); - border: $s-1 solid var(--input-border-color-focus); - } - } - - &.editing { - background-color: var(--input-background-color-active); - &:hover { - border: $s-1 solid var(--input-border-color-active); - } - } - } - .gradient-name-wrapper { - border-radius: 0 $br-8 $br-8 0; - .color-name { - @include flexRow; - border-radius: 0 $br-8 $br-8 0; - } - } - .library-name-wrapper { - border-radius: $br-8; - } - .opacity-element-wrapper { - @extend .input-element; - width: $s-60; - border-radius: 0 $br-8 $br-8 0; - .opacity-input { - padding: 0; - border-radius: 0 $br-8 $br-8 0; - min-width: $s-28; - } - .icon-text { - @include flexCenter; - height: $s-32; - margin-right: $s-4; - padding-top: $s-2; } } - &:hover { - .detach-btn, - .select-btn { - background-color: transparent; - svg { - stroke: var(--input-foreground-color-active); - } + &:focus, + &:focus-within { + background-color: var(--input-background-color-focus); + border: $s-1 solid var(--input-border-color-focus); + &:hover { + background-color: var(--input-background-color-hover); + border: $s-1 solid var(--input-border-color-focus); } } + + &.editing { + background-color: var(--input-background-color-active); + &:hover { + border: $s-1 solid var(--input-border-color-active); + } + } +} + +.gradient-name-wrapper { + border-radius: 0 $br-8 $br-8 0; + .color-name { + @include flexRow; + border-radius: 0 $br-8 $br-8 0; + } +} + +.library-name-wrapper { + border-radius: $br-8; +} + +.opacity-element-wrapper { + @extend .input-element; + width: $s-60; + border-radius: 0 $br-8 $br-8 0; + .opacity-input { + padding: 0; + border-radius: 0 $br-8 $br-8 0; + min-width: $s-28; + } + .icon-text { + @include flexCenter; + height: $s-32; + margin-inline-end: $s-4; + margin-block-start: $s-2; + } } .remove-btn, From 4acc98749cbc4cf0c1430997757c534ef786626d Mon Sep 17 00:00:00 2001 From: Xaviju Date: Thu, 15 Feb 2024 15:02:14 +0100 Subject: [PATCH 11/17] :bug: Fix ellipsis on color row --- .../sidebar/options/rows/color_row.cljs | 16 ++++++++-------- .../sidebar/options/rows/color_row.scss | 3 +++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs index ae9be05ad..121efb9d7 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs @@ -193,14 +193,14 @@ :dnd-over-top (= (:over dprops) :top) :dnd-over-bot (= (:over dprops) :bot)) :ref dref} - [:span {:class (stl/css :color-info)} - [:span {:class (stl/css-case :color-name-wrapper true - :no-opacity (or disable-opacity - (not opacity?)) - :library-name-wrapper library-color? - :editing editing-text? - :gradient-name-wrapper gradient-color?)} - [:span {:class (stl/css :color-bullet-wrapper)} + [:div {:class (stl/css :color-info)} + [:div {:class (stl/css-case :color-name-wrapper true + :no-opacity (or disable-opacity + (not opacity?)) + :library-name-wrapper library-color? + :editing editing-text? + :gradient-name-wrapper gradient-color?)} + [:div {:class (stl/css :color-bullet-wrapper)} [:& cbn/color-bullet {:color (cond-> color (nil? color-name) (assoc :id nil diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.scss b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.scss index f91d71b45..f02cf1aeb 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.scss @@ -28,6 +28,7 @@ height: $s-32; width: 100%; flex-grow: 1; + min-width: 0; &:hover { --detach-icon-foreground-color: var(--input-foreground-color-active); @@ -55,6 +56,8 @@ padding: 0 $s-2 0 $s-8; border-radius: $br-8 0 0 $br-8; background-color: transparent; + display: flex; + align-items: center; &:hover { background-color: transparent; } From 15cd9432b7e9312b152a6886cd6071f3602a92b4 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 15 Feb 2024 15:38:27 +0100 Subject: [PATCH 12/17] :bug: Fix onboarding dialog is not loaded from profile settings --- frontend/shadow-cljs.edn | 6 -- frontend/src/app/main/ui.cljs | 17 ++--- frontend/src/app/main/ui/onboarding.cljs | 1 - .../src/app/main/ui/onboarding/questions.cljs | 7 +- frontend/src/app/main/ui/releases.cljs | 4 +- .../src/app/main/ui/settings/sidebar.cljs | 72 +++++++++---------- 6 files changed, 46 insertions(+), 61 deletions(-) diff --git a/frontend/shadow-cljs.edn b/frontend/shadow-cljs.edn index 17d0d1bc1..901448197 100644 --- a/frontend/shadow-cljs.edn +++ b/frontend/shadow-cljs.edn @@ -35,12 +35,6 @@ {:entries [app.main.ui.viewer] :depends-on #{:main :main-auth}} - :main-onboarding - {:entries [app.main.ui.onboarding - app.main.ui.onboarding.questions - app.main.ui.releases] - :depends-on #{:main}} - :main-workspace {:entries [app.main.ui.workspace] :depends-on #{:main}} diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs index 68bd5d58a..8d6306075 100644 --- a/frontend/src/app/main/ui.cljs +++ b/frontend/src/app/main/ui.cljs @@ -15,6 +15,9 @@ [app.main.ui.frame-preview :as frame-preview] [app.main.ui.icons :as i] [app.main.ui.messages :as msgs] + [app.main.ui.onboarding :refer [onboarding-modal]] + [app.main.ui.onboarding.questions :refer [questions-modal]] + [app.main.ui.releases :refer [release-notes-modal]] [app.main.ui.static :as static] [app.util.dom :as dom] [app.util.i18n :refer [tr]] @@ -39,15 +42,6 @@ (def workspace-page (mf/lazy-component app.main.ui.workspace/workspace)) -(def questions-modal - (mf/lazy-component app.main.ui.onboarding.questions/questions)) - -(def onboarding-modal - (mf/lazy-component app.main.ui.onboarding/onboarding-modal)) - -(def release-modal - (mf/lazy-component app.main.ui.releases/release-notes-modal)) - (mf/defc on-main-error [{:keys [error] :as props}] (mf/with-effect @@ -55,7 +49,8 @@ [:span "Internal application error"]) (mf/defc main-page - {::mf/wrap [#(mf/catch % {:fallback on-main-error})]} + {::mf/wrap [#(mf/catch % {:fallback on-main-error})] + ::mf/props :obj} [{:keys [route profile]}] (let [{:keys [data params]} route] [:& (mf/provider ctx/current-route) {:value route} @@ -116,7 +111,7 @@ (:onboarding-viewed props) (not= (:release-notes-viewed props) (:main cf/version)) (not= "0.0" (:main cf/version))) - [:& release-modal {:version (:main cf/version)}])) + [:& release-notes-modal {:version (:main cf/version)}])) (when profile [:& dashboard-page {:route route :profile profile}])] diff --git a/frontend/src/app/main/ui/onboarding.cljs b/frontend/src/app/main/ui/onboarding.cljs index b16589df3..00a19a11a 100644 --- a/frontend/src/app/main/ui/onboarding.cljs +++ b/frontend/src/app/main/ui/onboarding.cljs @@ -133,7 +133,6 @@ :data-test "onboarding-next-btn"} (tr "labels.continue")]]]])) - (mf/defc onboarding-modal {::mf/register modal/components ::mf/register-as :onboarding} diff --git a/frontend/src/app/main/ui/onboarding/questions.cljs b/frontend/src/app/main/ui/onboarding/questions.cljs index d324b1699..3d72a1011 100644 --- a/frontend/src/app/main/ui/onboarding/questions.cljs +++ b/frontend/src/app/main/ui/onboarding/questions.cljs @@ -206,8 +206,11 @@ :default "" :name :team-size}]]])) -(mf/defc questions - [{:keys []}] +;; NOTE: we don't register it on registry modal because we reference +;; this modal directly on the ui namespace. + +(mf/defc questions-modal + [] (let [container (mf/use-ref) step (mf/use-state 1) clean-data (mf/use-state {}) diff --git a/frontend/src/app/main/ui/releases.cljs b/frontend/src/app/main/ui/releases.cljs index 084d77dfd..fc01fe294 100644 --- a/frontend/src/app/main/ui/releases.cljs +++ b/frontend/src/app/main/ui/releases.cljs @@ -33,7 +33,7 @@ ;;; --- RELEASE NOTES MODAL (mf/defc release-notes - {::mf/wrap-props false} + {::mf/props :obj} [{:keys [version]}] (let [slide* (mf/use-state :start) slide (deref slide*) @@ -90,4 +90,4 @@ (defmethod rc/render-release-notes "0.0" [params] - (rc/render-release-notes (assoc params :version "1.18"))) + (rc/render-release-notes (assoc params :version "1.19"))) diff --git a/frontend/src/app/main/ui/settings/sidebar.cljs b/frontend/src/app/main/ui/settings/sidebar.cljs index 71cd5bf46..366a0df9a 100644 --- a/frontend/src/app/main/ui/settings/sidebar.cljs +++ b/frontend/src/app/main/ui/settings/sidebar.cljs @@ -20,52 +20,44 @@ [potok.v2.core :as ptk] [rumext.v2 :as mf])) +(def ^:private go-settings-profile + #(st/emit! (rt/nav :settings-profile))) + +(def ^:private go-settings-feedback + #(st/emit! (rt/nav :settings-feedback))) + +(def ^:private go-settings-password + #(st/emit! (rt/nav :settings-password))) + +(def ^:private go-settings-options + #(st/emit! (rt/nav :settings-options))) + +(def ^:private go-settings-access-tokens + #(st/emit! (rt/nav :settings-access-tokens))) + +(defn- show-release-notes + [event] + (let [version (:main cf/version)] + (st/emit! (ptk/event ::ev/event {::ev/name "show-release-notes" :version version})) + + (if (and (kbd/alt? event) (kbd/mod? event)) + (st/emit! (modal/show {:type :onboarding})) + (st/emit! (modal/show {:type :release-notes :version version}))))) + (mf/defc sidebar-content - [{:keys [profile section] :as props}] + {::mf/props :obj} + [{:keys [profile section]}] (let [profile? (= section :settings-profile) password? (= section :settings-password) options? (= section :settings-options) feedback? (= section :settings-feedback) access-tokens? (= section :settings-access-tokens) + team-id (du/get-current-team-id profile) go-dashboard - (mf/use-callback - (mf/deps profile) - #(st/emit! (rt/nav :dashboard-projects {:team-id (du/get-current-team-id profile)}))) - - go-settings-profile - (mf/use-callback - (mf/deps profile) - #(st/emit! (rt/nav :settings-profile))) - - go-settings-feedback - (mf/use-callback - (mf/deps profile) - #(st/emit! (rt/nav :settings-feedback))) - - go-settings-password - (mf/use-callback - (mf/deps profile) - #(st/emit! (rt/nav :settings-password))) - - go-settings-options - (mf/use-callback - (mf/deps profile) - #(st/emit! (rt/nav :settings-options))) - - go-settings-access-tokens - (mf/use-callback - (mf/deps profile) - #(st/emit! (rt/nav :settings-access-tokens))) - - show-release-notes - (mf/use-callback - (fn [event] - (let [version (:main cf/version)] - (st/emit! (ptk/event ::ev/event {::ev/name "show-release-notes" :version version})) - (if (and (kbd/alt? event) (kbd/mod? event)) - (st/emit! (modal/show {:type :onboarding})) - (st/emit! (modal/show {:type :release-notes :version version}))))))] + (mf/use-fn + (mf/deps team-id) + #(st/emit! (rt/nav :dashboard-projects {:team-id team-id})))] [:div {:class (stl/css :sidebar-content)} [:div {:class (stl/css :sidebar-content-section)} @@ -73,6 +65,7 @@ :on-click go-dashboard} [:span {:class (stl/css :icon)} i/arrow-down] [:span {:class (stl/css :text)} (tr "labels.dashboard")]]] + [:hr] [:div {:class (stl/css :sidebar-content-section)} @@ -108,7 +101,8 @@ [:span {:class (stl/css :element-title)} (tr "labels.give-feedback")]])]]])) (mf/defc sidebar - {::mf/wrap [mf/memo]} + {::mf/wrap [mf/memo] + ::mf/props :obj} [{:keys [profile locale section]}] [:div {:class (stl/css :dashboard-sidebar :settings)} [:& sidebar-content {:profile profile From 2bb2d4ca59239a18a66024c346eac3ce1637afa5 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 13 Feb 2024 12:21:54 +0100 Subject: [PATCH 13/17] :bug: Fix problem with align-self default --- .../app/main/ui/components/radio_buttons.cljs | 30 +++++++++++-------- .../sidebar/options/menus/layout_item.cljs | 3 +- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/frontend/src/app/main/ui/components/radio_buttons.cljs b/frontend/src/app/main/ui/components/radio_buttons.cljs index 92563917a..a4366ba2a 100644 --- a/frontend/src/app/main/ui/components/radio_buttons.cljs +++ b/frontend/src/app/main/ui/components/radio_buttons.cljs @@ -17,9 +17,9 @@ (mf/create-context nil)) (mf/defc radio-button - {::mf/wrap-props false} + {::mf/props :obj} [props] - (let [context (mf/use-ctx context) + (let [context (mf/use-ctx context) icon (unchecked-get props "icon") id (unchecked-get props "id") value (unchecked-get props "value") @@ -27,7 +27,10 @@ title (unchecked-get props "title") unique-key (unchecked-get props "unique-key") icon-class (unchecked-get props "icon-class") - type (or (unchecked-get props "type") "radio") + type (or (unchecked-get props "type") + (if (unchecked-get context "allow-empty") + "checkbox" + "radio")) on-change (unchecked-get context "on-change") selected (unchecked-get context "selected") @@ -59,14 +62,15 @@ :checked checked?}]])) (mf/defc radio-buttons - {::mf/wrap-props false} + {::mf/props :obj} [props] - (let [children (unchecked-get props "children") - on-change (unchecked-get props "on-change") - selected (unchecked-get props "selected") - name (unchecked-get props "name") - class (unchecked-get props "class") - wide (unchecked-get props "wide") + (let [children (unchecked-get props "children") + on-change (unchecked-get props "on-change") + selected (unchecked-get props "selected") + name (unchecked-get props "name") + class (unchecked-get props "class") + wide (unchecked-get props "wide") + allow-empty? (unchecked-get props "allow-empty") encode-fn (d/nilv (unchecked-get props "encode-fn") identity) decode-fn (d/nilv (unchecked-get props "encode-fn") identity) @@ -87,7 +91,8 @@ (mf/deps on-change) (fn [event] (let [input-node (dom/get-target event) - value (dom/get-target-val event)] + value (dom/get-target-val event) + value (when (not= value selected) value)] (when (fn? on-change) (do (on-change (decode-fn value) event) (dom/blur! input-node)))))) @@ -98,7 +103,8 @@ :on-change on-change' :name name :encode-fn encode-fn - :decode-fn decode-fn})] + :decode-fn decode-fn + :allow-empty allow-empty?})] [:& (mf/provider context) {:value context-value} [:div {:class (dm/str class " " (stl/css :radio-btn-wrapper)) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs index 8ea0346d3..6929eb505 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_item.cljs @@ -230,7 +230,8 @@ [{:keys [is-col? align-self on-change] :as props}] [:& radio-buttons {:selected (d/name align-self) :on-change on-change - :name "flex-align-self"} + :name "flex-align-self" + :allow-empty true} [:& radio-button {:value "start" :icon (get-layout-flex-icon :align-self :start is-col?) :title "Align self start" From 4ece2ba14890c7e0736350234e19375c838e9ce3 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 13 Feb 2024 12:22:05 +0100 Subject: [PATCH 14/17] :bug: Fix problem with calculated margins in flex layout --- common/src/app/common/geom/shapes/flex_layout/params.cljc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/app/common/geom/shapes/flex_layout/params.cljc b/common/src/app/common/geom/shapes/flex_layout/params.cljc index 7bd1ce855..b1e15c70b 100644 --- a/common/src/app/common/geom/shapes/flex_layout/params.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/params.cljc @@ -88,8 +88,8 @@ parent-selrect (:selrect parent) padding (when (and (not (nil? parent)) (> (count shapes) 0)) - {:p1 (min (- min-y (:y1 parent-selrect)) (- (:y2 parent-selrect) max-y)) - :p2 (min (- min-x (:x1 parent-selrect)) (- (:x2 parent-selrect) max-x))})] + {:p1 (- min-y (:y1 parent-selrect)) + :p2 (- min-x (:x1 parent-selrect))})] (cond-> {:layout-flex-dir direction :layout-gap layout-gap} (not (nil? padding)) From 4c9174969f22be8db8461b809fff2bc17e5f5a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Wed, 14 Feb 2024 16:48:00 +0100 Subject: [PATCH 15/17] :bug: Fix collapsable palette position --- .../src/app/main/ui/workspace/palette.scss | 109 +++++++++--------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/palette.scss b/frontend/src/app/main/ui/workspace/palette.scss index 995d886a0..70f0639e0 100644 --- a/frontend/src/app/main/ui/workspace/palette.scss +++ b/frontend/src/app/main/ui/workspace/palette.scss @@ -39,10 +39,7 @@ &.wide { width: 100%; } - &.mid-palette, - &.small-palette { - grid-template-columns: $s-64 auto 1fr; - } + .resize-area { grid-area: resize; height: $s-8; @@ -108,56 +105,62 @@ width: 100%; min-width: 0; } - .handler { - @include buttonStyle; - @include flexCenter; - width: $s-12; +} + +.handler { + @include buttonStyle; + @include flexCenter; + width: $s-12; + height: 100%; + .handler-btn { + width: $s-4; height: 100%; - .handler-btn { - width: $s-4; - height: 100%; - max-height: $s-40; - margin: $s-8 $s-4; - padding: 0; - border-radius: $s-4; - background-color: var(--palette-handler-background-color); - } - } - &.hidden-bts { - right: 10px; - z-index: 1; - width: 22px; - grid-template-columns: $s-8 auto 1fr; + max-height: $s-40; + margin: $s-8 $s-4; padding: 0; - &.small-palette, - &.mid-palette { - right: 10px; - } - .palette-btn-list { - opacity: $op-0; - visibility: hidden; - width: 0; - .palette-item { - opacity: $op-0; - visibility: hidden; - z-index: 0; - } - } - .resize-area { - visibility: hidden; - z-index: 0; - width: 0; - } - .palette-actions { - visibility: hidden; - z-index: 0; - } - .palette { - visibility: hidden; - z-index: 0; - } - .handler { - padding-bottom: $s-8; - } + border-radius: $s-4; + background-color: var(--palette-handler-background-color); + } +} + +.mid-palette, +.small-palette { + grid-template-columns: $s-64 auto 1fr; +} + +.hidden-bts { + right: $s-2; + z-index: $z-index-1; + width: 22px; + grid-template-columns: $s-8 auto 1fr; + padding: 0; + border-inline-start: 0; + border-start-start-radius: 0; + border-end-start-radius: 0; + .palette-btn-list { + opacity: $op-0; + visibility: hidden; + width: 0; + .palette-item { + opacity: $op-0; + visibility: hidden; + z-index: 0; + } + } + .resize-area { + visibility: hidden; + z-index: 0; + width: 0; + } + .palette-actions { + visibility: hidden; + z-index: 0; + } + .palette { + visibility: hidden; + z-index: 0; + } + .handler { + padding-bottom: $s-8; } } From 261dc553bb67e11ad23dac347d3e87281954ad38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Wed, 14 Feb 2024 16:59:14 +0100 Subject: [PATCH 16/17] :bug: Fix collapsed toolbar position --- .../app/main/ui/workspace/top_toolbar.cljs | 2 +- .../app/main/ui/workspace/top_toolbar.scss | 25 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/top_toolbar.cljs b/frontend/src/app/main/ui/workspace/top_toolbar.cljs index 86f3484df..2c20e9c25 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.cljs +++ b/frontend/src/app/main/ui/workspace/top_toolbar.cljs @@ -108,7 +108,7 @@ (when-not ^boolean read-only? [:aside {:class (stl/css-case :main-toolbar true :not-rulers-present (not rulers?) - :hidden-toolbar hide-toolbar?)} + :main-toolbar-hidden hide-toolbar?)} [:ul {:class (stl/css :main-toolbar-options)} [:li [:button diff --git a/frontend/src/app/main/ui/workspace/top_toolbar.scss b/frontend/src/app/main/ui/workspace/top_toolbar.scss index 993953c89..aec2d2f6b 100644 --- a/frontend/src/app/main/ui/workspace/top_toolbar.scss +++ b/frontend/src/app/main/ui/workspace/top_toolbar.scss @@ -9,7 +9,6 @@ .main-toolbar { cursor: initial; position: absolute; - top: $s-28; left: calc(50% - $s-160); display: flex; align-items: center; @@ -24,6 +23,20 @@ top 0.3s, height 0.3s, opacity 0.3s; + &:not(.main-toolbar-hidden) { + top: $s-28; + } +} + +.main-toolbar-hidden { + top: $s-24; + height: $s-16; + z-index: $z-index-1; + border-radius: 0 0 $s-8 $s-8; + border-block-start: 0; + .main-toolbar-options { + opacity: $op-0; + } } .main-toolbar-options { @@ -76,16 +89,6 @@ } } -.main-toolbar.hidden-toolbar { - top: $s-20; - height: $s-16; - z-index: $z-index-1; - border-radius: 0 0 $s-8 $s-8; - .main-toolbar-options { - opacity: $op-0; - } -} - .main-toolbar.not-rulers-present { top: $s-8; &.hidden-toolbar { From 415ce339a755e9bdc277e4655ffe98f250e8266e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Thu, 15 Feb 2024 16:10:09 +0100 Subject: [PATCH 17/17] :bug: Fix cropped text for typographies in the small palette --- frontend/src/app/main/ui/workspace/text_palette.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/text_palette.scss b/frontend/src/app/main/ui/workspace/text_palette.scss index faee2df1b..43bbe062b 100644 --- a/frontend/src/app/main/ui/workspace/text_palette.scss +++ b/frontend/src/app/main/ui/workspace/text_palette.scss @@ -124,9 +124,6 @@ } } &.small-item { - .typography-name { - height: $s-12; - } .typography-data, .typography-font { display: none;