diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index cf6e9e17f9..05d60cf659 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -32,6 +32,15 @@ (def profile (l/derived (l/key :profile) st/state)) +(def ui-scale + "Effective UI scale factor, gated by the `:ui-scale` flag. Returns 1.0 when the + flag is disabled or the profile prop has never been set." + (l/derived (fn [state] + (if (contains? cf/flags :ui-scale) + (or (get-in state [:profile :props :ui-scale]) 1.0) + 1.0)) + st/state)) + (def current-page-id (l/derived (l/key :current-page-id) st/state)) diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs index 81e7b25db3..4813afac7e 100644 --- a/frontend/src/app/main/ui.cljs +++ b/frontend/src/app/main/ui.cljs @@ -373,9 +373,7 @@ (let [route (mf/deref refs/route) edata (mf/deref refs/exception) profile (mf/deref refs/profile) - ui-scale (if (contains? cf/flags :ui-scale) - (or (-> profile :props :ui-scale) 1.0) - 1.0)] + ui-scale (mf/deref refs/ui-scale)] ;; initialize themes (theme/use-initialize profile) diff --git a/frontend/src/app/main/ui/dashboard/inline_edition.scss b/frontend/src/app/main/ui/dashboard/inline_edition.scss index e12b9110e2..20bd59ca44 100644 --- a/frontend/src/app/main/ui/dashboard/inline_edition.scss +++ b/frontend/src/app/main/ui/dashboard/inline_edition.scss @@ -5,6 +5,7 @@ // Copyright (c) KALEIDOS INC Sucursal en España SL @use "refactor/common-refactor.scss" as deprecated; +@use "ds/_utils.scss" as *; .edit-wrapper { border-radius: deprecated.$br-4; @@ -40,7 +41,7 @@ input.element-title { svg { fill: var(--color-foreground-secondary); height: deprecated.$s-16; - transform: rotate(45deg) translateY(7px); + transform: rotate(45deg) translateY(px2rem(7)); width: deprecated.$s-16; margin: 0; } diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.scss b/frontend/src/app/main/ui/ds/tooltip/tooltip.scss index 0647a74c3c..58415117d1 100644 --- a/frontend/src/app/main/ui/ds/tooltip/tooltip.scss +++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.scss @@ -6,10 +6,13 @@ @use "ds/_sizes.scss" as *; @use "ds/_borders.scss" as *; +@use "ds/_utils.scss" as *; @use "ds/z-index.scss" as *; @use "ds/typography.scss" as t; -$arrow-side: 12px; +// Expressed in rem so the arrow (and its offsets below) scale with the UI like +// the tooltip body it points from. +$arrow-side: px2rem(12); .tooltip { position: fixed; @@ -45,7 +48,7 @@ $arrow-side: 12px; justify-self: center; border-radius: 0 0 var(--sp-xs) 0; transform-origin: 0 0; - transform: rotate(45deg) translate(-2px, -10px); + transform: rotate(45deg) translate(px2rem(-2), px2rem(-10)); border-block-end: $b-1 solid var(--color-accent-primary-muted); border-inline-end: $b-1 solid var(--color-accent-primary-muted); } @@ -60,7 +63,7 @@ $arrow-side: 12px; justify-self: center; border-radius: var(--sp-xs) 0; transform-origin: 0 0; - transform: rotate(45deg) translate(7px, -2px); + transform: rotate(45deg) translate(px2rem(7), px2rem(-2)); border-block-start: $b-1 solid var(--color-accent-primary-muted); border-inline-start: $b-1 solid var(--color-accent-primary-muted); } @@ -73,7 +76,7 @@ $arrow-side: 12px; align-self: center; border-radius: 0 var(--sp-xs); transform-origin: 0 0; - transform: rotate(45deg) translate(-2px, -1px); + transform: rotate(45deg) translate(px2rem(-2), px2rem(-1)); border-block-start: $b-1 solid var(--color-accent-primary-muted); border-inline-end: $b-1 solid var(--color-accent-primary-muted); } @@ -86,7 +89,7 @@ $arrow-side: 12px; align-self: center; border-radius: 0 var(--sp-xs); transform-origin: 0 0; - transform: rotate(45deg) translate(7px, -10px); + transform: rotate(45deg) translate(px2rem(7), px2rem(-10)); border-block-end: $b-1 solid var(--color-accent-primary-muted); border-inline-start: $b-1 solid var(--color-accent-primary-muted); } diff --git a/frontend/src/app/main/ui/inspect/code.cljs b/frontend/src/app/main/ui/inspect/code.cljs index 57f6ea10b8..ecb5fcd087 100644 --- a/frontend/src/app/main/ui/inspect/code.cljs +++ b/frontend/src/app/main/ui/inspect/code.cljs @@ -316,7 +316,7 @@ (when-not collapsed-css? [:div {:class (stl/css :code-row-display) - :style {:--code-height (dm/str (or style-size 400) "px")}} + :style {:--code-height (dm/str "calc(" (or style-size 400) "px * var(--ui-scale))")}} [:> code-block* {:type style-type :code style-code}]]) @@ -357,7 +357,7 @@ (when-not collapsed-markup? [:div {:class (stl/css :code-row-display) - :style {:--code-height (dm/str (or markup-size 400) "px")}} + :style {:--code-height (dm/str "calc(" (or markup-size 400) "px * var(--ui-scale))")}} [:> code-block* {:type markup-type :code markup-code}]]) diff --git a/frontend/src/app/main/ui/workspace/color_palette.cljs b/frontend/src/app/main/ui/workspace/color_palette.cljs index 16425b2f83..325be023e6 100644 --- a/frontend/src/app/main/ui/workspace/color_palette.cljs +++ b/frontend/src/app/main/ui/workspace/color_palette.cljs @@ -91,35 +91,44 @@ (reset! search-term* "") (reset! search-open* false))) - offset-step (cond - (<= size 64) 40 - (<= size 80) 72 - :else 72) + ;; Everything below is expressed in real (rendered) pixels: the swatch + ;; sizes and the horizontal paging math are all multiplied by `ui-scale` + ;; so they stay coupled with the (measured, already-scaled) `width`. + ui-scale (mf/deref refs/ui-scale) + + offset-step (* ui-scale + (cond + (<= size 64) 40 + (<= size 80) 72 + :else 72)) ;; Reserve room for the search bar, icon button, or nothing search-width (cond (not has-colors?) 0 search-open? 192 :else 32) - buttons-size (cond - (<= size 64) (+ 164 search-width) - :else (+ 132 search-width)) + buttons-size (* ui-scale + (cond + (<= size 64) (+ 164 search-width) + :else (+ 132 search-width))) width (- width buttons-size) visible (int (/ width offset-step)) show-arrows? (> (count filtered-colors) visible) visible (if show-arrows? - (int (/ (- width 48) offset-step)) + (int (/ (- width (* ui-scale 48)) offset-step)) visible) offset (:offset @state 0) max-offset (- (count filtered-colors) visible) container (mf/use-ref nil) - bullet-size (cond - (<= size 64) "32" - (<= size 72) "28" - (<= size 80) "32" - :else "32") - color-cell-width (cond - (<= size 64) 32 - :else 64) + bullet-size (* ui-scale + (cond + (<= size 64) 32 + (<= size 72) 28 + (<= size 80) 32 + :else 32)) + color-cell-width (* ui-scale + (cond + (<= size 64) 32 + :else 64)) on-left-arrow-click (mf/use-fn diff --git a/frontend/src/app/main/ui/workspace/colorpicker/slider_selector.scss b/frontend/src/app/main/ui/workspace/colorpicker/slider_selector.scss index fc34824198..2a97f8d992 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker/slider_selector.scss +++ b/frontend/src/app/main/ui/workspace/colorpicker/slider_selector.scss @@ -5,6 +5,7 @@ // Copyright (c) KALEIDOS INC Sucursal en España SL @use "refactor/common-refactor.scss" as deprecated; +@use "ds/_utils.scss" as *; .slider-selector { --gradient-direction: 90deg; @@ -91,14 +92,14 @@ height: calc(deprecated.$s-24 + deprecated.$s-1); border-radius: deprecated.$br-4; z-index: deprecated.$z-index-1; - transform: translate(-4px, -3px); + transform: translate(px2rem(-4), px2rem(-3)); background-color: var(--colorpicker-handlers-color); } &.vertical .handler { height: calc(deprecated.$s-8 + deprecated.$s-2); width: calc(deprecated.$s-24 + deprecated.$s-1); - transform: translate(-12px, 5px); + transform: translate(px2rem(-12), px2rem(5)); } } diff --git a/frontend/src/app/main/ui/workspace/palette.cljs b/frontend/src/app/main/ui/workspace/palette.cljs index 0c96fce938..569e7ae7d6 100644 --- a/frontend/src/app/main/ui/workspace/palette.cljs +++ b/frontend/src/app/main/ui/workspace/palette.cljs @@ -50,8 +50,10 @@ ;; viewport (not scaled), so only the sidebar portions are multiplied. fixed-left (+ rulers-width left-padding 1)] - #js {"paddingLeft" (dm/str "calc(" sidebar-width "px * var(--ui-scale) + " fixed-left "px)") - "paddingRight" (dm/str "calc(" right-sidebar-default-width "px * var(--ui-scale) + 4px)")})) + ;; round() matches the sidebars, which snap their scaled width to whole + ;; pixels — so the palette clears them without a sub-pixel gap/overlap. + #js {"paddingLeft" (dm/str "calc(round(" sidebar-width "px * var(--ui-scale), 1px) + " fixed-left "px)") + "paddingRight" (dm/str "calc(round(" right-sidebar-default-width "px * var(--ui-scale), 1px) + 4px)")})) (mf/defc palette* [{:keys [layout on-change-size]}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs index 3283050d23..6dccfc0205 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/sitemap.cljs @@ -283,7 +283,7 @@ permissions (mf/use-ctx ctx/permissions)] [:div {:class (stl/css :sitemap) - :style {:--height (dm/str height "px")}} + :style {:--height (dm/str "calc(" height "px * var(--ui-scale))")}} [:> title-bar* {:collapsable true :collapsed collapsed diff --git a/frontend/src/app/main/ui/workspace/text_palette.cljs b/frontend/src/app/main/ui/workspace/text_palette.cljs index abc3981090..4be73c29fb 100644 --- a/frontend/src/app/main/ui/workspace/text_palette.cljs +++ b/frontend/src/app/main/ui/workspace/text_palette.cljs @@ -78,12 +78,16 @@ :file (sort-by #(str/lower (:name %)) (vals file-typographies)) (sort-by #(str/lower (:name %)) (vals (get-in libraries [selected :data :typographies])))) state (mf/use-state {:offset 0}) - offset-step 144 - buttons-size (cond - (<= size 64) 164 - (<= size 72) 164 - (<= size 80) 132 - :else 132) + ;; Real (rendered) pixels: item step and reserved button space are + ;; multiplied by `ui-scale` to stay coupled with the measured `width`. + ui-scale (mf/deref refs/ui-scale) + offset-step (* ui-scale 144) + buttons-size (* ui-scale + (cond + (<= size 64) 164 + (<= size 72) 164 + (<= size 80) 132 + :else 132)) width (- width buttons-size) visible (int (/ width offset-step)) show-arrows? (> (count current-typographies) visible) @@ -140,7 +144,7 @@ (swap! state assoc :offset 0))) [:div {:class (stl/css :text-palette) - :style #js {"--height" (str size "px")}} + :style #js {"--height" (str (* ui-scale size) "px")}} (when show-arrows? [:button {:class (stl/css :left-arrow) :disabled (= offset 0)