From 481d1ec53a48e418f4ae4f4d83a4096388641eb5 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 16 Jun 2025 12:20:40 +0200 Subject: [PATCH] :sparkles: Normalize layout schemas --- .../src/app/common/files/shapes_helpers.cljc | 8 +- common/src/app/common/types/shape.cljc | 44 ++---- common/src/app/common/types/shape/layout.cljc | 127 ++++++++---------- 3 files changed, 73 insertions(+), 106 deletions(-) diff --git a/common/src/app/common/files/shapes_helpers.cljc b/common/src/app/common/files/shapes_helpers.cljc index fa1ba12bd0..a6421f9405 100644 --- a/common/src/app/common/files/shapes_helpers.cljc +++ b/common/src/app/common/files/shapes_helpers.cljc @@ -91,10 +91,10 @@ parent-id (or parent-id (get selected-obj :parent-id)) base-parent (get objects parent-id) - layout-props + layout-attrs (when (and (= 1 (count selected)) (ctl/any-layout? base-parent)) - (select-keys selected-obj ctl/layout-item-props)) + (select-keys selected-obj ctl/layout-child-attrs)) target-cell-id (if (and (nil? target-cell-id) @@ -129,8 +129,8 @@ :parent-id parent-id :shapes (into [] selected)) - (some? layout-props) - (d/patch-object layout-props) + (some? layout-attrs) + (d/patch-object layout-attrs) ;; Frames from shapes will not be displayed in viewer and no clipped (or (not= frame-id uuid/zero) without-fill?) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index aac6b018e8..ed0ba5ae3a 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -313,7 +313,7 @@ :title "Shape"} [:group [:merge {:title "GroupShape"} - ctsl/schema:layout-attrs + ctsl/schema:layout-child-attrs schema:group-attrs schema:shape-generic-attrs schema:shape-geom-attrs @@ -321,8 +321,8 @@ [:frame [:merge {:title "FrameShape"} + ctsl/schema:layout-child-attrs ctsl/schema:layout-attrs - ::ctsl/layout-attrs schema:frame-attrs schema:shape-generic-attrs schema:shape-geom-attrs @@ -332,14 +332,14 @@ [:bool [:merge {:title "BoolShape"} - ctsl/schema:layout-attrs + ctsl/schema:layout-child-attrs schema:bool-attrs schema:shape-generic-attrs schema:shape-base-attrs]] [:rect [:merge {:title "RectShape"} - ctsl/schema:layout-attrs + ctsl/schema:layout-child-attrs schema:rect-attrs schema:shape-generic-attrs schema:shape-geom-attrs @@ -347,7 +347,7 @@ [:circle [:merge {:title "CircleShape"} - ctsl/schema:layout-attrs + ctsl/schema:layout-child-attrs schema:circle-attrs schema:shape-generic-attrs schema:shape-geom-attrs @@ -355,7 +355,7 @@ [:image [:merge {:title "ImageShape"} - ctsl/schema:layout-attrs + ctsl/schema:layout-child-attrs schema:image-attrs schema:shape-generic-attrs schema:shape-geom-attrs @@ -363,7 +363,7 @@ [:svg-raw [:merge {:title "SvgRawShape"} - ctsl/schema:layout-attrs + ctsl/schema:layout-child-attrs schema:svg-raw-attrs schema:shape-generic-attrs schema:shape-geom-attrs @@ -371,14 +371,14 @@ [:path [:merge {:title "PathShape"} - ctsl/schema:layout-attrs + ctsl/schema:layout-child-attrs schema:path-attrs schema:shape-generic-attrs schema:shape-base-attrs]] [:text [:merge {:title "TextShape"} - ctsl/schema:layout-attrs + ctsl/schema:layout-child-attrs schema:text-attrs schema:shape-generic-attrs schema:shape-geom-attrs @@ -682,23 +682,6 @@ :r3 :r4}) -(def ^:private layout-extract-props - #{:layout - :layout-flex-dir - :layout-gap-type - :layout-gap - :layout-wrap-type - :layout-align-items - :layout-align-content - :layout-justify-items - :layout-justify-content - :layout-padding-type - :layout-padding - :layout-grid-dir - :layout-grid-rows - :layout-grid-columns - :layout-grid-cells}) - (defn extract-props "Retrieves an object with the 'pasteable' properties for a shape." [shape] @@ -729,9 +712,8 @@ (assoc-props node txt/text-node-attrs))) props))) - (extract-layout-props - [props shape] - (d/patch-object props (select-keys shape layout-extract-props)))] + (extract-layout-attrs [props shape] + (d/patch-object props (select-keys shape ctsl/layout-attrs)))] (let [;; For texts we don't extract the fill extract-props @@ -739,7 +721,7 @@ (-> shape (select-keys extract-props) (cond-> (cfh/text-shape? shape) (extract-text-props shape)) - (cond-> (ctsl/any-layout? shape) (extract-layout-props shape)))))) + (cond-> (ctsl/any-layout? shape) (extract-layout-attrs shape)))))) (defn patch-props "Given the object of `extract-props` applies it to a shape. Adapt the shape if necesary" @@ -764,7 +746,7 @@ (d/patch-object (select-keys props txt/text-node-attrs)))))))))) (patch-layout-props [shape props] - (let [shape (d/patch-object shape (select-keys props layout-extract-props))] + (let [shape (d/patch-object shape (select-keys props ctsl/layout-attrs))] (cond-> shape (ctsl/grid-layout? shape) (ctsl/assign-cells objects))))] diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index e66016502f..10051ee759 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -43,7 +43,6 @@ ;; :layout-item-absolute ;; boolean ;; :layout-item-z-index ;; int - (def layout-types #{:flex :grid}) @@ -74,49 +73,6 @@ (def justify-items-types #{:start :end :center :stretch}) -(def layout-item-props - [:layout-item-margin - :layout-item-margin-type - :layout-item-h-sizing - :layout-item-v-sizing - :layout-item-max-h - :layout-item-min-h - :layout-item-max-w - :layout-item-min-w - :layout-item-absolute - :layout-item-z-index]) - -(sm/register! - ^{::sm/type ::layout-attrs} - [:map {:title "LayoutAttrs"} - [:layout {:optional true} [::sm/one-of layout-types]] - [:layout-flex-dir {:optional true} [::sm/one-of flex-direction-types]] - [:layout-gap {:optional true} - [:map - [:row-gap {:optional true} ::sm/safe-number] - [:column-gap {:optional true} ::sm/safe-number]]] - [:layout-gap-type {:optional true} [::sm/one-of gap-types]] - [:layout-wrap-type {:optional true} [::sm/one-of wrap-types]] - [:layout-padding-type {:optional true} [::sm/one-of padding-type]] - [:layout-padding {:optional true} - [:map - [:p1 ::sm/safe-number] - [:p2 ::sm/safe-number] - [:p3 ::sm/safe-number] - [:p4 ::sm/safe-number]]] - [:layout-justify-content {:optional true} [::sm/one-of justify-content-types]] - [:layout-justify-items {:optional true} [::sm/one-of justify-items-types]] - [:layout-align-content {:optional true} [::sm/one-of align-content-types]] - [:layout-align-items {:optional true} [::sm/one-of align-items-types]] - - [:layout-grid-dir {:optional true} [::sm/one-of grid-direction-types]] - [:layout-grid-rows {:optional true} - [:vector {:gen/max 2} ::grid-track]] - [:layout-grid-columns {:optional true} - [:vector {:gen/max 2} ::grid-track]] - [:layout-grid-cells {:optional true} - [:map-of {:gen/max 5} ::sm/uuid ::grid-cell]]]) - ;; Grid types (def grid-track-types #{:percent :flex :auto :fixed}) @@ -130,29 +86,59 @@ (def grid-cell-justify-self-types #{:auto :start :center :end :stretch}) -(sm/register! - ^{::sm/type ::grid-cell} - [:map {:title "GridCell"} - [:id ::sm/uuid] - [:area-name {:optional true} :string] - [:row ::sm/safe-int] - [:row-span ::sm/safe-int] - [:column ::sm/safe-int] - [:column-span ::sm/safe-int] - [:position {:optional true} [::sm/one-of grid-position-types]] - [:align-self {:optional true} [::sm/one-of grid-cell-align-self-types]] - [:justify-self {:optional true} [::sm/one-of grid-cell-justify-self-types]] - [:shapes - [:vector {:gen/max 1} ::sm/uuid]]]) +(def ^:private schema:grid-cell + [:map {:title "GridCell"} + [:id ::sm/uuid] + [:area-name {:optional true} :string] + [:row ::sm/safe-int] + [:row-span ::sm/safe-int] + [:column ::sm/safe-int] + [:column-span ::sm/safe-int] + [:position {:optional true} [::sm/one-of grid-position-types]] + [:align-self {:optional true} [::sm/one-of grid-cell-align-self-types]] + [:justify-self {:optional true} [::sm/one-of grid-cell-justify-self-types]] + [:shapes + [:vector {:gen/max 1} ::sm/uuid]]]) -(sm/register! - ^{::sm/type ::grid-track} - [:map {:title "GridTrack"} - [:type [::sm/one-of grid-track-types]] - [:value {:optional true} [:maybe ::sm/safe-number]]]) +(def ^:private schema:grid-track + [:map {:title "GridTrack"} + [:type [::sm/one-of grid-track-types]] + [:value {:optional true} [:maybe ::sm/safe-number]]]) -(def check-grid-track! - (sm/check-fn ::grid-track)) +(def schema:layout-attrs + [:map {:title "LayoutAttrs"} + [:layout {:optional true} [::sm/one-of layout-types]] + [:layout-flex-dir {:optional true} [::sm/one-of flex-direction-types]] + [:layout-gap {:optional true} + [:map + [:row-gap {:optional true} ::sm/safe-number] + [:column-gap {:optional true} ::sm/safe-number]]] + [:layout-gap-type {:optional true} [::sm/one-of gap-types]] + [:layout-wrap-type {:optional true} [::sm/one-of wrap-types]] + [:layout-padding-type {:optional true} [::sm/one-of padding-type]] + [:layout-padding {:optional true} + [:map + [:p1 ::sm/safe-number] + [:p2 ::sm/safe-number] + [:p3 ::sm/safe-number] + [:p4 ::sm/safe-number]]] + [:layout-justify-content {:optional true} [::sm/one-of justify-content-types]] + [:layout-justify-items {:optional true} [::sm/one-of justify-items-types]] + [:layout-align-content {:optional true} [::sm/one-of align-content-types]] + [:layout-align-items {:optional true} [::sm/one-of align-items-types]] + [:layout-grid-dir {:optional true} [::sm/one-of grid-direction-types]] + [:layout-grid-rows {:optional true} + [:vector {:gen/max 2} schema:grid-track]] + [:layout-grid-columns {:optional true} + [:vector {:gen/max 2} schema:grid-track]] + [:layout-grid-cells {:optional true} + [:map-of {:gen/max 5} ::sm/uuid schema:grid-cell]]]) + +(def ^:private check-grid-track + (sm/check-fn schema:grid-track)) + +(def layout-attrs + (sm/keys schema:layout-attrs)) ;; LAYOUT CHILDREN @@ -168,7 +154,7 @@ (def item-align-self-types #{:start :end :center :stretch}) -(def schema:layout-attrs +(def schema:layout-child-attrs [:map {:title "LayoutChildAttrs"} [:layout-item-margin-type {:optional true} [::sm/one-of item-margin-types]] [:layout-item-margin {:optional true} @@ -187,6 +173,9 @@ [:layout-item-absolute {:optional true} :boolean] [:layout-item-z-index {:optional true} ::sm/safe-number]]) +(def layout-child-attrs + (sm/keys schema:layout-child-attrs)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SCHEMAS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -194,8 +183,6 @@ (def valid-layouts #{:flex :grid}) -(sm/register! ::layout [::sm/one-of valid-layouts]) - (defn flex-layout? ([objects id] (flex-layout? (get objects id))) @@ -754,9 +741,7 @@ ([type parent value] (add-grid-track type parent value nil)) ([type parent value index] - (dm/assert! - "expected a valid grid definition for `value`" - (check-grid-track! value)) + (assert (check-grid-track value)) (let [[tracks-prop tracks-prop-other prop prop-other prop-span prop-span-other] (if (= type :column)