Fix table header transparency with opaque background (#18499)

Replace the translucent bg-muted/25 with an opaque color-mix blend
(40% muted on background) to ensure scrolled rows don't show through
the sticky header. Add test coverage for header styling and layout.
This commit is contained in:
Jinjing
2026-09-03 11:16:40 -07:00
committed by GitHub
parent 67e22345da
commit 0f22e1e905
2 changed files with 47 additions and 2 deletions
@@ -0,0 +1,45 @@
// @vitest-environment happy-dom
import { cleanup, render, screen } from '@testing-library/react'
import { afterEach, describe, expect, it } from 'vitest'
import { AutomationListTableHeader } from './AutomationListTableHeader'
import {
LIST_TABLE_HEADER_CLASS,
LIST_TABLE_STICKY_HEADER_CELL_CLASS
} from '@/lib/list-table-layout'
describe('AutomationListTableHeader', () => {
afterEach(cleanup)
it('renders all expected columns', () => {
render(<AutomationListTableHeader />)
expect(screen.getByText('Name')).toBeDefined()
expect(screen.getByText('Schedule')).toBeDefined()
expect(screen.getByText('Project')).toBeDefined()
expect(screen.getByText('Host')).toBeDefined()
expect(screen.getByText('Next run')).toBeDefined()
expect(screen.getByText('Last run')).toBeDefined()
expect(screen.getByText('Status')).toBeDefined()
expect(screen.getByText('Agent')).toBeDefined()
expect(screen.getByText('Actions')).toBeDefined()
})
it('uses opaque background and sticky positioning on the header row', () => {
const { container } = render(<AutomationListTableHeader />)
const header = container.firstElementChild as HTMLElement
expect(header.className).toContain(LIST_TABLE_HEADER_CLASS)
expect(header.className).toContain('sticky')
expect(header.className).toContain('top-0')
expect(header.className).toContain('bg-[color-mix(in_srgb,var(--muted)_40%,var(--background))]')
expect(header.className).not.toContain('bg-muted/25')
})
it('applies sticky cell styling to the first column', () => {
render(<AutomationListTableHeader />)
const nameCell = screen.getByText('Name')
expect(nameCell.className).toBe(LIST_TABLE_STICKY_HEADER_CELL_CLASS)
})
})
+2 -2
View File
@@ -5,9 +5,9 @@
*/
export const LIST_TABLE_CONTAINER_CLASS = 'rounded-md border border-border/50 bg-muted/20'
// Why: z-30 must beat the rows' sticky first cells (z-20) so the header still covers them.
// Why: z-30 and opaque wash ensure scrolled rows cannot show through the sticky header.
export const LIST_TABLE_HEADER_CLASS =
'sticky top-0 z-30 h-8 items-center gap-3 border-b border-border/50 bg-muted/25 px-3 text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground'
'sticky top-0 z-30 h-8 items-center gap-3 border-b border-border/50 bg-[color-mix(in_srgb,var(--muted)_40%,var(--background))] px-3 text-[11px] font-medium uppercase tracking-[0.08em] text-muted-foreground'
// Why: keep keyboard-selected rows clear of the sticky table header.
export const LIST_TABLE_ROW_CLASS =