From 12dd4d19d001d9c3af8f7ee35c483c68cc387d62 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Thu, 29 Oct 2026 18:10:02 +0100 Subject: [PATCH] :recycle: Use a DS icon button for Share in the workspace header (#12681) * :recycle: Use a DS icon button for Share in the workspace header The Share link of the right header becomes an icon-button* with the DS share icon, like its neighbours (comments, history, viewer). It gets keyboard focus, a name and the DS tooltip and hover. It also makes Share visible again on develop: since the share icon moved to currentColor, the legacy icon drew with the transparent color of its svg. The button is 32px wide instead of 28px, so the zoom, comments and history controls move 4px to the left. AI-assisted-by: claude-opus-5-5 * :fire: Remove the share link styles from the workspace header Delete .share-btn and its svg rule, which no markup uses since Share is a DS icon button. refactor/ stays only for the menu placeholders. No visual change (0 px). AI-assisted-by: claude-opus-5-5 --- .../data/workspace/get-teams-shared.json | 25 ++++++++++++++++ .../ui/visual-specs/workspace.spec.js | 24 +++++++++++++++ .../app/main/ui/workspace/right_header.cljs | 10 +++---- .../app/main/ui/workspace/right_header.scss | 29 ++----------------- 4 files changed, 56 insertions(+), 32 deletions(-) create mode 100644 frontend/playwright/data/workspace/get-teams-shared.json diff --git a/frontend/playwright/data/workspace/get-teams-shared.json b/frontend/playwright/data/workspace/get-teams-shared.json new file mode 100644 index 0000000000..2c6119c75f --- /dev/null +++ b/frontend/playwright/data/workspace/get-teams-shared.json @@ -0,0 +1,25 @@ +[ + { + "~: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 + }, + "~:name": "Default", + "~:modified-at": "~m1713533116375", + "~:id": "~uc7ce0794-0992-8105-8004-38e630f7920a", + "~:created-at": "~m1713533116375", + "~:is-default": false + } +] diff --git a/frontend/playwright/ui/visual-specs/workspace.spec.js b/frontend/playwright/ui/visual-specs/workspace.spec.js index d831b30a07..5441abf974 100644 --- a/frontend/playwright/ui/visual-specs/workspace.spec.js +++ b/frontend/playwright/ui/visual-specs/workspace.spec.js @@ -780,6 +780,30 @@ test.describe("Right header", () => { }); }); +test.describe("Share button", () => { + const shot = { maxDiffPixelRatio: 0, threshold: 0 }; + + test("Share button in the right header", async ({ page }) => { + const workspace = new WorkspacePage(page); + await workspace.setupEmptyFile(); + // A shared team where the user is admin, so the header shows Share. + await workspace.mockRPC("get-teams", "workspace/get-teams-shared.json"); + await workspace.goToWorkspace(); + + const header = page.locator('[class*="workspace-header-right"]'); + const share = header + .locator("[class*='share-btn']") + .or(header.getByRole("button", { name: "Share" })); + await expect(share).toBeVisible(); + await page.mouse.move(640, 300); + await expect(header).toHaveScreenshot(shot); + + await share.hover(); + await page.waitForTimeout(1000); + await expect(header).toHaveScreenshot(shot); + }); +}); + test.describe("Undo history", () => { test("Shows the actions list with an entry expanded", async ({ page }) => { const workspace = new WorkspacePage(page); diff --git a/frontend/src/app/main/ui/workspace/right_header.cljs b/frontend/src/app/main/ui/workspace/right_header.cljs index 0b2f9a9b0e..b76ac50fa9 100644 --- a/frontend/src/app/main/ui/workspace/right_header.cljs +++ b/frontend/src/app/main/ui/workspace/right_header.cljs @@ -25,7 +25,6 @@ [app.main.ui.ds.foundations.assets.icon :as i] [app.main.ui.exports.assets :refer [progress-widget]] [app.main.ui.formats :as fmt] - [app.main.ui.icons :as deprecated-icon] [app.main.ui.workspace.presence :refer [active-sessions*]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -239,10 +238,11 @@ :on-click toggle-history}]]) (when display-share-button? - [:a {:class (stl/css :share-btn) - :title (tr "workspace.header.share") - :on-click open-share-dialog} - deprecated-icon/share]) + [:> icon-button* {:variant "action" + :tooltip-placement "bottom-left" + :aria-label (tr "workspace.header.share") + :icon i/share + :on-click open-share-dialog}]) [:> icon-button* {:variant "action" :tooltip-placement "bottom-left" diff --git a/frontend/src/app/main/ui/workspace/right_header.scss b/frontend/src/app/main/ui/workspace/right_header.scss index 040b270490..a67b400537 100644 --- a/frontend/src/app/main/ui/workspace/right_header.scss +++ b/frontend/src/app/main/ui/workspace/right_header.scss @@ -9,8 +9,8 @@ @use "ds/_utils.scss" as *; @use "ds/typography.scss" as *; -// Only for the shared menu placeholders, and the button placeholders of -// the share link until the DS has a share icon. +// Only for the shared menu placeholders (%menu-dropdown, %menu-item-base, +// %shortcut-*), which move with the menus group. @use "refactor/common-refactor.scss" as deprecated; .workspace-header-right { @@ -120,31 +120,6 @@ position: relative; } -// Raw link until the DS has a share icon. -.share-btn { - @extend %button-tertiary; - - border-radius: $br-8; - margin: 0; - inline-size: $sz-28; - block-size: $sz-28; - border: none; - - // The legacy share icon has no class. - svg { - @extend %button-icon; - - block-size: $sz-16; - inline-size: $sz-16; - stroke: var(--color-foreground-secondary); - } - - &:hover { - background-color: transparent; - border: none; - } -} - .unread { position: absolute; inline-size: px2rem(8);