diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index 61586ed52e..f6b6c615da 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -357,7 +357,9 @@ f.is_shared, ft.media_id from file as f - left join file_thumbnail as ft on (ft.file_id = f.id and ft.revn = f.revn) + left join file_thumbnail as ft on (ft.file_id = f.id + and ft.revn = f.revn + and ft.deleted_at is null) where f.project_id = ? and f.deleted_at is null order by f.modified_at desc") @@ -660,7 +662,9 @@ row_number() over w as row_num from file as f inner join project as p on (p.id = f.project_id) - left join file_thumbnail as ft on (ft.file_id = f.id and ft.revn = f.revn) + left join file_thumbnail as ft on (ft.file_id = f.id + and ft.revn = f.revn + and ft.deleted_at is null) where p.team_id = ? and p.deleted_at is null and f.deleted_at is null diff --git a/common/src/app/common/files/defaults.cljc b/common/src/app/common/files/defaults.cljc index 862330dad0..12e18921eb 100644 --- a/common/src/app/common/files/defaults.cljc +++ b/common/src/app/common/files/defaults.cljc @@ -6,4 +6,4 @@ (ns app.common.files.defaults) -(def version 37) +(def version 38) diff --git a/common/src/app/common/files/migrations.cljc b/common/src/app/common/files/migrations.cljc index 86145dc97f..c5952d5718 100644 --- a/common/src/app/common/files/migrations.cljc +++ b/common/src/app/common/files/migrations.cljc @@ -671,3 +671,31 @@ (defmethod migrate 37 [data] (d/without-nils data)) + +(defmethod migrate 38 + [data] + (letfn [(fix-gradient [{:keys [type] :as gradient}] + (if (string? type) + (assoc gradient :type (keyword type)) + gradient)) + + (update-fill [fill] + (d/update-when fill :fill-color-gradient fix-gradient)) + + (update-object [object] + (d/update-when object :fills #(mapv update-fill %))) + + (update-shape [shape] + (let [shape (update-object shape)] + (if (cfh/text-shape? shape) + (-> shape + (update :content (partial txt/transform-nodes identity update-fill)) + (d/update-when :position-data #(mapv update-object %))) + shape))) + + (update-container [container] + (update container :objects update-vals update-shape))] + + (-> data + (update :pages-index update-vals update-container) + (update :components update-vals update-container)))) diff --git a/common/src/app/common/geom/shapes/bool.cljc b/common/src/app/common/geom/shapes/bool.cljc index a1eeb1581c..48116a88db 100644 --- a/common/src/app/common/geom/shapes/bool.cljc +++ b/common/src/app/common/geom/shapes/bool.cljc @@ -7,6 +7,7 @@ (ns app.common.geom.shapes.bool (:require [app.common.data :as d] + [app.common.files.helpers :as cpf] [app.common.svg.path.bool :as pb] [app.common.svg.path.shapes-to-path :as stp])) @@ -16,6 +17,7 @@ (let [extract-content-xf (comp (map (d/getf objects)) (filter (comp not :hidden)) + (remove cpf/svg-raw-shape?) (map #(stp/convert-to-path % objects)) (map :content)) diff --git a/common/src/app/common/types/color.cljc b/common/src/app/common/types/color.cljc index 00823c631d..8049628941 100644 --- a/common/src/app/common/types/color.cljc +++ b/common/src/app/common/types/color.cljc @@ -56,7 +56,7 @@ (sm/define! ::gradient [:map {:title "Gradient"} - [:type [::sm/one-of #{:linear :radial "linear" "radial"}]] + [:type [::sm/one-of #{:linear :radial}]] [:start-x ::sm/safe-number] [:start-y ::sm/safe-number] [:end-x ::sm/safe-number] diff --git a/common/src/app/common/types/container.cljc b/common/src/app/common/types/container.cljc index 3d5cb31c43..f70705230b 100644 --- a/common/src/app/common/types/container.cljc +++ b/common/src/app/common/types/container.cljc @@ -301,6 +301,9 @@ (gpt/add orig-pos delta) {:skip-components? true :bottom-frames? true})) + frame (get-shape container frame-id) + component-frame (get-component-shape (:objects container) frame {:allow-main? true}) + ids-map (volatile! {}) update-new-shape @@ -339,7 +342,8 @@ :component-root true :name new-name) - (some? (:parent-id original-shape)) ;; On v2 we have removed the parent-id for component roots (see above) + (or (some? (:parent-id original-shape)) ; On v2 we have removed the parent-id for component roots (see above) + (some? component-frame)) (dissoc :component-root)))) [new-shape new-shapes _] diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index fb6df40679..28289219d4 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -375,8 +375,8 @@ {:frame-id uuid/zero :fills [{:fill-color clr/white :fill-opacity 1}] - :name "Board" :strokes [] + :name "Board" :shapes [] :hide-fill-on-export false}) @@ -390,11 +390,15 @@ (def ^:private minimal-group-attrs {:type :group :name "Group" + :fills [] + :strokes [] :shapes []}) (def ^:private minimal-bool-attrs {:type :bool :name "Bool" + :fills [] + :strokes [] :shapes []}) (def ^:private minimal-text-attrs diff --git a/frontend/resources/styles/common/refactor/basic-rules.scss b/frontend/resources/styles/common/refactor/basic-rules.scss index b4a5f2481c..0b120e9e5a 100644 --- a/frontend/resources/styles/common/refactor/basic-rules.scss +++ b/frontend/resources/styles/common/refactor/basic-rules.scss @@ -769,10 +769,6 @@ @include titleTipography; color: var(--color-foreground-primary); text-align: left; - display: grid; - grid-template-columns: 1fr 22px; - grid-template-areas: "name button"; - width: 100%; margin: 0; padding: 0; height: fit-content; diff --git a/frontend/resources/styles/common/refactor/mixins.scss b/frontend/resources/styles/common/refactor/mixins.scss index c2f2ce7561..856d6ae033 100644 --- a/frontend/resources/styles/common/refactor/mixins.scss +++ b/frontend/resources/styles/common/refactor/mixins.scss @@ -97,8 +97,7 @@ color: var(--menu-foreground-color); } -@mixin copyWrapper { - @include flexColumn; +@mixin copyWrapperBase { position: relative; min-height: $s-32; width: $s-156; diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 6cba4a35e5..ee5cf792d9 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -944,7 +944,7 @@ (let [shape (get objects id) parent (get objects parent-id) component-shape (ctn/get-component-shape objects shape) - component-shape-parent (ctn/get-component-shape objects parent) + component-shape-parent (ctn/get-component-shape objects parent {:allow-main? true}) root-parent (ctn/get-instance-root objects parent) detach? (and (ctk/in-component-copy-not-head? shape) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 292265dd95..0548f137f2 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -827,7 +827,7 @@ 0))))) (defn- add-component-for-swap - [shape file-id id-new-component target-cell] + [shape file-id id-new-component index target-cell] (dm/assert! (uuid? id-new-component)) (dm/assert! (uuid? file-id)) (ptk/reify ::add-component-for-swap @@ -837,7 +837,6 @@ libraries (wsh/get-libraries state) objects (:objects page) - index (find-shape-index objects (:parent-id shape) (:id shape)) position (gpt/point (:x shape) (:y shape)) changes (-> (pcb/empty-changes it (:id page)) (pcb/with-objects objects)) @@ -877,9 +876,11 @@ ;; 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)))] + (ctl/get-cell-by-shape-id parent (:id shape))) + + index (find-shape-index objects (:parent-id shape) (: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) + (add-component-for-swap shape file-id id-new-component index target-cell) (ptk/data-event :layout/update [(:parent-id shape)])))))) (defn component-multi-swap diff --git a/frontend/src/app/main/snap.cljs b/frontend/src/app/main/snap.cljs index 3cd6b7dc6c..5b164429db 100644 --- a/frontend/src/app/main/snap.cljs +++ b/frontend/src/app/main/snap.cljs @@ -210,8 +210,9 @@ (defn search-snap-distance [selrect coord shapes-lt shapes-gt zoom] (->> (rx/combine-latest shapes-lt shapes-gt) - (rx/map (fn [[shapes-lt shapes-gt]] - (calculate-snap coord selrect shapes-lt shapes-gt zoom))))) + (rx/map + (fn [[shapes-lt shapes-gt]] + (calculate-snap coord selrect shapes-lt shapes-gt zoom))))) (defn select-shapes-area [page-id frame-id selected objects area] @@ -233,12 +234,12 @@ (rx/merge-map (fn [[frame selrect]] (let [vbox (deref refs/vbox) + frame-id (->> shapes first :frame-id) + frame-sr (when-not (cfh/root? frame) (dm/get-prop frame :selrect)) + bounds (d/nilv (grc/clip-rect frame-sr vbox) vbox) selected (into #{} (map :id shapes)) - areas (->> (gsh/get-areas - (or (grc/clip-rect (dm/get-prop frame :selrect) vbox) - vbox) - selrect) + areas (->> (gsh/get-areas bounds selrect) (d/mapm #(select-shapes-area page-id frame-id selected objects %2))) snap-x (search-snap-distance selrect :x (:left areas) (:right areas) zoom) snap-y (search-snap-distance selrect :y (:top areas) (:bottom areas) zoom)] diff --git a/frontend/src/app/main/ui/auth/common.scss b/frontend/src/app/main/ui/auth/common.scss index 0bec2bf2d7..9483f9ba5d 100644 --- a/frontend/src/app/main/ui/auth/common.scss +++ b/frontend/src/app/main/ui/auth/common.scss @@ -73,6 +73,9 @@ text-transform: uppercase; font-size: $fs-11; } + &.register a { + @extend .button-primary; + } } .forgot-password { diff --git a/frontend/src/app/main/ui/auth/login.cljs b/frontend/src/app/main/ui/auth/login.cljs index 9a710d9a83..bd5804b248 100644 --- a/frontend/src/app/main/ui/auth/login.cljs +++ b/frontend/src/app/main/ui/auth/login.cljs @@ -275,10 +275,6 @@ (mf/use-fn #(st/emit! (rt/nav :auth-register {} params))) - on-pass-recovery - (mf/use-fn - #(st/emit! (rt/nav :auth-recovery-request))) - on-create-demo-profile (mf/use-fn #(st/emit! (du/create-demo-profile)))] @@ -292,13 +288,6 @@ [:& login-methods {:params params}] [:div {:class (stl/css :links)} - (when (or (contains? cf/flags :login) - (contains? cf/flags :login-with-password)) - [:div {:class (stl/css :link-entry :register)} - [:& lk/link {:action on-pass-recovery - :data-test "forgot-password"} - (tr "auth.forgot-password")]]) - (when (contains? cf/flags :registration) [:div {:class (stl/css :link-entry :register)} [:span (tr "auth.register") " "] diff --git a/frontend/src/app/main/ui/components/copy_button.cljs b/frontend/src/app/main/ui/components/copy_button.cljs index b0e09e246c..909b42abc2 100644 --- a/frontend/src/app/main/ui/components/copy_button.cljs +++ b/frontend/src/app/main/ui/components/copy_button.cljs @@ -25,7 +25,7 @@ (let [sub (timers/schedule 1000 #(reset! just-copied false))] ;; On unmount we dispose the timer #(rx/-dispose sub))))) - [:button {:class (dm/str class " " (stl/css-case :copy-button true + [:button {:class (dm/str class " " (stl/css-case :copy-button (not (some? children)) :copy-wrapper (some? children))) :on-click #(when-not @just-copied (reset! just-copied true) diff --git a/frontend/src/app/main/ui/components/copy_button.scss b/frontend/src/app/main/ui/components/copy_button.scss index f13f914872..1e07f6455c 100644 --- a/frontend/src/app/main/ui/components/copy_button.scss +++ b/frontend/src/app/main/ui/components/copy_button.scss @@ -10,7 +10,7 @@ @include buttonStyle; @include flexCenter; height: $s-32; - width: $s-28; + width: $s-32; border: $s-1 solid transparent; border-radius: $br-8; background-color: transparent; @@ -46,32 +46,50 @@ stroke: var(--button-tertiary-foreground-color-active); } } +} - &.copy-wrapper { - @include copyWrapper; - height: fit-content; - text-align: left; - .icon-btn { - position: absolute; - display: flex; - justify-content: center; - align-items: center; - top: 0; - right: 0; - height: 32px; - width: 28px; - svg { - @extend .button-icon-small; - display: none; - } +.copy-wrapper { + @include buttonStyle; + @include copyWrapperBase; + display: grid; + grid-template-columns: 1fr $s-24; + grid-template-areas: "name button"; + width: 100%; + height: fit-content; + text-align: left; + .icon-btn { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + top: 0; + right: 0; + height: $s-32; + width: $s-32; + svg { + @extend .button-icon-small; + display: none; } - &:hover { - .icon-btn { - svg { - display: flex; - stroke: var(--button-tertiary-foreground-color-active); - } + } + &:hover { + .icon-btn { + svg { + display: flex; + stroke: var(--button-tertiary-foreground-color-active); } } } + + &:hover { + background-color: var(--color-background-tertiary); + color: var(--color-foreground-primary); + border: $s-1 solid var(--color-background-tertiary); + } + &:focus, + &:focus-visible { + outline: none; + border: $s-1 solid var(--button-tertiary-border-color-focus); + background-color: transparent; + color: var(--button-tertiary-foreground-color-focus); + } } diff --git a/frontend/src/app/main/ui/components/forms.cljs b/frontend/src/app/main/ui/components/forms.cljs index 267cf66be0..c37ca4b52c 100644 --- a/frontend/src/app/main/ui/components/forms.cljs +++ b/frontend/src/app/main/ui/components/forms.cljs @@ -87,7 +87,7 @@ (swap! form assoc-in [:touched input-name] true))) props (-> props - (dissoc :help-icon :form :trim :children :show-success?) + (dissoc :help-icon :form :trim :children :show-success? :auto-focus?) (assoc :id (name input-name) :value value :auto-focus auto-focus? diff --git a/frontend/src/app/main/ui/components/forms.scss b/frontend/src/app/main/ui/components/forms.scss index ec64c521c8..b9d2c104a0 100644 --- a/frontend/src/app/main/ui/components/forms.scss +++ b/frontend/src/app/main/ui/components/forms.scss @@ -362,6 +362,7 @@ min-height: $s-32; border-radius: $br-8; padding: $s-0 $s-2; + color: var(--input-foreground-color); &:focus, &:focus-within { outline: none; diff --git a/frontend/src/app/main/ui/dashboard/grid.cljs b/frontend/src/app/main/ui/dashboard/grid.cljs index b71bc1eb0c..4badcf1172 100644 --- a/frontend/src/app/main/ui/dashboard/grid.cljs +++ b/frontend/src/app/main/ui/dashboard/grid.cljs @@ -359,7 +359,7 @@ :background-color (dm/get-in file [:data :options :background])}]) (when (and (:is-shared file) (not library-view?)) - [:div {:class (stl/css :item-badge)} i/library]) + [:div {:class (stl/css :item-badge)} i/library-refactor]) [:div {:class (stl/css :info-wrapper)} [:div {:class (stl/css :item-info)} diff --git a/frontend/src/app/main/ui/dashboard/grid.scss b/frontend/src/app/main/ui/dashboard/grid.scss index 818b7fdce6..b8521d9c24 100644 --- a/frontend/src/app/main/ui/dashboard/grid.scss +++ b/frontend/src/app/main/ui/dashboard/grid.scss @@ -144,7 +144,8 @@ $thumbnail-default-height: $s-168; // Default width justify-content: center; svg { - fill: $db-secondary; + stroke: $db-secondary; + fill: none; height: $s-16; width: $s-16; } diff --git a/frontend/src/app/main/ui/dashboard/projects.scss b/frontend/src/app/main/ui/dashboard/projects.scss index 8dcf8e9406..15941852b5 100644 --- a/frontend/src/app/main/ui/dashboard/projects.scss +++ b/frontend/src/app/main/ui/dashboard/projects.scss @@ -203,7 +203,6 @@ display: flex; flex-direction: column; align-items: flex-start; - flex-grow: 1; padding: $s-20 $s-20; } @@ -222,7 +221,7 @@ a { color: $da-primary; } - padding-top: $s-8; + padding: $s-8 0; } .close { position: absolute; @@ -249,8 +248,11 @@ height: $s-200; overflow: hidden; border-radius: $br-4; + @media (max-width: 1200px) { + display: none; + width: 0; + } } - img { border-radius: $br-4; height: $s-200; diff --git a/frontend/src/app/main/ui/dashboard/team_form.cljs b/frontend/src/app/main/ui/dashboard/team_form.cljs index 258459beea..81db878651 100644 --- a/frontend/src/app/main/ui/dashboard/team_form.cljs +++ b/frontend/src/app/main/ui/dashboard/team_form.cljs @@ -14,7 +14,9 @@ [app.main.store :as st] [app.main.ui.components.forms :as fm] [app.main.ui.icons :as i] + [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] + [app.util.keyboard :as kbd] [app.util.router :as rt] [beicon.v2.core :as rx] [cljs.spec.alpha :as s] @@ -74,6 +76,15 @@ :validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space")) (fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))] :initial initial) + handle-keydown + (mf/use-callback + (mf/deps) + (fn [e] + (when (kbd/enter? e) + (dom/prevent-default e) + (dom/stop-propagation e) + (on-submit form e)))) + on-close #(st/emit! (modal/hide))] [:div {:class (stl/css :modal-overlay)} @@ -97,7 +108,8 @@ :form form :name :name :placeholder "E.g. Design" - :label (tr "labels.create-team.placeholder")}]] + :label (tr "labels.create-team.placeholder") + :on-key-down handle-keydown}]] [:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :action-buttons)} diff --git a/frontend/src/app/main/ui/export.scss b/frontend/src/app/main/ui/export.scss index 144036d9d6..b8fa5c55e0 100644 --- a/frontend/src/app/main/ui/export.scss +++ b/frontend/src/app/main/ui/export.scss @@ -126,7 +126,7 @@ } .selection-title { @include titleTipography; - color: $df-primary; + color: var(--modal-text-foreground-color); } } .selection-wrapper { diff --git a/frontend/src/app/main/ui/onboarding.scss b/frontend/src/app/main/ui/onboarding.scss index 0ff0507a79..b820261663 100644 --- a/frontend/src/app/main/ui/onboarding.scss +++ b/frontend/src/app/main/ui/onboarding.scss @@ -64,6 +64,7 @@ .modal-text { @include titleTipography; + color: var(--modal-text-foreground-color); } .property-block { diff --git a/frontend/src/app/main/ui/onboarding/questions.cljs b/frontend/src/app/main/ui/onboarding/questions.cljs index fd3fcca94c..d324b16992 100644 --- a/frontend/src/app/main/ui/onboarding/questions.cljs +++ b/frontend/src/app/main/ui/onboarding/questions.cljs @@ -114,6 +114,13 @@ (s/keys :req-un [::experience-design-tool] :opt-un [::experience-design-tool-other])) +(defn- step-1-form-validator + [errors data] + (let [planning (-> (:planning data) (str/trim))] + (cond-> errors + (= planning "") + (assoc :planning {:code "missing"})))) + (defn- step-3-form-validator [errors data] (let [experience-design-tool (:experience-design-tool data) @@ -209,6 +216,7 @@ ;; and we want to keep the filled info step-1-form (fm/use-form :initial {} + :validators [step-1-form-validator] :spec ::questions-form-step-1) step-2-form (fm/use-form :initial {} diff --git a/frontend/src/app/main/ui/viewer.scss b/frontend/src/app/main/ui/viewer.scss index 351d4414de..94f54ae5f6 100644 --- a/frontend/src/app/main/ui/viewer.scss +++ b/frontend/src/app/main/ui/viewer.scss @@ -15,6 +15,7 @@ } .viewer-content { + overflow: hidden; grid-row: 2 / span 1; display: grid; grid-template-rows: $s-252 auto; diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/common.scss b/frontend/src/app/main/ui/viewer/inspect/attributes/common.scss index b955417321..bb33fa99c4 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/common.scss +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/common.scss @@ -89,12 +89,13 @@ .color-info, .color-row-copy-btn { - @include copyWrapper; + display: flex; + max-width: $s-144; } .first-row { display: grid; - grid-template-columns: 1fr $s-20; + grid-template-columns: 1fr $s-24; grid-template-areas: "name button"; height: fit-content; width: 100%; 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 66db41c7df..f3f817397f 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/text.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/text.cljs @@ -80,7 +80,8 @@ [:div {:class (stl/css :global/attr-label)} (tr "inspect.attributes.typography")] [:div {:class (stl/css :global/attr-value)} - [:& copy-button {:data (copy-style-data typography :font-family :font-weight :font-style)} + [:& copy-button {:data (copy-style-data typography :font-family :font-weight :font-style) + :class (stl/css :copy-btn-wrapper)} [:div {:class (stl/css :button-children)} (:name typography)]]]]) (when (:font-id style) diff --git a/frontend/src/app/main/ui/viewer/inspect/exports.cljs b/frontend/src/app/main/ui/viewer/inspect/exports.cljs index b9847866d3..a300bcc859 100644 --- a/frontend/src/app/main/ui/viewer/inspect/exports.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/exports.cljs @@ -120,10 +120,10 @@ {:value "1.5" :label "1.5x"} {:value "2" :label "2x"} {:value "4" :label "4x"} - {:value "6" :label "6"}] + {:value "6" :label "6x"}] format-options [{:value "png" :label "PNG"} - {:value "jpeg" :label "JPE"} + {:value "jpeg" :label "JPEG"} {:value "svg" :label "SVG"} {:value "pdf" :label "PDF"}]] diff --git a/frontend/src/app/main/ui/viewer/inspect/exports.scss b/frontend/src/app/main/ui/viewer/inspect/exports.scss index 9d96c8339f..28ad83a354 100644 --- a/frontend/src/app/main/ui/viewer/inspect/exports.scss +++ b/frontend/src/app/main/ui/viewer/inspect/exports.scss @@ -46,43 +46,50 @@ @include flexRow; } -.action-btn { - @extend .button-tertiary; - height: $s-32; - width: $s-28; - svg { - @extend .button-icon; +.element-group { + display: grid; + grid-template-columns: repeat(8, 1fr); + column-gap: $s-4; + .action-btn { + @extend .button-tertiary; + height: $s-32; + width: $s-28; + svg { + @extend .button-icon; + } } } -.element-group { - @include flexRow; -} - .input-wrapper { - @include flexRow; + grid-column: span 7; + display: grid; + grid-template-columns: subgrid; } .format-select { - width: $s-60; + grid-column: span 2; padding: 0; -} -.dropdown-upwards { - bottom: $s-36; - width: $s-80; - top: unset; + .dropdown-upwards { + bottom: $s-36; + width: $s-80; + top: unset; + } } .size-select { - width: $s-60; + grid-column: span 2; padding: 0; + .dropdown-upwards { + bottom: $s-36; + top: unset; + width: $s-80; + } } .suffix-input { @extend .input-element; - min-width: $s-92; - flex-grow: 1; + grid-column: span 3; } .export-btn { diff --git a/frontend/src/app/main/ui/viewer/share_link.scss b/frontend/src/app/main/ui/viewer/share_link.scss index 259fe954ba..7219154c81 100644 --- a/frontend/src/app/main/ui/viewer/share_link.scss +++ b/frontend/src/app/main/ui/viewer/share_link.scss @@ -14,6 +14,7 @@ left: calc(100vw - $s-512); z-index: $z-index-modal; } + .share-link-dialog { @extend .modal-container-base; min-height: unset; @@ -86,6 +87,7 @@ .description { @include titleTipography; + color: var(--modal-text-foreground-color); margin-bottom: $s-24; } @@ -141,7 +143,7 @@ } .view-mode { - max-height: $s-248; + max-height: $s-216; overflow: hidden auto; scrollbar-gutter: stable; } diff --git a/frontend/src/app/main/ui/workspace/left_header.cljs b/frontend/src/app/main/ui/workspace/left_header.cljs index cdd6864ad1..25c47f99f8 100644 --- a/frontend/src/app/main/ui/workspace/left_header.cljs +++ b/frontend/src/app/main/ui/workspace/left_header.cljs @@ -341,8 +341,8 @@ :id "file-menu-text-palette"} [:span {:class (stl/css :item-name)} (if (contains? layout :textpalette) - (tr "workspace.header.menu.hide-palette") - (tr "workspace.header.menu.show-palette"))] + (tr "workspace.header.menu.hide-textpalette") + (tr "workspace.header.menu.show-textpalette"))] [:span {:class (stl/css :shortcut)} (for [sc (scd/split-sc (sc/get-tooltip :toggle-textpalette))] [:span {:class (stl/css :shortcut-key) :key sc} sc])]]]) diff --git a/frontend/src/app/main/ui/workspace/sidebar/history.scss b/frontend/src/app/main/ui/workspace/sidebar/history.scss index 5cebfbcb0d..312967c78a 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/history.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/history.scss @@ -64,7 +64,7 @@ } .history-entries { - height: 100%; + height: calc(100vh - $s-100); padding: $s-12; overflow-x: hidden; overflow-y: auto; diff --git a/frontend/src/app/main/ui/workspace/sidebar/layers.scss b/frontend/src/app/main/ui/workspace/sidebar/layers.scss index 1e4f17f714..71289de1a0 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/layers.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/layers.scss @@ -100,7 +100,7 @@ padding: 0; } -.back-button-icon { +.back-button { @include flexCenter; height: $s-32; width: $s-24; 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 7c4f6d2649..9a02869c3a 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 @@ -162,10 +162,10 @@ {:value "1.5" :label "1.5x"} {:value "2" :label "2x"} {:value "4" :label "4x"} - {:value "6" :label "6"}] + {:value "6" :label "6x"}] format-options [{:value "png" :label "PNG"} - {:value "jpeg" :label "JPE"} + {:value "jpeg" :label "JPEG"} {:value "svg" :label "SVG"} {:value "pdf" :label "PDF"}]] 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 3f0b3d8cb5..c88dbc51b7 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 @@ -611,7 +611,7 @@ :options animation-opts :on-change change-animation-type}]]] - ;; Direction + ;; Direction (when (ctsi/has-way? interaction) [:div {:class (stl/css :property-row)} [:div {:class (stl/css :inputs-wrapper)} @@ -624,7 +624,7 @@ [:& radio-button {:id "animation-way-out" :value "out"}]]]]) - ;; Direction + ;; Direction (when (ctsi/has-direction? interaction) [:div {:class (stl/css :property-row)} [:div {:class (stl/css :buttons-wrapper)} @@ -648,7 +648,7 @@ :id "animation-up" :value "up"}]]]]) - ;; Duration + ;; Duration (when (ctsi/has-duration? interaction) [:div {:class (stl/css :property-row)} [:span {:class (stl/css :interaction-name)} (tr "workspace.options.interaction-duration")] @@ -661,7 +661,7 @@ :value (-> interaction :animation :duration) :title (tr "workspace.options.interaction-ms")}]]]) - ;; Easing + ;; Easing (when (ctsi/has-easing? interaction) [:div {:class (stl/css :property-row)} [:span {:class (stl/css :interaction-name)} (tr "workspace.options.interaction-easing")] @@ -672,7 +672,7 @@ :options easing-options :on-change change-easing}]]]) - ;; Offset effect + ;; Offset effect (when (ctsi/has-offset-effect? interaction) [:div {:class (stl/css :property-row)} [:div {:class (stl/css :checkbox-option)} 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 d6332d87ca..dff6d0888e 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 @@ -913,9 +913,10 @@ [:button {:class (stl/css :layout-option) :on-click set-flex} "Flex layout"] [:button {:class (stl/css :layout-option) :on-click set-grid} "Grid layout"]]]]) - [:button {:class (stl/css :remove-layout) - :on-click on-remove-layout} - i/remove-refactor]] + (when has-layout? + [:button {:class (stl/css :remove-layout) + :on-click on-remove-layout} + i/remove-refactor])] [:div {:class (stl/css :title-actions)} (if ^boolean grid-enabled? @@ -933,9 +934,10 @@ :data-value "flex" :on-click on-set-layout} i/add-refactor]) - [:button {:class (stl/css :remove-layout) - :on-click on-remove-layout} - i/remove-refactor]])]] + (when has-layout? + [:button {:class (stl/css :remove-layout) + :on-click on-remove-layout} + i/remove-refactor])])]] (when (and open? has-layout?) (when (not= :multiple layout-type) 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 6edb371760..48ca30a7c6 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 @@ -407,7 +407,7 @@ [:div {:class (stl/css :row)} [:& align-self-row {:is-col? is-col? :align-self align-self - :on-changer set-align-self}]]) + :on-change set-align-self}]]) (when is-layout-child? [:div {:class (stl/css :row)} diff --git a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss index ad7b1c7c50..acd82fd10f 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.scss @@ -195,6 +195,7 @@ } .not-found { @include titleTipography; + color: var(--empty-message-foreground-color); margin: $s-12; } } diff --git a/frontend/src/app/main/ui/workspace/viewport/gradients.cljs b/frontend/src/app/main/ui/workspace/viewport/gradients.cljs index ae1dee6537..3e076fbb8f 100644 --- a/frontend/src/app/main/ui/workspace/viewport/gradients.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/gradients.cljs @@ -118,7 +118,7 @@ :on-pointer-up on-pointer-up}]]) (mf/defc gradient-handler-transformed - [{:keys [from-p to-p width-p from-color to-color zoom editing + [{:keys [from-p to-p width-p from-color to-color zoom editing transform on-change-start on-change-finish on-change-width]}] (let [moving-point (mf/use-var nil) angle (+ 90 (gpt/angle from-p to-p)) @@ -151,7 +151,7 @@ (reset! moving-point nil))] (mf/use-effect - (mf/deps @moving-point from-p to-p width-p) + (mf/deps @moving-point from-p to-p width-p transform) (fn [] (let [subs (->> st/stream (rx/filter mse/pointer-event?) @@ -159,17 +159,18 @@ (rx/map mse/get-pointer-position) (rx/subs! (fn [pt] - (case @moving-point - :from-p (when on-change-start (on-change-start pt)) - :to-p (when on-change-finish (on-change-finish pt)) - :width-p (when on-change-width - (let [width-v (gpt/unit (gpt/to-vec from-p width-p)) - distance (gpt/point-line-distance pt from-p to-p) - new-width-p (gpt/add - from-p - (gpt/multiply width-v (gpt/point distance)))] - (on-change-width new-width-p))) - nil))))] + (let [pt (gpt/transform pt transform)] + (case @moving-point + :from-p (when on-change-start (on-change-start pt)) + :to-p (when on-change-finish (on-change-finish pt)) + :width-p (when on-change-width + (let [width-v (gpt/unit (gpt/to-vec from-p width-p)) + distance (gpt/point-line-distance pt from-p to-p) + new-width-p (gpt/add + from-p + (gpt/multiply width-v (gpt/point distance)))] + (on-change-width new-width-p))) + nil)))))] (fn [] (rx/dispose! subs))))) [:g.gradient-handlers [:defs @@ -295,6 +296,7 @@ :width-p (when (= :radial (:type gradient)) width-p) :from-color {:value start-color :opacity start-opacity} :to-color {:value end-color :opacity end-opacity} + :transform transform :zoom zoom :on-change-start on-change-start :on-change-finish on-change-finish diff --git a/frontend/src/app/main/ui/workspace/viewport/snap_distances.cljs b/frontend/src/app/main/ui/workspace/viewport/snap_distances.cljs index 8b0b477cf9..4d8941fc66 100644 --- a/frontend/src/app/main/ui/workspace/viewport/snap_distances.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/snap_distances.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.files.helpers :as cph] [app.common.geom.rect :as grc] [app.common.geom.shapes :as gsh] [app.common.math :as mth] @@ -212,9 +213,9 @@ gt-side (if (= coord :x) :right :bottom) vbox (deref refs/vbox) - areas (gsh/get-areas - (or (grc/clip-rect (dm/get-prop frame :selrect) vbox) vbox) - selrect) + frame-sr (when-not (cph/root? frame) (dm/get-prop frame :selrect)) + bounds (d/nilv (grc/clip-rect frame-sr vbox) vbox) + areas (gsh/get-areas bounds selrect) query-side (fn [side]