Copy token name from contextual menu (#8566)

This commit is contained in:
Xaviju
2026-03-19 23:22:44 +01:00
committed by GitHub
parent 8ad62c6800
commit ee1dd80b6e
5 changed files with 41 additions and 16 deletions

View File

@@ -17,6 +17,7 @@
- Add copy as image to clipboard option to workspace context menu (by @dfelinto) [Github #8313](https://github.com/penpot/penpot/pull/8313)
- Add Tab/Shift+Tab navigation to rename layers sequentially (by @bittoby) [Github #8474](https://github.com/penpot/penpot/pull/8474)
- Rename token group [Taiga #13137](https://tree.taiga.io/project/penpot/us/13137)
- Copy token name from contextual menu [Taiga #13568](https://tree.taiga.io/project/penpot/issue/13568)
### :bug: Bugs fixed

View File

@@ -84,8 +84,9 @@ test.describe("Tokens: Apply token", () => {
await brTokenPillSM.click();
// Change token from dropdown
const brTokenOptionXl = borderRadiusSection
.getByRole("option", { name: "borderRadius.xl" });
const brTokenOptionXl = borderRadiusSection.getByRole("option", {
name: "borderRadius.xl",
});
await expect(brTokenOptionXl).toBeVisible();
await brTokenOptionXl.click();
@@ -151,7 +152,9 @@ test.describe("Tokens: Apply token", () => {
await detachButton.click();
// Open dropdown from input
const dropdownBtn = layerMenuSection.getByRole('button', { name: 'Open token list' })
const dropdownBtn = layerMenuSection.getByRole("button", {
name: "Open token list",
});
await expect(dropdownBtn).toBeVisible();
await dropdownBtn.click();
@@ -227,8 +230,12 @@ test.describe("Tokens: Apply token", () => {
await expect(firstShadowFields).toBeVisible();
// Fill in the shadow values
const offsetXInput = firstShadowFields.getByRole('textbox', { name: 'X' });
const offsetYInput = firstShadowFields.getByRole('textbox', { name: 'Y' });
const offsetXInput = firstShadowFields.getByRole("textbox", {
name: "X",
});
const offsetYInput = firstShadowFields.getByRole("textbox", {
name: "Y",
});
const blurInput = firstShadowFields.getByRole("textbox", {
name: "Blur",
});
@@ -301,8 +308,12 @@ test.describe("Tokens: Apply token", () => {
await expect(thirdShadowFields).toBeVisible();
// User adds values for the third shadow
const thirdOffsetXInput = thirdShadowFields.getByRole('textbox', { name: 'X' });
const thirdOffsetYInput = thirdShadowFields.getByRole('textbox', { name: 'Y' });
const thirdOffsetXInput = thirdShadowFields.getByRole("textbox", {
name: "X",
});
const thirdOffsetYInput = thirdShadowFields.getByRole("textbox", {
name: "Y",
});
const thirdBlurInput = thirdShadowFields.getByRole("textbox", {
name: "Blur",
});
@@ -330,10 +341,10 @@ test.describe("Tokens: Apply token", () => {
// Verify that the first shadow kept its values
const firstOffsetXValue = await firstShadowFields
.getByRole('textbox', { name: 'X' })
.getByRole("textbox", { name: "X" })
.inputValue();
const firstOffsetYValue = await firstShadowFields
.getByRole('textbox', { name: 'Y' })
.getByRole("textbox", { name: "Y" })
.inputValue();
const firstBlurValue = await firstShadowFields
.getByRole("textbox", { name: "Blur" })
@@ -359,10 +370,10 @@ test.describe("Tokens: Apply token", () => {
await expect(newSecondShadowFields).toBeVisible();
const secondOffsetXValue = await newSecondShadowFields
.getByRole('textbox', { name: 'X' })
.getByRole("textbox", { name: "X" })
.inputValue();
const secondOffsetYValue = await newSecondShadowFields
.getByRole('textbox', { name: 'Y' })
.getByRole("textbox", { name: "Y" })
.inputValue();
const secondBlurValue = await newSecondShadowFields
.getByRole("textbox", { name: "Blur" })
@@ -412,10 +423,10 @@ test.describe("Tokens: Apply token", () => {
// Verify first shadow values are still there
const restoredFirstOffsetX = await firstShadowFields
.getByRole('textbox', { name: 'X' })
.getByRole("textbox", { name: "X" })
.inputValue();
const restoredFirstOffsetY = await firstShadowFields
.getByRole('textbox', { name: 'Y' })
.getByRole("textbox", { name: "Y" })
.inputValue();
const restoredFirstBlur = await firstShadowFields
.getByRole("textbox", { name: "Blur" })
@@ -435,10 +446,10 @@ test.describe("Tokens: Apply token", () => {
// Verify second shadow values are still there
const restoredSecondOffsetX = await newSecondShadowFields
.getByRole('textbox', { name: 'X' })
.getByRole("textbox", { name: "X" })
.inputValue();
const restoredSecondOffsetY = await newSecondShadowFields
.getByRole('textbox', { name: 'Y' })
.getByRole("textbox", { name: "Y" })
.inputValue();
const restoredSecondBlur = await newSecondShadowFields
.getByRole("textbox", { name: "Blur" })
@@ -616,7 +627,7 @@ test.describe("Tokens: Apply token", () => {
await tokensSidebar
.getByRole("button", { name: "dimension.sm" })
.click({ button: "right" });
await tokenContextMenuForToken.getByText("Y").click();
await tokenContextMenuForToken.getByText("Y", { exact: true }).click();
// Check if measures sections is visible on right sidebar
const measuresSection = page.getByRole("region", {

View File

@@ -20,6 +20,7 @@
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
[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]]
[app.util.timers :as timers]
@@ -333,6 +334,7 @@
(defn default-actions [{:keys [token selected-token-set-id on-delete-token]}]
(let [{:keys [modal]} (dwta/get-token-properties token)
on-copy-name #(clipboard/to-clipboard (:name token))
on-duplicate-token #(st/emit! (dwtl/duplicate-token (:id token)))]
[{:title (tr "workspace.tokens.edit")
:no-selectable true
@@ -350,6 +352,9 @@
{:title (tr "workspace.tokens.duplicate")
:no-selectable true
:action on-duplicate-token}
{:title (tr "workspace.tokens.copy-name")
:no-selectable true
:action on-copy-name}
{:title (tr "workspace.tokens.delete")
:no-selectable true
:action #(on-delete-token token)}]))

View File

@@ -7955,6 +7955,10 @@ msgstr "Delete theme"
msgid "workspace.tokens.duplicate"
msgstr "Duplicate token"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:350
msgid "workspace.tokens.copy-name"
msgstr "Copy token path"
#: src/app/main/data/workspace/tokens/library_edit.cljs:240, src/app/main/data/workspace/tokens/library_edit.cljs:509
msgid "workspace.tokens.duplicate-suffix"
msgstr "copy"

View File

@@ -7866,6 +7866,10 @@ msgstr "Borrar theme"
msgid "workspace.tokens.duplicate"
msgstr "Duplicar token"
#: src/app/main/ui/workspace/tokens/management/context_menu.cljs:350
msgid "workspace.tokens.copy-name"
msgstr "Copiar ruta de token"
#: src/app/main/data/workspace/tokens/library_edit.cljs:240, src/app/main/data/workspace/tokens/library_edit.cljs:509
msgid "workspace.tokens.duplicate-suffix"
msgstr "copiar"