mirror of
https://github.com/penpot/penpot.git
synced 2026-05-09 01:58:46 +00:00
🎉 Add selection size badge below bounding box (#9210)
* 🎉 Add selection size badge below bounding box Signed-off-by: bittoby <218712309+bittoby@users.noreply.github.com> * 💄 Address review comments Signed-off-by: bittoby <218712309+bittoby@users.noreply.github.com> * 💄 Move selection size badge text styles to SCSS class --------- Signed-off-by: bittoby <218712309+bittoby@users.noreply.github.com> Signed-off-by: BitToby <218712309+bittoby@users.noreply.github.com> Co-authored-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
parent
bb93928099
commit
6aeccb1208
@ -8,6 +8,8 @@
|
||||
|
||||
### :sparkles: New features & Enhancements
|
||||
|
||||
- Show a read-only W × H size badge below the bounding box of the current selection so dimensions are visible directly on the canvas (initial implementation: always-on badge, single visual variant, no live-resize integration; remaining spec items follow in subsequent PRs) [Github #9205](https://github.com/penpot/penpot/issues/9205)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Harden Nginx responses with standard security headers and hide upstream `X-Powered-By` headers
|
||||
|
||||
@ -78,6 +78,32 @@ test("User draws a rect", async ({ page }) => {
|
||||
await expect(workspacePage.canvas).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test("Selection size badge appears on selection and hides on deselect", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspacePage = new WasmWorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile();
|
||||
await workspacePage.mockRPC(
|
||||
/get\-file\?/,
|
||||
"workspace/get-file-not-empty.json",
|
||||
);
|
||||
|
||||
await workspacePage.goToWorkspace({
|
||||
fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374",
|
||||
pageId: "6191cd35-bb1f-81f7-8004-7cc63d087375",
|
||||
});
|
||||
|
||||
const badge = page.locator(".selection-size-badge");
|
||||
|
||||
await expect(badge).toHaveCount(0);
|
||||
|
||||
await workspacePage.clickLeafLayer("Rectangle");
|
||||
await expect(badge).toBeVisible();
|
||||
|
||||
await workspacePage.page.keyboard.press("Escape");
|
||||
await expect(badge).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("User makes a group", async ({ page }) => {
|
||||
const workspacePage = new WasmWorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile();
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.measurements
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
@ -43,6 +44,13 @@
|
||||
(def distance-pill-height 16)
|
||||
(def distance-line-stroke 1)
|
||||
|
||||
(def ^:private ^:const selection-badge-bg-color "var(--color-accent-tertiary)")
|
||||
(def ^:private ^:const selection-badge-height 16)
|
||||
(def ^:private ^:const selection-badge-padding-x 6)
|
||||
(def ^:private ^:const selection-badge-vertical-gap 8)
|
||||
(def ^:private ^:const selection-badge-border-radius 2)
|
||||
(def ^:private ^:const selection-badge-char-width 6.5)
|
||||
|
||||
|
||||
;; ------------------------------------------------
|
||||
;; HELPERS
|
||||
@ -179,6 +187,35 @@
|
||||
:stroke hover-color
|
||||
:stroke-width selection-rect-width}}]]))
|
||||
|
||||
(mf/defc selection-size-badge*
|
||||
[{:keys [selrect zoom]}]
|
||||
(let [{:keys [x y width height]} selrect
|
||||
size-label (dm/str (fmt/format-number width) " x " (fmt/format-number height))
|
||||
badge-height (/ selection-badge-height zoom)
|
||||
padding-x (/ selection-badge-padding-x zoom)
|
||||
gap (/ selection-badge-vertical-gap zoom)
|
||||
radius (/ selection-badge-border-radius zoom)
|
||||
text-width (* (count size-label) (/ selection-badge-char-width zoom))
|
||||
badge-width (+ text-width (* 2 padding-x))
|
||||
center-x (+ x (/ width 2))
|
||||
badge-x (- center-x (/ badge-width 2))
|
||||
badge-y (+ y height gap)
|
||||
text-y (+ badge-y (/ badge-height 2))]
|
||||
[:g.selection-size-badge {:pointer-events "none"}
|
||||
[:rect {:x badge-x
|
||||
:y badge-y
|
||||
:width badge-width
|
||||
:height badge-height
|
||||
:rx radius
|
||||
:ry radius
|
||||
:style {:fill selection-badge-bg-color}}]
|
||||
[:text {:class (stl/css :badge-text)
|
||||
:x center-x
|
||||
:y text-y
|
||||
:text-anchor "middle"
|
||||
:dominant-baseline "middle"}
|
||||
size-label]]))
|
||||
|
||||
(mf/defc distance-display* [{:keys [from to zoom bounds]}]
|
||||
(let [fixed-x (if (gsh/fully-contained? from to)
|
||||
(+ (:x to) (/ (:width to) 2))
|
||||
@ -244,6 +281,7 @@
|
||||
:bounds bounds
|
||||
:zoom zoom}]
|
||||
[:> size-display* {:selrect selected-selrect :zoom zoom}]
|
||||
[:> selection-size-badge* {:selrect selected-selrect :zoom zoom}]
|
||||
|
||||
(if (or (not hover-shape) (not hover-selected-shape?))
|
||||
(when (and frame (not= uuid/zero (:id frame)))
|
||||
|
||||
13
frontend/src/app/main/ui/measurements.scss
Normal file
13
frontend/src/app/main/ui/measurements.scss
Normal file
@ -0,0 +1,13 @@
|
||||
// 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
|
||||
|
||||
@use "refactor/common-refactor.scss" as deprecated;
|
||||
|
||||
.badge-text {
|
||||
fill: var(--app-black);
|
||||
font-size: calc(deprecated.$fs-12 / var(--zoom));
|
||||
font-family: "worksans", "vazirmatn", sans-serif;
|
||||
}
|
||||
@ -500,6 +500,14 @@
|
||||
:zoom zoom
|
||||
:modifiers modifiers}])
|
||||
|
||||
(when (and (seq selected-shapes)
|
||||
(not transform)
|
||||
(not text-editing?)
|
||||
(not edition))
|
||||
[:> msr/selection-size-badge*
|
||||
{:selrect (gsh/shapes->rect selected-shapes)
|
||||
:zoom zoom}])
|
||||
|
||||
(when show-measures?
|
||||
[:> msr/measurement*
|
||||
{:bounds vbox
|
||||
|
||||
@ -653,6 +653,15 @@
|
||||
{:shape (get base-objects edition)
|
||||
:zoom zoom}])
|
||||
|
||||
(when (and (seq selected-shapes)
|
||||
(not transform)
|
||||
(not text-editing?)
|
||||
(not edition)
|
||||
(not page-transition?))
|
||||
[:> msr/selection-size-badge*
|
||||
{:selrect (gsh/shapes->rect selected-shapes)
|
||||
:zoom zoom}])
|
||||
|
||||
(when show-measures?
|
||||
[:> msr/measurement*
|
||||
{:bounds vbox
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user