fix(issues): keep pinned table cells opaque

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
Lambda
2026-07-16 03:17:33 +08:00
parent 4cee38cec0
commit f414a2de5c
2 changed files with 59 additions and 5 deletions

View File

@@ -223,7 +223,8 @@ export function DataTable<TData>({
// content scrolling beneath them and follow row hover state.
className={cn(
"overflow-hidden px-4 py-2",
isPinned && "bg-background group-hover:bg-muted/50",
isPinned &&
"bg-background group-hover:bg-[color-mix(in_oklab,var(--muted)_50%,var(--background))]",
)}
style={getCellStyle(cell.column, {
withBorder: true,
@@ -293,12 +294,14 @@ export function DataTable<TData>({
// exceeds column.size. Tooltip / dropdown /
// hover-card bodies are portaled, so they are
// unaffected.
// Pinned header cell uses muted/30 so it blends
// into the header strip rather than appearing as
// a white block under sticky scroll.
// Pinned cells must be opaque: translucent backgrounds
// reveal horizontally scrolled columns underneath. Mix
// muted with background to preserve the same visual tone
// as muted/30 without introducing alpha.
className={cn(
"relative h-8 overflow-hidden px-4 py-2 text-xs uppercase tracking-wider text-muted-foreground",
isPinned && "bg-muted/30 backdrop-blur",
isPinned &&
"bg-[color-mix(in_oklab,var(--muted)_30%,var(--background))]",
)}
style={getCellStyle(header.column, {
withBorder: true,

View File

@@ -0,0 +1,51 @@
import { render, screen } from "@testing-library/react";
import {
getCoreRowModel,
useReactTable,
type ColumnDef,
} from "@tanstack/react-table";
import { describe, expect, it } from "vitest";
import { DataTable } from "@multica/ui/components/ui/data-table";
type Row = {
title: string;
status: string;
};
const columns: ColumnDef<Row>[] = [
{ accessorKey: "title", header: "Issue" },
{ accessorKey: "status", header: "Status" },
];
function PinnedTable() {
const table = useReactTable({
data: [{ title: "Pinned title", status: "In progress" }],
columns,
getCoreRowModel: getCoreRowModel(),
state: { columnPinning: { left: ["title"], right: [] } },
});
return <DataTable table={table} />;
}
describe("DataTable pinned columns", () => {
it("uses opaque backgrounds so scrolled columns cannot show through", () => {
render(<PinnedTable />);
const titleHeader = screen.getByRole("columnheader", { name: /^Issue/ });
const titleCell = screen.getByRole("cell", { name: "Pinned title" });
const statusCell = screen.getByRole("cell", { name: "In progress" });
expect(titleHeader).toHaveClass(
"bg-[color-mix(in_oklab,var(--muted)_30%,var(--background))]",
);
expect(titleHeader).not.toHaveClass("bg-muted/30", "backdrop-blur");
expect(titleCell).toHaveClass(
"bg-background",
"group-hover:bg-[color-mix(in_oklab,var(--muted)_50%,var(--background))]",
);
expect(titleCell).not.toHaveClass("group-hover:bg-muted/50");
expect(titleCell).toHaveStyle({ position: "sticky", zIndex: 1 });
expect(statusCell).not.toHaveStyle({ position: "sticky" });
});
});