From 1822103936fd2a8c924984bc610d6ad36c6c5ef0 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 9 Jan 2024 09:23:41 +0100 Subject: [PATCH 01/25] :lipstick: Make the `title-bar` component usable externally By removing the usage of `?` character on prop names --- .../src/app/main/ui/components/title_bar.cljs | 10 +++++----- .../app/main/ui/debug/components_preview.cljs | 14 +++++++------- .../app/main/ui/viewer/inspect/annotation.cljs | 6 +++--- .../ui/viewer/inspect/attributes/blur.cljs | 6 +++--- .../ui/viewer/inspect/attributes/fill.cljs | 6 +++--- .../ui/viewer/inspect/attributes/geometry.cljs | 6 +++--- .../ui/viewer/inspect/attributes/layout.cljs | 6 +++--- .../inspect/attributes/layout_element.cljs | 6 +++--- .../ui/viewer/inspect/attributes/shadow.cljs | 6 +++--- .../ui/viewer/inspect/attributes/stroke.cljs | 6 +++--- .../main/ui/viewer/inspect/attributes/svg.cljs | 6 +++--- .../ui/viewer/inspect/attributes/text.cljs | 6 +++--- .../app/main/ui/viewer/inspect/exports.cljs | 6 +++--- .../src/app/main/ui/workspace/libraries.cljs | 12 ++++++------ .../src/app/main/ui/workspace/sidebar.cljs | 4 +++- .../ui/workspace/sidebar/assets/common.cljs | 17 +++++++++-------- .../workspace/sidebar/assets/file_library.cljs | 6 +++--- .../ui/workspace/sidebar/assets/groups.cljs | 6 +++--- .../app/main/ui/workspace/sidebar/layers.cljs | 2 +- .../workspace/sidebar/options/menus/blur.cljs | 4 ++-- .../sidebar/options/menus/color_selection.cljs | 4 ++-- .../sidebar/options/menus/component.cljs | 4 ++-- .../sidebar/options/menus/constraints.cljs | 4 ++-- .../sidebar/options/menus/exports.cljs | 4 ++-- .../workspace/sidebar/options/menus/fill.cljs | 4 ++-- .../sidebar/options/menus/frame_grid.cljs | 4 ++-- .../sidebar/options/menus/grid_cell.cljs | 4 ++-- .../sidebar/options/menus/interactions.cljs | 18 +++++++++--------- .../options/menus/layout_container.cljs | 4 ++-- .../sidebar/options/menus/layout_item.cljs | 4 ++-- .../sidebar/options/menus/shadow.cljs | 4 ++-- .../sidebar/options/menus/stroke.cljs | 4 ++-- .../sidebar/options/menus/svg_attrs.cljs | 4 ++-- .../workspace/sidebar/options/menus/text.cljs | 4 ++-- .../ui/workspace/sidebar/options/page.cljs | 6 +++--- .../app/main/ui/workspace/sidebar/sitemap.cljs | 12 ++++++------ 36 files changed, 116 insertions(+), 113 deletions(-) diff --git a/frontend/src/app/main/ui/components/title_bar.cljs b/frontend/src/app/main/ui/components/title_bar.cljs index 1a78fd1340..61c664303f 100644 --- a/frontend/src/app/main/ui/components/title_bar.cljs +++ b/frontend/src/app/main/ui/components/title_bar.cljs @@ -13,23 +13,23 @@ (mf/defc title-bar {::mf/wrap-props false} - [{:keys [collapsable? collapsed? on-collapsed title children on-btn-click btn-children class clickable-all?]}] + [{:keys [collapsable collapsed on-collapsed title children on-btn-click btn-children class all-clickable]}] (let [klass (dm/str (stl/css :title-bar) " " class)] [:div {:class klass} - (if collapsable? + (if ^boolean collapsable [:div {:class (stl/css :title-wrapper)} - (if clickable-all? + (if ^boolean all-clickable [:button {:class (stl/css :toggle-btn) :on-click on-collapsed} [:span {:class (stl/css-case :collapsabled-icon true - :rotated collapsed?)} + :rotated collapsed)} i/arrow-refactor] [:div {:class (stl/css :title)} title]] [:* [:button {:class (stl/css-case :collapsabled-icon true - :rotated collapsed?) + :rotated collapsed) :on-click on-collapsed} i/arrow-refactor] [:div {:class (stl/css :title)} title]])] diff --git a/frontend/src/app/main/ui/debug/components_preview.cljs b/frontend/src/app/main/ui/debug/components_preview.cljs index 9f180aa094..c9dafa6e4a 100644 --- a/frontend/src/app/main/ui/debug/components_preview.cljs +++ b/frontend/src/app/main/ui/debug/components_preview.cljs @@ -102,26 +102,26 @@ [:h3 "Titles"] [:& component-wrapper {:title "Title"} - [:& title-bar {:collapsable? false - :title "Title"}]] + [:& title-bar {:collapsable false + :title "Title"}]] [:& component-wrapper {:title "Title and action button"} - [:& title-bar {:collapsable? false + [:& title-bar {:collapsable false :title "Title" :on-btn-click on-btn-click :btn-children i/add-refactor}]] [:& component-wrapper {:title "Collapsed title and action button"} - [:& title-bar {:collapsable? true - :collapsed? collapsed? + [:& title-bar {:collapsable true + :collapsed collapsed? :on-collapsed toggle-collapsed :title "Title" :on-btn-click on-btn-click :btn-children i/add-refactor}]] [:& component-wrapper {:title "Collapsed title and children"} - [:& title-bar {:collapsable? true - :collapsed? collapsed? + [:& title-bar {:collapsable true + :collapsed collapsed? :on-collapsed toggle-collapsed :title "Title"} [:& tab-container {:on-change-tab set-tab diff --git a/frontend/src/app/main/ui/viewer/inspect/annotation.cljs b/frontend/src/app/main/ui/viewer/inspect/annotation.cljs index a3cccae4db..7f1282f3a5 100644 --- a/frontend/src/app/main/ui/viewer/inspect/annotation.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/annotation.cljs @@ -15,9 +15,9 @@ (mf/defc annotation [{:keys [content] :as props}] [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title (tr "workspace.options.component.annotation") - :class (stl/css :title-spacing-annotation)} + [:& title-bar {:collapsable false + :title (tr "workspace.options.component.annotation") + :class (stl/css :title-spacing-annotation)} [:& copy-button {:data content}]] [:div {:class (stl/css :annotation-content)} content]]) diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/blur.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/blur.cljs index ef87631173..162fb5db8c 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/blur.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/blur.cljs @@ -21,9 +21,9 @@ (let [shapes (->> shapes (filter has-blur?))] (when (seq shapes) [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title (tr "inspect.attributes.blur") - :class (stl/css :title-spacing-blur)} + [:& title-bar {:collapsable false + :title (tr "inspect.attributes.blur") + :class (stl/css :title-spacing-blur)} (when (= (count shapes) 1) [:& copy-button {:data (css/get-css-property objects (first shapes) :filter)}])] diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/fill.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/fill.cljs index 77df200a0e..8383ca0855 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/fill.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/fill.cljs @@ -54,9 +54,9 @@ (let [shapes (filter has-fill? shapes)] (when (seq shapes) [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title (tr "inspect.attributes.fill") - :class (stl/css :title-spacing-fill)}] + [:& title-bar {:collapsable false + :title (tr "inspect.attributes.fill") + :class (stl/css :title-spacing-fill)}] [:div {:class (stl/css :attributes-content)} (for [shape shapes] diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/geometry.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/geometry.cljs index b22c157267..58e39ca5f8 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/geometry.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/geometry.cljs @@ -31,9 +31,9 @@ (mf/defc geometry-panel [{:keys [objects shapes]}] [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title (tr "inspect.attributes.size") - :class (stl/css :title-spacing-geometry)} + [:& title-bar {:collapsable false + :title (tr "inspect.attributes.size") + :class (stl/css :title-spacing-geometry)} (when (= (count shapes) 1) [:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])] diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/layout.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/layout.cljs index 0e644210b9..e015aecd16 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/layout.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/layout.cljs @@ -45,9 +45,9 @@ (when (seq shapes) [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title "Layout" - :class (stl/css :title-spacing-layout)} + [:& title-bar {:collapsable false + :title "Layout" + :class (stl/css :title-spacing-layout)} (when (= (count shapes) 1) [:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])] diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/layout_element.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/layout_element.cljs index c0efb66c3a..14eaf7f93c 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/layout_element.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/layout_element.cljs @@ -63,9 +63,9 @@ (when some-layout-prop? [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title menu-title - :class (stl/css :title-spacing-layout-element)} + [:& title-bar {:collapsable false + :title menu-title + :class (stl/css :title-spacing-layout-element)} (when (= (count shapes) 1) [:& copy-button {:data (css/get-shape-properties-css objects (first shapes) properties)}])] diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/shadow.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/shadow.cljs index 6ff7d452ea..586d4488a2 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/shadow.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/shadow.cljs @@ -53,9 +53,9 @@ (when (and (seq shapes) (> (count shapes) 0)) [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title (tr "inspect.attributes.shadow") - :class (stl/css :title-spacing-shadow)}] + [:& title-bar {:collapsable false + :title (tr "inspect.attributes.shadow") + :class (stl/css :title-spacing-shadow)}] [:div {:class (stl/css :attributes-content)} (for [shape shapes] diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/stroke.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/stroke.cljs index 64ff491041..9dd86a0352 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/stroke.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/stroke.cljs @@ -61,9 +61,9 @@ (let [shapes (->> shapes (filter has-stroke?))] (when (seq shapes) [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title (tr "inspect.attributes.stroke") - :class (stl/css :title-spacing-stroke)}] + [:& title-bar {:collapsable false + :title (tr "inspect.attributes.stroke") + :class (stl/css :title-spacing-stroke)}] [:div {:class (stl/css :attributes-content)} (for [shape shapes] diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/svg.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/svg.cljs index eb5548f54c..8df36110f0 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/svg.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/svg.cljs @@ -47,7 +47,7 @@ (let [shape (first shapes)] (when (seq (:svg-attrs shape)) [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title (tr "workspace.sidebar.options.svg-attrs.title") - :class (stl/css :title-spacing-svg)}] + [:& title-bar {:collapsable false + :title (tr "workspace.sidebar.options.svg-attrs.title") + :class (stl/css :title-spacing-svg)}] [:& svg-block {:shape shape}]]))) diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/text.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/text.cljs index 56068bcbe3..66db41c7df 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/text.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/text.cljs @@ -189,9 +189,9 @@ [{:keys [shapes]}] (when-let [shapes (seq (filter has-text? shapes))] [:div {:class (stl/css :attributes-block)} - [:& title-bar {:collapsable? false - :title (tr "inspect.attributes.typography") - :class (stl/css :title-spacing-text)}] + [:& title-bar {:collapsable false + :title (tr "inspect.attributes.typography") + :class (stl/css :title-spacing-text)}] (for [shape shapes] [:& text-block {:shape shape diff --git a/frontend/src/app/main/ui/viewer/inspect/exports.cljs b/frontend/src/app/main/ui/viewer/inspect/exports.cljs index da23a0ad76..b9847866d3 100644 --- a/frontend/src/app/main/ui/viewer/inspect/exports.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/exports.cljs @@ -136,9 +136,9 @@ vec)))) [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? false - :title (tr "workspace.options.export") - :class (stl/css :title-spacing-export-viewer)} + [:& title-bar {:collapsable false + :title (tr "workspace.options.export") + :class (stl/css :title-spacing-export-viewer)} [:button {:class (stl/css :add-export) :on-click add-export} i/add-refactor]]] diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index e8a74b563f..67dc5df167 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -199,9 +199,9 @@ [:* [:div {:class (stl/css :section)} - [:& title-bar {:collapsable? false - :title (tr "workspace.libraries.in-this-file") - :class (stl/css :title-spacing-lib)}] + [:& title-bar {:collapsable false + :title (tr "workspace.libraries.in-this-file") + :class (stl/css :title-spacing-lib)}] [:div {:class (stl/css :section-list)} [:div {:class (stl/css :section-list-item)} @@ -245,9 +245,9 @@ i/detach-refactor]])]] [:div {:class (stl/css :section)} - [:& title-bar {:collapsable? false - :title (tr "workspace.libraries.shared-libraries") - :class (stl/css :title-spacing-lib)}] + [:& title-bar {:collapsable false + :title (tr "workspace.libraries.shared-libraries") + :class (stl/css :title-spacing-lib)}] [:div {:class (stl/css :libraries-search)} [:& search-bar {:on-change change-search-term :value search-term diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index faa27b292d..d0fba4fc25 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -55,7 +55,9 @@ (mf/use-fn #(st/emit! (dw/toggle-layout-flag :collapse-left-sidebar))) on-tab-change - (mf/use-fn #(st/emit! (dw/go-to-layout %)))] + (mf/use-fn #(do + (prn "on-tab-change" %) + (st/emit! (dw/go-to-layout %))))] [:aside {:ref parent-ref :id "left-sidebar-aside" diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs index c6d63c7d3e..d421f90a92 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs @@ -136,9 +136,9 @@ title-buttons (filter #(= (get-role %) :title-button) children) content (filter #(= (get-role %) :content) children)] [:div {:class (stl/css :asset-section)} - [:& title-bar {:collapsable? true - :collapsed? (not open?) - :clickable-all? true + [:& title-bar {:collapsable true + :collapsed (not open?) + :all-clickable true :on-collapsed #(st/emit! (dw/set-assets-section-open file-id section (not open?))) :class (stl/css :title-spacing) :title (mf/html [:span {:class (stl/css :title-name)} @@ -154,6 +154,7 @@ content)])) (mf/defc asset-section-block + {::mf/wrap-props false} [{:keys [children]}] [:* children]) @@ -161,11 +162,11 @@ [rename components-to-group group-name] (let [undo-id (js/Symbol)] (st/emit! (dwu/start-undo-transaction undo-id)) - (apply st/emit! - (->> components-to-group - (map #(rename - (:id %) - (add-group % group-name))))) + (->> components-to-group + (map #(rename + (:id %) + (add-group % group-name))) + (run! st/emit!)) (st/emit! (dwu/commit-undo-transaction undo-id)))) (defn on-drop-asset diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs index f9fcbc82a3..2b025708bb 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs @@ -52,9 +52,9 @@ (fn [] (st/emit! (dw/set-assets-section-open file-id :library (not open?)))))] [:div {:class (stl/css :library-title)} - [:& title-bar {:collapsable? true - :collapsed? (not open?) - :clickable-all? true + [:& title-bar {:collapsable true + :collapsed (not open?) + :all-clickable true :on-collapsed toggle-open :title (if local? (mf/html [:div {:class (stl/css :special-title)} diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs index 2705c891cb..bbc02f72ac 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs @@ -46,9 +46,9 @@ (mf/use-fn #(swap! menu-state cmm/close-context-menu))] [:div {:class (stl/css :group-title) :on-context-menu on-context-menu} - [:& title-bar {:collapsable? true - :collapsed? (not group-open?) - :clickable-all? true + [:& title-bar {:collapsable true + :collapsed (not group-open?) + :all-clickable true :on-collapsed on-fold-group :title (mf/html [:* (when-not (empty? other-path) [:span {:class (stl/css :pre-path) diff --git a/frontend/src/app/main/ui/workspace/sidebar/layers.cljs b/frontend/src/app/main/ui/workspace/sidebar/layers.cljs index 296daa7b37..b306434959 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/layers.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/layers.cljs @@ -374,7 +374,7 @@ i/tick-refactor])]])] [:div {:class (stl/css :tool-window-bar)} - [:& title-bar {:collapsable? false + [:& title-bar {:collapsable false :title (:name page) :on-btn-click toggle-search :btn-children i/search-refactor}]]))])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs index 989d262b11..102c9e68c1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs @@ -77,8 +77,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? has-value? - :collapsed? (not open?) + [:& title-bar {:collapsable has-value? + :collapsed (not open?) :on-collapsed toggle-content :title (case type :multiple (tr "workspace.options.blur-options.title.multiple") diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs index 6dce1cc000..0fdc7d4747 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/color_selection.cljs @@ -215,8 +215,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? has-colors? - :collapsed? (not open?) + [:& title-bar {:collapsable has-colors? + :collapsed (not open?) :on-collapsed toggle-content :title (tr "workspace.options.selection-color") :class (stl/css-case :title-spacing-selected-colors (not has-colors?))}]] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index 074baa58a4..9bda71d910 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -484,8 +484,8 @@ :on-click on-component-back} [:span i/arrow-refactor] [:span (tr "workspace.options.component")]] - [:& title-bar {:collapsable? true - :collapsed? (not open?) + [:& title-bar {:collapsable true + :collapsed (not open?) :on-collapsed toggle-content :title (tr "workspace.options.component") :class (stl/css :title-spacing-component)}])] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs index 35b72810ef..d0d5b145b4 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/constraints.cljs @@ -157,8 +157,8 @@ (when in-frame? [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? true - :collapsed? (not open?) + [:& title-bar {:collapsable true + :collapsed (not open?) :on-collapsed toggle-content :title (tr "workspace.options.constraints")}]] (when open? diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs index 72556669d0..b27efded98 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/exports.cljs @@ -171,8 +171,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? has-exports? - :collapsed? (not open?) + [:& title-bar {:collapsable has-exports? + :collapsed (not open?) :on-collapsed toggle-content :title (tr (if (> (count ids) 1) "workspace.options.export-multiple" "workspace.options.export")) :class (stl/css-case :title-spacing-export (not has-exports?))} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs index 4e45960c57..eb6eff7f2c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs @@ -137,8 +137,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? has-fills? - :collapsed? (not open?) + [:& title-bar {:collapsable has-fills? + :collapsed (not open?) :on-collapsed toggle-content :title label :class (stl/css-case :title-spacing-fill (not has-fills?))} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs index 8191cf0908..0e8d126b09 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/frame_grid.cljs @@ -294,8 +294,8 @@ handle-create-grid (mf/use-fn (mf/deps id) #(st/emit! (dw/add-frame-grid id)))] [:div {:class (stl/css :element-set)} - [:& title-bar {:collapsable? has-frame-grids? - :collapsed? (not open?) + [:& title-bar {:collapsable has-frame-grids? + :collapsed (not open?) :on-collapsed toggle-content :class (stl/css-case :title-spacing-board-grid (not has-frame-grids?)) :title (tr "workspace.options.guides.title")} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs index dacb1d8d7e..f1c83cbbc2 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/grid_cell.cljs @@ -165,8 +165,8 @@ [:div {:class (stl/css :grid-cell-menu)} [:div {:class (stl/css :grid-cell-menu-title)} - [:& title-bar {:collapsable? true - :collapsed? (not open?) + [:& title-bar {:collapsable true + :collapsed (not open?) :on-collapsed #(swap! state* update :open not) :title "Grid cell"}]] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs index 42c3718019..d88daf5c40 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs @@ -157,9 +157,9 @@ [{:keys [flows]}] (when (seq flows) [:div {:class (stl/css :interaction-options)} - [:& title-bar {:collapsable? false - :title (tr "workspace.options.flows.flow-starts") - :class (stl/css :title-spacing-layout-flow)}] + [:& title-bar {:collapsable false + :title (tr "workspace.options.flows.flow-starts") + :class (stl/css :title-spacing-layout-flow)}] (for [flow flows] [:& flow-item {:flow flow :key (str (:id flow))}])])) @@ -170,9 +170,9 @@ add-flow (mf/use-fn #(st/emit! (dwi/add-flow-selected-frame)))] [:div {:class (stl/css :element-set)} - [:& title-bar {:collapsable? false - :title (tr "workspace.options.flows.flow") - :class (stl/css :title-spacing-layout-flow)} + [:& title-bar {:collapsable false + :title (tr "workspace.options.flows.flow") + :class (stl/css :title-spacing-layout-flow)} (when (nil? flow) [:button {:class (stl/css :add-flow-btn) :title (tr "workspace.options.flows.add-flow-start") @@ -712,9 +712,9 @@ [:div {:class (stl/css :interaction-options)} (when (and shape (not (cfh/unframed-shape? shape))) [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? false - :title (tr "workspace.options.interactions") - :class (stl/css :title-spacing-layout-interactions)} + [:& title-bar {:collapsable false + :title (tr "workspace.options.interactions") + :class (stl/css :title-spacing-layout-interactions)} [:button {:class (stl/css :add-interaction-btn) :on-click add-interaction} 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 b2e48ab8c9..35901bda90 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 @@ -895,8 +895,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? has-layout? - :collapsed? (not open?) + [:& title-bar {:collapsable has-layout? + :collapsed (not open?) :on-collapsed toggle-content :title "Layout" :class (stl/css-case :title-spacing-layout (not has-layout?))} 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 5d98c2b6ee..6edb371760 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 @@ -361,8 +361,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? has-content? - :collapsed? (not open?) + [:& title-bar {:collapsable has-content? + :collapsed (not open?) :on-collapsed toggle-content :title title :class (stl/css-case :title-spacing-layout-element true diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs index 063466dcc9..fb31665c45 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs @@ -288,8 +288,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? has-shadows? - :collapsed? (not open?) + [:& title-bar {:collapsable has-shadows? + :collapsed (not open?) :on-collapsed toggle-content :title (case type :multiple (tr "workspace.options.shadow-options.title.multiple") diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs index 093434da9b..337882fe97 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs @@ -163,8 +163,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? has-strokes? - :collapsed? (not open?) + [:& title-bar {:collapsable has-strokes? + :collapsed (not open?) :on-collapsed toggle-content :title label :class (stl/css-case :title-spacing-stroke (not has-strokes?))} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs index 2092e55101..3891f5556e 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/svg_attrs.cljs @@ -86,8 +86,8 @@ (when-not (empty? attrs) [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-set-title)} - [:& title-bar {:collapsable? has-attributes? - :collapsed? (not open?) + [:& title-bar {:collapsable has-attributes? + :collapsed (not open?) :on-collapsed toggle-content :title (tr "workspace.sidebar.options.svg-attrs.title") :class (stl/css-case :title-spacing-svg-attrs (not has-attributes?))}]] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs index 913630f049..882eb4aee8 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs @@ -283,8 +283,8 @@ [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? true - :collapsed? (not main-menu-open?) + [:& title-bar {:collapsable true + :collapsed (not main-menu-open?) :on-collapsed toggle-main-menu :title label :class (stl/css :title-spacing-text)} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/page.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/page.cljs index 9a99b7dbfd..791d7d3da7 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/page.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/page.cljs @@ -28,9 +28,9 @@ on-close (mf/use-fn #(st/emit! (dwu/commit-undo-transaction :options)))] [:div {:class (stl/css :element-set)} [:div {:class (stl/css :element-title)} - [:& title-bar {:collapsable? false - :title (tr "workspace.options.canvas-background") - :class (stl/css :title-spacing-page)}]] + [:& title-bar {:collapsable false + :title (tr "workspace.options.canvas-background") + :class (stl/css :title-spacing-page)}]] [:div {:class (stl/css :element-content)} [:& color-row {:disable-gradient true diff --git a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs index 0c0d6a94b4..071a5a6423 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs @@ -210,12 +210,12 @@ [:div {:class (stl/css :sitemap) :style #js {"--height" (str size "px")}} - [:& title-bar {:collapsable? true - :collapsed? (not show-pages?) - :on-collapsed toggle-pages - :clickable-all? true - :title (tr "workspace.sidebar.sitemap") - :class (stl/css :title-spacing-sitemap)} + [:& title-bar {:collapsable true + :collapsed (not show-pages?) + :on-collapsed toggle-pages + :all-clickable true + :title (tr "workspace.sidebar.sitemap") + :class (stl/css :title-spacing-sitemap)} (if ^boolean read-only? [:di {:class (stl/css :view-only-mode)} From 97d6214ff498739c3f59fe7ffddd53e94ccea355 Mon Sep 17 00:00:00 2001 From: Tsiura Vasyl Date: Fri, 15 Dec 2023 20:25:25 +0200 Subject: [PATCH 02/25] :sparkles: Add set of events for hiding and revealing bounding box for selected shape Signed-off-by: Tsiura Vasyl --- frontend/src/app/main/data/workspace.cljs | 1 + .../src/app/main/data/workspace/shapes.cljs | 7 ++++--- .../app/main/data/workspace/transforms.cljs | 21 +++++++++++++++++++ .../sidebar/options/menus/measures.cljs | 7 +++++-- .../main/ui/workspace/viewport/outline.cljs | 3 ++- .../main/ui/workspace/viewport/selection.cljs | 6 ++++-- 6 files changed, 37 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index edb21077c4..8f0d9a6c37 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -2304,6 +2304,7 @@ ;; Transform +(dm/export dwt/trigger-bounding-box-cloaking) (dm/export dwt/start-resize) (dm/export dwt/update-dimensions) (dm/export dwt/change-orientation) diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index 3bfe0e2666..cf82d2a16b 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -369,7 +369,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defn update-shape-flags - [ids {:keys [blocked hidden] :as flags}] + [ids {:keys [blocked hidden transforming] :as flags}] (dm/assert! "expected valid coll of uuids" (every? uuid? ids)) @@ -385,14 +385,15 @@ (fn [obj] (cond-> obj (boolean? blocked) (assoc :blocked blocked) - (boolean? hidden) (assoc :hidden hidden))) + (boolean? hidden) (assoc :hidden hidden) + (boolean? transforming) (assoc :transforming transforming))) objects (wsh/lookup-page-objects state) ;; We have change only the hidden behaviour, to hide only the ;; selected shape, block behaviour remains the same. ids (if (boolean? blocked) (into ids (->> ids (mapcat #(cfh/get-children-ids objects %)))) ids)] - (rx/of (dch/update-shapes ids update-fn {:attrs #{:blocked :hidden}})))))) + (rx/of (dch/update-shapes ids update-fn {:attrs #{:blocked :hidden :transforming}})))))) (defn toggle-visibility-selected [] diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 5cc82e5b07..5a232caf0c 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -28,6 +28,7 @@ [app.main.data.workspace.collapse :as dwc] [app.main.data.workspace.modifiers :as dwm] [app.main.data.workspace.selection :as dws] + [app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.undo :as dwu] [app.main.snap :as snap] @@ -240,6 +241,26 @@ (rx/of (dwm/apply-modifiers) (finish-transform)))))))) +(defn trigger-bounding-box-cloaking + "Trigger the bounding box cloaking (with default timer of 1sec) + + Used to hide bounding-box of shape after changes in sidebar->measures." + [ids] + (dm/assert! + "expected valid coll of uuids" + (every? uuid? ids)) + + (ptk/reify ::trigger-bounding-box-cloaking + ptk/WatchEvent + (watch [_ _ stream] + (rx/concat + (rx/of (dwsh/update-shape-flags ids {:transforming true})) + (->> (rx/timer 1000) + (rx/map (fn [] + (dwsh/update-shape-flags ids {:transforming false}))) + (rx/take-until + (rx/filter (ptk/type? ::trigger-bounding-box-cloaking) stream))))))) + (defn update-dimensions "Change size of shapes, from the sideber options form. Will ignore pixel snap used in the options side panel" diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index fc408f592e..4a4879fb96 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -214,7 +214,8 @@ (mf/use-fn (mf/deps ids) (fn [value attr] - (st/emit! (udw/update-dimensions ids attr value)))) + (st/emit! (udw/trigger-bounding-box-cloaking ids) + (udw/update-dimensions ids attr value)))) on-proportion-lock-change (mf/use-fn @@ -236,6 +237,7 @@ (mf/use-fn (mf/deps ids) (fn [value attr] + (st/emit! (udw/trigger-bounding-box-cloaking ids)) (doall (map #(do-position-change %1 %2 value attr) shapes frames)))) ;; ROTATION @@ -244,7 +246,8 @@ (mf/use-fn (mf/deps ids) (fn [value] - (st/emit! (udw/increase-rotation ids value)))) + (st/emit! (udw/trigger-bounding-box-cloaking ids) + (udw/increase-rotation ids value)))) ;; RADIUS diff --git a/frontend/src/app/main/ui/workspace/viewport/outline.cljs b/frontend/src/app/main/ui/workspace/viewport/outline.cljs index a87178749a..13d5b2cf05 100644 --- a/frontend/src/app/main/ui/workspace/viewport/outline.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/outline.cljs @@ -114,7 +114,8 @@ (defn- show-outline? [shape] (and (not (:hidden shape)) - (not (:blocked shape)))) + (not (:blocked shape)) + (not (:transforming shape)))) (mf/defc shape-outlines {::mf/wrap-props false} diff --git a/frontend/src/app/main/ui/workspace/viewport/selection.cljs b/frontend/src/app/main/ui/workspace/viewport/selection.cljs index 65437ed8d9..dbe07b117e 100644 --- a/frontend/src/app/main/ui/workspace/viewport/selection.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/selection.cljs @@ -279,7 +279,8 @@ selrect (:selrect shape) transform (gsh/transform-str shape)] - (when (not (#{:move :rotate} current-transform)) + (when (and (not (:transforming shape)) + (not (#{:move :rotate} current-transform))) [:g.controls {:pointer-events (if disable-handlers "none" "visible")} ;; Selection rect [:& selection-rect {:rect selrect @@ -310,7 +311,8 @@ (mod 360))] (when (and (not (#{:move :rotate} current-transform)) - (not workspace-read-only?)) + (not workspace-read-only?) + (not (:transforming shape))) [:g.controls {:pointer-events (if disable-handlers "none" "visible")} ;; Handlers (for [{:keys [type position props]} (handlers-for-selection selrect shape zoom)] From 5c2bdfcefe8ab9217517f59927671145403ee752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Tue, 9 Jan 2024 13:42:16 +0100 Subject: [PATCH 03/25] :bug: Fix icon color for Give Feedback in Your Account sidebar --- frontend/src/app/main/ui/settings/sidebar.scss | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/ui/settings/sidebar.scss b/frontend/src/app/main/ui/settings/sidebar.scss index e5e05cef46..c7593f9b26 100644 --- a/frontend/src/app/main/ui/settings/sidebar.scss +++ b/frontend/src/app/main/ui/settings/sidebar.scss @@ -49,6 +49,7 @@ display: flex; flex-shrink: 0; padding: $s-8 $s-8 $s-8 $s-24; + color: $df-secondary; a { font-weight: $fw400; @@ -59,14 +60,13 @@ } svg { - fill: $db-secondary; + fill: currentColor; margin-right: $s-8; height: $s-12; width: $s-12; } span { - color: $df-secondary; font-size: $fs-14; overflow: hidden; text-overflow: ellipsis; @@ -119,12 +119,11 @@ &.current { background-color: $db-cuaternary; + color: $da-primary; + a { font-weight: $fw400; - color: $da-primary; - } - span { - color: $da-primary; + color: currentColor; } &::before { From fa99d9aaedcaf421817cef128243409502c1ab56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Tue, 9 Jan 2024 14:24:02 +0100 Subject: [PATCH 04/25] :bug: Fix buttons appearance in the feedback form --- frontend/resources/styles/common/refactor/basic-rules.scss | 3 +++ frontend/src/app/main/ui/settings/feedback.cljs | 5 +++-- frontend/src/app/main/ui/settings/feedback.scss | 4 ++++ frontend/src/app/main/ui/settings/profile.scss | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/frontend/resources/styles/common/refactor/basic-rules.scss b/frontend/resources/styles/common/refactor/basic-rules.scss index 5b79ec81da..d8b30487f6 100644 --- a/frontend/resources/styles/common/refactor/basic-rules.scss +++ b/frontend/resources/styles/common/refactor/basic-rules.scss @@ -38,10 +38,12 @@ @include buttonStyle; @include flexCenter; @include focusPrimary; + @include tabTitleTipography; background-color: var(--button-primary-background-color-rest); border: $s-1 solid var(--button-primary-border-color-rest); color: var(--button-primary-foreground-color-rest); border-radius: $br-8; + min-height: $s-32; svg, span svg { stroke: var(--button-primary-foreground-color-rest); @@ -54,6 +56,7 @@ span svg { stroke: var(--button-primary-foreground-color-hover); } + text-decoration: none; } &:active { background-color: var(--button-primary-background-color-active); diff --git a/frontend/src/app/main/ui/settings/feedback.cljs b/frontend/src/app/main/ui/settings/feedback.cljs index 82daf3c5b4..31d9d374cf 100644 --- a/frontend/src/app/main/ui/settings/feedback.cljs +++ b/frontend/src/app/main/ui/settings/feedback.cljs @@ -80,6 +80,7 @@ [:> fm/submit-button* {:label (if @loading (tr "labels.sending") (tr "labels.send")) + :class (stl/css :feedback-button-link) :disabled @loading}] [:hr] @@ -88,7 +89,7 @@ [:p {:class (stl/css :field-text)} (tr "feedback.discourse-subtitle1")] [:a - {:class (stl/css :btn-secondary :btn-large) + {:class (stl/css :feedback-button-link) :href "https://community.penpot.app" :target "_blank"} (tr "feedback.discourse-go-to")] @@ -98,7 +99,7 @@ [:p {:class (stl/css :field-text)} (tr "feedback.twitter-subtitle1")] [:a - {:class (stl/css :btn-secondary :btn-large) + {:class (stl/css :feedback-button-link) :href "https://twitter.com/penpotapp" :target "_blank"} (tr "feedback.twitter-go-to")]])) diff --git a/frontend/src/app/main/ui/settings/feedback.scss b/frontend/src/app/main/ui/settings/feedback.scss index dec2597db0..f2638a7f54 100644 --- a/frontend/src/app/main/ui/settings/feedback.scss +++ b/frontend/src/app/main/ui/settings/feedback.scss @@ -23,3 +23,7 @@ } } } + +.feedback-button-link { + @extend .button-primary; +} diff --git a/frontend/src/app/main/ui/settings/profile.scss b/frontend/src/app/main/ui/settings/profile.scss index e33ef5a3ad..59e22acbbc 100644 --- a/frontend/src/app/main/ui/settings/profile.scss +++ b/frontend/src/app/main/ui/settings/profile.scss @@ -11,7 +11,7 @@ width: 100%; justify-content: center; align-items: center; - a { + a:not(.button-primary) { color: $df-secondary; } } @@ -211,7 +211,7 @@ text-transform: uppercase; } - a { + a:not(.button-primary) { &:hover { text-decoration: underline; } From 5c3ea37bbef51d21b00814c0b0558afddc7f455c Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 9 Jan 2024 15:41:54 +0100 Subject: [PATCH 05/25] :bug: Fix problem with create board on cells --- common/src/app/common/types/shape/layout.cljc | 2 -- .../main/ui/workspace/viewport/grid_layout_editor.cljs | 8 +++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index 43e446978b..5a48aa0162 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -1111,7 +1111,6 @@ (defn assign-cell-positions [parent objects] - (prn ">>>>assign-cell-positions" (:name parent)) (-> parent (check-deassigned-cells objects) (reassign-positions) @@ -1128,7 +1127,6 @@ ;; - (maybe) create group/frames. This case will assigna a cell that had one of its children (defn assign-cells [parent objects] - (prn ">assign-cells") (let [parent (assign-cell-positions parent objects) shape-has-cell? 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 0e95f631fd..52f4cf8b3b 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 @@ -341,11 +341,17 @@ handle-context-menu (mf/use-callback + (mf/deps (:id shape) (:id cell) selected?) (fn [event] (dom/prevent-default event) (dom/stop-propagation event) (let [position (dom/get-client-position event)] - (st/emit! (dw/show-grid-cell-context-menu {:position position :grid-id (:id shape)})))))] + (if selected? + (st/emit! (dw/show-grid-cell-context-menu {:position position :grid-id (:id shape)})) + + ;; If right-click on a non-selected cell we select the cell and then open the menu + (st/emit! (dwge/set-selection (:id shape) (:id cell)) + (dw/show-grid-cell-context-menu {:position position :grid-id (:id shape)}))))))] [:g.cell-editor ;; DEBUG OVERLAY From a4796e8db8e9a69386428dbd77693798eedea4b2 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 9 Jan 2024 15:42:15 +0100 Subject: [PATCH 06/25] :bug: Fix swap component breaks grid layout --- .../app/main/data/workspace/libraries.cljs | 25 +++++++++++++------ .../sidebar/options/menus/component.scss | 1 + 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index c2a624a2ad..a36f660e7d 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -825,12 +825,11 @@ second) 0))))) -(defn- component-swap - "Swaps a component with another one" +(defn- add-component-for-swap [shape file-id id-new-component] (dm/assert! (uuid? id-new-component)) (dm/assert! (uuid? file-id)) - (ptk/reify ::component-swap + (ptk/reify ::add-component-for-swap ptk/WatchEvent (watch [it state _] (let [page (wsh/lookup-page state) @@ -856,12 +855,24 @@ ;; We need to set the same index as the original shape changes (pcb/change-parent changes (:parent-id shape) [new-shape] index {:component-swap true})] + + ;; First delete so we don't break the grid layout cells (rx/of (dch/commit-changes changes) - (ptk/data-event :layout/update [(:id new-shape)]) - (dws/select-shape (:id new-shape) true) - (dwsh/delete-shapes nil (d/ordered-set (:id shape)) {:component-swap true})))))) - + (dws/select-shape (:id new-shape) true)))))) +(defn- component-swap + "Swaps a component with another one" + [shape file-id id-new-component] + (dm/assert! (uuid? id-new-component)) + (dm/assert! (uuid? file-id)) + (ptk/reify ::component-swap + ptk/WatchEvent + (watch [_ _ _] + ;; First delete shapes so we have space in the layout otherwise we can have problems + ;; in the grid creating new rows/columns to make space + (rx/of (dwsh/delete-shapes nil (d/ordered-set (:id shape)) {:component-swap true}) + (add-component-for-swap shape file-id id-new-component) + (ptk/data-event :layout/update [(:parent-id shape)]))))) (defn component-multi-swap "Swaps several components with another one" diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss index 7c620a2f47..1c190f2d7f 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss @@ -213,6 +213,7 @@ .component-list-empty { @include titleTipography; margin: 0 $s-4 0 $s-8; + color: $df-secondary; } .component-list { From 9c35652043e7d6946f3d1430aba699bf77c92ded Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 9 Jan 2024 17:10:12 +0100 Subject: [PATCH 07/25] :bug: Fix problem with font loading --- frontend/src/app/main/fonts.cljs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/app/main/fonts.cljs b/frontend/src/app/main/fonts.cljs index b6c8b2bf1c..f934966d9f 100644 --- a/frontend/src/app/main/fonts.cljs +++ b/frontend/src/app/main/fonts.cljs @@ -211,7 +211,7 @@ ;; Font is currently downloading. We attach the caller to the promise (contains? @loading font-id) - (p/resolved (get @loading font-id)) + (get @loading font-id) ;; First caller, we create the promise and then wait :else @@ -220,13 +220,13 @@ (swap! loading dissoc font-id) (resolve font-id)) - load-p (->> (p/create - (fn [resolve _] - (-> font - (assoc ::on-loaded (partial on-load resolve)) - (load-font)))) + load-p (-> (p/create + (fn [resolve _] + (-> font + (assoc ::on-loaded (partial on-load resolve)) + (load-font)))) ;; We need to wait for the font to be loaded - (p/delay 120))] + (p/then (partial p/delay 120)))] (swap! loading assoc font-id load-p) load-p)))))) From 443d157dbe7e22c6957d69569ad057208f95941b Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 9 Jan 2024 11:20:05 +0100 Subject: [PATCH 08/25] :bug: Fix notification modal styles --- .../app/main/data/workspace/libraries.cljs | 2 + frontend/src/app/main/ui/messages.cljs | 9 +++- frontend/src/app/main/ui/messages.scss | 41 ++++++++++++++++--- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index a36f660e7d..091cbe92c1 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -1060,8 +1060,10 @@ :links [{:label (tr "workspace.updates.more-info") :callback do-more-info}] :actions [{:label (tr "workspace.updates.update") + :type :primary :callback do-update} {:label (tr "workspace.updates.dismiss") + :type :secondary :callback do-dismiss}] :tag :sync-dialog))))))) diff --git a/frontend/src/app/main/ui/messages.cljs b/frontend/src/app/main/ui/messages.cljs index 489eae2a60..1d64e42259 100644 --- a/frontend/src/app/main/ui/messages.cljs +++ b/frontend/src/app/main/ui/messages.cljs @@ -46,17 +46,22 @@ content (for [[index link] (d/enumerate links)] [:* {:key (dm/str "link-" index)} - " " [:& lb/link-button {:class "link" + " " [:& lb/link-button {:class (stl/css :link) :on-click (:callback link) :value (:label link)}]])] (when (or (= controls :bottom-actions) (= controls :inline-actions)) + [:div {:class (stl/css :actions)} (for [action actions] [:button {:key (uuid/next) - :class (stl/css :action-bnt) + :class (stl/css-case :action-btn true + :primary (= :primary (:type action)) + :secondary (= :secondary (:type action)) + :danger (= :danger (:type action))) :on-click (:callback action)} (:label action)])])] + (when (= controls :close) [:button {:class (stl/css :btn-close) :on-click on-close} i/close-refactor])]]) diff --git a/frontend/src/app/main/ui/messages.scss b/frontend/src/app/main/ui/messages.scss index e2a571c8f7..03ad9dfed9 100644 --- a/frontend/src/app/main/ui/messages.scss +++ b/frontend/src/app/main/ui/messages.scss @@ -16,6 +16,7 @@ background-color: var(--bg-color); color: var(--fg-color); } + .warning { --bg-color: var(--alert-background-color-warning); --fg-color: var(--alert-foreground-color-warning); @@ -30,16 +31,18 @@ --bg-color: var(--alert-background-color-neutral); --fg-color: var(--alert-foreground-color-neutral-active); } + .banner.info .icon { --fg-color: var(--alert-foreground-color-neutral); } + .banner.info:hover .icon { --fg-color: var(--alert-foreground-color-neutral); } .wrapper { - display: grid; - grid-template-columns: $s-16 1fr $s-40; + display: flex; + align-items: center; padding: $s-8 $s-8 $s-8 $s-16; gap: $s-8; height: 100%; @@ -94,20 +97,46 @@ .content { @include flexRow; + gap: $s-8; + flex-grow: 1; } .text { @include titleTipography; + flex-grow: 1; +} + +.link { + @include titleTipography; + color: var(--modal-link-foreground-color); + margin: 0; +} + +.actions { + @include flexRow; + gap: $s-8; } .action-btn { @extend .button-tertiary; - height: $s-32; - width: $s-32; - color: black; + @include tabTitleTipography; + min-height: $s-32; + min-width: $s-32; svg { @extend .button-icon-small; } + &.primary { + @extend .button-primary; + padding: $s-8 $s-24; + } + &.secondary { + @extend .button-secondary; + padding: $s-8 $s-24; + } + &.danger { + @extend .modal-danger-btn; + padding: $s-8 $s-24; + } } .btn-close { @@ -116,6 +145,6 @@ width: $s-32; svg { @extend .button-icon-small; - stroke: black; + stroke: var(--icon-foreground); } } From 5cb8ce331995e6e3019b4c75308142b9a96e3fd7 Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 9 Jan 2024 12:06:01 +0100 Subject: [PATCH 09/25] :bug: Fix loader position while verifying token --- .../styles/common/refactor/basic-rules.scss | 16 ++++++++++++++++ frontend/src/app/main/ui/auth/verify_token.scss | 4 ++++ frontend/src/app/main/ui/loader.cljs | 4 +++- frontend/src/app/main/ui/loader.scss | 11 +++++++++++ frontend/src/app/main/ui/viewer.cljs | 2 +- frontend/src/app/main/ui/viewer.scss | 4 ++-- frontend/src/app/main/ui/workspace.scss | 4 +--- 7 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 frontend/src/app/main/ui/loader.scss diff --git a/frontend/resources/styles/common/refactor/basic-rules.scss b/frontend/resources/styles/common/refactor/basic-rules.scss index 5b79ec81da..9e22e1869c 100644 --- a/frontend/resources/styles/common/refactor/basic-rules.scss +++ b/frontend/resources/styles/common/refactor/basic-rules.scss @@ -600,6 +600,22 @@ color: var(--modal-button-foreground-color-error); } +.loader-base { + @include flexCenter; + position: fixed; + top: 0; + left: 0; + height: 100vh; + width: 100vw; + z-index: $z-index-alert; + background-color: var(--loader-background); + :global(svg#loader-pencil) { + height: $s-100; + width: $s-100; + animation: loaderColor 5s infinite ease; + fill: var(--icon-foreground); + } +} // UI ELEMENTS .asset-element { @include titleTipography; diff --git a/frontend/src/app/main/ui/auth/verify_token.scss b/frontend/src/app/main/ui/auth/verify_token.scss index b0002114f9..df815d4f4b 100644 --- a/frontend/src/app/main/ui/auth/verify_token.scss +++ b/frontend/src/app/main/ui/auth/verify_token.scss @@ -5,3 +5,7 @@ // Copyright (c) KALEIDOS INC @use "./common.scss"; + +.verify-token { + @extend .loader-base; +} diff --git a/frontend/src/app/main/ui/loader.cljs b/frontend/src/app/main/ui/loader.cljs index 393de79d6b..43a7901815 100644 --- a/frontend/src/app/main/ui/loader.cljs +++ b/frontend/src/app/main/ui/loader.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.loader + (:require-macros [app.main.style :as stl]) (:require [app.main.store :as st] [app.main.ui.icons :as i] @@ -15,4 +16,5 @@ (mf/defc loader [] (when (mf/deref st/loader) - [:div.loader-content i/loader-pencil])) + [:div {:class (stl/css :loader-content)} + i/loader-pencil])) diff --git a/frontend/src/app/main/ui/loader.scss b/frontend/src/app/main/ui/loader.scss new file mode 100644 index 0000000000..71121f51d9 --- /dev/null +++ b/frontend/src/app/main/ui/loader.scss @@ -0,0 +1,11 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC + +@import "refactor/common-refactor.scss"; + +.loader-content { + @extend .loader-base; +} diff --git a/frontend/src/app/main/ui/viewer.cljs b/frontend/src/app/main/ui/viewer.cljs index 68f19b9cf8..651a7c8061 100644 --- a/frontend/src/app/main/ui/viewer.cljs +++ b/frontend/src/app/main/ui/viewer.cljs @@ -607,6 +607,6 @@ (let [props (obj/merge props #js {:data data :key (dm/str file-id)})] [:> viewer-content props]) - [:div.loader-content.viewer-loader + [:div {:class (stl/css :loader-content)} i/loader-pencil])) diff --git a/frontend/src/app/main/ui/viewer.scss b/frontend/src/app/main/ui/viewer.scss index 897cf905af..351d4414de 100644 --- a/frontend/src/app/main/ui/viewer.scss +++ b/frontend/src/app/main/ui/viewer.scss @@ -175,8 +175,8 @@ } } -:global(svg#loader-pencil) { - fill: var(--icon-foreground); +.loader-content { + @extend .loader-base; } /** FULLSCREEN */ diff --git a/frontend/src/app/main/ui/workspace.scss b/frontend/src/app/main/ui/workspace.scss index 410c831862..a9e8a35a72 100644 --- a/frontend/src/app/main/ui/workspace.scss +++ b/frontend/src/app/main/ui/workspace.scss @@ -30,9 +30,7 @@ grid-template-columns: auto 1fr auto; .workspace-loader { - display: flex; - justify-content: center; - align-items: center; + @include flexCenter; grid-area: viewport; background-color: var(--loader-background); :global(svg#loader-pencil) { From a8a784bea4e3807e88c1ff5782af2539c277c990 Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 9 Jan 2024 16:17:31 +0100 Subject: [PATCH 10/25] :bug: Fix icons preview page --- .../resources/images/icons/open-refactor.svg | 1 - .../main/partials/debug-icons-preview.scss | 41 +++++++++++++++++-- frontend/src/app/main/ui/icons.cljs | 11 ++--- 3 files changed, 44 insertions(+), 9 deletions(-) delete mode 100644 frontend/resources/images/icons/open-refactor.svg diff --git a/frontend/resources/images/icons/open-refactor.svg b/frontend/resources/images/icons/open-refactor.svg deleted file mode 100644 index 294e1741b2..0000000000 --- a/frontend/resources/images/icons/open-refactor.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/resources/styles/main/partials/debug-icons-preview.scss b/frontend/resources/styles/main/partials/debug-icons-preview.scss index e08f1d274b..7634858902 100644 --- a/frontend/resources/styles/main/partials/debug-icons-preview.scss +++ b/frontend/resources/styles/main/partials/debug-icons-preview.scss @@ -3,14 +3,33 @@ flex-direction: column; overflow: scroll; height: 100%; + h1 { + color: white; + font-size: 24px; + display: block; + width: 100vw; + margin: 12px; + } } .debug-icons-preview { display: flex; flex-wrap: wrap; + h2 { + color: white; + font-size: 16px; + display: block; + width: 100vw; + margin: 12px; + } + + .subtitle-old { + color: #ff3277; + } .icon-item, - .cursor-item { + .cursor-item, + .icon-item-old { padding: 10px; display: flex; flex-direction: column; @@ -24,12 +43,28 @@ height: 100%; min-width: 16px; min-height: 16px; - fill: black; fill: none; color: transparent; - stroke: black; + stroke: #91fadb; + } + + span { + color: white; + max-width: 100px; + overflow: hidden; + font-size: 12px; + margin-top: 4px; + word-break: break-word; + min-height: 40px; } } + + .cursor-item div, + .icon-item-old svg { + fill: #aab5ba; + stroke: none; + } + .cursor-item { height: auto; } diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs index 05d45d0759..f73fef49be 100644 --- a/frontend/src/app/main/ui/icons.cljs +++ b/frontend/src/app/main/ui/icons.cljs @@ -400,7 +400,6 @@ (def ^:icon msg-warning-refactor (icon-xref :msg-warning-refactor)) (def ^:icon move-refactor (icon-xref :move-refactor)) (def ^:icon open-link-refactor (icon-xref :open-link-refactor)) -(def ^:icon open-refactor (icon-xref :open-refactor)) (def ^:icon padding-bottom-refactor (icon-xref :padding-bottom-refactor)) (def ^:icon padding-top-refactor (icon-xref :padding-top-refactor)) (def ^:icon padding-top-bottom-refactor (icon-xref :padding-top-bottom-refactor)) @@ -496,17 +495,19 @@ refactor? (fn [[key]] (str/ends-with? key "Refactor"))] [:* [:section.debug-icons-preview - [:h2 "Classic"] + [:h2.subtitle-old "Classic (Deprecated)"] (for [[key val] (remove refactor? entries)] - [:div.icon-item {:key key} + [:div.icon-item-old {:key key + :title key} val [:span key]])] [:section.debug-icons-preview [:h2 "Refactor"] (for [[key val] (filter refactor? entries)] - [:div.icon-item {:key key} - (deref val) + [:div.icon-item {:key key + :title key} + val [:span key]])]])) (defn key->icon From df99ca55f85c5d8479d00c1991983b4a85ef14e3 Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 9 Jan 2024 17:47:51 +0100 Subject: [PATCH 11/25] :bug: Fix spacing in prototype tab empty state --- .../src/app/main/ui/viewer/inspect/right_sidebar.scss | 3 ++- .../ui/workspace/sidebar/options/menus/interactions.scss | 9 +++++++-- frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/viewer/inspect/right_sidebar.scss b/frontend/src/app/main/ui/viewer/inspect/right_sidebar.scss index 3074e676ae..b66e44ce7e 100644 --- a/frontend/src/app/main/ui/viewer/inspect/right_sidebar.scss +++ b/frontend/src/app/main/ui/viewer/inspect/right_sidebar.scss @@ -62,7 +62,8 @@ @include flexColumn; align-items: center; justify-content: flex-start; - gap: $s-8; + gap: $s-12; + margin-right: $s-8; } .placeholder-icon { diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.scss index 9ab6a9d811..93d9bb5626 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.scss @@ -27,11 +27,17 @@ } .help-content { - padding: $s-20; + padding: $s-32 0; + width: $s-200; + margin: 0 auto; } .help-group { + display: flex; + flex-direction: column; + align-items: center; margin-bottom: $s-40; + gap: $s-12; } .interactions-help-icon { @@ -40,7 +46,6 @@ height: $s-48; border-radius: $br-circle; background-color: var(--pill-background-color); - margin: 0 auto $s-12 auto; svg { @extend .button-icon; stroke: var(--icon-foreground); diff --git a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs index 071a5a6423..f40719327d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs @@ -218,7 +218,7 @@ :class (stl/css :title-spacing-sitemap)} (if ^boolean read-only? - [:di {:class (stl/css :view-only-mode)} + [:div {:class (stl/css :view-only-mode)} (tr "labels.view-only")] [:button {:class (stl/css :add-page) :on-click on-create} From 9d8628b4cc150f1270580a07539cf2e800ed2100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Mon, 8 Jan 2024 16:23:36 +0100 Subject: [PATCH 12/25] :bug: Fix groups without :shapes when converting to frames in migration --- backend/src/app/features/components_v2.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/app/features/components_v2.clj b/backend/src/app/features/components_v2.clj index 45c196f47a..c85719b83b 100644 --- a/backend/src/app/features/components_v2.clj +++ b/backend/src/app/features/components_v2.clj @@ -255,6 +255,7 @@ (assoc shape :type :frame ; Old groups must be converted :fills (or (:fills shape) []) ; to frames and conform to spec + :shapes (or (:shapes shape) []) :hide-in-viewer (or (:hide-in-viewer shape) true) :rx (or (:rx shape) 0) :ry (or (:ry shape) 0)) From 4d6c0f3da9f7a70f76bd93c16576e4deb4a334a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Mon, 8 Jan 2024 16:24:01 +0100 Subject: [PATCH 13/25] :bug: Fix debug validate single shape --- common/src/app/common/files/validate.cljc | 3 --- frontend/src/debug.cljs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/common/src/app/common/files/validate.cljc b/common/src/app/common/files/validate.cljc index 280271701d..1c25b82dcd 100644 --- a/common/src/app/common/files/validate.cljc +++ b/common/src/app/common/files/validate.cljc @@ -502,6 +502,3 @@ :hint "error on validating file referential integrity" :file-id (:id file) :details errors))) - - - diff --git a/frontend/src/debug.cljs b/frontend/src/debug.cljs index 56b36406af..5090efc5c2 100644 --- a/frontend/src/debug.cljs +++ b/frontend/src/debug.cljs @@ -393,7 +393,7 @@ (try (->> (if-let [shape-id (some-> shape-id parse-uuid)] (let [page (dm/get-in file [:data :pages-index (get @st/state :current-page-id)])] - (cfv/validate-shape (uuid shape-id) file page libraries)) + (cfv/validate-shape shape-id file page libraries)) (cfv/validate-file file libraries)) (group-by :code) (clj->js)) From b7b7b9d58005cc2dd57288738c2ad6a3c2bba2dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Tue, 9 Jan 2024 13:02:52 +0100 Subject: [PATCH 14/25] :bug: Touch modified file when ignore sync, to avoid ETAG caching --- backend/src/app/rpc/commands/files.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index 58b10742d7..61586ed52e 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -1030,7 +1030,8 @@ (defn ignore-sync [conn {:keys [file-id date] :as params}] (db/update! conn :file - {:ignore-sync-until date} + {:ignore-sync-until date + :modified-at (dt/now)} {:id file-id} {::db/return-keys true})) From 9e40b4551d439c71a770a13c6668949cc19c9788 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 9 Jan 2024 22:29:27 +0100 Subject: [PATCH 15/25] :bug: Fix problem with swap component --- .../src/app/main/data/workspace/libraries.cljs | 18 +++++++++++++----- .../main/data/workspace/libraries_helpers.cljs | 6 +++++- .../src/app/main/ui/workspace/sidebar.cljs | 4 +--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 091cbe92c1..292265dd95 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -20,6 +20,7 @@ [app.common.types.components-list :as ctkl] [app.common.types.container :as ctn] [app.common.types.file :as ctf] + [app.common.types.shape.layout :as ctl] [app.common.types.typography :as ctt] [app.common.uuid :as uuid] [app.main.data.events :as ev] @@ -826,7 +827,7 @@ 0))))) (defn- add-component-for-swap - [shape file-id id-new-component] + [shape file-id id-new-component target-cell] (dm/assert! (uuid? id-new-component)) (dm/assert! (uuid? file-id)) (ptk/reify ::add-component-for-swap @@ -840,6 +841,7 @@ position (gpt/point (:x shape) (:y shape)) changes (-> (pcb/empty-changes it (:id page)) (pcb/with-objects objects)) + position (-> position (with-meta {:cell target-cell})) [new-shape changes] (dwlh/generate-instantiate-component changes @@ -867,12 +869,18 @@ (dm/assert! (uuid? file-id)) (ptk/reify ::component-swap ptk/WatchEvent - (watch [_ _ _] + (watch [_ state _] ;; First delete shapes so we have space in the layout otherwise we can have problems ;; in the grid creating new rows/columns to make space - (rx/of (dwsh/delete-shapes nil (d/ordered-set (:id shape)) {:component-swap true}) - (add-component-for-swap shape file-id id-new-component) - (ptk/data-event :layout/update [(:parent-id shape)]))))) + (let [objects (wsh/lookup-page-objects state) + parent (get objects (:parent-id shape)) + + ;; If the target parent is a grid layout we need to pass the target cell + target-cell (when (ctl/grid-layout? parent) + (ctl/get-cell-by-shape-id parent (:id shape)))] + (rx/of (dwsh/delete-shapes nil (d/ordered-set (:id shape)) {:component-swap true}) + (add-component-for-swap shape file-id id-new-component target-cell) + (ptk/data-event :layout/update [(:parent-id shape)])))))) (defn component-multi-swap "Swaps several components with another one" diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index 937079b2bd..1d9c11318f 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -177,7 +177,11 @@ changes (if (ctl/grid-layout? objects (:parent-id first-shape)) - (let [[row column] (gslg/get-drop-cell (:parent-id first-shape) objects position)] + (let [target-cell (-> position meta :cell) + [row column] + (if (some? target-cell) + [(:row target-cell) (:column target-cell)] + (gslg/get-drop-cell (:parent-id first-shape) objects position))] (-> changes (pcb/update-shapes [(:parent-id first-shape)] diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index d0fba4fc25..faa27b292d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -55,9 +55,7 @@ (mf/use-fn #(st/emit! (dw/toggle-layout-flag :collapse-left-sidebar))) on-tab-change - (mf/use-fn #(do - (prn "on-tab-change" %) - (st/emit! (dw/go-to-layout %))))] + (mf/use-fn #(st/emit! (dw/go-to-layout %)))] [:aside {:ref parent-ref :id "left-sidebar-aside" From 5502f317ad846dfec74b313fcf7d085078920c3f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 9 Jan 2024 23:10:14 +0100 Subject: [PATCH 16/25] :bug: Fix unexpected exception on incorrect thumbnail gen of root shape --- common/src/app/common/files/helpers.cljc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/src/app/common/files/helpers.cljc b/common/src/app/common/files/helpers.cljc index 701575583d..01507eea09 100644 --- a/common/src/app/common/files/helpers.cljc +++ b/common/src/app/common/files/helpers.cljc @@ -32,13 +32,17 @@ ([objects id] (is-direct-child-of-root? (get objects id))) ([shape] - (and (some? shape) (= (dm/get-prop shape :frame-id) uuid/zero)))) + (and (some? shape) + (= (dm/get-prop shape :frame-id) uuid/zero)))) (defn root-frame? ([objects id] - (root-frame? (get objects id))) + (if (= id uuid/zero) + false + (root-frame? (get objects id)))) ([shape] (and (some? shape) + (not= (dm/get-prop shape :id) uuid/zero) (= (dm/get-prop shape :type) :frame) (= (dm/get-prop shape :frame-id) uuid/zero)))) From 870e4f96b207f59ccfedfb173b81741092d6d077 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 11:18:20 +0100 Subject: [PATCH 17/25] :arrow_up: Update dependencies --- backend/deps.edn | 12 +- common/deps.edn | 21 +- exporter/package.json | 10 +- exporter/yarn.lock | 26 +- frontend/deps.edn | 8 +- frontend/package.json | 26 +- frontend/src/app/main/style.clj | 4 +- frontend/yarn.lock | 789 +++++++++++++++++++------------- 8 files changed, 536 insertions(+), 360 deletions(-) diff --git a/backend/deps.edn b/backend/deps.edn index d3c9893183..810d6bf527 100644 --- a/backend/deps.edn +++ b/backend/deps.edn @@ -6,7 +6,7 @@ org.clojure/clojure {:mvn/version "1.12.0-alpha5"} org.clojure/tools.namespace {:mvn/version "1.4.4"} - com.github.luben/zstd-jni {:mvn/version "1.5.5-10"} + com.github.luben/zstd-jni {:mvn/version "1.5.5-11"} io.prometheus/simpleclient {:mvn/version "0.16.0"} io.prometheus/simpleclient_hotspot {:mvn/version "0.16.0"} @@ -17,7 +17,7 @@ io.prometheus/simpleclient_httpserver {:mvn/version "0.16.0"} - io.lettuce/lettuce-core {:mvn/version "6.2.6.RELEASE"} + io.lettuce/lettuce-core {:mvn/version "6.3.0.RELEASE"} java-http-clj/java-http-clj {:mvn/version "0.4.3"} funcool/yetti @@ -29,9 +29,9 @@ com.github.seancorfield/next.jdbc {:mvn/version "1.3.909"} metosin/reitit-core {:mvn/version "0.6.0"} nrepl/nrepl {:mvn/version "1.1.0"} - cider/cider-nrepl {:mvn/version "0.43.1"} + cider/cider-nrepl {:mvn/version "0.44.0"} - org.postgresql/postgresql {:mvn/version "42.6.0"} + org.postgresql/postgresql {:mvn/version "42.7.1"} com.zaxxer/HikariCP {:mvn/version "5.1.0"} @@ -42,7 +42,7 @@ com.github.ben-manes.caffeine/caffeine {:mvn/version "3.1.8"} - org.jsoup/jsoup {:mvn/version "1.16.2"} + org.jsoup/jsoup {:mvn/version "1.17.2"} org.im4java/im4java {:git/tag "1.4.0-penpot-2" :git/sha "e2b3e16" @@ -57,7 +57,7 @@ ;; Pretty Print specs pretty-spec/pretty-spec {:mvn/version "0.1.4"} - software.amazon.awssdk/s3 {:mvn/version "2.20.138"} + software.amazon.awssdk/s3 {:mvn/version "2.22.12"} } :paths ["src" "resources" "target/classes"] diff --git a/common/deps.edn b/common/deps.edn index 4dcd1987db..f8c649fab6 100644 --- a/common/deps.edn +++ b/common/deps.edn @@ -1,18 +1,18 @@ {:deps {org.clojure/clojure {:mvn/version "1.11.1"} - org.clojure/data.json {:mvn/version "2.4.0"} + org.clojure/data.json {:mvn/version "2.5.0"} org.clojure/tools.cli {:mvn/version "1.0.219"} org.clojure/clojurescript {:mvn/version "1.11.60"} org.clojure/test.check {:mvn/version "1.1.1"} org.clojure/data.fressian {:mvn/version "1.0.0"} ;; Logging - org.apache.logging.log4j/log4j-api {:mvn/version "2.21.1"} - org.apache.logging.log4j/log4j-core {:mvn/version "2.21.1"} - org.apache.logging.log4j/log4j-web {:mvn/version "2.21.1"} - org.apache.logging.log4j/log4j-jul {:mvn/version "2.21.1"} - org.apache.logging.log4j/log4j-slf4j2-impl {:mvn/version "2.21.1"} - org.slf4j/slf4j-api {:mvn/version "2.0.9"} + org.apache.logging.log4j/log4j-api {:mvn/version "2.22.1"} + org.apache.logging.log4j/log4j-core {:mvn/version "2.22.1"} + org.apache.logging.log4j/log4j-web {:mvn/version "2.22.1"} + org.apache.logging.log4j/log4j-jul {:mvn/version "2.22.1"} + org.apache.logging.log4j/log4j-slf4j2-impl {:mvn/version "2.22.1"} + org.slf4j/slf4j-api {:mvn/version "2.0.10"} pl.tkowalcz.tjahzi/log4j2-appender {:mvn/version "0.9.32"} selmer/selmer {:mvn/version "1.12.59"} @@ -31,7 +31,7 @@ org.graalvm.js/js {:mvn/version "23.0.2"} funcool/tubax {:mvn/version "2021.05.20-0"} - funcool/cuerdas {:mvn/version "2022.06.16-403"} + funcool/cuerdas {:mvn/version "2023.11.09-407"} funcool/promesa {:git/sha "484b7f5c0d08d817746caa685ed9ac5583eb37fa" :git/url "https://github.com/funcool/promesa"} @@ -48,9 +48,10 @@ ;; exception printing fipp/fipp {:mvn/version "0.6.26"} + io.github.eerohele/pp - {:git/tag "2023-11-25.47" - :git/sha "15d572c"} + {:git/tag "2024-01-04.60" + :git/sha "e8a9773"} io.aviso/pretty {:mvn/version "1.4.4"} environ/environ {:mvn/version "1.2.0"}} diff --git a/exporter/package.json b/exporter/package.json index 9437e9a678..1dd53fa660 100644 --- a/exporter/package.json +++ b/exporter/package.json @@ -10,13 +10,13 @@ "url": "https://github.com/penpot/penpot" }, "dependencies": { - "archiver": "^6.0.0", - "cookies": "^0.8.0", + "archiver": "^6.0.1", + "cookies": "^0.9.1", "generic-pool": "^3.9.0", - "inflation": "^2.0.0", + "inflation": "^2.1.0", "ioredis": "^5.3.2", - "luxon": "^3.4.2", - "playwright": "^1.37.1", + "luxon": "^3.4.4", + "playwright": "^1.40.1", "raw-body": "^2.5.2", "xml-js": "^1.6.11", "xregexp": "^5.1.1" diff --git a/exporter/yarn.lock b/exporter/yarn.lock index 9e9c1111c5..f7016c8b43 100644 --- a/exporter/yarn.lock +++ b/exporter/yarn.lock @@ -135,7 +135,7 @@ __metadata: languageName: node linkType: hard -"archiver@npm:^6.0.0": +"archiver@npm:^6.0.1": version: 6.0.1 resolution: "archiver@npm:6.0.1" dependencies: @@ -453,13 +453,13 @@ __metadata: languageName: node linkType: hard -"cookies@npm:^0.8.0": - version: 0.8.0 - resolution: "cookies@npm:0.8.0" +"cookies@npm:^0.9.1": + version: 0.9.1 + resolution: "cookies@npm:0.9.1" dependencies: depd: "npm:~2.0.0" keygrip: "npm:~1.1.0" - checksum: 0af32f30d1ece0596efc05782c66b9d61659e20c6cc5b695452abf5ceb51883ef43c5c73d86badd7d028a0da7d39f864c95f33640aef04f97fad70f35986bea3 + checksum: 3ffa1c0e992b62ee119adae4dd2ddd4a89166fa5434cd9bd9ff84ec4d2f14dfe2318a601280abfe32a4f64f884ec9345fb1912e488b002d188d2efa0d3919ba3 languageName: node linkType: hard @@ -727,13 +727,13 @@ __metadata: version: 0.0.0-use.local resolution: "exporter@workspace:." dependencies: - archiver: "npm:^6.0.0" - cookies: "npm:^0.8.0" + archiver: "npm:^6.0.1" + cookies: "npm:^0.9.1" generic-pool: "npm:^3.9.0" - inflation: "npm:^2.0.0" + inflation: "npm:^2.1.0" ioredis: "npm:^5.3.2" - luxon: "npm:^3.4.2" - playwright: "npm:^1.37.1" + luxon: "npm:^3.4.4" + playwright: "npm:^1.40.1" raw-body: "npm:^2.5.2" shadow-cljs: "npm:2.26.2" source-map-support: "npm:^0.5.21" @@ -1023,7 +1023,7 @@ __metadata: languageName: node linkType: hard -"inflation@npm:^2.0.0": +"inflation@npm:^2.1.0": version: 2.1.0 resolution: "inflation@npm:2.1.0" checksum: aadfcb8047a7e00d644e2e195f901dd9d7266c2be2326b7f8f6a99298f14916f1e322d00108a7e2778d6e76a8dc2174ddb9ac14bcdfe4f4866dfd612b695ab5d @@ -1181,7 +1181,7 @@ __metadata: languageName: node linkType: hard -"luxon@npm:^3.4.2": +"luxon@npm:^3.4.4": version: 3.4.4 resolution: "luxon@npm:3.4.4" checksum: 02e26a0b039c11fd5b75e1d734c8f0332c95510f6a514a9a0991023e43fb233884da02d7f966823ffb230632a733fc86d4a4b1e63c3fbe00058b8ee0f8c728af @@ -1555,7 +1555,7 @@ __metadata: languageName: node linkType: hard -"playwright@npm:^1.37.1": +"playwright@npm:^1.40.1": version: 1.40.1 resolution: "playwright@npm:1.40.1" dependencies: diff --git a/frontend/deps.edn b/frontend/deps.edn index 1190661d06..6c57b02a68 100644 --- a/frontend/deps.edn +++ b/frontend/deps.edn @@ -5,7 +5,7 @@ org.clojure/clojure {:mvn/version "1.11.1"} binaryage/devtools {:mvn/version "RELEASE"} - metosin/reitit-core {:mvn/version "0.5.18"} + metosin/reitit-core {:mvn/version "0.6.0"} funcool/okulary {:mvn/version "2022.04.11-16"} funcool/potok2 @@ -19,8 +19,8 @@ :git/url "https://github.com/funcool/beicon.git"} funcool/rumext - {:git/tag "v2.8.1" - :git/sha "168738b" + {:git/tag "v2.9.2" + :git/sha "faa6e6c" :git/url "https://github.com/funcool/rumext.git"} instaparse/instaparse {:mvn/version "1.4.12"} @@ -43,7 +43,7 @@ :extra-deps {thheller/shadow-cljs {:mvn/version "2.26.2"} org.clojure/tools.namespace {:mvn/version "RELEASE"} - cider/cider-nrepl {:mvn/version "0.37.0"}}} + cider/cider-nrepl {:mvn/version "0.44.0"}}} :shadow-cljs {:main-opts ["-m" "shadow.cljs.devtools.cli"]} diff --git a/frontend/package.json b/frontend/package.json index fce3711da2..f398772c62 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -39,15 +39,15 @@ "storybook:build": "npm run storybook:compile && storybook build" }, "devDependencies": { - "@storybook/addon-essentials": "^7.6.6", - "@storybook/addon-interactions": "^7.6.6", - "@storybook/addon-links": "^7.6.6", + "@storybook/addon-essentials": "^7.6.7", + "@storybook/addon-interactions": "^7.6.7", + "@storybook/addon-links": "^7.6.7", "@storybook/addon-onboarding": "^1.0.10", - "@storybook/blocks": "^7.6.6", - "@storybook/react": "^7.6.6", - "@storybook/react-vite": "^7.6.6", + "@storybook/blocks": "^7.6.7", + "@storybook/react": "^7.6.7", + "@storybook/react-vite": "^7.6.7", "@storybook/testing-library": "^0.2.2", - "@types/node": "^20.10.5", + "@types/node": "^20.10.6", "animate.css": "^4.1.1", "autoprefixer": "^10.4.16", "concurrently": "^8.2.2", @@ -62,23 +62,23 @@ "gulp-sass": "^5.1.0", "gulp-sourcemaps": "^3.0.0", "gulp-svg-sprite": "^2.0.3", - "jsdom": "^23.0.1", + "jsdom": "^23.1.0", "map-stream": "0.0.7", "marked": "^7.0.5", "mkdirp": "^3.0.1", "nodemon": "^3.0.2", "npm-run-all": "^4.1.5", - "postcss": "^8.4.32", + "postcss": "^8.4.33", "postcss-clean": "^1.2.2", "prettier": "^3.1.1", "prop-types": "^15.8.1", "rimraf": "^5.0.5", - "sass": "^1.69.5", + "sass": "^1.69.7", "shadow-cljs": "2.26.2", - "storybook": "^7.6.6", + "storybook": "^7.6.7", "typescript": "^5.3.3", - "vite": "^5.0.10", - "vitest": "^1.1.0" + "vite": "^5.0.11", + "vitest": "^1.1.3" }, "dependencies": { "date-fns": "^2.30.0", diff --git a/frontend/src/app/main/style.clj b/frontend/src/app/main/style.clj index 1881d59d8f..a1870314af 100644 --- a/frontend/src/app/main/style.clj +++ b/frontend/src/app/main/style.clj @@ -12,7 +12,7 @@ [clojure.data.json :as json] [clojure.java.io :as io] [cuerdas.core :as str] - [rumext.v2.util :as mfu])) + [rumext.v2.compiler :as mfu])) ;; Should match with the `ROOT_NAME` constant in gulpfile.js (def ROOT-NAME "app") @@ -141,7 +141,7 @@ (mfu/compile-concat :safe? false))) `~(binding [*css-prefix* prefix] (-> (into [] xform-css-case params) - (mfu/compile-concat :safe? false)))))) + (mfu/compile-concat :safe? false)))))) (defmacro css-case* [& params] diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 210abe1bc2..fe5aa7d237 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2938,61 +2938,61 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-actions@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-actions@npm:7.6.6" +"@storybook/addon-actions@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-actions@npm:7.6.7" dependencies: - "@storybook/core-events": "npm:7.6.6" + "@storybook/core-events": "npm:7.6.7" "@storybook/global": "npm:^5.0.0" "@types/uuid": "npm:^9.0.1" dequal: "npm:^2.0.2" polished: "npm:^4.2.2" uuid: "npm:^9.0.0" - checksum: 71bfd976c0b9f23bd23661787f382193814291e2ad06d7828c70b6c5c4e1f0636d02d8a7788828037a62dee4f87ce6ce25a9c6b79ed6d8a6db94b698cfaf614a + checksum: 64d9f460e73b3665b9e1cbde6680762b7d34b2fe0ba5415ba6c0f5492149a3a05abd95f39ef4052c509f844264b646618f73995ec219f894447e8bf0f91dc3ae languageName: node linkType: hard -"@storybook/addon-backgrounds@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-backgrounds@npm:7.6.6" +"@storybook/addon-backgrounds@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-backgrounds@npm:7.6.7" dependencies: "@storybook/global": "npm:^5.0.0" memoizerific: "npm:^1.11.3" ts-dedent: "npm:^2.0.0" - checksum: 485e9712c82e72579ad538a36bac1200e652dbf42141164f75930ddd2d394493adbba94ad930ff4233504a3f9b9bdded51df5c4758e14703727ec7789448d283 + checksum: aac3a8c08049c8cf0a6f9004c861b818dae40ef503b0f2cf0d38215f4b1d71c078bda26c0d7059b7cad9f93770c1f0c122e27a53911138ba0ab56b97ad94bd73 languageName: node linkType: hard -"@storybook/addon-controls@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-controls@npm:7.6.6" +"@storybook/addon-controls@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-controls@npm:7.6.7" dependencies: - "@storybook/blocks": "npm:7.6.6" + "@storybook/blocks": "npm:7.6.7" lodash: "npm:^4.17.21" ts-dedent: "npm:^2.0.0" - checksum: 895139db0c3f8e2fd8ad666133e60c8fab9c514baae4d895d2c533c2501114ed271f0e8c8997ba2220f560634028d55a991389ab48373b73840a5be24331214d + checksum: 234883c6db9f7a6afe43bf516d4b6527353096ed8ab88bc162025254730dc5d0a19ddc58393a23f1bbfe8d6f1e9b3b154f71e0df1465924e17c90a128deb1303 languageName: node linkType: hard -"@storybook/addon-docs@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-docs@npm:7.6.6" +"@storybook/addon-docs@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-docs@npm:7.6.7" dependencies: "@jest/transform": "npm:^29.3.1" "@mdx-js/react": "npm:^2.1.5" - "@storybook/blocks": "npm:7.6.6" - "@storybook/client-logger": "npm:7.6.6" - "@storybook/components": "npm:7.6.6" - "@storybook/csf-plugin": "npm:7.6.6" - "@storybook/csf-tools": "npm:7.6.6" + "@storybook/blocks": "npm:7.6.7" + "@storybook/client-logger": "npm:7.6.7" + "@storybook/components": "npm:7.6.7" + "@storybook/csf-plugin": "npm:7.6.7" + "@storybook/csf-tools": "npm:7.6.7" "@storybook/global": "npm:^5.0.0" "@storybook/mdx2-csf": "npm:^1.0.0" - "@storybook/node-logger": "npm:7.6.6" - "@storybook/postinstall": "npm:7.6.6" - "@storybook/preview-api": "npm:7.6.6" - "@storybook/react-dom-shim": "npm:7.6.6" - "@storybook/theming": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/node-logger": "npm:7.6.7" + "@storybook/postinstall": "npm:7.6.7" + "@storybook/preview-api": "npm:7.6.7" + "@storybook/react-dom-shim": "npm:7.6.7" + "@storybook/theming": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" fs-extra: "npm:^11.1.0" remark-external-links: "npm:^8.0.0" remark-slug: "npm:^6.0.0" @@ -3000,60 +3000,60 @@ __metadata: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: f98102c91d0f811a75f765088a3cc4ec2e79ce7ae07eb102ca49f7cc2f1fd54e9ad54ee94b560812d93cad9ad0ece5dd83f916f6d133ec8aebaa3ecea177ed76 + checksum: 06768cdf02d61af0c619676514b035775931bad4e7ed2bd086c85903391ffd31fccc6f6a74614893ead656e1206a46add5e35d6e4c26655693dd6ee5e68ed917 languageName: node linkType: hard -"@storybook/addon-essentials@npm:^7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-essentials@npm:7.6.6" +"@storybook/addon-essentials@npm:^7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-essentials@npm:7.6.7" dependencies: - "@storybook/addon-actions": "npm:7.6.6" - "@storybook/addon-backgrounds": "npm:7.6.6" - "@storybook/addon-controls": "npm:7.6.6" - "@storybook/addon-docs": "npm:7.6.6" - "@storybook/addon-highlight": "npm:7.6.6" - "@storybook/addon-measure": "npm:7.6.6" - "@storybook/addon-outline": "npm:7.6.6" - "@storybook/addon-toolbars": "npm:7.6.6" - "@storybook/addon-viewport": "npm:7.6.6" - "@storybook/core-common": "npm:7.6.6" - "@storybook/manager-api": "npm:7.6.6" - "@storybook/node-logger": "npm:7.6.6" - "@storybook/preview-api": "npm:7.6.6" + "@storybook/addon-actions": "npm:7.6.7" + "@storybook/addon-backgrounds": "npm:7.6.7" + "@storybook/addon-controls": "npm:7.6.7" + "@storybook/addon-docs": "npm:7.6.7" + "@storybook/addon-highlight": "npm:7.6.7" + "@storybook/addon-measure": "npm:7.6.7" + "@storybook/addon-outline": "npm:7.6.7" + "@storybook/addon-toolbars": "npm:7.6.7" + "@storybook/addon-viewport": "npm:7.6.7" + "@storybook/core-common": "npm:7.6.7" + "@storybook/manager-api": "npm:7.6.7" + "@storybook/node-logger": "npm:7.6.7" + "@storybook/preview-api": "npm:7.6.7" ts-dedent: "npm:^2.0.0" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 3392e9fe5994f996804425a942762f7bdb8f26344848d9b58a81b50d85f9ce86ebdaf2ba15d7dac1f64897a61b61653ead3f2e995897cfd7fe894f60e452ac56 + checksum: f6e729db162cc448e3f2bdc1b0e926a9556145237b09260ba1b33f137392978e0132a391a0e4933d94077afe75f05de02e873f90a22bd0a73f1049031d7292f7 languageName: node linkType: hard -"@storybook/addon-highlight@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-highlight@npm:7.6.6" +"@storybook/addon-highlight@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-highlight@npm:7.6.7" dependencies: "@storybook/global": "npm:^5.0.0" - checksum: fc526ae81476dca1b0d4e1f062af41ba534a06a762bd1197a5c30e10d68cb94ab3d42454171609de32cc2283adee37f0d29c84704c436a02b9bd1fa03b97c8d7 + checksum: efe8b7ff074db5b67705af9a033069e26b730425f112b5c748086f0a526352ee721c087a41324a90049b9800c2b9c47f9cab85b33ecb7aae58b3eb7d54e7e1b6 languageName: node linkType: hard -"@storybook/addon-interactions@npm:^7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-interactions@npm:7.6.6" +"@storybook/addon-interactions@npm:^7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-interactions@npm:7.6.7" dependencies: "@storybook/global": "npm:^5.0.0" - "@storybook/types": "npm:7.6.6" + "@storybook/types": "npm:7.6.7" jest-mock: "npm:^27.0.6" polished: "npm:^4.2.2" ts-dedent: "npm:^2.2.0" - checksum: 6ae3d389f5a569fb718b4137f4dbba16d7524af8f1e6b3da7a0b6793fae1402eea27be2d6741d662824f1e000147f39a0300ac3b46f809cfd916d60483e2ac1b + checksum: 037714fd46df09a22111ceeff8062aa4f1fc6af358f6f7e0c9dc7dc04595bdbb2c238b3b2b1b651e157408fc024e7237c2580f6ce4fd13dda8e6caa7e117c23f languageName: node linkType: hard -"@storybook/addon-links@npm:^7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-links@npm:7.6.6" +"@storybook/addon-links@npm:^7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-links@npm:7.6.7" dependencies: "@storybook/csf": "npm:^0.1.2" "@storybook/global": "npm:^5.0.0" @@ -3063,17 +3063,17 @@ __metadata: peerDependenciesMeta: react: optional: true - checksum: 2598ee0bff2794f86e5797d0cae157960b6ba083820628d1bf1a90ef0d48dc7d54901a5cb8cba8cdf3d2aa8e5147b6e362034981a5a5ff14870b594d49b6898f + checksum: 8c61d0dd7dd7072074f59c57a478f328bc0039bf0102134efea261bd1158ab19465605fac4eae42a9360b3c1f93143e2ee0f68e8001ad7de27f56e066d1cb17a languageName: node linkType: hard -"@storybook/addon-measure@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-measure@npm:7.6.6" +"@storybook/addon-measure@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-measure@npm:7.6.7" dependencies: "@storybook/global": "npm:^5.0.0" tiny-invariant: "npm:^1.3.1" - checksum: 7dfa01eedb3432afff9122afa091f9d841a81b18a4049d2bf50525de1914511ffd7fb4c1fc1349a3c07148d0f69fe38761635b576da4bf735863be7f8089ba8f + checksum: f6670147430d519d9d5340c041e4fe491538fd36b15079bbe273e9691be58f1b89b89983803f98b79deca2076039ec02d94712af3edf19745b777b7397f10be9 languageName: node linkType: hard @@ -3090,47 +3090,47 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-outline@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-outline@npm:7.6.6" +"@storybook/addon-outline@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-outline@npm:7.6.7" dependencies: "@storybook/global": "npm:^5.0.0" ts-dedent: "npm:^2.0.0" - checksum: 789ce5acd082256ccc5e754c6877beb45d8d27e9c3aef30a9eef0f391beaa4fbac25053a860136f74a4bfc6c593684f194e1a5cce299c67a969cfa2bb027026d + checksum: aae1ccdf1b946fa2eac943211d6110242de0e2a93a6b9c37300d81697d4a246f97b82f7d382bdf4e7ececf326167df07d1d36ab05b4bac59b4bf3e27ab9b32d3 languageName: node linkType: hard -"@storybook/addon-toolbars@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-toolbars@npm:7.6.6" - checksum: 1a71902f5e4a0e1d54847fdbe1312355eac6f3043ccd4c0ebaabb057b530b6c271bdad0a13e7b84b2cc2a604b144234567177f43a8bd1411a671d496c6151693 +"@storybook/addon-toolbars@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-toolbars@npm:7.6.7" + checksum: bc5725ca9c9285311d31c5e867b5c18f7baeafc903f32034bb452f2140654face6c4039abbfb9d00f47f5e3fea8627baa2ba2b608557c4b277f326102bb3b6fe languageName: node linkType: hard -"@storybook/addon-viewport@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/addon-viewport@npm:7.6.6" +"@storybook/addon-viewport@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/addon-viewport@npm:7.6.7" dependencies: memoizerific: "npm:^1.11.3" - checksum: 4821247b05fb08771c65ae2a31e54acae5ce75ceef251693789d1fbe40b8baf948848f3b22032df62053a20a46b16b14f2a0234f5576ec970ef2bb81c7cac124 + checksum: 7b62b06110df6dd407a66585a8fc79857772ab766253bfcf764958d79e7fec4ac582fd4dada561d00cadd5471cb3ff36db260ed44c57282d2079037c1d021f80 languageName: node linkType: hard -"@storybook/blocks@npm:7.6.6, @storybook/blocks@npm:^7.6.6": - version: 7.6.6 - resolution: "@storybook/blocks@npm:7.6.6" +"@storybook/blocks@npm:7.6.7, @storybook/blocks@npm:^7.6.7": + version: 7.6.7 + resolution: "@storybook/blocks@npm:7.6.7" dependencies: - "@storybook/channels": "npm:7.6.6" - "@storybook/client-logger": "npm:7.6.6" - "@storybook/components": "npm:7.6.6" - "@storybook/core-events": "npm:7.6.6" + "@storybook/channels": "npm:7.6.7" + "@storybook/client-logger": "npm:7.6.7" + "@storybook/components": "npm:7.6.7" + "@storybook/core-events": "npm:7.6.7" "@storybook/csf": "npm:^0.1.2" - "@storybook/docs-tools": "npm:7.6.6" + "@storybook/docs-tools": "npm:7.6.7" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:7.6.6" - "@storybook/preview-api": "npm:7.6.6" - "@storybook/theming": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/manager-api": "npm:7.6.7" + "@storybook/preview-api": "npm:7.6.7" + "@storybook/theming": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" "@types/lodash": "npm:^4.14.167" color-convert: "npm:^2.0.1" dequal: "npm:^2.0.2" @@ -3146,18 +3146,18 @@ __metadata: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: b824c337fe4f8eafc36c2c41f69ce005db364bf9b9396110b00f87b2e7600a9827663d80e1ab85c34e5ee4697f9109857a4547aabc37d99f68cbf482596dbf4b + checksum: 69230851b63f466a46d14d352378d9ae73c57c64604771397b6f8d41cb518fbc0106510563a1a625fa23f0fc7dd62322dba5b6183d711ee2fef702db761694f7 languageName: node linkType: hard -"@storybook/builder-manager@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/builder-manager@npm:7.6.6" +"@storybook/builder-manager@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/builder-manager@npm:7.6.7" dependencies: "@fal-works/esbuild-plugin-global-externals": "npm:^2.1.2" - "@storybook/core-common": "npm:7.6.6" - "@storybook/manager": "npm:7.6.6" - "@storybook/node-logger": "npm:7.6.6" + "@storybook/core-common": "npm:7.6.7" + "@storybook/manager": "npm:7.6.7" + "@storybook/node-logger": "npm:7.6.7" "@types/ejs": "npm:^3.1.1" "@types/find-cache-dir": "npm:^3.2.1" "@yarnpkg/esbuild-plugin-pnp": "npm:^3.0.0-rc.10" @@ -3170,22 +3170,22 @@ __metadata: fs-extra: "npm:^11.1.0" process: "npm:^0.11.10" util: "npm:^0.12.4" - checksum: a6f2ca8c4478f15c561cea0f06f4bc38af5eaf39d743803414561546c04d3707f485f8cd219f83863d3d3ccade10600d1f3053bdb8cdbdf19da19acdc4c86097 + checksum: 07df0b1a9f8665afab0919110e8895ba9dec3fbc4ed1071d51bfacc0bac57f7b07864205fc031beb1a6c3f716c35810170d4b35ee7ce300f8b3c54478c20fe96 languageName: node linkType: hard -"@storybook/builder-vite@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/builder-vite@npm:7.6.6" +"@storybook/builder-vite@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/builder-vite@npm:7.6.7" dependencies: - "@storybook/channels": "npm:7.6.6" - "@storybook/client-logger": "npm:7.6.6" - "@storybook/core-common": "npm:7.6.6" - "@storybook/csf-plugin": "npm:7.6.6" - "@storybook/node-logger": "npm:7.6.6" - "@storybook/preview": "npm:7.6.6" - "@storybook/preview-api": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/channels": "npm:7.6.7" + "@storybook/client-logger": "npm:7.6.7" + "@storybook/core-common": "npm:7.6.7" + "@storybook/csf-plugin": "npm:7.6.7" + "@storybook/node-logger": "npm:7.6.7" + "@storybook/preview": "npm:7.6.7" + "@storybook/preview-api": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" "@types/find-cache-dir": "npm:^3.2.1" browser-assert: "npm:^1.2.1" es-module-lexer: "npm:^0.9.3" @@ -3206,7 +3206,7 @@ __metadata: optional: true vite-plugin-glimmerx: optional: true - checksum: 71ca9359925b71e936dfdfe1bde7f2735d5f139f988251d1daed5e19f16b1333389878377cb8ec06347c784b9e40e37939eaf854b8a0faf584fe9d8327fc41be + checksum: 0150bc6fbd3ab65425b582ba7ce5701e92bc825a0507c82fc5cd26e62d1c43f9ac156335ca6564c0b1ce7a3789677b34757564476531fbaa92f0914c1a8aa79c languageName: node linkType: hard @@ -3224,22 +3224,36 @@ __metadata: languageName: node linkType: hard -"@storybook/cli@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/cli@npm:7.6.6" +"@storybook/channels@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/channels@npm:7.6.7" + dependencies: + "@storybook/client-logger": "npm:7.6.7" + "@storybook/core-events": "npm:7.6.7" + "@storybook/global": "npm:^5.0.0" + qs: "npm:^6.10.0" + telejson: "npm:^7.2.0" + tiny-invariant: "npm:^1.3.1" + checksum: 8964d36b74dcdfa0f12861b34b985c0425178130baf612ee0ce9ff469c33e582ed4eec31d4063aa938f0ea2b55ba6c97d9c929835040008f7876ff65297d13be + languageName: node + linkType: hard + +"@storybook/cli@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/cli@npm:7.6.7" dependencies: "@babel/core": "npm:^7.23.2" "@babel/preset-env": "npm:^7.23.2" "@babel/types": "npm:^7.23.0" "@ndelangen/get-tarball": "npm:^3.0.7" - "@storybook/codemod": "npm:7.6.6" - "@storybook/core-common": "npm:7.6.6" - "@storybook/core-events": "npm:7.6.6" - "@storybook/core-server": "npm:7.6.6" - "@storybook/csf-tools": "npm:7.6.6" - "@storybook/node-logger": "npm:7.6.6" - "@storybook/telemetry": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/codemod": "npm:7.6.7" + "@storybook/core-common": "npm:7.6.7" + "@storybook/core-events": "npm:7.6.7" + "@storybook/core-server": "npm:7.6.7" + "@storybook/csf-tools": "npm:7.6.7" + "@storybook/node-logger": "npm:7.6.7" + "@storybook/telemetry": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" "@types/semver": "npm:^7.3.4" "@yarnpkg/fslib": "npm:2.10.3" "@yarnpkg/libzip": "npm:2.3.0" @@ -3272,7 +3286,7 @@ __metadata: bin: getstorybook: ./bin/index.js sb: ./bin/index.js - checksum: 2f186d602508c19e4a46b69c2e1bb4d41c00e81c4cbed3babd91e522fb29a70313a49924376f4d50a23ccb9becbf2226891303840af864d5f2f2be5dace8c2f0 + checksum: 1f070c5f4d2d154e6d46473e429d4c03a20fd89e0c50f49c599a1889d25231e2e013c3bea7c9799e7240c29b43cc1bb452b2d2a5f98263295788ecd5db0069fa languageName: node linkType: hard @@ -3285,17 +3299,26 @@ __metadata: languageName: node linkType: hard -"@storybook/codemod@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/codemod@npm:7.6.6" +"@storybook/client-logger@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/client-logger@npm:7.6.7" + dependencies: + "@storybook/global": "npm:^5.0.0" + checksum: ba2c672086cdef7896a94f8858a5c7a8a71a429af0d1dd553d5e2090e8832644e9f7ef386e6136e5bf43c99db479754404bbf9a7859d1843198e143806e4d9c6 + languageName: node + linkType: hard + +"@storybook/codemod@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/codemod@npm:7.6.7" dependencies: "@babel/core": "npm:^7.23.2" "@babel/preset-env": "npm:^7.23.2" "@babel/types": "npm:^7.23.0" "@storybook/csf": "npm:^0.1.2" - "@storybook/csf-tools": "npm:7.6.6" - "@storybook/node-logger": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/csf-tools": "npm:7.6.7" + "@storybook/node-logger": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" "@types/cross-spawn": "npm:^6.0.2" cross-spawn: "npm:^7.0.3" globby: "npm:^11.0.2" @@ -3303,38 +3326,38 @@ __metadata: lodash: "npm:^4.17.21" prettier: "npm:^2.8.0" recast: "npm:^0.23.1" - checksum: 0611928617ceeb998b82353cf7926b9a7f7db3729dc5cf3230bf28794b1fbfba113fbf94edeed2ac67926359f8dc4cd2f1e3646075b27aedd65f9399e21e6314 + checksum: 4f37240c133bc2dc110ba67b5ca0a3081ec8fcdd8cbf23bd0b0f76193adf6119fae640c354c13ba6827026ac1293913fa7ae8823f17eaecbf17f41d2267decf0 languageName: node linkType: hard -"@storybook/components@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/components@npm:7.6.6" +"@storybook/components@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/components@npm:7.6.7" dependencies: "@radix-ui/react-select": "npm:^1.2.2" "@radix-ui/react-toolbar": "npm:^1.0.4" - "@storybook/client-logger": "npm:7.6.6" + "@storybook/client-logger": "npm:7.6.7" "@storybook/csf": "npm:^0.1.2" "@storybook/global": "npm:^5.0.0" - "@storybook/theming": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/theming": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" memoizerific: "npm:^1.11.3" use-resize-observer: "npm:^9.1.0" util-deprecate: "npm:^1.0.2" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 125918bef3cc57cbdc0d267fcfde0553c306e644b99c4451a704632e071a6f38d3395757d442227a48648ae1b399585ffc74d1e1130d94b2f2d626bc04b1db8e + checksum: 76fc642f2e588d82b226ff58fbbaeb8cb58a2171f5ab05484f32982c14dff5ba2226824d07be5dadeee030d66ece6a7139537f864ee90ca5edafc1db2cb40ccc languageName: node linkType: hard -"@storybook/core-client@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/core-client@npm:7.6.6" +"@storybook/core-client@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/core-client@npm:7.6.7" dependencies: - "@storybook/client-logger": "npm:7.6.6" - "@storybook/preview-api": "npm:7.6.6" - checksum: 71eff6c95de026bc00d7fd78b49c9213ebb698670692859aa05371d6afcd3d621bc4912e00e7aa54acb7d72df0311c1d8e3e86d0ca9902d7b9ab978cd37c2304 + "@storybook/client-logger": "npm:7.6.7" + "@storybook/preview-api": "npm:7.6.7" + checksum: bdd3a4bc5ac4accceff08ad00a70b3599040025abb4a88319c1745d47b5849ec3d5352b6688b21c4897ed6c1590bc0616f5a3ba3f568f7be42c0c5a48bab92b4 languageName: node linkType: hard @@ -3369,6 +3392,37 @@ __metadata: languageName: node linkType: hard +"@storybook/core-common@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/core-common@npm:7.6.7" + dependencies: + "@storybook/core-events": "npm:7.6.7" + "@storybook/node-logger": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" + "@types/find-cache-dir": "npm:^3.2.1" + "@types/node": "npm:^18.0.0" + "@types/node-fetch": "npm:^2.6.4" + "@types/pretty-hrtime": "npm:^1.0.0" + chalk: "npm:^4.1.0" + esbuild: "npm:^0.18.0" + esbuild-register: "npm:^3.5.0" + file-system-cache: "npm:2.3.0" + find-cache-dir: "npm:^3.0.0" + find-up: "npm:^5.0.0" + fs-extra: "npm:^11.1.0" + glob: "npm:^10.0.0" + handlebars: "npm:^4.7.7" + lazy-universal-dotenv: "npm:^4.0.0" + node-fetch: "npm:^2.0.0" + picomatch: "npm:^2.3.0" + pkg-dir: "npm:^5.0.0" + pretty-hrtime: "npm:^1.0.3" + resolve-from: "npm:^5.0.0" + ts-dedent: "npm:^2.0.0" + checksum: 3e91bf0a6604a529be41ecf924fd2f564267f89052e30ac5d43dc6cef371b7d0605b9238aa3a7f4b913acf4a5da4283b349078edfdc18bb6e4658f5104fb7739 + languageName: node + linkType: hard + "@storybook/core-events@npm:7.6.6": version: 7.6.6 resolution: "@storybook/core-events@npm:7.6.6" @@ -3378,25 +3432,34 @@ __metadata: languageName: node linkType: hard -"@storybook/core-server@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/core-server@npm:7.6.6" +"@storybook/core-events@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/core-events@npm:7.6.7" + dependencies: + ts-dedent: "npm:^2.0.0" + checksum: def57a404aa7d76691d1f6c9a990bc7ede45198d453a338f8735584706f7b05af09e2ab8a47e851e91bfdaf55be2a4fbe5810ef8d55caabf487c1b8b1e7e599e + languageName: node + linkType: hard + +"@storybook/core-server@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/core-server@npm:7.6.7" dependencies: "@aw-web-design/x-default-browser": "npm:1.4.126" "@discoveryjs/json-ext": "npm:^0.5.3" - "@storybook/builder-manager": "npm:7.6.6" - "@storybook/channels": "npm:7.6.6" - "@storybook/core-common": "npm:7.6.6" - "@storybook/core-events": "npm:7.6.6" + "@storybook/builder-manager": "npm:7.6.7" + "@storybook/channels": "npm:7.6.7" + "@storybook/core-common": "npm:7.6.7" + "@storybook/core-events": "npm:7.6.7" "@storybook/csf": "npm:^0.1.2" - "@storybook/csf-tools": "npm:7.6.6" + "@storybook/csf-tools": "npm:7.6.7" "@storybook/docs-mdx": "npm:^0.1.0" "@storybook/global": "npm:^5.0.0" - "@storybook/manager": "npm:7.6.6" - "@storybook/node-logger": "npm:7.6.6" - "@storybook/preview-api": "npm:7.6.6" - "@storybook/telemetry": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/manager": "npm:7.6.7" + "@storybook/node-logger": "npm:7.6.7" + "@storybook/preview-api": "npm:7.6.7" + "@storybook/telemetry": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" "@types/detect-port": "npm:^1.3.0" "@types/node": "npm:^18.0.0" "@types/pretty-hrtime": "npm:^1.0.0" @@ -3423,17 +3486,17 @@ __metadata: util-deprecate: "npm:^1.0.2" watchpack: "npm:^2.2.0" ws: "npm:^8.2.3" - checksum: 6381bd6fa0f55320d3204a42cb8ea8da2d48c940c3ede060e6d07a980bc6c3a460094d5b5b2b9a11ddd1b78bfa3e2f5e4a54f8cbb64ec7d084413ff1c9ad763d + checksum: 45fbac92bbc00fddc7e5052f8ca534ecf55f2972509809761509c88e1ded9e1cc5cd415c2f5bce2171d4effbfc21162ce60cc5c7d18a0a53be2a5891c122d84a languageName: node linkType: hard -"@storybook/csf-plugin@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/csf-plugin@npm:7.6.6" +"@storybook/csf-plugin@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/csf-plugin@npm:7.6.7" dependencies: - "@storybook/csf-tools": "npm:7.6.6" + "@storybook/csf-tools": "npm:7.6.7" unplugin: "npm:^1.3.1" - checksum: 9abfe41923e26d804d65fa3e653c1eb07d1b3d003e1e27c96ee3146a0c4d0757ca1ad201c4d3ae5939a29c5276d1081bfcc55b793354b9aeb2e4cfe5af6770d5 + checksum: 366e48c5247a33a4fa403c7689501c2960a98cd27877e08297bdafa7a707d1c32636f292dd74156f5df727b84a6a527ce49f6eff764dddc08dac60c0a194dc39 languageName: node linkType: hard @@ -3454,6 +3517,23 @@ __metadata: languageName: node linkType: hard +"@storybook/csf-tools@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/csf-tools@npm:7.6.7" + dependencies: + "@babel/generator": "npm:^7.23.0" + "@babel/parser": "npm:^7.23.0" + "@babel/traverse": "npm:^7.23.2" + "@babel/types": "npm:^7.23.0" + "@storybook/csf": "npm:^0.1.2" + "@storybook/types": "npm:7.6.7" + fs-extra: "npm:^11.1.0" + recast: "npm:^0.23.1" + ts-dedent: "npm:^2.0.0" + checksum: 1117186a163d20b9cedeac582f65ea97517c88312574619ad7d81bdceebd8471083c05af3ad1bfde0e3eebaa79d9e2f3c3e8718019ac6f67ad57ae59e365b557 + languageName: node + linkType: hard + "@storybook/csf@npm:^0.1.2": version: 0.1.2 resolution: "@storybook/csf@npm:0.1.2" @@ -3470,18 +3550,18 @@ __metadata: languageName: node linkType: hard -"@storybook/docs-tools@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/docs-tools@npm:7.6.6" +"@storybook/docs-tools@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/docs-tools@npm:7.6.7" dependencies: - "@storybook/core-common": "npm:7.6.6" - "@storybook/preview-api": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/core-common": "npm:7.6.7" + "@storybook/preview-api": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" "@types/doctrine": "npm:^0.0.3" assert: "npm:^2.1.0" doctrine: "npm:^3.0.0" lodash: "npm:^4.17.21" - checksum: fae6350b3f1328078129c8efe32abafd1c215d440ab189886178e300467b5a6306c9e2bab8f5629adb2461647b61b9243c790418cd4336510a1553ac0bdfea8d + checksum: be0acc6918bd5584034171f532c5c0d79ec55fb3c9625938e839a8a8e8573cd7522affe619b49a3ef6aff1f9d15335ac7dae0057604be553b6658a9310324e26 languageName: node linkType: hard @@ -3492,33 +3572,32 @@ __metadata: languageName: node linkType: hard -"@storybook/manager-api@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/manager-api@npm:7.6.6" +"@storybook/manager-api@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/manager-api@npm:7.6.7" dependencies: - "@storybook/channels": "npm:7.6.6" - "@storybook/client-logger": "npm:7.6.6" - "@storybook/core-events": "npm:7.6.6" + "@storybook/channels": "npm:7.6.7" + "@storybook/client-logger": "npm:7.6.7" + "@storybook/core-events": "npm:7.6.7" "@storybook/csf": "npm:^0.1.2" "@storybook/global": "npm:^5.0.0" - "@storybook/router": "npm:7.6.6" - "@storybook/theming": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/router": "npm:7.6.7" + "@storybook/theming": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" dequal: "npm:^2.0.2" lodash: "npm:^4.17.21" memoizerific: "npm:^1.11.3" - semver: "npm:^7.3.7" store2: "npm:^2.14.2" telejson: "npm:^7.2.0" ts-dedent: "npm:^2.0.0" - checksum: 2d72453d55dbe329ded778164fa2bc9ebe3556e4daba8bd39732a7707fef842dadd7210274cbfa5f28e4709d14a010f3207794e211c2aa2dab92ef609ce674a9 + checksum: e7683a947621857070157b0c9b059bc38e2035135a4ec544947c69fc698a53ff0d432326382f23ade6071c82fd950437388c085fc4465e6ebddeb73200ae2a15 languageName: node linkType: hard -"@storybook/manager@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/manager@npm:7.6.6" - checksum: c6352090a810155fa04d670f682cd19e063245d9164416a7ae042b29c84af1963ad98c238613ae6c47a8af0c8a80eba22bf80528af73199610f086e4cc858ce3 +"@storybook/manager@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/manager@npm:7.6.7" + checksum: 5b50ea2faeafaaa4448aea6456ee5800a6d625814063ca4d301fe43e3b9a7bf5e45427663e66bb798bef91f1615bdb4d2b12328c27dfc4dc783c086928cea395 languageName: node linkType: hard @@ -3536,23 +3615,30 @@ __metadata: languageName: node linkType: hard -"@storybook/postinstall@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/postinstall@npm:7.6.6" - checksum: f70bc49a7f490da2615b4e59a0a2fd2dde14e4bb88322428055977182d85cd68cc85bdb46b5c8b4ba17e5920c3295bc6124550b2f8bd2e05b84ad28613367896 +"@storybook/node-logger@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/node-logger@npm:7.6.7" + checksum: a5e270cf827cbec21b4900ce6424913e038d9123092140b3b99bb957fba35d346500c1af238f49fb95f77ecf7feddcc92bf68178a7ada7d02a24aae43429a1fb languageName: node linkType: hard -"@storybook/preview-api@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/preview-api@npm:7.6.6" +"@storybook/postinstall@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/postinstall@npm:7.6.7" + checksum: 2cd33667c38b67e07b2c6bf76b7be5e705b363c4082597ec09bd7bcdeea68f0f9c24d275c03d38d495c2d4c32333d4793b8dcbfedcfd1769cd5163c7b422b33b + languageName: node + linkType: hard + +"@storybook/preview-api@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/preview-api@npm:7.6.7" dependencies: - "@storybook/channels": "npm:7.6.6" - "@storybook/client-logger": "npm:7.6.6" - "@storybook/core-events": "npm:7.6.6" + "@storybook/channels": "npm:7.6.7" + "@storybook/client-logger": "npm:7.6.7" + "@storybook/core-events": "npm:7.6.7" "@storybook/csf": "npm:^0.1.2" "@storybook/global": "npm:^5.0.0" - "@storybook/types": "npm:7.6.6" + "@storybook/types": "npm:7.6.7" "@types/qs": "npm:^6.9.5" dequal: "npm:^2.0.2" lodash: "npm:^4.17.21" @@ -3561,35 +3647,35 @@ __metadata: synchronous-promise: "npm:^2.0.15" ts-dedent: "npm:^2.0.0" util-deprecate: "npm:^1.0.2" - checksum: 7a26c769de6255c4ed5644da83b857960bae804f709f88d896cf0b643331d8ef1387ffd892231de9ed580f320406b75f9a7c436726916aae648a8e789734f4a3 + checksum: 157406c3d6c94075af27088583c605dd180b14e0f50cab6b9305a1044b9d66b98a42b10cc4f3927f4c63a71d342b8452c0b3e1dc993cf8de3a5e05b826e9874f languageName: node linkType: hard -"@storybook/preview@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/preview@npm:7.6.6" - checksum: c9e966f667da878b771aed60ce18eb5c7e49ca8ed24de28a95c24d9ae3e604cedc10e77c9391ceda79764899b1aa5d3c5ca8dff000041930fffd1b9b44d2a048 +"@storybook/preview@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/preview@npm:7.6.7" + checksum: 04bad205c4bade10111085443f49faf2f11a130d9046f08b63f5ab0ebc06848b34c0d4091f951ce5d6b725672974f7af1d9589842130996a266853a2f5d24d29 languageName: node linkType: hard -"@storybook/react-dom-shim@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/react-dom-shim@npm:7.6.6" +"@storybook/react-dom-shim@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/react-dom-shim@npm:7.6.7" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: bf28419e6369f9044614b368816696b822e7543bed97487671b9749a76215000ad40393b1294aa5cf9effc5e5046372a3159a9534e7852e817d2b8deaea8d126 + checksum: 2d6dd1077ebe3695358386fce65800c504fd689418228303243f6d6d54b7bab60a89d8883a151b80e21167119a9f3b34e97e147d5f441eaebeebb322efdf8fe1 languageName: node linkType: hard -"@storybook/react-vite@npm:^7.6.6": - version: 7.6.6 - resolution: "@storybook/react-vite@npm:7.6.6" +"@storybook/react-vite@npm:^7.6.7": + version: 7.6.7 + resolution: "@storybook/react-vite@npm:7.6.7" dependencies: "@joshwooding/vite-plugin-react-docgen-typescript": "npm:0.3.0" "@rollup/pluginutils": "npm:^5.0.2" - "@storybook/builder-vite": "npm:7.6.6" - "@storybook/react": "npm:7.6.6" + "@storybook/builder-vite": "npm:7.6.7" + "@storybook/react": "npm:7.6.7" "@vitejs/plugin-react": "npm:^3.0.1" magic-string: "npm:^0.30.0" react-docgen: "npm:^7.0.0" @@ -3597,21 +3683,21 @@ __metadata: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 vite: ^3.0.0 || ^4.0.0 || ^5.0.0 - checksum: 03f4bb7077fdd765664b0219a86f8cfeef9965c07a98ad19328f36836e696f4cf3fbaf9b1c125d19b36298d5e6aee28a89cfa9095796b432c5cad96dc9698129 + checksum: 7c5b681be888e2277af0be1e4c59927838bdfc54bc4ee919aa6bec4f08a491210bba82f8a0cd94181136e1d082cbc81982c1fb8d55a0dbddf1003526d1e405fc languageName: node linkType: hard -"@storybook/react@npm:7.6.6, @storybook/react@npm:^7.6.6": - version: 7.6.6 - resolution: "@storybook/react@npm:7.6.6" +"@storybook/react@npm:7.6.7, @storybook/react@npm:^7.6.7": + version: 7.6.7 + resolution: "@storybook/react@npm:7.6.7" dependencies: - "@storybook/client-logger": "npm:7.6.6" - "@storybook/core-client": "npm:7.6.6" - "@storybook/docs-tools": "npm:7.6.6" + "@storybook/client-logger": "npm:7.6.7" + "@storybook/core-client": "npm:7.6.7" + "@storybook/docs-tools": "npm:7.6.7" "@storybook/global": "npm:^5.0.0" - "@storybook/preview-api": "npm:7.6.6" - "@storybook/react-dom-shim": "npm:7.6.6" - "@storybook/types": "npm:7.6.6" + "@storybook/preview-api": "npm:7.6.7" + "@storybook/react-dom-shim": "npm:7.6.7" + "@storybook/types": "npm:7.6.7" "@types/escodegen": "npm:^0.0.6" "@types/estree": "npm:^0.0.51" "@types/node": "npm:^18.0.0" @@ -3633,22 +3719,38 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: b9b349597b47f040faa7949405dc843073d0ca1c0799477e4ac3e1c8ffb0f5ff9462b2ff782391cefb8cf521ee804dbfb5da8a8f74d7ab69c3b012bccac556c0 + checksum: 00aaf41a3bf6755320ca5ead5792ba6fce5194212586a7804c4fbcab255d299e730fae7d747f08484d9a072c8a0273aababdf1e65fb34285e1aab96b700fc31c languageName: node linkType: hard -"@storybook/router@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/router@npm:7.6.6" +"@storybook/router@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/router@npm:7.6.7" dependencies: - "@storybook/client-logger": "npm:7.6.6" + "@storybook/client-logger": "npm:7.6.7" memoizerific: "npm:^1.11.3" qs: "npm:^6.10.0" - checksum: cf8b81908a64692ebda42620ca18aa4db1e4472ea5e8bf6085db489503d2d315e3dbcee1d3097ead724cebfb20d26f8ca656055ebb5afa607e073ccd5488f0a4 + checksum: 2d6f3a12b451f325362a3734fea78d1fe5cde8b52a6ecb6e0bf3ee1429c73d9f71979bc13e798945148199027242017982af7743b56e0877600d9105aefbf661 languageName: node linkType: hard -"@storybook/telemetry@npm:7.6.6, @storybook/telemetry@npm:^7.1.0": +"@storybook/telemetry@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/telemetry@npm:7.6.7" + dependencies: + "@storybook/client-logger": "npm:7.6.7" + "@storybook/core-common": "npm:7.6.7" + "@storybook/csf-tools": "npm:7.6.7" + chalk: "npm:^4.1.0" + detect-package-manager: "npm:^2.0.1" + fetch-retry: "npm:^5.0.2" + fs-extra: "npm:^11.1.0" + read-pkg-up: "npm:^7.0.1" + checksum: 984e564eb78c92b28a8062f13079a807c50f17e643a79b41987a2bbbfd60572a364fbffb61fe5aeadd273f0481dba91fe66a6731c2ed35c91a9898a2112f38e2 + languageName: node + linkType: hard + +"@storybook/telemetry@npm:^7.1.0": version: 7.6.6 resolution: "@storybook/telemetry@npm:7.6.6" dependencies: @@ -3675,18 +3777,18 @@ __metadata: languageName: node linkType: hard -"@storybook/theming@npm:7.6.6": - version: 7.6.6 - resolution: "@storybook/theming@npm:7.6.6" +"@storybook/theming@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/theming@npm:7.6.7" dependencies: "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.0" - "@storybook/client-logger": "npm:7.6.6" + "@storybook/client-logger": "npm:7.6.7" "@storybook/global": "npm:^5.0.0" memoizerific: "npm:^1.11.3" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 6f38bf55108c85ef8ab83e32839136cdb82495ff64a8a562ffda1d9e05361f2583f388b3ec0748ad8eb38c36fdcd302db360bff9c4e1e2745dbb2621f4b88b58 + checksum: bbeb9210a71c3c6b219936a20f49e32a190e2e0a6e7eb0dc2a5452c5380b74f755c0092d30f0ff183ba14395dcece8440516ff3d7d15cf0a58bd77bffe05cb62 languageName: node linkType: hard @@ -3702,6 +3804,18 @@ __metadata: languageName: node linkType: hard +"@storybook/types@npm:7.6.7": + version: 7.6.7 + resolution: "@storybook/types@npm:7.6.7" + dependencies: + "@storybook/channels": "npm:7.6.7" + "@types/babel__core": "npm:^7.0.0" + "@types/express": "npm:^4.7.0" + file-system-cache: "npm:2.3.0" + checksum: e0c91e3d672edba9a2c392ea7f9a33b6f2cfada6c89860ac98c8363233d76d5f8ea8e785c96e7993322c5a14c7988bf18ed6275a074dd1bae4e3180ad6c1dc81 + languageName: node + linkType: hard + "@testing-library/dom@npm:^9.0.0": version: 9.3.3 resolution: "@testing-library/dom@npm:9.3.3" @@ -4018,12 +4132,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.10.5": - version: 20.10.5 - resolution: "@types/node@npm:20.10.5" +"@types/node@npm:^20.10.6": + version: 20.10.6 + resolution: "@types/node@npm:20.10.6" dependencies: undici-types: "npm:~5.26.4" - checksum: be30609aae0bfe492097815f166ccc07f465220cb604647fa4e5ec05a1d16c012a41b82b5f11ecfe2485cbb479d4d20384b95b809ca0bcff6d94d5bbafa645bb + checksum: 6692ccfa8552ef60c4069fda3c8de726c23e8d403cdf788e3c7efa769987e80fbda5f02723dd857f9de7df24a5fa40b3ed4580ec3c5cbac04eba44cf7b2ab1dc languageName: node linkType: hard @@ -4176,56 +4290,57 @@ __metadata: languageName: node linkType: hard -"@vitest/expect@npm:1.1.0": - version: 1.1.0 - resolution: "@vitest/expect@npm:1.1.0" +"@vitest/expect@npm:1.1.3": + version: 1.1.3 + resolution: "@vitest/expect@npm:1.1.3" dependencies: - "@vitest/spy": "npm:1.1.0" - "@vitest/utils": "npm:1.1.0" + "@vitest/spy": "npm:1.1.3" + "@vitest/utils": "npm:1.1.3" chai: "npm:^4.3.10" - checksum: df60235fdcef6aaa739e6d7302b5b0f2cd9b7dea17fc6319a7e2cff9b6f526576a9b291c5feb6fc93f634323b4b846422bf087a978d2ef490a301e18681f962d + checksum: fe5c9eade516a754efc26d4b6378a250f0c3b668fa15b3e6b6042190b64a65c4459b7fd67bfca72fb1fbf215feb838b68da4ab224a2a10137d8828ca6af70516 languageName: node linkType: hard -"@vitest/runner@npm:1.1.0": - version: 1.1.0 - resolution: "@vitest/runner@npm:1.1.0" +"@vitest/runner@npm:1.1.3": + version: 1.1.3 + resolution: "@vitest/runner@npm:1.1.3" dependencies: - "@vitest/utils": "npm:1.1.0" + "@vitest/utils": "npm:1.1.3" p-limit: "npm:^5.0.0" pathe: "npm:^1.1.1" - checksum: 96cba65963b67116253be08ff3fbe72f3627628fe24bc8dcadcea151603385f0fc889d2a02d57a1ed16c9bb6fd16cda1f1db23cfd2ec28dc6d746bb1610b4a8e + checksum: 544455f7d7d3e04e8b6df18dfc8dec0ca5a90dd6c39ce72685de4383d4b2f77e907e6cf225df12af5127293344256056021d3d39b8c8960e943a518c30196801 languageName: node linkType: hard -"@vitest/snapshot@npm:1.1.0": - version: 1.1.0 - resolution: "@vitest/snapshot@npm:1.1.0" +"@vitest/snapshot@npm:1.1.3": + version: 1.1.3 + resolution: "@vitest/snapshot@npm:1.1.3" dependencies: magic-string: "npm:^0.30.5" pathe: "npm:^1.1.1" pretty-format: "npm:^29.7.0" - checksum: ba516d660b88e757864417da19478b74273f93cd531c86d3271dea730b47b52f05564acb7b8f73bffa7d9546e6a822d84c4258513074f65dc78cca4d51e45193 + checksum: bf841693c0210a12b96060e5bc5d3eeda36d6d96f3446c789ccaf22c68d13c41d868d0e76dddcd298cd7c08564f0bed75ad26fb2e94e4909d83f60b5ec9c8904 languageName: node linkType: hard -"@vitest/spy@npm:1.1.0": - version: 1.1.0 - resolution: "@vitest/spy@npm:1.1.0" +"@vitest/spy@npm:1.1.3": + version: 1.1.3 + resolution: "@vitest/spy@npm:1.1.3" dependencies: tinyspy: "npm:^2.2.0" - checksum: 3e44f916d5db981365093923deb7b36a8cccf62b04142372278987a83f1007d8b509bce0a0e45bc9fddaeac7eb50d02d343b53c5da6264361ee6e23d2c660441 + checksum: d1692582afb7b665ec283723b15bbb7da95896cbfd7befaad9fdac6b64a8250fd918781263d43e8e10ee4874cdd18646224f6d993749c3751296dced8095a9ed languageName: node linkType: hard -"@vitest/utils@npm:1.1.0": - version: 1.1.0 - resolution: "@vitest/utils@npm:1.1.0" +"@vitest/utils@npm:1.1.3": + version: 1.1.3 + resolution: "@vitest/utils@npm:1.1.3" dependencies: diff-sequences: "npm:^29.6.3" + estree-walker: "npm:^3.0.3" loupe: "npm:^2.3.7" pretty-format: "npm:^29.7.0" - checksum: afadbd53e0659b4be71b1349ef8db61ac8d58368c2686bb570852ad6a056afa0a37ae7458284696a5fca09cab458773c7fa9d0053e9d1d1668ed39b570ce6b07 + checksum: 86f48a7722927741449f40f33584dd9857629782f6661654225b5dd3c039d61cc60806c5dfe419bd793f2a231ba91fe708cbdec5d99b62a1f6f819b6f2121fc3 languageName: node linkType: hard @@ -4316,7 +4431,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.3.0": +"acorn-walk@npm:^8.3.1": version: 8.3.1 resolution: "acorn-walk@npm:8.3.1" checksum: a23d2f7c6b6cad617f4c77f14dfeb062a239208d61753e9ba808d916c550add92b39535467d2e6028280761ac4f5a904cc9df21530b84d3f834e3edef74ddde5 @@ -6121,12 +6236,12 @@ __metadata: languageName: node linkType: hard -"cssstyle@npm:^3.0.0": - version: 3.0.0 - resolution: "cssstyle@npm:3.0.0" +"cssstyle@npm:^4.0.1": + version: 4.0.1 + resolution: "cssstyle@npm:4.0.1" dependencies: rrweb-cssom: "npm:^0.6.0" - checksum: 23acee092c1cec670fb7b8110e48abd740dc4e574d3b74848743067cb3377a86a1f64cf02606aabd7bb153785e68c2c1e09ce53295ddf7a4b470b3c7c55ec807 + checksum: cadf9a8b23e11f4c6d63f21291096a0b0be868bd4ab9c799daa2c5b18330e39e5281605f01da906e901b42f742df0f3b3645af6465e83377ff7d15a88ee432a0 languageName: node linkType: hard @@ -7146,6 +7261,15 @@ __metadata: languageName: node linkType: hard +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + checksum: c12e3c2b2642d2bcae7d5aa495c60fa2f299160946535763969a1c83fc74518ffa9c2cd3a8b69ac56aea547df6a8aac25f729a342992ef0bbac5f1c73e78995d + languageName: node + linkType: hard + "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -7745,15 +7869,15 @@ __metadata: version: 0.0.0-use.local resolution: "frontend@workspace:." dependencies: - "@storybook/addon-essentials": "npm:^7.6.6" - "@storybook/addon-interactions": "npm:^7.6.6" - "@storybook/addon-links": "npm:^7.6.6" + "@storybook/addon-essentials": "npm:^7.6.7" + "@storybook/addon-interactions": "npm:^7.6.7" + "@storybook/addon-links": "npm:^7.6.7" "@storybook/addon-onboarding": "npm:^1.0.10" - "@storybook/blocks": "npm:^7.6.6" - "@storybook/react": "npm:^7.6.6" - "@storybook/react-vite": "npm:^7.6.6" + "@storybook/blocks": "npm:^7.6.7" + "@storybook/react": "npm:^7.6.7" + "@storybook/react-vite": "npm:^7.6.7" "@storybook/testing-library": "npm:^0.2.2" - "@types/node": "npm:^20.10.5" + "@types/node": "npm:^20.10.6" animate.css: "npm:^4.1.1" autoprefixer: "npm:^10.4.16" concurrently: "npm:^8.2.2" @@ -7773,7 +7897,7 @@ __metadata: gulp-svg-sprite: "npm:^2.0.3" highlight.js: "npm:^11.9.0" js-beautify: "npm:^1.14.11" - jsdom: "npm:^23.0.1" + jsdom: "npm:^23.1.0" jszip: "npm:^3.10.1" luxon: "npm:^3.4.4" map-stream: "npm:0.0.7" @@ -7783,7 +7907,7 @@ __metadata: nodemon: "npm:^3.0.2" npm-run-all: "npm:^4.1.5" opentype.js: "npm:^1.3.4" - postcss: "npm:^8.4.32" + postcss: "npm:^8.4.33" postcss-clean: "npm:^1.2.2" postcss-modules: "npm:^6.0.0" prettier: "npm:^3.1.1" @@ -7794,16 +7918,16 @@ __metadata: react-virtualized: "npm:^9.22.5" rimraf: "npm:^5.0.5" rxjs: "npm:8.0.0-alpha.13" - sass: "npm:^1.69.5" + sass: "npm:^1.69.7" sax: "npm:^1.3.0" shadow-cljs: "npm:2.26.2" source-map-support: "npm:^0.5.21" - storybook: "npm:^7.6.6" + storybook: "npm:^7.6.7" tdigest: "npm:^0.1.2" typescript: "npm:^5.3.3" ua-parser-js: "npm:^1.0.37" - vite: "npm:^5.0.10" - vitest: "npm:^1.1.0" + vite: "npm:^5.0.11" + vitest: "npm:^1.1.3" xregexp: "npm:^5.1.1" languageName: unknown linkType: soft @@ -9617,11 +9741,11 @@ __metadata: languageName: node linkType: hard -"jsdom@npm:^23.0.1": - version: 23.0.1 - resolution: "jsdom@npm:23.0.1" +"jsdom@npm:^23.1.0": + version: 23.1.0 + resolution: "jsdom@npm:23.1.0" dependencies: - cssstyle: "npm:^3.0.0" + cssstyle: "npm:^4.0.1" data-urls: "npm:^5.0.0" decimal.js: "npm:^10.4.3" form-data: "npm:^4.0.0" @@ -9640,14 +9764,14 @@ __metadata: whatwg-encoding: "npm:^3.1.1" whatwg-mimetype: "npm:^4.0.0" whatwg-url: "npm:^14.0.0" - ws: "npm:^8.14.2" + ws: "npm:^8.16.0" xml-name-validator: "npm:^5.0.0" peerDependencies: canvas: ^2.11.2 peerDependenciesMeta: canvas: optional: true - checksum: 13b2b3693ccb40215d1cce77bac7a295414ee4c0a06e30167f8087c9867145ba23dbd592bd95a801cadd7b3698bfd20b9c3f2c26fd8422607f22609ed2e404ef + checksum: 5740b2133f30b546d768cddbb3e5db82b7e9cc8ad2f97410fc32e7d85586accee4fe2d9280306018a417f63e4cb30e018d1c56759a0446fe34f1e4433669208a languageName: node linkType: hard @@ -11858,6 +11982,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.4.33": + version: 8.4.33 + resolution: "postcss@npm:8.4.33" + dependencies: + nanoid: "npm:^3.3.7" + picocolors: "npm:^1.0.0" + source-map-js: "npm:^1.0.2" + checksum: 16eda83458fcd8a91bece287b5920c7f57164c3ea293e6c80d0ea71ce7843007bcd8592260a5160b9a7f02693e6ac93e2495b02d8c7596d3f3f72c1447e3ba79 + languageName: node + linkType: hard + "prettier@npm:^2.8.0": version: 2.8.8 resolution: "prettier@npm:2.8.8" @@ -13016,16 +13151,16 @@ __metadata: languageName: node linkType: hard -"sass@npm:^1.69.5": - version: 1.69.5 - resolution: "sass@npm:1.69.5" +"sass@npm:^1.69.7": + version: 1.69.7 + resolution: "sass@npm:1.69.7" dependencies: chokidar: "npm:>=3.0.0 <4.0.0" immutable: "npm:^4.0.0" source-map-js: "npm:>=0.6.2 <2.0.0" bin: sass: sass.js - checksum: a9003a9482f2e467fc412cfe58ba4fa14fb78bef7e1283ce5d64a065f8a31114ec3bbf5d4e724f94eb8512c32c768a6f91f228c7f16a26a300bbf4db293b5608 + checksum: 773d0938e7d4ff3972d3fda3132f34fe98a2f712e028a58e28fecd615434795eff3266eddc38d5e13f03b90c0d6360d0e737b30bff2949a47280c64a18e0fb18 languageName: node linkType: hard @@ -13603,15 +13738,15 @@ __metadata: languageName: node linkType: hard -"storybook@npm:^7.6.6": - version: 7.6.6 - resolution: "storybook@npm:7.6.6" +"storybook@npm:^7.6.7": + version: 7.6.7 + resolution: "storybook@npm:7.6.7" dependencies: - "@storybook/cli": "npm:7.6.6" + "@storybook/cli": "npm:7.6.7" bin: sb: ./index.js storybook: ./index.js - checksum: 3fa91dfc9c107c19817fd09f2ae76960ca84594e0773460a9cf4ce066656aa7331eec817139ad35f2594e5f93ff9770bc204576f78e5b12a52025042e587ab51 + checksum: 0f27d7fe47da8d9a87caef62e490cdad173d5d8405d0d096d62f9abc6265d8bf53a45d92b1d9a824e9708c21430bdf3a841107de7b64dc36d5eb40d8d8d7bb9b languageName: node linkType: hard @@ -14969,9 +15104,9 @@ __metadata: languageName: node linkType: hard -"vite-node@npm:1.1.0": - version: 1.1.0 - resolution: "vite-node@npm:1.1.0" +"vite-node@npm:1.1.3": + version: 1.1.3 + resolution: "vite-node@npm:1.1.3" dependencies: cac: "npm:^6.7.14" debug: "npm:^4.3.4" @@ -14980,11 +15115,11 @@ __metadata: vite: "npm:^5.0.0" bin: vite-node: vite-node.mjs - checksum: 0162f6b2bea58278fd32bfdd1ed72a2583fd803adaad3456881a6b2ff3ff89404c1746c841990ae985c324b2a8aa06559d7d2be1776328b998f31e099e965e34 + checksum: 011346c156c4df7cb49fc1de357ff7dc6316011faeb00855aca7ecab24ed19aac4c03c0bc921923d13c37870f2954c3fcbf975c5eeee3a03d675831a60556dfb languageName: node linkType: hard -"vite@npm:^5.0.0, vite@npm:^5.0.10": +"vite@npm:^5.0.0": version: 5.0.10 resolution: "vite@npm:5.0.10" dependencies: @@ -15024,16 +15159,56 @@ __metadata: languageName: node linkType: hard -"vitest@npm:^1.1.0": - version: 1.1.0 - resolution: "vitest@npm:1.1.0" +"vite@npm:^5.0.11": + version: 5.0.11 + resolution: "vite@npm:5.0.11" dependencies: - "@vitest/expect": "npm:1.1.0" - "@vitest/runner": "npm:1.1.0" - "@vitest/snapshot": "npm:1.1.0" - "@vitest/spy": "npm:1.1.0" - "@vitest/utils": "npm:1.1.0" - acorn-walk: "npm:^8.3.0" + esbuild: "npm:^0.19.3" + fsevents: "npm:~2.3.3" + postcss: "npm:^8.4.32" + rollup: "npm:^4.2.0" + peerDependencies: + "@types/node": ^18.0.0 || >=20.0.0 + less: "*" + lightningcss: ^1.21.0 + sass: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 74a3ddc6d43cf19cb6f827a53d77c481a07517a72b7d82a178df082012ad81ab5231a287a6dcc5471c0b2a5c8dd7e6ea8e1d62d268803057d0315729f09c5e33 + languageName: node + linkType: hard + +"vitest@npm:^1.1.3": + version: 1.1.3 + resolution: "vitest@npm:1.1.3" + dependencies: + "@vitest/expect": "npm:1.1.3" + "@vitest/runner": "npm:1.1.3" + "@vitest/snapshot": "npm:1.1.3" + "@vitest/spy": "npm:1.1.3" + "@vitest/utils": "npm:1.1.3" + acorn-walk: "npm:^8.3.1" cac: "npm:^6.7.14" chai: "npm:^4.3.10" debug: "npm:^4.3.4" @@ -15047,7 +15222,7 @@ __metadata: tinybench: "npm:^2.5.1" tinypool: "npm:^0.8.1" vite: "npm:^5.0.0" - vite-node: "npm:1.1.0" + vite-node: "npm:1.1.3" why-is-node-running: "npm:^2.2.2" peerDependencies: "@edge-runtime/vm": "*" @@ -15071,7 +15246,7 @@ __metadata: optional: true bin: vitest: vitest.mjs - checksum: e0b3eea9312df4747262758310e1f928c4b10f43e84e1ead48a8b3e115c12f97ef2c9034a2e1358d47762e6fe57e17b7d7374ce163e353d634f73fdae0584b76 + checksum: 5dc6010b14ab069f6483e343724bd4b6ff72c0ea1cca52b2f5d2ea2b0b7acc9584887b2d428af309c855b731d081dc32ec370032d2d40a20492ced5695950acb languageName: node linkType: hard @@ -15394,9 +15569,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.14.2": - version: 8.15.1 - resolution: "ws@npm:8.15.1" +"ws@npm:^8.16.0": + version: 8.16.0 + resolution: "ws@npm:8.16.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -15405,7 +15580,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 9964360dd5ab35c7376bd7c4295a3c8bd44ea0838c9413742548a6fb3ec371fc6c18552d5b8e76bdc21536db1909765612815bae072674b5ec69971605395a96 + checksum: a7783bb421c648b1e622b423409cb2a58ac5839521d2f689e84bc9dc41d59379c692dd405b15a997ea1d4c0c2e5314ad707332d0c558f15232d2bc07c0b4618a languageName: node linkType: hard From 0ea07469d295cba75c55aa88a629feef77e2dc10 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 11:19:11 +0100 Subject: [PATCH 18/25] :lipstick: Add minor cosmetic fixes to link react component --- frontend/src/app/main/ui/components/link.cljs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/ui/components/link.cljs b/frontend/src/app/main/ui/components/link.cljs index ad010f093e..ddaad53615 100644 --- a/frontend/src/app/main/ui/components/link.cljs +++ b/frontend/src/app/main/ui/components/link.cljs @@ -6,16 +6,19 @@ (ns app.main.ui.components.link (:require + [app.common.data :as d] [app.util.keyboard :as kbd] [rumext.v2 :as mf])) -(mf/defc link [{:keys [action klass data-test keyboard-action children]}] - (let [keyboard-action (or keyboard-action action)] +(mf/defc link + {::mf/wrap-props false} + [{:keys [action klass data-test keyboard-action children]}] + (let [keyboard-action (d/nilv keyboard-action action)] [:a {:on-click action :class klass :on-key-down (fn [event] - (when (kbd/enter? event) + (when ^boolean (kbd/enter? event) (keyboard-action event))) :tab-index "0" :data-test data-test} - [:* children]])) + children])) From 1465ed3607b4797233e2be0109449c271e6c022c Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 12:43:15 +0100 Subject: [PATCH 19/25] :zap: Improve performance on selection react component Mainly do more static calls and reduce unnecesary allocation --- .../main/ui/workspace/viewport/selection.cljs | 578 ++++++++++-------- frontend/src/app/util/array.cljs | 22 +- 2 files changed, 338 insertions(+), 262 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/viewport/selection.cljs b/frontend/src/app/main/ui/workspace/viewport/selection.cljs index 2db02dfc94..bd7a0c7df2 100644 --- a/frontend/src/app/main/ui/workspace/viewport/selection.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/selection.cljs @@ -8,6 +8,7 @@ "Selection handlers component." (:require [app.common.data.macros :as dm] + [app.common.files.helpers :as cfh] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] @@ -19,11 +20,11 @@ [app.main.ui.context :as ctx] [app.main.ui.css-cursors :as cur] [app.main.ui.workspace.shapes.path.editor :refer [path-editor]] + [app.util.array :as array] [app.util.debug :as dbg] [app.util.dom :as dom] [app.util.object :as obj] - [rumext.v2 :as mf] - [rumext.v2.util :refer [map->obj]])) + [rumext.v2 :as mf])) (def rotation-handler-size 20) (def resize-point-radius 4) @@ -37,134 +38,150 @@ (def small-selrect-side 30) (mf/defc selection-rect + {::mf/wrap-props false} [{:keys [transform rect zoom color on-move-selected on-context-menu]}] - (when rect - (let [{:keys [x y width height]} rect] - [:rect.main.viewport-selrect - {:x x - :y y - :width width - :height height - :transform (str transform) - :on-pointer-down on-move-selected - :on-context-menu on-context-menu - :style {:stroke color - :stroke-width (/ selection-rect-width zoom) - :fill "none"}}]))) + (let [x (dm/get-prop rect :x) + y (dm/get-prop rect :y) + width (dm/get-prop rect :width) + height (dm/get-prop rect :height)] + [:rect.main.viewport-selrect + {:x x + :y y + :width width + :height height + :transform (str transform) + :on-pointer-down on-move-selected + :on-context-menu on-context-menu + :style {:stroke color + :stroke-width (/ selection-rect-width zoom) + :fill "none"}}])) -(defn- handlers-for-selection [{:keys [x y width height]} {:keys [type]} zoom] - (let [threshold-small (/ 25 zoom) - threshold-tiny (/ 10 zoom) +(defn- calculate-handlers + "Calculates selection handlers for the current selection." + [selection shape zoom] + (let [x (dm/get-prop selection :x) + y (dm/get-prop selection :y) + width (dm/get-prop selection :width) + height (dm/get-prop selection :height) - small-width? (<= width threshold-small) - tiny-width? (<= width threshold-tiny) + threshold-small (/ 25 zoom) + threshold-tiny (/ 10 zoom) - small-height? (<= height threshold-small) - tiny-height? (<= height threshold-tiny) + small-width? (<= width threshold-small) + tiny-width? (<= width threshold-tiny) - vertical-line? (and (= type :path) tiny-width?) - horizontal-line? (and (= type :path) tiny-height?) + small-height? (<= height threshold-small) + tiny-height? (<= height threshold-tiny) - align (if (or small-width? small-height?) - :outside - :inside)] - (->> - [;; TOP-LEFT - {:type :rotation - :position :top-left - :props {:cx x :cy y}} + path? (cfh/path-shape? shape) + vertical-line? (and ^boolean path? ^boolean tiny-width?) + horizontal-line? (and ^boolean path? ^boolean tiny-height?) - {:type :rotation - :position :top-right - :props {:cx (+ x width) :cy y}} + align (if (or ^boolean small-width? ^boolean small-height?) + :outside + :inside) - {:type :rotation - :position :bottom-right - :props {:cx (+ x width) :cy (+ y height)}} + result #js [#js {:type :rotation + :position :top-left + :props #js {:cx x :cy y}} - {:type :rotation - :position :bottom-left - :props {:cx x :cy (+ y height)}} + #js {:type :rotation + :position :top-right + :props #js {:cx (+ x width) :cy y}} - (when-not horizontal-line? - (let [x (if small-width? (+ x (/ (- width threshold-small) 2)) x) - length (if small-width? threshold-small width)] - {:type :resize-side - :position :top - :props {:x x - :y y - :length length - :angle 0 - :align align - :show-handler? tiny-width?}})) + #js {:type :rotation + :position :bottom-right + :props #js {:cx (+ x width) :cy (+ y height)}} - (when-not horizontal-line? - (let [x (if small-width? (+ x (/ (+ width threshold-small) 2)) (+ x width)) - length (if small-width? threshold-small width)] - {:type :resize-side - :position :bottom - :props {:x x - :y (+ y height) - :length length - :angle 180 - :align align - :show-handler? tiny-width?}})) + #js {:type :rotation + :position :bottom-left + :props #js {:cx x :cy (+ y height)}}]] - (when-not vertical-line? - (let [y (if small-height? (+ y (/ (- height threshold-small) 2)) y) - length (if small-height? threshold-small height)] - {:type :resize-side - :position :right - :props {:x (+ x width) - :y y - :length length - :angle 90 - :align align - :show-handler? tiny-height?}})) - (when-not vertical-line? - (let [y (if small-height? (+ y (/ (+ height threshold-small) 2)) (+ y height)) - length (if small-height? threshold-small height)] - {:type :resize-side - :position :left - :props {:x x - :y y - :length length - :angle 270 - :align align - :show-handler? tiny-height?}})) + (when-not ^boolean horizontal-line? + (array/conj! result + #js {:type :resize-side + :position :top + :props #js {:x (if ^boolean small-width? + (+ x (/ (- width threshold-small) 2)) + x) + :y y + :length (if ^boolean small-width? + threshold-small + width) + :angle 0 + :align align + :show-handler tiny-width?}} + #js {:type :resize-side + :position :bottom + :props #js {:x (if ^boolean small-width? + (+ x (/ (+ width threshold-small) 2)) + (+ x width)) + :y (+ y height) + :length (if small-width? threshold-small width) + :angle 180 + :align align + :show-handler tiny-width?}})) - (when (and (not tiny-width?) (not tiny-height?)) - {:type :resize-point - :position :top-left - :props {:cx x :cy y :align align}}) + (when-not vertical-line? + (array/conj! result + #js {:type :resize-side + :position :right + :props #js {:x (+ x width) + :y (if small-height? (+ y (/ (- height threshold-small) 2)) y) + :length (if small-height? threshold-small height) + :angle 90 + :align align + :show-handler tiny-height?}} - (when (and (not tiny-width?) (not tiny-height?)) - {:type :resize-point - :position :top-right - :props {:cx (+ x width) :cy y :align align}}) + #js {:type :resize-side + :position :left + :props #js {:x x + :y (if ^boolean small-height? + (+ y (/ (+ height threshold-small) 2)) + (+ y height)) + :length (if ^boolean small-height? + threshold-small + height) + :angle 270 + :align align + :show-handler tiny-height?}})) - (when (and (not tiny-width?) (not tiny-height?)) - {:type :resize-point - :position :bottom-right - :props {:cx (+ x width) :cy (+ y height) :align align}}) + (when (and (not tiny-width?) (not tiny-height?)) + (array/conj! result + #js {:type :resize-point + :position :top-left + :props #js {:cx x :cy y :align align}} + #js {:type :resize-point + :position :top-right + :props #js {:cx (+ x width) :cy y :align align}} + #js {:type :resize-point + :position :bottom-right + :props #js {:cx (+ x width) :cy (+ y height) :align align}} + #js {:type :resize-point + :position :bottom-left + :props #js {:cx x :cy (+ y height) :align align}})))) - (when (and (not tiny-width?) (not tiny-height?)) - {:type :resize-point - :position :bottom-left - :props {:cx x :cy (+ y height) :align align}})] +(mf/defc rotation-handler + {::mf/wrap-props false} + [{:keys [cx cy transform position rotation zoom on-rotate] :as props}] + (let [size (/ rotation-handler-size zoom) + delta-x (if (or (= position :top-left) + (= position :bottom-left)) + size + 0) + delta-y (if (or (= :top-left position) + (= :top-right position)) + size + 0) - (filterv (comp not nil?))))) - -(mf/defc rotation-handler [{:keys [cx cy transform position rotation zoom on-rotate]}] - (let [size (/ rotation-handler-size zoom) - x (- cx (if (#{:top-left :bottom-left} position) size 0)) - y (- cy (if (#{:top-left :top-right} position) size 0)) - angle (case position - :top-left 0 - :top-right 90 - :bottom-right 180 - :bottom-left 270)] + x (- cx delta-x) + y (- cy delta-y) + angle (case position + :top-left 0 + :top-right 90 + :bottom-right 180 + :bottom-left 270)] [:rect {:x x :y y :class (cur/get-dynamic "rotate" (+ rotation angle)) @@ -176,13 +193,20 @@ :on-pointer-down on-rotate}])) (mf/defc resize-point-handler - [{:keys [cx cy zoom position on-resize transform rotation color align]}] - (let [layout (mf/deref refs/workspace-layout) - scale-text (:scale-text layout) - cursor (if (#{:top-left :bottom-right} position) - (if scale-text (cur/get-dynamic "scale-nesw" rotation) (cur/get-dynamic "resize-nesw" rotation)) - (if scale-text (cur/get-dynamic "scale-nwse" rotation) (cur/get-dynamic "resize-nwse" rotation))) - {cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform)] + {::mf/wrap-props false} + [{:keys [cx cy zoom position on-resize transform rotation color align scale-text]}] + (let [cursor (if (or (= position :top-left) + (= position :bottom-right)) + (if ^boolean scale-text + (cur/get-dynamic "scale-nesw" rotation) + (cur/get-dynamic "resize-nesw" rotation)) + (if ^boolean scale-text + (cur/get-dynamic "scale-nwse" rotation) + (cur/get-dynamic "resize-nwse" rotation))) + + pt (gpt/transform (gpt/point cx cy) transform) + cx' (dm/get-prop pt :x) + cy' (dm/get-prop pt :y)] [:g.resize-handler [:circle {:r (/ resize-point-radius zoom) @@ -196,49 +220,68 @@ (if (= align :outside) (let [resize-point-circle-radius (/ resize-point-circle-radius zoom) - offset-x (if (#{:top-right :bottom-right} position) 0 (- resize-point-circle-radius)) - offset-y (if (#{:bottom-left :bottom-right} position) 0 (- resize-point-circle-radius)) - cx (+ cx offset-x) - cy (+ cy offset-y) - {cx' :x cy' :y} (gpt/transform (gpt/point cx cy) transform)] + offset-x (if (or (= position :top-right) + (= position :bottom-right)) + 0 + (- resize-point-circle-radius)) + offset-y (if (or (= position :bottom-left) + (= position :bottom-right)) + 0 + (- resize-point-circle-radius)) + cx (+ cx offset-x) + cy (+ cy offset-y) + pt (gpt/transform (gpt/point cx cy) transform) + cx' (dm/get-prop pt :x) + cy' (dm/get-prop pt :y)] [:rect {:x cx' :y cy' + :data-position (name position) :class cursor - :width resize-point-circle-radius - :height resize-point-circle-radius - :transform (when rotation (dm/fmt "rotate(%, %, %)" rotation cx' cy')) :style {:fill (if (dbg/enabled? :handlers) "red" "none") :stroke-width 0} - :on-pointer-down #(on-resize {:x cx' :y cy'} %)}]) + :width resize-point-circle-radius + :height resize-point-circle-radius + :transform (when (some? rotation) + (dm/fmt "rotate(%, %, %)" rotation cx' cy')) + :on-pointer-down on-resize}]) - [:circle {:on-pointer-down #(on-resize {:x cx' :y cy'} %) + [:circle {:on-pointer-down on-resize :r (/ resize-point-circle-radius zoom) + :data-position (name position) :cx cx' :cy cy' + :data-x cx' + :data-y cy' :class cursor :style {:fill (if (dbg/enabled? :handlers) "red" "none") :stroke-width 0}}])])) +;; The side handler is always rendered horizontally and then rotated (mf/defc resize-side-handler - "The side handler is always rendered horizontally and then rotated" - [{:keys [x y length align angle zoom position rotation transform on-resize color show-handler?]}] - (let [res-point (if (#{:top :bottom} position) - {:y y} - {:x x}) - layout (mf/deref refs/workspace-layout) - scale-text (:scale-text layout) - height (/ resize-side-height zoom) - offset-y (if (= align :outside) (- height) (- (/ height 2))) - target-y (+ y offset-y) - transform-str (dm/str (gmt/multiply transform (gmt/rotate-matrix angle (gpt/point x y))))] + {::mf/wrap-props false} + [{:keys [x y length align angle zoom position rotation transform on-resize color show-handler scale-text]}] + (let [height (/ resize-side-height zoom) + offset-y (if (= align :outside) (- height) (- (/ height 2))) + target-y (+ y offset-y) + transform-str (dm/str (gmt/multiply transform (gmt/rotate-matrix angle (gpt/point x y)))) + cursor (if (or (= position :left) + (= position :right)) + (if ^boolean scale-text + (cur/get-dynamic "scale-ew" rotation) + (cur/get-dynamic "resize-ew" rotation)) + (if ^boolean scale-text + (cur/get-dynamic "scale-ns" rotation) + (cur/get-dynamic "resize-ns" rotation)))] + [:g.resize-handler - (when show-handler? + (when ^boolean show-handler [:circle {:r (/ resize-point-radius zoom) :style {:fillOpacity 1 :stroke color :strokeWidth "1px" :fill "var(--color-white)" :vectorEffect "non-scaling-stroke"} + :data-position (name position) :cx (+ x (/ length 2)) :cy y :transform transform-str}]) @@ -246,42 +289,25 @@ :y target-y :width length :height height - :class (if (#{:left :right} position) - (if scale-text (cur/get-dynamic "scale-ew" rotation) (cur/get-dynamic "resize-ew" rotation)) - (if scale-text (cur/get-dynamic "scale-ns" rotation) (cur/get-dynamic "resize-ns" rotation))) + :class cursor + :data-position (name position) :transform transform-str - :on-pointer-down #(on-resize res-point %) + :on-pointer-down on-resize :style {:fill (if (dbg/enabled? :handlers) "yellow" "none") :stroke-width 0}}]])) -(defn minimum-selrect [{:keys [x y width height] :as selrect}] - (let [final-width (max width min-selrect-side) - final-height (max height min-selrect-side) - offset-x (/ (- final-width width) 2) - offset-y (/ (- final-height height) 2)] - {:x (- x offset-x) - :y (- y offset-y) - :width final-width - :height final-height})) - (mf/defc controls-selection {::mf/wrap-props false} - [props] - (let [shape (obj/get props "shape") - zoom (obj/get props "zoom") - color (obj/get props "color") - on-move-selected (obj/get props "on-move-selected") - on-context-menu (obj/get props "on-context-menu") - disable-handlers (obj/get props "disable-handlers") + [{:keys [shape zoom color on-move-selected on-context-menu disable-handlers]}] + (let [selrect (dm/get-prop shape :selrect) + transform-type (mf/deref refs/current-transform) + transform (gsh/transform-str shape)] - current-transform (mf/deref refs/current-transform) - - selrect (:selrect shape) - transform (gsh/transform-str shape)] - - (when (and (not (:transforming shape)) - (not (#{:move :rotate} current-transform))) - [:g.controls {:pointer-events (if disable-handlers "none" "visible")} + (when (and (some? selrect) + (not (:transforming shape)) + (not (or (= transform-type :move) + (= transform-type :rotate)))) + [:g.controls {:pointer-events (if ^boolean disable-handlers "none" "visible")} ;; Selection rect [:& selection-rect {:rect selrect :transform transform @@ -292,54 +318,61 @@ (mf/defc controls-handlers {::mf/wrap-props false} - [props] - (let [shape (obj/get props "shape") - zoom (obj/get props "zoom") - color (obj/get props "color") - on-resize (obj/get props "on-resize") - on-rotate (obj/get props "on-rotate") - disable-handlers (obj/get props "disable-handlers") - current-transform (mf/deref refs/current-transform) - workspace-read-only? (mf/use-ctx ctx/workspace-read-only?) + [{:keys [shape zoom color on-resize on-rotate disable-handlers]}] + (let [transform-type (mf/deref refs/current-transform) + read-only? (mf/use-ctx ctx/workspace-read-only?) - selrect (:selrect shape) - transform (gsh/transform-matrix shape) + layout (mf/deref refs/workspace-layout) + scale-text? (contains? layout :scale-text) - rotation (-> (gpt/point 1 0) - (gpt/transform (:transform shape)) - (gpt/angle) - (mod 360))] + selrect (dm/get-prop shape :selrect) + transform (gsh/transform-matrix shape) - (when (and (not (#{:move :rotate} current-transform)) - (not workspace-read-only?) - (not (:transforming shape))) - [:g.controls {:pointer-events (if disable-handlers "none" "visible")} - ;; Handlers - (for [{:keys [type position props]} (handlers-for-selection selrect shape zoom)] - (let [rotation - (cond - (and (#{:top-left :bottom-right} position) - (or (and (:flip-x shape) (not (:flip-y shape))) - (and (:flip-y shape) (not (:flip-x shape))))) - (- rotation 90) + rotation (-> (gpt/point 1 0) + (gpt/transform (:transform shape)) + (gpt/angle) + (mod 360)) - (and (#{:top-right :bottom-left} position) - (or (and (:flip-x shape) (not (:flip-y shape))) - (and (:flip-y shape) (not (:flip-x shape))))) - (+ rotation 90) + flip-x (get shape :flip-x) + flip-y (get shape :flip-y) + half-flip? (or (and (some? flip-x) (not (some? flip-y))) + (and (some? flip-y) (not (some? flip-x))))] - :else - rotation) + (when (and (not ^boolean read-only?) + (not (:transforming shape)) + (not (or (= transform-type :move) + (= transform-type :rotate)))) - common-props {:key (dm/str (name type) "-" (name position)) - :zoom zoom - :position position - :on-rotate on-rotate - :on-resize (partial on-resize position) - :transform transform - :rotation rotation - :color color} - props (map->obj (merge common-props props))] + [:g.controls {:pointer-events (if ^boolean disable-handlers "none" "visible")} + (for [handler (calculate-handlers selrect shape zoom)] + (let [type (obj/get handler "type") + position (obj/get handler "position") + props (obj/get handler "props") + rotation (cond + (and ^boolean half-flip? + (or (= position :top-left) + (= position :bottom-right))) + (- rotation 90) + + (and ^boolean half-flip? + (or (= position :top-right) + (= position :bottom-left))) + (- rotation 90) + + :else + rotation) + + props (obj/merge! + #js {:key (dm/str (name type) "-" (name position)) + :scale-text scale-text? + :zoom zoom + :position position + :on-rotate on-rotate + :on-resize on-resize + :transform transform + :rotation rotation + :color color} + props)] (case type :rotation [:> rotation-handler props] :resize-point [:> resize-point-handler props] @@ -348,8 +381,12 @@ ;; --- Selection Handlers (Component) (mf/defc text-edition-selection - [{:keys [shape color zoom] :as props}] - (let [{:keys [x y width height]} shape] + {::mf/wrap-props false} + [{:keys [shape color zoom]}] + (let [x (dm/get-prop shape :x) + y (dm/get-prop shape :y) + width (dm/get-prop shape :width) + height (dm/get-prop shape :height)] [:g.controls [:rect.main {:x x :y y :transform (gsh/transform-str shape) @@ -362,23 +399,31 @@ :fill "none"}}]])) (mf/defc multiple-handlers - [{:keys [shapes selected zoom color disable-handlers] :as props}] + {::mf/wrap-props false} + [{:keys [shapes selected zoom color disable-handlers]}] (let [shape (mf/with-memo [shapes] (-> shapes (gsh/shapes->rect) (assoc :type :multiple) (cts/setup-shape))) + on-resize - (fn [current-position _initial-position event] - (when (dom/left-mouse? event) - (dom/stop-propagation event) - (st/emit! (dw/start-resize current-position selected shape)))) + (mf/use-fn + (mf/deps selected shape) + (fn [event] + (when (dom/left-mouse? event) + (dom/stop-propagation event) + (let [target (dom/get-current-target event) + position (keyword (dom/get-data target "position"))] + (st/emit! (dw/start-resize position selected shape)))))) on-rotate - (fn [event] - (when (dom/left-mouse? event) - (dom/stop-propagation event) - (st/emit! (dw/start-rotate shapes))))] + (mf/use-fn + (mf/deps shapes) + (fn [event] + (when (dom/left-mouse? event) + (dom/stop-propagation event) + (st/emit! (dw/start-rotate shapes)))))] [:& controls-handlers {:shape shape @@ -389,7 +434,8 @@ :on-rotate on-rotate}])) (mf/defc multiple-selection - [{:keys [shapes zoom color disable-handlers on-move-selected on-context-menu] :as props}] + {::mf/wrap-props false} + [{:keys [shapes zoom color disable-handlers on-move-selected on-context-menu]}] (let [shape (mf/with-memo [shapes] (-> shapes (gsh/shapes->rect) @@ -405,20 +451,27 @@ :on-context-menu on-context-menu}])) (mf/defc single-handlers - [{:keys [shape zoom color disable-handlers] :as props}] - (let [shape-id (:id shape) + {::mf/wrap-props false} + [{:keys [shape zoom color disable-handlers]}] + (let [shape-id (dm/get-prop shape :id) on-resize - (fn [current-position _initial-position event] - (when (dom/left-mouse? event) - (dom/stop-propagation event) - (st/emit! (dw/start-resize current-position #{shape-id} shape)))) + (mf/use-fn + (mf/deps shape-id shape) + (fn [event] + (when (dom/left-mouse? event) + (dom/stop-propagation event) + (let [target (dom/get-current-target event) + position (keyword (dom/get-data target "position"))] + (st/emit! (dw/start-resize position #{shape-id} shape)))))) on-rotate - (fn [event] - (when (dom/left-mouse? event) - (dom/stop-propagation event) - (st/emit! (dw/start-rotate [shape]))))] + (mf/use-fn + (mf/deps shape) + (fn [event] + (when (dom/left-mouse? event) + (dom/stop-propagation event) + (st/emit! (dw/start-rotate [shape])))))] [:& controls-handlers {:shape shape @@ -429,7 +482,8 @@ :on-resize on-resize}])) (mf/defc single-selection - [{:keys [shape zoom color disable-handlers on-move-selected on-context-menu] :as props}] + {::mf/wrap-props false} + [{:keys [shape zoom color disable-handlers on-move-selected on-context-menu]}] [:& controls-selection {:shape shape :zoom zoom @@ -439,23 +493,25 @@ :on-context-menu on-context-menu}]) (mf/defc selection-area - {::mf/wrap [mf/memo]} - [{:keys [shapes edition zoom disable-handlers on-move-selected on-context-menu] :as props}] - (let [num (count shapes) - {:keys [type] :as shape} (first shapes) + {::mf/wrap-props false} + [{:keys [shapes edition zoom disable-handlers on-move-selected on-context-menu]}] + (let [total (count shapes) + + shape (first shapes) + shape-id (dm/get-prop shape :id) ;; Note that we don't use mf/deref to avoid a repaint dependency here objects (deref refs/workspace-page-objects) - color (if (and (= num 1) - (ctn/in-any-component? objects shape)) - selection-rect-color-component - selection-rect-color-normal)] + color (if (and (= total 1) ^boolean (ctn/in-any-component? objects shape)) + selection-rect-color-component + selection-rect-color-normal)] + (cond - (zero? num) + (zero? total) nil - (> num 1) + (> total 1) [:& multiple-selection {:shapes shapes :zoom zoom @@ -464,13 +520,14 @@ :on-move-selected on-move-selected :on-context-menu on-context-menu}] - (and (= type :text) (= edition (:id shape))) + (and (cfh/text-shape? shape) + (= edition shape-id)) [:& text-edition-selection {:shape shape :zoom zoom :color color}] - (= edition (:id shape)) + (= edition shape-id) nil :else @@ -483,23 +540,25 @@ :on-context-menu on-context-menu}]))) (mf/defc selection-handlers - {::mf/wrap [mf/memo]} - [{:keys [shapes selected edition zoom disable-handlers] :as props}] - (let [num (count shapes) - {:keys [type] :as shape} (first shapes) + {::mf/wrap-props false} + [{:keys [shapes selected edition zoom disable-handlers]}] + (let [total (count shapes) + + shape (first shapes) + shape-id (dm/get-prop shape :id) ;; Note that we don't use mf/deref to avoid a repaint dependency here objects (deref refs/workspace-page-objects) - color (if (and (= num 1) - (ctn/in-any-component? objects shape)) - selection-rect-color-component - selection-rect-color-normal)] + color (if (and (= total 1) ^boolean (ctn/in-any-component? objects shape)) + selection-rect-color-component + selection-rect-color-normal)] + (cond - (zero? num) + (zero? total) nil - (> num 1) + (> total 1) [:& multiple-handlers {:shapes shapes :selected selected @@ -507,10 +566,11 @@ :color color :disable-handlers disable-handlers}] - (and (= type :text) (= edition (:id shape))) + (and (cfh/text-shape? shape) + (= edition shape-id)) nil - (= edition (:id shape)) + (= edition shape-id) [:& path-editor {:zoom zoom :shape shape}] diff --git a/frontend/src/app/util/array.cljs b/frontend/src/app/util/array.cljs index 2c85375e9e..875a4ba32d 100644 --- a/frontend/src/app/util/array.cljs +++ b/frontend/src/app/util/array.cljs @@ -15,6 +15,22 @@ (defn conj! "A conj! like function for js arrays." - [a v] - (.push ^js a v) - a) + ([a v] + (.push ^js a v) + a) + ([a v1 v2] + (.push ^js a v1 v2) + a) + ([a v1 v2 v3] + (.push ^js a v1 v2 v3) + a) + ([a v1 v2 v3 v4] + (.push ^js a v1 v2 v3 v4) + a) + ([a v1 v2 v3 v4 v5] + (.push ^js a v1 v2 v3 v4 v5) + a) + ([a v1 v2 v3 v4 v5 v6] + (.push ^js a v1 v2 v3 v4 v5 v6) + a)) + From 36b5ca7313bd6eaf7b706ee914e42f86be01978a Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 13:15:23 +0100 Subject: [PATCH 20/25] :zap: Add performance improvements to start-resize --- .../app/main/data/workspace/transforms.cljs | 211 +++++++++++------- 1 file changed, 125 insertions(+), 86 deletions(-) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index b24fa35735..de8195d90a 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -45,17 +45,19 @@ ;; For each of the 8 handlers gives the multiplier for resize ;; for example, right will only grow in the x coordinate and left ;; will grow in the inverse of the x coordinate -(def ^:private handler-multipliers - {:right [1 0] - :bottom [0 1] - :left [-1 0] - :top [0 -1] - :top-right [1 -1] - :top-left [-1 -1] - :bottom-right [1 1] - :bottom-left [-1 1]}) +(defn get-handler-multiplier + [handler] + (case handler + :right (gpt/point 1 0) + :bottom (gpt/point 0 1) + :left (gpt/point -1 0) + :top (gpt/point 0 -1) + :top-right (gpt/point 1 -1) + :top-left (gpt/point -1 -1) + :bottom-right (gpt/point 1 1) + :bottom-left (gpt/point -1 1))) -(defn- handler-resize-origin +(defn- get-handler-resize-origin "Given a handler, return the coordinate origin for resizes. This is the opposite of the handler so for right we want the left side as origin of the resize. @@ -64,39 +66,66 @@ mx, my => middle x/y ex, ey => end x/y " - [{sx :x sy :y :keys [width height]} handler] - (let [mx (+ sx (/ width 2)) - my (+ sy (/ height 2)) - ex (+ sx width) - ey (+ sy height) - - [x y] (case handler - :right [sx my] - :bottom [mx sy] - :left [ex my] - :top [mx ey] - :top-right [sx ey] - :top-left [ex ey] - :bottom-right [sx sy] - :bottom-left [ex sy])] - (gpt/point x y))) + [selrect handler] + (let [sx (dm/get-prop selrect :x) + sy (dm/get-prop selrect :y) + width (dm/get-prop selrect :width) + height (dm/get-prop selrect :height) + mx (+ sx (/ width 2)) + my (+ sy (/ height 2)) + ex (+ sx width) + ey (+ sy height)] + (case handler + :right (gpt/point sx my) + :bottom (gpt/point mx sy) + :left (gpt/point ex my) + :top (gpt/point mx ey) + :top-right (gpt/point sx ey) + :top-left (gpt/point ex ey) + :bottom-right (gpt/point sx sy) + :bottom-left (gpt/point ex sy)))) (defn- fix-init-point "Fix the initial point so the resizes are accurate" [initial handler shape] - (let [{:keys [x y width height]} (:selrect shape)] - (cond-> initial - (contains? #{:left :top-left :bottom-left} handler) - (assoc :x x) + (let [selrect (dm/get-prop shape :selrect) + x (dm/get-prop selrect :x) + y (dm/get-prop selrect :y) + width (dm/get-prop selrect :width) + height (dm/get-prop selrect :height)] - (contains? #{:right :top-right :bottom-right} handler) - (assoc :x (+ x width)) + (case handler + :left + (assoc initial :x x) - (contains? #{:top :top-right :top-left} handler) - (assoc :y y) + :top + (assoc initial :y y) - (contains? #{:bottom :bottom-right :bottom-left} handler) - (assoc :y (+ y height))))) + :top-left + (-> initial + (assoc :x x) + (assoc :y y)) + + :bottom-left + (-> initial + (assoc :x x) + (assoc :y (+ y height))) + + :right + (assoc initial :x (+ x width)) + + :top-right + (-> initial + (assoc :x (+ x width)) + (assoc :y y)) + + :bottom-right + (-> initial + (assoc :x (+ x width)) + (assoc :y (+ y height))) + + :bottom + (assoc initial :y (+ y height))))) (defn finish-transform [] (ptk/reify ::finish-transform @@ -104,16 +133,16 @@ (update [_ state] (update state :workspace-local dissoc :transform :duplicate-move-started? false)))) - ;; -- Resize -------------------------------------------------------- (defn start-resize "Enter mouse resize mode, until mouse button is released." [handler ids shape] - (letfn [(resize - [shape initial layout [point lock? center? point-snap]] - (let [{:keys [width height]} (:selrect shape) - {:keys [rotation]} shape + (letfn [(resize [shape initial layout [point lock? center? point-snap]] + (let [selrect (dm/get-prop shape :selrect) + width (dm/get-prop selrect :width) + height (dm/get-prop selrect :height) + rotation (dm/get-prop shape :rotation) shape-center (gsh/shape->center shape) shape-transform (:transform shape) @@ -129,78 +158,84 @@ shapev (-> (gpt/point width height)) - scale-text (:scale-text layout) + scale-text (contains? layout :scale-text) ;; Force lock if the scale text mode is active - lock? (or lock? scale-text) + lock? (or ^boolean lock? + ^boolean scale-text) - ;; Vector modifiers depending on the handler - handler-mult (let [[x y] (handler-multipliers handler)] (gpt/point x y)) - - ;; Difference between the origin point in the coordinate system of the rotation + ;; Difference between the origin point in the + ;; coordinate system of the rotation deltav (-> (gpt/to-vec initial point) - (gpt/multiply handler-mult)) + ;; Vector modifiers depending on the handler + (gpt/multiply (get-handler-multiplier handler))) ;; Resize vector scalev (-> (gpt/divide (gpt/add shapev deltav) shapev) (gpt/no-zeros)) - scalev (if lock? + scalev (if ^boolean lock? (let [v (cond - (#{:right :left} handler) (:x scalev) - (#{:top :bottom} handler) (:y scalev) - :else (max (:x scalev) (:y scalev)))] - (gpt/point v v)) + (or (= handler :right) + (= handler :left)) + (dm/get-prop scalev :x) + (or (= handler :top) + (= handler :bottom)) + (dm/get-prop scalev :y) + + :else + (mth/max (dm/get-prop scalev :x) + (dm/get-prop scalev :y)))] + (gpt/point v v)) scalev) ;; Resize origin point given the selected handler - handler-origin (handler-resize-origin (:selrect shape) handler) - + selrect (dm/get-prop shape :selrect) + handler-origin (get-handler-resize-origin selrect handler) ;; If we want resize from center, displace the shape ;; so it is still centered after resize. - displacement - (when center? - (-> shape-center - (gpt/subtract handler-origin) - (gpt/multiply scalev) - (gpt/add handler-origin) - (gpt/subtract shape-center) - (gpt/multiply (gpt/point -1 -1)) - (gpt/transform shape-transform))) + displacement (when ^boolean center? + (-> shape-center + (gpt/subtract handler-origin) + (gpt/multiply scalev) + (gpt/add handler-origin) + (gpt/subtract shape-center) + (gpt/multiply (gpt/point -1 -1)) + (gpt/transform shape-transform))) - resize-origin - (cond-> (gmt/transform-point-center handler-origin shape-center shape-transform) - (some? displacement) - (gpt/add displacement)) + resize-origin (gmt/transform-point-center handler-origin shape-center shape-transform) + resize-origin (if (some? displacement) + (gpt/add resize-origin displacement) + resize-origin) ;; When the horizontal/vertical scale a flex children with auto/fill ;; we change it too fixed set-fix-width? - (not (mth/close? (:x scalev) 1)) + (not (mth/close? (dm/get-prop scalev :x) 1)) set-fix-height? - (not (mth/close? (:y scalev) 1)) + (not (mth/close? (dm/get-prop scalev :y) 1)) - modifiers - (-> (ctm/empty) + modifiers (cond-> (ctm/empty) + (some? displacement) + (ctm/move displacement) - (cond-> displacement - (ctm/move displacement)) + :always + (ctm/resize scalev resize-origin shape-transform shape-transform-inverse) - (ctm/resize scalev resize-origin shape-transform shape-transform-inverse) + ^boolean set-fix-width? + (ctm/change-property :layout-item-h-sizing :fix) - (cond-> set-fix-width? - (ctm/change-property :layout-item-h-sizing :fix)) + ^boolean set-fix-height? + (ctm/change-property :layout-item-v-sizing :fix) - (cond-> set-fix-height? - (ctm/change-property :layout-item-v-sizing :fix)) - - (cond-> scale-text - (ctm/scale-content (:x scalev)))) + ^boolean scale-text + (ctm/scale-content (dm/get-prop scalev :x))) modif-tree (dwm/create-modif-tree ids modifiers)] + (rx/of (dwm/set-modifiers modif-tree scale-text)))) ;; Unifies the instantaneous proportion lock modifier @@ -208,7 +243,10 @@ ;; lock flag that can be activated on element options. (normalize-proportion-lock [[point shift? alt?]] (let [proportion-lock? (:proportion-lock shape)] - [point (or proportion-lock? shift?) alt?]))] + [point + (or ^boolean proportion-lock? + ^boolean shift?) + alt?]))] (reify ptk/UpdateEvent (update [_ state] @@ -218,15 +256,16 @@ ptk/WatchEvent (watch [_ state stream] (let [initial-position @ms/mouse-position + stopper (->> stream (rx/filter mse/mouse-event?) (rx/filter mse/mouse-up-event?)) layout (:workspace-layout state) page-id (:current-page-id state) focus (:workspace-focus-selected state) - zoom (get-in state [:workspace-local :zoom] 1) + zoom (dm/get-in state [:workspace-local :zoom] 1) objects (wsh/lookup-page-objects state page-id) - resizing-shapes (map #(get objects %) ids)] + shapes (map (d/getf objects) ids)] (rx/concat (->> ms/mouse-position @@ -234,7 +273,7 @@ (rx/with-latest-from ms/mouse-position-shift ms/mouse-position-alt) (rx/map normalize-proportion-lock) (rx/switch-map (fn [[point _ _ :as current]] - (->> (snap/closest-snap-point page-id resizing-shapes objects layout zoom focus point) + (->> (snap/closest-snap-point page-id shapes objects layout zoom focus point) (rx/map #(conj current %))))) (rx/mapcat (partial resize shape initial-position layout)) (rx/take-until stopper)) From 77472aabea2e3c52b4c50be6cc585e3b65041008 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 14:58:19 +0100 Subject: [PATCH 21/25] :sparkles: Add path parser js impl more resilent to parse errors --- common/src/app/common/svg/path/parser.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/common/src/app/common/svg/path/parser.js b/common/src/app/common/svg/path/parser.js index 804112f073..5bbcddd3a0 100644 --- a/common/src/app/common/svg/path/parser.js +++ b/common/src/app/common/svg/path/parser.js @@ -916,11 +916,21 @@ function simplifyPathData(pdata) { export function parse(string) { if (!string || string.length === 0) return []; - var source = new Parser(string); - var result = Array.from(source); + try { + var source = new Parser(string); + var result = Array.from(source); - result = absolutizePathData(result); - result = simplifyPathData(result); + result = absolutizePathData(result); + result = simplifyPathData(result); - return result; + return result; + } catch (cause) { + const msg = "unexpected exception parsing path"; + console.group(msg); + console.log(`string: ${string}`) + console.error(cause); + console.groupEnd(msg); + + return []; + } } From b6c257bfc5f631f6e30dc45c897b6a8a8341571d Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 16:13:04 +0100 Subject: [PATCH 22/25] :bug: Fix incorrect svg-attrs handlng on .zip import process --- common/src/app/common/files/builder.cljc | 9 +- common/src/app/common/svg.cljc | 112 ++++++------------ common/test/common_tests/svg_test.cljc | 6 +- frontend/src/app/main/ui/shapes/export.cljs | 2 +- frontend/src/app/main/ui/shapes/svg_defs.cljs | 9 +- frontend/src/app/main/ui/shapes/svg_raw.cljs | 7 +- frontend/src/app/worker/import.cljs | 3 +- 7 files changed, 56 insertions(+), 92 deletions(-) diff --git a/common/src/app/common/files/builder.cljc b/common/src/app/common/files/builder.cljc index 46c1e91317..0fe6b98d36 100644 --- a/common/src/app/common/files/builder.cljc +++ b/common/src/app/common/files/builder.cljc @@ -15,6 +15,7 @@ [app.common.geom.shapes :as gsh] [app.common.pprint :as pp] [app.common.schema :as sm] + [app.common.svg :as csvg] [app.common.types.components-list :as ctkl] [app.common.types.container :as ctn] [app.common.types.file :as ctf] @@ -300,9 +301,13 @@ (-> file (update :parent-stack pop)))) -(defn create-shape [file type data] - (let [obj (-> (cts/setup-shape (assoc data :type type)) +(defn create-shape + [file type data] + (let [obj (-> (assoc data :type type) + (update :svg-attrs csvg/attrs->props) + (cts/setup-shape) (check-name file :type))] + (-> file (commit-shape obj) (assoc :last-id (:id obj)) diff --git a/common/src/app/common/svg.cljc b/common/src/app/common/svg.cljc index 878d561093..7974eaa28d 100644 --- a/common/src/app/common/svg.cljc +++ b/common/src/app/common/svg.cljc @@ -608,12 +608,18 @@ (contains? svg-attr-list k) (contains? svg-present-list k)) (cond + (nil? v) + res + (= k :class) (assoc res :className v) (= k :style) - (let [v (if (string? v) (parse-style v) v)] - (assoc res k (attrs->props v false))) + (let [v (if (string? v) (parse-style v) v) + v (not-empty (attrs->props v false))] + (if v + (assoc res k v) + res)) :else (let [k (if (contains? non-react-props k) @@ -624,68 +630,6 @@ {} attrs))) -(defn clean-attrs - "Transforms attributes to their react equivalent - - DEPRECATED: replaced by attrs->props" - ([attrs] - (clean-attrs attrs true)) - - ([attrs whitelist?] - (letfn [(known-property? [[key _]] - (or (not whitelist?) - (contains? svg-attr-list key) - (contains? svg-present-list key))) - - (camelize [s] - (when (string? s) - #?(:cljs (js* "~{}.replace(\":\", \"-\").replace(/-./g, x=>x[1].toUpperCase())", s) - :clj (str/camel s)))) - - (transform-key [key] - (if (contains? non-react-props key) - key - (-> (d/name key) - (camelize) - (keyword)))) - - (format-styles [style-str] - (->> (str/split style-str ";") - (map str/trim) - (map #(str/split % ":")) - (group-by first) - (map (fn [[key val]] - [(transform-key key) - (second (first val))])) - (into {}))) - - (clean-key [[key val]] - (let [key (keyword key)] - (cond - (= key :class) - [:className val] - - (and (= key :style) - (string? val)) - [key (format-styles val)] - - (and (= key :style) - (map? val)) - [key (clean-attrs val false)] - - :else - [(transform-key key) val])))] - - ;; Removed this warning because slows a lot rendering with big svgs - #_(let [filtered-props (->> attrs (remove known-property?) (map first))] - (when (seq filtered-props) - (.warn js/console "Unknown properties: " (str/join ", " filtered-props)))) - - (into {} - (comp (filter known-property?) - (map clean-key)) - attrs)))) - (defn update-attr-ids "Replaces the ids inside a property" [attrs replace-fn] @@ -723,7 +667,8 @@ (reduce visit-node result (:content node))))] (visit-node {} content))) -(defn extract-defs [{:keys [attrs] :as node}] +(defn extract-defs + [{:keys [attrs] :as node}] (if-not (map? node) [{} node] @@ -741,19 +686,22 @@ [node-defs node]))) -(defn find-attr-references [attrs] +(defn find-attr-references + [attrs] (->> attrs (mapcat (fn [[_ attr-value]] (if (string? attr-value) (extract-ids attr-value) (find-attr-references attr-value)))))) -(defn find-node-references [node] +(defn find-node-references + [node] (let [current (->> (find-attr-references (:attrs node)) (into #{})) children (->> (:content node) (map find-node-references) (flatten) (into #{}))] (vec (into current children)))) -(defn find-def-references [defs references] +(defn find-def-references + [defs references] (loop [result (into #{} references) checked? #{} to-check (first references) @@ -778,7 +726,8 @@ (first pending) (rest pending)))))) -(defn svg-transform-matrix [shape] +(defn svg-transform-matrix + [shape] (if (:svg-viewbox shape) (let [{svg-x :x svg-y :y @@ -810,34 +759,39 @@ ;; Transforms spec: ;; https://www.w3.org/TR/SVG11/single-page.html#coords-TransformAttribute - -(defn format-translate-params [params] +(defn format-translate-params + [params] (assert (or (= (count params) 1) (= (count params) 2))) (if (= (count params) 1) [(gpt/point (nth params 0) 0)] [(gpt/point (nth params 0) (nth params 1))])) -(defn format-scale-params [params] +(defn format-scale-params + [params] (assert (or (= (count params) 1) (= (count params) 2))) (if (= (count params) 1) [(gpt/point (nth params 0))] [(gpt/point (nth params 0) (nth params 1))])) -(defn format-rotate-params [params] +(defn format-rotate-params + [params] (assert (or (= (count params) 1) (= (count params) 3)) (str "??" (count params))) (if (= (count params) 1) [(nth params 0) (gpt/point 0 0)] [(nth params 0) (gpt/point (nth params 1) (nth params 2))])) -(defn format-skew-x-params [params] +(defn format-skew-x-params + [params] (assert (= (count params) 1)) [(nth params 0) 0]) -(defn format-skew-y-params [params] +(defn format-skew-y-params + [params] (assert (= (count params) 1)) [0 (nth params 0)]) -(defn to-matrix [{:keys [type params]}] +(defn to-matrix + [{:keys [type params]}] (assert (#{"matrix" "translate" "scale" "rotate" "skewX" "skewY"} type)) (case type "matrix" (apply gmt/matrix params) @@ -847,7 +801,8 @@ "skewX" (apply gmt/skew-matrix (format-skew-x-params params)) "skewY" (apply gmt/skew-matrix (format-skew-y-params params)))) -(defn parse-transform [transform-attr] +(defn parse-transform + [transform-attr] (if transform-attr (let [process-matrix (fn [[_ type params]] @@ -865,7 +820,8 @@ (defn format-move [[x y]] (str "M" x " " y)) (defn format-line [[x y]] (str "L" x " " y)) -(defn points->path [points-str] +(defn points->path + [points-str] (let [points (->> points-str (re-seq number-regex) (filter (comp not empty? first)) diff --git a/common/test/common_tests/svg_test.cljc b/common/test/common_tests/svg_test.cljc index f5731999f8..364286e5f3 100644 --- a/common/test/common_tests/svg_test.cljc +++ b/common/test/common_tests/svg_test.cljc @@ -12,21 +12,21 @@ (t/deftest clean-attrs-1 (let [attrs {:class "foobar"} - result (svg/clean-attrs attrs)] + result (svg/attrs->props attrs)] (t/is (= result {:className "foobar"})))) (t/deftest clean-attrs-2 (let [attrs {:overline-position "top" :style {:fill "none" :stroke-dashoffset 1}} - result (svg/clean-attrs attrs true)] + result (svg/attrs->props attrs true)] (t/is (= result {:overlinePosition "top", :style {:fill "none", :strokeDashoffset 1}})))) (t/deftest clean-attrs-3 (let [attrs {:overline-position "top" :style (str "fill:#00801b;fill-opacity:1;stroke:none;stroke-width:2749.72;" "stroke-linecap:round;stroke-dasharray:none;stop-color:#000000")} - result (svg/clean-attrs attrs true)] + result (svg/attrs->props attrs true)] (t/is (= result {:overlinePosition "top", :style {:fill "#00801b", :fillOpacity "1", diff --git a/frontend/src/app/main/ui/shapes/export.cljs b/frontend/src/app/main/ui/shapes/export.cljs index 959be058fb..5c03bf78f8 100644 --- a/frontend/src/app/main/ui/shapes/export.cljs +++ b/frontend/src/app/main/ui/shapes/export.cljs @@ -29,7 +29,7 @@ (cond (map? node) - [:> (d/name tag) (clj->js (csvg/clean-attrs attrs)) + [:> (d/name tag) (obj/map->obj (csvg/attrs->props attrs)) (for [child content] [:& render-xml {:xml child :key (swap! internal-counter inc)}])] diff --git a/frontend/src/app/main/ui/shapes/svg_defs.cljs b/frontend/src/app/main/ui/shapes/svg_defs.cljs index 50092747c0..c2f0fa2be7 100644 --- a/frontend/src/app/main/ui/shapes/svg_defs.cljs +++ b/frontend/src/app/main/ui/shapes/svg_defs.cljs @@ -13,6 +13,7 @@ [app.common.geom.shapes :as gsh] [app.common.geom.shapes.bounds :as gsb] [app.common.svg :as csvg] + [app.util.object :as obj] [rumext.v2 :as mf])) (defn add-matrix [attrs transform-key transform-matrix] @@ -23,7 +24,9 @@ (str transform-matrix " " val) (str transform-matrix))))) -(mf/defc svg-node [{:keys [type node prefix-id transform bounds]}] +(mf/defc svg-node + {::mf/wrap-props false} + [{:keys [type node prefix-id transform bounds]}] (cond (string? node) node @@ -48,7 +51,7 @@ attrs (-> attrs (csvg/update-attr-ids prefix-id) - (csvg/clean-attrs) + (csvg/attrs->props) ;; This clasname will be used to change the transform on the viewport ;; only necessary for groups because shapes have their own transform (cond-> (and (or transform-gradient? @@ -80,7 +83,7 @@ :transform (str transform)}] [mf/Fragment #js {}])] - [:> (name tag) (clj->js attrs) + [:> (name tag) (obj/map->obj attrs) [:> wrapper wrapper-props (for [[index node] (d/enumerate content)] [:& svg-node {:key (dm/str "node-" index) diff --git a/frontend/src/app/main/ui/shapes/svg_raw.cljs b/frontend/src/app/main/ui/shapes/svg_raw.cljs index 21f8c19516..c1b2f5d1be 100644 --- a/frontend/src/app/main/ui/shapes/svg_raw.cljs +++ b/frontend/src/app/main/ui/shapes/svg_raw.cljs @@ -10,7 +10,7 @@ [app.common.geom.shapes :as gsh] [app.common.svg :as csvg] [app.main.ui.context :as muc] - [app.main.ui.shapes.attrs :as usa] + [app.main.ui.shapes.attrs :as attrs] [app.util.object :as obj] [cuerdas.core :as str] [rumext.v2 :as mf])) @@ -41,7 +41,7 @@ props (mf/with-memo [shape render-id] (-> #js {} - (usa/add-fill-props! shape render-id) + (attrs/add-fill-props! shape render-id) (obj/unset! "transform") (obj/set! "x" x) (obj/set! "y" y) @@ -79,8 +79,7 @@ props (mf/with-memo [shape render-id] (let [element-id (dm/get-in shape [:svg-attrs :id]) - props (-> #js {} - (usa/add-fill-props! shape render-id))] + props (attrs/add-fill-props! #js {} shape render-id)] (when (and (some? element-id) (contains? ids-mapping element-id)) diff --git a/frontend/src/app/worker/import.cljs b/frontend/src/app/worker/import.cljs index 3946075c85..2e3875e182 100644 --- a/frontend/src/app/worker/import.cljs +++ b/frontend/src/app/worker/import.cljs @@ -199,7 +199,8 @@ (rx/tap #(progress! context :upload-media name)) (rx/merge-map #(rp/cmd! :upload-file-media-object %)))) -(defn resolve-text-content [node context] +(defn resolve-text-content + [node context] (let [resolve (:resolve context)] (->> node (ct/transform-nodes From e0a1cd6e7737a6bc6ce767e75460f3e3607c10c3 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 16:20:29 +0100 Subject: [PATCH 23/25] :paperclip: Move import parser from util to worker directory --- frontend/src/app/worker/import.cljs | 84 +++++++++---------- .../app/{util => worker}/import/parser.cljs | 2 +- 2 files changed, 43 insertions(+), 43 deletions(-) rename frontend/src/app/{util => worker}/import/parser.cljs (99%) diff --git a/frontend/src/app/worker/import.cljs b/frontend/src/app/worker/import.cljs index 2e3875e182..cc7e3dff52 100644 --- a/frontend/src/app/worker/import.cljs +++ b/frontend/src/app/worker/import.cljs @@ -20,12 +20,12 @@ [app.main.repo :as rp] [app.util.http :as http] [app.util.i18n :as i18n :refer [tr]] - [app.util.import.parser :as cip] [app.util.json :as json] [app.util.sse :as sse] [app.util.webapi :as wapi] [app.util.zip :as uz] [app.worker.impl :as impl] + [app.worker.import.parser :as parser] [beicon.v2.core :as rx] [cuerdas.core :as str] [tubax.core :as tubax])) @@ -259,8 +259,8 @@ (defn process-import-node [context file node] - (let [type (cip/get-type node) - close? (cip/close? node)] + (let [type (parser/get-type node) + close? (parser/close? node)] (if close? (case type :frame (fb/close-artboard file) @@ -270,11 +270,11 @@ #_default file) (let [resolve (:resolve context) - old-id (cip/get-id node) - interactions (->> (cip/parse-interactions node) + old-id (parser/get-id node) + interactions (->> (parser/parse-interactions node) (mapv #(update % :destination resolve))) - data (-> (cip/parse-data type node) + data (-> (parser/parse-data type node) (resolve-data-ids type context) (cond-> (some? old-id) (assoc :id (resolve old-id))) @@ -319,17 +319,17 @@ (defn resolve-media [context file-id node] - (if (or (and (not (cip/close? node)) - (cip/has-image? node)) - (cip/has-stroke-images? node) - (cip/has-fill-images? node)) - (let [name (cip/get-image-name node) - has-image (cip/has-image? node) - image-data (cip/get-image-data node) - image-fill (cip/get-image-fill node) - fill-images-data (->> (cip/get-fill-images-data node) + (if (or (and (not (parser/close? node)) + (parser/has-image? node)) + (parser/has-stroke-images? node) + (parser/has-fill-images? node)) + (let [name (parser/get-image-name node) + has-image (parser/has-image? node) + image-data (parser/get-image-data node) + image-fill (parser/get-image-fill node) + fill-images-data (->> (parser/get-fill-images-data node) (map #(assoc % :type :fill))) - stroke-images-data (->> (cip/get-stroke-images-data node) + stroke-images-data (->> (parser/get-stroke-images-data node) (map #(assoc % :type :stroke))) images-data (concat @@ -367,18 +367,18 @@ (rx/observe-on :async)))) (defn media-node? [node] - (or (and (cip/shape? node) - (cip/has-image? node) - (not (cip/close? node))) - (cip/has-stroke-images? node) - (cip/has-fill-images? node))) + (or (and (parser/shape? node) + (parser/has-image? node) + (not (parser/close? node))) + (parser/has-stroke-images? node) + (parser/has-fill-images? node))) (defn import-page [context file [page-id page-name content]] - (let [nodes (->> content cip/node-seq) + (let [nodes (->> content parser/node-seq) file-id (:id file) resolve (:resolve context) - page-data (-> (cip/parse-page-data content) + page-data (-> (parser/parse-page-data content) (assoc :name page-name) (assoc :id (resolve page-id))) flows (->> (get-in page-data [:options :flows]) @@ -412,32 +412,32 @@ (rx/merge-map (fn [pre-proc] (->> (rx/from nodes) - (rx/filter cip/shape?) + (rx/filter parser/shape?) (rx/map (fn [node] (or (get pre-proc node) node))) (rx/reduce (partial process-import-node context) file) (rx/map (comp fb/close-page setup-interactions)))))))) (defn import-component [context file node] (let [resolve (:resolve context) - content (cip/find-node node :g) + content (parser/find-node node :g) file-id (:id file) - old-id (cip/get-id node) + old-id (parser/get-id node) id (resolve old-id) path (get-in node [:attrs :penpot:path] "") - type (cip/get-type content) + type (parser/get-type content) main-instance-id (resolve (uuid (get-in node [:attrs :penpot:main-instance-id] ""))) main-instance-page (resolve (uuid (get-in node [:attrs :penpot:main-instance-page] ""))) - data (-> (cip/parse-data type content) + data (-> (parser/parse-data type content) (assoc :path path) (assoc :id id) (assoc :main-instance-id main-instance-id) (assoc :main-instance-page main-instance-page)) file (-> file (fb/start-component data type)) - children (cip/node-seq node)] + children (parser/node-seq node)] (->> (rx/from children) - (rx/filter cip/shape?) + (rx/filter parser/shape?) (rx/skip 1) ;; Skip the outer component and the respective closint tag (rx/skip-last 1) ;; because they are handled in start-component an finish-component (rx/mapcat (partial resolve-media context file-id)) @@ -446,18 +446,18 @@ (defn import-deleted-component [context file node] (let [resolve (:resolve context) - content (cip/find-node node :g) + content (parser/find-node node :g) file-id (:id file) - old-id (cip/get-id node) + old-id (parser/get-id node) id (resolve old-id) path (get-in node [:attrs :penpot:path] "") main-instance-id (resolve (uuid (get-in node [:attrs :penpot:main-instance-id] ""))) main-instance-page (resolve (uuid (get-in node [:attrs :penpot:main-instance-page] ""))) main-instance-x (get-in node [:attrs :penpot:main-instance-x] "") main-instance-y (get-in node [:attrs :penpot:main-instance-y] "") - type (cip/get-type content) + type (parser/get-type content) - data (-> (cip/parse-data type content) + data (-> (parser/parse-data type content) (assoc :path path) (assoc :id id) (assoc :main-instance-id main-instance-id) @@ -467,10 +467,10 @@ file (-> file (fb/start-component data)) component-id (:current-component-id file) - children (cip/node-seq node)] + children (parser/node-seq node)] (->> (rx/from children) - (rx/filter cip/shape?) + (rx/filter parser/shape?) (rx/skip 1) (rx/skip-last 1) (rx/mapcat (partial resolve-media context file-id)) @@ -511,7 +511,7 @@ (assoc :id (resolve id)))] (fb/add-library-color file color)))] (->> (get-file context :colors) - (rx/merge-map (comp d/kebab-keys cip/string->uuid)) + (rx/merge-map (comp d/kebab-keys parser/string->uuid)) (rx/reduce add-color file))) (rx/of file))) @@ -521,7 +521,7 @@ (if (:has-typographies context) (let [resolve (:resolve context)] (->> (get-file context :typographies) - (rx/merge-map (comp d/kebab-keys cip/string->uuid)) + (rx/merge-map (comp d/kebab-keys parser/string->uuid)) (rx/map (fn [[id typography]] (-> typography (d/kebab-keys) @@ -535,7 +535,7 @@ (if (:has-media context) (let [resolve (:resolve context)] (->> (get-file context :media-list) - (rx/merge-map (comp d/kebab-keys cip/string->uuid)) + (rx/merge-map (comp d/kebab-keys parser/string->uuid)) (rx/mapcat (fn [[id media]] (let [media (assoc media :id (resolve id))] @@ -559,7 +559,7 @@ [context file] (if (:has-components context) (let [split-components - (fn [content] (->> (cip/node-seq content) + (fn [content] (->> (parser/node-seq content) (filter #(= :symbol (:tag %)))))] (->> (get-file context :components) @@ -571,7 +571,7 @@ [context file] (if (:has-deleted-components context) (let [split-components - (fn [content] (->> (cip/node-seq content) + (fn [content] (->> (parser/node-seq content) (filter #(= :symbol (:tag %)))))] (->> (get-file context :deleted-components) @@ -645,7 +645,7 @@ (rx/filter (fn [data] (= "application/zip" (:type data)))) (rx/merge-map #(zip/loadAsync (:body %))) (rx/merge-map #(get-file {:zip %} :manifest)) - (rx/map (comp d/kebab-keys cip/string->uuid)) + (rx/map (comp d/kebab-keys parser/string->uuid)) (rx/map #(hash-map :uri (:uri file) :data % :type "application/zip"))) (->> st (rx/filter (fn [data] (= "application/octet-stream" (:type data)))) diff --git a/frontend/src/app/util/import/parser.cljs b/frontend/src/app/worker/import/parser.cljs similarity index 99% rename from frontend/src/app/util/import/parser.cljs rename to frontend/src/app/worker/import/parser.cljs index 28271502bb..90ba834afa 100644 --- a/frontend/src/app/util/import/parser.cljs +++ b/frontend/src/app/worker/import/parser.cljs @@ -4,7 +4,7 @@ ;; ;; Copyright (c) KALEIDOS INC -(ns app.util.import.parser +(ns app.worker.import.parser (:require [app.common.colors :as cc] [app.common.data :as d] From eeaee5ad425503d62fef3ea1f285ccea413da3ef Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 17:51:33 +0100 Subject: [PATCH 24/25] :zap: Add minor optimizations to tab-container react component --- .../app/main/ui/components/tab_container.cljs | 67 +++++++++---------- .../app/main/ui/workspace/colorpicker.cljs | 2 +- .../src/app/main/ui/workspace/libraries.cljs | 2 +- .../src/app/main/ui/workspace/sidebar.cljs | 5 +- .../main/ui/workspace/sidebar/options.cljs | 4 +- .../app/main/ui/workspace/viewport/hooks.cljs | 1 + frontend/src/app/util/array.cljs | 10 +++ 7 files changed, 48 insertions(+), 43 deletions(-) diff --git a/frontend/src/app/main/ui/components/tab_container.cljs b/frontend/src/app/main/ui/components/tab_container.cljs index 3f1aac1cd0..9373027413 100644 --- a/frontend/src/app/main/ui/components/tab_container.cljs +++ b/frontend/src/app/main/ui/components/tab_container.cljs @@ -10,6 +10,7 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.main.ui.icons :as i] + [app.util.array :as array] [app.util.dom :as dom] [app.util.i18n :refer [tr]] [cuerdas.core :as str] @@ -17,41 +18,32 @@ (mf/defc tab-element {::mf/wrap-props false} - [props] - (let [children (unchecked-get props "children")] - [:div {:class (stl/css :tab-element)} - children])) + [{:keys [children]}] + [:div {:class (stl/css :tab-element)} children]) (mf/defc tab-container {::mf/wrap-props false} - [props] - (let [children (->> - (unchecked-get props "children") - (filter some?)) - selected (unchecked-get props "selected") - on-change (unchecked-get props "on-change-tab") - collapsable? (unchecked-get props "collapsable?") - handle-collapse (unchecked-get props "handle-collapse") - class (unchecked-get props "class") - content-class (unchecked-get props "content-class") + [{:keys [children selected on-change-tab collapsable handle-collapse header-class content-class]}] + (let [children (-> (array/normalize-to-array children) + (array/without-nils)) - state (mf/use-state #(or selected (-> children first .-props .-id))) - selected (or selected @state) + selected* (mf/use-state #(or selected (-> children first .-props .-id))) + selected (or selected @selected*) - select-fn - (mf/use-fn - (mf/deps on-change) - (fn [event] - (let [id (-> event - (dom/get-current-target) - (dom/get-data "id") - (keyword))] - (reset! state id) - (when (fn? on-change) (on-change id)))))] + on-click (mf/use-fn + (mf/deps on-change-tab) + (fn [event] + (let [id (-> event + (dom/get-current-target) + (dom/get-data "id") + (keyword))] + (reset! selected* id) + (when (fn? on-change-tab) + (on-change-tab id)))))] [:div {:class (stl/css :tab-container)} - [:div {:class (dm/str class " " (stl/css :tab-container-tabs))} - (when collapsable? + [:div {:class (dm/str header-class " " (stl/css :tab-container-tabs))} + (when ^boolean collapsable [:button {:on-click handle-collapse :class (stl/css :collapse-sidebar) @@ -61,13 +53,16 @@ (for [tab children] (let [props (.-props tab) id (.-id props) - title (.-title props)] - [:div - {:key (str/concat "tab-" (d/name id)) - :data-id (d/name id) - :on-click select-fn - :class (stl/css-case :tab-container-tab-title true - :current (= selected id))} + title (.-title props) + sid (d/name id)] + [:div {:key (str/concat "tab-" sid) + :data-id sid + :on-click on-click + :class (stl/css-case + :tab-container-tab-title true + :current (= selected id))} title]))]] + [:div {:class (dm/str content-class " " (stl/css :tab-container-content))} - (d/seek #(= selected (-> % .-props .-id)) children)]])) + (d/seek #(= selected (-> % .-props .-id)) + children)]])) diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index eaf1660371..82ccaa7012 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -311,7 +311,7 @@ [:& tab-container {:on-change-tab set-tab! :selected @active-color-tab - :collapsable? false} + :collapsable false} [:& tab-element {:id :ramp :title i/rgba-refactor} (if picking-color? diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index 67dc5df167..3829f7ca39 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -502,7 +502,7 @@ [:& tab-container {:on-change-tab on-tab-change :selected selected-tab - :collapsable? false} + :collapsable false} [:& tab-element {:id :libraries :title (tr "workspace.libraries.libraries")} [:div {:class (stl/css :libraries-content)} [:& libraries-tab {:file-id file-id diff --git a/frontend/src/app/main/ui/workspace/sidebar.cljs b/frontend/src/app/main/ui/workspace/sidebar.cljs index faa27b292d..b38c1cd444 100644 --- a/frontend/src/app/main/ui/workspace/sidebar.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar.cljs @@ -83,10 +83,9 @@ [:& tab-container {:on-change-tab on-tab-change :selected section - :shortcuts? shortcuts? - :collapsable? true + :collapsable true :handle-collapse handle-collapse - :class (stl/css :tab-spacing)} + :header-class (stl/css :tab-spacing)} [:& tab-element {:id :layers :title (tr "workspace.sidebar.layers")} [:div {:class (stl/css :layers-tab) :style #js {"--height" (str size-pages "px")}} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index 763adb7fbb..ce83d7fa9b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -103,9 +103,9 @@ [:& tab-container {:on-change-tab on-change-tab :selected section - :collapsable? false + :collapsable false :content-class (stl/css :content-class) - :class (stl/css :tab-spacing)} + :header-class (stl/css :tab-spacing)} [:& tab-element {:id :design :title (tr "workspace.options.design")} [:div {:class (stl/css :element-options)} diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs index f995848ec6..01d95a9be8 100644 --- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs @@ -299,6 +299,7 @@ (not (cfh/is-direct-child-of-root? shape)) (empty? (get shape :fills))))) + hover-shape (->> ids (remove remove-id?) diff --git a/frontend/src/app/util/array.cljs b/frontend/src/app/util/array.cljs index 875a4ba32d..c04dddb204 100644 --- a/frontend/src/app/util/array.cljs +++ b/frontend/src/app/util/array.cljs @@ -34,3 +34,13 @@ (.push ^js a v1 v2 v3 v4 v5 v6) a)) +(defn normalize-to-array + "If `o` is an array, returns it as-is, if not, wrap into an array." + [o] + (if (array? o) + o + #js [o])) + +(defn without-nils + [^js/Array o] + (.filter o (fn [v] (some? v)))) From a179f73deb320dee3568c069d558dff9a62e3b06 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 8 Jan 2024 18:05:35 +0100 Subject: [PATCH 25/25] :zap: Add minor performance improvements to asset-section react component --- .../ui/workspace/sidebar/assets/common.cljs | 60 ++++++++++++------- frontend/src/app/util/array.cljs | 7 ++- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs index d421f90a92..7b4194a7f8 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs @@ -26,6 +26,7 @@ [app.main.ui.components.title-bar :refer [title-bar]] [app.main.ui.context :as ctx] [app.main.ui.icons :as i] + [app.util.array :as array] [app.util.dom :as dom] [app.util.dom.dnd :as dnd] [app.util.i18n :as i18n :refer [tr]] @@ -120,7 +121,8 @@ :workspace? true}]) (mf/defc section-icon - [{:keys [section] :as props}] + {::mf/wrap-props false} + [{:keys [section]}] (case section :colors i/drop-refactor :components i/component-refactor @@ -130,28 +132,42 @@ (mf/defc asset-section {::mf/wrap-props false} [{:keys [children file-id title section assets-count open?]}] - (let [children (->> (if (array? children) children [children]) - (filter some?)) - get-role #(.. % -props -role) - title-buttons (filter #(= (get-role %) :title-button) children) - content (filter #(= (get-role %) :content) children)] - [:div {:class (stl/css :asset-section)} - [:& title-bar {:collapsable true - :collapsed (not open?) - :all-clickable true - :on-collapsed #(st/emit! (dw/set-assets-section-open file-id section (not open?))) - :class (stl/css :title-spacing) - :title (mf/html [:span {:class (stl/css :title-name)} - [:span {:class (stl/css :section-icon)} - [:& section-icon {:section section}]] - [:span {:class (stl/css :section-name)} - title] + (let [children (-> (array/normalize-to-array children) + (array/without-nils)) - [:span {:class (stl/css :num-assets)} - assets-count]])} - title-buttons] - (when ^boolean open? - content)])) + is-button? #(= :title-button (.. % -props -role)) + is-content? #(= :content (.. % -props -role)) + + buttons (array/filter is-button? children) + content (array/filter is-content? children) + + on-collapsed + (mf/use-fn + (mf/deps file-id section open?) + (fn [_] + (st/emit! (dw/set-assets-section-open file-id section (not open?))))) + + title + (mf/html + [:span {:class (stl/css :title-name)} + [:span {:class (stl/css :section-icon)} + [:& section-icon {:section section}]] + [:span {:class (stl/css :section-name)} + title] + + [:span {:class (stl/css :num-assets)} + assets-count]])] + + [:div {:class (stl/css :asset-section)} + [:& title-bar + {:collapsable true + :collapsed (not open?) + :all-clickable true + :on-collapsed on-collapsed + :class (stl/css :title-spacing) + :title title} + buttons] + (when ^boolean open? content)])) (mf/defc asset-section-block {::mf/wrap-props false} diff --git a/frontend/src/app/util/array.cljs b/frontend/src/app/util/array.cljs index c04dddb204..012b62c0ae 100644 --- a/frontend/src/app/util/array.cljs +++ b/frontend/src/app/util/array.cljs @@ -6,7 +6,7 @@ (ns app.util.array "A collection of helpers for work with javascript arrays." - (:refer-clojure :exclude [conj! conj])) + (:refer-clojure :exclude [conj! conj filter])) (defn conj "A conj like function for js arrays." @@ -44,3 +44,8 @@ (defn without-nils [^js/Array o] (.filter o (fn [v] (some? v)))) + +(defn filter + "A specific filter for js arrays." + [pred ^js/Array o] + (.filter o pred))