mirror of
https://github.com/penpot/penpot.git
synced 2026-10-28 21:40:34 +00:00
♻️ Use DS icons in the copy button (#12558)
* ♻️ Use DS icons in the copy button The shared copy button (Inspect attribute rows and code blocks, share link, integrations) draws its clipboard and tick icons with the DS icons at the small size, colored through the color property. The button itself stays: it wraps whole rows. The icons are the same drawings, so nothing changes on screen. A visual test covers an Inspect computed attribute row and the code block copy button, at rest, on hover and after copying. AI-assisted-by: claude-opus-5-5 * ♻️ Move copy button styles off the deprecated styles The copy button stylesheet no longer imports refactor/: the button-style, flex-center and copy-wrapper-base mixins are inlined with DS values, the tertiary button and icon color aliases resolve to their DS tokens, and physical properties become logical ones. No visual change (whole viewer visual spec compared; the code tab syntax highlighting loads late on a cold first run, with either stylesheet). AI-assisted-by: claude-opus-5-5
This commit is contained in:
parent
8800ff4bc9
commit
112e6dedd7
@ -395,3 +395,50 @@ test.describe("Interactions menu", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Copy buttons", () => {
|
||||
const shot = { maxDiffPixelRatio: 0, threshold: 0 };
|
||||
|
||||
const openInspectTab = async (page, name) => {
|
||||
const viewerPage = new ViewerPage(page);
|
||||
await viewerPage.setupLoggedInUser();
|
||||
await viewerPage.setupFileWithComments();
|
||||
await viewerPage.goToViewer({
|
||||
fileId: singleBoardFileId,
|
||||
pageId: singleBoardPageId,
|
||||
});
|
||||
await viewerPage.showCode();
|
||||
await page.getByRole("combobox").filter({ hasText: "Styles" }).click();
|
||||
await page.getByRole("option", { name }).click();
|
||||
};
|
||||
|
||||
test("Computed attribute rows", async ({ page }) => {
|
||||
await openInspectTab(page, "Computed");
|
||||
const row = page.locator("[class*='copy-wrapper']").first();
|
||||
await expect(row).toBeVisible();
|
||||
await page.mouse.move(10, 700);
|
||||
await expect(row).toHaveScreenshot(shot);
|
||||
|
||||
await row.hover();
|
||||
await expect(row).toHaveScreenshot(shot);
|
||||
|
||||
await row.click();
|
||||
await expect(row).toHaveAttribute("data-active", "true");
|
||||
await expect(row).toHaveScreenshot(shot);
|
||||
});
|
||||
|
||||
test("Code block copy button", async ({ page }) => {
|
||||
await openInspectTab(page, "Code");
|
||||
const copy = page.locator("[class*='css-copy-btn']");
|
||||
await expect(copy).toBeVisible();
|
||||
await page.mouse.move(10, 700);
|
||||
await expect(copy).toHaveScreenshot(shot);
|
||||
|
||||
await copy.hover();
|
||||
await expect(copy).toHaveScreenshot(shot);
|
||||
|
||||
await copy.click();
|
||||
await expect(copy).toHaveAttribute("data-active", "true");
|
||||
await expect(copy).toHaveScreenshot(shot);
|
||||
});
|
||||
});
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.event :as-alias ev]
|
||||
[app.main.ui.icons :as deprecated-icon]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||
[app.util.clipboard :as clipboard]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
@ -43,6 +43,6 @@
|
||||
:on-click on-click}
|
||||
children
|
||||
[:span {:class (stl/css :icon-btn)}
|
||||
(if active?
|
||||
deprecated-icon/tick
|
||||
deprecated-icon/clipboard)]]))
|
||||
[:> icon* {:icon-id (if active? i/tick i/clipboard)
|
||||
:size "s"
|
||||
:class (stl/css :icon)}]]]))
|
||||
|
||||
@ -4,89 +4,95 @@
|
||||
//
|
||||
// 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 *;
|
||||
|
||||
.copy-button {
|
||||
@include deprecated.button-style;
|
||||
|
||||
width: 100%;
|
||||
height: deprecated.$s-32;
|
||||
border: deprecated.$s-1 solid transparent;
|
||||
border-radius: deprecated.$br-8;
|
||||
border: $b-1 solid transparent;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
inline-size: 100%;
|
||||
block-size: $sz-32;
|
||||
border-radius: $br-8;
|
||||
background-color: transparent;
|
||||
box-sizing: border-box;
|
||||
|
||||
.icon-btn {
|
||||
@include deprecated.flex-center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
block-size: $sz-32;
|
||||
min-inline-size: $sz-28;
|
||||
inline-size: $sz-28;
|
||||
|
||||
height: deprecated.$s-32;
|
||||
min-width: deprecated.$s-28;
|
||||
width: deprecated.$s-28;
|
||||
|
||||
svg {
|
||||
@extend %button-icon-small;
|
||||
|
||||
stroke: var(--icon-foreground);
|
||||
.icon {
|
||||
flex-shrink: 0;
|
||||
stroke-width: 1.33px;
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-tertiary);
|
||||
color: var(--color-foreground-primary);
|
||||
border: deprecated.$s-1 solid var(--color-background-tertiary);
|
||||
border: $b-1 solid var(--color-background-tertiary);
|
||||
|
||||
.icon-btn {
|
||||
svg {
|
||||
stroke: var(--button-tertiary-foreground-color-active);
|
||||
}
|
||||
.icon-btn .icon {
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
outline: none;
|
||||
border: deprecated.$s-1 solid var(--button-tertiary-border-color-focus);
|
||||
border: $b-1 solid var(--color-accent-primary);
|
||||
background-color: transparent;
|
||||
color: var(--button-tertiary-foreground-color-focus);
|
||||
color: var(--color-foreground-primary);
|
||||
|
||||
.icon-btn svg {
|
||||
stroke: var(--button-tertiary-foreground-color-active);
|
||||
.icon-btn .icon {
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.copy-wrapper {
|
||||
@include deprecated.button-style;
|
||||
@include deprecated.copy-wrapper-base;
|
||||
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
text-align: left;
|
||||
border: deprecated.$s-1 solid transparent;
|
||||
position: relative;
|
||||
min-block-size: $sz-32;
|
||||
inline-size: 100%;
|
||||
block-size: fit-content;
|
||||
padding: px2rem(7) 0 px2rem(7) px2rem(7);
|
||||
border: $b-1 solid transparent;
|
||||
border-radius: $br-8;
|
||||
background: none;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
text-align: start;
|
||||
|
||||
.icon-btn {
|
||||
@include deprecated.flex-center;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: deprecated.$s-32;
|
||||
width: deprecated.$s-28;
|
||||
inset-block-start: 0;
|
||||
inset-inline-end: 0;
|
||||
block-size: $sz-32;
|
||||
inline-size: $sz-28;
|
||||
|
||||
svg {
|
||||
@extend %button-icon-small;
|
||||
|
||||
stroke: var(--button-tertiary-foreground-color-focus);
|
||||
.icon {
|
||||
flex-shrink: 0;
|
||||
stroke-width: 1.33px;
|
||||
color: var(--color-foreground-primary);
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--button-tertiary-background-color-focus);
|
||||
color: var(--button-tertiary-foreground-color-focus);
|
||||
border: deprecated.$s-1 solid var(--button-tertiary-background-color-focus);
|
||||
background-color: var(--color-background-tertiary);
|
||||
color: var(--color-foreground-primary);
|
||||
border: $b-1 solid var(--color-background-tertiary);
|
||||
|
||||
.icon-btn svg {
|
||||
.icon-btn .icon {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
@ -94,8 +100,8 @@
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
outline: none;
|
||||
border: deprecated.$s-1 solid var(--button-tertiary-border-color-focus);
|
||||
border: $b-1 solid var(--color-accent-primary);
|
||||
background-color: transparent;
|
||||
color: var(--button-tertiary-foreground-color-focus);
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user