@patternfly/react-table 4.61.21 → 4.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/esm/components/Table/Body.d.ts +4 -0
  3. package/dist/esm/components/Table/Body.d.ts.map +1 -1
  4. package/dist/esm/components/Table/Body.js.map +1 -1
  5. package/dist/esm/components/Table/Table.d.ts +4 -0
  6. package/dist/esm/components/Table/Table.d.ts.map +1 -1
  7. package/dist/esm/components/Table/Table.js.map +1 -1
  8. package/dist/esm/components/Table/base/provider.d.ts +4 -4
  9. package/dist/esm/components/Table/base/types.d.ts +4 -4
  10. package/dist/esm/components/TableComposable/TableComposable.d.ts +5 -1
  11. package/dist/esm/components/TableComposable/TableComposable.d.ts.map +1 -1
  12. package/dist/esm/components/TableComposable/TableComposable.js +3 -3
  13. package/dist/esm/components/TableComposable/TableComposable.js.map +1 -1
  14. package/dist/esm/components/TableComposable/Tbody.d.ts +5 -1
  15. package/dist/esm/components/TableComposable/Tbody.d.ts.map +1 -1
  16. package/dist/esm/components/TableComposable/Tbody.js +2 -2
  17. package/dist/esm/components/TableComposable/Tbody.js.map +1 -1
  18. package/dist/esm/components/TableComposable/Tr.d.ts +3 -1
  19. package/dist/esm/components/TableComposable/Tr.d.ts.map +1 -1
  20. package/dist/esm/components/TableComposable/Tr.js +2 -2
  21. package/dist/esm/components/TableComposable/Tr.js.map +1 -1
  22. package/dist/js/components/Table/Body.d.ts +4 -0
  23. package/dist/js/components/Table/Body.d.ts.map +1 -1
  24. package/dist/js/components/Table/Body.js.map +1 -1
  25. package/dist/js/components/Table/Table.d.ts +4 -0
  26. package/dist/js/components/Table/Table.d.ts.map +1 -1
  27. package/dist/js/components/Table/Table.js.map +1 -1
  28. package/dist/js/components/Table/base/provider.d.ts +4 -4
  29. package/dist/js/components/Table/base/types.d.ts +4 -4
  30. package/dist/js/components/TableComposable/TableComposable.d.ts +5 -1
  31. package/dist/js/components/TableComposable/TableComposable.d.ts.map +1 -1
  32. package/dist/js/components/TableComposable/TableComposable.js +3 -3
  33. package/dist/js/components/TableComposable/TableComposable.js.map +1 -1
  34. package/dist/js/components/TableComposable/Tbody.d.ts +5 -1
  35. package/dist/js/components/TableComposable/Tbody.d.ts.map +1 -1
  36. package/dist/js/components/TableComposable/Tbody.js +2 -2
  37. package/dist/js/components/TableComposable/Tbody.js.map +1 -1
  38. package/dist/js/components/TableComposable/Tr.d.ts +3 -1
  39. package/dist/js/components/TableComposable/Tr.d.ts.map +1 -1
  40. package/dist/js/components/TableComposable/Tr.js +2 -2
  41. package/dist/js/components/TableComposable/Tr.js.map +1 -1
  42. package/dist/umd/react-table.js +7 -7
  43. package/dist/umd/react-table.min.js +1 -1
  44. package/package.json +6 -6
  45. package/src/components/Table/Body.tsx +4 -0
  46. package/src/components/Table/Table.tsx +4 -0
  47. package/src/components/Table/examples/LegacyTableStriped.tsx +52 -0
  48. package/src/components/Table/examples/LegacyTableStripedCustomTr.tsx +52 -0
  49. package/src/components/Table/examples/LegacyTableStripedExpandable.tsx +174 -0
  50. package/src/components/Table/examples/Table.md +21 -0
  51. package/src/components/TableComposable/TableComposable.tsx +8 -0
  52. package/src/components/TableComposable/Tbody.tsx +17 -1
  53. package/src/components/TableComposable/Tr.tsx +4 -0
  54. package/src/components/TableComposable/examples/ComposableTable.md +28 -0
  55. package/src/components/TableComposable/examples/ComposableTableStriped.tsx +54 -0
  56. package/src/components/TableComposable/examples/ComposableTableStripedExpandable.tsx +200 -0
  57. package/src/components/TableComposable/examples/ComposableTableStripedMultipleTbody.tsx +120 -0
  58. package/src/components/TableComposable/examples/ComposableTableStripedTr.tsx +54 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-table",
3
- "version": "4.61.21",
3
+ "version": "4.62.0",
4
4
  "description": "This library provides a set of React table components for use with the PatternFly 4",
5
5
  "main": "dist/js/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -31,10 +31,10 @@
31
31
  "clean": "rimraf dist"
32
32
  },
33
33
  "dependencies": {
34
- "@patternfly/react-core": "^4.192.21",
35
- "@patternfly/react-icons": "^4.43.21",
36
- "@patternfly/react-styles": "^4.42.21",
37
- "@patternfly/react-tokens": "^4.44.21",
34
+ "@patternfly/react-core": "^4.193.0",
35
+ "@patternfly/react-icons": "^4.44.0",
36
+ "@patternfly/react-styles": "^4.43.0",
37
+ "@patternfly/react-tokens": "^4.45.0",
38
38
  "lodash": "^4.17.19",
39
39
  "tslib": "^2.0.0"
40
40
  },
@@ -46,5 +46,5 @@
46
46
  "react": "^16.8.0 || ^17.0.0",
47
47
  "react-dom": "^16.8.0 || ^17.0.0"
48
48
  },
49
- "gitHead": "a29d482c5848dda265c74301559f02ef0539ebcc"
49
+ "gitHead": "acfe91c96bf582f580d05d671f1fd979bd88d830"
50
50
  }
@@ -32,6 +32,10 @@ export interface TableBodyProps {
32
32
  onRowClick?: OnRowClick;
33
33
  /** @hide This prop should not be set manually */
34
34
  onRow?: Function;
35
+ /** Flag indicating the <tbody> contains oddly striped rows. */
36
+ isOddStriped?: boolean;
37
+ /** Flag indicating the <tbody> contains evenly striped rows. */
38
+ isEvenStriped?: boolean;
35
39
  }
36
40
 
37
41
  const flagVisibility = (rows: IRow[]) => {
@@ -114,6 +114,10 @@ export interface TableProps extends OUIAProps {
114
114
  isTreeTable?: boolean;
115
115
  /** Flag indicating this table is nested within another table */
116
116
  isNested?: boolean;
117
+ /** Flag indicating this table is striped */
118
+ isStriped?: boolean;
119
+ /** Flag indicating this table contains expandable rows to maintain proper striping */
120
+ isExpandable?: boolean;
117
121
  }
118
122
 
119
123
  export class Table extends React.Component<TableProps, {}> {
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import { Table, TableHeader, TableBody, TableProps } from '@patternfly/react-table';
3
+ interface Repository {
4
+ name: string;
5
+ branches: string;
6
+ prs: string;
7
+ workspaces: string;
8
+ lastCommit: string;
9
+ }
10
+
11
+ export const LegacyTableStriped: React.FunctionComponent = () => {
12
+ // In real usage, this data would come from some external source like an API via props.
13
+ const repositories: Repository[] = [
14
+ {
15
+ name: 'Repository one',
16
+ branches: 'Branch one',
17
+ prs: 'PR one',
18
+ workspaces: 'Workspace one',
19
+ lastCommit: 'Commit one'
20
+ },
21
+ {
22
+ name: 'Repository two',
23
+ branches: 'Branch two',
24
+ prs: 'PR two',
25
+ workspaces: 'Workspace two',
26
+ lastCommit: 'Commit two'
27
+ },
28
+ {
29
+ name: 'Repository three',
30
+ branches: 'Branch three',
31
+ prs: 'PR three',
32
+ workspaces: 'Workspace three',
33
+ lastCommit: 'Commit three'
34
+ }
35
+ ];
36
+
37
+ const columns: TableProps['cells'] = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit'];
38
+ const rows: TableProps['rows'] = repositories.map(repo => [
39
+ repo.name,
40
+ repo.branches,
41
+ repo.prs,
42
+ repo.workspaces,
43
+ repo.lastCommit
44
+ ]);
45
+
46
+ return (
47
+ <Table aria-label="Simple Table" cells={columns} rows={rows} isStriped>
48
+ <TableHeader />
49
+ <TableBody />
50
+ </Table>
51
+ );
52
+ };
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import { Table, TableHeader, TableBody, TableProps } from '@patternfly/react-table';
3
+ import { css } from '@patternfly/react-styles';
4
+
5
+ interface Repository {
6
+ name: string;
7
+ branches: string | null;
8
+ prs: string | null;
9
+ workspaces: string;
10
+ lastCommit: string;
11
+ }
12
+
13
+ export const LegacyTableStripedCustomTr: React.FunctionComponent = () => {
14
+ // In real usage, this data would come from some external source like an API via props.
15
+ const repositories: Repository[] = [
16
+ { name: 'one', branches: 'two', prs: 'three', workspaces: 'four', lastCommit: 'five' },
17
+ { name: 'one - 2', branches: null, prs: null, workspaces: 'four - 2', lastCommit: 'five - 2' },
18
+ { name: 'one - 3', branches: 'two - 3', prs: 'three - 3', workspaces: 'four - 3', lastCommit: 'five - 3' }
19
+ ];
20
+
21
+ const columns: TableProps['cells'] = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit'];
22
+ const rows: TableProps['rows'] = repositories.map(repo => [
23
+ repo.name,
24
+ repo.branches || '',
25
+ repo.prs || '',
26
+ repo.workspaces,
27
+ repo.lastCommit
28
+ ]);
29
+
30
+ const customRowWrapper: TableProps['rowWrapper'] = ({ trRef, className, rowProps, row: _row, ...props }) => {
31
+ const isOddRow = rowProps ? !!((rowProps.rowIndex + 1) % 2) : true;
32
+ return (
33
+ <tr
34
+ {...props}
35
+ ref={trRef as React.LegacyRef<HTMLTableRowElement>}
36
+ className={css(className, isOddRow && 'pf-m-striped')}
37
+ />
38
+ );
39
+ };
40
+
41
+ return (
42
+ <Table
43
+ caption="Table with custom row wrapper that stripes odd rows"
44
+ cells={columns}
45
+ rows={rows}
46
+ rowWrapper={customRowWrapper}
47
+ >
48
+ <TableHeader />
49
+ <TableBody />
50
+ </Table>
51
+ );
52
+ };
@@ -0,0 +1,174 @@
1
+ import React from 'react';
2
+ import { Table, TableBody, TableHeader, TableVariant, TableProps, expandable, IRowCell } from '@patternfly/react-table';
3
+ import { Checkbox } from '@patternfly/react-core';
4
+
5
+ interface Repository {
6
+ name: string;
7
+ branches: string;
8
+ prs: string;
9
+ workspaces: string;
10
+ details?: {
11
+ detail1?: string;
12
+ detail2?: string;
13
+ detail3?: string;
14
+ detailFormat: 0 | 1 | 2 | 3;
15
+ };
16
+ }
17
+
18
+ export const LegacyTableStripedExpandable: React.FunctionComponent = () => {
19
+ // In real usage, this data would come from some external source like an API via props.
20
+ const repositories: Repository[] = [
21
+ { name: 'one', branches: 'two', prs: 'a', workspaces: 'four' },
22
+ {
23
+ name: 'parent 1',
24
+ branches: 'two',
25
+ prs: 'k',
26
+ workspaces: 'four',
27
+ // This `details` structure is just for this example. You can drive expanded content from any kind of data.
28
+ details: { detailFormat: 0, detail1: 'single cell' }
29
+ },
30
+ {
31
+ name: 'parent 2',
32
+ branches: 'two',
33
+ prs: 'b',
34
+ workspaces: 'four',
35
+ details: { detailFormat: 1, detail1: 'single cell - fullWidth' }
36
+ },
37
+ {
38
+ name: 'parent 3',
39
+ branches: '2',
40
+ prs: 'b',
41
+ workspaces: 'four',
42
+ details: { detailFormat: 2, detail1: 'single cell - noPadding' }
43
+ },
44
+ {
45
+ name: 'parent 4',
46
+ branches: '2',
47
+ prs: 'b',
48
+ workspaces: 'four',
49
+ details: { detailFormat: 3, detail1: 'single cell - fullWidth & noPadding' }
50
+ },
51
+ {
52
+ name: 'parent 5',
53
+ branches: '2',
54
+ prs: 'b',
55
+ workspaces: 'four',
56
+ details: {
57
+ detailFormat: 0,
58
+ detail1: "spans 'Repositories and 'Branches'",
59
+ detail2: "spans 'Pull requests' and 'Workspaces', and 'Last commit'"
60
+ }
61
+ },
62
+ {
63
+ name: 'parent 6',
64
+ branches: '2',
65
+ prs: 'b',
66
+ workspaces: 'four',
67
+ details: {
68
+ detailFormat: 1,
69
+ detail1: "fullWidth, spans the collapsible column and 'Repositories'",
70
+ detail2: "fullWidth, spans 'Branches' and 'Pull requests'",
71
+ detail3: 'fullWidth, spans the empty column'
72
+ }
73
+ }
74
+ ];
75
+
76
+ // In this example, expanded rows are tracked by the repo names from each row. This could be any unique identifier.
77
+ // This is to prevent state from being based on row order index in case we later add sorting.
78
+ // Note that this behavior is very similar to selection state.
79
+ const initialExpandedRepoNames = repositories.filter(repo => !!repo.details).map(repo => repo.name); // Default to all expanded
80
+ const [expandedRepoNames, setExpandedRepoNames] = React.useState<string[]>(initialExpandedRepoNames);
81
+ const setRepoExpanded = (repo: Repository, isExpanding = true) =>
82
+ setExpandedRepoNames(prevExpanded => {
83
+ const otherExpandedRepoNames = prevExpanded.filter(r => r !== repo.name);
84
+ return isExpanding ? [...otherExpandedRepoNames, repo.name] : otherExpandedRepoNames;
85
+ });
86
+ const isRepoExpanded = (repo: Repository) => expandedRepoNames.includes(repo.name);
87
+
88
+ const [isExampleCompact, setIsExampleCompact] = React.useState(true);
89
+
90
+ // We want to be able to reference the original data object based on row index. But because an expanded
91
+ // row takes up two row indexes, repositories[rowIndex] will not be accurate like it would in a normal table.
92
+ // One solution to this is to create an array of data objects indexed by the displayed row index.
93
+ const reposByRowIndex: (Repository | null)[] = [];
94
+
95
+ const columns: TableProps['cells'] = [
96
+ {
97
+ title: 'Repositories',
98
+ cellFormatters: [expandable]
99
+ },
100
+ 'Branches',
101
+ { title: 'Pull requests' },
102
+ { title: '' /* deliberately empty */, dataLabel: 'Label for mobile view' }
103
+ ];
104
+ const rows: TableProps['rows'] = [];
105
+ repositories.forEach(repo => {
106
+ rows.push({
107
+ ...(repo.details ? { isOpen: isRepoExpanded(repo) } : {}),
108
+ cells: [repo.name, repo.branches, repo.prs, repo.workspaces]
109
+ });
110
+ reposByRowIndex.push(repo);
111
+ if (repo.details) {
112
+ // Some arbitrary examples of how you could customize the child row based on your needs
113
+ const { detail1, detail2, detail3, detailFormat } = repo.details;
114
+ const numColumns = 5;
115
+ const childIsFullWidth = [1, 3].includes(detailFormat);
116
+ const childHasNoPadding = [2, 3].includes(detailFormat);
117
+ let detailColSpans = [1, 1, 1];
118
+ if (detail1 && !detail2 && !detail3) {
119
+ detailColSpans = [childIsFullWidth ? numColumns : numColumns + 1]; // Account for toggle column
120
+ } else if (detail1 && detail2 && !detail3) {
121
+ detailColSpans = [2, childIsFullWidth ? 3 : 4];
122
+ } else if (detail1 && detail2 && detail3) {
123
+ detailColSpans = [2, 2, childIsFullWidth ? 1 : 2];
124
+ }
125
+ const cells: IRowCell[] = [];
126
+ [detail1, detail2, detail3].forEach((detail, index) => {
127
+ if (detail) {
128
+ cells.push({
129
+ title: detail1,
130
+ props: {
131
+ colSpan: detailColSpans[index]
132
+ }
133
+ });
134
+ }
135
+ });
136
+ rows.push({
137
+ parent: rows.length - 1,
138
+ cells,
139
+ fullWidth: childIsFullWidth,
140
+ noPadding: childHasNoPadding
141
+ });
142
+ reposByRowIndex.push(null);
143
+ }
144
+ });
145
+
146
+ return (
147
+ <React.Fragment>
148
+ <Checkbox
149
+ label="Compact"
150
+ isChecked={isExampleCompact}
151
+ onChange={checked => setIsExampleCompact(checked)}
152
+ aria-label="toggle striped compact variation"
153
+ id="toggle-compact-striped"
154
+ name="toggle-compact-striped"
155
+ />
156
+ <Table
157
+ aria-label="Expandable table"
158
+ variant={isExampleCompact ? TableVariant.compact : undefined}
159
+ onCollapse={(_event, rowIndex, isOpen) => {
160
+ if (reposByRowIndex[rowIndex]) {
161
+ setRepoExpanded(reposByRowIndex[rowIndex], isOpen);
162
+ }
163
+ }}
164
+ rows={rows}
165
+ cells={columns}
166
+ isStriped
167
+ isExpandable
168
+ >
169
+ <TableHeader />
170
+ <TableBody />
171
+ </Table>
172
+ </React.Fragment>
173
+ );
174
+ };
@@ -792,3 +792,24 @@ the voice over technologies will recognize the flat table structure as a tree.
792
792
 
793
793
  ```ts isBeta file="LegacyTableTree.tsx"
794
794
  ```
795
+
796
+ ### Striped
797
+
798
+ To apply striping to a basic table, add the `isStriped` property to `Table`.
799
+
800
+ ```ts file="LegacyTableStriped.tsx"
801
+ ```
802
+
803
+ ### Striped expandable
804
+
805
+ To apply striping to an expandable table, add the `isStriped` and `isExpandable` properties to `Table`.
806
+
807
+ ```ts file="LegacyTableStripedExpandable.tsx"
808
+ ```
809
+
810
+ ### Striped custom tr
811
+
812
+ To manually control striping, use a custom row wrapper that applies the `pf-m-striped` css class for each desired row.
813
+
814
+ ```ts file="LegacyTableStripedCustomTr.tsx"
815
+ ```
@@ -53,6 +53,10 @@ export interface TableComposableProps extends React.HTMLProps<HTMLTableElement>,
53
53
  isTreeTable?: boolean;
54
54
  /** Flag indicating this table is nested within another table */
55
55
  isNested?: boolean;
56
+ /** Flag indicating this table should be striped. This property works best for a single <tbody> table. Striping may also be done manually by applying this property to Tbody and Tr components. */
57
+ isStriped?: boolean;
58
+ /** Flag indicating this table contains expandable rows to maintain proper striping */
59
+ isExpandable?: boolean;
56
60
  /** Collection of column spans for nested headers. Deprecated: see https://github.com/patternfly/patternfly/issues/4584 */
57
61
  nestedHeaderColumnSpans?: number[];
58
62
  }
@@ -71,6 +75,8 @@ const TableComposableBase: React.FunctionComponent<TableComposableProps> = ({
71
75
  ouiaSafe = true,
72
76
  isTreeTable = false,
73
77
  isNested = false,
78
+ isStriped = false,
79
+ isExpandable = false,
74
80
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
75
81
  nestedHeaderColumnSpans,
76
82
  ...props
@@ -153,6 +159,8 @@ const TableComposableBase: React.FunctionComponent<TableComposableProps> = ({
153
159
  !borders && styles.modifiers.noBorderRows,
154
160
  isStickyHeader && styles.modifiers.stickyHeader,
155
161
  isTreeTable && stylesTreeView.modifiers.treeView,
162
+ isStriped && styles.modifiers.striped,
163
+ isExpandable && styles.modifiers.expandable,
156
164
  isNested && 'pf-m-nested'
157
165
  )}
158
166
  ref={tableRef}
@@ -11,6 +11,10 @@ export interface TbodyProps extends React.HTMLProps<HTMLTableSectionElement> {
11
11
  isExpanded?: boolean;
12
12
  /** Forwarded ref */
13
13
  innerRef?: React.Ref<any>;
14
+ /** Flag indicating the <tbody> contains oddly striped rows. */
15
+ isOddStriped?: boolean;
16
+ /** Flag indicating the <tbody> contains evenly striped rows. */
17
+ isEvenStriped?: boolean;
14
18
  }
15
19
 
16
20
  const TbodyBase: React.FunctionComponent<TbodyProps> = ({
@@ -18,9 +22,21 @@ const TbodyBase: React.FunctionComponent<TbodyProps> = ({
18
22
  className,
19
23
  isExpanded,
20
24
  innerRef,
25
+ isEvenStriped = false,
26
+ isOddStriped = false,
21
27
  ...props
22
28
  }: TbodyProps) => (
23
- <tbody role="rowgroup" className={css(className, isExpanded && styles.modifiers.expanded)} ref={innerRef} {...props}>
29
+ <tbody
30
+ role="rowgroup"
31
+ className={css(
32
+ className,
33
+ isExpanded && styles.modifiers.expanded,
34
+ isOddStriped && styles.modifiers.striped,
35
+ isEvenStriped && styles.modifiers.stripedEven
36
+ )}
37
+ ref={innerRef}
38
+ {...props}
39
+ >
24
40
  {children}
25
41
  </tbody>
26
42
  );
@@ -21,6 +21,8 @@ export interface TrProps extends React.HTMLProps<HTMLTableRowElement>, OUIAProps
21
21
  isHoverable?: boolean;
22
22
  /** Flag indicating the row is selected - adds selected styling */
23
23
  isRowSelected?: boolean;
24
+ /** Flag indicating the row is striped */
25
+ isStriped?: boolean;
24
26
  /** An event handler for the row */
25
27
  onRowClick?: (event?: React.KeyboardEvent | React.MouseEvent) => void;
26
28
  /** Flag indicating the spacing offset of the first cell should be reset */
@@ -35,6 +37,7 @@ const TrBase: React.FunctionComponent<TrProps> = ({
35
37
  isHidden = false,
36
38
  isHoverable = false,
37
39
  isRowSelected = false,
40
+ isStriped = false,
38
41
  innerRef,
39
42
  ouiaId,
40
43
  ouiaSafe = true,
@@ -63,6 +66,7 @@ const TrBase: React.FunctionComponent<TrProps> = ({
63
66
  isEditable && inlineStyles.modifiers.inlineEditable,
64
67
  isHoverable && styles.modifiers.hoverable,
65
68
  isRowSelected && styles.modifiers.selected,
69
+ isStriped && styles.modifiers.striped,
66
70
  resetOffset && styles.modifiers.firstCellOffsetReset
67
71
  )}
68
72
  hidden={isHidden || (isExpanded !== undefined && !isExpanded)}
@@ -349,3 +349,31 @@ The second `Tr` represents the second level of sub columns. The `Th` in this row
349
349
 
350
350
  ```ts file="ComposableTableNestedTableExpandable.tsx"
351
351
  ```
352
+
353
+ ### Composable: Striped
354
+
355
+ To apply striping to a basic table, add the `isStriped` property to `TableComposable`.
356
+
357
+ ```ts file="ComposableTableStriped.tsx"
358
+ ```
359
+
360
+ ### Composable: Striped expandable
361
+
362
+ To apply striping to an expandable table, add the `isStriped` and `isExpandable` properties to `TableComposable`.
363
+
364
+ ```ts file="ComposableTableStripedExpandable.tsx"
365
+ ```
366
+
367
+ ### Composable: Striped multiple tobdy
368
+
369
+ When there are multiple `Tbody` components within a table, a more granular application of striping may be controlled by adding either the `isEvenStriped` or `isOddStriped` properties to `Tbody`. These properties will stripe even or odd rows within that `Tbody` respectively.
370
+
371
+ ```ts file="ComposableTableStripedMultipleTbody.tsx"
372
+ ```
373
+
374
+ ### Composable: Striped tr
375
+
376
+ To manually control striping, add the `isStriped` property to each desired `Tr`. This replaces adding the `isStriped` property to `TableComposable`.
377
+
378
+ ```ts file="ComposableTableStripedTr.tsx"
379
+ ```
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import { TableComposable, Caption, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
3
+
4
+ interface Repository {
5
+ name: string;
6
+ branches: number;
7
+ prs: number;
8
+ workspaces: number;
9
+ lastCommit: string;
10
+ }
11
+
12
+ export const ComposableTableStriped: React.FunctionComponent = () => {
13
+ // In real usage, this data would come from some external source like an API via props.
14
+ const repositories: Repository[] = [
15
+ { name: 'Repository 1', branches: 10, prs: 25, workspaces: 5, lastCommit: '2 days ago' },
16
+ { name: 'Repository 2', branches: 10, prs: 25, workspaces: 5, lastCommit: '2 days ago' },
17
+ { name: 'Repository 3', branches: 10, prs: 25, workspaces: 5, lastCommit: '2 days ago' },
18
+ { name: 'Repository 4', branches: 10, prs: 25, workspaces: 5, lastCommit: '2 days ago' }
19
+ ];
20
+
21
+ const columnNames = {
22
+ name: 'Repositories',
23
+ branches: 'Branches',
24
+ prs: 'Pull requests',
25
+ workspaces: 'Workspaces',
26
+ lastCommit: 'Last commit'
27
+ };
28
+
29
+ return (
30
+ <TableComposable aria-label="Simple table" isStriped>
31
+ <Caption>Simple striped table using composable components</Caption>
32
+ <Thead>
33
+ <Tr>
34
+ <Th>{columnNames.name}</Th>
35
+ <Th>{columnNames.branches}</Th>
36
+ <Th>{columnNames.prs}</Th>
37
+ <Th>{columnNames.workspaces}</Th>
38
+ <Th>{columnNames.lastCommit}</Th>
39
+ </Tr>
40
+ </Thead>
41
+ <Tbody>
42
+ {repositories.map(repo => (
43
+ <Tr key={repo.name}>
44
+ <Td dataLabel={columnNames.name}>{repo.name}</Td>
45
+ <Td dataLabel={columnNames.branches}>{repo.branches}</Td>
46
+ <Td dataLabel={columnNames.prs}>{repo.prs}</Td>
47
+ <Td dataLabel={columnNames.workspaces}>{repo.workspaces}</Td>
48
+ <Td dataLabel={columnNames.lastCommit}>{repo.lastCommit}</Td>
49
+ </Tr>
50
+ ))}
51
+ </Tbody>
52
+ </TableComposable>
53
+ );
54
+ };