diff --git a/src/components/Table/GridTable.test.tsx b/src/components/Table/GridTable.test.tsx index 4e698710d..87658fe79 100644 --- a/src/components/Table/GridTable.test.tsx +++ b/src/components/Table/GridTable.test.tsx @@ -1121,6 +1121,23 @@ describe("GridTable", () => { expect(cellOf(r, "customTestId", 0, 0).textContent).toBe("Name"); expect(row(r, 0, "customTestId").textContent).toBe("NameValue"); }); + + it("can use __typename for the kid", async () => { + // Given the table with a column that defines the `kind: data` as an empty cell + type AuthorFragment = { __typename: "Author"; id: string; firstName: string }; + type Row = { kind: "header" } | AuthorFragment; + const nameColumn: GridColumn = { header: () => "Name", author: emptyCell }; + // And a table where the there is an `emptyCell` style specified + const r = await render( + + columns={[nameColumn]} + rows={[simpleHeader, { __typename: "Author", id: "a:1", firstName: "a" }]} + />, + ); + // Then the cell in this column should actually be empty + expect(cell(r, 1, 0)).toBeEmptyDOMElement(); + expect(cell(r, 1, 1).textContent).toBe("1"); + }); }); function Collapse({ id }: { id: string }) { diff --git a/src/components/Table/GridTable.tsx b/src/components/Table/GridTable.tsx index f65972063..febf1bdcf 100644 --- a/src/components/Table/GridTable.tsx +++ b/src/components/Table/GridTable.tsx @@ -24,7 +24,7 @@ import { Css, Margin, Only, Properties, Xss } from "src/Css"; import tinycolor from "tinycolor2"; import { defaultStyle } from "."; -export type Kinded = { kind: string }; +export type Kinded = { kind: string } | { __typename: string }; export type GridTableXss = Xss; export const ASC = "ASC" as const; @@ -721,11 +721,17 @@ function maybeAddCardColumns(sizes: string[], firstLastColumnWidth: number | und export type DiscriminateUnion = T extends Record ? T : never; /** A specific kind of row, including the GridDataRow props. */ -type GridRowKind = DiscriminateUnion & { +type GridRowKind["kind"]> = DiscriminateUnion< + KindOrTypename, + "kind", + P +> & { id: string; children: GridDataRow[]; }; +type KindOrTypename = R extends { __typename: infer T } ? { kind: T } : R; + /** * Defines how a single column will render each given row `kind` in `R`. * @@ -738,9 +744,9 @@ type GridRowKind = DiscriminateUnion = { - [K in R["kind"]]: + [K in KindOrTypename["kind"]]: | string - | (DiscriminateUnion extends { data: infer D } + | (DiscriminateUnion, "kind", K> extends { data: infer D } ? (data: D, row: GridRowKind) => ReactNode | GridCellContent : (row: GridRowKind) => ReactNode | GridCellContent); } & { @@ -783,7 +789,7 @@ type RenderCellFn = ( /** Defines row-specific styling for each given row `kind` in `R` */ export type GridRowStyles = { - [P in R["kind"]]?: RowStyle>; + [P in KindOrTypename["kind"]]?: RowStyle, "kind", P>>; }; export interface RowStyle { @@ -852,15 +858,17 @@ type MaybeFn = T | (() => T); * The presentation concerns instead mainly live in each GridColumn definition, which will format/render * each kind's data for that specific row+column (i.e. cell) combination. */ -export type GridDataRow = { - kind: R["kind"]; - /** Combined with the `kind` to determine a table wide React key. */ - id: string; - /** A list of parent/grand-parent ids for collapsing parent/child rows. */ - children?: GridDataRow[]; - /** Whether to pin this sort to the first/last of its parent's children. */ - pin?: "first" | "last"; -} & DiscriminateUnion; +export type GridDataRow = R extends { kind: any } + ? { + kind: R["kind"]; + /** Combined with the `kind` to determine a table wide React key. */ + id: string; + /** A list of parent/grand-parent ids for collapsing parent/child rows. */ + children?: GridDataRow[]; + /** Whether to pin this sort to the first/last of its parent's children. */ + pin?: "first" | "last"; + } & DiscriminateUnion + : never; interface GridRowProps { as: RenderAs; @@ -896,7 +904,7 @@ function GridRow(props: GridRowProps): ReactElement { // We treat the "header" kind as special for "good defaults" styling const isHeader = row.kind === "header"; - const rowStyle = rowStyles?.[row.kind]; + const rowStyle = rowStyles?.[(row.kind ?? row.__typename) as R]; const rowStyleCellCss = maybeApplyFunction(row, rowStyle?.cellCss); const rowCss = {