From 96b62f6475697b9fe7919c46ed17b353ed52598b Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Mon, 26 Oct 2026 17:17:46 +0100 Subject: [PATCH] :recycle: Use DS buttons in the delete account modal (#12540) * :recycle: Use DS buttons in the delete account modal The close button of the delete account modal becomes a ghost DS icon button named "Close"; the class that places it goes on the tooltip wrapper. The cancel and delete buttons become DS secondary and destructive buttons, so their labels no longer wrap and the delete button takes the DS destructive red. The delete button keeps its test id. A visual test covers the modal at rest and with the close and delete buttons hovered. AI-assisted-by: claude-opus-5-5 * :recycle: Move delete account modal styles closer to the DS The delete account stylesheet resolves its legacy sizes, spacing, mixins and color aliases to DS tokens and uses logical properties and the DS typography module without a namespace. The legacy uppercase title becomes the DS headline-small typography, which differs only in its size (12px instead of 11px), so the title and the content below sit 1px lower. The organization counts used a fixed dark-theme gray; they now use the themed DS secondary foreground. Two unused selectors are commented out with a TODO. refactor/ stays only for the modal placeholders (%modal-*), which move with the modals refactor. AI-assisted-by: claude-opus-5-5 * :fire: Remove unused styles from the delete account modal The SCSS refactor of the delete account modal left rules commented out with a TODO because the module does not use them, or because they target an svg inside a DS icon that is the svg itself. CSS modules scope the classes to this module and no other source uses them, so they go: .fields-row, .select-title. No visual change. AI-assisted-by: claude-opus-5-5 --- .../ui/visual-specs/visual-dashboard.spec.js | 20 +++++++ .../app/main/ui/settings/delete_account.cljs | 23 ++++--- .../app/main/ui/settings/delete_account.scss | 60 +++++++------------ 3 files changed, 56 insertions(+), 47 deletions(-) diff --git a/frontend/playwright/ui/visual-specs/visual-dashboard.spec.js b/frontend/playwright/ui/visual-specs/visual-dashboard.spec.js index 3b783793f6..1b2ce0d483 100644 --- a/frontend/playwright/ui/visual-specs/visual-dashboard.spec.js +++ b/frontend/playwright/ui/visual-specs/visual-dashboard.spec.js @@ -317,3 +317,23 @@ test("User goes to the team settings section", async ({ page }) => { await expect(page.getByText("TEAM INFO")).toBeVisible(); await expect(dashboardPage.page).toHaveScreenshot(); }); + +test.describe("Delete account modal", () => { + const shot = { maxDiffPixelRatio: 0, threshold: 0 }; + + test("Delete account modal buttons", async ({ page }) => { + await page.goto("/?screen=settings-profile"); + await page.getByText("Want to remove your account?").click(); + + const modal = page.locator("[class*='modal-container']"); + await expect(page.getByTestId("delete-account-btn")).toBeVisible(); + await page.mouse.move(10, 700); + await expect(modal).toHaveScreenshot(shot); + + await modal.locator("[class*='modal-header'] button").hover(); + await expect(modal).toHaveScreenshot(shot); + + await page.getByTestId("delete-account-btn").hover(); + await expect(modal).toHaveScreenshot(shot); + }); +}); diff --git a/frontend/src/app/main/ui/settings/delete_account.cljs b/frontend/src/app/main/ui/settings/delete_account.cljs index 678ff29f20..b916734729 100644 --- a/frontend/src/app/main/ui/settings/delete_account.cljs +++ b/frontend/src/app/main/ui/settings/delete_account.cljs @@ -14,8 +14,9 @@ [app.main.repo :as rp] [app.main.store :as st] [app.main.ui.components.organization-avatar :refer [organization-avatar*]] + [app.main.ui.ds.buttons.button :refer [button*]] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.foundations.assets.icon :as i :refer [icon*]] - [app.main.ui.icons :as deprecated-icon] [app.main.ui.notifications.context-notification :refer [context-notification]] [app.util.i18n :as i18n :refer [tr]] [beicon.v2.core :as rx] @@ -62,8 +63,11 @@ [:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)} (tr "modals.delete-account.title")] - [:button {:class (stl/css :modal-close-btn) - :on-click modal/hide!} deprecated-icon/close]] + [:> icon-button* {:variant "ghost" + :tooltip-class (stl/css :modal-close-btn) + :aria-label (tr "labels.close") + :icon i/close + :on-click modal/hide!}]] [:div {:class (stl/css :modal-content)} [:div {:class (stl/css :warning-notice)} @@ -100,11 +104,12 @@ [:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :action-buttons)} - [:button {:class (stl/css :cancel-button) - :on-click modal/hide!} + [:> button* {:variant "secondary" + :type "button" + :on-click modal/hide!} (tr "modals.delete-account.cancel")] - [:button {:class (stl/css-case :accept-button true - :danger true) - :on-click on-accept - :data-testid "delete-account-btn"} + [:> button* {:variant "destructive" + :type "button" + :on-click on-accept + :data-testid "delete-account-btn"} (tr "modals.delete-account.confirm")]]]]])) diff --git a/frontend/src/app/main/ui/settings/delete_account.scss b/frontend/src/app/main/ui/settings/delete_account.scss index 4d0c1efafc..f27a48c7a4 100644 --- a/frontend/src/app/main/ui/settings/delete_account.scss +++ b/frontend/src/app/main/ui/settings/delete_account.scss @@ -4,8 +4,10 @@ // // Copyright (c) KALEIDOS SUBSIDIARY SL +// refactor/ stays for the modal placeholders (%modal-*), which move with +// the modals refactor. @use "refactor/common-refactor.scss" as deprecated; -@use "ds/typography.scss" as t; +@use "ds/typography.scss" as *; @use "ds/spacing.scss" as *; @use "ds/_sizes.scss" as *; @use "ds/_utils.scss" as *; @@ -19,54 +21,48 @@ display: flex; flex-direction: column; - min-width: deprecated.$s-408; + min-inline-size: px2rem(408); } .modal-header { - margin-bottom: deprecated.$s-24; + margin-block-end: var(--sp-xxl); } .modal-title { - @include deprecated.uppercase-title-typography; + @include use-typography("headline-small"); - color: var(--modal-title-foreground-color); + color: var(--color-foreground-primary); } +// Tooltip wrapper of the close button: it places it in the corner. .modal-close-btn { - @extend %modal-close-btn-base; + position: absolute; + inset-block-start: var(--sp-s); + inset-inline-end: var(--sp-xs); } .modal-content { - @include deprecated.flex-column; - @include deprecated.body-small-typography; + @include use-typography("body-small"); + display: flex; + flex-direction: column; flex: 1 1 auto; - min-height: 0; - gap: deprecated.$s-24; - margin-bottom: deprecated.$s-24; + min-block-size: 0; + gap: var(--sp-xxl); + margin-block-end: var(--sp-xxl); } .warning-notice { flex-shrink: 0; } -.fields-row { - @include deprecated.flex-column; -} - -.select-title { - @include deprecated.body-small-typography; - - color: var(--modal-title-foreground-color); -} - .organizations-section { - @include t.use-typography("body-medium"); + @include use-typography("body-medium"); display: flex; flex-direction: column; flex: 1 1 auto; - min-height: 0; + min-block-size: 0; gap: var(--sp-l); } @@ -98,7 +94,7 @@ display: flex; flex-direction: column; flex: 1 1 auto; - min-height: 0; + min-block-size: 0; gap: var(--sp-l); margin: 0; padding: 0; @@ -119,28 +115,16 @@ } .organization-name { - color: var(--modal-title-foreground-color); + color: var(--color-foreground-primary); } .organization-counts { display: flex; flex-direction: row; gap: var(--sp-s); - color: var(--df-secondary); + color: var(--color-foreground-secondary); } .action-buttons { @extend %modal-action-btns; } - -.cancel-button { - @extend %modal-cancel-btn; -} - -.accept-button { - @extend %modal-accept-btn; - - &.danger { - @extend %modal-danger-btn; - } -}