mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
♻️ Use a DS icon in the grid editor track options button (#12486)
* ♻️ Use a DS icon in the grid editor track options button The options button of each grid track on the canvas drew a deprecated icon and had no accessible name. Use the DS menu icon and label the button "Track options". The button stays raw: it lives on the canvas, where the track editor keeps a fixed screen size at any zoom. The DS icon has a fixed 16px size, so its class scales it down with the zoom (transform: scale(1 / zoom)), as the old svg rule did with its width. It looks the same, but for a few antialiasing pixels. Add the workspace.layout-grid.editor.track-options key (en, es) and a visual test of a track at two zoom levels. AI-assisted-by: claude-opus-5-5 * ♻️ Move grid editor styles off the deprecated styles Move grid_layout_editor.scss to DS sizes, borders, spacing tokens, colors and logical properties, and drop the refactor import. The canvas sizes keep their division by the zoom. The grid editor color aliases resolve to their DS tokens, and the unused close-btn class, the last user of the deprecated button placeholders here, goes away. The track editor and the editing bar look the same as before. AI-assisted-by: claude-opus-5-5
This commit is contained in:
parent
7ff8df6ffb
commit
9911f82087
@ -136,6 +136,63 @@ test.describe("Grid layout", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Grid editor", () => {
|
||||
test("Shows the track options button on the canvas", async ({ page }) => {
|
||||
const workspace = new WorkspacePage(page);
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockRPC(/get\-file\?/, "workspace/get-file-9042.json");
|
||||
await workspace.mockRPC(
|
||||
"get-file-fragment?file-id=*&fragment-id=*",
|
||||
"workspace/get-file-fragment-9042.json",
|
||||
);
|
||||
await workspace.goToWorkspace({
|
||||
fileId: "af2494d0-39ba-8184-8005-230696f6df5c",
|
||||
pageId: "af2494d0-39ba-8184-8005-230696f6df5d",
|
||||
});
|
||||
|
||||
await workspace.clickLeafLayer("Board");
|
||||
// Tracks need 110px or more on screen to show their options button.
|
||||
await page.keyboard.press("Control+=");
|
||||
await page.keyboard.press("Control+=");
|
||||
await page
|
||||
.getByTestId("inspect-layout")
|
||||
.getByRole("button", { name: "Edit grid" })
|
||||
.click();
|
||||
|
||||
const shotTrack = async () => {
|
||||
const track = page.getByTestId("grid-track-editor-wrapper").first();
|
||||
await track.hover();
|
||||
await expect(
|
||||
page.getByTestId("grid-track-options-btn").first(),
|
||||
).toBeVisible();
|
||||
// Wait until the zoom animation leaves the track in place.
|
||||
let box = await track.boundingBox();
|
||||
await expect
|
||||
.poll(async () => {
|
||||
const prev = box;
|
||||
box = await track.boundingBox();
|
||||
return prev.x === box.x && prev.width === box.width;
|
||||
})
|
||||
.toBe(true);
|
||||
await expect(page).toHaveScreenshot({
|
||||
clip: {
|
||||
x: Math.floor(box.x) - 8,
|
||||
y: Math.floor(box.y) - 8,
|
||||
width: Math.ceil(box.width) + 16,
|
||||
height: Math.ceil(box.height) + 16,
|
||||
},
|
||||
maxDiffPixelRatio: 0,
|
||||
threshold: 0,
|
||||
});
|
||||
};
|
||||
|
||||
// The track editors draw at a fixed screen size at any zoom.
|
||||
await shotTrack();
|
||||
await page.keyboard.press("Control+=");
|
||||
await shotTrack();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Design tab", () => {
|
||||
test("Shows the boolean options when selecting two shapes", async ({
|
||||
page,
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.css-cursors :as cur]
|
||||
[app.main.ui.ds.buttons.button :refer [button*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :as i :refer [icon*]]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.main.ui.icons :as deprecated-icon]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :as uwvv]
|
||||
[app.util.debug :as dbg]
|
||||
[app.util.dom :as dom]
|
||||
@ -918,9 +918,15 @@
|
||||
:on-key-down handle-keydown-track-input
|
||||
:on-blur handle-blur-track-input}]
|
||||
(when (and (not medium?) (not small?))
|
||||
[:button {:class (stl/css :grid-editor-button)
|
||||
;; Raw button on purpose: it lives on the canvas and keeps a
|
||||
;; fixed screen size at any zoom.
|
||||
[:button {:type "button"
|
||||
:class (stl/css :grid-editor-button)
|
||||
:data-testid "grid-track-options-btn"
|
||||
:on-click handle-show-track-menu} deprecated-icon/menu])]])]
|
||||
:aria-label (tr "workspace.layout-grid.editor.track-options")
|
||||
:on-click handle-show-track-menu}
|
||||
[:> icon* {:icon-id i/menu
|
||||
:class (stl/css :grid-editor-button-icon)}]])]])]
|
||||
|
||||
[:g {:transform (when (= type :row) (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p)))}
|
||||
[:& track-marker
|
||||
|
||||
@ -4,17 +4,23 @@
|
||||
//
|
||||
// Copyright (c) KALEIDOS SUBSIDIARY SL
|
||||
|
||||
@use "refactor/common-refactor.scss" as deprecated;
|
||||
@use "ds/_borders.scss" as *;
|
||||
@use "ds/_sizes.scss" as *;
|
||||
@use "ds/_utils.scss" as *;
|
||||
@use "ds/colors.scss" as *;
|
||||
@use "ds/z-index.scss" as *;
|
||||
|
||||
// The track editor lives on the canvas: its sizes are divided by the zoom
|
||||
// so it keeps the same size on screen.
|
||||
|
||||
.grid-track-marker {
|
||||
.marker-shape {
|
||||
fill: var(--grid-editor-marker-color);
|
||||
fill: var(--color-accent-quaternary);
|
||||
}
|
||||
|
||||
.marker-text {
|
||||
fill: var(--app-white);
|
||||
font-size: calc(deprecated.$s-12 / var(--zoom));
|
||||
fill: $white;
|
||||
font-size: calc(#{px2rem(12)} / var(--zoom));
|
||||
font-family: "worksans", "vazirmatn", sans-serif;
|
||||
}
|
||||
}
|
||||
@ -22,8 +28,8 @@
|
||||
.grid-editor-wrapper {
|
||||
cursor: grab;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
inline-size: 100%;
|
||||
block-size: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
@ -31,21 +37,20 @@
|
||||
}
|
||||
|
||||
.grid-editor-header-hover {
|
||||
fill: var(--grid-editor-marker-color);
|
||||
fill: var(--color-accent-quaternary);
|
||||
}
|
||||
|
||||
.grid-editor-label {
|
||||
flex: 1;
|
||||
background: none;
|
||||
border: 0;
|
||||
color: var(--grid-editor-marker-text);
|
||||
color: var(--color-accent-quaternary);
|
||||
font-family: "worksans", "vazirmatn", sans-serif;
|
||||
font-size: calc(deprecated.$fs-12 / var(--zoom));
|
||||
font-size: calc(#{px2rem(12)} / var(--zoom));
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
max-width: calc(deprecated.$s-60 / var(--zoom));
|
||||
padding: 0;
|
||||
padding: calc(deprecated.$s-4 / var(--zoom));
|
||||
max-inline-size: calc(#{px2rem(60)} / var(--zoom));
|
||||
padding: calc(var(--sp-xs) / var(--zoom));
|
||||
text-align: center;
|
||||
|
||||
&:focus {
|
||||
@ -60,21 +65,23 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: calc(deprecated.$s-6 / var(--zoom));
|
||||
right: calc(deprecated.$s-20 / var(--zoom));
|
||||
width: calc(deprecated.$s-20 / var(--zoom));
|
||||
height: calc(deprecated.$s-20 / var(--zoom));
|
||||
inset-block-start: calc(#{px2rem(6)} / var(--zoom));
|
||||
inset-inline-end: calc(#{px2rem(20)} / var(--zoom));
|
||||
inline-size: calc(#{px2rem(20)} / var(--zoom));
|
||||
block-size: calc(#{px2rem(20)} / var(--zoom));
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: calc(deprecated.$s-16 / var(--zoom));
|
||||
height: auto;
|
||||
stroke: var(--grid-editor-marker-color);
|
||||
}
|
||||
// The DS icon has a fixed 16px size: scale it down with the zoom, as the
|
||||
// rest of the track editor, so it keeps the same size on screen.
|
||||
.grid-editor-button-icon {
|
||||
position: absolute;
|
||||
inset-block-start: 0;
|
||||
inset-inline-start: 0;
|
||||
transform: scale(calc(1 / var(--zoom)));
|
||||
transform-origin: top left;
|
||||
color: var(--color-accent-quaternary);
|
||||
}
|
||||
|
||||
.grid-editor-wrapper:hover .grid-editor-button {
|
||||
@ -83,7 +90,7 @@
|
||||
}
|
||||
|
||||
.grid-frame {
|
||||
fill: var(--grid-editor-marker-color);
|
||||
fill: var(--color-accent-quaternary);
|
||||
fill-opacity: 0.1;
|
||||
}
|
||||
|
||||
@ -92,13 +99,13 @@
|
||||
opacity: 0.5;
|
||||
|
||||
.grid-plus-shape {
|
||||
fill: var(--grid-editor-plus-btn-background);
|
||||
stroke: var(--grid-editor-plus-btn-background);
|
||||
stroke-width: calc(deprecated.$s-1 / var(--zoom));
|
||||
fill: var(--color-accent-quaternary);
|
||||
stroke: var(--color-accent-quaternary);
|
||||
stroke-width: calc(#{px2rem(1)} / var(--zoom));
|
||||
}
|
||||
|
||||
.grid-plus-icon {
|
||||
stroke: var(--grid-editor-plus-btn-foreground);
|
||||
stroke: $white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@ -108,7 +115,7 @@
|
||||
|
||||
.grid-cell-outline {
|
||||
fill: transparent;
|
||||
stroke: var(--grid-editor-line-color);
|
||||
stroke: var(--color-accent-quaternary);
|
||||
stroke-opacity: 0.5;
|
||||
stroke-width: calc(1 / var(--zoom));
|
||||
|
||||
@ -122,37 +129,32 @@
|
||||
.grid-actions {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: deprecated.$s-44;
|
||||
left: 50%;
|
||||
inset-block-start: px2rem(44);
|
||||
inset-inline-start: 50%;
|
||||
z-index: var(--z-index-notifications);
|
||||
}
|
||||
|
||||
.grid-actions-container {
|
||||
@include deprecated.flex-row;
|
||||
|
||||
background: var(--panel-background-color);
|
||||
border-radius: deprecated.$br-12;
|
||||
box-shadow: 0 0 deprecated.$s-12 0 var(--menu-shadow-color);
|
||||
gap: deprecated.$s-8;
|
||||
height: deprecated.$s-48;
|
||||
margin-left: -50%;
|
||||
padding: deprecated.$s-8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-s);
|
||||
background: var(--color-background-primary);
|
||||
border-radius: $br-12;
|
||||
box-shadow: 0 0 px2rem(12) 0 var(--color-shadow-dark);
|
||||
block-size: $sz-48;
|
||||
margin-inline-start: -50%;
|
||||
padding: var(--sp-s);
|
||||
cursor: initial;
|
||||
pointer-events: initial;
|
||||
width: deprecated.$s-512;
|
||||
inline-size: $sz-512;
|
||||
}
|
||||
|
||||
.grid-actions-title {
|
||||
flex: 1;
|
||||
font-size: deprecated.$fs-12;
|
||||
|
||||
// TODO: No exact DS typography match found.
|
||||
// Closest match: body-small.
|
||||
font-size: px2rem(12);
|
||||
color: var(--color-foreground-secondary);
|
||||
padding-left: deprecated.$s-8;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
@extend %button-tertiary;
|
||||
|
||||
svg {
|
||||
@extend %button-icon;
|
||||
}
|
||||
padding-inline-start: var(--sp-s);
|
||||
}
|
||||
|
||||
@ -6791,6 +6791,10 @@ msgstr "Top padding"
|
||||
msgid "workspace.layout-grid.editor.padding.vertical"
|
||||
msgstr "Vertical padding"
|
||||
|
||||
#: src/app/main/ui/workspace/viewport/grid_layout_editor.cljs
|
||||
msgid "workspace.layout-grid.editor.track-options"
|
||||
msgstr "Track options"
|
||||
|
||||
#: src/app/main/ui/workspace/viewport/grid_layout_editor.cljs:61
|
||||
msgid "workspace.layout-grid.editor.title"
|
||||
msgstr "Editing grid"
|
||||
|
||||
@ -6875,6 +6875,10 @@ msgstr "Padding superior"
|
||||
msgid "workspace.layout-grid.editor.padding.vertical"
|
||||
msgstr "Padding vertical"
|
||||
|
||||
#: src/app/main/ui/workspace/viewport/grid_layout_editor.cljs
|
||||
msgid "workspace.layout-grid.editor.track-options"
|
||||
msgstr "Opciones de la pista"
|
||||
|
||||
#: src/app/main/ui/workspace/viewport/grid_layout_editor.cljs:61
|
||||
msgid "workspace.layout-grid.editor.title"
|
||||
msgstr "Editando rejilla"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user