♻️ Use DS buttons in the delete shared libraries modal (#12554)

* ♻️ Use DS buttons in the delete shared libraries modal

The delete shared libraries modal (unpublish a library, delete a shared
file or project) gets a ghost DS icon button named "Close", placed on
the tooltip wrapper, and DS buttons for cancel (secondary) and accept
(destructive for the danger style, primary otherwise) instead of raw
inputs. The buttons are narrower and the accept button takes the DS
destructive red.

A new empty library references fixture and a visual test cover the
unpublish library modal from the workspace main menu.

AI-assisted-by: claude-opus-5-5

* ♻️ Move delete shared libraries modal styles closer to the DS

The delete shared libraries stylesheet resolves its legacy modal color
aliases to DS tokens, uses a logical property and the DS typography
module without a namespace. refactor/ stays only for the modal
placeholders (%modal-*), which move with the modals refactor. Two
unused selectors are commented out with a TODO. No visual change.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the delete shared libraries modal

The SCSS refactor of the delete shared libraries 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: &.transparent, .list-wrapper. No visual change.

AI-assisted-by: claude-opus-5-5
This commit is contained in:
Eva Marco 2026-10-27 10:20:11 +01:00 committed by GitHub
parent e4c1b154e3
commit 411f661bdb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 44 deletions

View File

@ -1077,3 +1077,32 @@ test.describe("Export modal", () => {
});
});
});
test.describe("Unpublish library modal", () => {
test("Shows the close, cancel and unpublish buttons", async ({ page }) => {
const shot = { maxDiffPixelRatio: 0, threshold: 0 };
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "workspace/get-file-library.json");
await workspace.mockRPC(
"get-library-file-references?file-id=*",
"workspace/get-library-file-references-empty.json",
);
await workspace.goToWorkspace({
fileId: "c1249a66-fce0-8175-8004-7433fe4be8bc",
pageId: "c1249a66-fce0-8175-8004-7433fe4be8bd",
});
await page.getByRole("button", { name: "Main menu" }).click();
await page.locator("#file-menu-file").click();
await page.locator("#file-menu-remove-shared").click();
const modal = page.locator("[class*='delete_shared__modal-container']");
await expect(modal).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);
});
});

View File

@ -11,8 +11,10 @@
[app.main.data.modal :as modal]
[app.main.repo :as rp]
[app.main.store :as st]
[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]
[app.main.ui.ds.notifications.context-notification :refer [context-notification*]]
[app.main.ui.icons :as deprecated-icon]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as k]
@ -97,8 +99,11 @@
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
[:h2 {:class (stl/css :modal-title)} title]
[:button {:class (stl/css :modal-close-btn)
:on-click cancel-fn} deprecated-icon/close]]
[:> icon-button* {:variant "ghost"
:tooltip-class (stl/css :modal-close-btn)
:aria-label (tr "labels.close")
:icon i/close
:on-click cancel-fn}]]
[:div {:class (stl/css :modal-content)}
(when (and (string? subtitle) (not= subtitle ""))
@ -124,14 +129,12 @@
[:div {:class (stl/css :modal-footer)}
[:div {:class (stl/css :action-buttons)}
(when-not (= cancel-label :omit)
[:input {:class (stl/css :cancel-button)
:type "button"
:value cancel-label
:on-click cancel-fn}])
[:> button* {:variant "secondary"
:type "button"
:on-click cancel-fn}
cancel-label])
[:input {:class (stl/css-case :accept-btn true
:danger (= accept-style :danger)
:primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]]))
[:> button* {:variant (if (= accept-style :danger) "destructive" "primary")
:type "button"
:on-click accept-fn}
accept-label]]]]]))

View File

@ -4,15 +4,13 @@
//
// Copyright (c) KALEIDOS SUBSIDIARY SL
// refactor/ stays for the modal placeholders (%modal-*), which move with
// the modals refactor.
@use "refactor/basic-rules.scss" as *;
@use "ds/typography.scss" as t;
@use "ds/typography.scss" as *;
.modal-overlay {
@extend %modal-overlay-base;
&.transparent {
background-color: transparent;
}
}
.modal-container {
@ -23,33 +21,30 @@
grid-template-rows: auto minmax(0, 1fr) auto;
}
.list-wrapper {
display: grid;
grid-template-rows: auto 1fr auto;
max-height: 100%;
}
.modal-title {
@include t.use-typography("headline-medium");
@include use-typography("headline-medium");
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 t.use-typography("body-small");
@include use-typography("body-small");
display: grid;
gap: var(--sp-s);
}
.element-list {
@include t.use-typography("body-large");
@include use-typography("body-large");
color: var(--modal-text-foreground-color);
color: var(--color-foreground-secondary);
overflow-y: auto;
margin-block: 0;
}
@ -58,18 +53,6 @@
@extend %modal-action-btns;
}
.cancel-button {
@extend %modal-cancel-btn;
}
.accept-btn {
@extend %modal-accept-btn;
&.danger {
@extend %modal-danger-btn;
}
}
.modal-scd-msg {
margin-block: 0;
}
@ -77,8 +60,8 @@
.modal-scd-msg,
.modal-subtitle,
.modal-msg {
@include t.use-typography("body-large");
@include use-typography("body-large");
color: var(--modal-text-foreground-color);
color: var(--color-foreground-secondary);
line-height: 1.5;
}