From a9205df3b2feed38ea41d6bc58aac8d67d3c1411 Mon Sep 17 00:00:00 2001
From: linshen <32978552+linshenkx@users.noreply.github.com>
Date: Mon, 6 Apr 2026 22:26:29 +0800
Subject: [PATCH] fix(ui): make multi-image remove action explicit
---
.../image-mode/ImageMultiImageWorkspace.vue | 44 ++++++++++++-------
.../image-multiimage-input-guards.spec.ts | 24 ++++++++++
2 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/packages/ui/src/components/image-mode/ImageMultiImageWorkspace.vue b/packages/ui/src/components/image-mode/ImageMultiImageWorkspace.vue
index b1815f5c..e3b467dc 100644
--- a/packages/ui/src/components/image-mode/ImageMultiImageWorkspace.vue
+++ b/packages/ui/src/components/image-mode/ImageMultiImageWorkspace.vue
@@ -150,17 +150,6 @@
:alt="`图${index + 1}`"
object-fit="cover"
/>
-
- ×
-
@@ -1820,19 +1822,31 @@ onUnmounted(() => {
.image-card__footer:active {
cursor: grabbing;
}
+.image-card__actions {
+ display: inline-flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 6px;
+ min-width: 0;
+}
.image-card__drag-handle {
display: inline-flex;
align-items: center;
justify-content: center;
- min-width: 20px;
- height: 20px;
+ min-width: 22px;
+ height: 24px;
color: var(--n-text-color-2);
line-height: 1;
font-size: 14px;
letter-spacing: -1px;
}
.image-card__label { flex: 1; min-width: 0; text-align: left; }
-.image-card__remove { position: absolute; top: 6px; right: 6px; z-index: 1; background: var(--n-color); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12); }
+.image-card__remove {
+ flex-shrink: 0;
+ min-width: 44px;
+ padding-inline: 10px;
+ border-radius: 999px;
+}
.image-upload-card { width: 116px; min-height: 140px; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 8px; padding: 8px; border: 1px dashed var(--n-border-color); border-radius: 14px; background: var(--n-color-embedded); color: var(--n-text-color-2); cursor: pointer; appearance: none; font: inherit; text-align: center; transition: border-color 0.18s ease, box-shadow 0.18s ease, color 0.18s ease, transform 0.18s ease; }
.image-upload-card:hover { border-color: var(--n-border-color-hover); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.05); transform: translateY(-1px); }
.image-upload-card:focus-visible { outline: none; border-color: var(--n-primary-color); box-shadow: 0 0 0 2px var(--n-primary-color-suppl); }
diff --git a/packages/ui/tests/unit/image/image-multiimage-input-guards.spec.ts b/packages/ui/tests/unit/image/image-multiimage-input-guards.spec.ts
index 9bf67896..28966c8f 100644
--- a/packages/ui/tests/unit/image/image-multiimage-input-guards.spec.ts
+++ b/packages/ui/tests/unit/image/image-multiimage-input-guards.spec.ts
@@ -47,6 +47,30 @@ describe('image multiimage input UI guards', () => {
expect(source).not.toMatch(/preview-disabled/)
})
+ it('keeps an explicit remove action in the card footer instead of relying on a tiny preview overlay', () => {
+ const source = readWorkspaceSource()
+
+ expect(source).toMatch(/class="image-card__actions"/)
+ expect(source).toMatch(/class="image-card__remove"/)
+ expect(source).toMatch(/:aria-label="`删除图\$\{index \+ 1\}`"/)
+
+ const previewWrapIndex = source.indexOf('class="image-card__preview-wrap"')
+ const removeIndex = source.indexOf('class="image-card__remove"')
+ const footerIndex = source.indexOf('class="image-card__footer"')
+ const actionsIndex = source.indexOf('class="image-card__actions"')
+
+ expect(previewWrapIndex).toBeGreaterThan(-1)
+ expect(removeIndex).toBeGreaterThan(-1)
+ expect(footerIndex).toBeGreaterThan(-1)
+ expect(actionsIndex).toBeGreaterThan(-1)
+ expect(footerIndex).toBeGreaterThan(previewWrapIndex)
+ expect(removeIndex).toBeGreaterThan(footerIndex)
+ expect(removeIndex).toBeGreaterThan(actionsIndex)
+
+ const previewSegment = source.slice(previewWrapIndex, footerIndex)
+ expect(previewSegment).not.toContain('class="image-card__remove"')
+ })
+
it('splits the left pane into an input card and a fill-height optimized prompt workspace', () => {
const source = readWorkspaceSource()