From 593966a30a8a97b163b8742f701d165955291523 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 20 Feb 2024 19:49:35 +0100 Subject: [PATCH 01/10] :zap: Add incremental performance enhacements to layout-containers (part 1) --- .../options/menus/layout_container.cljs | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index ce4ecc472..928f2ca20 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -1041,11 +1041,13 @@ saved-grid-dir (:layout-grid-dir values) set-direction - (fn [dir] - (let [dir (keyword dir)] - (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))) + (mf/use-fn + (mf/deps ids) + (fn [dir] + (let [dir (keyword dir)] + (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))) - set-gap + on-gap-change (fn [gap-multiple? type val] (if gap-multiple? (st/emit! (dwsl/update-layout ids {:layout-gap {:row-gap val :column-gap val}})) @@ -1053,8 +1055,10 @@ ;; Padding change-padding-type - (fn [type] - (st/emit! (dwsl/update-layout ids {:layout-padding-type type}))) + (mf/use-fn + (mf/deps ids) + (fn [type] + (st/emit! (dwsl/update-layout ids {:layout-padding-type type})))) on-padding-change (fn [type prop val] @@ -1095,20 +1099,17 @@ (st/emit! (dwsl/update-layout ids {:layout-justify-content value})) (st/emit! (dwsl/update-layout ids {:layout-align-content value})))))) - ;;Grid columns - column-grid-values (:layout-grid-columns values) - grid-columns-open? (mf/use-state false) - toggle-columns-info (mf/use-fn - (fn [_] - (swap! grid-columns-open? not))) + columns-open? (mf/use-state false) + rows-open? (mf/use-state false) - ;; Grid rows / columns - rows-grid-values (:layout-grid-rows values) - grid-rows-open? (mf/use-state false) - toggle-rows-info - (mf/use-fn - (fn [_] - (swap! grid-rows-open? not))) + column-values (:layout-grid-columns values) + rows-values (:layout-grid-rows values) + + toggle-columns-open + (mf/use-fn #(swap! columns-open? not)) + + toggle-rows-open + (mf/use-fn #(swap! rows-open? not)) add-new-element (mf/use-fn @@ -1214,9 +1215,9 @@ [:div {:class (stl/css :row :grid-tracks-row)} [:& grid-columns-row {:is-col? true - :expanded? @grid-columns-open? - :toggle toggle-columns-info - :column-values column-grid-values + :expanded? @columns-open? + :toggle toggle-columns-open + :column-values column-values :add-new-element add-new-element :set-column-value set-column-value :set-column-type set-column-type @@ -1226,9 +1227,9 @@ :on-select-track handle-select-track}] [:& grid-columns-row {:is-col? false - :expanded? @grid-rows-open? - :toggle toggle-rows-info - :column-values rows-grid-values + :expanded? @rows-open? + :toggle toggle-rows-open + :column-values rows-values :add-new-element add-new-element :set-column-value set-column-value :set-column-type set-column-type From 32ae1bcdc86c3e6793fa6f35747180d0f8bb1a69 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 20 Feb 2024 20:13:35 +0100 Subject: [PATCH 02/10] :bug: Add missing key prop on grid editor element --- frontend/src/app/main/ui/workspace/viewport.cljs | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 58e5548c8..0894f0b84 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -632,6 +632,7 @@ (not= @hover-top-frame-id (:id frame))) [:& grid-layout/editor {:zoom zoom + :key (dm/str (:id frame)) :objects base-objects :modifiers modifiers :shape frame From 35f3c6e90f994ce72e5d3b1bf1104712b100f511 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 20 Feb 2024 20:14:06 +0100 Subject: [PATCH 03/10] :lipstick: Add cosmetic changes to grid layout editor react components --- .../viewport/grid_layout_editor.cljs | 83 +++++++++---------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs index 62ab5a1cb..7f9a1af28 100644 --- a/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/grid_layout_editor.cljs @@ -113,7 +113,7 @@ (+ (:y start-p) (/ 9 zoom))]) handle-click - (mf/use-callback + (mf/use-fn (mf/deps on-click) #(when on-click (on-click)))] @@ -142,7 +142,7 @@ current-pos-ref (mf/use-ref nil) handle-pointer-down - (mf/use-callback + (mf/use-fn (mf/deps on-drag-start) (fn [event] (let [raw-pt (dom/get-client-position event) @@ -154,7 +154,7 @@ (when on-drag-start (on-drag-start event position))))) handle-lost-pointer-capture - (mf/use-callback + (mf/use-fn (mf/deps on-drag-end) (fn [event] (let [raw-pt (mf/ref-val current-pos-ref) @@ -165,7 +165,7 @@ (when on-drag-end (on-drag-end event position))))) handle-pointer-move - (mf/use-callback + (mf/use-fn (mf/deps on-drag-delta on-drag-position) (fn [event] (when (mf/ref-val dragging-ref) @@ -198,7 +198,7 @@ layout-data (unchecked-get props "layout-data") handle-drag-position - (mf/use-callback + (mf/use-fn (mf/deps shape row column row-span column-span) (fn [_ position] (let [[drag-row drag-column] (gsg/get-position-grid-coord layout-data position) @@ -235,7 +235,7 @@ (st/emit! (dwm/set-modifiers (dwm/create-modif-tree [(:id shape)] modifiers)))))) handle-drag-end - (mf/use-callback + (mf/use-fn (fn [] (st/emit! (dwm/apply-modifiers)))) @@ -291,17 +291,10 @@ text]])) (mf/defc grid-cell - {::mf/wrap [#(mf/memo' % (mf/check-props ["shape" "cell" "layout-data" "zoom" "hover?" "selected?"]))] - ::mf/wrap-props false} - [props] - (let [shape (unchecked-get props "shape") - cell (unchecked-get props "cell") - layout-data (unchecked-get props "layout-data") - zoom (unchecked-get props "zoom") - hover? (unchecked-get props "hover?") - selected? (unchecked-get props "selected?") - - cell-bounds (gsg/cell-bounds layout-data cell) + {::mf/memo #{:shape :cell :layout-data :zoom :hover? :selected?} + ::mf/props :obj} + [{:keys [shape cell layout-data zoom hover? selected?]}] + (let [cell-bounds (gsg/cell-bounds layout-data cell) cell-origin (gpo/origin cell-bounds) cell-width (gpo/width-points cell-bounds) cell-height (gpo/height-points cell-bounds) @@ -309,19 +302,19 @@ cell-origin (gpt/transform cell-origin (gmt/transform-in cell-center (:transform-inverse shape))) handle-pointer-enter - (mf/use-callback + (mf/use-fn (mf/deps (:id shape) (:id cell)) (fn [] (st/emit! (dwge/hover-grid-cell (:id shape) (:id cell) true)))) handle-pointer-leave - (mf/use-callback + (mf/use-fn (mf/deps (:id shape) (:id cell)) (fn [] (st/emit! (dwge/hover-grid-cell (:id shape) (:id cell) false)))) handle-pointer-down - (mf/use-callback + (mf/use-fn (mf/deps (:id shape) (:id cell) selected?) (fn [event] (when (dom/left-mouse? event) @@ -339,7 +332,7 @@ (st/emit! (dwge/set-selection (:id shape) (:id cell))))))) handle-context-menu - (mf/use-callback + (mf/use-fn (mf/deps (:id shape) (:id cell) selected?) (fn [event] (dom/prevent-default event) @@ -424,7 +417,7 @@ start-size-after (mf/use-var nil) handle-drag-start - (mf/use-callback + (mf/use-fn (mf/deps shape track-before track-after) (fn [] (reset! start-size-before (:size track-before)) @@ -444,7 +437,7 @@ (st/emit! (dwm/set-modifiers (dwm/create-modif-tree [(:id shape)] modifiers)))))) handle-drag-position - (mf/use-callback + (mf/use-fn (mf/deps shape track-before track-after) (fn [_ position] (let [[tracks-prop axis] @@ -469,7 +462,7 @@ (st/emit! (dwm/set-modifiers (dwm/create-modif-tree [(:id shape)] modifiers)))))) handle-drag-end - (mf/use-callback + (mf/use-fn (mf/deps track-before track-after) (fn [] (reset! start-size-before nil) @@ -732,7 +725,7 @@ text-p (if (= type :column) hpt vpt) handle-blur-track-input - (mf/use-callback + (mf/use-fn (mf/deps (:id shape)) (fn [event] (let [target (-> event dom/get-target) @@ -760,7 +753,7 @@ (obj/set! target "value" (dom/get-attribute target "data-default-value")))))) handle-keydown-track-input - (mf/use-callback + (mf/use-fn (fn [event] (let [enter? (kbd/enter? event) esc? (kbd/esc? event)] @@ -770,13 +763,13 @@ (dom/blur! (dom/get-target event)))))) handle-pointer-enter - (mf/use-callback + (mf/use-fn (mf/deps (:id shape) type index) (fn [] (st/emit! (dwsl/hover-layout-track [(:id shape)] type index true)))) handle-pointer-leave - (mf/use-callback + (mf/use-fn (mf/deps (:id shape) type index) (fn [] (st/emit! (dwsl/hover-layout-track [(:id shape)] type index false)))) @@ -788,25 +781,25 @@ [(- (:x text-p) (max 0 (:size track-data))) (- (:y text-p) (/ 36 zoom)) (max 0 (:size track-data)) (/ 36 zoom)]) handle-drag-start - (mf/use-callback + (mf/use-fn (mf/deps on-start-reorder-track type index) (fn [] (on-start-reorder-track type index))) handle-drag-end - (mf/use-callback + (mf/use-fn (mf/deps on-end-reorder-track type index) (fn [event position] (on-end-reorder-track type index position (not (kbd/mod? event))))) handle-drag-position - (mf/use-callback + (mf/use-fn (mf/deps on-move-reorder-track type index) (fn [_ position] (on-move-reorder-track type index position))) handle-show-track-menu - (mf/use-callback + (mf/use-fn (fn [event] (dom/stop-propagation event) (dom/prevent-default event) @@ -895,10 +888,9 @@ :zoom zoom}]])) (mf/defc editor - {::mf/wrap [mf/memo] - ::mf/wrap-props false} + {::mf/memo true + ::mf/props :obj} [props] - (let [base-shape (unchecked-get props "shape") objects (unchecked-get props "objects") modifiers (unchecked-get props "modifiers") @@ -962,31 +954,30 @@ height (max (gpo/height-points bounds) (+ row-total-size row-total-gap (ctl/v-padding shape))) handle-pointer-down - (mf/use-callback + (mf/use-fn (fn [event] (let [left-click? (= 1 (.-which (.-nativeEvent event)))] (when left-click? (dom/stop-propagation event))))) handle-add-column - (mf/use-callback + (mf/use-fn (mf/deps (:id shape)) (fn [] (st/emit! (st/emit! (dwsl/add-layout-track [(:id shape)] :column ctl/default-track-value))))) handle-add-row - (mf/use-callback + (mf/use-fn (mf/deps (:id shape)) (fn [] (st/emit! (st/emit! (dwsl/add-layout-track [(:id shape)] :row ctl/default-track-value))))) - target-tracks* (mf/use-ref nil) drop-track-type* (mf/use-state nil) drop-track-target* (mf/use-state nil) handle-start-reorder-track - (mf/use-callback + (mf/use-fn (mf/deps layout-data) (fn [type _from-idx] ;; Initialize target-tracks @@ -1014,7 +1005,7 @@ (reset! drop-track-type* type)))) handle-move-reorder-track - (mf/use-callback + (mf/use-fn (fn [_type _from-idx position] (let [index (->> (mf/ref-val target-tracks*) @@ -1025,7 +1016,7 @@ (reset! drop-track-target* index))))) handle-end-reorder-track - (mf/use-callback + (mf/use-fn (mf/deps base-shape @drop-track-target*) (fn [type from-index _position move-content?] (when-let [to-index @drop-track-target*] @@ -1041,9 +1032,8 @@ (reset! drop-track-type* nil) (reset! drop-track-target* nil)))] - (mf/use-effect - (fn [] - #(st/emit! (dwge/stop-grid-layout-editing (:id shape))))) + (mf/with-effect [] + #(st/emit! (dwge/stop-grid-layout-editing (:id shape)))) (when (and (not (:hidden shape)) (not (:blocked shape))) [:g.grid-editor {:pointer-events (when view-only "none") @@ -1057,7 +1047,8 @@ :zoom zoom :hover? (contains? hover-cells (:id cell)) :selected? (contains? selected-cells (:id cell))}])] - (when-not view-only + + (when-not ^boolean view-only [:* [:& grid-editor-frame {:zoom zoom :bounds bounds From 897968939de7d51a158363ae7edc1ae9cbf32269 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 20 Feb 2024 23:49:00 +0100 Subject: [PATCH 04/10] :zap: Add performance enhacenements to layout-container menu (part 2) Refactor and improve performance of padding related react components --- .../options/menus/layout_container.cljs | 326 +++++++++++------- 1 file changed, 198 insertions(+), 128 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index 928f2ca20..c835634fa 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -284,141 +284,211 @@ :title "Justify content space-evenly" :id "justify-content-space-evenly"}]]) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PADDING +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defn- select-padding + ([p] + (select-padding (= p :p1) (= p :p2) (= p :p3) (= p :p4))) + ([p1? p2? p3? p4?] + (st/emit! (udw/set-paddings-selected {:p1 p1? :p2 p2? :p3 p3? :p4 p4?})))) + +(defn- on-padding-blur + [_event] + (select-padding false false false false)) + +(mf/defc simple-padding-selection + {::mf/props :obj} + [{:keys [padding on-change]}] + (let [p1 (:p1 padding) + p2 (:p2 padding) + p3 (:p3 padding) + p4 (:p4 padding) + + p1 (if (and (not (= :multiple padding)) + (= p1 p3)) + p1 + "--") + + p2 (if (and (not (= :multiple padding)) + (= p2 p4)) + p2 + "--") + + on-change' + (mf/use-fn + (mf/deps on-change) + (fn [value event] + (let [attr (-> (dom/get-current-target event) + (dom/get-data "attr") + (keyword))] + (on-change :simple attr value event)))) + + on-focus + (mf/use-fn + (fn [event] + (let [attr (-> (dom/get-current-target event) + (dom/get-data "attr") + (keyword))] + + (case attr + :p1 (select-padding true false true false) + :p2 (select-padding false true false true)) + + (dom/select-target event))))] + + [:div {:class (stl/css :paddings-simple)} + [:div {:class (stl/css :padding-simple) + :title "Vertical padding"} + [:span {:class (stl/css :icon)} + i/padding-top-bottom-refactor] + [:> numeric-input* + {:class (stl/css :numeric-input) + :placeholder "--" + :data-attr "p1" + :on-change on-change' + :on-focus on-focus + :nillable true + :min 0 + :value p1}]] + [:div {:class (stl/css :padding-simple) + :title "Horizontal padding"} + + [:span {:class (stl/css :icon)} + i/padding-left-right-refactor] + [:> numeric-input* + {:className (stl/css :numeric-input) + :placeholder "--" + :data-attr "p2" + :on-change on-change' + :on-focus on-focus + :on-blur on-padding-blur + :nillable true + :min 0 + :value p2}]]])) + +(mf/defc multiple-padding-selection + {::mf/props :obj} + [{:keys [padding on-change]}] + (let [p1 (:p1 padding) + p2 (:p2 padding) + p3 (:p3 padding) + p4 (:p4 padding) + + on-change' + (mf/use-fn + (mf/deps on-change) + (fn [value event] + (let [attr (-> (dom/get-current-target event) + (dom/get-data "attr") + (keyword))] + (on-change :multiple attr value event)))) + + on-focus + (mf/use-fn + (fn [event] + (let [attr (-> (dom/get-current-target event) + (dom/get-data "attr") + (keyword))] + + (select-padding attr) + (dom/select-target event))))] + + [:div {:class (stl/css :paddings-multiple)} + [:div {:class (stl/css :padding-multiple) + :title "Top padding"} + [:span {:class (stl/css :icon)} + i/padding-top-refactor] + [:> numeric-input* + {:class (stl/css :numeric-input) + :placeholder "--" + :data-attr "p1" + :on-change on-change' + :on-focus on-focus + :on-blur on-padding-blur + :nillable true + :min 0 + :value p1}]] + + [:div {:class (stl/css :padding-multiple) + :title "Right padding"} + [:span {:class (stl/css :icon)} + i/padding-right-refactor] + [:> numeric-input* + {:class (stl/css :numeric-input) + :placeholder "--" + :data-attr "p2" + :on-change on-change' + :on-focus on-focus + :on-blur on-padding-blur + :nillable true + :min 0 + :value p2}]] + + [:div {:class (stl/css :padding-multiple) + :title "Bottom padding"} + [:span {:class (stl/css :icon)} + i/padding-bottom-refactor] + [:> numeric-input* + {:class (stl/css :numeric-input) + :placeholder "--" + :data-attr "p3" + :on-change on-change' + :on-focus on-focus + :on-blur on-padding-blur + :nillable true + :min 0 + :value p3}]] + + [:div {:class (stl/css :padding-multiple) + :title "Left padding"} + [:span {:class (stl/css :icon)} + i/padding-left-refactor] + [:> numeric-input* + {:class (stl/css :numeric-input) + :placeholder "--" + :data-attr "p4" + :on-change on-change' + :on-focus on-focus + :on-blur on-padding-blur + :nillable true + :min 0 + :value p4}]]])) + (mf/defc padding-section {::mf/props :obj} - [{:keys [values on-change-style on-change]}] - (let [padding-type (:layout-padding-type values) - - toggle-padding-mode + [{:keys [type on-type-change on-change] :as props}] + (let [on-type-change' (mf/use-fn - (mf/deps padding-type on-change-style) - (fn [] - (let [padding (if (= padding-type :multiple) :simple :multiple)] - (on-change-style padding)))) + (mf/deps on-type-change) + (fn [event] + (let [type (-> (dom/get-current-target event) + (dom/get-data "type")) + type (if (= type "multiple") :simple :multiple)] + (on-type-change type)))) - p1 (if (and (not (= :multiple (:layout-padding values))) - (= (dm/get-in values [:layout-padding :p1]) - (dm/get-in values [:layout-padding :p3]))) - (dm/get-in values [:layout-padding :p1]) - "--") + props (mf/spread-obj props {:on-change on-change})] - p2 (if (and (not (= :multiple (:layout-padding values))) - (= (dm/get-in values [:layout-padding :p2]) - (dm/get-in values [:layout-padding :p4]))) - (dm/get-in values [:layout-padding :p2]) - "--") - - select-paddings - (fn [p1? p2? p3? p4?] - (st/emit! (udw/set-paddings-selected {:p1 p1? :p2 p2? :p3 p3? :p4 p4?}))) - - select-padding #(select-paddings (= % :p1) (= % :p2) (= % :p3) (= % :p4))] - - (mf/use-effect - (fn [] - (fn [] - ;;on destroy component - (select-paddings false false false false)))) + (mf/with-effect [] + ;; on destroy component + (fn [] + (on-padding-blur nil))) [:div {:class (stl/css :padding-group)} [:div {:class (stl/css :padding-inputs)} (cond - (= padding-type :simple) - [:div {:class (stl/css :paddings-simple)} - [:div {:class (stl/css :padding-simple) - :title "Vertical padding"} - [:span {:class (stl/css :icon)} - i/padding-top-bottom-refactor] - [:> numeric-input* - {:className (stl/css :numeric-input) - :placeholder "--" - :on-change (partial on-change :simple :p1) - :on-focus #(do - (dom/select-target %) - (select-paddings true false true false)) - :nillable true - :min 0 - :value p1}]] - [:div {:class (stl/css :padding-simple) - :title "Horizontal padding"} + (= type :simple) + [:> simple-padding-selection props] - [:span {:class (stl/css :icon)} - i/padding-left-right-refactor] - [:> numeric-input* - {:className (stl/css :numeric-input) - :placeholder "--" - :on-change (partial on-change :simple :p2) - :on-focus #(do (dom/select-target %) - (select-paddings false true false true)) - :on-blur #(select-paddings false false false false) - :nillable true - :min 0 - :value p2}]]] - (= padding-type :multiple) - [:div {:class (stl/css :paddings-multiple)} + (= type :multiple) + [:> multiple-padding-selection props])] - [:div {:class (stl/css :padding-multiple) - :title "Top padding"} - [:span {:class (stl/css :icon)} - i/padding-top-refactor] - [:> numeric-input* - {:className (stl/css :numeric-input) - :placeholder "--" - :on-change (partial on-change :multiple :p1) - :on-focus #(do (dom/select-target %) - (select-padding :p1)) - :on-blur #(select-paddings false false false false) - :nillable true - :min 0 - :value (:p1 (:layout-padding values))}]] - - [:div {:class (stl/css :padding-multiple) - :title "Right padding"} - [:span {:class (stl/css :icon)} - i/padding-right-refactor] - [:> numeric-input* - {:className (stl/css :numeric-input) - :placeholder "--" - :on-change (partial on-change :multiple :p2) - :on-focus #(do (dom/select-target %) - (select-padding :p2)) - :on-blur #(select-paddings false false false false) - :nillable true - :min 0 - :value (:p2 (:layout-padding values))}]] - - [:div {:class (stl/css :padding-multiple) - :title "Bottom padding"} - [:span {:class (stl/css :icon)} - i/padding-bottom-refactor] - [:> numeric-input* - {:className (stl/css :numeric-input) - :placeholder "--" - :on-change (partial on-change :multiple :p3) - :on-focus #(do (dom/select-target %) - (select-padding :p3)) - :on-blur #(select-paddings false false false false) - :nillable true - :min 0 - :value (:p3 (:layout-padding values))}]] - - [:div {:class (stl/css :padding-multiple) - :title "Left padding"} - [:span {:class (stl/css :icon)} - i/padding-left-refactor] - [:> numeric-input* - {:className (stl/css :numeric-input) - :placeholder "--" - :on-change (partial on-change :multiple :p4) - :on-focus #(do (dom/select-target %) - (select-padding :p4)) - :on-blur #(select-paddings false false false false) - :nillable true - :min 0 - :value (:p4 (:layout-padding values))}]]])] - [:button {:class (stl/css-case :padding-toggle true - :selected (= padding-type :multiple)) - :on-click toggle-padding-mode} + [:button {:class (stl/css-case + :padding-toggle true + :selected (= type :multiple)) + :data-type (name type) + :on-click on-type-change'} i/padding-extended-refactor]])) (mf/defc gap-section @@ -439,7 +509,7 @@ :disabled (and (= :nowrap wrap-type) (not is-col?))) :title "Row gap"} [:span {:class (stl/css :icon)} i/gap-vertical-refactor] - [:> numeric-input* {:className (stl/css :numeric-input true) + [:> numeric-input* {:class (stl/css :numeric-input true) :no-validate true :placeholder "--" :on-focus (fn [event] @@ -988,11 +1058,11 @@ :on-change set-gap :gap-value (:layout-gap values)}] - [:& padding-section {:values values - :on-change-style change-padding-type + [:& padding-section {:padding (:layout-padding values) + :type (:layout-padding-type values) + :on-type-change change-padding-type :on-change on-padding-change}]]] - :grid [:div {:class (stl/css :grid-layout-menu)} (when (= 1 (count ids)) From c1d4fc71a8a85ddb598d8fa9f1739ff1e9b202ec Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 20 Feb 2024 23:55:02 +0100 Subject: [PATCH 05/10] :lipstick: Rename `is-col?` to is-column on layout-container ns --- .../options/menus/layout_container.cljs | 140 +++++++++--------- 1 file changed, 66 insertions(+), 74 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index c835634fa..466c331b4 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -61,10 +61,10 @@ :layout-grid-rows]) (defn get-layout-flex-icon - [type val ^boolean is-col?] + [type val ^boolean column?] (case type :align-items - (if is-col? + (if column? (case val :start i/align-items-column-start-refactor :end i/align-items-column-end-refactor @@ -79,7 +79,7 @@ :baseline i/align-items-row-baseline)) :justify-content - (if is-col? + (if column? (case val :start i/justify-content-column-start-refactor :end i/justify-content-column-end-refactor @@ -96,7 +96,7 @@ :space-between i/justify-content-row-between-refactor)) :align-content - (if is-col? + (if column? (case val :start i/align-content-column-start-refactor :end i/align-content-column-end-refactor @@ -116,7 +116,7 @@ :stretch nil)) :align-self - (if is-col? + (if column? (case val :auto i/remove-refactor :start i/align-self-row-left-refactor @@ -133,10 +133,10 @@ :baseline i/align-self-column-baseline)))) (defn get-layout-grid-icon-refactor - [type val ^boolean is-col?] + [type val ^boolean column?] (case type :align-items - (if is-col? + (if column? (case val :auto i/remove-refactor :start i/align-self-row-left-refactor @@ -153,7 +153,7 @@ :baseline i/align-self-column-baseline)) :justify-items - (if (not is-col?) + (if (not column?) (case val :start i/align-content-column-start-refactor :center i/align-content-column-center-refactor @@ -205,82 +205,82 @@ (mf/defc align-row {::mf/props :obj} - [{:keys [is-col? align-items on-change]}] + [{:keys [is-column align-items on-change]}] [:& radio-buttons {:selected (d/name align-items) :on-change on-change :name "flex-align-items"} [:& radio-button {:value "start" - :icon (get-layout-flex-icon :align-items :start is-col?) + :icon (get-layout-flex-icon :align-items :start is-column) :title "Align items start" :id "align-items-start"}] [:& radio-button {:value "center" - :icon (get-layout-flex-icon :align-items :center is-col?) + :icon (get-layout-flex-icon :align-items :center is-column) :title "Align items center" :id "align-items-center"}] [:& radio-button {:value "end" - :icon (get-layout-flex-icon :align-items :end is-col?) + :icon (get-layout-flex-icon :align-items :end is-column) :title "Align items end" :id "align-items-end"}]]) (mf/defc align-content-row {::mf/props :obj} - [{:keys [is-col? align-content on-change]}] + [{:keys [is-column align-content on-change]}] [:& radio-buttons {:selected (d/name align-content) :on-change on-change :name "flex-align-content"} [:& radio-button {:value "start" - :icon (get-layout-flex-icon :align-content :start is-col?) + :icon (get-layout-flex-icon :align-content :start is-column) :title "Align content start" :id "align-content-start"}] [:& radio-button {:value "center" - :icon (get-layout-flex-icon :align-content :center is-col?) + :icon (get-layout-flex-icon :align-content :center is-column) :title "Align content center" :id "align-content-center"}] [:& radio-button {:value "end" - :icon (get-layout-flex-icon :align-content :end is-col?) + :icon (get-layout-flex-icon :align-content :end is-column) :title "Align content end" :id "align-content-end"}] [:& radio-button {:value "space-between" - :icon (get-layout-flex-icon :align-content :space-between is-col?) + :icon (get-layout-flex-icon :align-content :space-between is-column) :title "Align content space-between" :id "align-content-space-between"}] [:& radio-button {:value "space-around" - :icon (get-layout-flex-icon :align-content :space-around is-col?) + :icon (get-layout-flex-icon :align-content :space-around is-column) :title "Align content space-around" :id "align-content-space-around"}] [:& radio-button {:value "space-evenly" - :icon (get-layout-flex-icon :align-content :space-evenly is-col?) + :icon (get-layout-flex-icon :align-content :space-evenly is-column) :title "Align content space-evenly" :id "align-content-space-evenly"}]]) (mf/defc justify-content-row {::mf/props :obj} - [{:keys [is-col? justify-content on-change]}] + [{:keys [is-column justify-content on-change]}] [:& radio-buttons {:selected (d/name justify-content) :on-change on-change :name "flex-justify"} [:& radio-button {:value "start" - :icon (get-layout-flex-icon :justify-content :start is-col?) + :icon (get-layout-flex-icon :justify-content :start is-column) :title "Justify content start" :id "justify-content-start"}] [:& radio-button {:value "center" - :icon (get-layout-flex-icon :justify-content :center is-col?) + :icon (get-layout-flex-icon :justify-content :center is-column) :title "Justify content center" :id "justify-content-center"}] [:& radio-button {:value "end" - :icon (get-layout-flex-icon :justify-content :end is-col?) + :icon (get-layout-flex-icon :justify-content :end is-column) :title "Justify content end" :id "justify-content-end"}] [:& radio-button {:value "space-between" - :icon (get-layout-flex-icon :justify-content :space-between is-col?) + :icon (get-layout-flex-icon :justify-content :space-between is-column) :title "Justify content space-between" :id "justify-content-space-between"}] [:& radio-button {:value "space-around" - :icon (get-layout-flex-icon :justify-content :space-around is-col?) + :icon (get-layout-flex-icon :justify-content :space-around is-column) :title "Justify content space-around" :id "justify-content-space-around"}] [:& radio-button {:value "space-evenly" - :icon (get-layout-flex-icon :justify-content :space-evenly is-col?) + :icon (get-layout-flex-icon :justify-content :space-evenly is-column) :title "Justify content space-evenly" :id "justify-content-space-evenly"}]]) @@ -493,7 +493,7 @@ (mf/defc gap-section {::mf/props :obj} - [{:keys [is-col? wrap-type gap-selected? on-change gap-value]}] + [{:keys [is-column wrap-type on-change gap-value]}] (let [select-gap (fn [gap] (st/emit! (udw/set-gap-selected gap)))] @@ -506,7 +506,7 @@ [:div {:class (stl/css :gap-group)} [:div {:class (stl/css-case :row-gap true - :disabled (and (= :nowrap wrap-type) (not is-col?))) + :disabled (and (= :nowrap wrap-type) (not is-column))) :title "Row gap"} [:span {:class (stl/css :icon)} i/gap-vertical-refactor] [:> numeric-input* {:class (stl/css :numeric-input true) @@ -514,19 +514,17 @@ :placeholder "--" :on-focus (fn [event] (select-gap :row-gap) - (reset! gap-selected? :row-gap) (dom/select-target event)) :on-change (partial on-change (= :nowrap wrap-type) :row-gap) :on-blur (fn [_] - (select-gap nil) - (reset! gap-selected? :none)) + (select-gap nil)) :nillable true :min 0 :value (:row-gap gap-value) - :disabled (and (= :nowrap wrap-type) (not is-col?))}]] + :disabled (and (= :nowrap wrap-type) (not is-column))}]] [:div {:class (stl/css-case :column-gap true - :disabled (and (= :nowrap wrap-type) is-col?)) + :disabled (and (= :nowrap wrap-type) is-column)) :title "Column gap"} [:span {:class (stl/css :icon)} i/gap-horizontal-refactor] @@ -535,24 +533,23 @@ :placeholder "--" :on-focus (fn [event] (select-gap :column-gap) - (reset! gap-selected? :column-gap) (dom/select-target event)) :on-change (partial on-change (= :nowrap wrap-type) :column-gap) :on-blur (fn [_] (select-gap nil) - (reset! gap-selected? :none)) + ) :nillable true :min 0 :value (:column-gap gap-value) - :disabled (and (= :nowrap wrap-type) is-col?)}]]])) + :disabled (and (= :nowrap wrap-type) is-column)}]]])) ;; GRID COMPONENTS (defn get-layout-grid-icon - [type val ^boolean is-col?] + [type val ^boolean column?] (case type :justify-items - (if is-col? + (if column? (case val :stretch i/align-items-row-strech :start i/grid-justify-content-column-start @@ -607,28 +604,28 @@ (mf/defc align-grid-row {::mf/props :obj} - [{:keys [is-col? align-items set-align]}] - (let [type (if is-col? :column :row)] + [{:keys [is-column align-items set-align]}] + (let [type (if is-column :column :row)] [:& radio-buttons {:selected (d/name align-items) :on-change #(set-align % type) :name (dm/str "flex-align-items-" (d/name type))} [:& radio-button {:value "start" - :icon (get-layout-grid-icon-refactor :align-items :start is-col?) + :icon (get-layout-grid-icon-refactor :align-items :start is-column) :title "Align items start" :id (dm/str "align-items-start-" (d/name type))}] [:& radio-button {:value "center" - :icon (get-layout-grid-icon-refactor :align-items :center is-col?) + :icon (get-layout-grid-icon-refactor :align-items :center is-column) :title "Align items center" :id (dm/str "align-items-center-" (d/name type))}] [:& radio-button {:value "end" - :icon (get-layout-grid-icon-refactor :align-items :end is-col?) + :icon (get-layout-grid-icon-refactor :align-items :end is-column) :title "Align items end" :id (dm/str "align-items-end-" (d/name type))}]])) (mf/defc justify-grid-row {::mf/props :obj} - [{:keys [is-col? justify-items set-justify]}] - (let [type (if is-col? :column :row)] + [{:keys [is-column justify-items set-justify]}] + (let [type (if is-column :column :row)] [:& radio-buttons {:selected (d/name justify-items) :on-change #(set-justify % type) @@ -636,7 +633,7 @@ (for [justify [:start :center :end :space-around :space-between :stretch]] [:& radio-button {:key (dm/str "justify-item-" (d/name justify)) :value (d/name justify) - :icon (get-layout-grid-icon-refactor :justify-items justify is-col?) + :icon (get-layout-grid-icon-refactor :justify-items justify is-column) :title (dm/str "Justify items " (d/name justify)) :id (dm/str "justify-items-" (d/name justify) "-" (d/name type))}])])) @@ -651,7 +648,7 @@ (mf/defc grid-track-info {::mf/props :obj} - [{:keys [is-col? + [{:keys [is-column type index column @@ -691,7 +688,7 @@ (h/use-sortable :data-type "penpot/grid-track" :on-drop drop-track - :data {:is-col? is-col? + :data {:is-column is-column :index index :column column} :draggable? true)] @@ -707,7 +704,7 @@ [:div {:class (stl/css :track-info-container)} [:div {:class (stl/css :track-info-dir-icon) :on-click handle-select-track} - (if is-col? i/flex-vertical-refactor i/flex-horizontal-refactor)] + (if is-column i/flex-vertical-refactor i/flex-horizontal-refactor)] [:div {:class (stl/css :track-info-value)} [:> numeric-input* {:no-validate true @@ -732,17 +729,17 @@ (mf/defc grid-columns-row {::mf/props :obj} - [{:keys [is-col? expanded? column-values toggle add-new-element set-column-value set-column-type + [{:keys [is-column expanded? column-values toggle add-new-element set-column-value set-column-type remove-element reorder-track hover-track on-select-track]}] (let [column-num (count column-values) direction (if (> column-num 1) - (if ^boolean is-col? "Columns " "Rows ") - (if ^boolean is-col? "Column " "Row ")) + (if ^boolean is-column "Columns " "Rows ") + (if ^boolean is-column "Column " "Row ")) track-name (dm/str direction (if (= column-num 0) " - empty" column-num)) track-detail (str/join ", " (map manage-values column-values)) - type (if is-col? :column :row) + type (if is-column :column :row) add-track #(do @@ -763,7 +760,7 @@ (for [[index column] (d/enumerate column-values)] [:& grid-track-info {:key (dm/str index "-" (name type)) :type type - :is-col? is-col? + :is-column is-column :index index :column column :set-column-value set-column-value @@ -826,7 +823,7 @@ saved-dir (:layout-flex-dir values) - is-col? (or (= :column saved-dir) (= :column-reverse saved-dir)) + is-column (or (= :column saved-dir) (= :column-reverse saved-dir)) set-direction-refactor (mf/use-fn @@ -885,9 +882,6 @@ ;; Gap - - gap-selected? (mf/use-state :none) - set-gap (fn [gap-multiple? type val] (let [val (mth/finite val 0)] @@ -1029,7 +1023,7 @@ :flex [:div {:class (stl/css :flex-layout-menu)} [:div {:class (stl/css :first-row)} - [:& align-row {:is-col? is-col? + [:& align-row {:is-column is-column :align-items align-items :on-change set-align-items}] @@ -1040,7 +1034,7 @@ :on-click toggle-wrap}]] [:div {:class (stl/css :second-row :help-button-wrapper)} - [:& justify-content-row {:is-col? is-col? + [:& justify-content-row {:is-column is-column :justify-content justify-content :on-change set-justify-content}] @@ -1048,13 +1042,12 @@ :class (stl/css :help-button)} i/help-refactor]] (when (= :wrap wrap-type) [:div {:class (stl/css :third-row)} - [:& align-content-row {:is-col? is-col? + [:& align-content-row {:is-column is-column :align-content align-content :on-change set-align-content}]]) [:div {:class (stl/css :forth-row)} - [:& gap-section {:is-col? is-col? + [:& gap-section {:is-column is-column :wrap-type wrap-type - :gap-selected? gap-selected? :on-change set-gap :gap-value (:layout-gap values)}] @@ -1076,19 +1069,19 @@ [:& direction-row-grid {:saved-dir saved-grid-dir :on-change set-direction}]]] - [:& align-grid-row {:is-col? false + [:& align-grid-row {:is-column false :align-items align-items-row :set-align set-align-grid}] - [:& align-grid-row {:is-col? true + [:& align-grid-row {:is-column true :align-items align-items-column :set-align set-align-grid}]] [:div {:class (stl/css :row :grid-layout-align)} - [:& justify-grid-row {:is-col? true + [:& justify-grid-row {:is-column true :justify-items grid-justify-content-column :set-justify set-justify-grid}] - [:& justify-grid-row {:is-col? false + [:& justify-grid-row {:is-column false :justify-items grid-justify-content-row :set-justify set-justify-grid}]] [:div {:class (stl/css :row)} @@ -1107,7 +1100,6 @@ ::mf/props :obj} [{:keys [ids values]}] (let [;; Gap - gap-selected? (mf/use-state :none) saved-grid-dir (:layout-grid-dir values) set-direction @@ -1253,19 +1245,19 @@ [:& direction-row-grid {:saved-dir saved-grid-dir :on-change set-direction}]]] - [:& align-grid-row {:is-col? false + [:& align-grid-row {:is-column false :align-items align-items-row :set-align set-align-grid}] - [:& align-grid-row {:is-col? true + [:& align-grid-row {:is-column true :align-items align-items-column :set-align set-align-grid}]] [:div {:class (stl/css :row :grid-layout-align)} - [:& justify-grid-row {:is-col? true + [:& justify-grid-row {:is-column true :justify-items grid-justify-content-column :set-justify set-justify-grid}] - [:& justify-grid-row {:is-col? false + [:& justify-grid-row {:is-column false :justify-items grid-justify-content-row :set-justify set-justify-grid}] @@ -1284,7 +1276,7 @@ :on-change on-padding-change}]] [:div {:class (stl/css :row :grid-tracks-row)} - [:& grid-columns-row {:is-col? true + [:& grid-columns-row {:is-column true :expanded? @columns-open? :toggle toggle-columns-open :column-values column-values @@ -1296,7 +1288,7 @@ :hover-track hover-track :on-select-track handle-select-track}] - [:& grid-columns-row {:is-col? false + [:& grid-columns-row {:is-column false :expanded? @rows-open? :toggle toggle-rows-open :column-values rows-values From 2170a92dd2ff947c362045e7c8506ed9e61a5109 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 21 Feb 2024 09:33:34 +0100 Subject: [PATCH 06/10] :zap: Add performance enhacenements to layout-container menu (part 3) Refactor and improve performance of gap related components --- .../options/menus/layout_container.cljs | 142 +++++++++++------- 1 file changed, 90 insertions(+), 52 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index 466c331b4..2db0ae3cf 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -491,57 +491,94 @@ :on-click on-type-change'} i/padding-extended-refactor]])) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; GAP +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defn- select-gap! + [value] + (st/emit! (udw/set-gap-selected value))) + +(defn- on-gap-focus + [event] + (let [type (-> (dom/get-current-target event) + (dom/get-data "type") + (keyword))] + (select-gap! type) + (dom/select-target event))) + +(defn- on-gap-blur + [_event] + (select-gap! nil)) + (mf/defc gap-section {::mf/props :obj} - [{:keys [is-column wrap-type on-change gap-value]}] - (let [select-gap - (fn [gap] - (st/emit! (udw/set-gap-selected gap)))] + [{:keys [is-column wrap-type on-change value] + :or {wrap-type :none} + :as props}] + (let [nowrap? (= :nowrap wrap-type) - (mf/use-effect - (fn [] - (fn [] - ;;on destroy component - (select-gap nil)))) + row-gap-disabled? + (and ^boolean nowrap? + (not ^boolean is-column)) + + col-gap-disabled? + (and ^boolean nowrap? + ^boolean is-column) + + on-change' + (mf/use-fn + (mf/deps on-change) + (fn [value event] + (let [target (dom/get-current-target event) + wrap-type (dom/get-data target "wrap-type") + type (keyword (dom/get-data target "type"))] + (on-change (= "nowrap" wrap-type) type value event))))] + + (mf/with-effect [] + ;; on destroy component + (fn [] + (on-gap-blur nil))) [:div {:class (stl/css :gap-group)} - [:div {:class (stl/css-case :row-gap true - :disabled (and (= :nowrap wrap-type) (not is-column))) + + [:div {:class (stl/css-case + :row-gap true + :disabled row-gap-disabled?) :title "Row gap"} [:span {:class (stl/css :icon)} i/gap-vertical-refactor] - [:> numeric-input* {:class (stl/css :numeric-input true) - :no-validate true - :placeholder "--" - :on-focus (fn [event] - (select-gap :row-gap) - (dom/select-target event)) - :on-change (partial on-change (= :nowrap wrap-type) :row-gap) - :on-blur (fn [_] - (select-gap nil)) - :nillable true - :min 0 - :value (:row-gap gap-value) - :disabled (and (= :nowrap wrap-type) (not is-column))}]] + [:> numeric-input* + {:class (stl/css :numeric-input true) + :no-validate true + :placeholder "--" + :data-type "row-gap" + :data-wrap-type (name wrap-type) + :on-focus on-gap-focus + :on-change on-change' + :on-blur on-gap-blur + :nillable true + :min 0 + :value (:row-gap value) + :disabled row-gap-disabled?}]] - [:div {:class (stl/css-case :column-gap true - :disabled (and (= :nowrap wrap-type) is-column)) + [:div {:class (stl/css-case + :column-gap true + :disabled col-gap-disabled?) :title "Column gap"} - [:span {:class (stl/css :icon)} - i/gap-horizontal-refactor] - [:> numeric-input* {:className (stl/css :numeric-input) - :no-validate true - :placeholder "--" - :on-focus (fn [event] - (select-gap :column-gap) - (dom/select-target event)) - :on-change (partial on-change (= :nowrap wrap-type) :column-gap) - :on-blur (fn [_] - (select-gap nil) - ) - :nillable true - :min 0 - :value (:column-gap gap-value) - :disabled (and (= :nowrap wrap-type) is-column)}]]])) + [:span {:class (stl/css :icon)} i/gap-horizontal-refactor] + [:> numeric-input* + {:class (stl/css :numeric-input true) + :no-validate true + :placeholder "--" + :data-type "column-gap" + :data-wrap-type (name wrap-type) + :on-focus on-gap-focus + :on-change on-change' + :on-blur on-gap-blur + :nillable true + :min 0 + :value (:column-gap value) + :disabled col-gap-disabled?}]]])) ;; GRID COMPONENTS @@ -882,15 +919,14 @@ ;; Gap - set-gap - (fn [gap-multiple? type val] + on-gap-change + (fn [multiple? type val] (let [val (mth/finite val 0)] - (if gap-multiple? + (if ^boolean multiple? (st/emit! (dwsl/update-layout ids {:layout-gap {:row-gap val :column-gap val}})) (st/emit! (dwsl/update-layout ids {:layout-gap {type val}}))))) ;; Padding - change-padding-type (fn [type] (st/emit! (dwsl/update-layout ids {:layout-padding-type type}))) @@ -1048,8 +1084,8 @@ [:div {:class (stl/css :forth-row)} [:& gap-section {:is-column is-column :wrap-type wrap-type - :on-change set-gap - :gap-value (:layout-gap values)}] + :on-change on-gap-change + :value (:layout-gap values)}] [:& padding-section {:padding (:layout-padding values) :type (:layout-padding-type values) @@ -1110,10 +1146,12 @@ (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))) on-gap-change - (fn [gap-multiple? type val] - (if gap-multiple? - (st/emit! (dwsl/update-layout ids {:layout-gap {:row-gap val :column-gap val}})) - (st/emit! (dwsl/update-layout ids {:layout-gap {type val}})))) + (mf/use-fn + (mf/deps ids) + (fn [multiple? type val] + (if multiple? + (st/emit! (dwsl/update-layout ids {:layout-gap {:row-gap val :column-gap val}})) + (st/emit! (dwsl/update-layout ids {:layout-gap {type val}}))))) ;; Padding change-padding-type From 2d5500d96f7541d03e4fbfe75ec1d2d588cbd707 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 21 Feb 2024 12:15:33 +0100 Subject: [PATCH 07/10] :sparkles: And minor enhancements to the radio-buttons react component And fix blur handling when on-change is not provided --- frontend/src/app/main/ui/components/radio_buttons.cljs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/app/main/ui/components/radio_buttons.cljs b/frontend/src/app/main/ui/components/radio_buttons.cljs index 6c7d3c73a..1e4f23b52 100644 --- a/frontend/src/app/main/ui/components/radio_buttons.cljs +++ b/frontend/src/app/main/ui/components/radio_buttons.cljs @@ -18,7 +18,7 @@ (mf/defc radio-button {::mf/props :obj} - [{:keys [icon id value disabled title unique-key icon-class type]}] + [{:keys [icon id value disabled title icon-class type]}] (let [context (mf/use-ctx context) allow-empty (unchecked-get context "allow-empty") type (if ^boolean type @@ -39,7 +39,6 @@ [:label {:html-for id :title title - :key unique-key :class (stl/css-case :radio-icon true :checked checked? From 0735fa93f6a041e769dc1487dbc0711e6b639603 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 21 Feb 2024 12:16:27 +0100 Subject: [PATCH 08/10] :zap: Add performance enhacenements to layout-container menu (part 4) Mainly improve performance and minor code refactor on column and row justify buttons. --- .../options/menus/layout_container.cljs | 116 +++++++++++------- 1 file changed, 75 insertions(+), 41 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index 2db0ae3cf..b1af79b32 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -642,7 +642,7 @@ (mf/defc align-grid-row {::mf/props :obj} [{:keys [is-column align-items set-align]}] - (let [type (if is-column :column :row)] + (let [type (if ^boolean is-column :column :row)] [:& radio-buttons {:selected (d/name align-items) :on-change #(set-align % type) :name (dm/str "flex-align-items-" (d/name type))} @@ -661,18 +661,48 @@ (mf/defc justify-grid-row {::mf/props :obj} - [{:keys [is-column justify-items set-justify]}] - (let [type (if is-column :column :row)] + [{:keys [is-column value on-change]}] + (let [type (if ^boolean is-column "column" "row")] + [:& radio-buttons {:selected (name value) + :on-change on-change + :decode-fn keyword + :name (dm/str "grid-justify-items-" type)} - [:& radio-buttons {:selected (d/name justify-items) - :on-change #(set-justify % type) - :name (dm/str "grid-justify-items-" (d/name type))} - (for [justify [:start :center :end :space-around :space-between :stretch]] - [:& radio-button {:key (dm/str "justify-item-" (d/name justify)) - :value (d/name justify) - :icon (get-layout-grid-icon-refactor :justify-items justify is-column) - :title (dm/str "Justify items " (d/name justify)) - :id (dm/str "justify-items-" (d/name justify) "-" (d/name type))}])])) + [:& radio-button {:key "justify-item-start" + :value "start" + :icon (get-layout-grid-icon-refactor :justify-items :start is-column) + :title "Justify items start" + :id (dm/str "justify-items-start-" type)}] + + [:& radio-button {:key "justify-item-center" + :value "center" + :icon (get-layout-grid-icon-refactor :justify-items :center is-column) + :title "Justify items center" + :id (dm/str "justify-items-center-" type)}] + + [:& radio-button {:key "justify-item-end" + :value "end" + :icon (get-layout-grid-icon-refactor :justify-items :end is-column) + :title "Justify items end" + :id (dm/str "justify-items-end-" type)}] + + [:& radio-button {:key "justify-item-space-around" + :value "space-around" + :icon (get-layout-grid-icon-refactor :justify-items :space-around is-column) + :title "Justify items space-around" + :id (dm/str "justify-items-space-around-" type)}] + + [:& radio-button {:key "justify-item-space-between" + :value "space-between" + :icon (get-layout-grid-icon-refactor :justify-items :space-between is-column) + :title "Justify items space-between" + :id (dm/str "justify-items-space-between-" type)}] + + [:& radio-button {:key "justify-item-stretch" + :value "stretch" + :icon (get-layout-grid-icon-refactor :justify-items :stretch is-column) + :title "Justify items stretch" + :id (dm/str "justify-items-stretch-" type)}]])) (defn- manage-values [{:keys [type value]}] @@ -978,14 +1008,17 @@ grid-enabled? (features/use-feature "layout/grid") - set-justify-grid + on-column-justify-change (mf/use-fn (mf/deps ids) - (fn [value type] - (let [value (keyword value)] - (if (= type :row) - (st/emit! (dwsl/update-layout ids {:layout-justify-content value})) - (st/emit! (dwsl/update-layout ids {:layout-align-content value})))))) + (fn [value] + (st/emit! (dwsl/update-layout ids {:layout-align-content value})))) + + on-row-justify-change + (mf/use-fn + (mf/deps ids) + (fn [value] + (st/emit! (dwsl/update-layout ids {:layout-justify-content value})))) handle-show-layout-dropdown (mf/use-fn @@ -1087,7 +1120,7 @@ :on-change on-gap-change :value (:layout-gap values)}] - [:& padding-section {:padding (:layout-padding values) + [:& padding-section {:values (:layout-padding values) :type (:layout-padding-type values) :on-type-change change-padding-type :on-change on-padding-change}]]] @@ -1115,15 +1148,14 @@ [:div {:class (stl/css :row :grid-layout-align)} [:& justify-grid-row {:is-column true - :justify-items grid-justify-content-column - :set-justify set-justify-grid}] + :value grid-justify-content-column + :on-change on-column-justify-change}] [:& justify-grid-row {:is-column false - :justify-items grid-justify-content-row - :set-justify set-justify-grid}]] + :value grid-justify-content-row + :on-change on-row-justify-change}]] [:div {:class (stl/css :row)} - [:& gap-section {:gap-selected? gap-selected? - :on-change set-gap - :gap-value (:layout-gap values)}]] + [:& gap-section {:on-change on-gap-change + :value (:layout-gap values)}]] [:div {:class (stl/css :row :padding-section)} [:& padding-section {:values values @@ -1185,19 +1217,21 @@ (st/emit! (dwsl/update-layout ids {:layout-align-items value})) (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))))) - ;; Justify grid grid-justify-content-row (:layout-justify-content values) grid-justify-content-column (:layout-align-content values) - set-justify-grid + on-column-justify-change (mf/use-fn (mf/deps ids) - (fn [value type] - (let [value (keyword value)] - (if (= type :row) - (st/emit! (dwsl/update-layout ids {:layout-justify-content value})) - (st/emit! (dwsl/update-layout ids {:layout-align-content value})))))) + (fn [value] + (st/emit! (dwsl/update-layout ids {:layout-align-content value})))) + + on-row-justify-change + (mf/use-fn + (mf/deps ids) + (fn [value] + (st/emit! (dwsl/update-layout ids {:layout-justify-content value})))) columns-open? (mf/use-state false) rows-open? (mf/use-state false) @@ -1293,23 +1327,23 @@ [:div {:class (stl/css :row :grid-layout-align)} [:& justify-grid-row {:is-column true - :justify-items grid-justify-content-column - :set-justify set-justify-grid}] + :value grid-justify-content-column + :on-change on-column-justify-change}] [:& justify-grid-row {:is-column false - :justify-items grid-justify-content-row - :set-justify set-justify-grid}] + :value grid-justify-content-row + :on-change on-row-justify-change}] [:button {:on-click handle-locate-grid :class (stl/css :locate-button)} i/locate-refactor]] [:div {:class (stl/css :row)} - [:& gap-section {:gap-selected? gap-selected? - :on-change set-gap - :gap-value (:layout-gap values)}]] + [:& gap-section {:on-change on-gap-change + :value (:layout-gap values)}]] [:div {:class (stl/css :row :padding-section)} - [:& padding-section {:values values + [:& padding-section {:value (:layout-padding values) + :type (:layout-padding-type values) :on-change-style change-padding-type :on-change on-padding-change}]] From 87f0e4603679dc884b72d335dc74beb76fd0c904 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 21 Feb 2024 12:45:50 +0100 Subject: [PATCH 09/10] :zap: Add performance enhacenements to layout-container menu (part 5) Refactor and improve performance of align-grid-row related components --- .../options/menus/layout_container.cljs | 70 +++++++++++-------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index b1af79b32..2af19d2d8 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -640,27 +640,30 @@ (tr "workspace.layout_grid.editor.options.edit-grid")])) (mf/defc align-grid-row - {::mf/props :obj} - [{:keys [is-column align-items set-align]}] - (let [type (if ^boolean is-column :column :row)] - [:& radio-buttons {:selected (d/name align-items) - :on-change #(set-align % type) - :name (dm/str "flex-align-items-" (d/name type))} + {::mf/props :obj + ::mf/private true} + [{:keys [is-column value on-change]}] + (let [type (if ^boolean is-column "column" "row")] + [:& radio-buttons {:selected (name value) + :decode-fn keyword + :on-change on-change + :name (dm/str "flex-align-items-" type)} [:& radio-button {:value "start" :icon (get-layout-grid-icon-refactor :align-items :start is-column) :title "Align items start" - :id (dm/str "align-items-start-" (d/name type))}] + :id (dm/str "align-items-start-" type)}] [:& radio-button {:value "center" :icon (get-layout-grid-icon-refactor :align-items :center is-column) :title "Align items center" - :id (dm/str "align-items-center-" (d/name type))}] + :id (dm/str "align-items-center-" type)}] [:& radio-button {:value "end" :icon (get-layout-grid-icon-refactor :align-items :end is-column) :title "Align items end" - :id (dm/str "align-items-end-" (d/name type))}]])) + :id (dm/str "align-items-end-" type)}]])) (mf/defc justify-grid-row - {::mf/props :obj} + {::mf/props :obj + ::mf/private :obj} [{:keys [is-column value on-change]}] (let [type (if ^boolean is-column "column" "row")] [:& radio-buttons {:selected (name value) @@ -993,14 +996,17 @@ align-items-row (:layout-align-items values) align-items-column (:layout-justify-items values) - set-align-grid + on-column-align-change (mf/use-fn (mf/deps ids) - (fn [value type] - (let [value (keyword value)] - (if (= type :row) - (st/emit! (dwsl/update-layout ids {:layout-align-items value})) - (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))))) + (fn [value] + (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))) + + on-row-align-change + (mf/use-fn + (mf/deps ids) + (fn [value] + (st/emit! (dwsl/update-layout ids {:layout-align-items value})))) ;; Justify grid grid-justify-content-row (:layout-justify-content values) @@ -1139,12 +1145,12 @@ :on-change set-direction}]]] [:& align-grid-row {:is-column false - :align-items align-items-row - :set-align set-align-grid}] + :value align-items-row + :on-change on-row-align-change}] [:& align-grid-row {:is-column true - :align-items align-items-column - :set-align set-align-grid}]] + :value align-items-column + :on-change on-column-align-change}]] [:div {:class (stl/css :row :grid-layout-align)} [:& justify-grid-row {:is-column true @@ -1208,14 +1214,18 @@ align-items-row (:layout-align-items values) align-items-column (:layout-justify-items values) - set-align-grid + on-column-align-change (mf/use-fn (mf/deps ids) - (fn [value type] - (let [value (keyword value)] - (if (= type :row) - (st/emit! (dwsl/update-layout ids {:layout-align-items value})) - (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))))) + (fn [value] + (st/emit! (dwsl/update-layout ids {:layout-justify-items value})))) + + on-row-align-change + (mf/use-fn + (mf/deps ids) + (fn [value] + (st/emit! (dwsl/update-layout ids {:layout-align-items value})))) + ;; Justify grid grid-justify-content-row (:layout-justify-content values) @@ -1318,12 +1328,12 @@ :on-change set-direction}]]] [:& align-grid-row {:is-column false - :align-items align-items-row - :set-align set-align-grid}] + :value align-items-row + :on-change on-row-align-change}] [:& align-grid-row {:is-column true - :align-items align-items-column - :set-align set-align-grid}]] + :value align-items-column + :on-change on-column-align-change}]] [:div {:class (stl/css :row :grid-layout-align)} [:& justify-grid-row {:is-column true From 65df775937512f7e4788d7a8f9668aedab813f7f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 21 Feb 2024 12:47:39 +0100 Subject: [PATCH 10/10] :lipstick: Fix naming inconsistencies on layout menu components --- .../options/menus/layout_container.cljs | 465 ++++++++---------- .../sidebar/options/menus/layout_item.cljs | 144 +++--- 2 files changed, 279 insertions(+), 330 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs index 2af19d2d8..b646311e8 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs @@ -32,7 +32,7 @@ [cuerdas.core :as str] [rumext.v2 :as mf])) -(defn dir-icons-refactor +(defn- dir-icons-refactor [val] (case val :row i/grid-row-refactor @@ -132,7 +132,7 @@ :stretch i/align-self-column-strech :baseline i/align-self-column-baseline)))) -(defn get-layout-grid-icon-refactor +(defn get-layout-grid-icon [type val ^boolean column?] (case type :align-items @@ -170,9 +170,11 @@ :stretch i/align-content-row-stretch-refactor)))) (mf/defc direction-row-flex - {::mf/props :obj} - [{:keys [saved-dir on-change]}] - [:& radio-buttons {:selected (d/name saved-dir) + {::mf/props :obj + ::mf/private true} + [{:keys [value on-change]}] + [:& radio-buttons {:selected (d/name value) + :decode-fn keyword :on-change on-change :name "flex-direction"} [:& radio-button {:value "row" @@ -205,8 +207,9 @@ (mf/defc align-row {::mf/props :obj} - [{:keys [is-column align-items on-change]}] - [:& radio-buttons {:selected (d/name align-items) + [{:keys [is-column value on-change]}] + [:& radio-buttons {:selected (d/name value) + :decode-fn keyword :on-change on-change :name "flex-align-items"} [:& radio-button {:value "start" @@ -224,34 +227,35 @@ (mf/defc align-content-row {::mf/props :obj} - [{:keys [is-column align-content on-change]}] - [:& radio-buttons {:selected (d/name align-content) + [{:keys [is-column value on-change]}] + [:& radio-buttons {:selected (d/name value) + :decode-fn keyword :on-change on-change :name "flex-align-content"} - [:& radio-button {:value "start" - :icon (get-layout-flex-icon :align-content :start is-column) - :title "Align content start" - :id "align-content-start"}] - [:& radio-button {:value "center" - :icon (get-layout-flex-icon :align-content :center is-column) - :title "Align content center" - :id "align-content-center"}] - [:& radio-button {:value "end" - :icon (get-layout-flex-icon :align-content :end is-column) - :title "Align content end" - :id "align-content-end"}] - [:& radio-button {:value "space-between" - :icon (get-layout-flex-icon :align-content :space-between is-column) - :title "Align content space-between" - :id "align-content-space-between"}] - [:& radio-button {:value "space-around" - :icon (get-layout-flex-icon :align-content :space-around is-column) - :title "Align content space-around" - :id "align-content-space-around"}] - [:& radio-button {:value "space-evenly" - :icon (get-layout-flex-icon :align-content :space-evenly is-column) - :title "Align content space-evenly" - :id "align-content-space-evenly"}]]) + [:& radio-button {:value "start" + :icon (get-layout-flex-icon :align-content :start is-column) + :title "Align content start" + :id "align-content-start"}] + [:& radio-button {:value "center" + :icon (get-layout-flex-icon :align-content :center is-column) + :title "Align content center" + :id "align-content-center"}] + [:& radio-button {:value "end" + :icon (get-layout-flex-icon :align-content :end is-column) + :title "Align content end" + :id "align-content-end"}] + [:& radio-button {:value "space-between" + :icon (get-layout-flex-icon :align-content :space-between is-column) + :title "Align content space-between" + :id "align-content-space-between"}] + [:& radio-button {:value "space-around" + :icon (get-layout-flex-icon :align-content :space-around is-column) + :title "Align content space-around" + :id "align-content-space-around"}] + [:& radio-button {:value "space-evenly" + :icon (get-layout-flex-icon :align-content :space-evenly is-column) + :title "Align content space-evenly" + :id "align-content-space-evenly"}]]) (mf/defc justify-content-row {::mf/props :obj} @@ -300,18 +304,18 @@ (mf/defc simple-padding-selection {::mf/props :obj} - [{:keys [padding on-change]}] - (let [p1 (:p1 padding) - p2 (:p2 padding) - p3 (:p3 padding) - p4 (:p4 padding) + [{:keys [value on-change]}] + (let [p1 (:p1 value) + p2 (:p2 value) + p3 (:p3 value) + p4 (:p4 value) - p1 (if (and (not (= :multiple padding)) + p1 (if (and (not (= :multiple value)) (= p1 p3)) p1 "--") - p2 (if (and (not (= :multiple padding)) + p2 (if (and (not (= :multiple value)) (= p2 p4)) p2 "--") @@ -370,11 +374,11 @@ (mf/defc multiple-padding-selection {::mf/props :obj} - [{:keys [padding on-change]}] - (let [p1 (:p1 padding) - p2 (:p2 padding) - p3 (:p3 padding) - p4 (:p4 padding) + [{:keys [value on-change]}] + (let [p1 (:p1 value) + p2 (:p2 value) + p3 (:p3 value) + p4 (:p4 value) on-change' (mf/use-fn @@ -582,33 +586,11 @@ ;; GRID COMPONENTS -(defn get-layout-grid-icon - [type val ^boolean column?] - (case type - :justify-items - (if column? - (case val - :stretch i/align-items-row-strech - :start i/grid-justify-content-column-start - :end i/grid-justify-content-column-end - :center i/grid-justify-content-column-center - :space-around i/grid-justify-content-column-around - :space-between i/grid-justify-content-column-between - :space-evenly i/grid-justify-content-column-between) - - (case val - :stretch i/align-items-column-strech - :start i/grid-justify-content-row-start - :end i/grid-justify-content-row-end - :center i/grid-justify-content-row-center - :space-around i/grid-justify-content-row-around - :space-between i/grid-justify-content-row-between - :space-evenly i/grid-justify-content-row-between)))) - (mf/defc direction-row-grid {::mf/props :obj} - [{:keys [saved-dir on-change] :as props}] - [:& radio-buttons {:selected (d/name saved-dir) + [{:keys [value on-change] :as props}] + [:& radio-buttons {:selected (d/name value) + :decode-fn keyword :on-change on-change :name "grid-direction"} [:& radio-button {:value "row" @@ -649,15 +631,15 @@ :on-change on-change :name (dm/str "flex-align-items-" type)} [:& radio-button {:value "start" - :icon (get-layout-grid-icon-refactor :align-items :start is-column) + :icon (get-layout-grid-icon :align-items :start is-column) :title "Align items start" :id (dm/str "align-items-start-" type)}] [:& radio-button {:value "center" - :icon (get-layout-grid-icon-refactor :align-items :center is-column) + :icon (get-layout-grid-icon :align-items :center is-column) :title "Align items center" :id (dm/str "align-items-center-" type)}] [:& radio-button {:value "end" - :icon (get-layout-grid-icon-refactor :align-items :end is-column) + :icon (get-layout-grid-icon :align-items :end is-column) :title "Align items end" :id (dm/str "align-items-end-" type)}]])) @@ -673,37 +655,37 @@ [:& radio-button {:key "justify-item-start" :value "start" - :icon (get-layout-grid-icon-refactor :justify-items :start is-column) + :icon (get-layout-grid-icon :justify-items :start is-column) :title "Justify items start" :id (dm/str "justify-items-start-" type)}] [:& radio-button {:key "justify-item-center" :value "center" - :icon (get-layout-grid-icon-refactor :justify-items :center is-column) + :icon (get-layout-grid-icon :justify-items :center is-column) :title "Justify items center" :id (dm/str "justify-items-center-" type)}] [:& radio-button {:key "justify-item-end" :value "end" - :icon (get-layout-grid-icon-refactor :justify-items :end is-column) + :icon (get-layout-grid-icon :justify-items :end is-column) :title "Justify items end" :id (dm/str "justify-items-end-" type)}] [:& radio-button {:key "justify-item-space-around" :value "space-around" - :icon (get-layout-grid-icon-refactor :justify-items :space-around is-column) + :icon (get-layout-grid-icon :justify-items :space-around is-column) :title "Justify items space-around" :id (dm/str "justify-items-space-around-" type)}] [:& radio-button {:key "justify-item-space-between" :value "space-between" - :icon (get-layout-grid-icon-refactor :justify-items :space-between is-column) + :icon (get-layout-grid-icon :justify-items :space-between is-column) :title "Justify items space-between" :id (dm/str "justify-items-space-between-" type)}] [:& radio-button {:key "justify-item-stretch" :value "stretch" - :icon (get-layout-grid-icon-refactor :justify-items :stretch is-column) + :icon (get-layout-grid-icon :justify-items :stretch is-column) :title "Justify items stretch" :id (dm/str "justify-items-stretch-" type)}]])) @@ -842,70 +824,51 @@ ;; LAYOUT COMPONENT +(defn- open-flex-help + [_] + (st/emit! (dom/open-new-window cf/flex-help-uri))) + +(defn- open-grid-help + [_] + (st/emit! (dom/open-new-window cf/grid-help-uri))) + (mf/defc layout-container-menu {::mf/memo #{:ids :values :multiple} ::mf/props :obj} [{:keys [ids values multiple]}] (let [;; Display - layout-type (:layout values) - has-layout? (some? layout-type) + layout-type (:layout values) + has-layout? (some? layout-type) - show-layout-dropdown* (mf/use-state false) - show-layout-dropdown? @show-layout-dropdown* + show-dropdown* (mf/use-state false) + show-dropdown? @show-dropdown* - state* (mf/use-state (if layout-type - true - false)) + open* (mf/use-state #(if layout-type true false)) + open? (deref open*) - open? (deref state*) - toggle-content (mf/use-fn #(swap! state* not)) + on-toggle-visibility + (mf/use-fn #(swap! open* not)) on-add-layout - (mf/use-fn - (fn [type] - (st/emit! (dwsl/create-layout type)) - (reset! state* true))) - - on-set-layout (mf/use-fn (fn [event] - (let [value (-> (dom/get-current-target event) - (dom/get-data "value") - (keyword))] - (on-add-layout value)))) + (let [type (-> (dom/get-current-target event) + (dom/get-data "type") + (keyword))] + (st/emit! (dwsl/create-layout type)) + (reset! open* true)))) on-remove-layout - (fn [_] - (st/emit! (dwsl/remove-layout ids)) - (reset! state* false)) - - set-flex (mf/use-fn - (mf/deps on-add-layout) - (fn [] - (on-add-layout :flex))) - - set-grid - (mf/use-fn - (mf/deps on-add-layout) - (fn [] - (on-add-layout :grid))) + (mf/deps ids) + (fn [_] + (st/emit! (dwsl/remove-layout ids)) + (reset! open* false))) saved-dir (:layout-flex-dir values) - - is-column (or (= :column saved-dir) (= :column-reverse saved-dir)) - - set-direction-refactor - (mf/use-fn - (mf/deps layout-type ids) - (fn [dir] - (let [dir (keyword dir)] - (if (= :flex layout-type) - (st/emit! (dwsl/update-layout ids {:layout-flex-dir dir})) - (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))))) + is-column (or (= :column saved-dir) (= :column-reverse saved-dir)) ;; Wrap type - wrap-type (:layout-wrap-type values) toggle-wrap @@ -919,7 +882,6 @@ ;; Align items - align-items (:layout-align-items values) set-align-items @@ -929,7 +891,6 @@ (st/emit! (dwsl/update-layout ids {:layout-align-items (keyword value)})))) ;; Justify content - justify-content (:layout-justify-content values) set-justify-content @@ -939,18 +900,17 @@ (st/emit! (dwsl/update-layout ids {:layout-justify-content (keyword value)})))) ;; Align content - align-content (:layout-align-content values) - set-align-content + ;; FIXME revisit??? + on-align-content-change (mf/use-fn - (mf/deps ids) - (fn [value align-content] + (mf/deps ids align-content) + (fn [value] (if (= align-content value) (st/emit! (dwsl/update-layout ids {:layout-align-content :stretch})) (st/emit! (dwsl/update-layout ids {:layout-align-content (keyword value)}))))) - ;; Gap on-gap-change (fn [multiple? type val] @@ -960,9 +920,11 @@ (st/emit! (dwsl/update-layout ids {:layout-gap {type val}}))))) ;; Padding - change-padding-type - (fn [type] - (st/emit! (dwsl/update-layout ids {:layout-padding-type type}))) + on-padding-type-change + (mf/use-fn + (mf/deps ids) + (fn [type] + (st/emit! (dwsl/update-layout ids {:layout-padding-type type})))) on-padding-change (mf/use-fn @@ -983,14 +945,13 @@ saved-grid-dir (:layout-grid-dir values) - set-direction + on-direction-change (mf/use-fn (mf/deps layout-type ids) (fn [dir] - (let [dir (keyword dir)] - (if (= :flex layout-type) - (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})) - (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))))) + (if (= :flex layout-type) + (st/emit! (dwsl/update-layout ids {:layout-flex-dir dir})) + (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))) ;; Align grid align-items-row (:layout-align-items values) @@ -1026,45 +987,40 @@ (fn [value] (st/emit! (dwsl/update-layout ids {:layout-justify-content value})))) - handle-show-layout-dropdown - (mf/use-fn - (fn [] - (swap! show-layout-dropdown* not))) + on-toggle-dropdown-visibility + (mf/use-fn #(swap! show-dropdown* not)) - handle-close-layout-options - (mf/use-fn - (fn [] - (reset! show-layout-dropdown* false))) - - handle-open-flex-help - (mf/use-fn - (fn [] - (st/emit! (dom/open-new-window cf/flex-help-uri)))) - - handle-open-grid-help - (mf/use-fn - (fn [] - (st/emit! (dom/open-new-window cf/grid-help-uri))))] + on-hide-dropdown + (mf/use-fn #(reset! show-dropdown* false))] [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable has-layout? - :collapsed (not open?) - :on-collapsed toggle-content - :title "Layout" - :class (stl/css-case :title-spacing-layout (not has-layout?))} + [:& title-bar + {:collapsable has-layout? + :collapsed (not open?) + :on-collapsed on-toggle-visibility + :title "Layout" + :class (stl/css-case :title-spacing-layout (not has-layout?))} + (if (and (not multiple) (:layout values)) [:div {:class (stl/css :title-actions)} (when ^boolean grid-enabled? [:* [:button {:class (stl/css :add-layout) - :on-click handle-show-layout-dropdown} + :on-click on-toggle-dropdown-visibility} i/menu-refactor] - [:& dropdown {:show show-layout-dropdown? :on-close handle-close-layout-options} + [:& dropdown {:show show-dropdown? + :on-close on-hide-dropdown} [:div {:class (stl/css :layout-options)} - [:button {:class (stl/css :layout-option) :on-click set-flex} "Flex layout"] - [:button {:class (stl/css :layout-option) :on-click set-grid} "Grid layout"]]]]) + [:button {:class (stl/css :layout-option) + :data-type "flex" + :on-click on-add-layout} + "Flex layout"] + [:button {:class (stl/css :layout-option) + :data-type "grid" + :on-click on-add-layout} + "Grid layout"]]]]) (when has-layout? [:button {:class (stl/css :remove-layout) @@ -1075,99 +1031,110 @@ (if ^boolean grid-enabled? [:* [:button {:class (stl/css :add-layout) - :on-click handle-show-layout-dropdown} + :on-click on-toggle-dropdown-visibility} i/add-refactor] - [:& dropdown {:show show-layout-dropdown? :on-close handle-close-layout-options} + [:& dropdown {:show show-dropdown? + :on-close on-hide-dropdown} [:div {:class (stl/css :layout-options)} - [:button {:class (stl/css :layout-option) :on-click set-flex} "Flex layout"] - [:button {:class (stl/css :layout-option) :on-click set-grid} "Grid layout"]]]] + [:button {:class (stl/css :layout-option) + :data-type "flex" + :on-click on-add-layout} + "Flex layout"] + [:button {:class (stl/css :layout-option) + :data-type "grid" + :on-click on-add-layout} + "Grid layout"]]]] [:button {:class (stl/css :add-layout) - :data-value "flex" - :on-click on-set-layout} + :data-type "flex" + :on-click on-add-layout} i/add-refactor]) (when has-layout? [:button {:class (stl/css :remove-layout) :on-click on-remove-layout} i/remove-refactor])])]] - (when (and open? has-layout?) - (when (not= :multiple layout-type) - (case layout-type - :flex - [:div {:class (stl/css :flex-layout-menu)} - [:div {:class (stl/css :first-row)} - [:& align-row {:is-column is-column - :align-items align-items - :on-change set-align-items}] + (when (and ^boolean open? + ^boolean has-layout? + (not= :multiple layout-type)) + (case layout-type + :flex + [:div {:class (stl/css :flex-layout-menu)} + [:div {:class (stl/css :first-row)} + [:& align-row {:is-column is-column + :value align-items + :on-change set-align-items}] - [:& direction-row-flex {:on-change set-direction-refactor - :saved-dir saved-dir}] + [:& direction-row-flex {:on-change on-direction-change + :value saved-dir}] - [:& wrap-row {:wrap-type wrap-type - :on-click toggle-wrap}]] + [:& wrap-row {:wrap-type wrap-type + :on-click toggle-wrap}]] - [:div {:class (stl/css :second-row :help-button-wrapper)} - [:& justify-content-row {:is-column is-column - :justify-content justify-content - :on-change set-justify-content}] + [:div {:class (stl/css :second-row :help-button-wrapper)} + [:& justify-content-row {:is-column is-column + :justify-content justify-content + :on-change set-justify-content}] - [:button {:on-click handle-open-flex-help - :class (stl/css :help-button)} i/help-refactor]] - (when (= :wrap wrap-type) - [:div {:class (stl/css :third-row)} - [:& align-content-row {:is-column is-column - :align-content align-content - :on-change set-align-content}]]) - [:div {:class (stl/css :forth-row)} - [:& gap-section {:is-column is-column - :wrap-type wrap-type - :on-change on-gap-change - :value (:layout-gap values)}] + [:button {:on-click open-flex-help + :class (stl/css :help-button)} + i/help-refactor]] + (when (= :wrap wrap-type) + [:div {:class (stl/css :third-row)} + [:& align-content-row {:is-column is-column + :value align-content + :on-change on-align-content-change}]]) + [:div {:class (stl/css :forth-row)} + [:& gap-section {:is-column is-column + :wrap-type wrap-type + :on-change on-gap-change + :value (:layout-gap values)}] - [:& padding-section {:values (:layout-padding values) - :type (:layout-padding-type values) - :on-type-change change-padding-type - :on-change on-padding-change}]]] + [:& padding-section {:value (:layout-padding values) + :type (:layout-padding-type values) + :on-type-change on-padding-type-change + :on-change on-padding-change}]]] - :grid - [:div {:class (stl/css :grid-layout-menu)} - (when (= 1 (count ids)) - [:div {:class (stl/css :edit-grid-wrapper)} - [:& grid-edit-mode {:id (first ids)}] - [:button {:on-click handle-open-grid-help - :class (stl/css :help-button)} i/help-refactor]]) - [:div {:class (stl/css :row :first-row)} - [:div {:class (stl/css :direction-edit)} - [:div {:class (stl/css :direction)} - [:& direction-row-grid {:saved-dir saved-grid-dir - :on-change set-direction}]]] + :grid + [:div {:class (stl/css :grid-layout-menu)} + (when (= 1 (count ids)) + [:div {:class (stl/css :edit-grid-wrapper)} + [:& grid-edit-mode {:id (first ids)}] + [:button {:on-click open-grid-help + :class (stl/css :help-button)} i/help-refactor]]) - [:& align-grid-row {:is-column false - :value align-items-row - :on-change on-row-align-change}] + [:div {:class (stl/css :row :first-row)} + [:div {:class (stl/css :direction-edit)} + [:div {:class (stl/css :direction)} + [:& direction-row-grid {:value saved-grid-dir + :on-change on-direction-change}]]] - [:& align-grid-row {:is-column true - :value align-items-column - :on-change on-column-align-change}]] + [:& align-grid-row {:is-column false + :value align-items-row + :on-change on-row-align-change}] + [:& align-grid-row {:is-column true + :value align-items-column + :on-change on-column-align-change}]] - [:div {:class (stl/css :row :grid-layout-align)} - [:& justify-grid-row {:is-column true - :value grid-justify-content-column - :on-change on-column-justify-change}] - [:& justify-grid-row {:is-column false - :value grid-justify-content-row - :on-change on-row-justify-change}]] - [:div {:class (stl/css :row)} - [:& gap-section {:on-change on-gap-change - :value (:layout-gap values)}]] + [:div {:class (stl/css :row :grid-layout-align)} + [:& justify-grid-row {:is-column true + :value grid-justify-content-column + :on-change on-column-justify-change}] + [:& justify-grid-row {:is-column false + :value grid-justify-content-row + :on-change on-row-justify-change}]]] + [:div {:class (stl/css :row)} + [:& gap-section {:on-change on-gap-change + :value (:layout-gap values)}]] - [:div {:class (stl/css :row :padding-section)} - [:& padding-section {:values values - :on-change-style change-padding-type - :on-change on-padding-change}]]] - nil)))])) + [:div {:class (stl/css :row :padding-section)} + [:& padding-section {:value (:layout-padding values) + :type (:layout-padding-type values) + :on-change-style on-padding-type-change + :on-change on-padding-change}]] + + nil))])) (mf/defc grid-layout-edition {::mf/memo #{:ids :values} @@ -1176,12 +1143,11 @@ (let [;; Gap saved-grid-dir (:layout-grid-dir values) - set-direction + on-direction-change (mf/use-fn (mf/deps ids) (fn [dir] - (let [dir (keyword dir)] - (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))) + (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))) on-gap-change (mf/use-fn @@ -1192,7 +1158,7 @@ (st/emit! (dwsl/update-layout ids {:layout-gap {type val}}))))) ;; Padding - change-padding-type + on-padding-type-change (mf/use-fn (mf/deps ids) (fn [type] @@ -1226,7 +1192,6 @@ (fn [value] (st/emit! (dwsl/update-layout ids {:layout-align-items value})))) - ;; Justify grid grid-justify-content-row (:layout-justify-content values) grid-justify-content-column (:layout-align-content values) @@ -1302,20 +1267,16 @@ :fixed 100)] (st/emit! (dwsl/change-layout-track ids type index {:value value :type track-type}))))) - handle-open-grid-help - (mf/use-fn - (fn [] - (st/emit! (dom/open-new-window cf/grid-help-uri)))) - handle-locate-grid (mf/use-fn + (mf/deps ids) (fn [] (st/emit! (dwge/locate-board (first ids)))))] [:div {:class (stl/css :grid-layout-menu)} [:div {:class (stl/css :row)} [:div {:class (stl/css :grid-layout-menu-title)} "GRID LAYOUT"] - [:button {:on-click handle-open-grid-help + [:button {:on-click open-grid-help :class (stl/css :help-button)} i/help-refactor] [:button {:class (stl/css :exit-btn) :on-click #(st/emit! udw/clear-edition-mode)} @@ -1324,8 +1285,8 @@ [:div {:class (stl/css :row :first-row)} [:div {:class (stl/css :direction-edit)} [:div {:class (stl/css :direction)} - [:& direction-row-grid {:saved-dir saved-grid-dir - :on-change set-direction}]]] + [:& direction-row-grid {:value saved-grid-dir + :on-change on-direction-change}]]] [:& align-grid-row {:is-column false :value align-items-row @@ -1354,7 +1315,7 @@ [:div {:class (stl/css :row :padding-section)} [:& padding-section {:value (:layout-padding values) :type (:layout-padding-type values) - :on-change-style change-padding-type + :on-change-style on-padding-type-change :on-change on-padding-change}]] [:div {:class (stl/css :row :grid-tracks-row)} 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 dff99e0a9..b0b539f28 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 @@ -20,8 +20,7 @@ [app.main.ui.workspace.sidebar.options.menus.layout-container :refer [get-layout-flex-icon]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] - [rumext.v2 :as mf] - [rumext.v2.props :as-alias mf.props])) + [rumext.v2 :as mf])) (def layout-item-attrs [:layout-item-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0} @@ -46,14 +45,14 @@ (mf/defc margin-simple {::mf/props :obj} - [{:keys [margin on-change on-blur]}] - (let [m1 (:m1 margin) - m2 (:m2 margin) - m3 (:m3 margin) - m4 (:m4 margin) + [{:keys [value on-change on-blur]}] + (let [m1 (:m1 value) + m2 (:m2 value) + m3 (:m3 value) + m4 (:m4 value) - m1 (when (and (not= margin :multiple) (= m1 m3)) m1) - m2 (when (and (not= margin :multiple) (= m2 m4)) m2) + m1 (when (and (not= value :multiple) (= m1 m3)) m1) + m2 (when (and (not= value :multiple) (= m2 m4)) m2) on-focus (mf/use-fn @@ -106,11 +105,11 @@ (mf/defc margin-multiple {::mf/props :obj} - [{:keys [margin on-change on-blur]}] - (let [m1 (:m1 margin) - m2 (:m2 margin) - m3 (:m3 margin) - m4 (:m4 margin) + [{:keys [value on-change on-blur]}] + (let [m1 (:m1 value) + m2 (:m2 value) + m3 (:m3 value) + m4 (:m4 value) on-focus (mf/use-fn @@ -186,7 +185,7 @@ (mf/defc margin-section {::mf/props :obj ::mf/private true - ::mf.props/expect #{:margin :type :on-type-change :on-change}} + ::mf/expect-props #{:value :type :on-type-change :on-change}} [{:keys [type on-type-change] :as props}] (let [type (d/nilv type :simple) on-blur (mf/use-fn #(select-margins false false false false)) @@ -220,14 +219,17 @@ i/margin-refactor]])) (mf/defc element-behaviour-horizontal - {::mf/props :obj} - [{:keys [^boolean is-auto ^boolean has-fill sizing on-change]}] - [:div {:class (stl/css-case :horizontal-behaviour true - :one-element (and (not has-fill) (not is-auto)) - :two-element (or has-fill is-auto) - :three-element (and has-fill is-auto))} + {::mf/props :obj + ::mf/private true} + [{:keys [^boolean is-auto ^boolean has-fill value on-change]}] + [:div {:class (stl/css-case + :horizontal-behaviour true + :one-element (and (not has-fill) (not is-auto)) + :two-element (or has-fill is-auto) + :three-element (and has-fill is-auto))} [:& radio-buttons - {:selected (d/name sizing) + {:selected (d/name value) + :decode-fn keyword :on-change on-change :wide true :name "flex-behaviour-h"} @@ -252,14 +254,17 @@ :id "behaviour-h-auto"}])]]) (mf/defc element-behaviour-vertical - {::mf/props :obj} - [{:keys [^boolean is-auto ^boolean has-fill sizing on-change]}] - [:div {:class (stl/css-case :vertical-behaviour true - :one-element (and (not has-fill) (not is-auto)) - :two-element (or has-fill is-auto) - :three-element (and has-fill is-auto))} + {::mf/props :obj + ::mf/private true} + [{:keys [^boolean is-auto ^boolean has-fill value on-change]}] + [:div {:class (stl/css-case + :vertical-behaviour true + :one-element (and (not has-fill) (not is-auto)) + :two-element (or has-fill is-auto) + :three-element (and has-fill is-auto))} [:& radio-buttons - {:selected (d/name sizing) + {:selected (d/name value) + :decode-fn keyword :on-change on-change :wide true :name "flex-behaviour-v"} @@ -286,34 +291,11 @@ :title "Fit content" :id "behaviour-v-auto"}])]]) -(mf/defc element-behaviour - {::mf/props :obj - ::mf/private true} - [{:keys [^boolean is-auto - ^boolean has-fill - h-sizing - v-sizing - on-h-change - on-v-change]}] - [:div {:class (stl/css-case - :behaviour-menu true - :wrap (and has-fill is-auto))} - - [:& element-behaviour-horizontal - {:is-auto is-auto - :has-fill has-fill - :sizing h-sizing - :on-change on-h-change}] - [:& element-behaviour-vertical - {:is-auto is-auto - :has-fill has-fill - :sizing v-sizing - :on-change on-v-change}]]) - (mf/defc align-self-row {::mf/props :obj} - [{:keys [^boolean is-col align-self on-change]}] - [:& radio-buttons {:selected (d/name align-self) + [{:keys [^boolean is-col value on-change]}] + [:& radio-buttons {:selected (d/name value) + :decode-fn keyword :on-change on-change :name "flex-align-self" :allow-empty true} @@ -392,16 +374,16 @@ :else "Layout element") - set-align-self + on-align-self-change (mf/use-fn (mf/deps ids align-self) (fn [value] (if (= align-self value) (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil})) - (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self (keyword value)}))))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value}))))) ;; Margin - on-change-margin-type + on-margin-type-change (mf/use-fn (mf/deps ids) (fn [type] @@ -422,19 +404,17 @@ (st/emit! (dwsl/update-layout-child ids {:layout-item-margin {prop val}}))))) ;; Behaviour - on-change-behaviour-h + on-behaviour-h-change (mf/use-fn (mf/deps ids) (fn [value] - (let [value (keyword value)] - (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value}))))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-h-sizing value})))) - on-change-behaviour-v + on-behaviour-v-change (mf/use-fn (mf/deps ids) (fn [value] - (let [value (keyword value)] - (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value}))))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-v-sizing value})))) ;; Size and position on-size-change @@ -450,10 +430,9 @@ (mf/use-fn (mf/deps ids) (fn [value] - (let [value (keyword value)] - (when (= value :static) - (st/emit! (dwsl/update-layout-child ids {:layout-item-z-index nil}))) - (st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)}))))) + (when (= value :static) + (st/emit! (dwsl/update-layout-child ids {:layout-item-z-index nil}))) + (st/emit! (dwsl/update-layout-child ids {:layout-item-absolute (= value :absolute)})))) ;; Z Index on-change-z-index @@ -476,6 +455,7 @@ [:div {:class (stl/css :row)} [:div {:class (stl/css :position-options)} [:& radio-buttons {:selected (if is-absolute? "absolute" "static") + :decode-fn keyword :on-change on-change-position :name "layout-style" :wide true} @@ -497,24 +477,32 @@ :value (:layout-item-z-index values)}]]]) [:div {:class (stl/css :row)} - [:& element-behaviour {:has-fill is-layout-child? - :is-auto is-layout-container? - :v-sizing (:layout-item-v-sizing values) - :h-sizing (:layout-item-h-sizing values) - :on-h-change on-change-behaviour-h - :on-v-change on-change-behaviour-v}]] + [:div {:class (stl/css-case + :behaviour-menu true + :wrap (and ^boolean is-layout-child? + ^boolean is-layout-container?))} + [:& element-behaviour-horizontal + {:is-auto is-layout-container? + :has-fill is-layout-child? + :value (:layout-item-h-sizing values) + :on-change on-behaviour-h-change}] + [:& element-behaviour-vertical + {:is-auto is-layout-container? + :has-fill is-layout-child? + :value (:layout-item-v-sizing values) + :on-change on-behaviour-v-change}]]] (when (and is-layout-child? is-flex-parent?) [:div {:class (stl/css :row)} [:& align-self-row {:is-col is-col? - :align-self align-self - :on-change set-align-self}]]) + :value align-self + :on-change on-align-self-change}]]) (when is-layout-child? [:div {:class (stl/css :row)} - [:& margin-section {:margin (:layout-item-margin values) + [:& margin-section {:value (:layout-item-margin values) :type (:layout-item-margin-type values) - :on-type-change on-change-margin-type + :on-type-change on-margin-type-change :on-change on-margin-change}]]) (when (or (= h-sizing :fill)