Skip to content

Commit 20f84cb

Browse files
committed
fix(badge): handle all-null/empty arrays in renderBadge and fix hover test
- renderBadge now filters array items and returns placeholder when all values are null or empty strings - Add tests for [null, null] and ["", ""] badge column cases - Change field-renderers test to use user.hover instead of user.click to match the openOnHover popover behavior
1 parent 412c160 commit 20f84cb

3 files changed

Lines changed: 76 additions & 6 deletions

File tree

packages/core/src/components/data-table/cell-renderers.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ function renderDate(value: unknown, options: DateCellOptions | undefined): React
122122
}
123123

124124
function renderBadge(value: unknown, options: BadgeCellOptions | undefined): ReactNode {
125-
if (isEmpty(value) || (Array.isArray(value) && value.length === 0)) return PLACEHOLDER;
125+
const items = Array.isArray(value) ? value : value != null ? [value] : [];
126+
const nonEmpty = items.filter((v) => v != null && v !== "");
127+
if (nonEmpty.length === 0) return PLACEHOLDER;
126128
return <BadgeList value={value} options={options} maxVisible={options?.maxVisible} />;
127129
}
128130

packages/core/src/components/data-table/data-table.test.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,72 @@ describe("DataTable", () => {
774774
expect(container.textContent).toContain("—");
775775
});
776776

777+
it("renders placeholder for array of all-null values in badge column", () => {
778+
const rows = [
779+
{
780+
id: "1",
781+
name: "Item",
782+
tags: [null, null] as (string | null)[],
783+
status: "shipped",
784+
amount: 100,
785+
date: "2026-01-01",
786+
detailUrl: "/items/1",
787+
},
788+
];
789+
function Harness() {
790+
const table = useDataTable<(typeof rows)[number]>({
791+
columns: [
792+
{
793+
label: "Tags",
794+
type: "badge",
795+
accessor: (r) => r.tags as unknown as string[],
796+
},
797+
],
798+
data: { rows },
799+
});
800+
return (
801+
<DataTable.Root value={table}>
802+
<DataTable.Table />
803+
</DataTable.Root>
804+
);
805+
}
806+
const { container } = render(<Harness />, { wrapper });
807+
expect(container.textContent).toContain("—");
808+
});
809+
810+
it("renders placeholder for array of empty strings in badge column", () => {
811+
const rows = [
812+
{
813+
id: "1",
814+
name: "Item",
815+
tags: ["", ""],
816+
status: "shipped",
817+
amount: 100,
818+
date: "2026-01-01",
819+
detailUrl: "/items/1",
820+
},
821+
];
822+
function Harness() {
823+
const table = useDataTable<(typeof rows)[number]>({
824+
columns: [
825+
{
826+
label: "Tags",
827+
type: "badge",
828+
accessor: (r) => r.tags,
829+
},
830+
],
831+
data: { rows },
832+
});
833+
return (
834+
<DataTable.Root value={table}>
835+
<DataTable.Table />
836+
</DataTable.Root>
837+
);
838+
}
839+
const { container } = render(<Harness />, { wrapper });
840+
expect(container.textContent).toContain("—");
841+
});
842+
777843
it("renders link cells with anchor when href is provided", () => {
778844
function RouterWrapper({ children }: { children: ReactNode }) {
779845
return <MemoryRouter>{wrapper({ children })}</MemoryRouter>;

packages/core/src/components/description-card/field-renderers.test.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2-
import { cleanup, render, screen } from "@testing-library/react";
2+
import { cleanup, render, screen, waitFor } from "@testing-library/react";
33
import userEvent from "@testing-library/user-event";
44
import { MemoryRouter } from "react-router";
55
import { createAppShellWrapper } from "../../../tests/test-utils";
@@ -124,7 +124,7 @@ describe("renderField", () => {
124124
expect(container.textContent).not.toContain("+");
125125
});
126126

127-
it("shows overflow badges in popover on click", async () => {
127+
it("shows overflow badges in popover on hover", async () => {
128128
const user = userEvent.setup();
129129
render(
130130
renderField(
@@ -138,10 +138,12 @@ describe("renderField", () => {
138138
);
139139

140140
const trigger = screen.getByText("+2");
141-
await user.click(trigger);
141+
await user.hover(trigger);
142142

143-
expect(screen.getByText("C")).toBeDefined();
144-
expect(screen.getByText("D")).toBeDefined();
143+
await waitFor(() => {
144+
expect(screen.getByText("C")).toBeDefined();
145+
expect(screen.getByText("D")).toBeDefined();
146+
});
145147
});
146148
});
147149

0 commit comments

Comments
 (0)