0
# Layout and Scrolling
1
2
Components for managing table layout, scrolling behavior, responsive design, and sticky column/header functionality.
3
4
## Capabilities
5
6
### OuterScrollContainer
7
8
Outer wrapper for scrollable tables providing the container for horizontal scrolling.
9
10
```typescript { .api }
11
/**
12
* Outer wrapper for scrollable tables
13
* @param props - OuterScrollContainer configuration props
14
* @returns OuterScrollContainer component
15
*/
16
function OuterScrollContainer(props: OuterScrollContainerProps): React.FunctionComponent<OuterScrollContainerProps>;
17
18
interface OuterScrollContainerProps extends React.HTMLProps<HTMLDivElement> {
19
/** Content rendered inside the outer scroll container */
20
children?: React.ReactNode;
21
/** Additional classes added to the container */
22
className?: string;
23
}
24
```
25
26
### InnerScrollContainer
27
28
Inner wrapper for scrollable tables providing the immediate container around the table element.
29
30
```typescript { .api }
31
/**
32
* Inner wrapper for scrollable tables
33
* @param props - InnerScrollContainer configuration props
34
* @returns InnerScrollContainer component
35
*/
36
function InnerScrollContainer(props: InnerScrollContainerProps): React.FunctionComponent<InnerScrollContainerProps>;
37
38
interface InnerScrollContainerProps extends React.HTMLProps<HTMLDivElement> {
39
/** Content rendered inside the inner scroll container */
40
children?: React.ReactNode;
41
/** Additional classes added to the container */
42
className?: string;
43
}
44
```
45
46
**Usage Examples:**
47
48
```typescript
49
import { OuterScrollContainer, InnerScrollContainer, Table } from "@patternfly/react-table";
50
51
// Scrollable table setup
52
<OuterScrollContainer>
53
<InnerScrollContainer>
54
<Table aria-label="Scrollable table">
55
{/* table content */}
56
</Table>
57
</InnerScrollContainer>
58
</OuterScrollContainer>
59
60
// Scrollable table with custom styling
61
<OuterScrollContainer className="custom-outer-scroll">
62
<InnerScrollContainer className="custom-inner-scroll">
63
<Table
64
aria-label="Data table"
65
isStickyHeader
66
gridBreakPoint="grid-lg"
67
>
68
{/* table content with sticky headers */}
69
</Table>
70
</InnerScrollContainer>
71
</OuterScrollContainer>
72
```
73
74
### RowWrapper
75
76
Row wrapper component with scroll and resize event handling for advanced table interactions.
77
78
```typescript { .api }
79
/**
80
* Row wrapper with scroll and resize event handling
81
* @param props - RowWrapper configuration props
82
* @returns RowWrapper component
83
*/
84
class RowWrapper extends React.Component<RowWrapperProps> {
85
static displayName: string;
86
static defaultProps: Partial<RowWrapperProps>;
87
}
88
89
interface RowWrapperProps extends OUIAProps {
90
children?: React.ReactNode;
91
/** Ref to forward to the table row */
92
trRef?: React.Ref<any> | Function;
93
className?: string;
94
/** Scroll event handler */
95
onScroll?: React.UIEventHandler;
96
/** Resize event handler */
97
onResize?: React.UIEventHandler;
98
/** Row data */
99
row?: IRow;
100
/** Row properties */
101
rowProps?: {
102
rowIndex: number;
103
rowKey: string;
104
};
105
/** Value to set the data-ouia-component-id */
106
ouiaId?: number | string;
107
}
108
109
// Legacy interface for row data
110
interface RowWrapperRow {
111
isOpen?: boolean;
112
isExpanded?: boolean;
113
isEditable?: boolean;
114
}
115
```
116
117
**Usage Examples:**
118
119
```typescript
120
import { RowWrapper } from "@patternfly/react-table";
121
122
// Row wrapper with scroll handling
123
<RowWrapper
124
onScroll={(event) => handleRowScroll(event)}
125
onResize={(event) => handleRowResize(event)}
126
row={{
127
isExpanded: expandedRows.includes(rowIndex),
128
isEditable: editableRows.includes(rowIndex),
129
isClickable: true
130
}}
131
rowProps={{
132
rowIndex,
133
rowKey: `row-${rowIndex}`
134
}}
135
>
136
<Td>Row content</Td>
137
</RowWrapper>
138
139
// Row wrapper for responsive tables
140
<RowWrapper
141
className="responsive-row"
142
onResize={(event) => {
143
// Handle responsive layout changes
144
updateResponsiveLayout(event);
145
}}
146
row={rowData}
147
>
148
{/* row cells */}
149
</RowWrapper>
150
```
151
152
### TreeRowWrapper
153
154
Specialized row wrapper component for tree table functionality with aria attributes for hierarchical data.
155
156
```typescript { .api }
157
/**
158
* Specialized row wrapper for tree tables
159
* @param props - TreeRowWrapper configuration props
160
* @returns TreeRowWrapper component
161
*/
162
function TreeRowWrapper(props: RowWrapperProps): React.FunctionComponent<RowWrapperProps>;
163
164
// Uses the same RowWrapperProps interface as RowWrapper
165
// but expects specific row.props for tree functionality:
166
interface TreeRowProps {
167
'aria-level'?: number;
168
'aria-posinset'?: number;
169
'aria-setsize'?: number;
170
isExpanded?: boolean;
171
isDetailsExpanded?: boolean;
172
isHidden?: boolean;
173
}
174
```
175
176
**Usage Examples:**
177
178
```typescript
179
import { TreeRowWrapper } from "@patternfly/react-table";
180
181
// Tree row with hierarchy information
182
<TreeRowWrapper
183
row={{
184
props: {
185
'aria-level': 2, // Nesting level in tree
186
'aria-posinset': 1, // Position within siblings
187
'aria-setsize': 3, // Total number of siblings
188
isExpanded: true, // Whether node is expanded
189
isDetailsExpanded: false, // Whether details are expanded
190
isHidden: false // Whether row is hidden
191
}
192
}}
193
className="tree-row"
194
>
195
<Td>Folder Name</Td>
196
<Td>Directory</Td>
197
</TreeRowWrapper>
198
199
// Collapsed tree node
200
<TreeRowWrapper
201
row={{
202
props: {
203
'aria-level': 1,
204
'aria-posinset': 2,
205
'aria-setsize': 5,
206
isExpanded: false,
207
isHidden: false
208
}
209
}}
210
>
211
<Td>Root Folder</Td>
212
<Td>3 items</Td>
213
</TreeRowWrapper>
214
```
215
216
## Sticky Column and Header Support
217
218
### Sticky Headers
219
220
```typescript { .api }
221
// Table with sticky header
222
<Table isStickyHeader aria-label="Table with sticky header">
223
<Thead>
224
<Tr>
225
<Th>Column 1</Th>
226
<Th>Column 2</Th>
227
</Tr>
228
</Thead>
229
<Tbody>
230
{/* table rows */}
231
</Tbody>
232
</Table>
233
```
234
235
### Sticky Columns
236
237
```typescript { .api }
238
// Sticky column configuration
239
interface StickyColumnProps {
240
/** Indicates the column should be sticky */
241
isStickyColumn: boolean;
242
/** Minimum width for a sticky column */
243
stickyMinWidth?: string;
244
/** Left offset of a sticky column */
245
stickyLeftOffset?: string;
246
/** Right offset of a sticky column */
247
stickyRightOffset?: string;
248
/** Adds a border to the right side of the cell */
249
hasRightBorder?: boolean;
250
/** Adds a border to the left side of the cell */
251
hasLeftBorder?: boolean;
252
}
253
```
254
255
**Usage Examples:**
256
257
```typescript
258
// Left sticky column
259
<Th
260
isStickyColumn
261
stickyMinWidth="150px"
262
stickyLeftOffset="0px"
263
hasRightBorder
264
>
265
Name
266
</Th>
267
268
// Multiple sticky columns
269
<Thead>
270
<Tr>
271
<Th
272
isStickyColumn
273
stickyMinWidth="120px"
274
stickyLeftOffset="0px"
275
hasRightBorder
276
>
277
ID
278
</Th>
279
<Th
280
isStickyColumn
281
stickyMinWidth="150px"
282
stickyLeftOffset="120px"
283
hasRightBorder
284
>
285
Name
286
</Th>
287
<Th>Description</Th>
288
<Th
289
isStickyColumn
290
stickyMinWidth="100px"
291
stickyRightOffset="0px"
292
hasLeftBorder
293
>
294
Actions
295
</Th>
296
</Tr>
297
</Thead>
298
299
// Corresponding sticky data cells
300
<Tbody>
301
<Tr>
302
<Td
303
isStickyColumn
304
stickyMinWidth="120px"
305
stickyLeftOffset="0px"
306
hasRightBorder
307
>
308
001
309
</Td>
310
<Td
311
isStickyColumn
312
stickyMinWidth="150px"
313
stickyLeftOffset="120px"
314
hasRightBorder
315
>
316
John Doe
317
</Td>
318
<Td>Description content</Td>
319
<Td
320
isStickyColumn
321
stickyMinWidth="100px"
322
stickyRightOffset="0px"
323
hasLeftBorder
324
>
325
<ActionsColumn items={actions} />
326
</Td>
327
</Tr>
328
</Tbody>
329
```
330
331
## Grid Breakpoints and Responsive Layout
332
333
### Grid Breakpoint Configuration
334
335
```typescript { .api }
336
enum TableGridBreakpoint {
337
none = '',
338
grid = 'grid',
339
gridMd = 'grid-md',
340
gridLg = 'grid-lg',
341
gridXl = 'grid-xl',
342
grid2xl = 'grid-2xl'
343
}
344
345
// Table responsive configuration
346
<Table
347
gridBreakPoint="grid-lg"
348
aria-label="Responsive table"
349
>
350
{/* table content */}
351
</Table>
352
```
353
354
### Visibility Controls
355
356
```typescript { .api }
357
// Visibility interface for responsive display
358
interface IVisibility {
359
hidden?: boolean;
360
hiddenOnSm?: boolean;
361
hiddenOnMd?: boolean;
362
hiddenOnLg?: boolean;
363
hiddenOnXl?: boolean;
364
hiddenOn2Xl?: boolean;
365
visibleOnSm?: boolean;
366
visibleOnMd?: boolean;
367
visibleOnLg?: boolean;
368
visibleOnXl?: boolean;
369
visibleOn2Xl?: boolean;
370
}
371
```
372
373
**Usage Examples:**
374
375
```typescript
376
// Responsive column visibility
377
<Thead>
378
<Tr>
379
<Th>Name</Th>
380
<Th
381
visibility={['hiddenOnSm', 'hiddenOnMd']}
382
>
383
Description
384
</Th>
385
<Th
386
visibility={['visibleOnLg', 'visibleOnXl']}
387
>
388
Additional Info
389
</Th>
390
<Th>Actions</Th>
391
</Tr>
392
</Thead>
393
394
// Responsive cell content
395
<Tbody>
396
<Tr>
397
<Td dataLabel="Name">John Doe</Td>
398
<Td
399
dataLabel="Description"
400
visibility={['hiddenOnSm', 'hiddenOnMd']}
401
>
402
Software Developer
403
</Td>
404
<Td
405
dataLabel="Additional Info"
406
visibility={['visibleOnLg', 'visibleOnXl']}
407
>
408
Senior level, 5 years experience
409
</Td>
410
<Td dataLabel="Actions">
411
<ActionsColumn items={actions} />
412
</Td>
413
</Tr>
414
</Tbody>
415
```
416
417
## Advanced Layout Patterns
418
419
### Tree Table Layout
420
421
```typescript { .api }
422
// Tree table configuration
423
<Table
424
isTreeTable
425
hasNoInset={!hasVisibleChildren}
426
gridBreakPoint="grid-lg"
427
aria-label="Tree table"
428
>
429
<Thead>
430
<Tr>
431
<Th>File Name</Th>
432
<Th>Size</Th>
433
<Th>Modified</Th>
434
</Tr>
435
</Thead>
436
<Tbody>
437
{/* tree table rows with hierarchy */}
438
</Tbody>
439
</Table>
440
```
441
442
### Nested Tables
443
444
```typescript { .api }
445
// Nested table configuration
446
<Table
447
isNested
448
borders={false}
449
aria-label="Nested table"
450
>
451
{/* nested table content */}
452
</Table>
453
```
454
455
### Expandable Layout
456
457
```typescript { .api }
458
// Expandable table with animations
459
<Table
460
isExpandable
461
hasAnimations
462
aria-label="Expandable table"
463
>
464
<Tbody>
465
<Tr isExpanded={expandedRows.includes(0)}>
466
<Td>Row content</Td>
467
</Tr>
468
<Tr isExpanded={expandedRows.includes(0)}>
469
<Td colSpan={columnCount}>
470
<ExpandableRowContent>
471
Expanded content
472
</ExpandableRowContent>
473
</Td>
474
</Tr>
475
</Tbody>
476
</Table>
477
```
478
479
## Layout Utilities
480
481
### Width and Sizing
482
483
```typescript { .api }
484
// Width options for cells
485
type CellWidth = 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 60 | 70 | 80 | 90 | 100;
486
487
// Text modifiers for content control
488
type TextModifier = 'breakWord' | 'fitContent' | 'nowrap' | 'truncate' | 'wrap';
489
```
490
491
**Usage Examples:**
492
493
```typescript
494
// Column width control
495
<Th width={25}>Name</Th>
496
<Th width={50} modifier="truncate">Description</Th>
497
<Th width={15}>Status</Th>
498
<Th width={10}>Actions</Th>
499
500
// Content fitting
501
<Td modifier="fitContent">
502
<Button>Action</Button>
503
</Td>
504
<Td modifier="breakWord">
505
very-long-url-that-needs-to-break@example.com
506
</Td>
507
```
508
509
### Borders and Spacing
510
511
```typescript { .api }
512
// Border controls
513
<Table borders={false}> {/* Remove all borders */}
514
<Th hasRightBorder> {/* Add right border */}
515
<Th hasLeftBorder> {/* Add left border */}
516
517
// Spacing controls
518
<Td noPadding> {/* Remove cell padding */}
519
<Tr resetOffset> {/* Reset first cell offset */}
520
```
521
522
### Striped Patterns
523
524
```typescript { .api }
525
// Table-level striping
526
<Table isStriped>
527
{/* All rows will be striped */}
528
</Table>
529
530
// Body-level striping
531
<Tbody isOddStriped>
532
{/* Odd rows in this tbody will be striped */}
533
</Tbody>
534
<Tbody isEvenStriped>
535
{/* Even rows in this tbody will be striped */}
536
</Tbody>
537
538
// Row-level striping
539
<Tr isStriped>
540
{/* This specific row will be striped */}
541
</Tr>
542
```