@patternfly/react-table 5.4.0-prerelease.3 → 5.4.0-prerelease.30

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.
Files changed (120) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/README.md +2 -17
  3. package/components/package.json +1 -1
  4. package/deprecated/package.json +1 -1
  5. package/dist/dynamic/components/Table/package.json +1 -1
  6. package/dist/dynamic/components/Table/utils/decorators/package.json +1 -1
  7. package/dist/dynamic/components/Table/utils/package.json +1 -1
  8. package/dist/dynamic/deprecated/components/Table/base/package.json +1 -1
  9. package/dist/dynamic/deprecated/components/Table/package.json +1 -1
  10. package/dist/dynamic/deprecated/components/package.json +1 -1
  11. package/dist/esm/components/Table/ActionsColumn.js.map +1 -1
  12. package/dist/esm/components/Table/RowWrapper.js.map +1 -1
  13. package/dist/esm/components/Table/SortColumn.js.map +1 -1
  14. package/dist/esm/components/Table/Table.js.map +1 -1
  15. package/dist/esm/components/Table/TableText.js.map +1 -1
  16. package/dist/esm/components/Table/TableTypes.d.ts +22 -22
  17. package/dist/esm/components/Table/TableTypes.d.ts.map +1 -1
  18. package/dist/esm/components/Table/Td.js.map +1 -1
  19. package/dist/esm/components/Table/Th.js.map +1 -1
  20. package/dist/esm/components/Table/Tr.d.ts +2 -0
  21. package/dist/esm/components/Table/Tr.d.ts.map +1 -1
  22. package/dist/esm/components/Table/Tr.js +2 -2
  23. package/dist/esm/components/Table/Tr.js.map +1 -1
  24. package/dist/esm/components/Table/base/columns-are-equal.js.map +1 -1
  25. package/dist/esm/components/Table/base/evaluate-transforms.js.map +1 -1
  26. package/dist/esm/components/Table/base/merge-props.js.map +1 -1
  27. package/dist/esm/components/Table/base/provider.js.map +1 -1
  28. package/dist/esm/components/Table/base/types.d.ts +10 -10
  29. package/dist/esm/components/Table/base/types.d.ts.map +1 -1
  30. package/dist/esm/components/Table/utils/decorators/compoundExpand.js.map +1 -1
  31. package/dist/esm/components/Table/utils/decorators/editable.js.map +1 -1
  32. package/dist/esm/components/Table/utils/decorators/favoritable.js.map +1 -1
  33. package/dist/esm/components/Table/utils/decorators/selectable.js.map +1 -1
  34. package/dist/esm/components/Table/utils/decorators/sortable.js.map +1 -1
  35. package/dist/esm/components/Table/utils/headerUtils.js.map +1 -1
  36. package/dist/esm/components/Table/utils/utils.js.map +1 -1
  37. package/dist/esm/demos/DashboardWrapper.js.map +1 -1
  38. package/dist/esm/deprecated/components/Table/Body.d.ts +1 -1
  39. package/dist/esm/deprecated/components/Table/Body.d.ts.map +1 -1
  40. package/dist/esm/deprecated/components/Table/Body.js.map +1 -1
  41. package/dist/esm/deprecated/components/Table/BodyCell.js.map +1 -1
  42. package/dist/esm/deprecated/components/Table/BodyWrapper.js.map +1 -1
  43. package/dist/esm/deprecated/components/Table/Table.js.map +1 -1
  44. package/dist/esm/deprecated/components/Table/base/body-row.js.map +1 -1
  45. package/dist/esm/deprecated/components/Table/base/body.js.map +1 -1
  46. package/dist/esm/deprecated/components/Table/base/header-row.js.map +1 -1
  47. package/dist/esm/deprecated/components/Table/base/resolve-row-key.js.map +1 -1
  48. package/dist/esm/test-helpers/data-helpers.js.map +1 -1
  49. package/dist/js/components/Table/ActionsColumn.js.map +1 -1
  50. package/dist/js/components/Table/CollapseColumn.js.map +1 -1
  51. package/dist/js/components/Table/DraggableCell.js.map +1 -1
  52. package/dist/js/components/Table/EditColumn.js.map +1 -1
  53. package/dist/js/components/Table/EditableSelectInputCell.js.map +1 -1
  54. package/dist/js/components/Table/EditableTextCell.js.map +1 -1
  55. package/dist/js/components/Table/FavoritesCell.js.map +1 -1
  56. package/dist/js/components/Table/HeaderCellInfoWrapper.js.map +1 -1
  57. package/dist/js/components/Table/RowWrapper.js +0 -1
  58. package/dist/js/components/Table/RowWrapper.js.map +1 -1
  59. package/dist/js/components/Table/SelectColumn.js +1 -1
  60. package/dist/js/components/Table/SelectColumn.js.map +1 -1
  61. package/dist/js/components/Table/SortColumn.js +1 -2
  62. package/dist/js/components/Table/SortColumn.js.map +1 -1
  63. package/dist/js/components/Table/Table.js.map +1 -1
  64. package/dist/js/components/Table/TableText.js +2 -2
  65. package/dist/js/components/Table/TableText.js.map +1 -1
  66. package/dist/js/components/Table/TableTypes.d.ts +22 -22
  67. package/dist/js/components/Table/TableTypes.d.ts.map +1 -1
  68. package/dist/js/components/Table/TableTypes.js +2 -6
  69. package/dist/js/components/Table/TableTypes.js.map +1 -1
  70. package/dist/js/components/Table/Td.js.map +1 -1
  71. package/dist/js/components/Table/Th.js.map +1 -1
  72. package/dist/js/components/Table/Tr.d.ts +2 -0
  73. package/dist/js/components/Table/Tr.d.ts.map +1 -1
  74. package/dist/js/components/Table/Tr.js +2 -2
  75. package/dist/js/components/Table/Tr.js.map +1 -1
  76. package/dist/js/components/Table/base/columns-are-equal.js.map +1 -1
  77. package/dist/js/components/Table/base/evaluate-transforms.js.map +1 -1
  78. package/dist/js/components/Table/base/merge-props.js.map +1 -1
  79. package/dist/js/components/Table/base/provider.js.map +1 -1
  80. package/dist/js/components/Table/base/types.d.ts +10 -10
  81. package/dist/js/components/Table/base/types.d.ts.map +1 -1
  82. package/dist/js/components/Table/base/types.js +0 -4
  83. package/dist/js/components/Table/base/types.js.map +1 -1
  84. package/dist/js/components/Table/utils/decorators/compoundExpand.js.map +1 -1
  85. package/dist/js/components/Table/utils/decorators/editable.js.map +1 -1
  86. package/dist/js/components/Table/utils/decorators/favoritable.js.map +1 -1
  87. package/dist/js/components/Table/utils/decorators/selectable.js.map +1 -1
  88. package/dist/js/components/Table/utils/decorators/sortable.js.map +1 -1
  89. package/dist/js/components/Table/utils/decorators/treeRow.js.map +1 -1
  90. package/dist/js/components/Table/utils/headerUtils.js.map +1 -1
  91. package/dist/js/components/Table/utils/utils.js.map +1 -1
  92. package/dist/js/demos/DashboardHeader.js.map +1 -1
  93. package/dist/js/demos/DashboardWrapper.js.map +1 -1
  94. package/dist/js/deprecated/components/Table/Body.d.ts +1 -1
  95. package/dist/js/deprecated/components/Table/Body.d.ts.map +1 -1
  96. package/dist/js/deprecated/components/Table/Body.js.map +1 -1
  97. package/dist/js/deprecated/components/Table/BodyCell.js +0 -1
  98. package/dist/js/deprecated/components/Table/BodyCell.js.map +1 -1
  99. package/dist/js/deprecated/components/Table/BodyWrapper.js.map +1 -1
  100. package/dist/js/deprecated/components/Table/Table.js.map +1 -1
  101. package/dist/js/deprecated/components/Table/base/body-row.js.map +1 -1
  102. package/dist/js/deprecated/components/Table/base/body.js.map +1 -1
  103. package/dist/js/deprecated/components/Table/base/header-row.js.map +1 -1
  104. package/dist/js/deprecated/components/Table/base/resolve-row-key.js.map +1 -1
  105. package/dist/js/test-helpers/data-helpers.js.map +1 -1
  106. package/dist/umd/assets/output-C9SGt1J5.css +30664 -0
  107. package/dist/umd/react-table.min.js +4 -5
  108. package/package.json +8 -11
  109. package/rollup.config.mjs +8 -0
  110. package/src/components/Table/TableTypes.tsx +5 -5
  111. package/src/components/Table/Tr.tsx +4 -0
  112. package/src/components/Table/examples/Table.md +11 -0
  113. package/src/components/Table/examples/TableCompoundExpandable.tsx +1 -1
  114. package/src/components/Table/examples/TableEditable.tsx +313 -0
  115. package/src/components/Table/utils/__snapshots__/transformers.test.tsx.snap +2 -2
  116. package/src/demos/examples/TableColumnManagement.tsx +1 -1
  117. package/src/demos/examples/TableColumnManagementWithDraggable.tsx +1 -1
  118. package/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +57 -0
  119. package/src/deprecated/components/Table/examples/Table.md +36 -18
  120. 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.0-prerelease.3",
3
+ "version": "5.4.0-prerelease.30",
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.0-prerelease.3",
43
- "@patternfly/react-icons": "^5.4.0-prerelease.1",
44
- "@patternfly/react-styles": "^5.4.0-prerelease.1",
45
- "@patternfly/react-tokens": "^5.4.0-prerelease.1",
46
- "lodash": "^4.17.19",
47
- "tslib": "^2.5.0"
48
- },
49
- "devDependencies": {
50
- "typescript": "^4.7.4"
42
+ "@patternfly/react-core": "^5.4.0-prerelease.27",
43
+ "@patternfly/react-icons": "^5.4.0-prerelease.10",
44
+ "@patternfly/react-styles": "^5.4.0-prerelease.11",
45
+ "@patternfly/react-tokens": "^5.4.0-prerelease.10",
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": "75849b05bb14b3d8f50535a92a65136b4a2cb13b"
53
+ "gitHead": "0781d69df6e3426e8973572c587e1f51b5ce693e"
57
54
  }
@@ -0,0 +1,8 @@
1
+ // @ts-check
2
+ import baseConfig from '../rollup.base.mjs';
3
+ import pkg from './package.json' with { type: 'json' };
4
+
5
+ export default baseConfig({
6
+ packageName: pkg.name.replace('@patternfly/', ''),
7
+ name: 'PatternFlyTable'
8
+ });
@@ -138,7 +138,7 @@ export interface IExtra extends IExtraData {
138
138
  }
139
139
 
140
140
  export type IFormatterValueType = formatterValueType & {
141
- title?: string | React.ReactNode;
141
+ title?: React.ReactNode;
142
142
  props?: any;
143
143
  };
144
144
 
@@ -157,7 +157,7 @@ export interface IAction extends Omit<DropdownItemProps, 'title' | 'onClick'>, P
157
157
  /** Key of actions menu item */
158
158
  itemKey?: string;
159
159
  /** Content to display in the actions menu item */
160
- title?: string | React.ReactNode;
160
+ title?: React.ReactNode;
161
161
  /** Render item as aria-disabled option */
162
162
  isAriaDisabled?: boolean;
163
163
  /** Props for adding a tooltip to a menu item. This is used to display tooltip when hovered over the item */
@@ -191,7 +191,7 @@ export interface decoratorReturnType {
191
191
  textCenter?: boolean;
192
192
  component?: string;
193
193
  isVisible?: boolean;
194
- title?: string | React.ReactNode;
194
+ title?: React.ReactNode;
195
195
  props?: any;
196
196
  scope?: string;
197
197
  parentId?: number;
@@ -205,7 +205,7 @@ export type IFormatter = (data?: IFormatterValueType, extra?: IExtra) => formatt
205
205
 
206
206
  export interface ICell {
207
207
  /* cell contents */
208
- title?: string | React.ReactNode;
208
+ title?: React.ReactNode;
209
209
  /** transformations applied to the header cell */
210
210
  transforms?: ITransform[];
211
211
  /** transformations applied to the cells within the column's body */
@@ -229,7 +229,7 @@ export interface ICell {
229
229
  export type RowCellContent<T = any> = (value?: string, rowIndex?: number, cellIndex?: number, props?: T) => void;
230
230
 
231
231
  export interface IRowCell<T = any> {
232
- title?: string | React.ReactNode | RowCellContent<T>;
232
+ title?: React.ReactNode | RowCellContent<T>;
233
233
  props?: T;
234
234
  formatters?: IFormatter[];
235
235
  }
@@ -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
+ };
@@ -1,7 +1,7 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`Transformer functions selectable unselected 1`] = `
4
- Object {
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
- Object {
20
+ {
21
21
  "aria-sort": "ascending",
22
22
  "children": <SortColumn
23
23
  isSortedBy={true}
@@ -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="secondary" onClick={handleModalToggle}>
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="secondary" onClick={handleModalToggle}>
442
+ <Button key="cancel" variant="link" onClick={handleModalToggle}>
443
443
  Cancel
444
444
  </Button>
445
445
  ]}