@patternfly/react-table 5.4.0-prerelease.9 → 5.4.1
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 +132 -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/ActionsColumn.js.map +1 -1
- package/dist/esm/components/Table/RowWrapper.js.map +1 -1
- package/dist/esm/components/Table/SortColumn.js.map +1 -1
- package/dist/esm/components/Table/Table.js.map +1 -1
- package/dist/esm/components/Table/TableText.js.map +1 -1
- package/dist/esm/components/Table/TableTypes.d.ts +22 -22
- package/dist/esm/components/Table/TableTypes.d.ts.map +1 -1
- package/dist/esm/components/Table/Td.js.map +1 -1
- package/dist/esm/components/Table/Th.js.map +1 -1
- package/dist/esm/components/Table/Tr.d.ts +2 -0
- package/dist/esm/components/Table/Tr.d.ts.map +1 -1
- package/dist/esm/components/Table/Tr.js +2 -2
- package/dist/esm/components/Table/Tr.js.map +1 -1
- package/dist/esm/components/Table/base/columns-are-equal.js.map +1 -1
- package/dist/esm/components/Table/base/evaluate-transforms.js.map +1 -1
- package/dist/esm/components/Table/base/merge-props.js.map +1 -1
- package/dist/esm/components/Table/base/provider.js.map +1 -1
- package/dist/esm/components/Table/base/types.d.ts +10 -10
- package/dist/esm/components/Table/base/types.d.ts.map +1 -1
- package/dist/esm/components/Table/utils/decorators/compoundExpand.js.map +1 -1
- package/dist/esm/components/Table/utils/decorators/editable.js.map +1 -1
- package/dist/esm/components/Table/utils/decorators/favoritable.js.map +1 -1
- package/dist/esm/components/Table/utils/decorators/selectable.js.map +1 -1
- package/dist/esm/components/Table/utils/decorators/sortable.js.map +1 -1
- package/dist/esm/components/Table/utils/headerUtils.js.map +1 -1
- package/dist/esm/components/Table/utils/transformers.js +1 -1
- package/dist/esm/components/Table/utils/transformers.js.map +1 -1
- package/dist/esm/components/Table/utils/utils.js.map +1 -1
- package/dist/esm/demos/DashboardWrapper.js.map +1 -1
- package/dist/esm/deprecated/components/Table/Body.d.ts +1 -1
- package/dist/esm/deprecated/components/Table/Body.d.ts.map +1 -1
- package/dist/esm/deprecated/components/Table/Body.js.map +1 -1
- package/dist/esm/deprecated/components/Table/BodyCell.js.map +1 -1
- package/dist/esm/deprecated/components/Table/BodyWrapper.js.map +1 -1
- package/dist/esm/deprecated/components/Table/Table.js.map +1 -1
- package/dist/esm/deprecated/components/Table/base/body-row.js.map +1 -1
- package/dist/esm/deprecated/components/Table/base/body.js.map +1 -1
- package/dist/esm/deprecated/components/Table/base/header-row.js +1 -1
- package/dist/esm/deprecated/components/Table/base/header-row.js.map +1 -1
- package/dist/esm/deprecated/components/Table/base/resolve-row-key.js.map +1 -1
- package/dist/esm/test-helpers/data-helpers.js.map +1 -1
- package/dist/js/components/Table/ActionsColumn.js.map +1 -1
- package/dist/js/components/Table/CollapseColumn.js.map +1 -1
- package/dist/js/components/Table/DraggableCell.js.map +1 -1
- package/dist/js/components/Table/EditColumn.js.map +1 -1
- package/dist/js/components/Table/EditableSelectInputCell.js.map +1 -1
- package/dist/js/components/Table/EditableTextCell.js.map +1 -1
- package/dist/js/components/Table/FavoritesCell.js.map +1 -1
- package/dist/js/components/Table/HeaderCellInfoWrapper.js.map +1 -1
- package/dist/js/components/Table/RowWrapper.js +0 -1
- package/dist/js/components/Table/RowWrapper.js.map +1 -1
- package/dist/js/components/Table/SelectColumn.js +1 -1
- package/dist/js/components/Table/SelectColumn.js.map +1 -1
- package/dist/js/components/Table/SortColumn.js +1 -2
- package/dist/js/components/Table/SortColumn.js.map +1 -1
- package/dist/js/components/Table/Table.js.map +1 -1
- package/dist/js/components/Table/TableText.js +2 -2
- package/dist/js/components/Table/TableText.js.map +1 -1
- package/dist/js/components/Table/TableTypes.d.ts +22 -22
- package/dist/js/components/Table/TableTypes.d.ts.map +1 -1
- package/dist/js/components/Table/TableTypes.js +2 -6
- package/dist/js/components/Table/TableTypes.js.map +1 -1
- package/dist/js/components/Table/Td.js.map +1 -1
- package/dist/js/components/Table/Th.js.map +1 -1
- package/dist/js/components/Table/Tr.d.ts +2 -0
- package/dist/js/components/Table/Tr.d.ts.map +1 -1
- package/dist/js/components/Table/Tr.js +2 -2
- package/dist/js/components/Table/Tr.js.map +1 -1
- package/dist/js/components/Table/base/columns-are-equal.js.map +1 -1
- package/dist/js/components/Table/base/evaluate-transforms.js.map +1 -1
- package/dist/js/components/Table/base/merge-props.js.map +1 -1
- package/dist/js/components/Table/base/provider.js.map +1 -1
- package/dist/js/components/Table/base/types.d.ts +10 -10
- package/dist/js/components/Table/base/types.d.ts.map +1 -1
- package/dist/js/components/Table/base/types.js +0 -4
- package/dist/js/components/Table/base/types.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/compoundExpand.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/editable.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/favoritable.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/selectable.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/sortable.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/treeRow.js.map +1 -1
- package/dist/js/components/Table/utils/headerUtils.js.map +1 -1
- package/dist/js/components/Table/utils/transformers.js +1 -1
- package/dist/js/components/Table/utils/transformers.js.map +1 -1
- package/dist/js/components/Table/utils/utils.js.map +1 -1
- package/dist/js/demos/DashboardHeader.js.map +1 -1
- package/dist/js/demos/DashboardWrapper.js.map +1 -1
- package/dist/js/deprecated/components/Table/Body.d.ts +1 -1
- package/dist/js/deprecated/components/Table/Body.d.ts.map +1 -1
- package/dist/js/deprecated/components/Table/Body.js.map +1 -1
- package/dist/js/deprecated/components/Table/BodyCell.js +0 -1
- package/dist/js/deprecated/components/Table/BodyCell.js.map +1 -1
- package/dist/js/deprecated/components/Table/BodyWrapper.js.map +1 -1
- package/dist/js/deprecated/components/Table/Table.js.map +1 -1
- package/dist/js/deprecated/components/Table/base/body-row.js.map +1 -1
- package/dist/js/deprecated/components/Table/base/body.js.map +1 -1
- package/dist/js/deprecated/components/Table/base/header-row.js +1 -1
- package/dist/js/deprecated/components/Table/base/header-row.js.map +1 -1
- package/dist/js/deprecated/components/Table/base/resolve-row-key.js.map +1 -1
- package/dist/js/test-helpers/data-helpers.js.map +1 -1
- package/dist/umd/assets/output-CFB2Aorq.css +30664 -0
- package/dist/umd/react-table.min.js +4 -5
- package/package.json +8 -11
- package/rollup.config.mjs +8 -0
- package/src/components/Table/TableTypes.tsx +5 -6
- package/src/components/Table/Tr.tsx +4 -0
- package/src/components/Table/examples/Table.md +11 -0
- package/src/components/Table/examples/TableActionsOverflow.tsx +0 -1
- package/src/components/Table/examples/TableCompoundExpandable.tsx +1 -1
- package/src/components/Table/examples/TableEditable.tsx +313 -0
- package/src/components/Table/examples/TableExpandable.tsx +0 -1
- package/src/components/Table/utils/__snapshots__/transformers.test.tsx.snap +2 -2
- package/src/components/Table/utils/transformers.test.tsx +1 -1
- package/src/components/Table/utils/transformers.tsx +1 -1
- package/src/demos/examples/TableColumnManagement.tsx +1 -1
- package/src/demos/examples/TableColumnManagementWithDraggable.tsx +1 -1
- package/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +57 -6
- package/src/deprecated/components/Table/base/header-row.tsx +1 -1
- package/src/deprecated/components/Table/examples/Table.md +36 -18
- package/rollup.config.js +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-table",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.1",
|
|
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",
|
|
@@ -39,19 +39,16 @@
|
|
|
39
39
|
"subpaths": "node ../../scripts/exportSubpaths.js --config subpaths.config.json"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@patternfly/react-core": "^5.4.
|
|
43
|
-
"@patternfly/react-icons": "^5.4.0
|
|
44
|
-
"@patternfly/react-styles": "^5.4.0
|
|
45
|
-
"@patternfly/react-tokens": "^5.4.0
|
|
46
|
-
"lodash": "^4.17.
|
|
47
|
-
"tslib": "^2.
|
|
48
|
-
},
|
|
49
|
-
"devDependencies": {
|
|
50
|
-
"typescript": "^4.7.4"
|
|
42
|
+
"@patternfly/react-core": "^5.4.1",
|
|
43
|
+
"@patternfly/react-icons": "^5.4.0",
|
|
44
|
+
"@patternfly/react-styles": "^5.4.0",
|
|
45
|
+
"@patternfly/react-tokens": "^5.4.0",
|
|
46
|
+
"lodash": "^4.17.21",
|
|
47
|
+
"tslib": "^2.6.3"
|
|
51
48
|
},
|
|
52
49
|
"peerDependencies": {
|
|
53
50
|
"react": "^17 || ^18",
|
|
54
51
|
"react-dom": "^17 || ^18"
|
|
55
52
|
},
|
|
56
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "6796622fd206340b01366ccb89758f9897427e60"
|
|
57
54
|
}
|
|
@@ -82,7 +82,6 @@ export type OnCheckChange = (
|
|
|
82
82
|
// Todo: Update type with next breaking change release
|
|
83
83
|
// export type IHeaderRow = ColumnType;
|
|
84
84
|
|
|
85
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
86
85
|
export interface IHeaderRow extends ColumnType {}
|
|
87
86
|
|
|
88
87
|
export interface IRowData extends IRow {
|
|
@@ -138,7 +137,7 @@ export interface IExtra extends IExtraData {
|
|
|
138
137
|
}
|
|
139
138
|
|
|
140
139
|
export type IFormatterValueType = formatterValueType & {
|
|
141
|
-
title?:
|
|
140
|
+
title?: React.ReactNode;
|
|
142
141
|
props?: any;
|
|
143
142
|
};
|
|
144
143
|
|
|
@@ -157,7 +156,7 @@ export interface IAction extends Omit<DropdownItemProps, 'title' | 'onClick'>, P
|
|
|
157
156
|
/** Key of actions menu item */
|
|
158
157
|
itemKey?: string;
|
|
159
158
|
/** Content to display in the actions menu item */
|
|
160
|
-
title?:
|
|
159
|
+
title?: React.ReactNode;
|
|
161
160
|
/** Render item as aria-disabled option */
|
|
162
161
|
isAriaDisabled?: boolean;
|
|
163
162
|
/** Props for adding a tooltip to a menu item. This is used to display tooltip when hovered over the item */
|
|
@@ -191,7 +190,7 @@ export interface decoratorReturnType {
|
|
|
191
190
|
textCenter?: boolean;
|
|
192
191
|
component?: string;
|
|
193
192
|
isVisible?: boolean;
|
|
194
|
-
title?:
|
|
193
|
+
title?: React.ReactNode;
|
|
195
194
|
props?: any;
|
|
196
195
|
scope?: string;
|
|
197
196
|
parentId?: number;
|
|
@@ -205,7 +204,7 @@ export type IFormatter = (data?: IFormatterValueType, extra?: IExtra) => formatt
|
|
|
205
204
|
|
|
206
205
|
export interface ICell {
|
|
207
206
|
/* cell contents */
|
|
208
|
-
title?:
|
|
207
|
+
title?: React.ReactNode;
|
|
209
208
|
/** transformations applied to the header cell */
|
|
210
209
|
transforms?: ITransform[];
|
|
211
210
|
/** transformations applied to the cells within the column's body */
|
|
@@ -229,7 +228,7 @@ export interface ICell {
|
|
|
229
228
|
export type RowCellContent<T = any> = (value?: string, rowIndex?: number, cellIndex?: number, props?: T) => void;
|
|
230
229
|
|
|
231
230
|
export interface IRowCell<T = any> {
|
|
232
|
-
title?:
|
|
231
|
+
title?: React.ReactNode | RowCellContent<T>;
|
|
233
232
|
props?: T;
|
|
234
233
|
formatters?: IFormatter[];
|
|
235
234
|
}
|
|
@@ -28,6 +28,8 @@ export interface TrProps extends Omit<React.HTMLProps<HTMLTableRowElement>, 'onR
|
|
|
28
28
|
isStriped?: boolean;
|
|
29
29
|
/** Flag indicating the row will act as a border. This is typically used for a table with a nested and sticky header. */
|
|
30
30
|
isBorderRow?: boolean;
|
|
31
|
+
/** Flag indicating the row is controlling the expansion of another row. */
|
|
32
|
+
isControlRow?: boolean;
|
|
31
33
|
/** An event handler for the row */
|
|
32
34
|
onRowClick?: (event?: React.KeyboardEvent | React.MouseEvent) => void;
|
|
33
35
|
/** Flag indicating that the row is selectable */
|
|
@@ -50,6 +52,7 @@ const TrBase: React.FunctionComponent<TrProps> = ({
|
|
|
50
52
|
isRowSelected = false,
|
|
51
53
|
isStriped = false,
|
|
52
54
|
isBorderRow = false,
|
|
55
|
+
isControlRow = false,
|
|
53
56
|
innerRef,
|
|
54
57
|
ouiaId,
|
|
55
58
|
ouiaSafe = true,
|
|
@@ -100,6 +103,7 @@ const TrBase: React.FunctionComponent<TrProps> = ({
|
|
|
100
103
|
isRowSelected && styles.modifiers.selected,
|
|
101
104
|
isStriped && styles.modifiers.striped,
|
|
102
105
|
isBorderRow && styles.modifiers.borderRow,
|
|
106
|
+
isControlRow && styles.tableControlRow,
|
|
103
107
|
resetOffset && styles.modifiers.firstCellOffsetReset
|
|
104
108
|
)}
|
|
105
109
|
hidden={rowIsHidden}
|
|
@@ -51,11 +51,15 @@ import FolderOpenIcon from '@patternfly/react-icons/dist/esm/icons/folder-open-i
|
|
|
51
51
|
import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon';
|
|
52
52
|
import BlueprintIcon from '@patternfly/react-icons/dist/esm/icons/blueprint-icon';
|
|
53
53
|
import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
|
|
54
|
+
import PencilAltIcon from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon';
|
|
55
|
+
import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon';
|
|
56
|
+
import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
|
|
54
57
|
|
|
55
58
|
import { css } from '@patternfly/react-styles';
|
|
56
59
|
import styles from '@patternfly/react-styles/css/components/Table/table';
|
|
57
60
|
import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing';
|
|
58
61
|
import textStyles from '@patternfly/react-styles/css/utilities/Text/text';
|
|
62
|
+
import inlineEditStyles from '@patternfly/react-styles/css/components/InlineEdit/inline-edit';
|
|
59
63
|
import global_BackgroundColor_150 from '@patternfly/react-tokens/dist/esm/global_BackgroundColor_150';
|
|
60
64
|
|
|
61
65
|
## Table examples
|
|
@@ -156,6 +160,13 @@ This selectable rows feature is intended for use when a table is used to present
|
|
|
156
160
|
```ts file="TableClickable.tsx"
|
|
157
161
|
```
|
|
158
162
|
|
|
163
|
+
### Editable rows
|
|
164
|
+
|
|
165
|
+
This example shows a table with editable rows. Cells in a row can be edited after clicking on the edit icon.
|
|
166
|
+
|
|
167
|
+
```ts file="TableEditable.tsx"
|
|
168
|
+
```
|
|
169
|
+
|
|
159
170
|
### Actions
|
|
160
171
|
|
|
161
172
|
This example demonstrates adding actions as the last column. The header's last cell is an empty cell, and each body row's last cell is an action cell.
|
|
@@ -75,7 +75,7 @@ export const TableCompoundExpandable: React.FunctionComponent = () => {
|
|
|
75
75
|
const isRowExpanded = !!expandedCellKey;
|
|
76
76
|
return (
|
|
77
77
|
<Tbody key={repo.name} isExpanded={isRowExpanded}>
|
|
78
|
-
<Tr>
|
|
78
|
+
<Tr isControlRow>
|
|
79
79
|
<Td width={25} dataLabel={columnNames.name} component="th">
|
|
80
80
|
<a href="#">{repo.name}</a>
|
|
81
81
|
</Td>
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
|
|
3
|
+
import { Button, Checkbox, Radio, TextInput, KeyTypes, getUniqueId } from '@patternfly/react-core';
|
|
4
|
+
import PencilAltIcon from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon';
|
|
5
|
+
import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon';
|
|
6
|
+
import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
|
|
7
|
+
import inlineEditStyles from '@patternfly/react-styles/css/components/InlineEdit/inline-edit';
|
|
8
|
+
import { css } from '@patternfly/react-styles';
|
|
9
|
+
|
|
10
|
+
interface EditButtonsCellProps {
|
|
11
|
+
onClick: (type: 'save' | 'cancel' | 'edit') => void;
|
|
12
|
+
elementToFocusOnEditRef?: React.MutableRefObject<HTMLElement>;
|
|
13
|
+
rowAriaLabel: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const EditButtonsCell: React.FunctionComponent<EditButtonsCellProps> = ({
|
|
17
|
+
onClick,
|
|
18
|
+
elementToFocusOnEditRef,
|
|
19
|
+
rowAriaLabel = 'row'
|
|
20
|
+
}) => {
|
|
21
|
+
const editButtonRef = React.useRef<HTMLButtonElement>();
|
|
22
|
+
|
|
23
|
+
const onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>, button: 'edit' | 'stopEditing') => {
|
|
24
|
+
const focusRef = button === 'edit' ? elementToFocusOnEditRef : editButtonRef;
|
|
25
|
+
|
|
26
|
+
if (event.key === KeyTypes.Enter || event.key === KeyTypes.Space) {
|
|
27
|
+
// because space key triggers click event before keyDown, we have to prevent default behaviour and trigger click manually
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
(event.target as HTMLButtonElement).click();
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
focusRef?.current?.focus();
|
|
32
|
+
}, 0);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
<Td
|
|
39
|
+
dataLabel="Save and cancel buttons"
|
|
40
|
+
className={css(
|
|
41
|
+
inlineEditStyles.inlineEditGroup,
|
|
42
|
+
inlineEditStyles.modifiers.iconGroup,
|
|
43
|
+
inlineEditStyles.modifiers.actionGroup
|
|
44
|
+
)}
|
|
45
|
+
>
|
|
46
|
+
<div className={css(inlineEditStyles.inlineEditAction, inlineEditStyles.modifiers.valid)}>
|
|
47
|
+
<Button
|
|
48
|
+
aria-label={`Save edits of ${rowAriaLabel}`}
|
|
49
|
+
onClick={() => onClick('save')}
|
|
50
|
+
onKeyDown={(event) => onKeyDown(event, 'stopEditing')}
|
|
51
|
+
variant="plain"
|
|
52
|
+
>
|
|
53
|
+
<CheckIcon />
|
|
54
|
+
</Button>
|
|
55
|
+
</div>
|
|
56
|
+
<div className={css(inlineEditStyles.inlineEditAction)}>
|
|
57
|
+
<Button
|
|
58
|
+
aria-label={`Discard edits of ${rowAriaLabel}`}
|
|
59
|
+
onClick={() => onClick('cancel')}
|
|
60
|
+
onKeyDown={(event) => onKeyDown(event, 'stopEditing')}
|
|
61
|
+
variant="plain"
|
|
62
|
+
>
|
|
63
|
+
<TimesIcon />
|
|
64
|
+
</Button>
|
|
65
|
+
</div>
|
|
66
|
+
</Td>
|
|
67
|
+
<Td
|
|
68
|
+
dataLabel="Edit button"
|
|
69
|
+
className={css(inlineEditStyles.inlineEditAction, inlineEditStyles.modifiers.enableEditable)}
|
|
70
|
+
>
|
|
71
|
+
<Button
|
|
72
|
+
ref={editButtonRef}
|
|
73
|
+
aria-label={`Edit ${rowAriaLabel}`}
|
|
74
|
+
onClick={() => onClick('edit')}
|
|
75
|
+
onKeyDown={(event) => onKeyDown(event, 'edit')}
|
|
76
|
+
variant="plain"
|
|
77
|
+
>
|
|
78
|
+
<PencilAltIcon />
|
|
79
|
+
</Button>
|
|
80
|
+
</Td>
|
|
81
|
+
</>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
interface EditableCellProps {
|
|
86
|
+
dataLabel: string;
|
|
87
|
+
staticValue: React.ReactNode;
|
|
88
|
+
editingValue: React.ReactNode;
|
|
89
|
+
role?: string;
|
|
90
|
+
ariaLabel?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const EditableCell: React.FunctionComponent<EditableCellProps> = ({
|
|
94
|
+
dataLabel,
|
|
95
|
+
staticValue,
|
|
96
|
+
editingValue,
|
|
97
|
+
role,
|
|
98
|
+
ariaLabel
|
|
99
|
+
}) => {
|
|
100
|
+
const hasMultipleInputs = Array.isArray(editingValue) && editingValue.every((elem) => React.isValidElement(elem));
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<Td dataLabel={dataLabel}>
|
|
104
|
+
<div className={css(inlineEditStyles.inlineEditValue)}>{staticValue}</div>
|
|
105
|
+
{hasMultipleInputs ? (
|
|
106
|
+
<div className={css(inlineEditStyles.inlineEditGroup, 'pf-m-column')} role={role} aria-label={ariaLabel}>
|
|
107
|
+
{(editingValue as React.ReactElement[]).map((elem, index) => (
|
|
108
|
+
<div key={index} className={css(inlineEditStyles.inlineEditInput)}>
|
|
109
|
+
{elem}
|
|
110
|
+
</div>
|
|
111
|
+
))}
|
|
112
|
+
</div>
|
|
113
|
+
) : (
|
|
114
|
+
<div className={css(inlineEditStyles.inlineEditInput)}>{editingValue}</div>
|
|
115
|
+
)}
|
|
116
|
+
</Td>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
interface EditableRow {
|
|
121
|
+
data: CustomData;
|
|
122
|
+
columnNames: ColumnNames<CustomData>;
|
|
123
|
+
dataOptions?: CustomDataOptions;
|
|
124
|
+
saveChanges: (editedData: CustomData) => void;
|
|
125
|
+
ariaLabel: string;
|
|
126
|
+
rowIndex?: number;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const EditableRow: React.FunctionComponent<EditableRow> = ({
|
|
130
|
+
data,
|
|
131
|
+
columnNames,
|
|
132
|
+
dataOptions,
|
|
133
|
+
saveChanges,
|
|
134
|
+
ariaLabel,
|
|
135
|
+
rowIndex
|
|
136
|
+
}) => {
|
|
137
|
+
const [editable, setEditable] = React.useState(false);
|
|
138
|
+
const [editedData, setEditedData] = React.useState(data);
|
|
139
|
+
|
|
140
|
+
const inputRef = React.useRef();
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<Tr className={css(inlineEditStyles.inlineEdit, editable ? inlineEditStyles.modifiers.inlineEditable : '')}>
|
|
144
|
+
<EditableCell
|
|
145
|
+
dataLabel={columnNames.textInput}
|
|
146
|
+
staticValue={data.textInput}
|
|
147
|
+
editingValue={
|
|
148
|
+
<TextInput
|
|
149
|
+
aria-label={`${columnNames.textInput} ${ariaLabel}`}
|
|
150
|
+
ref={inputRef}
|
|
151
|
+
value={editedData.textInput}
|
|
152
|
+
onChange={(e) => setEditedData((data) => ({ ...data, textInput: (e.target as HTMLInputElement).value }))}
|
|
153
|
+
/>
|
|
154
|
+
}
|
|
155
|
+
/>
|
|
156
|
+
<EditableCell
|
|
157
|
+
dataLabel={columnNames.textInputDisabled}
|
|
158
|
+
staticValue={data.textInputDisabled}
|
|
159
|
+
editingValue={
|
|
160
|
+
<TextInput
|
|
161
|
+
aria-label={`${columnNames.textInputDisabled} ${ariaLabel}`}
|
|
162
|
+
isDisabled={true}
|
|
163
|
+
value={editedData.textInputDisabled ?? ''}
|
|
164
|
+
/>
|
|
165
|
+
}
|
|
166
|
+
/>
|
|
167
|
+
<EditableCell
|
|
168
|
+
dataLabel={columnNames.checkboxes}
|
|
169
|
+
staticValue={data.checkboxes.join(', ')}
|
|
170
|
+
role="group"
|
|
171
|
+
ariaLabel={`Checkbox group row ${rowIndex}`}
|
|
172
|
+
editingValue={dataOptions?.checkboxes.map((option) => {
|
|
173
|
+
const id = getUniqueId('checkbox');
|
|
174
|
+
return (
|
|
175
|
+
<Checkbox
|
|
176
|
+
key={id}
|
|
177
|
+
name={id}
|
|
178
|
+
id={id}
|
|
179
|
+
label={option}
|
|
180
|
+
isChecked={editedData.checkboxes.includes(option)}
|
|
181
|
+
onChange={(_e, checked) =>
|
|
182
|
+
setEditedData((data) => ({
|
|
183
|
+
...data,
|
|
184
|
+
checkboxes: checked ? [...data.checkboxes, option] : data.checkboxes.filter((item) => item !== option)
|
|
185
|
+
}))
|
|
186
|
+
}
|
|
187
|
+
/>
|
|
188
|
+
);
|
|
189
|
+
})}
|
|
190
|
+
/>
|
|
191
|
+
<EditableCell
|
|
192
|
+
dataLabel={columnNames.radios}
|
|
193
|
+
staticValue={data.radios}
|
|
194
|
+
ariaLabel={`Radio button group row ${rowIndex}`}
|
|
195
|
+
role="radiogroup"
|
|
196
|
+
editingValue={dataOptions?.radios.map((option) => {
|
|
197
|
+
const id = getUniqueId('radio');
|
|
198
|
+
return (
|
|
199
|
+
<Radio
|
|
200
|
+
key={id}
|
|
201
|
+
name={id}
|
|
202
|
+
id={id}
|
|
203
|
+
label={option}
|
|
204
|
+
isChecked={editedData.radios === option}
|
|
205
|
+
onChange={() => setEditedData((data) => ({ ...data, radios: option }))}
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
})}
|
|
209
|
+
/>
|
|
210
|
+
<EditButtonsCell
|
|
211
|
+
onClick={(type) => {
|
|
212
|
+
type === 'edit' ? setEditable(true) : setEditable(false);
|
|
213
|
+
type === 'save' && saveChanges(editedData);
|
|
214
|
+
type === 'cancel' && setEditedData(data);
|
|
215
|
+
}}
|
|
216
|
+
rowAriaLabel={ariaLabel}
|
|
217
|
+
elementToFocusOnEditRef={inputRef}
|
|
218
|
+
/>
|
|
219
|
+
</Tr>
|
|
220
|
+
);
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
interface CustomData {
|
|
224
|
+
textInput: string;
|
|
225
|
+
textInputDisabled: string | null;
|
|
226
|
+
checkboxes: string[];
|
|
227
|
+
radios: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
interface CustomDataOptions {
|
|
231
|
+
checkboxes: string[];
|
|
232
|
+
radios: string[];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
type ColumnNames<T> = { [K in keyof T]: string };
|
|
236
|
+
|
|
237
|
+
export const TableEditable: React.FunctionComponent = () => {
|
|
238
|
+
// In real usage, this data would come from some external source like an API via props.
|
|
239
|
+
const initialRows: CustomData[] = [
|
|
240
|
+
{
|
|
241
|
+
textInput: 'Editable text 1',
|
|
242
|
+
textInputDisabled: 'Non-editable text 1',
|
|
243
|
+
checkboxes: ['Option A'],
|
|
244
|
+
radios: 'Option A'
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
textInput: 'Editable text 2',
|
|
248
|
+
textInputDisabled: null,
|
|
249
|
+
checkboxes: [],
|
|
250
|
+
radios: 'Option B'
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
textInput: 'Editable text 3',
|
|
254
|
+
textInputDisabled: 'Non-editable text 3',
|
|
255
|
+
checkboxes: ['Option A', 'Option B'],
|
|
256
|
+
radios: 'Option A'
|
|
257
|
+
}
|
|
258
|
+
];
|
|
259
|
+
|
|
260
|
+
// List of all selectable options for some cells of initialRows
|
|
261
|
+
const initialRowsOptions: CustomDataOptions[] = [
|
|
262
|
+
{
|
|
263
|
+
checkboxes: ['Option A', 'Option B', 'Option C'],
|
|
264
|
+
radios: ['Option A', 'Option B']
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
checkboxes: ['Option A', 'Option B'],
|
|
268
|
+
radios: ['Option A', 'Option B', 'Option C']
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
checkboxes: ['Option A', 'Option B'],
|
|
272
|
+
radios: ['Option A', 'Option B']
|
|
273
|
+
}
|
|
274
|
+
];
|
|
275
|
+
|
|
276
|
+
const [rows, setRows] = React.useState(initialRows);
|
|
277
|
+
|
|
278
|
+
const columnNames: ColumnNames<CustomData> = {
|
|
279
|
+
textInput: 'Text input',
|
|
280
|
+
textInputDisabled: 'Disabled text input',
|
|
281
|
+
checkboxes: 'Checkboxes',
|
|
282
|
+
radios: 'Radios'
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
return (
|
|
286
|
+
<Table aria-label="Editable table">
|
|
287
|
+
<Thead>
|
|
288
|
+
<Tr>
|
|
289
|
+
<Th>{columnNames.textInput}</Th>
|
|
290
|
+
<Th>{columnNames.textInputDisabled}</Th>
|
|
291
|
+
<Th>{columnNames.checkboxes}</Th>
|
|
292
|
+
<Th>{columnNames.radios}</Th>
|
|
293
|
+
<Th screenReaderText="Row edit actions" />
|
|
294
|
+
</Tr>
|
|
295
|
+
</Thead>
|
|
296
|
+
<Tbody>
|
|
297
|
+
{rows.map((data, index) => (
|
|
298
|
+
<EditableRow
|
|
299
|
+
key={index}
|
|
300
|
+
data={data}
|
|
301
|
+
rowIndex={index}
|
|
302
|
+
dataOptions={initialRowsOptions[index]}
|
|
303
|
+
columnNames={columnNames}
|
|
304
|
+
saveChanges={(editedRow) => {
|
|
305
|
+
setRows((rows) => rows.map((row, i) => (i === index ? editedRow : row)));
|
|
306
|
+
}}
|
|
307
|
+
ariaLabel={`row ${index + 1}`}
|
|
308
|
+
></EditableRow>
|
|
309
|
+
))}
|
|
310
|
+
</Tbody>
|
|
311
|
+
</Table>
|
|
312
|
+
);
|
|
313
|
+
};
|
|
@@ -16,7 +16,6 @@ interface Repository {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
19
|
export const TableExpandable: React.FunctionComponent = () => {
|
|
21
20
|
// In real usage, this data would come from some external source like an API via props.
|
|
22
21
|
const repositories: Repository[] = [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`Transformer functions selectable unselected 1`] = `
|
|
4
|
-
|
|
4
|
+
{
|
|
5
5
|
"children": <SelectColumn
|
|
6
6
|
aria-label="Select row 0"
|
|
7
7
|
checked={false}
|
|
@@ -17,7 +17,7 @@ Object {
|
|
|
17
17
|
`;
|
|
18
18
|
|
|
19
19
|
exports[`Transformer functions sortable asc 1`] = `
|
|
20
|
-
|
|
20
|
+
{
|
|
21
21
|
"aria-sort": "ascending",
|
|
22
22
|
"children": <SortColumn
|
|
23
23
|
isSortedBy={true}
|
|
@@ -9,7 +9,7 @@ export const scopeColTransformer: ITransform = () => ({
|
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
export const emptyCol: ITransform = (label: IFormatterValueType) => ({
|
|
12
|
-
...(label ? {} : { scope:
|
|
12
|
+
...(label ? {} : { scope: null })
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
export const parentId: ITransform = (_value: IFormatterValueType, { rowData }: IExtra) => ({
|
|
@@ -225,7 +225,7 @@ export const TableColumnManagement: React.FunctionComponent = () => {
|
|
|
225
225
|
<Button key="save" variant="primary" onClick={onSave}>
|
|
226
226
|
Save
|
|
227
227
|
</Button>,
|
|
228
|
-
<Button key="cancel" variant="
|
|
228
|
+
<Button key="cancel" variant="link" onClick={handleModalToggle}>
|
|
229
229
|
Cancel
|
|
230
230
|
</Button>
|
|
231
231
|
]}
|
|
@@ -439,7 +439,7 @@ export const TableColumnManagementWithDraggable: React.FunctionComponent = () =>
|
|
|
439
439
|
<Button key="save" variant="primary" onClick={onSave}>
|
|
440
440
|
Save
|
|
441
441
|
</Button>,
|
|
442
|
-
<Button key="cancel" variant="
|
|
442
|
+
<Button key="cancel" variant="link" onClick={handleModalToggle}>
|
|
443
443
|
Cancel
|
|
444
444
|
</Button>
|
|
445
445
|
]}
|