♻️ Update button-icon with tooltip component (#6539)

* 🐛 Add tooltip to base icon button

* 🎉 Update id prop

* 🐛 Fix test
This commit is contained in:
Eva Marco 2025-06-05 10:18:56 +02:00 committed by GitHub
parent 55997a3d4a
commit a2abaea637
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 60 additions and 39 deletions

View file

@ -40,6 +40,7 @@ test("Create a LINEAR gradient", async ({ page }) => {
fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374",
pageId: "6191cd35-bb1f-81f7-8004-7cc63d087375",
});
await workspacePage.clickLeafLayer("Rectangle");
const swatch = workspacePage.page.getByRole("button", { name: "#B1B2B5" });
@ -74,17 +75,21 @@ test("Create a LINEAR gradient", async ({ page }) => {
const inputColor2 = workspacePage.colorpicker
.getByPlaceholder("Mixed")
.nth(1);
.nth(2);
await inputColor2.fill("red");
const inputOpacity2 = workspacePage.colorpicker.getByPlaceholder("--").nth(1);
await inputOpacity2.fill("100");
const inputOpacity2 = workspacePage.colorpicker.getByPlaceholder("--").nth(2);
await inputOpacity2.fill("40");
const inputOpacityGlobal = workspacePage.page
.locator("div")
.filter({ hasText: /^FillLinear gradient%$/ })
.getByPlaceholder("--");
await inputOpacityGlobal.fill("100");
const inputOpacityGlobal = workspacePage.colorpicker.getByTestId(
"opacity-global-input",
);
await inputOpacityGlobal.fill("50");
await inputOpacityGlobal.press("Enter");
await expect(inputOpacityGlobal).toHaveValue("50");
await expect(inputOpacityGlobal).toBeVisible();
await expect(workspacePage.page.getByText("Linear gradient")).toBeVisible();
});
test("Create a RADIAL gradient", async ({ page }) => {
@ -147,8 +152,18 @@ test("Create a RADIAL gradient", async ({ page }) => {
const inputColor2 = workspacePage.page.getByPlaceholder("Mixed").nth(2);
await inputColor2.fill("red");
const inputOpacity2 = workspacePage.colorpicker.getByPlaceholder("--").nth(1);
const inputOpacity2 = workspacePage.colorpicker.getByPlaceholder("--").nth(2);
await inputOpacity2.fill("100");
const inputOpacityGlobal = workspacePage.colorpicker.getByTestId(
"opacity-global-input",
);
await inputOpacityGlobal.fill("50");
await inputOpacityGlobal.press("Enter");
await expect(inputOpacityGlobal).toHaveValue("50");
await expect(inputOpacityGlobal).toBeVisible();
await expect(workspacePage.page.getByText("Radial gradient")).toBeVisible();
});
test("Gradient stops limit", async ({ page }) => {

View file

@ -92,7 +92,9 @@ test.describe("Tokens: Tokens Tab", () => {
await setupEmptyTokensFile(page);
const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" });
await tokensTabPanel.getByTitle("Add token: Color").click();
await tokensTabPanel
.getByRole("button", { name: "Add Token: Color" })
.click();
// Create color token with mouse
@ -129,7 +131,9 @@ test.describe("Tokens: Tokens Tab", () => {
// Create token referencing the previous one with keyboard
await tokensTabPanel.getByTitle("Add token: Color").click();
await tokensTabPanel
.getByRole("button", { name: "Add Token: Color" })
.click();
await expect(tokensUpdateCreateModal).toBeVisible();
await nameField.click();
@ -171,7 +175,9 @@ test.describe("Tokens: Tokens Tab", () => {
await setupEmptyTokensFile(page);
const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" });
await tokensTabPanel.getByTitle("Add token: Dimensions").click();
await tokensTabPanel
.getByRole("button", { name: "Add token: Dimensions" })
.click();
await expect(tokensUpdateCreateModal).toBeVisible();
@ -351,7 +357,9 @@ test.describe("Tokens: Tokens Tab", () => {
await setupEmptyTokensFile(page);
const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" });
await tokensTabPanel.getByTitle("Add token: Color").click();
await tokensTabPanel
.getByRole("button", { name: "Add Token: Color" })
.click();
// Create grouped color token with mouse
@ -382,7 +390,9 @@ test.describe("Tokens: Tokens Tab", () => {
await setupEmptyTokensFile(page);
const tokensTabPanel = page.getByRole("tabpanel", { name: "tokens" });
await tokensTabPanel.getByTitle("Add token: Color").click();
await tokensTabPanel
.getByRole("button", { name: "Add Token: Color" })
.click();
await expect(tokensUpdateCreateModal).toBeVisible();
const nameField = tokensUpdateCreateModal.getByLabel("Name");

View file

@ -22,7 +22,7 @@ test("Group bubbles when zooming out if they overlap", async ({ page }) => {
const zoom = page.getByTitle("Zoom");
await zoom.click();
const zoomOut = page.getByTitle("Zoom out");
const zoomOut = page.getByRole("button", { name: "Zoom out" });
await zoomOut.click();
await zoomOut.click();
await zoomOut.click();

View file

@ -18,7 +18,7 @@ test("User haven't toolbar", async ({ page }) => {
});
test("User haven't edition menu entries", async ({ page }) => {
await page.getByTitle("main menu").click();
await page.getByRole("button", { name: "Main menu" }).click();
await page.getByText("file").last().click();
await expect(page.getByText("Add as Shared Library")).toBeHidden();

View file

@ -294,7 +294,7 @@ test("User have edition menu entries", async ({ page }) => {
await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace();
await page.getByTitle("Main menu").click();
await page.getByRole("button", { name: "Main menu" }).click();
await page.getByText("file").last().click();
await expect(page.getByText("Add as Shared Library")).toBeVisible();
@ -390,7 +390,7 @@ test("[Taiga #9930] Zoom fit all doesn't fits all", async ({
const zoom = await page.getByTitle("Zoom");
await zoom.click();
const zoomIn = await page.getByTitle("Zoom in");
const zoomIn = await page.getByRole("button", { name: "Zoom in" });
await zoomIn.click();
await zoomIn.click();
await zoomIn.click();

View file

@ -10,13 +10,13 @@
[app.main.style :as stl])
(:require
[app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]]
[app.main.ui.ds.tooltip.tooltip :refer [tooltip*]]
[rumext.v2 :as mf]))
(def ^:private schema:icon-button
[:map
[:class {:optional true} :string]
[:icon-class {:optional true} :string]
[:tooltip-id {:optional true} :string]
[:icon
[:and :string [:fn #(contains? icon-list %)]]]
[:aria-label :string]
@ -25,18 +25,17 @@
(mf/defc icon-button*
{::mf/schema schema:icon-button}
[{:keys [class icon icon-class variant aria-label children tooltip-id] :rest props}]
[{:keys [class icon icon-class variant aria-label children] :rest props}]
(let [variant (or variant "primary")
tooltip-id (mf/use-id)
class (dm/str class " " (stl/css-case :icon-button true
:icon-button-primary (= variant "primary")
:icon-button-secondary (= variant "secondary")
:icon-button-ghost (= variant "ghost")
:icon-button-action (= variant "action")
:icon-button-destructive (= variant "destructive")))
props (if (some? tooltip-id)
(mf/spread-props props {:class class
:aria-describedby tooltip-id})
(mf/spread-props props {:class class
:aria-label aria-label
:title aria-label}))]
[:> "button" props [:> icon* {:icon-id icon :aria-hidden true :class icon-class}] children]))
props (mf/spread-props props {:class class
:aria-labelledby tooltip-id})]
[:> tooltip* {:tooltip-content aria-label
:id tooltip-id}
[:> "button" props [:> icon* {:icon-id icon :aria-hidden true :class icon-class}] children]]))

View file

@ -42,7 +42,7 @@
"left"
{:top (- (+ trigger-top (/ trigger-height 2) half-arrow-height) (/ tooltip-height 2))
:left (- trigger-left tooltip-width)
:left (- trigger-left tooltip-width arrow-height)
:right (+ (- trigger-left tooltip-width) tooltip-width)
:bottom (+ (- (+ trigger-top (/ trigger-height 2) half-arrow-height) (/ tooltip-height 2)) tooltip-height)
:width tooltip-width
@ -109,7 +109,7 @@
(def ^:private schema:tooltip
[:map
[:class {:optional true} :string]
[:id :string]
[:id {:optional true} :string]
[:offset {:optional true} :int]
[:delay {:optional true} :int]
[:placement {:optional true}
@ -118,7 +118,8 @@
(mf/defc tooltip*
{::mf/schema schema:tooltip}
[{:keys [class id children tooltip-content placement offset delay] :rest props}]
(let [placement* (mf/use-state #(d/nilv placement "top"))
(let [id (or id (mf/use-id))
placement* (mf/use-state #(d/nilv placement "top"))
placement (deref placement*)
delay (d/nilv delay 300)

View file

@ -420,6 +420,7 @@
{:value (-> data :opacity opacity->string)
:on-change handle-change-gradient-opacity
:default 100
:data-testid "opacity-global-input"
:min 0
:max 100}]])

View file

@ -336,7 +336,6 @@
[:> icon-button*
{:variant "ghost"
:aria-label (tr "workspace.options.fit-content")
:title (tr "workspace.options.fit-content")
:on-pointer-down handle-fit-content
:icon "fit-content"}]])
(when (options :size)

View file

@ -26,7 +26,6 @@
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.foundations.typography.text :refer [text*]]
[app.main.ui.ds.tooltip.tooltip :refer [tooltip*]]
[app.main.ui.hooks :as h]
[app.main.ui.hooks.resize :refer [use-resize-hook]]
[app.main.ui.workspace.sidebar.assets.common :as cmm]
@ -424,13 +423,10 @@
(when (contains? cf/flags :token-units)
[:> tooltip* {:tooltip-content "Tokens settings"
:id "button-setting"}
[:> icon-button* {:variant "secondary"
:icon "settings"
:tooltip-id "button-setting"
:aria-label "Settings"
:on-click open-settings-modal}]])]))
:on-click open-settings-modal}])]))
(mf/defc tokens-sidebar-tab*
{::mf/wrap [mf/memo]}