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()