Skip to content

Commit a441bae

Browse files
committed
Make SkeletonTable modular (#352)
* feat(skeleton): Refactor SkeletonTable to be modular * feat(skeleton): Add new SkeletonTable docs * feat(skeleton): Enhance cypress tests
1 parent f6dc8f6 commit a441bae

24 files changed

+1161
-173
lines changed

cypress/component/SkeletonTable.cy.tsx

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,73 @@
11
import React from 'react';
2-
import { RowSelectVariant, Th } from '@patternfly/react-table';
3-
import SkeletonTable from '../../packages/module/dist/dynamic/SkeletonTable';
2+
import { RowSelectVariant } from '@patternfly/react-table';
3+
import SkeletonTable from '@patternfly/react-component-groups/dist/dynamic/SkeletonTable';
44

55
describe('SkeletonTable', () => {
66
beforeEach(() => {
77
cy.viewport(1600, 800);
88
});
99

1010
it('renders SkeletonTable', () => {
11-
const SkeletonTableExample = <SkeletonTable rows={10} columns={[ 'first', 'second' ]} />;
11+
const SkeletonTableExample = <SkeletonTable rowsCount={10} columns={[ 'First', 'Second' ]} />;
1212
cy.mount(SkeletonTableExample);
1313
cy.get('table').should('exist');
14-
cy.get('table thead tr').should('have.text', 'firstsecond');
14+
cy.get('table thead tr th').eq(0).should('have.text', 'First');
15+
cy.get('table thead tr th').eq(1).should('have.text', 'Second');
1516
});
1617

1718
it ('can be used without passing columns', () => {
18-
const SkeletonTableExample = <SkeletonTable rows={10} numberOfColumns={2} />;
19+
const SkeletonTableExample = <SkeletonTable rowsCount={10} columnsCount={2} />;
1920
cy.mount(SkeletonTableExample);
2021
cy.get('table').should('exist');
2122
cy.get('table thead tr').should('have.text', '');
2223
});
2324

2425
it('contains checkboxes when passed isSelectable', () => {
25-
const SkeletonTableExample = <SkeletonTable rows={10} columns={[ 'first', 'second' ]} isSelectable />;
26+
const SkeletonTableExample = <SkeletonTable rowsCount={10} columns={[ 'First', 'Second' ]} isSelectable />;
2627
cy.mount(SkeletonTableExample);
2728
cy.get('table').should('exist');
28-
cy.get('table thead tr').should('have.text', 'firstsecond');
29+
cy.get('table thead tr th').eq(0).should('have.text', 'Data selection table header cell');
30+
cy.get('table thead tr th').eq(1).should('have.text', 'First');
31+
cy.get('table thead tr th').eq(2).should('have.text', 'Second');
2932
cy.get('input[type="checkbox"]').should('have.length', 10);
3033
});
3134

3235
it('is expandable when passed isExpandable', () => {
33-
const SkeletonTableExample = <SkeletonTable rows={10} columns={[ 'first', 'second' ]} isExpandable />;
36+
const SkeletonTableExample = <SkeletonTable rowsCount={10} columns={[ 'First', 'Second' ]} isExpandable />;
3437
cy.mount(SkeletonTableExample);
3538
cy.get('table').should('exist');
36-
cy.get('table thead tr').should('have.text', 'firstsecond');
39+
cy.get('table thead tr th').eq(0).should('have.text', 'Data expansion table header cell');
40+
cy.get('table thead tr th').eq(1).should('have.text', 'First');
41+
cy.get('table thead tr th').eq(2).should('have.text', 'Second');
3742
cy.get('.pf-v6-c-table__toggle-icon').should('have.length', 10);
3843
});
3944

4045
it('can be passed a selectVariant to render radio buttons', () => {
41-
const SkeletonTableExample = <SkeletonTable rows={10} columns={[ 'first', 'second' ]} isSelectable selectVariant={RowSelectVariant.radio} />;
46+
const SkeletonTableExample = <SkeletonTable rowsCount={10} columns={[ 'First', 'Second' ]} isSelectable selectVariant={RowSelectVariant.radio} />;
4247
cy.mount(SkeletonTableExample);
4348
cy.get('table').should('exist');
44-
cy.get('table thead tr').should('have.text', 'firstsecond');
49+
cy.get('table thead tr th').eq(0).should('have.text', 'Data selection table header cell');
50+
cy.get('table thead tr th').eq(1).should('have.text', 'First');
51+
cy.get('table thead tr th').eq(2).should('have.text', 'Second');
4552
cy.get('input[type="radio"]').should('have.length', 10);
4653
});
4754

48-
it('can be passed custom columns', () => {
55+
it('can be passed custom columns props', () => {
4956
const SkeletonTableExample = (
5057
<SkeletonTable
5158
rows={10}
52-
columns={[
53-
<Th key="1" sort={{ columnIndex: 0, sortBy: { index: 0, direction: 'asc' } }}>
54-
first
55-
</Th>,
56-
<Th key="2">second</Th>,
57-
<Th key="3">third</Th>
59+
columns={[
60+
{ cell: 'first', props: { sort: { columnIndex: 0, sortBy: { index: 0, direction: 'asc' } } } },
61+
{ cell: 'second' },
62+
{ cell: 'third' }
5863
]}
5964
/>
6065
);
6166
cy.mount(SkeletonTableExample);
6267
cy.get('table').should('exist');
63-
cy.get('table thead tr').should('have.text', 'firstsecondthird');
68+
cy.get('table thead tr th').eq(0).should('have.text', 'first');
69+
cy.get('table thead tr th').eq(1).should('have.text', 'second');
70+
cy.get('table thead tr th').eq(2).should('have.text', 'third');
6471
cy.get('.pf-v6-c-table__sort-indicator').eq(0).find('path').should(
6572
'have.attr',
6673
'd',
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
import { RowSelectVariant } from '@patternfly/react-table';
3+
import SkeletonTableBody from '@patternfly/react-component-groups/dist/dynamic/SkeletonTableBody';
4+
5+
describe('SkeletonTableBody', () => {
6+
beforeEach(() => {
7+
cy.viewport(1600, 800);
8+
});
9+
10+
it('renders SkeletonTableBody', () => {
11+
const SkeletonTableExample = <SkeletonTableBody rowsCount={10} columnsCount={2} />;
12+
cy.mount(SkeletonTableExample);
13+
cy.get('div[class="pf-v5-c-skeleton"]').should('have.length', 20);
14+
});
15+
16+
it('contains checkboxes when passed isSelectable', () => {
17+
cy.mount(<SkeletonTableBody rowsCount={10} columnsCount={2} isSelectable />);
18+
cy.get('input[type="checkbox"]').should('have.length', 10);
19+
});
20+
21+
it('is expandable when passed isExpandable', () => {
22+
cy.mount(<SkeletonTableBody rowsCount={10} columnsCount={2} isExpandable />);
23+
cy.get('.pf-v5-c-table__toggle-icon').should('have.length', 10);
24+
});
25+
26+
it('can be passed a selectVariant to render radio buttons', () => {
27+
cy.mount(<SkeletonTableBody rowsCount={10} columnsCount={2} isSelectable selectVariant={RowSelectVariant.radio} />);
28+
cy.get('input[type="radio"]').should('have.length', 10);
29+
});
30+
});
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import React from 'react';
2+
import { Table } from '@patternfly/react-table';
3+
import { SkeletonTableHead } from '@patternfly/react-component-groups/dist/dynamic/SkeletonTableHead';
4+
5+
describe('SkeletonTableHead', () => {
6+
beforeEach(() => {
7+
cy.viewport(1600, 800);
8+
});
9+
10+
it('renders SkeletonTable with custom columns', () => {
11+
const SkeletonTableExample = (
12+
<Table>
13+
<SkeletonTableHead columns={[ 'First', 'Second' ]} />
14+
</Table>
15+
);
16+
cy.mount(SkeletonTableExample);
17+
cy.get('table thead tr th').eq(0).should('have.text', 'First');
18+
cy.get('table thead tr th').eq(1).should('have.text', 'Second');
19+
});
20+
21+
it('renders SkeletonTable with column count but no custom columns', () => {
22+
const SkeletonTableExample = (
23+
<Table>
24+
<SkeletonTableHead columnsCount={2} />
25+
</Table>
26+
);
27+
cy.mount(SkeletonTableExample);
28+
cy.get('table thead tr th').should('have.length', 2);
29+
cy.get('table thead tr th').each((th) => {
30+
cy.wrap(th).find('.pf-v5-c-skeleton').should('exist');
31+
});
32+
});
33+
34+
it('renders SkeletonTable with selectable column', () => {
35+
const SkeletonTableExample = (
36+
<Table>
37+
<SkeletonTableHead columns={[ 'First' ]} isSelectable />
38+
</Table>
39+
);
40+
cy.mount(SkeletonTableExample);
41+
cy.get('table thead tr th').should('have.length', 2);
42+
cy.get('table thead tr th').eq(0).should('have.text', 'Data selection table header cell');
43+
});
44+
45+
it('renders SkeletonTable with expandable column', () => {
46+
const SkeletonTableExample = (
47+
<Table>
48+
<SkeletonTableHead columns={[ 'First' ]} isExpandable />
49+
</Table>
50+
);
51+
cy.mount(SkeletonTableExample);
52+
cy.get('table thead tr th').should('have.length', 2);
53+
cy.get('table thead tr th').eq(0).should('have.text', 'Data expansion table header cell');
54+
});
55+
56+
it('renders SkeletonTable with selectable and expandable columns', () => {
57+
const SkeletonTableExample = (
58+
<Table>
59+
<SkeletonTableHead columns={[ 'First', 'Second' ]} isSelectable isExpandable />
60+
</Table>
61+
);
62+
cy.mount(SkeletonTableExample);
63+
cy.get('table thead tr th').should('have.length', 4);
64+
});
65+
66+
it('renders SkeletonTable with custom ouiaId', () => {
67+
const customOuiaId = 'CustomOuia';
68+
const SkeletonTableExample = (
69+
<Table>
70+
<SkeletonTableHead columns={[ 'First', 'Second' ]} ouiaId={customOuiaId} />
71+
</Table>
72+
);
73+
cy.mount(SkeletonTableExample);
74+
cy.get('thead').should('have.attr', 'data-ouia-component-id', `${customOuiaId}-thead`);
75+
cy.get('th').each((th, index) => {
76+
cy.wrap(th).should('have.attr', 'data-ouia-component-id', `${customOuiaId}-th-${index}`);
77+
});
78+
});
79+
80+
it('handles no columns and no columnsCount', () => {
81+
const SkeletonTableExample = (
82+
<Table>
83+
<SkeletonTableHead />
84+
</Table>
85+
);
86+
cy.mount(SkeletonTableExample);
87+
cy.get('table thead tr th').should('have.length', 1);
88+
});
89+
});

packages/module/patternfly-docs/content/extensions/component-groups/examples/SkeletonTable/SkeletonTable.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ id: Skeleton table
1010
source: react
1111
# If you use typescript, the name of the interface to display props for
1212
# These are found through the sourceProps function provided in patternfly-docs.source.js
13-
propComponents: ['SkeletonTable']
14-
sourceLink: https://github.com/patternfly/react-component-groups/blob/main/packages/module/patternfly-docs/content/extensions/component-groups/examples/Skeleton/Skeleton.md
13+
propComponents: ['SkeletonTable', 'SkeletonTableHead', 'SkeletonTableBody']
14+
sourceLink: https://github.com/patternfly/react-component-groups/blob/main/packages/module/patternfly-docs/content/extensions/component-groups/examples/SkeletonTable/SkeletonTable.md
1515
---
16-
import { useCallback, useEffect } from 'react';
16+
import { RowSelectVariant, TableVariant, Table } from '@patternfly/react-table';
1717
import SkeletonTable from '@patternfly/react-component-groups/dist/dynamic/SkeletonTable';
18+
import SkeletonTableHead from '@patternfly/react-component-groups/dist/dynamic/SkeletonTableHead';
19+
import SkeletonTableBody from '@patternfly/react-component-groups/dist/dynamic/SkeletonTableBody';
1820

1921
The **skeleton table** component is used to display placeholder "skeletons" within a table as its contents load.
2022

@@ -70,3 +72,19 @@ To simulate this loading process, click the "Reload table" button and wait for t
7072
```js file="./SkeletonTableLoadingExample.tsx"
7173

7274
```
75+
76+
### Skeleton table head
77+
78+
You can render only the `<Thead>` part of the skeleton table by using the `<SkeletonTableHead/>`.
79+
80+
```js file="./SkeletonTableHeadExample.tsx"
81+
82+
```
83+
84+
### Skeleton table body
85+
86+
You can also render only the `<Tbody>` part of the skeleton table by using the `<SkeletonTableBody/>`.
87+
88+
```js file="./SkeletonTableBodyExample.tsx"
89+
90+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react';
2+
import { Table } from '@patternfly/react-table';
3+
import SkeletonTableBody from "@patternfly/react-component-groups/dist/dynamic/SkeletonTableBody";
4+
5+
export const SkeletonTableBodyExample: React.FC = () => (
6+
<Table>
7+
<SkeletonTableBody isSelectable rowsCount={5} columnsCount={2} />
8+
</Table>
9+
);

packages/module/patternfly-docs/content/extensions/component-groups/examples/SkeletonTable/SkeletonTableCompactExample.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ import React from 'react';
22
import SkeletonTable from "@patternfly/react-component-groups/dist/dynamic/SkeletonTable";
33
import { TableVariant } from '@patternfly/react-table';
44

5-
export const SkeletonTableExample: React.FC = () => <SkeletonTable rows={10} columns={[ 'first', 'second' ]} variant={TableVariant.compact} borders={false} />;
5+
export const SkeletonTableExample: React.FC = () => <SkeletonTable rowsCount={10} columns={[ 'First', 'Second' ]} variant={TableVariant.compact} borders={false} />;

packages/module/patternfly-docs/content/extensions/component-groups/examples/SkeletonTable/SkeletonTableCustomExample.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import React from 'react';
2-
import SkeletonTable from "@patternfly/react-component-groups/dist/dynamic/SkeletonTable";
3-
import { Th } from '@patternfly/react-table';
2+
import SkeletonTable from "@patternfly/react-component-groups/dist/dynamic/SkeletonTable";import { Th } from '@patternfly/react-table';
43

54
export const SkeletonTableExample: React.FC = () => (
65
<SkeletonTable
7-
rows={10}
6+
rowsCount={10}
87
columns={[
98
<Th key="1" sort={{ columnIndex: 0, sortBy: {} }}>
10-
first
9+
First
1110
</Th>,
1211
<Th key="2" sort={{ columnIndex: 1, sortBy: {} }}>
13-
second
12+
Second
1413
</Th>
1514
]}
1615
/>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import React from 'react';
22
import SkeletonTable from "@patternfly/react-component-groups/dist/dynamic/SkeletonTable";
33

4-
export const SkeletonTableExample: React.FC = () => <SkeletonTable rows={10} columns={[ 'first', 'second' ]} />
4+
export const SkeletonTableExample: React.FC = () => <SkeletonTable rowsCount={10} columns={[ 'First', 'Second' ]} />
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import React from 'react';
22
import SkeletonTable from "@patternfly/react-component-groups/dist/dynamic/SkeletonTable";
33

4-
export const SkeletonTableExample: React.FC = () => <SkeletonTable rows={10} columns={[ 'first', 'second' ]} isExpandable />;
4+
export const SkeletonTableExample: React.FC = () => <SkeletonTable rowsCount={10} columns={[ 'First', 'Second' ]} isExpandable />;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react';
2+
import { Table } from '@patternfly/react-table';
3+
import SkeletonTableHead from "@patternfly/react-component-groups/dist/dynamic/SkeletonTableHead";
4+
5+
export const SkeletonTableHeadExample: React.FC = () => (
6+
<Table>
7+
<SkeletonTableHead columns={[ 'First', 'Second' ]} />
8+
</Table>
9+
);

0 commit comments

Comments
 (0)