From 0fcaf92d678d38a5b110832f588978abfe8eb45e Mon Sep 17 00:00:00 2001 From: Stephen Zhou Date: Tue, 23 Jun 2026 16:10:28 +0800 Subject: [PATCH] fix(web): polish main nav and deployment tooltip styles (#37800) --- .../main-nav/__tests__/skip-nav.spec.tsx | 15 +++++ web/app/components/main-nav/skip-nav.tsx | 2 +- .../__tests__/instance-card-sections.spec.tsx | 64 +++++++++++++++++++ .../list/ui/instance-card-sections.tsx | 2 +- 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 web/app/components/main-nav/__tests__/skip-nav.spec.tsx create mode 100644 web/features/deployments/list/ui/__tests__/instance-card-sections.spec.tsx diff --git a/web/app/components/main-nav/__tests__/skip-nav.spec.tsx b/web/app/components/main-nav/__tests__/skip-nav.spec.tsx new file mode 100644 index 00000000000..3bd072f3c93 --- /dev/null +++ b/web/app/components/main-nav/__tests__/skip-nav.spec.tsx @@ -0,0 +1,15 @@ +import { render, screen } from '@testing-library/react' +import { SkipNav } from '../skip-nav' + +describe('SkipNav', () => { + it('keeps the shadow hidden until the link is visible', () => { + render(Skip to main content) + + const link = screen.getByRole('link', { name: 'Skip to main content' }) + + expect(link).not.toHaveClass('shadow-lg') + expect(link).not.toHaveClass('shadow-shadow-shadow-5') + expect(link).toHaveClass('focus-visible:shadow-lg') + expect(link).toHaveClass('focus-visible:shadow-shadow-shadow-5') + }) +}) diff --git a/web/app/components/main-nav/skip-nav.tsx b/web/app/components/main-nav/skip-nav.tsx index eda7ad4b5f0..6bdb82c6563 100644 --- a/web/app/components/main-nav/skip-nav.tsx +++ b/web/app/components/main-nav/skip-nav.tsx @@ -26,7 +26,7 @@ export function SkipNav({ href={MAIN_CONTENT_HREF} onClick={handleClick} className={cn( - 'fixed top-2 left-2 z-60 inline-flex h-9 -translate-y-[calc(100%+0.75rem)] items-center justify-center rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 system-sm-medium text-components-button-secondary-text shadow-lg shadow-shadow-shadow-5 outline-hidden transition-transform duration-150 focus-visible:translate-y-0 focus-visible:ring-2 focus-visible:ring-state-accent-solid motion-reduce:transition-none', + 'fixed top-2 left-2 z-60 inline-flex h-9 -translate-y-[calc(100%+0.75rem)] items-center justify-center rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 system-sm-medium text-components-button-secondary-text outline-hidden transition-transform duration-150 focus-visible:translate-y-0 focus-visible:shadow-lg focus-visible:ring-2 focus-visible:shadow-shadow-shadow-5 focus-visible:ring-state-accent-solid motion-reduce:transition-none', className, )} {...props} diff --git a/web/features/deployments/list/ui/__tests__/instance-card-sections.spec.tsx b/web/features/deployments/list/ui/__tests__/instance-card-sections.spec.tsx new file mode 100644 index 00000000000..d1bdfbe5c43 --- /dev/null +++ b/web/features/deployments/list/ui/__tests__/instance-card-sections.spec.tsx @@ -0,0 +1,64 @@ +import type { Release } from '@dify/contracts/enterprise/types.gen' +import { ReleaseSource } from '@dify/contracts/enterprise/types.gen' +import { act, fireEvent, render, screen } from '@testing-library/react' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { ReleaseMetaTooltip } from '../instance-card-sections' + +function createRelease(overrides: Partial = {}): Release { + return { + id: 'release-1', + appInstanceId: 'app-instance-1', + displayName: 'Initial release', + description: '', + source: ReleaseSource.RELEASE_SOURCE_SOURCE_APP, + sourceAppId: 'source-app-1', + gateCommitId: 'commit-1', + requiredSlots: [], + createdBy: { + id: 'user-1', + displayName: 'Ada', + }, + createdAt: '2026-01-01T00:00:00.000Z', + ...overrides, + } +} + +function closestWithClass(element: HTMLElement, className: string) { + let current: HTMLElement | null = element + + while (current) { + if (current.classList.contains(className)) + return current + current = current.parentElement + } + + return null +} + +describe('ReleaseMetaTooltip', () => { + beforeEach(() => { + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + + it('should use compact typography for the release metadata preview', async () => { + render( + + + Initial release · 14 days ago + + , + ) + + await act(async () => { + fireEvent.mouseEnter(screen.getByRole('link', { name: 'Initial release · 14 days ago' })) + await vi.advanceTimersByTimeAsync(700) + }) + + const previewValue = screen.getByText('Initial release') + expect(closestWithClass(previewValue, 'min-w-48')).toHaveClass('system-xs-regular') + }) +}) diff --git a/web/features/deployments/list/ui/instance-card-sections.tsx b/web/features/deployments/list/ui/instance-card-sections.tsx index 821ebf63144..77502da39bc 100644 --- a/web/features/deployments/list/ui/instance-card-sections.tsx +++ b/web/features/deployments/list/ui/instance-card-sections.tsx @@ -50,7 +50,7 @@ export function ReleaseMetaTooltip({ release, deployed, children }: { -
+
{rows.map(row => (
{row.label}