mirror of
https://github.com/penpot/penpot.git
synced 2025-06-11 22:01:38 +02:00
♻️ Update button-icon with tooltip component (#6539)
* 🐛 Add tooltip to base icon button * 🎉 Update id prop * 🐛 Fix test
This commit is contained in:
parent
55997a3d4a
commit
a2abaea637
10 changed files with 60 additions and 39 deletions
|
@ -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 }) => {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]]))
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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}]])
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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}]])]))
|
||||
[:> icon-button* {:variant "secondary"
|
||||
:icon "settings"
|
||||
:aria-label "Settings"
|
||||
:on-click open-settings-modal}])]))
|
||||
|
||||
(mf/defc tokens-sidebar-tab*
|
||||
{::mf/wrap [mf/memo]}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue