mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-26 12:35:35 +02:00
#4288 swapped the chip cap from a fixed `max-w-72` to `max-w-[min(18rem,100%)]`. A percentage max-width on a flex item is dropped while its flex-container wrapper (`<a class="inline-flex">`) computes its own max-content size, so the wrapper ballooned to the untruncated title width while the chip truncated to the cap — leaving an empty, clickable strip after the visible chip. Fix it as standard atomic-inline behavior instead of a fixed magic cap: - IssueChip caps at `max-w-full` with the title truncating to an ellipsis, so it wraps to the next line as a unit and only truncates once a whole line can't hold it. - Drop `inline-flex` from the editor NodeView `<a>` (issue + project) and the markdown AppLink so the chip's only wrapper is a plain inline box with a definite (line-based) percentage basis — no second flex container to balloon. ProjectChip uses a definite `max-w-72`, so it never hit the gap; left as-is. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
import { render, screen } from "@testing-library/react";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { IssueChip } from "./issue-chip";
|
|
|
|
vi.mock("@tanstack/react-query", () => ({
|
|
useQuery: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("@multica/core/hooks", () => ({
|
|
useWorkspaceId: () => "workspace-1",
|
|
}));
|
|
|
|
vi.mock("@multica/core/issues/queries", () => ({
|
|
issueListOptions: () => ({ queryKey: ["issues"] }),
|
|
issueDetailOptions: (_workspaceId: string, issueId: string) => ({
|
|
queryKey: ["issue", issueId],
|
|
}),
|
|
}));
|
|
|
|
vi.mock("./status-icon", () => ({
|
|
StatusIcon: ({ className }: { className?: string }) => (
|
|
<svg data-testid="status-icon" className={className} />
|
|
),
|
|
}));
|
|
|
|
const mockUseQuery = vi.mocked(useQuery);
|
|
|
|
describe("IssueChip", () => {
|
|
beforeEach(() => {
|
|
mockUseQuery.mockImplementation((options: { queryKey?: readonly unknown[] }) => {
|
|
if (options.queryKey?.[0] === "issues") {
|
|
return {
|
|
data: [
|
|
{
|
|
id: "issue-1",
|
|
identifier: "MUL-3405",
|
|
title: "A very long issue title that should stay inside a narrow chat bubble",
|
|
status: "todo",
|
|
},
|
|
],
|
|
} as ReturnType<typeof useQuery>;
|
|
}
|
|
return { data: undefined } as ReturnType<typeof useQuery>;
|
|
});
|
|
});
|
|
|
|
it("caps the chip to its parent container and truncates the title", () => {
|
|
render(<IssueChip issueId="issue-1" />);
|
|
|
|
const chip = screen.getByText("MUL-3405").closest(".issue-mention");
|
|
expect(chip).toHaveClass("min-w-0", "max-w-full");
|
|
expect(screen.getByText("A very long issue title that should stay inside a narrow chat bubble"))
|
|
.toHaveClass("min-w-0", "truncate");
|
|
});
|
|
|
|
it("truncates unresolved fallback labels inside the chip width", () => {
|
|
render(
|
|
<IssueChip
|
|
issueId="missing-issue"
|
|
fallbackLabel="MUL-999999999999999999999999999999999"
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByText("MUL-999999999999999999999999999999999"))
|
|
.toHaveClass("min-w-0", "truncate");
|
|
});
|
|
});
|