@patternfly/react-table 6.5.0-prerelease.8 → 6.5.0-prerelease.81
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 +302 -0
- package/README.md +1 -1
- 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/CollapseColumn.js +2 -2
- package/dist/esm/components/Table/CollapseColumn.js.map +1 -1
- package/dist/esm/components/Table/EditColumn.js +2 -2
- package/dist/esm/components/Table/EditColumn.js.map +1 -1
- package/dist/esm/components/Table/EditableSelectInputCell.d.ts.map +1 -1
- package/dist/esm/components/Table/EditableSelectInputCell.js.map +1 -1
- package/dist/esm/components/Table/InnerScrollContainer.d.ts +3 -1
- package/dist/esm/components/Table/InnerScrollContainer.d.ts.map +1 -1
- package/dist/esm/components/Table/InnerScrollContainer.js +5 -3
- package/dist/esm/components/Table/InnerScrollContainer.js.map +1 -1
- package/dist/esm/components/Table/SelectColumn.d.ts +2 -0
- package/dist/esm/components/Table/SelectColumn.d.ts.map +1 -1
- package/dist/esm/components/Table/SelectColumn.js +3 -2
- package/dist/esm/components/Table/SelectColumn.js.map +1 -1
- package/dist/esm/components/Table/Table.d.ts +7 -1
- package/dist/esm/components/Table/Table.d.ts.map +1 -1
- package/dist/esm/components/Table/Table.js +3 -3
- package/dist/esm/components/Table/Table.js.map +1 -1
- package/dist/esm/components/Table/TableTypes.d.ts +1 -0
- package/dist/esm/components/Table/TableTypes.d.ts.map +1 -1
- package/dist/esm/components/Table/Th.d.ts.map +1 -1
- package/dist/esm/components/Table/Th.js +2 -1
- package/dist/esm/components/Table/Th.js.map +1 -1
- package/dist/esm/components/Table/base/types.d.ts +2 -0
- package/dist/esm/components/Table/base/types.d.ts.map +1 -1
- package/dist/esm/components/Table/base/types.js.map +1 -1
- package/dist/esm/components/Table/utils/decorators/selectable.d.ts.map +1 -1
- package/dist/esm/components/Table/utils/decorators/selectable.js +2 -2
- package/dist/esm/components/Table/utils/decorators/selectable.js.map +1 -1
- package/dist/esm/components/Table/utils/decorators/sortable.js +2 -2
- package/dist/esm/components/Table/utils/decorators/sortable.js.map +1 -1
- package/dist/esm/components/Table/utils/decorators/treeRow.js +2 -2
- package/dist/esm/components/Table/utils/decorators/treeRow.js.map +1 -1
- package/dist/esm/demos/DashboardHeader.js +4 -4
- package/dist/esm/demos/DashboardHeader.js.map +1 -1
- package/dist/js/components/Table/CollapseColumn.js +2 -2
- package/dist/js/components/Table/CollapseColumn.js.map +1 -1
- package/dist/js/components/Table/EditColumn.js +2 -2
- package/dist/js/components/Table/EditColumn.js.map +1 -1
- package/dist/js/components/Table/EditableSelectInputCell.d.ts.map +1 -1
- package/dist/js/components/Table/EditableSelectInputCell.js.map +1 -1
- package/dist/js/components/Table/InnerScrollContainer.d.ts +3 -1
- package/dist/js/components/Table/InnerScrollContainer.d.ts.map +1 -1
- package/dist/js/components/Table/InnerScrollContainer.js +5 -4
- package/dist/js/components/Table/InnerScrollContainer.js.map +1 -1
- package/dist/js/components/Table/SelectColumn.d.ts +2 -0
- package/dist/js/components/Table/SelectColumn.d.ts.map +1 -1
- package/dist/js/components/Table/SelectColumn.js +3 -2
- package/dist/js/components/Table/SelectColumn.js.map +1 -1
- package/dist/js/components/Table/Table.d.ts +7 -1
- package/dist/js/components/Table/Table.d.ts.map +1 -1
- package/dist/js/components/Table/Table.js +3 -3
- package/dist/js/components/Table/Table.js.map +1 -1
- package/dist/js/components/Table/TableTypes.d.ts +1 -0
- package/dist/js/components/Table/TableTypes.d.ts.map +1 -1
- package/dist/js/components/Table/Th.d.ts.map +1 -1
- package/dist/js/components/Table/Th.js +2 -1
- package/dist/js/components/Table/Th.js.map +1 -1
- package/dist/js/components/Table/base/types.d.ts +2 -0
- package/dist/js/components/Table/base/types.d.ts.map +1 -1
- package/dist/js/components/Table/base/types.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/selectable.d.ts.map +1 -1
- package/dist/js/components/Table/utils/decorators/selectable.js +2 -2
- package/dist/js/components/Table/utils/decorators/selectable.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/sortable.js +2 -2
- package/dist/js/components/Table/utils/decorators/sortable.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/treeRow.js +2 -2
- package/dist/js/components/Table/utils/decorators/treeRow.js.map +1 -1
- package/dist/js/demos/DashboardHeader.js +4 -4
- package/dist/js/demos/DashboardHeader.js.map +1 -1
- package/dist/umd/assets/{output-B4SR7-ii.css → output-CRl_aBqA.css} +5443 -5243
- package/dist/umd/react-table.min.js +5 -5
- package/package.json +7 -7
- package/src/components/Table/CollapseColumn.tsx +2 -2
- package/src/components/Table/EditColumn.tsx +2 -2
- package/src/components/Table/EditableSelectInputCell.tsx +4 -2
- package/src/components/Table/InnerScrollContainer.tsx +9 -2
- package/src/components/Table/SelectColumn.tsx +9 -1
- package/src/components/Table/Table.tsx +13 -1
- package/src/components/Table/TableTypes.tsx +1 -0
- package/src/components/Table/Th.tsx +3 -3
- package/src/components/Table/__tests__/Table.test.tsx +66 -0
- package/src/components/Table/__tests__/Th.test.tsx +23 -0
- package/src/components/Table/__tests__/__snapshots__/RowWrapper.test.tsx.snap +2 -2
- package/src/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +1 -1
- package/src/components/Table/__tests__/__snapshots__/Tr.test.tsx.snap +2 -2
- package/src/components/Table/base/types.tsx +2 -0
- package/src/components/Table/examples/Table.md +26 -6
- package/src/components/Table/examples/TableActions.tsx +4 -9
- package/src/components/Table/examples/TableBasic.tsx +5 -10
- package/src/components/Table/examples/TableEditable.tsx +2 -2
- package/src/components/Table/examples/TableMultipleStickyColumns.tsx +2 -2
- package/src/components/Table/examples/TableSelectableIndeterminate.tsx +128 -0
- package/src/components/Table/examples/TableStickyColumnsAndHeader.tsx +2 -2
- package/src/components/Table/examples/TableStickyHeaderDynamic.tsx +140 -0
- package/src/components/Table/utils/decorators/selectable.tsx +2 -1
- package/src/components/Table/utils/decorators/sortable.tsx +2 -2
- package/src/components/Table/utils/decorators/treeRow.tsx +2 -2
- package/src/demos/DashboardHeader.tsx +4 -4
- package/src/demos/Table.md +7 -8
- package/src/demos/examples/TableEmptyStateError.tsx +2 -2
- package/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +937 -469
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-table",
|
|
3
|
-
"version": "6.5.0-prerelease.
|
|
3
|
+
"version": "6.5.0-prerelease.81",
|
|
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,16 +40,16 @@
|
|
|
40
40
|
"subpaths": "node ../../scripts/exportSubpaths.mjs --config subpaths.config.json"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@patternfly/react-core": "^6.5.0-prerelease.
|
|
44
|
-
"@patternfly/react-icons": "^6.5.0-prerelease.
|
|
45
|
-
"@patternfly/react-styles": "^6.5.0-prerelease.
|
|
46
|
-
"@patternfly/react-tokens": "^6.5.0-prerelease.
|
|
47
|
-
"lodash": "^4.
|
|
43
|
+
"@patternfly/react-core": "^6.5.0-prerelease.77",
|
|
44
|
+
"@patternfly/react-icons": "^6.5.0-prerelease.37",
|
|
45
|
+
"@patternfly/react-styles": "^6.5.0-prerelease.27",
|
|
46
|
+
"@patternfly/react-tokens": "^6.5.0-prerelease.26",
|
|
47
|
+
"lodash": "^4.18.1",
|
|
48
48
|
"tslib": "^2.8.1"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"react": "^17 || ^18 || ^19",
|
|
52
52
|
"react-dom": "^17 || ^18 || ^19"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "2753c22c70d9a5fc5107d5fcf8c1cc2c32598d04"
|
|
55
55
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import RhMicronsCaretDownIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-caret-down-icon';
|
|
3
3
|
import { css } from '@patternfly/react-styles';
|
|
4
4
|
import { Button } from '@patternfly/react-core/dist/esm/components/Button';
|
|
5
5
|
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
@@ -34,7 +34,7 @@ export const CollapseColumn: React.FunctionComponent<CollapseColumnProps> = ({
|
|
|
34
34
|
aria-expanded={isOpen}
|
|
35
35
|
icon={
|
|
36
36
|
<div className={css(styles.tableToggleIcon)}>
|
|
37
|
-
<
|
|
37
|
+
<RhMicronsCaretDownIcon />
|
|
38
38
|
</div>
|
|
39
39
|
}
|
|
40
40
|
/>
|
|
@@ -2,7 +2,7 @@ import { Fragment } from 'react';
|
|
|
2
2
|
import { Button } from '@patternfly/react-core/dist/esm/components/Button';
|
|
3
3
|
import PencilAltIcon from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon';
|
|
4
4
|
import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon';
|
|
5
|
-
import
|
|
5
|
+
import RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';
|
|
6
6
|
import { OnRowEdit } from './TableTypes';
|
|
7
7
|
import inlineStyles from '@patternfly/react-styles/css/components/InlineEdit/inline-edit';
|
|
8
8
|
import { css } from '@patternfly/react-styles';
|
|
@@ -47,7 +47,7 @@ export const EditColumn: React.FunctionComponent<EditColumnProps> = ({
|
|
|
47
47
|
{...props}
|
|
48
48
|
onClick={(e) => onClick(e, 'cancel')}
|
|
49
49
|
variant="plain"
|
|
50
|
-
icon={<
|
|
50
|
+
icon={<RhMicronsCloseIcon />}
|
|
51
51
|
/>
|
|
52
52
|
</div>
|
|
53
53
|
</div>
|
|
@@ -6,8 +6,10 @@ import inlineStyles from '@patternfly/react-styles/css/components/InlineEdit/inl
|
|
|
6
6
|
import formStyles from '@patternfly/react-styles/css/components/Form/form';
|
|
7
7
|
import { EditableSelectInputProps } from './base/types';
|
|
8
8
|
|
|
9
|
-
export interface IEditableSelectInputCell
|
|
10
|
-
|
|
9
|
+
export interface IEditableSelectInputCell extends Omit<
|
|
10
|
+
React.HTMLProps<HTMLElement | HTMLDivElement>,
|
|
11
|
+
'onSelect' | 'onToggle'
|
|
12
|
+
> {
|
|
11
13
|
/** Row index of this select input cell */
|
|
12
14
|
rowIndex: number;
|
|
13
15
|
/** Cell index of this select input cell */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
1
2
|
import { css } from '@patternfly/react-styles';
|
|
2
3
|
import styles from '@patternfly/react-styles/css/components/Table/table-scrollable';
|
|
3
4
|
|
|
@@ -6,16 +7,22 @@ export interface InnerScrollContainerProps extends React.HTMLProps<HTMLDivElemen
|
|
|
6
7
|
children?: React.ReactNode;
|
|
7
8
|
/** Additional classes added to the container */
|
|
8
9
|
className?: string;
|
|
10
|
+
/** @hide Forwarded ref */
|
|
11
|
+
innerRef?: React.Ref<HTMLDivElement>;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
const InnerScrollContainerBase: React.FunctionComponent<InnerScrollContainerProps> = ({
|
|
12
15
|
children,
|
|
13
16
|
className,
|
|
17
|
+
innerRef,
|
|
14
18
|
...props
|
|
15
19
|
}: InnerScrollContainerProps) => (
|
|
16
|
-
<div className={css(className, styles.scrollInnerWrapper)} {...props}>
|
|
20
|
+
<div ref={innerRef} className={css(className, styles.scrollInnerWrapper)} {...props}>
|
|
17
21
|
{children}
|
|
18
22
|
</div>
|
|
19
23
|
);
|
|
20
24
|
|
|
25
|
+
export const InnerScrollContainer = forwardRef((props: InnerScrollContainerProps, ref: React.Ref<HTMLDivElement>) => (
|
|
26
|
+
<InnerScrollContainerBase innerRef={ref} {...props} />
|
|
27
|
+
));
|
|
21
28
|
InnerScrollContainer.displayName = 'InnerScrollContainer';
|
|
@@ -21,6 +21,8 @@ export interface SelectColumnProps {
|
|
|
21
21
|
id?: string;
|
|
22
22
|
/** name for the input element - required by Radio component */
|
|
23
23
|
name?: string;
|
|
24
|
+
/** Whether the checkbox should be in an indeterminate state */
|
|
25
|
+
isIndeterminate?: boolean;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export const SelectColumn: React.FunctionComponent<SelectColumnProps> = ({
|
|
@@ -33,6 +35,7 @@ export const SelectColumn: React.FunctionComponent<SelectColumnProps> = ({
|
|
|
33
35
|
tooltipProps,
|
|
34
36
|
id,
|
|
35
37
|
name,
|
|
38
|
+
isIndeterminate,
|
|
36
39
|
...props
|
|
37
40
|
}: SelectColumnProps) => {
|
|
38
41
|
const inputRef = createRef<any>();
|
|
@@ -48,10 +51,15 @@ export const SelectColumn: React.FunctionComponent<SelectColumnProps> = ({
|
|
|
48
51
|
onChange: handleChange
|
|
49
52
|
};
|
|
50
53
|
|
|
54
|
+
const checkboxProps = {
|
|
55
|
+
...commonProps,
|
|
56
|
+
...(isIndeterminate && { isChecked: null })
|
|
57
|
+
};
|
|
58
|
+
|
|
51
59
|
const content = (
|
|
52
60
|
<Fragment>
|
|
53
61
|
{selectVariant === RowSelectVariant.checkbox ? (
|
|
54
|
-
<Checkbox {...
|
|
62
|
+
<Checkbox {...checkboxProps} />
|
|
55
63
|
) : (
|
|
56
64
|
<Radio {...commonProps} name={name} />
|
|
57
65
|
)}
|
|
@@ -50,8 +50,14 @@ export interface TableProps extends React.HTMLProps<HTMLTableElement>, OUIAProps
|
|
|
50
50
|
role?: string;
|
|
51
51
|
/** @beta Flag indicating if the table should have plain styling with a transparent background */
|
|
52
52
|
isPlain?: boolean;
|
|
53
|
-
/**
|
|
53
|
+
/** @beta Flag indicating if the table should not have plain styling when in the glass theme */
|
|
54
|
+
isNoPlainOnGlass?: boolean;
|
|
55
|
+
/** If set to true, the table header sticks to the top of its container. This property applies both the sticky position and styling. */
|
|
54
56
|
isStickyHeader?: boolean;
|
|
57
|
+
/** @beta Flag indicating the table header should have sticky positioning to the top of the parent InnerScrollContainer. */
|
|
58
|
+
isStickyHeaderBase?: boolean;
|
|
59
|
+
/** @beta Flag indicating the table header should have stuck styling, when the header is not at the top of the scroll container. */
|
|
60
|
+
isStickyHeaderStuck?: boolean;
|
|
55
61
|
/** @hide Forwarded ref */
|
|
56
62
|
innerRef?: React.RefObject<any>;
|
|
57
63
|
/** Flag indicating table is a tree table */
|
|
@@ -96,7 +102,10 @@ const TableBase: React.FunctionComponent<TableProps> = ({
|
|
|
96
102
|
variant,
|
|
97
103
|
borders = true,
|
|
98
104
|
isStickyHeader = false,
|
|
105
|
+
isStickyHeaderBase = false,
|
|
106
|
+
isStickyHeaderStuck = false,
|
|
99
107
|
isPlain = false,
|
|
108
|
+
isNoPlainOnGlass = false,
|
|
100
109
|
gridBreakPoint = TableGridBreakpoint.gridMd,
|
|
101
110
|
'aria-label': ariaLabel,
|
|
102
111
|
role = 'grid',
|
|
@@ -222,10 +231,13 @@ const TableBase: React.FunctionComponent<TableProps> = ({
|
|
|
222
231
|
styles.modifiers[variant],
|
|
223
232
|
!borders && styles.modifiers.noBorderRows,
|
|
224
233
|
isStickyHeader && styles.modifiers.stickyHeader,
|
|
234
|
+
isStickyHeaderBase && styles.modifiers.stickyHeaderBase,
|
|
235
|
+
isStickyHeaderStuck && styles.modifiers.stickyHeaderStuck,
|
|
225
236
|
isTreeTable && stylesTreeView.modifiers.treeView,
|
|
226
237
|
isStriped && styles.modifiers.striped,
|
|
227
238
|
isExpandable && styles.modifiers.expandable,
|
|
228
239
|
isPlain && styles.modifiers.plain,
|
|
240
|
+
isNoPlainOnGlass && styles.modifiers.noPlainOnGlass,
|
|
229
241
|
hasNoInset && stylesTreeView.modifiers.noInset,
|
|
230
242
|
isNested && 'pf-m-nested',
|
|
231
243
|
hasAnimations && styles.modifiers.animateExpand
|
|
@@ -15,8 +15,7 @@ import cssStickyCellInlineStart from '@patternfly/react-tokens/dist/esm/c_table_
|
|
|
15
15
|
import cssStickyCellInlineEnd from '@patternfly/react-tokens/dist/esm/c_table__sticky_cell_InsetInlineEnd';
|
|
16
16
|
|
|
17
17
|
export interface ThProps
|
|
18
|
-
extends BaseCellProps,
|
|
19
|
-
Omit<React.HTMLProps<HTMLTableHeaderCellElement>, 'onSelect' | 'width'> {
|
|
18
|
+
extends BaseCellProps, Omit<React.HTMLProps<HTMLTableHeaderCellElement>, 'onSelect' | 'width'> {
|
|
20
19
|
/**
|
|
21
20
|
* The column header the cell corresponds to. Applicable when this component is used as a direct child to <Tr>.
|
|
22
21
|
* This attribute replaces table header in mobile viewport. It is rendered by ::before pseudo element.
|
|
@@ -159,7 +158,8 @@ const ThBase: React.FunctionComponent<ThProps> = ({
|
|
|
159
158
|
onSelect: select?.onSelect,
|
|
160
159
|
selectVariant: 'checkbox',
|
|
161
160
|
allRowsSelected: select.isSelected,
|
|
162
|
-
isHeaderSelectDisabled: !!select.isHeaderSelectDisabled
|
|
161
|
+
isHeaderSelectDisabled: !!select.isHeaderSelectDisabled,
|
|
162
|
+
isIndeterminate: select?.isIndeterminate
|
|
163
163
|
}
|
|
164
164
|
},
|
|
165
165
|
tooltip: tooltip as string,
|
|
@@ -156,3 +156,69 @@ test(`Renders with class ${styles.modifiers.plain} when isPlain is true`, () =>
|
|
|
156
156
|
|
|
157
157
|
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.modifiers.plain);
|
|
158
158
|
});
|
|
159
|
+
|
|
160
|
+
test(`Does not render with class ${styles.modifiers.plain} when isPlain is not defined`, () => {
|
|
161
|
+
render(<Table aria-label="Test table" />);
|
|
162
|
+
|
|
163
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.plain);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test(`Does not render with class ${styles.modifiers.plain} when isPlain is false`, () => {
|
|
167
|
+
render(<Table isPlain={false} aria-label="Test table" />);
|
|
168
|
+
|
|
169
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.plain);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test(`Renders with class ${styles.modifiers.noPlainOnGlass} when isNoPlainOnGlass is true`, () => {
|
|
173
|
+
render(<Table isNoPlainOnGlass aria-label="Test table" />);
|
|
174
|
+
|
|
175
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.modifiers.noPlainOnGlass);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test(`Does not render with class ${styles.modifiers.noPlainOnGlass} when isNoPlainOnGlass is undefined`, () => {
|
|
179
|
+
render(<Table aria-label="Test table" />);
|
|
180
|
+
|
|
181
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.noPlainOnGlass);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test(`Does not render with class ${styles.modifiers.noPlainOnGlass} when isNoPlainOnGlass is false`, () => {
|
|
185
|
+
render(<Table isNoPlainOnGlass={false} aria-label="Test table" />);
|
|
186
|
+
|
|
187
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.noPlainOnGlass);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test(`Renders with class ${styles.modifiers.stickyHeaderBase} when isStickyHeaderBase is true`, () => {
|
|
191
|
+
render(<Table isStickyHeaderBase aria-label="Test table" />);
|
|
192
|
+
|
|
193
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.modifiers.stickyHeaderBase);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test(`Does not render with class ${styles.modifiers.stickyHeaderBase} when isStickyHeaderBase is false`, () => {
|
|
197
|
+
render(<Table isStickyHeaderBase={false} aria-label="Test table" />);
|
|
198
|
+
|
|
199
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyHeaderBase);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test(`Does not render with class ${styles.modifiers.stickyHeaderBase} when isStickyHeaderBase is undefined`, () => {
|
|
203
|
+
render(<Table aria-label="Test table" />);
|
|
204
|
+
|
|
205
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyHeaderBase);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test(`Renders with class ${styles.modifiers.stickyHeaderStuck} when isStickyHeaderStuck is true`, () => {
|
|
209
|
+
render(<Table isStickyHeaderStuck aria-label="Test table" />);
|
|
210
|
+
|
|
211
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.modifiers.stickyHeaderStuck);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test(`Does not render with class ${styles.modifiers.stickyHeaderStuck} when isStickyHeaderStuck is false`, () => {
|
|
215
|
+
render(<Table isStickyHeaderStuck={false} aria-label="Test table" />);
|
|
216
|
+
|
|
217
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyHeaderStuck);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test(`Does not render with class ${styles.modifiers.stickyHeaderStuck} when isStickyHeaderStuck is undefined`, () => {
|
|
221
|
+
render(<Table aria-label="Test table" />);
|
|
222
|
+
|
|
223
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyHeaderStuck);
|
|
224
|
+
});
|
|
@@ -54,3 +54,26 @@ test('Additional content renders after children when additionalContent is passed
|
|
|
54
54
|
expect(thChildren.item(0)?.textContent).toEqual('Test');
|
|
55
55
|
expect(thChildren.item(1)?.textContent).toEqual('Extra');
|
|
56
56
|
});
|
|
57
|
+
|
|
58
|
+
test('Renders checkbox without indeterminate state by default', () => {
|
|
59
|
+
render(<Th select={{ onSelect: jest.fn(), isSelected: false }} aria-label="Select all" />);
|
|
60
|
+
|
|
61
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
62
|
+
expect(checkbox).not.toBeChecked();
|
|
63
|
+
expect(checkbox.indeterminate).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('Renders checkbox with indeterminate state when isIndeterminate is true', () => {
|
|
67
|
+
render(<Th select={{ onSelect: jest.fn(), isSelected: false, isIndeterminate: true }} aria-label="Select all" />);
|
|
68
|
+
|
|
69
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
70
|
+
expect(checkbox.indeterminate).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('Renders checked checkbox when isSelected is true and isIndeterminate is false', () => {
|
|
74
|
+
render(<Th select={{ onSelect: jest.fn(), isSelected: true, isIndeterminate: false }} aria-label="Select all" />);
|
|
75
|
+
|
|
76
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
77
|
+
expect(checkbox).toBeChecked();
|
|
78
|
+
expect(checkbox.indeterminate).toBe(false);
|
|
79
|
+
});
|
|
@@ -6,7 +6,7 @@ exports[`RowWrapper renders correctly 1`] = `
|
|
|
6
6
|
<tbody>
|
|
7
7
|
<tr
|
|
8
8
|
class="pf-v6-c-table__tr"
|
|
9
|
-
data-ouia-component-id="OUIA-Generated-TableRow
|
|
9
|
+
data-ouia-component-id="OUIA-Generated-TableRow-:r0:"
|
|
10
10
|
data-ouia-component-type="PF6/TableRow"
|
|
11
11
|
data-ouia-safe="true"
|
|
12
12
|
/>
|
|
@@ -21,7 +21,7 @@ exports[`RowWrapper renders expanded correctly 1`] = `
|
|
|
21
21
|
<tbody>
|
|
22
22
|
<tr
|
|
23
23
|
class="pf-v6-c-table__tr pf-v6-c-table__expandable-row pf-m-expanded"
|
|
24
|
-
data-ouia-component-id="OUIA-Generated-TableRow
|
|
24
|
+
data-ouia-component-id="OUIA-Generated-TableRow-:r1:"
|
|
25
25
|
data-ouia-component-type="PF6/TableRow"
|
|
26
26
|
data-ouia-safe="true"
|
|
27
27
|
/>
|
|
@@ -4,7 +4,7 @@ exports[`Matches snapshot without children 1`] = `
|
|
|
4
4
|
<DocumentFragment>
|
|
5
5
|
<table
|
|
6
6
|
class="pf-v6-c-table pf-m-grid-md"
|
|
7
|
-
data-ouia-component-id="OUIA-Generated-Table
|
|
7
|
+
data-ouia-component-id="OUIA-Generated-Table-:rb:"
|
|
8
8
|
data-ouia-component-type="PF6/Table"
|
|
9
9
|
data-ouia-safe="true"
|
|
10
10
|
role="grid"
|
|
@@ -6,7 +6,7 @@ exports[`Matches snapshot with children 1`] = `
|
|
|
6
6
|
<tbody>
|
|
7
7
|
<tr
|
|
8
8
|
class="pf-v6-c-table__tr"
|
|
9
|
-
data-ouia-component-id="OUIA-Generated-TableRow
|
|
9
|
+
data-ouia-component-id="OUIA-Generated-TableRow-:r5:"
|
|
10
10
|
data-ouia-component-type="PF6/TableRow"
|
|
11
11
|
data-ouia-safe="true"
|
|
12
12
|
>
|
|
@@ -25,7 +25,7 @@ exports[`Matches snapshot without children 1`] = `
|
|
|
25
25
|
<tbody>
|
|
26
26
|
<tr
|
|
27
27
|
class="pf-v6-c-table__tr"
|
|
28
|
-
data-ouia-component-id="OUIA-Generated-TableRow
|
|
28
|
+
data-ouia-component-id="OUIA-Generated-TableRow-:r4:"
|
|
29
29
|
data-ouia-component-type="PF6/TableRow"
|
|
30
30
|
data-ouia-safe="true"
|
|
31
31
|
/>
|
|
@@ -180,6 +180,8 @@ export interface ThSelectType {
|
|
|
180
180
|
onSelect?: OnSelect;
|
|
181
181
|
/** Whether the cell is selected */
|
|
182
182
|
isSelected: boolean;
|
|
183
|
+
/** Whether the select checkbox should be in an indeterminate state (some items selected) */
|
|
184
|
+
isIndeterminate?: boolean;
|
|
183
185
|
/** Flag indicating the select checkbox in the th is disabled */
|
|
184
186
|
isHeaderSelectDisabled?: boolean;
|
|
185
187
|
/** Whether to disable the selection */
|
|
@@ -41,7 +41,7 @@ The `Table` component takes an explicit and declarative approach, and its implem
|
|
|
41
41
|
|
|
42
42
|
The documentation for the deprecated table implementation can be found under the [React deprecated](/components/table/react-deprecated) tab. It is configuration based and takes a less declarative and more implicit approach to laying out the table structure, such as the rows and cells within it.
|
|
43
43
|
|
|
44
|
-
import { Fragment, isValidElement, useCallback, useEffect, useRef, useState } from 'react';
|
|
44
|
+
import { Fragment, isValidElement, useCallback, useEffect, useRef, useState, useLayoutEffect } from 'react';
|
|
45
45
|
import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
|
|
46
46
|
import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';
|
|
47
47
|
import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon';
|
|
@@ -50,11 +50,11 @@ import LeafIcon from '@patternfly/react-icons/dist/esm/icons/leaf-icon';
|
|
|
50
50
|
import FolderIcon from '@patternfly/react-icons/dist/esm/icons/folder-icon';
|
|
51
51
|
import FolderOpenIcon from '@patternfly/react-icons/dist/esm/icons/folder-open-icon';
|
|
52
52
|
import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon';
|
|
53
|
-
import
|
|
53
|
+
import RhUiBlueprintIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-blueprint-icon';
|
|
54
54
|
import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
|
|
55
55
|
import PencilAltIcon from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon';
|
|
56
56
|
import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon';
|
|
57
|
-
import
|
|
57
|
+
import RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';
|
|
58
58
|
|
|
59
59
|
import { css } from '@patternfly/react-styles';
|
|
60
60
|
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
@@ -78,10 +78,13 @@ Some general notes:
|
|
|
78
78
|
```ts file="TableBasic.tsx"
|
|
79
79
|
|
|
80
80
|
```
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
|
|
82
|
+
### Plain
|
|
83
|
+
|
|
84
|
+
```ts file="TablePlain.tsx"
|
|
83
85
|
|
|
84
86
|
```
|
|
87
|
+
|
|
85
88
|
### Custom row wrapper, header tooltips & popovers
|
|
86
89
|
|
|
87
90
|
- If you add the `noWrap` prop to `Thead`, it won't wrap it if there is no space
|
|
@@ -155,6 +158,14 @@ checking checkboxes will check intermediate rows' checkboxes.
|
|
|
155
158
|
|
|
156
159
|
```
|
|
157
160
|
|
|
161
|
+
### Selectable with indeterminate state
|
|
162
|
+
|
|
163
|
+
To indicate partial selection, use `isIndeterminate` on the header's `select` prop. When some (but not all) selectable rows are selected, the header checkbox will convey this information to assistive technologies and also display a dash instead of a checkmark.
|
|
164
|
+
|
|
165
|
+
```ts file="TableSelectableIndeterminate.tsx"
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
|
|
158
169
|
### Selectable radio input
|
|
159
170
|
|
|
160
171
|
Similarly to the selectable example above, the radio buttons use the first column. The first header cell is empty, and each body row's first cell has radio button props.
|
|
@@ -324,7 +335,6 @@ To enable a tree table:
|
|
|
324
335
|
- `checkAriaLabel` - (optional) accessible label for the checkbox
|
|
325
336
|
- `showDetailsAriaLabel` - (optional) accessible label for the show row details button in the responsive view
|
|
326
337
|
4. The first `Td` in each row will pass the following to the `treeRow` prop:
|
|
327
|
-
|
|
328
338
|
- `onCollapse` - Callback when user expands/collapses a row to reveal/hide the row's children.
|
|
329
339
|
- `onCheckChange` - (optional) Callback when user changes the checkbox on a row.
|
|
330
340
|
- `onToggleRowDetails` - (optional) Callback when user shows/hides the row details in responsive view.
|
|
@@ -416,6 +426,16 @@ To prevent the default text wrapping behavior and allow horizontal scrolling, al
|
|
|
416
426
|
|
|
417
427
|
```
|
|
418
428
|
|
|
429
|
+
### Dynamic sticky header
|
|
430
|
+
|
|
431
|
+
A sticky header may alternatively be implemented with two properties: `isStickyHeaderBase` and `isStickyHeaderStuck` - which allows separate control of the sticky position and sticky styling. `isStickyHeaderBase` should always be applied to make the header position sticky, and `isStickyHeaderStuck` may be applied dynamically to enable the sticky styling, such as when the sticky header is not at the top of the scroll parent as shown in the example.
|
|
432
|
+
|
|
433
|
+
`isStickyHeader` acts as if both properties are present and true when applied, and is useful when dynamic sticky styling is not necessary.
|
|
434
|
+
|
|
435
|
+
```ts file="TableStickyHeaderDynamic.tsx"
|
|
436
|
+
|
|
437
|
+
```
|
|
438
|
+
|
|
419
439
|
### Sticky columns and header
|
|
420
440
|
|
|
421
441
|
To maintain proper sticky behavior across sticky columns and header, `Table` must be wrapped with `OuterScrollContainer` and `InnerScrollContainer`.
|
|
@@ -23,7 +23,7 @@ interface Repository {
|
|
|
23
23
|
singleAction: string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
type ExampleType = '
|
|
26
|
+
type ExampleType = 'customToggle';
|
|
27
27
|
|
|
28
28
|
export const TableActions: React.FunctionComponent = () => {
|
|
29
29
|
// In real usage, this data would come from some external source like an API via props.
|
|
@@ -45,10 +45,11 @@ export const TableActions: React.FunctionComponent = () => {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
// This state is just for the ToggleGroup in this example and isn't necessary for Table usage.
|
|
48
|
-
const [exampleChoice, setExampleChoice] = useState<ExampleType>('
|
|
48
|
+
const [exampleChoice, setExampleChoice] = useState<ExampleType | ''>('');
|
|
49
49
|
const onExampleTypeChange: ToggleGroupItemProps['onChange'] = (event, _isSelected) => {
|
|
50
50
|
const id = event.currentTarget.id;
|
|
51
|
-
|
|
51
|
+
// Allow toggling off if clicking the already selected item
|
|
52
|
+
setExampleChoice(exampleChoice === id ? '' : (id as ExampleType));
|
|
52
53
|
};
|
|
53
54
|
|
|
54
55
|
const customActionsToggle = (props: CustomActionsToggleProps) => (
|
|
@@ -95,12 +96,6 @@ export const TableActions: React.FunctionComponent = () => {
|
|
|
95
96
|
return (
|
|
96
97
|
<Fragment>
|
|
97
98
|
<ToggleGroup aria-label="Default uses kebab toggle">
|
|
98
|
-
<ToggleGroupItem
|
|
99
|
-
text="Default actions toggle"
|
|
100
|
-
buttonId="defaultToggle"
|
|
101
|
-
isSelected={exampleChoice === 'defaultToggle'}
|
|
102
|
-
onChange={onExampleTypeChange}
|
|
103
|
-
/>
|
|
104
99
|
<ToggleGroupItem
|
|
105
100
|
text="Custom actions toggle"
|
|
106
101
|
buttonId="customToggle"
|
|
@@ -10,7 +10,7 @@ interface Repository {
|
|
|
10
10
|
lastCommit: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
type ExampleType = '
|
|
13
|
+
type ExampleType = 'compact' | 'compactBorderless';
|
|
14
14
|
|
|
15
15
|
export const TableBasic: React.FunctionComponent = () => {
|
|
16
16
|
// In real usage, this data would come from some external source like an API via props.
|
|
@@ -29,21 +29,16 @@ export const TableBasic: React.FunctionComponent = () => {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
// This state is just for the ToggleGroup in this example and isn't necessary for Table usage.
|
|
32
|
-
const [exampleChoice, setExampleChoice] = useState<ExampleType>('
|
|
32
|
+
const [exampleChoice, setExampleChoice] = useState<ExampleType | ''>('');
|
|
33
33
|
const onExampleTypeChange: ToggleGroupItemProps['onChange'] = (event, _isSelected) => {
|
|
34
34
|
const id = event.currentTarget.id;
|
|
35
|
-
|
|
35
|
+
// Allow toggling off if clicking the already selected item
|
|
36
|
+
setExampleChoice(exampleChoice === id ? '' : (id as ExampleType));
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
return (
|
|
39
40
|
<Fragment>
|
|
40
41
|
<ToggleGroup aria-label="Default with single selectable">
|
|
41
|
-
<ToggleGroupItem
|
|
42
|
-
text="Default"
|
|
43
|
-
buttonId="default"
|
|
44
|
-
isSelected={exampleChoice === 'default'}
|
|
45
|
-
onChange={onExampleTypeChange}
|
|
46
|
-
/>
|
|
47
42
|
<ToggleGroupItem
|
|
48
43
|
text="Compact"
|
|
49
44
|
buttonId="compact"
|
|
@@ -59,7 +54,7 @@ export const TableBasic: React.FunctionComponent = () => {
|
|
|
59
54
|
</ToggleGroup>
|
|
60
55
|
<Table
|
|
61
56
|
aria-label="Simple table"
|
|
62
|
-
variant={exampleChoice
|
|
57
|
+
variant={exampleChoice === 'compact' || exampleChoice === 'compactBorderless' ? 'compact' : undefined}
|
|
63
58
|
borders={exampleChoice !== 'compactBorderless'}
|
|
64
59
|
>
|
|
65
60
|
<Caption>Simple table using composable components</Caption>
|
|
@@ -3,7 +3,7 @@ import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
|
|
|
3
3
|
import { Button, Checkbox, Radio, TextInput, KeyTypes, getUniqueId } from '@patternfly/react-core';
|
|
4
4
|
import PencilAltIcon from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon';
|
|
5
5
|
import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon';
|
|
6
|
-
import
|
|
6
|
+
import RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';
|
|
7
7
|
import inlineEditStyles from '@patternfly/react-styles/css/components/InlineEdit/inline-edit';
|
|
8
8
|
import { css } from '@patternfly/react-styles';
|
|
9
9
|
|
|
@@ -60,7 +60,7 @@ const EditButtonsCell: React.FunctionComponent<EditButtonsCellProps> = ({
|
|
|
60
60
|
onKeyDown={(event) => onKeyDown(event, 'stopEditing')}
|
|
61
61
|
variant="plain"
|
|
62
62
|
>
|
|
63
|
-
<
|
|
63
|
+
<RhMicronsCloseIcon />
|
|
64
64
|
</Button>
|
|
65
65
|
</div>
|
|
66
66
|
</Td>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { Table, Thead, Tr, Th, Tbody, Td, InnerScrollContainer, ThProps } from '@patternfly/react-table';
|
|
3
|
-
import
|
|
3
|
+
import RhUiBlueprintIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-blueprint-icon';
|
|
4
4
|
|
|
5
5
|
interface Fact {
|
|
6
6
|
name: string;
|
|
@@ -120,7 +120,7 @@ export const TableMultipleStickyColumns: React.FunctionComponent = () => {
|
|
|
120
120
|
{fact.name}
|
|
121
121
|
</Th>
|
|
122
122
|
<Th isStickyColumn stickyMinWidth="120px" stickyLeftOffset="120px" modifier="truncate" hasRightBorder>
|
|
123
|
-
<
|
|
123
|
+
<RhUiBlueprintIcon />
|
|
124
124
|
{` ${fact.state}`}
|
|
125
125
|
</Th>
|
|
126
126
|
<Td modifier="nowrap" dataLabel={columnNames.header3}>
|