@patternfly/react-table 6.3.0-prerelease.9 → 6.3.1-prerelease.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +126 -0
- package/components/package.json +1 -1
- package/deprecated/package.json +1 -1
- package/dist/dynamic/components/Table/package.json +1 -1
- package/dist/dynamic/components/Table/utils/decorators/package.json +1 -1
- package/dist/dynamic/components/Table/utils/package.json +1 -1
- package/dist/dynamic/deprecated/components/Table/base/package.json +1 -1
- package/dist/dynamic/deprecated/components/Table/package.json +1 -1
- package/dist/dynamic/deprecated/components/package.json +1 -1
- package/dist/esm/components/Table/ExpandableRowContent.d.ts +5 -0
- package/dist/esm/components/Table/ExpandableRowContent.d.ts.map +1 -1
- package/dist/esm/components/Table/ExpandableRowContent.js +2 -2
- package/dist/esm/components/Table/ExpandableRowContent.js.map +1 -1
- package/dist/esm/components/Table/Table.d.ts +6 -1
- package/dist/esm/components/Table/Table.d.ts.map +1 -1
- package/dist/esm/components/Table/Table.js +5 -4
- package/dist/esm/components/Table/Table.js.map +1 -1
- package/dist/esm/components/Table/Td.d.ts +2 -0
- package/dist/esm/components/Table/Td.d.ts.map +1 -1
- package/dist/esm/components/Table/Td.js +25 -4
- package/dist/esm/components/Table/Td.js.map +1 -1
- package/dist/esm/components/Table/Tr.d.ts +5 -1
- package/dist/esm/components/Table/Tr.d.ts.map +1 -1
- package/dist/esm/components/Table/Tr.js +3 -3
- package/dist/esm/components/Table/Tr.js.map +1 -1
- package/dist/esm/demos/DashboardHeader.d.ts.map +1 -1
- package/dist/esm/demos/DashboardHeader.js +1 -2
- package/dist/esm/demos/DashboardHeader.js.map +1 -1
- package/dist/esm/demos/sampleData.d.ts.map +1 -1
- package/dist/esm/demos/sampleData.js +359 -360
- package/dist/esm/demos/sampleData.js.map +1 -1
- package/dist/js/components/Table/ExpandableRowContent.d.ts +5 -0
- package/dist/js/components/Table/ExpandableRowContent.d.ts.map +1 -1
- package/dist/js/components/Table/ExpandableRowContent.js +2 -2
- package/dist/js/components/Table/ExpandableRowContent.js.map +1 -1
- package/dist/js/components/Table/Table.d.ts +6 -1
- package/dist/js/components/Table/Table.d.ts.map +1 -1
- package/dist/js/components/Table/Table.js +5 -4
- package/dist/js/components/Table/Table.js.map +1 -1
- package/dist/js/components/Table/Td.d.ts +2 -0
- package/dist/js/components/Table/Td.d.ts.map +1 -1
- package/dist/js/components/Table/Td.js +24 -3
- package/dist/js/components/Table/Td.js.map +1 -1
- package/dist/js/components/Table/Tr.d.ts +5 -1
- package/dist/js/components/Table/Tr.d.ts.map +1 -1
- package/dist/js/components/Table/Tr.js +3 -3
- package/dist/js/components/Table/Tr.js.map +1 -1
- package/dist/js/demos/DashboardHeader.d.ts.map +1 -1
- package/dist/js/demos/DashboardHeader.js +1 -2
- package/dist/js/demos/DashboardHeader.js.map +1 -1
- package/dist/js/demos/sampleData.d.ts.map +1 -1
- package/dist/js/demos/sampleData.js +359 -360
- package/dist/js/demos/sampleData.js.map +1 -1
- package/dist/umd/assets/{output-PMQiOdP-.css → output-CKjCu3-7.css} +3852 -3434
- package/dist/umd/react-table.min.js +2 -2
- package/package.json +6 -6
- package/src/components/Table/ExpandableRowContent.tsx +7 -1
- package/src/components/Table/Table.tsx +12 -4
- package/src/components/Table/Td.tsx +41 -2
- package/src/components/Table/Tr.tsx +9 -3
- package/src/components/Table/__tests__/ExpandableRowContent.test.tsx +39 -0
- package/src/components/Table/__tests__/Table.test.tsx +62 -0
- package/src/components/Table/__tests__/Td.test.tsx +87 -0
- package/src/components/Table/__tests__/Tr.test.tsx +79 -0
- package/src/components/Table/__tests__/__snapshots__/ExpandableRowContent.test.tsx.snap +11 -0
- package/src/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +13 -0
- package/src/components/Table/__tests__/__snapshots__/Td.test.tsx.snap +33 -0
- package/src/components/Table/__tests__/__snapshots__/Tr.test.tsx.snap +35 -0
- package/src/components/Table/examples/Table.md +12 -6
- package/src/components/Table/examples/TableActions.tsx +1 -1
- package/src/components/Table/examples/TableCompoundExpandable.tsx +23 -21
- package/src/components/Table/examples/TableExpandable.tsx +7 -2
- package/src/components/Table/examples/TableMisc.tsx +0 -1
- package/src/components/Table/examples/TableNestedExpandable.tsx +2 -2
- package/src/components/Table/examples/TableNestedTableExpandable.tsx +2 -2
- package/src/components/Table/examples/TableStripedExpandable.tsx +8 -2
- package/src/demos/DashboardHeader.tsx +2 -5
- package/src/demos/examples/TableCompoundExpansion.tsx +87 -84
- package/src/demos/examples/TableExpandCollapseAll.tsx +2 -2
- package/src/demos/examples/TableSortableResponsive.tsx +5 -5
- package/src/demos/sampleData.tsx +359 -361
- package/src/deprecated/components/Table/examples/LegacyTableMisc.tsx +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-table",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.1-prerelease.0",
|
|
4
4
|
"description": "This library provides a set of React table components for use with the PatternFly 4",
|
|
5
5
|
"main": "dist/js/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"subpaths": "node ../../scripts/exportSubpaths.mjs --config subpaths.config.json"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@patternfly/react-core": "^6.3.
|
|
44
|
-
"@patternfly/react-icons": "^6.3.0
|
|
45
|
-
"@patternfly/react-styles": "^6.3.0
|
|
46
|
-
"@patternfly/react-tokens": "^6.3.0
|
|
43
|
+
"@patternfly/react-core": "^6.3.1-prerelease.0",
|
|
44
|
+
"@patternfly/react-icons": "^6.3.0",
|
|
45
|
+
"@patternfly/react-styles": "^6.3.0",
|
|
46
|
+
"@patternfly/react-tokens": "^6.3.0",
|
|
47
47
|
"lodash": "^4.17.21",
|
|
48
48
|
"tslib": "^2.8.1"
|
|
49
49
|
},
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"react": "^17 || ^18 || ^19",
|
|
52
52
|
"react-dom": "^17 || ^18 || ^19"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "999dd945fd4f8ec281d9015586ac773833f16217"
|
|
55
55
|
}
|
|
@@ -2,14 +2,20 @@ import { css } from '@patternfly/react-styles';
|
|
|
2
2
|
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
3
3
|
|
|
4
4
|
interface ExpandableRowContentProps {
|
|
5
|
+
/** Content rendered inside the expandable row. */
|
|
5
6
|
children?: React.ReactNode;
|
|
7
|
+
/** Flag indicating whether the expandable row content has no background. This should be passed in when
|
|
8
|
+
* the parent Td is passed the noPadding prop.
|
|
9
|
+
*/
|
|
10
|
+
hasNoBackground?: boolean;
|
|
6
11
|
}
|
|
7
12
|
|
|
8
13
|
export const ExpandableRowContent: React.FunctionComponent<ExpandableRowContentProps> = ({
|
|
9
14
|
children = null as React.ReactNode,
|
|
15
|
+
hasNoBackground,
|
|
10
16
|
...props
|
|
11
17
|
}: ExpandableRowContentProps) => (
|
|
12
|
-
<div {...props} className={css(styles.tableExpandableRowContent)}>
|
|
18
|
+
<div {...props} className={css(styles.tableExpandableRowContent, hasNoBackground && styles.modifiers.noBackground)}>
|
|
13
19
|
{children}
|
|
14
20
|
</div>
|
|
15
21
|
);
|
|
@@ -57,8 +57,12 @@ export interface TableProps extends React.HTMLProps<HTMLTableElement>, OUIAProps
|
|
|
57
57
|
isNested?: boolean;
|
|
58
58
|
/** Flag indicating this table should be striped. This property works best for a single <tbody> table. Striping may also be done manually by applying this property to Tbody and Tr components. */
|
|
59
59
|
isStriped?: boolean;
|
|
60
|
-
/** Flag indicating this table contains expandable rows
|
|
60
|
+
/** Flag indicating this table contains expandable rows. */
|
|
61
61
|
isExpandable?: boolean;
|
|
62
|
+
/** @beta Flag indicating whether expandable rows within the table have animations. Expandable rows cannot be dynamically rendered. This prop
|
|
63
|
+
* will be removed in the next breaking change, with the default behavior becoming animations always being enabled.
|
|
64
|
+
*/
|
|
65
|
+
hasAnimations?: boolean;
|
|
62
66
|
/** Flag indicating this table's rows will not have the inset typically reserved for expanding/collapsing rows in a tree table. Intended for use on tree tables with no visible rows with children. */
|
|
63
67
|
hasNoInset?: boolean;
|
|
64
68
|
/** Collection of column spans for nested headers. Deprecated: see https://github.com/patternfly/patternfly/issues/4584 */
|
|
@@ -73,10 +77,12 @@ export interface TableProps extends React.HTMLProps<HTMLTableElement>, OUIAProps
|
|
|
73
77
|
|
|
74
78
|
interface TableContextProps {
|
|
75
79
|
registerSelectableRow?: () => void;
|
|
80
|
+
hasAnimations?: boolean;
|
|
76
81
|
}
|
|
77
82
|
|
|
78
83
|
export const TableContext = createContext<TableContextProps>({
|
|
79
|
-
registerSelectableRow: () => {}
|
|
84
|
+
registerSelectableRow: () => {},
|
|
85
|
+
hasAnimations: false
|
|
80
86
|
});
|
|
81
87
|
|
|
82
88
|
const TableBase: React.FunctionComponent<TableProps> = ({
|
|
@@ -95,6 +101,7 @@ const TableBase: React.FunctionComponent<TableProps> = ({
|
|
|
95
101
|
isNested = false,
|
|
96
102
|
isStriped = false,
|
|
97
103
|
isExpandable = false,
|
|
104
|
+
hasAnimations = false,
|
|
98
105
|
hasNoInset = false,
|
|
99
106
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
100
107
|
nestedHeaderColumnSpans,
|
|
@@ -197,7 +204,7 @@ const TableBase: React.FunctionComponent<TableProps> = ({
|
|
|
197
204
|
};
|
|
198
205
|
|
|
199
206
|
return (
|
|
200
|
-
<TableContext.Provider value={{ registerSelectableRow }}>
|
|
207
|
+
<TableContext.Provider value={{ registerSelectableRow, hasAnimations }}>
|
|
201
208
|
<table
|
|
202
209
|
aria-label={ariaLabel}
|
|
203
210
|
role={role}
|
|
@@ -212,7 +219,8 @@ const TableBase: React.FunctionComponent<TableProps> = ({
|
|
|
212
219
|
isStriped && styles.modifiers.striped,
|
|
213
220
|
isExpandable && styles.modifiers.expandable,
|
|
214
221
|
hasNoInset && stylesTreeView.modifiers.noInset,
|
|
215
|
-
isNested && 'pf-m-nested'
|
|
222
|
+
isNested && 'pf-m-nested',
|
|
223
|
+
hasAnimations && styles.modifiers.animateExpand
|
|
216
224
|
)}
|
|
217
225
|
ref={tableRef}
|
|
218
226
|
{...(isTreeTable && { role: 'treegrid' })}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRef, forwardRef, useEffect, useState } from 'react';
|
|
1
|
+
import { createRef, forwardRef, useEffect, useState, useContext } from 'react';
|
|
2
2
|
import { css } from '@patternfly/react-styles';
|
|
3
3
|
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
4
4
|
import scrollStyles from '@patternfly/react-styles/css/components/Table/table-scrollable';
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
classNames,
|
|
15
15
|
favoritable
|
|
16
16
|
} from './utils';
|
|
17
|
+
import { IRowData, IExtraData } from './TableTypes';
|
|
17
18
|
import { draggable } from './utils/decorators/draggable';
|
|
18
19
|
import { treeRow } from './utils';
|
|
19
20
|
import { mergeProps } from './base/merge-props';
|
|
@@ -29,6 +30,7 @@ import {
|
|
|
29
30
|
TdSelectType,
|
|
30
31
|
TdTreeRowType
|
|
31
32
|
} from './base/types';
|
|
33
|
+
import { TableContext } from './Table';
|
|
32
34
|
import cssStickyCellMinWidth from '@patternfly/react-tokens/dist/esm/c_table__sticky_cell_MinWidth';
|
|
33
35
|
import cssStickyCellInlineStart from '@patternfly/react-tokens/dist/esm/c_table__sticky_cell_InsetInlineStart';
|
|
34
36
|
import cssStickyCellInlineEnd from '@patternfly/react-tokens/dist/esm/c_table__sticky_cell_InsetInlineEnd';
|
|
@@ -43,6 +45,8 @@ export interface TdProps extends BaseCellProps, Omit<React.HTMLProps<HTMLTableDa
|
|
|
43
45
|
select?: TdSelectType;
|
|
44
46
|
/** Turns the cell into an actions cell. Recommended to use an ActionsColumn component as a child of the Td rather than this prop. */
|
|
45
47
|
actions?: TdActionsType;
|
|
48
|
+
/** Indicates the cell contains an interactive element and prevents that element's padding from increasing row height. Recommended when other cells in the same row contains text. */
|
|
49
|
+
hasAction?: boolean;
|
|
46
50
|
/** Turns the cell into an expansion toggle and determines if the corresponding expansion row is open */
|
|
47
51
|
expand?: TdExpandType;
|
|
48
52
|
/** Turns the cell into a compound expansion toggle */
|
|
@@ -84,6 +88,7 @@ const TdBase: React.FunctionComponent<TdProps> = ({
|
|
|
84
88
|
children,
|
|
85
89
|
className,
|
|
86
90
|
isActionCell = false,
|
|
91
|
+
hasAction = false,
|
|
87
92
|
component = 'td',
|
|
88
93
|
dataLabel,
|
|
89
94
|
textCenter = false,
|
|
@@ -193,6 +198,39 @@ const TdBase: React.FunctionComponent<TdProps> = ({
|
|
|
193
198
|
}
|
|
194
199
|
})
|
|
195
200
|
: null;
|
|
201
|
+
|
|
202
|
+
const { hasAnimations } = useContext(TableContext);
|
|
203
|
+
const updateAnimationClass = () => {
|
|
204
|
+
const ancestorControlRow = (cellRef as React.RefObject<HTMLElement | null>)?.current?.closest(
|
|
205
|
+
`.${styles.tableTr}.${styles.tableControlRow}`
|
|
206
|
+
);
|
|
207
|
+
const isControlRowExpanded = ancestorControlRow.classList.contains(styles.modifiers.expanded);
|
|
208
|
+
if (!isControlRowExpanded) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const isCurrentCellExpanded = (cellRef as React.RefObject<HTMLElement | null>)?.current?.classList.contains(
|
|
213
|
+
styles.modifiers.expanded
|
|
214
|
+
);
|
|
215
|
+
if (isCurrentCellExpanded) {
|
|
216
|
+
ancestorControlRow.classList.remove(styles.modifiers.noAnimateExpand);
|
|
217
|
+
} else {
|
|
218
|
+
ancestorControlRow.classList.add(styles.modifiers.noAnimateExpand);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const internalCompoundOnToggle = (
|
|
223
|
+
event: React.MouseEvent,
|
|
224
|
+
rowIndex: number,
|
|
225
|
+
colIndex: number,
|
|
226
|
+
isOpen: boolean,
|
|
227
|
+
rowData: IRowData,
|
|
228
|
+
extraData: IExtraData
|
|
229
|
+
) => {
|
|
230
|
+
hasAnimations && updateAnimationClass();
|
|
231
|
+
compoundExpandProp?.onToggle(event, rowIndex, colIndex, isOpen, rowData, extraData);
|
|
232
|
+
};
|
|
233
|
+
|
|
196
234
|
const compoundParams =
|
|
197
235
|
compoundExpandProp !== null
|
|
198
236
|
? compoundExpand(
|
|
@@ -207,7 +245,7 @@ const TdBase: React.FunctionComponent<TdProps> = ({
|
|
|
207
245
|
columnIndex: compoundExpandProp?.columnIndex,
|
|
208
246
|
column: {
|
|
209
247
|
extraParams: {
|
|
210
|
-
onExpand:
|
|
248
|
+
onExpand: internalCompoundOnToggle,
|
|
211
249
|
expandId: compoundExpandProp?.expandId
|
|
212
250
|
}
|
|
213
251
|
}
|
|
@@ -279,6 +317,7 @@ const TdBase: React.FunctionComponent<TdProps> = ({
|
|
|
279
317
|
styles.tableTd,
|
|
280
318
|
className,
|
|
281
319
|
isActionCell && styles.tableAction,
|
|
320
|
+
hasAction && styles.modifiers.action,
|
|
282
321
|
textCenter && styles.modifiers.center,
|
|
283
322
|
noPadding && styles.modifiers.noPadding,
|
|
284
323
|
isStickyColumn && scrollStyles.tableStickyCell,
|
|
@@ -14,10 +14,14 @@ export interface TrProps extends Omit<React.HTMLProps<HTMLTableRowElement>, 'onR
|
|
|
14
14
|
innerRef?: React.Ref<any>;
|
|
15
15
|
/** Flag indicating the Tr is hidden */
|
|
16
16
|
isHidden?: boolean;
|
|
17
|
-
/**
|
|
17
|
+
/** Flag indicating whether an "expandable" Tr is expanded or not. Only applicable to a Tr within a Tbody.
|
|
18
18
|
* To prevent column widths from responding automatically when expandable rows are toggled, the width prop must also be passed into either the th or td component
|
|
19
19
|
*/
|
|
20
20
|
isExpanded?: boolean;
|
|
21
|
+
/** Flag indicating that the "control row" Tr has an expandable sibling Tr that is expanded or not. Only applicable to
|
|
22
|
+
* a Tr within a Tbody, and should have the same value as an expandable Tr's isExpanded prop.
|
|
23
|
+
*/
|
|
24
|
+
isContentExpanded?: boolean;
|
|
21
25
|
/** Only applicable to Tr within the Tbody: Whether the row is editable */
|
|
22
26
|
isEditable?: boolean;
|
|
23
27
|
/** Flag which adds hover styles for the clickable table row */
|
|
@@ -46,6 +50,7 @@ const TrBase: React.FunctionComponent<TrProps> = ({
|
|
|
46
50
|
children,
|
|
47
51
|
className,
|
|
48
52
|
isExpanded,
|
|
53
|
+
isContentExpanded,
|
|
49
54
|
isEditable,
|
|
50
55
|
isHidden = false,
|
|
51
56
|
isClickable = false,
|
|
@@ -77,7 +82,7 @@ const TrBase: React.FunctionComponent<TrProps> = ({
|
|
|
77
82
|
|
|
78
83
|
const rowIsHidden = isHidden || (isExpanded !== undefined && !isExpanded);
|
|
79
84
|
|
|
80
|
-
const { registerSelectableRow } = useContext(TableContext);
|
|
85
|
+
const { registerSelectableRow, hasAnimations } = useContext(TableContext);
|
|
81
86
|
|
|
82
87
|
useEffect(() => {
|
|
83
88
|
if (isSelectable && !rowIsHidden) {
|
|
@@ -97,7 +102,7 @@ const TrBase: React.FunctionComponent<TrProps> = ({
|
|
|
97
102
|
styles.tableTr,
|
|
98
103
|
className,
|
|
99
104
|
isExpanded !== undefined && styles.tableExpandableRow,
|
|
100
|
-
isExpanded && styles.modifiers.expanded,
|
|
105
|
+
(isExpanded || isContentExpanded) && styles.modifiers.expanded,
|
|
101
106
|
isEditable && inlineStyles.modifiers.inlineEditable,
|
|
102
107
|
isClickable && styles.modifiers.clickable,
|
|
103
108
|
isRowSelected && styles.modifiers.selected,
|
|
@@ -110,6 +115,7 @@ const TrBase: React.FunctionComponent<TrProps> = ({
|
|
|
110
115
|
{...(isClickable && { tabIndex: 0 })}
|
|
111
116
|
aria-label={ariaLabel}
|
|
112
117
|
ref={innerRef}
|
|
118
|
+
{...(hasAnimations && rowIsHidden && { inert: '' })}
|
|
113
119
|
{...(onRowClick && { onClick: onRowClick, onKeyDown })}
|
|
114
120
|
{...ouiaProps}
|
|
115
121
|
{...props}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { ExpandableRowContent } from '../ExpandableRowContent';
|
|
3
|
+
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
4
|
+
|
|
5
|
+
test('Renders without children', () => {
|
|
6
|
+
render(<ExpandableRowContent data-testid="row-id" />);
|
|
7
|
+
|
|
8
|
+
expect(screen.getByTestId('row-id')).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('Renders with children', () => {
|
|
12
|
+
render(<ExpandableRowContent>Row content</ExpandableRowContent>);
|
|
13
|
+
|
|
14
|
+
expect(screen.getByText('Row content')).toBeVisible();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test(`Renders only with class ${styles.tableExpandableRowContent} by default`, () => {
|
|
18
|
+
render(<ExpandableRowContent>Row content</ExpandableRowContent>);
|
|
19
|
+
|
|
20
|
+
expect(screen.getByText('Row content')).toHaveClass(styles.tableExpandableRowContent, { exact: true });
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test(`Renders with class ${styles.modifiers.noBackground} when hasNoBackground is true`, () => {
|
|
24
|
+
render(<ExpandableRowContent hasNoBackground>Row content</ExpandableRowContent>);
|
|
25
|
+
|
|
26
|
+
expect(screen.getByText('Row content')).toHaveClass(styles.modifiers.noBackground);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test(`Spreads additional props`, () => {
|
|
30
|
+
render(<ExpandableRowContent data-custom="true">Row content</ExpandableRowContent>);
|
|
31
|
+
|
|
32
|
+
expect(screen.getByText('Row content')).toHaveAttribute('data-custom', 'true');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('Matches snapshot', () => {
|
|
36
|
+
const { asFragment } = render(<ExpandableRowContent>Row content</ExpandableRowContent>);
|
|
37
|
+
|
|
38
|
+
expect(asFragment()).toMatchSnapshot();
|
|
39
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { Table } from '../Table';
|
|
3
|
+
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
4
|
+
|
|
5
|
+
test('Renders without children', () => {
|
|
6
|
+
render(<Table aria-label="Test table" />);
|
|
7
|
+
|
|
8
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('Renders with children', () => {
|
|
12
|
+
render(
|
|
13
|
+
<Table aria-label="Test table">
|
|
14
|
+
<caption>Table caption</caption>
|
|
15
|
+
</Table>
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveTextContent('Table caption');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('Renders with role="treegrid" when isTreeTable is true', () => {
|
|
22
|
+
render(<Table isTreeTable aria-label="Test table" />);
|
|
23
|
+
|
|
24
|
+
expect(screen.getByRole('treegrid', { name: 'Test table' })).toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test(`Renders with class ${styles.table} by default`, () => {
|
|
28
|
+
render(<Table aria-label="Test table" />);
|
|
29
|
+
|
|
30
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.table);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test(`Renders with a pf-m-grid class by default`, () => {
|
|
34
|
+
render(<Table aria-label="Test table" />);
|
|
35
|
+
|
|
36
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(/^pf-m-grid/);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test(`Renders with a pf-m-tree-view-grid class when isTreeTable is true`, () => {
|
|
40
|
+
render(<Table isTreeTable aria-label="Test table" />);
|
|
41
|
+
|
|
42
|
+
expect(screen.getByRole('treegrid', { name: 'Test table' })).not.toHaveClass(/^pf-m-grid/);
|
|
43
|
+
expect(screen.getByRole('treegrid', { name: 'Test table' })).toHaveClass(/^pf-m-tree-view-grid/);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test(`Does not render with class ${styles.modifiers.animateExpand} by default`, () => {
|
|
47
|
+
render(<Table aria-label="Test table" />);
|
|
48
|
+
|
|
49
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.animateExpand);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test(`Renders with class ${styles.modifiers.animateExpand} hasAnimations is true`, () => {
|
|
53
|
+
render(<Table hasAnimations aria-label="Test table" />);
|
|
54
|
+
|
|
55
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.modifiers.animateExpand);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('Matches snapshot without children', () => {
|
|
59
|
+
const { asFragment } = render(<Table />);
|
|
60
|
+
|
|
61
|
+
expect(asFragment()).toMatchSnapshot();
|
|
62
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
3
|
+
import { Td } from '../Td';
|
|
4
|
+
|
|
5
|
+
test('Renders without children', () => {
|
|
6
|
+
render(
|
|
7
|
+
<table>
|
|
8
|
+
<tbody>
|
|
9
|
+
<tr>
|
|
10
|
+
<Td />
|
|
11
|
+
</tr>
|
|
12
|
+
</tbody>
|
|
13
|
+
</table>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(screen.getByRole('cell')).toBeInTheDocument();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('Renders with children', () => {
|
|
20
|
+
render(
|
|
21
|
+
<table>
|
|
22
|
+
<tbody>
|
|
23
|
+
<tr>
|
|
24
|
+
<Td>Cell content</Td>
|
|
25
|
+
</tr>
|
|
26
|
+
</tbody>
|
|
27
|
+
</table>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
expect(screen.getByRole('cell')).toHaveTextContent('Cell content');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test(`Applies ${styles.modifiers.action} when hasAction is true`, () => {
|
|
34
|
+
render(
|
|
35
|
+
<table>
|
|
36
|
+
<tbody>
|
|
37
|
+
<tr>
|
|
38
|
+
<Td hasAction>Cell with action</Td>
|
|
39
|
+
</tr>
|
|
40
|
+
</tbody>
|
|
41
|
+
</table>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(screen.getByRole('cell')).toHaveClass('pf-m-action');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test(`Does not apply ${styles.modifiers.action} when hasAction is false`, () => {
|
|
48
|
+
render(
|
|
49
|
+
<table>
|
|
50
|
+
<tbody>
|
|
51
|
+
<tr>
|
|
52
|
+
<Td hasAction={false}>Cell without action</Td>
|
|
53
|
+
</tr>
|
|
54
|
+
</tbody>
|
|
55
|
+
</table>
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
expect(screen.getByRole('cell')).not.toHaveClass('pf-m-action');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('Matches snapshot without children', () => {
|
|
62
|
+
const { asFragment } = render(
|
|
63
|
+
<table>
|
|
64
|
+
<tbody>
|
|
65
|
+
<tr>
|
|
66
|
+
<Td />
|
|
67
|
+
</tr>
|
|
68
|
+
</tbody>
|
|
69
|
+
</table>
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
expect(asFragment()).toMatchSnapshot();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('Matches snapshot with children', () => {
|
|
76
|
+
const { asFragment } = render(
|
|
77
|
+
<table>
|
|
78
|
+
<tbody>
|
|
79
|
+
<tr>
|
|
80
|
+
<Td>Cell content</Td>
|
|
81
|
+
</tr>
|
|
82
|
+
</tbody>
|
|
83
|
+
</table>
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
expect(asFragment()).toMatchSnapshot();
|
|
87
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { Tr } from '../Tr';
|
|
3
|
+
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
4
|
+
|
|
5
|
+
test('Renders without children', () => {
|
|
6
|
+
render(
|
|
7
|
+
<table>
|
|
8
|
+
<tbody>
|
|
9
|
+
<Tr />
|
|
10
|
+
</tbody>
|
|
11
|
+
</table>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(screen.getByRole('row')).toBeInTheDocument();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('Renders with children', () => {
|
|
18
|
+
render(
|
|
19
|
+
<table>
|
|
20
|
+
<tbody>
|
|
21
|
+
<Tr>
|
|
22
|
+
<td>Row content</td>
|
|
23
|
+
</Tr>
|
|
24
|
+
</tbody>
|
|
25
|
+
</table>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
expect(screen.getByRole('row')).toHaveTextContent('Row content');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test(`Does not render as hidden by default`, () => {
|
|
32
|
+
render(
|
|
33
|
+
<table>
|
|
34
|
+
<tbody>
|
|
35
|
+
<Tr />
|
|
36
|
+
</tbody>
|
|
37
|
+
</table>
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
expect(screen.getByRole('row')).not.toHaveAttribute('hidden');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test(`Renders as hidden when isHidden is true`, () => {
|
|
44
|
+
render(
|
|
45
|
+
<table>
|
|
46
|
+
<tbody>
|
|
47
|
+
<Tr isHidden />
|
|
48
|
+
</tbody>
|
|
49
|
+
</table>
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(screen.queryByRole('row')).not.toBeInTheDocument();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('Matches snapshot without children', () => {
|
|
56
|
+
const { asFragment } = render(
|
|
57
|
+
<table>
|
|
58
|
+
<tbody>
|
|
59
|
+
<Tr />
|
|
60
|
+
</tbody>
|
|
61
|
+
</table>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
expect(asFragment()).toMatchSnapshot();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('Matches snapshot with children', () => {
|
|
68
|
+
const { asFragment } = render(
|
|
69
|
+
<table>
|
|
70
|
+
<tbody>
|
|
71
|
+
<Tr>
|
|
72
|
+
<td>Row content</td>
|
|
73
|
+
</Tr>
|
|
74
|
+
</tbody>
|
|
75
|
+
</table>
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(asFragment()).toMatchSnapshot();
|
|
79
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Matches snapshot without children 1`] = `
|
|
4
|
+
<DocumentFragment>
|
|
5
|
+
<table
|
|
6
|
+
class="pf-v6-c-table pf-m-grid-md"
|
|
7
|
+
data-ouia-component-id="OUIA-Generated-Table-9"
|
|
8
|
+
data-ouia-component-type="PF6/Table"
|
|
9
|
+
data-ouia-safe="true"
|
|
10
|
+
role="grid"
|
|
11
|
+
/>
|
|
12
|
+
</DocumentFragment>
|
|
13
|
+
`;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Matches snapshot with children 1`] = `
|
|
4
|
+
<DocumentFragment>
|
|
5
|
+
<table>
|
|
6
|
+
<tbody>
|
|
7
|
+
<tr>
|
|
8
|
+
<td
|
|
9
|
+
class="pf-v6-c-table__td"
|
|
10
|
+
tabindex="-1"
|
|
11
|
+
>
|
|
12
|
+
Cell content
|
|
13
|
+
</td>
|
|
14
|
+
</tr>
|
|
15
|
+
</tbody>
|
|
16
|
+
</table>
|
|
17
|
+
</DocumentFragment>
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
exports[`Matches snapshot without children 1`] = `
|
|
21
|
+
<DocumentFragment>
|
|
22
|
+
<table>
|
|
23
|
+
<tbody>
|
|
24
|
+
<tr>
|
|
25
|
+
<td
|
|
26
|
+
class="pf-v6-c-table__td"
|
|
27
|
+
tabindex="-1"
|
|
28
|
+
/>
|
|
29
|
+
</tr>
|
|
30
|
+
</tbody>
|
|
31
|
+
</table>
|
|
32
|
+
</DocumentFragment>
|
|
33
|
+
`;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Matches snapshot with children 1`] = `
|
|
4
|
+
<DocumentFragment>
|
|
5
|
+
<table>
|
|
6
|
+
<tbody>
|
|
7
|
+
<tr
|
|
8
|
+
class="pf-v6-c-table__tr"
|
|
9
|
+
data-ouia-component-id="OUIA-Generated-TableRow-6"
|
|
10
|
+
data-ouia-component-type="PF6/TableRow"
|
|
11
|
+
data-ouia-safe="true"
|
|
12
|
+
>
|
|
13
|
+
<td>
|
|
14
|
+
Row content
|
|
15
|
+
</td>
|
|
16
|
+
</tr>
|
|
17
|
+
</tbody>
|
|
18
|
+
</table>
|
|
19
|
+
</DocumentFragment>
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
exports[`Matches snapshot without children 1`] = `
|
|
23
|
+
<DocumentFragment>
|
|
24
|
+
<table>
|
|
25
|
+
<tbody>
|
|
26
|
+
<tr
|
|
27
|
+
class="pf-v6-c-table__tr"
|
|
28
|
+
data-ouia-component-id="OUIA-Generated-TableRow-5"
|
|
29
|
+
data-ouia-component-type="PF6/TableRow"
|
|
30
|
+
data-ouia-safe="true"
|
|
31
|
+
/>
|
|
32
|
+
</tbody>
|
|
33
|
+
</table>
|
|
34
|
+
</DocumentFragment>
|
|
35
|
+
`;
|
|
@@ -184,6 +184,8 @@ To make a cell an action cell, render an `ActionsColumn` component inside a row'
|
|
|
184
184
|
|
|
185
185
|
If actions menus are getting clipped by other items on the page, such as sticky columns or rows, the `ActionsColumn` can be passed a `menuAppendTo` prop to adjust where the actions menu is appended.
|
|
186
186
|
|
|
187
|
+
When a table row contains mixed content of text and interactive elements, the `hasAction` property may be passed to a `Td` which contains interactive content like the below example's start `Button`. This will align buttons and other elements with other cells' text. Note that `hasAction` should not be used with `Td`s in an `ActionsColumn` because that comes with it's own spacing.
|
|
188
|
+
|
|
187
189
|
```ts file="TableActions.tsx"
|
|
188
190
|
|
|
189
191
|
```
|
|
@@ -200,9 +202,10 @@ Using an `OverflowMenu` in the actions column, allowing the actions to condense
|
|
|
200
202
|
|
|
201
203
|
To make a parent/child row pair expandable:
|
|
202
204
|
|
|
203
|
-
1.
|
|
204
|
-
|
|
205
|
-
|
|
205
|
+
1. Pass `isExpandable` to `Table`.
|
|
206
|
+
1. Make the first cell in every row an expandable cell by passing `TdExpandType` object to the `expand` prop on the `Td`.
|
|
207
|
+
1. Wrap the content of each child row cell in `ExpandableRowContent`.
|
|
208
|
+
1. Pass `isExpanded` to `Tbody` and the `Tr` containing expandable content, and pass `isContentExpanded` to the `Tr` that acts as the "control row".
|
|
206
209
|
|
|
207
210
|
The `TdExpandType` expects an `OnCollapse` event handler that has the following signature:
|
|
208
211
|
|
|
@@ -226,9 +229,10 @@ Note: Table column widths will respond automatically when toggling expanded rows
|
|
|
226
229
|
|
|
227
230
|
To make a parent/child row pair compound expandable:
|
|
228
231
|
|
|
229
|
-
1. Pass
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
1. Pass `isExpandable` to `Table`.
|
|
233
|
+
1. Pass a `TdCompoundExpandType` object to the `compoundExpand` prop on any `Td` that has an expandable child row.
|
|
234
|
+
1. Wrap the content of each child row cell in `ExpandableRowContent`.
|
|
235
|
+
1. Pass `isExpanded` to `Tbody` and the `Tr` containing expandable content, and pass `isContentExpanded` to the `Tr` that acts as the "control row".
|
|
232
236
|
|
|
233
237
|
The `TdCompoundExpandType` expects an `OnExpand` event handler with the following signature
|
|
234
238
|
|
|
@@ -243,6 +247,8 @@ export type OnExpand = (
|
|
|
243
247
|
) => void;
|
|
244
248
|
```
|
|
245
249
|
|
|
250
|
+
For a more complex compound expandable implementation with nested tables, see our [table compound expansion demo](/components/table/react-demos/compound-expansion).
|
|
251
|
+
|
|
246
252
|
```ts file="TableCompoundExpandable.tsx"
|
|
247
253
|
|
|
248
254
|
```
|
|
@@ -146,7 +146,7 @@ export const TableActions: React.FunctionComponent = () => {
|
|
|
146
146
|
<Td dataLabel={columnNames.prs}>{repo.prs}</Td>
|
|
147
147
|
<Td dataLabel={columnNames.workspaces}>{repo.workspaces}</Td>
|
|
148
148
|
<Td dataLabel={columnNames.lastCommit}>{repo.lastCommit}</Td>
|
|
149
|
-
<Td dataLabel={columnNames.singleAction} modifier="fitContent">
|
|
149
|
+
<Td dataLabel={columnNames.singleAction} modifier="fitContent" hasAction>
|
|
150
150
|
{singleActionButton}
|
|
151
151
|
</Td>
|
|
152
152
|
<Td isActionCell>
|