@patternfly/react-table 6.5.0-prerelease.7 → 6.5.0-prerelease.71
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 +264 -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/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/Th.d.ts.map +1 -1
- package/dist/esm/components/Table/Th.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/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/Th.d.ts.map +1 -1
- package/dist/js/components/Table/Th.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-DgRiEz7K.css → output-CI0BoW1v.css} +4827 -4632
- 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/Table.tsx +13 -1
- package/src/components/Table/Th.tsx +1 -2
- package/src/components/Table/__tests__/Table.test.tsx +72 -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/examples/Table.md +18 -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/TableStickyColumnsAndHeader.tsx +2 -2
- package/src/components/Table/examples/TableStickyHeaderDynamic.tsx +140 -0
- 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.71",
|
|
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.68",
|
|
44
|
+
"@patternfly/react-icons": "^6.5.0-prerelease.30",
|
|
45
|
+
"@patternfly/react-styles": "^6.5.0-prerelease.21",
|
|
46
|
+
"@patternfly/react-tokens": "^6.5.0-prerelease.20",
|
|
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": "3502b378ff6c4c1f59467079b3405dd1f7f0afde"
|
|
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';
|
|
@@ -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.
|
|
@@ -150,3 +150,75 @@ test('Renders expandable toggle button in Th with pf-m-small class when variant
|
|
|
150
150
|
expect(button).toHaveClass('pf-m-small');
|
|
151
151
|
});
|
|
152
152
|
});
|
|
153
|
+
|
|
154
|
+
test(`Renders with class ${styles.modifiers.plain} when isPlain is true`, () => {
|
|
155
|
+
render(<Table isPlain aria-label="Test table" />);
|
|
156
|
+
|
|
157
|
+
expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.modifiers.plain);
|
|
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
|
+
});
|
|
@@ -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
|
/>
|
|
@@ -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
|
|
@@ -324,7 +327,6 @@ To enable a tree table:
|
|
|
324
327
|
- `checkAriaLabel` - (optional) accessible label for the checkbox
|
|
325
328
|
- `showDetailsAriaLabel` - (optional) accessible label for the show row details button in the responsive view
|
|
326
329
|
4. The first `Td` in each row will pass the following to the `treeRow` prop:
|
|
327
|
-
|
|
328
330
|
- `onCollapse` - Callback when user expands/collapses a row to reveal/hide the row's children.
|
|
329
331
|
- `onCheckChange` - (optional) Callback when user changes the checkbox on a row.
|
|
330
332
|
- `onToggleRowDetails` - (optional) Callback when user shows/hides the row details in responsive view.
|
|
@@ -416,6 +418,16 @@ To prevent the default text wrapping behavior and allow horizontal scrolling, al
|
|
|
416
418
|
|
|
417
419
|
```
|
|
418
420
|
|
|
421
|
+
### Dynamic sticky header
|
|
422
|
+
|
|
423
|
+
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.
|
|
424
|
+
|
|
425
|
+
`isStickyHeader` acts as if both properties are present and true when applied, and is useful when dynamic sticky styling is not necessary.
|
|
426
|
+
|
|
427
|
+
```ts file="TableStickyHeaderDynamic.tsx"
|
|
428
|
+
|
|
429
|
+
```
|
|
430
|
+
|
|
419
431
|
### Sticky columns and header
|
|
420
432
|
|
|
421
433
|
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}>
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
ThProps,
|
|
12
12
|
ISortBy
|
|
13
13
|
} from '@patternfly/react-table';
|
|
14
|
-
import
|
|
14
|
+
import RhUiBlueprintIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-blueprint-icon';
|
|
15
15
|
|
|
16
16
|
interface Fact {
|
|
17
17
|
name: string;
|
|
@@ -133,7 +133,7 @@ export const TableStickyColumnsAndHeader: React.FunctionComponent = () => {
|
|
|
133
133
|
{fact.name}
|
|
134
134
|
</Th>
|
|
135
135
|
<Th isStickyColumn stickyMinWidth="120px" stickyLeftOffset="120px" modifier="truncate" hasRightBorder>
|
|
136
|
-
<
|
|
136
|
+
<RhUiBlueprintIcon />
|
|
137
137
|
{` ${fact.state}`}
|
|
138
138
|
</Th>
|
|
139
139
|
<Td modifier="nowrap" dataLabel={columnNames.header3}>
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Table, Thead, Tr, Th, Tbody, Td, InnerScrollContainer } from '@patternfly/react-table';
|
|
3
|
+
import RhUiBlueprintIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-blueprint-icon';
|
|
4
|
+
|
|
5
|
+
interface Fact {
|
|
6
|
+
name: string;
|
|
7
|
+
state: string;
|
|
8
|
+
detail1: string;
|
|
9
|
+
detail2: string;
|
|
10
|
+
detail3: string;
|
|
11
|
+
detail4: string;
|
|
12
|
+
detail5: string;
|
|
13
|
+
detail6: string;
|
|
14
|
+
detail7: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const useIsStuckFromScrollParent = ({
|
|
18
|
+
shouldTrack,
|
|
19
|
+
scrollParentRef
|
|
20
|
+
}: {
|
|
21
|
+
/** Indicates whether to track the scroll top position of the scroll parent element */
|
|
22
|
+
shouldTrack: boolean;
|
|
23
|
+
/** Reference to the scroll parent element */
|
|
24
|
+
scrollParentRef: React.RefObject<any>;
|
|
25
|
+
}): boolean => {
|
|
26
|
+
const [isStuck, setIsStuck] = useState(false);
|
|
27
|
+
|
|
28
|
+
useLayoutEffect(() => {
|
|
29
|
+
if (!shouldTrack) {
|
|
30
|
+
setIsStuck(false);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const scrollElement = scrollParentRef.current;
|
|
35
|
+
if (!scrollElement) {
|
|
36
|
+
setIsStuck(false);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const syncFromScroll = () => {
|
|
41
|
+
setIsStuck(scrollElement.scrollTop > 0);
|
|
42
|
+
};
|
|
43
|
+
syncFromScroll();
|
|
44
|
+
scrollElement.addEventListener('scroll', syncFromScroll, { passive: true });
|
|
45
|
+
return () => scrollElement.removeEventListener('scroll', syncFromScroll);
|
|
46
|
+
}, [shouldTrack, scrollParentRef]);
|
|
47
|
+
|
|
48
|
+
return isStuck;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const TableStickyHeaderDynamic: React.FunctionComponent = () => {
|
|
52
|
+
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
53
|
+
const isStuck = useIsStuckFromScrollParent({ shouldTrack: true, scrollParentRef: scrollContainerRef });
|
|
54
|
+
|
|
55
|
+
// In real usage, this data would come from some external source like an API via props.
|
|
56
|
+
const facts: Fact[] = Array.from({ length: 9 }, (_, index) => ({
|
|
57
|
+
name: `Fact ${index + 1}`,
|
|
58
|
+
state: `State ${index + 1}`,
|
|
59
|
+
detail1: `Test cell ${index + 1}-3`,
|
|
60
|
+
detail2: `Test cell ${index + 1}-4`,
|
|
61
|
+
detail3: `Test cell ${index + 1}-5`,
|
|
62
|
+
detail4: `Test cell ${index + 1}-6`,
|
|
63
|
+
detail5: `Test cell ${index + 1}-7`,
|
|
64
|
+
detail6: `Test cell ${index + 1}-8`,
|
|
65
|
+
detail7: `Test cell ${index + 1}-9`
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
const columnNames = {
|
|
69
|
+
name: 'Fact',
|
|
70
|
+
state: 'State',
|
|
71
|
+
header3: 'Header 3',
|
|
72
|
+
header4: 'Header 4',
|
|
73
|
+
header5: 'Header 5',
|
|
74
|
+
header6: 'Header 6',
|
|
75
|
+
header7: 'Header 7',
|
|
76
|
+
header8: 'Header 8',
|
|
77
|
+
header9: 'Header 9'
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div style={{ height: '400px' }}>
|
|
82
|
+
<InnerScrollContainer ref={scrollContainerRef}>
|
|
83
|
+
<Table
|
|
84
|
+
aria-label="Dynamic sticky header table"
|
|
85
|
+
gridBreakPoint=""
|
|
86
|
+
isStickyHeaderBase
|
|
87
|
+
isStickyHeaderStuck={isStuck}
|
|
88
|
+
>
|
|
89
|
+
<Thead>
|
|
90
|
+
<Tr>
|
|
91
|
+
<Th modifier="truncate">{columnNames.name}</Th>
|
|
92
|
+
<Th modifier="truncate">{columnNames.state}</Th>
|
|
93
|
+
<Th modifier="truncate">{columnNames.header3}</Th>
|
|
94
|
+
<Th modifier="truncate">{columnNames.header4}</Th>
|
|
95
|
+
<Th modifier="truncate">{columnNames.header5}</Th>
|
|
96
|
+
<Th modifier="truncate">{columnNames.header6}</Th>
|
|
97
|
+
<Th modifier="truncate">{columnNames.header7}</Th>
|
|
98
|
+
<Th modifier="truncate">{columnNames.header8}</Th>
|
|
99
|
+
<Th modifier="truncate">{columnNames.header9}</Th>
|
|
100
|
+
</Tr>
|
|
101
|
+
</Thead>
|
|
102
|
+
<Tbody>
|
|
103
|
+
{facts.map((fact) => (
|
|
104
|
+
<Tr key={fact.name}>
|
|
105
|
+
<Td modifier="nowrap" dataLabel={columnNames.name}>
|
|
106
|
+
{fact.name}
|
|
107
|
+
</Td>
|
|
108
|
+
<Td modifier="nowrap" dataLabel={columnNames.state}>
|
|
109
|
+
<RhUiBlueprintIcon />
|
|
110
|
+
{` ${fact.state}`}
|
|
111
|
+
</Td>
|
|
112
|
+
<Td modifier="nowrap" dataLabel={columnNames.header3}>
|
|
113
|
+
{fact.detail1}
|
|
114
|
+
</Td>
|
|
115
|
+
<Td modifier="nowrap" dataLabel={columnNames.header4}>
|
|
116
|
+
{fact.detail2}
|
|
117
|
+
</Td>
|
|
118
|
+
<Td modifier="nowrap" dataLabel={columnNames.header5}>
|
|
119
|
+
{fact.detail3}
|
|
120
|
+
</Td>
|
|
121
|
+
<Td modifier="nowrap" dataLabel={columnNames.header6}>
|
|
122
|
+
{fact.detail4}
|
|
123
|
+
</Td>
|
|
124
|
+
<Td modifier="nowrap" dataLabel={columnNames.header7}>
|
|
125
|
+
{fact.detail5}
|
|
126
|
+
</Td>
|
|
127
|
+
<Td modifier="nowrap" dataLabel={columnNames.header8}>
|
|
128
|
+
{fact.detail6}
|
|
129
|
+
</Td>
|
|
130
|
+
<Td modifier="nowrap" dataLabel={columnNames.header9}>
|
|
131
|
+
{fact.detail7}
|
|
132
|
+
</Td>
|
|
133
|
+
</Tr>
|
|
134
|
+
))}
|
|
135
|
+
</Tbody>
|
|
136
|
+
</Table>
|
|
137
|
+
</InnerScrollContainer>
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
@@ -2,10 +2,10 @@ import { css } from '@patternfly/react-styles';
|
|
|
2
2
|
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
3
3
|
import { IExtra, IFormatterValueType, ITransform } from '../../TableTypes';
|
|
4
4
|
import { SortColumn, SortByDirection } from '../../SortColumn';
|
|
5
|
-
import
|
|
5
|
+
import RhUiStarFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-star-fill-icon';
|
|
6
6
|
|
|
7
7
|
export const sortableFavorites = (sort: any) => () =>
|
|
8
|
-
sortable(<
|
|
8
|
+
sortable(<RhUiStarFillIcon />, {
|
|
9
9
|
columnIndex: sort.columnIndex,
|
|
10
10
|
className: styles.tableFavorite,
|
|
11
11
|
ariaLabel: sort.ariaLabel ?? 'Sort favorites',
|