Place account deletion in its own danger row so it stays separate from routine options.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
adilalloandCursor committed 2026-09-28 15:08:12 -06:00
1 parent 72c51adbb3
commit 89f3e5684d
3 files changed
+38 -51

No files matched your search

@@ -6,6 +6,7 @@ import Rule from "../../../components/cards/Rule";
import TextInput from "../../../components/controls/TextInput"; import TextInput from "../../../components/controls/TextInput";
import List from "../../../components/layout/List"; import List from "../../../components/layout/List";
import type { ListItem, ListSize } from "../../../components/layout/List"; import type { ListItem, ListSize } from "../../../components/layout/List";
import ListEntry from "../../../components/layout/ListEntry";
import Icon from "../../../components/asset/icon"; import Icon from "../../../components/asset/icon";
import Dialog from "../../../components/modals/Dialog"; import Dialog from "../../../components/modals/Dialog";
import Alert from "../../../components/modals/Alert"; import Alert from "../../../components/modals/Alert";
@@ -397,33 +398,24 @@ export function ProfilePageView({
leadingIcon="edit" leadingIcon="edit"
/> />
</nav> </nav>
<section
aria-label={t("deleteAccount")}
className="w-full overflow-hidden rounded-[12px] border border-[var(--color-border-default-negative-primary)] bg-[var(--color-surface-default-negative-secondary)]"
>
<ListEntry
title={t("deleteAccount")}
description=""
showDescription={false}
onClick={onOpenDeleteAccount}
size={profileListSize}
leadingIcon="edit"
variant="danger"
topDivider={false}
bottomDivider={false}
/>
</section>
</section> </section>
</div> </div>
<section
className="flex w-full flex-col items-start gap-3 rounded-[12px] border border-[var(--color-border-default-negative-primary)] bg-[var(--color-surface-default-negative-secondary)] px-4 py-4 lg:px-6 lg:py-6"
aria-labelledby="profile-delete-heading"
>
<h2
id="profile-delete-heading"
className="text-small-label text-[var(--color-content-default-negative-primary)]"
>
{t("deleteAccount")}
</h2>
<p className="max-w-[640px] text-small-paragraph text-[var(--color-content-default-secondary)]">
{t("deleteAccountIntro")}
</p>
<Button
type="button"
size="small"
buttonType="danger"
palette="default"
className="self-start"
onClick={onOpenDeleteAccount}
>
{t("deleteAccountConfirm")}
</Button>
</section>
</div> </div>
</div> </div>
@@ -51,15 +51,8 @@ const ListEntryRow = memo(function ListEntryRow({
? `${layout.title} !text-[var(--color-content-default-negative-primary)]` ? `${layout.title} !text-[var(--color-content-default-negative-primary)]`
: layout.title; : layout.title;
const leadingToneClass = const leadingToneClass = "text-[var(--color-content-default-primary)]";
variant === "danger" const chevronToneClass = "text-[var(--color-content-default-primary)]";
? "text-[var(--color-content-default-negative-primary)]"
: "text-[var(--color-content-default-primary)]";
const chevronToneClass =
variant === "danger"
? "text-[var(--color-content-default-negative-primary)]"
: "text-[var(--color-content-default-primary)]";
const leadingSlot = ( const leadingSlot = (
<div className={`${leadingBoxClass} ${leadingToneClass}`}> <div className={`${leadingBoxClass} ${leadingToneClass}`}>
+19 -17
View File
@@ -69,34 +69,36 @@ function viewProps(
} }
describe("ProfilePageView", () => { describe("ProfilePageView", () => {
test("keeps account deletion out of the routine options list", () => { test("puts delete account in its own danger area", () => {
render(<ProfilePageView {...viewProps()} />); render(<ProfilePageView {...viewProps()} />);
const options = screen.getByRole("navigation", { const options = screen.getByRole("navigation", {
name: copy.yourOptionsHeading, name: copy.yourOptionsHeading,
}); });
const createRule = within(options).getByRole("button", {
name: copy.optionCreateCustom,
});
expect(createRule.closest("ul")).not.toBeNull();
expect( expect(
within(options).queryByRole("button", { name: copy.deleteAccountConfirm }), within(options).getByRole("button", { name: copy.optionCreateCustom }),
).not.toBeInTheDocument(); ).toBeInTheDocument();
expect( expect(
within(options).queryByRole("heading", { name: copy.deleteAccount }), within(options).queryByRole("button", { name: copy.deleteAccount }),
).not.toBeInTheDocument(); ).not.toBeInTheDocument();
expect(screen.queryByText(copy.deleteAccountIntro)).not.toBeInTheDocument();
const danger = screen.getByRole("region", { name: copy.deleteAccount }); const danger = screen.getByRole("region", { name: copy.deleteAccount });
expect(danger).toHaveTextContent(copy.deleteAccountIntro); expect(danger.className).toContain(
const deleteAccount = within(danger).getByRole("button", {
name: copy.deleteAccountConfirm,
});
expect(deleteAccount.closest("ul")).toBeNull();
expect(deleteAccount.className).toContain(
"border-[var(--color-border-default-negative-primary)]", "border-[var(--color-border-default-negative-primary)]",
); );
expect(deleteAccount.className).not.toContain( const deleteAccount = within(danger).getByRole("button", {
"bg-[var(--color-surface-inverse-primary)]", name: copy.deleteAccount,
});
const deleteTitle = within(deleteAccount).getByText(copy.deleteAccount);
expect(deleteTitle.className).toContain(
"!text-[var(--color-content-default-negative-primary)]",
);
expect(deleteAccount.firstElementChild?.className).not.toContain(
"negative-primary",
);
expect(deleteAccount.lastElementChild?.className).not.toContain(
"negative-primary",
); );
}); });
@@ -109,7 +111,7 @@ describe("ProfilePageView", () => {
); );
await user.click( await user.click(
screen.getByRole("button", { name: copy.deleteAccountConfirm }), screen.getByRole("button", { name: copy.deleteAccount }),
); );
expect(onOpenDeleteAccount).toHaveBeenCalledTimes(1); expect(onOpenDeleteAccount).toHaveBeenCalledTimes(1);