Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions packages/module/src/SkeletonTableHead/SkeletonTableHead.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
import { render } from '@testing-library/react';
import SkeletonTableHead from './SkeletonTableHead';
import { Table } from '@patternfly/react-table';
import { Table, Th } from '@patternfly/react-table';

describe('SkeletonTableHead component', () => {
it('should render correctly with count', () => {
expect(render(<Table><SkeletonTableHead columnsCount={2} isSelectable isExpandable /></Table>)).toMatchSnapshot();
});

it('should render correctly with count', () => {
it('should render correctly with string columns', () => {
expect(render(<Table><SkeletonTableHead columns={[ 'First', 'Second' ]} isTreeTable isSelectable /></Table>)).toMatchSnapshot();
});

it('should render correctly with Th element columns without nesting', () => {
const { container } = render(
<Table>
<SkeletonTableHead
columns={[
<Th key="1" sort={{ columnIndex: 0, sortBy: {} }}>First</Th>,
<Th key="2" sort={{ columnIndex: 1, sortBy: {} }}>Second</Th>
]}
/>
</Table>
);

// Ensure there are no nested <th> elements
const theadCells = container.querySelectorAll('thead th');
theadCells.forEach(th => {
const nestedTh = th.querySelector('th');
expect(nestedTh).toBeNull();
});

expect(container).toMatchSnapshot();
});
});
33 changes: 25 additions & 8 deletions packages/module/src/SkeletonTableHead/SkeletonTableHead.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FunctionComponent } from 'react';
import { ReactNode, useMemo } from 'react';
import type { FunctionComponent, ReactElement } from 'react';
import { ReactNode, useMemo, isValidElement } from 'react';
import {
Th,
ThProps,
Expand All @@ -10,6 +10,8 @@ import { Skeleton } from '@patternfly/react-core';

export const isThObject = (value: ReactNode | { cell: ReactNode; props?: ThProps }): value is { cell: ReactNode; props?: ThProps } => value != null && typeof value === 'object' && 'cell' in value;

export const isReactElement = (value: ReactNode): value is ReactElement => isValidElement(value);

export interface SkeletonTableHeadProps {
/** Custom columns for the table */
columns?: (ReactNode | { cell: ReactNode; props?: ThProps })[];
Expand Down Expand Up @@ -41,18 +43,33 @@ export const SkeletonTableHead: FunctionComponent<SkeletonTableHeadProps> = ({
...(isExpandable ? [ <Th key="row-expand" screenReaderText='Data expansion table header cell' /> ] : []),
...(isSelectable && !isTreeTable ? [ <Th key="row-select" screenReaderText='Data selection table header cell' /> ] : []),
...(hasCustomColumns ? (
columns.map((column, index) => (
<Th key={index} {...(isThObject(column) && column?.props)} data-ouia-component-id={`${ouiaId}-th-${index}`}>
{isThObject(column) ? column.cell : column}
</Th>
))
columns.map((column, index) => {
// If the column is an object with cell and props, wrap in Th
if (isThObject(column)) {
return (
<Th key={index} {...column.props} data-ouia-component-id={`${ouiaId}-th-${index}`}>
{column.cell}
</Th>
);
}
// If the column is already a React element (like <Th>), render it directly
if (isReactElement(column)) {
return column;
}
// Otherwise, wrap the content in Th
return (
<Th key={index} data-ouia-component-id={`${ouiaId}-th-${index}`}>
{column}
</Th>
);
})
) : (
[ ...Array(rowCellsCount) ].map((_, index) => (
<Th key={index} data-ouia-component-id={`${ouiaId}-th-${index}`}>
<Skeleton />
</Th>
))
))
))
]
, [ hasCustomColumns, isExpandable, isSelectable, isTreeTable, columns, rowCellsCount, ouiaId ]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,104 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`SkeletonTableHead component should render correctly with Th element columns without nesting 1`] = `
<div>
<table
class="pf-v6-c-table pf-m-grid-md"
data-ouia-component-id="OUIA-Generated-Table-3"
data-ouia-component-type="PF6/Table"
data-ouia-safe="true"
role="grid"
>
<thead
class="pf-v6-c-table__thead"
data-ouia-component-id="SkeletonTableHeader-thead"
>
<tr
class="pf-v6-c-table__tr"
data-ouia-component-id="SkeletonTableHeader-tr-head"
data-ouia-component-type="PF6/TableRow"
data-ouia-safe="true"
>
<th
class="pf-v6-c-table__th pf-v6-c-table__sort"
scope="col"
tabindex="-1"
>
<button
class="pf-v6-c-table__button"
type="button"
>
<div
class="pf-v6-c-table__button-content"
>
<span
class="pf-v6-c-table__text"
>
First
</span>
<span
class="pf-v6-c-table__sort-indicator"
>
<svg
aria-hidden="true"
class="pf-v6-svg"
fill="currentColor"
height="1em"
role="img"
viewBox="0 0 256 512"
width="1em"
>
<path
d="M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z"
/>
</svg>
</span>
</div>
</button>
</th>
<th
class="pf-v6-c-table__th pf-v6-c-table__sort"
scope="col"
tabindex="-1"
>
<button
class="pf-v6-c-table__button"
type="button"
>
<div
class="pf-v6-c-table__button-content"
>
<span
class="pf-v6-c-table__text"
>
Second
</span>
<span
class="pf-v6-c-table__sort-indicator"
>
<svg
aria-hidden="true"
class="pf-v6-svg"
fill="currentColor"
height="1em"
role="img"
viewBox="0 0 256 512"
width="1em"
>
<path
d="M214.059 377.941H168V134.059h46.059c21.382 0 32.09-25.851 16.971-40.971L144.971 7.029c-9.373-9.373-24.568-9.373-33.941 0L24.971 93.088c-15.119 15.119-4.411 40.971 16.971 40.971H88v243.882H41.941c-21.382 0-32.09 25.851-16.971 40.971l86.059 86.059c9.373 9.373 24.568 9.373 33.941 0l86.059-86.059c15.12-15.119 4.412-40.971-16.97-40.971z"
/>
</svg>
</span>
</div>
</button>
</th>
</tr>
</thead>
</table>
</div>
`;

exports[`SkeletonTableHead component should render correctly with count 1`] = `
{
"asFragment": [Function],
Expand Down Expand Up @@ -203,7 +302,7 @@ exports[`SkeletonTableHead component should render correctly with count 1`] = `
}
`;

exports[`SkeletonTableHead component should render correctly with count 2`] = `
exports[`SkeletonTableHead component should render correctly with string columns 1`] = `
{
"asFragment": [Function],
"baseElement": <body>
Expand Down
Loading