♻️ Use DS buttons in the delete account modal (#12540)

* ♻️ 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

* ♻️ 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

* 🔥 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
This commit is contained in:
Eva Marco 2026-10-26 17:17:46 +01:00 committed by GitHub
parent 376ecda94e
commit 96b62f6475
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 47 deletions

View File

@ -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);
});
});

View File

@ -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")]]]]]))

View File

@ -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;
}
}