mirror of
https://github.com/penpot/penpot.git
synced 2026-01-06 05:18:52 -05:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d89dfc5e30 | ||
|
|
cd586c81ee | ||
|
|
16e1e01234 | ||
|
|
fe6c9f24d3 | ||
|
|
fe314cf146 | ||
|
|
97a880c946 | ||
|
|
df66955594 | ||
|
|
07f055bd49 | ||
|
|
22d5b125bd | ||
|
|
ef3b4a5895 |
@@ -46,6 +46,9 @@
|
||||
- Fix percent calculation on grid layout tracks [Github #4688](https://github.com/penpot/penpot/issues/4688)
|
||||
- Fix problem with caps and inner shadows [Github #4517](https://github.com/penpot/penpot/issues/4517)
|
||||
- Fix problem with horizontal/vertical lines and shadows [Github #4516](https://github.com/penpot/penpot/issues/4516)
|
||||
- Fix problem with layers overflowing panel [Taiga #9021](https://tree.taiga.io/project/penpot/issue/9021)
|
||||
- Fix in workspace you can manage rulers on view mode [Taiga #8966](https://tree.taiga.io/project/penpot/issue/8966)
|
||||
- Fix problem with swap components in grid layout [Taiga #9066](https://tree.taiga.io/project/penpot/issue/9066)
|
||||
|
||||
## 2.2.1
|
||||
|
||||
|
||||
@@ -232,6 +232,7 @@
|
||||
[(:parent-id first-shape)]
|
||||
(fn [shape objects]
|
||||
(-> shape
|
||||
(ctl/assign-cells objects)
|
||||
(ctl/push-into-cell [(:id first-shape)] row column)
|
||||
(ctl/assign-cells objects)))
|
||||
{:with-objects? true})
|
||||
@@ -1988,7 +1989,8 @@
|
||||
(+ (:position guide) (- (:y new-frame) (:y frame))))
|
||||
guide {:id guide-id
|
||||
:frame-id new-id
|
||||
:position position}]
|
||||
:position position
|
||||
:axis (:axis guide)}]
|
||||
(pcb/set-guide changes guide-id guide))
|
||||
changes))
|
||||
changes
|
||||
|
||||
49
frontend/playwright/data/workspace/get-file-9042.json
Normal file
49
frontend/playwright/data/workspace/get-file-9042.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"~:features": {
|
||||
"~#set": [
|
||||
"layout/grid",
|
||||
"styles/v2",
|
||||
"fdata/pointer-map",
|
||||
"fdata/objects-map",
|
||||
"components/v2",
|
||||
"fdata/shape-data-type"
|
||||
]
|
||||
},
|
||||
"~:permissions": {
|
||||
"~:type": "~:membership",
|
||||
"~:is-owner": true,
|
||||
"~:is-admin": true,
|
||||
"~:can-edit": true,
|
||||
"~:can-read": true,
|
||||
"~:is-logged": true
|
||||
},
|
||||
"~:has-media-trimmed": false,
|
||||
"~:comment-thread-seqn": 0,
|
||||
"~:name": "New File 5",
|
||||
"~:revn": 3,
|
||||
"~:modified-at": "~m1729245873067",
|
||||
"~:id": "~uaf2494d0-39ba-8184-8005-230696f6df5c",
|
||||
"~:is-shared": false,
|
||||
"~:version": 55,
|
||||
"~:project-id": "~u17866431-4e74-816e-8004-eba55c3a5694",
|
||||
"~:created-at": "~m1729245083615",
|
||||
"~:data": {
|
||||
"~:pages": [
|
||||
"~uaf2494d0-39ba-8184-8005-230696f6df5d"
|
||||
],
|
||||
"~:pages-index": {
|
||||
"~uaf2494d0-39ba-8184-8005-230696f6df5d": {
|
||||
"~#penpot/pointer": [
|
||||
"~uaf2494d0-39ba-8184-8005-230999ec862d",
|
||||
{
|
||||
"~:created-at": "~m1729245873074"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"~:id": "~uaf2494d0-39ba-8184-8005-230696f6df5c",
|
||||
"~:options": {
|
||||
"~:components-v2": true
|
||||
}
|
||||
}
|
||||
}
|
||||
57
frontend/playwright/data/workspace/get-file-9066.json
Normal file
57
frontend/playwright/data/workspace/get-file-9066.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"~:features": {
|
||||
"~#set": [
|
||||
"layout/grid",
|
||||
"styles/v2",
|
||||
"fdata/pointer-map",
|
||||
"fdata/objects-map",
|
||||
"components/v2",
|
||||
"fdata/shape-data-type"
|
||||
]
|
||||
},
|
||||
"~:permissions": {
|
||||
"~:type": "~:membership",
|
||||
"~:is-owner": true,
|
||||
"~:is-admin": true,
|
||||
"~:can-edit": true,
|
||||
"~:can-read": true,
|
||||
"~:is-logged": true
|
||||
},
|
||||
"~:has-media-trimmed": false,
|
||||
"~:comment-thread-seqn": 0,
|
||||
"~:name": "New File 10",
|
||||
"~:revn": 10,
|
||||
"~:modified-at": "~m1729604566305",
|
||||
"~:id": "~ue179d9df-de35-80bf-8005-283bbd5516b0",
|
||||
"~:is-shared": false,
|
||||
"~:version": 55,
|
||||
"~:project-id": "~u3ffbd505-2f26-800f-8004-f34da98bdad8",
|
||||
"~:created-at": "~m1729594560852",
|
||||
"~:data": {
|
||||
"~:pages": [
|
||||
"~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||
],
|
||||
"~:pages-index": {
|
||||
"~ue179d9df-de35-80bf-8005-283bbd5516b1": {
|
||||
"~#penpot/pointer": [
|
||||
"~ue179d9df-de35-80bf-8005-2861e849785e",
|
||||
{
|
||||
"~:created-at": "~m1729604566310"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"~:id": "~ue179d9df-de35-80bf-8005-283bbd5516b0",
|
||||
"~:options": {
|
||||
"~:components-v2": true
|
||||
},
|
||||
"~:components": {
|
||||
"~#penpot/pointer": [
|
||||
"~ue179d9df-de35-80bf-8005-2861e849b3f7",
|
||||
{
|
||||
"~:created-at": "~m1729604566311"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
270
frontend/playwright/data/workspace/get-file-fragment-9042.json
Normal file
270
frontend/playwright/data/workspace/get-file-fragment-9042.json
Normal file
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"~:id": "~uaf2494d0-39ba-8184-8005-230999ec862d",
|
||||
"~:file-id": "~uaf2494d0-39ba-8184-8005-230696f6df5c",
|
||||
"~:created-at": "~m1729245873057",
|
||||
"~:data": {
|
||||
"~:options": {},
|
||||
"~:objects": {
|
||||
"~u00000000-0000-0000-0000-000000000000": {
|
||||
"~#shape": {
|
||||
"~:y": 0,
|
||||
"~:hide-fill-on-export": false,
|
||||
"~:transform": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:rotation": 0,
|
||||
"~:name": "Root Frame",
|
||||
"~:width": 0.01,
|
||||
"~:type": "~:frame",
|
||||
"~:points": [
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 0.0,
|
||||
"~:y": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 0.01,
|
||||
"~:y": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 0.01,
|
||||
"~:y": 0.01
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 0.0,
|
||||
"~:y": 0.01
|
||||
}
|
||||
}
|
||||
],
|
||||
"~:proportion-lock": false,
|
||||
"~:transform-inverse": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:parent-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:frame-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:strokes": [],
|
||||
"~:x": 0,
|
||||
"~:proportion": 1.0,
|
||||
"~:selrect": {
|
||||
"~#rect": {
|
||||
"~:x": 0,
|
||||
"~:y": 0,
|
||||
"~:width": 0.01,
|
||||
"~:height": 0.01,
|
||||
"~:x1": 0,
|
||||
"~:y1": 0,
|
||||
"~:x2": 0.01,
|
||||
"~:y2": 0.01
|
||||
}
|
||||
},
|
||||
"~:fills": [
|
||||
{
|
||||
"~:fill-color": "#FFFFFF",
|
||||
"~:fill-opacity": 1
|
||||
}
|
||||
],
|
||||
"~:flip-x": null,
|
||||
"~:height": 0.01,
|
||||
"~:flip-y": null,
|
||||
"~:shapes": [
|
||||
"~u8611ed3e-43d1-80dc-8005-23069fddf984"
|
||||
]
|
||||
}
|
||||
},
|
||||
"~u8611ed3e-43d1-80dc-8005-23069fddf984": {
|
||||
"~#shape": {
|
||||
"~:y": 128,
|
||||
"~:layout-grid-columns": [
|
||||
{
|
||||
"~:type": "~:flex",
|
||||
"~:value": 1
|
||||
},
|
||||
{
|
||||
"~:type": "~:flex",
|
||||
"~:value": 1
|
||||
}
|
||||
],
|
||||
"~:hide-fill-on-export": false,
|
||||
"~:layout-gap-type": "~:multiple",
|
||||
"~:layout-padding": {
|
||||
"~:p1": 0,
|
||||
"~:p2": 0,
|
||||
"~:p3": 0,
|
||||
"~:p4": 0
|
||||
},
|
||||
"~:transform": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:rotation": 0,
|
||||
"~:grow-type": "~:fixed",
|
||||
"~:layout": "~:grid",
|
||||
"~:hide-in-viewer": false,
|
||||
"~:name": "Board",
|
||||
"~:layout-align-items": "~:start",
|
||||
"~:width": 200,
|
||||
"~:layout-grid-cells": {
|
||||
"~u96353b58-4e42-8052-8005-230996dafe13": {
|
||||
"~:justify-self": "~:auto",
|
||||
"~:column": 1,
|
||||
"~:id": "~u96353b58-4e42-8052-8005-230996dafe13",
|
||||
"~:position": "~:auto",
|
||||
"~:column-span": 1,
|
||||
"~:align-self": "~:auto",
|
||||
"~:row": 1,
|
||||
"~:row-span": 1,
|
||||
"~:shapes": []
|
||||
},
|
||||
"~u96353b58-4e42-8052-8005-230996dafe14": {
|
||||
"~:justify-self": "~:auto",
|
||||
"~:column": 2,
|
||||
"~:id": "~u96353b58-4e42-8052-8005-230996dafe14",
|
||||
"~:position": "~:auto",
|
||||
"~:column-span": 1,
|
||||
"~:align-self": "~:auto",
|
||||
"~:row": 1,
|
||||
"~:row-span": 1,
|
||||
"~:shapes": []
|
||||
},
|
||||
"~u96353b58-4e42-8052-8005-230996dafe15": {
|
||||
"~:justify-self": "~:auto",
|
||||
"~:column": 1,
|
||||
"~:id": "~u96353b58-4e42-8052-8005-230996dafe15",
|
||||
"~:position": "~:auto",
|
||||
"~:column-span": 1,
|
||||
"~:align-self": "~:auto",
|
||||
"~:row": 2,
|
||||
"~:row-span": 1,
|
||||
"~:shapes": []
|
||||
},
|
||||
"~u96353b58-4e42-8052-8005-230996dafe16": {
|
||||
"~:justify-self": "~:auto",
|
||||
"~:column": 2,
|
||||
"~:id": "~u96353b58-4e42-8052-8005-230996dafe16",
|
||||
"~:position": "~:auto",
|
||||
"~:column-span": 1,
|
||||
"~:align-self": "~:auto",
|
||||
"~:row": 2,
|
||||
"~:row-span": 1,
|
||||
"~:shapes": []
|
||||
}
|
||||
},
|
||||
"~:layout-padding-type": "~:simple",
|
||||
"~:type": "~:frame",
|
||||
"~:points": [
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 128,
|
||||
"~:y": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 328,
|
||||
"~:y": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 328,
|
||||
"~:y": 328
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 128,
|
||||
"~:y": 328
|
||||
}
|
||||
}
|
||||
],
|
||||
"~:proportion-lock": false,
|
||||
"~:layout-gap": {
|
||||
"~:row-gap": 0,
|
||||
"~:column-gap": 0
|
||||
},
|
||||
"~:transform-inverse": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:layout-justify-content": "~:stretch",
|
||||
"~:id": "~u8611ed3e-43d1-80dc-8005-23069fddf984",
|
||||
"~:layout-justify-items": "~:start",
|
||||
"~:parent-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:layout-align-content": "~:stretch",
|
||||
"~:frame-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:strokes": [],
|
||||
"~:x": 128,
|
||||
"~:proportion": 1,
|
||||
"~:layout-grid-rows": [
|
||||
{
|
||||
"~:type": "~:flex",
|
||||
"~:value": 1
|
||||
},
|
||||
{
|
||||
"~:type": "~:flex",
|
||||
"~:value": 1
|
||||
}
|
||||
],
|
||||
"~:selrect": {
|
||||
"~#rect": {
|
||||
"~:x": 128,
|
||||
"~:y": 128,
|
||||
"~:width": 200,
|
||||
"~:height": 200,
|
||||
"~:x1": 128,
|
||||
"~:y1": 128,
|
||||
"~:x2": 328,
|
||||
"~:y2": 328
|
||||
}
|
||||
},
|
||||
"~:fills": [
|
||||
{
|
||||
"~:fill-color": "#FFFFFF",
|
||||
"~:fill-opacity": 1
|
||||
}
|
||||
],
|
||||
"~:layout-grid-dir": "~:row",
|
||||
"~:flip-x": null,
|
||||
"~:height": 200,
|
||||
"~:flip-y": null,
|
||||
"~:shapes": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"~:id": "~uaf2494d0-39ba-8184-8005-230696f6df5d",
|
||||
"~:name": "Page 1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"~:id": "~ue179d9df-de35-80bf-8005-2861e849b3f7",
|
||||
"~:file-id": "~ue179d9df-de35-80bf-8005-283bbd5516b0",
|
||||
"~:created-at": "~m1729604566293",
|
||||
"~:data": {
|
||||
"~u6ad3e6b9-c5a0-80cf-8005-283bbe38dba8": {
|
||||
"~:id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe38dba8",
|
||||
"~:name": "F",
|
||||
"~:path": "",
|
||||
"~:modified-at": "~m1729604566311",
|
||||
"~:main-instance-id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe378bcc",
|
||||
"~:main-instance-page": "~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||
},
|
||||
"~u6ad3e6b9-c5a0-80cf-8005-283bbe39bb51": {
|
||||
"~:id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe39bb51",
|
||||
"~:name": "E",
|
||||
"~:path": "",
|
||||
"~:modified-at": "~m1729604566311",
|
||||
"~:main-instance-id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe378bcd",
|
||||
"~:main-instance-page": "~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||
},
|
||||
"~u6ad3e6b9-c5a0-80cf-8005-283bbe3a9014": {
|
||||
"~:id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe3a9014",
|
||||
"~:name": "C",
|
||||
"~:path": "",
|
||||
"~:modified-at": "~m1729604566311",
|
||||
"~:main-instance-id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe378bcf",
|
||||
"~:main-instance-page": "~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||
},
|
||||
"~u6ad3e6b9-c5a0-80cf-8005-283bbe3b1793": {
|
||||
"~:id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe3b1793",
|
||||
"~:name": "B",
|
||||
"~:path": "",
|
||||
"~:modified-at": "~m1729604566311",
|
||||
"~:main-instance-id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe378bd0",
|
||||
"~:main-instance-page": "~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||
}
|
||||
}
|
||||
}
|
||||
1864
frontend/playwright/data/workspace/get-file-fragment-9066-2.json
Normal file
1864
frontend/playwright/data/workspace/get-file-fragment-9066-2.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -61,6 +61,7 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
);
|
||||
this.toolbarOptions = page.getByTestId("toolbar-options");
|
||||
this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" });
|
||||
this.boardButton = page.getByRole("button", { name: "Board (B)" });
|
||||
this.toggleToolbarButton = page.getByRole("button", {
|
||||
name: "Toggle toolbar",
|
||||
});
|
||||
@@ -173,13 +174,13 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
}
|
||||
|
||||
async clickLeafLayer(name, clickOptions = {}) {
|
||||
const layer = this.layers.getByText(name);
|
||||
const layer = this.layers.getByText(name).first();
|
||||
await layer.click(clickOptions);
|
||||
}
|
||||
|
||||
async clickToggableLayer(name, clickOptions = {}) {
|
||||
const layer = this.layers
|
||||
.getByTestId("layer-item")
|
||||
.getByTestId("layer-row")
|
||||
.filter({ has: this.page.getByText(name) });
|
||||
await layer.getByRole("button").click(clickOptions);
|
||||
}
|
||||
|
||||
34
frontend/playwright/ui/specs/inspect-layout.spec.js
Normal file
34
frontend/playwright/ui/specs/inspect-layout.spec.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { WorkspacePage } from "../pages/WorkspacePage";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await WorkspacePage.init(page);
|
||||
});
|
||||
|
||||
// Fix for https://tree.taiga.io/project/penpot/issue/9042
|
||||
test("Bug 9042 - Measurement unit dropdowns for columns are cut off in grid layout edit mode", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspacePage = new WorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile(page);
|
||||
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-9042.json");
|
||||
await workspacePage.mockRPC(
|
||||
"get-file-fragment?file-id=*&fragment-id=*",
|
||||
"workspace/get-file-fragment-9042.json",
|
||||
);
|
||||
|
||||
await workspacePage.goToWorkspace({
|
||||
fileId: "af2494d0-39ba-8184-8005-230696f6df5c",
|
||||
pageId: "af2494d0-39ba-8184-8005-230696f6df5d",
|
||||
});
|
||||
await workspacePage.clickLeafLayer("Board");
|
||||
await workspacePage.expectSelectedLayer("Board");
|
||||
|
||||
const layoutContainer = workspacePage.page.getByTestId("inspect-layout");
|
||||
await layoutContainer.getByRole("button", { name: "Edit grid" }).click();
|
||||
const rowsContainer = workspacePage.page.getByTestId("inspect-layout-rows");
|
||||
await rowsContainer.click();
|
||||
|
||||
await rowsContainer.getByText("FR").nth(2).click();
|
||||
await expect(rowsContainer.getByText("%")).toBeInViewport();
|
||||
});
|
||||
@@ -189,3 +189,39 @@ test("Bug 8784 - Use keyboard arrow to move inside a text input does not change
|
||||
|
||||
await expect(workspacePage.pageName).toHaveText("Page 1");
|
||||
});
|
||||
|
||||
test("Bug 9066 - Problem with grid layout", async ({ page }) => {
|
||||
const workspacePage = new WorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile(page);
|
||||
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-9066.json");
|
||||
await workspacePage.mockRPC(
|
||||
"get-file-fragment?file-id=*&fragment-id=e179d9df-de35-80bf-8005-2861e849b3f7",
|
||||
"workspace/get-file-fragment-9066-1.json",
|
||||
);
|
||||
await workspacePage.mockRPC(
|
||||
"get-file-fragment?file-id=*&fragment-id=e179d9df-de35-80bf-8005-2861e849785e",
|
||||
"workspace/get-file-fragment-9066-2.json",
|
||||
);
|
||||
|
||||
await workspacePage.mockRPC(
|
||||
"update-file?id=*",
|
||||
"workspace/update-file-create-rect.json",
|
||||
);
|
||||
|
||||
await workspacePage.goToWorkspace({
|
||||
fileId: "e179d9df-de35-80bf-8005-283bbd5516b0",
|
||||
pageId: "e179d9df-de35-80bf-8005-283bbd5516b1",
|
||||
});
|
||||
|
||||
await workspacePage.clickToggableLayer("Board");
|
||||
await workspacePage.clickToggableLayer("Group");
|
||||
await page.getByText("A", { exact: true }).click();
|
||||
|
||||
await workspacePage.rightSidebar.getByTestId("swap-component-btn").click();
|
||||
|
||||
await page.getByTitle("C", { exact: true }).click();
|
||||
|
||||
await expect(
|
||||
page.getByTestId("children-6ad3e6b9-c5a0-80cf-8005-283bbe378bcb"),
|
||||
).toHaveText(["CBCDEF"]);
|
||||
});
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
|
||||
filter-id-blur (dm/fmt "filter-blur-%" render-id)
|
||||
filter-id-shadows (dm/fmt "filter-shadow-%" render-id)
|
||||
filter-str-blur (filters/filter-str filter-id-blur shape)
|
||||
filter-str-shadows (filters/filter-str filter-id-shadows shape)
|
||||
filter-str-blur (filters/filter-str filter-id-blur (dissoc shape :shadow))
|
||||
filter-str-shadows (filters/filter-str filter-id-shadows (dissoc shape :blur))
|
||||
|
||||
x (dm/get-prop shape :x)
|
||||
y (dm/get-prop shape :y)
|
||||
|
||||
@@ -86,7 +86,8 @@
|
||||
(when (and (:shapes item) expanded?)
|
||||
[:div {:class (stl/css-case
|
||||
:element-children true
|
||||
:parent-selected selected?)}
|
||||
:parent-selected selected?)
|
||||
:data-testid (dm/str "children-" id)}
|
||||
(for [[index id] (reverse (d/enumerate (:shapes item)))]
|
||||
(when-let [item (get objects id)]
|
||||
[:& layer-item
|
||||
|
||||
@@ -29,6 +29,15 @@
|
||||
(def ^:private close-icon
|
||||
(i/icon-xref :close (stl/css :close-icon)))
|
||||
|
||||
(defn icon-url
|
||||
"Creates an sanitizes de icon URL to display"
|
||||
[host icon]
|
||||
(dm/str host
|
||||
(if (and (not (str/ends-with? host "/"))
|
||||
(not (str/starts-with? icon "/")))
|
||||
"/" "")
|
||||
icon))
|
||||
|
||||
(mf/defc plugin-entry
|
||||
[{:keys [index manifest on-open-plugin on-remove-plugin]}]
|
||||
|
||||
@@ -49,7 +58,7 @@
|
||||
[:div {:class (stl/css :plugins-list-element)}
|
||||
[:div {:class (stl/css :plugin-icon)}
|
||||
[:img {:src (if (some? icon)
|
||||
(dm/str host icon)
|
||||
(icon-url host icon)
|
||||
(avatars/generate {:name name}))}]]
|
||||
[:div {:class (stl/css :plugin-description)}
|
||||
[:div {:class (stl/css :plugin-title)} name]
|
||||
@@ -389,7 +398,7 @@
|
||||
[:div {:class (stl/css :modal-title)}
|
||||
[:div {:class (stl/css :plugin-icon)}
|
||||
[:img {:src (if (some? icon)
|
||||
(dm/str host icon)
|
||||
(icon-url host icon)
|
||||
(avatars/generate {:name name}))}]]
|
||||
(tr "workspace.plugins.try-out.title" (str/upper (:name plugin)))]
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ $width-settings-bar-max: $s-500;
|
||||
|
||||
.layers-tab {
|
||||
padding-top: $s-4;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.left-header {
|
||||
|
||||
@@ -386,7 +386,7 @@
|
||||
:element-children true
|
||||
:parent-selected selected?
|
||||
:sticky-children parent-board?)
|
||||
:data-id (when ^boolean parent-board? id)}
|
||||
:data-testid (dm/str "children-" id)}
|
||||
(for [[index id] (reverse (d/enumerate (:shapes item)))]
|
||||
(when-let [item (get objects id)]
|
||||
[:& layer-item
|
||||
|
||||
@@ -617,6 +617,7 @@
|
||||
[:button {:class (stl/css-case :component-name-wrapper true
|
||||
:with-main (and can-swap? (not multi))
|
||||
:swappeable (and can-swap? (not swap-opened?)))
|
||||
:data-testid "swap-component-btn"
|
||||
:on-click open-component-panel}
|
||||
|
||||
[:span {:class (stl/css :component-icon)}
|
||||
|
||||
@@ -776,13 +776,14 @@
|
||||
track-detail (str/join ", " (map manage-values column-values))
|
||||
|
||||
type (if is-column :column :row)
|
||||
testid (when (not is-column) "inspect-layout-rows")
|
||||
|
||||
add-track
|
||||
#(do
|
||||
(when-not expanded? (toggle))
|
||||
(add-new-element type ctl/default-track-value))]
|
||||
|
||||
[:div {:class (stl/css :grid-tracks)}
|
||||
[:div {:class (stl/css :grid-tracks) :data-testid testid}
|
||||
[:div {:class (stl/css :grid-track-header)}
|
||||
[:button {:class (stl/css :expand-icon) :on-click toggle} i/menu]
|
||||
[:div {:class (stl/css :track-title) :on-click toggle}
|
||||
@@ -982,7 +983,7 @@
|
||||
on-hide-dropdown
|
||||
(mf/use-fn #(reset! show-dropdown* false))]
|
||||
|
||||
[:div {:class (stl/css :element-set)}
|
||||
[:div {:class (stl/css :element-set) :data-testid "inspect-layout"}
|
||||
[:div {:class (stl/css :element-title)}
|
||||
[:& title-bar
|
||||
{:collapsable has-layout?
|
||||
@@ -996,6 +997,7 @@
|
||||
(when ^boolean grid-enabled?
|
||||
[:*
|
||||
[:button {:class (stl/css :add-layout)
|
||||
:aria-label "Add"
|
||||
:on-click on-toggle-dropdown-visibility}
|
||||
i/menu]
|
||||
|
||||
|
||||
@@ -150,7 +150,6 @@
|
||||
.grid-layout-menu {
|
||||
@include flexColumn;
|
||||
gap: $s-8;
|
||||
overflow: hidden;
|
||||
|
||||
.row {
|
||||
@include flexRow;
|
||||
@@ -282,7 +281,7 @@
|
||||
}
|
||||
|
||||
.track-title {
|
||||
@include flexColumn;
|
||||
display: grid;
|
||||
flex-grow: 1;
|
||||
padding: $s-8;
|
||||
gap: 0;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.css-cursors :as cur]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.main.ui.workspace.viewport.rulers :as rulers]
|
||||
@@ -56,67 +57,78 @@
|
||||
|
||||
snap-pixel? (mf/deref refs/snap-pixel?)
|
||||
|
||||
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
|
||||
on-pointer-enter
|
||||
(mf/use-callback
|
||||
(mf/deps workspace-read-only?)
|
||||
(fn []
|
||||
(st/emit! (dw/set-hover-guide id true))
|
||||
(swap! state assoc :hover true)))
|
||||
(when-not workspace-read-only?
|
||||
(st/emit! (dw/set-hover-guide id true))
|
||||
(swap! state assoc :hover true))))
|
||||
|
||||
on-pointer-leave
|
||||
(mf/use-callback
|
||||
(mf/deps workspace-read-only?)
|
||||
(fn []
|
||||
(st/emit! (dw/set-hover-guide id false))
|
||||
(swap! state assoc :hover false)))
|
||||
(when-not workspace-read-only?
|
||||
(st/emit! (dw/set-hover-guide id false))
|
||||
(swap! state assoc :hover false))))
|
||||
|
||||
on-pointer-down
|
||||
(mf/use-callback
|
||||
(mf/deps workspace-read-only?)
|
||||
(fn [event]
|
||||
(when (= 0 (.-button event))
|
||||
(dom/capture-pointer event)
|
||||
(mf/set-ref-val! dragging-ref true)
|
||||
(mf/set-ref-val! start-ref (dom/get-client-position event))
|
||||
(mf/set-ref-val! start-pos-ref (get @ms/mouse-position axis)))))
|
||||
(when-not workspace-read-only?
|
||||
(when (= 0 (.-button event))
|
||||
(dom/capture-pointer event)
|
||||
(mf/set-ref-val! dragging-ref true)
|
||||
(mf/set-ref-val! start-ref (dom/get-client-position event))
|
||||
(mf/set-ref-val! start-pos-ref (get @ms/mouse-position axis))))))
|
||||
|
||||
on-pointer-up
|
||||
(mf/use-callback
|
||||
(mf/deps (select-keys @state [:new-position :new-frame-id]) on-guide-change)
|
||||
(mf/deps (select-keys @state [:new-position :new-frame-id]) on-guide-change workspace-read-only?)
|
||||
(fn []
|
||||
(when (some? on-guide-change)
|
||||
(when (some? (:new-position @state))
|
||||
(on-guide-change {:position (:new-position @state)
|
||||
:frame-id (:new-frame-id @state)})))))
|
||||
(when-not workspace-read-only?
|
||||
(when (some? on-guide-change)
|
||||
(when (some? (:new-position @state))
|
||||
(on-guide-change {:position (:new-position @state)
|
||||
:frame-id (:new-frame-id @state)}))))))
|
||||
|
||||
on-lost-pointer-capture
|
||||
(mf/use-callback
|
||||
(mf/deps workspace-read-only?)
|
||||
(fn [event]
|
||||
(dom/release-pointer event)
|
||||
(mf/set-ref-val! dragging-ref false)
|
||||
(mf/set-ref-val! start-ref nil)
|
||||
(mf/set-ref-val! start-pos-ref nil)
|
||||
(swap! state assoc :new-position nil)))
|
||||
(when-not workspace-read-only?
|
||||
(dom/release-pointer event)
|
||||
(mf/set-ref-val! dragging-ref false)
|
||||
(mf/set-ref-val! start-ref nil)
|
||||
(mf/set-ref-val! start-pos-ref nil)
|
||||
(swap! state assoc :new-position nil))))
|
||||
|
||||
on-pointer-move
|
||||
(mf/use-callback
|
||||
(mf/deps position zoom snap-pixel?)
|
||||
(mf/deps position zoom snap-pixel? workspace-read-only?)
|
||||
(fn [event]
|
||||
(when-not workspace-read-only?
|
||||
(when-let [_ (mf/ref-val dragging-ref)]
|
||||
(let [start-pt (mf/ref-val start-ref)
|
||||
start-pos (mf/ref-val start-pos-ref)
|
||||
current-pt (dom/get-client-position event)
|
||||
delta (/ (- (get current-pt axis) (get start-pt axis)) zoom)
|
||||
new-position (if (some? position)
|
||||
(+ position delta)
|
||||
(+ start-pos delta))
|
||||
|
||||
(when-let [_ (mf/ref-val dragging-ref)]
|
||||
(let [start-pt (mf/ref-val start-ref)
|
||||
start-pos (mf/ref-val start-pos-ref)
|
||||
current-pt (dom/get-client-position event)
|
||||
delta (/ (- (get current-pt axis) (get start-pt axis)) zoom)
|
||||
new-position (if (some? position)
|
||||
(+ position delta)
|
||||
(+ start-pos delta))
|
||||
new-position (if snap-pixel?
|
||||
(mth/round new-position)
|
||||
new-position)
|
||||
|
||||
new-position (if snap-pixel?
|
||||
(mth/round new-position)
|
||||
new-position)
|
||||
|
||||
new-frame-id (:id (get-hover-frame))]
|
||||
(swap! state assoc
|
||||
:new-position new-position
|
||||
:new-frame-id new-frame-id)))))]
|
||||
new-frame-id (:id (get-hover-frame))]
|
||||
(swap! state assoc
|
||||
:new-position new-position
|
||||
:new-frame-id new-frame-id))))))]
|
||||
{:on-pointer-enter on-pointer-enter
|
||||
:on-pointer-leave on-pointer-leave
|
||||
:on-pointer-down on-pointer-down
|
||||
@@ -407,7 +419,8 @@
|
||||
on-pointer-move
|
||||
state
|
||||
frame]}
|
||||
(use-guide on-guide-change get-hover-frame zoom {:axis axis})]
|
||||
(use-guide on-guide-change get-hover-frame zoom {:axis axis})
|
||||
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)]
|
||||
|
||||
[:g.new-guides
|
||||
(when-not disabled-guides
|
||||
@@ -422,7 +435,8 @@
|
||||
:on-pointer-up on-pointer-up
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:class (if (= axis :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ns" 0))
|
||||
:class (when-not workspace-read-only?
|
||||
(if (= axis :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ns" 0)))
|
||||
:style {:fill "none"
|
||||
:pointer-events "fill"}}]))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user