@patternfly/react-table 6.7.0-prerelease.2 → 6.7.0-prerelease.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-table",
3
- "version": "6.7.0-prerelease.2",
3
+ "version": "6.7.0-prerelease.3",
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",
@@ -51,5 +51,5 @@
51
51
  "react": "^17 || ^18 || ^19",
52
52
  "react-dom": "^17 || ^18 || ^19"
53
53
  },
54
- "gitHead": "6a486021829bef4ba8c6a772c035b364ab5f0686"
54
+ "gitHead": "7ad66d2d0be3d09824a8d7c3319121f6c9778817"
55
55
  }
@@ -60,6 +60,10 @@ export interface TableProps extends React.HTMLProps<HTMLTableElement>, OUIAProps
60
60
  isStickyHeaderStuck?: boolean;
61
61
  /** Flag indicating the table footer should stick to the bottom of its scroll container. */
62
62
  isStickyFooter?: boolean;
63
+ /** @beta Flag indicating the table footer should have sticky positioning to the bottom of its scroll container. */
64
+ isStickyFooterBase?: boolean;
65
+ /** @beta Flag indicating the table footer should have stuck styling, when the footer is not at the bottom of the scroll container. */
66
+ isStickyFooterStuck?: boolean;
63
67
  /** @hide Forwarded ref */
64
68
  innerRef?: React.RefObject<any>;
65
69
  /** Flag indicating table is a tree table */
@@ -107,6 +111,8 @@ const TableBase: React.FunctionComponent<TableProps> = ({
107
111
  isStickyHeaderBase = false,
108
112
  isStickyHeaderStuck = false,
109
113
  isStickyFooter = false,
114
+ isStickyFooterBase = false,
115
+ isStickyFooterStuck = false,
110
116
  isPlain = false,
111
117
  isNoPlainOnGlass = false,
112
118
  gridBreakPoint = TableGridBreakpoint.gridMd,
@@ -237,6 +243,8 @@ const TableBase: React.FunctionComponent<TableProps> = ({
237
243
  isStickyHeaderBase && styles.modifiers.stickyHeaderBase,
238
244
  isStickyHeaderStuck && styles.modifiers.stickyHeaderStuck,
239
245
  isStickyFooter && styles.modifiers.stickyFooter,
246
+ isStickyFooterBase && styles.modifiers.stickyFooterBase,
247
+ isStickyFooterStuck && styles.modifiers.stickyFooterStuck,
240
248
  isTreeTable && stylesTreeView.modifiers.treeView,
241
249
  isStriped && styles.modifiers.striped,
242
250
  isExpandable && styles.modifiers.expandable,
@@ -234,3 +234,39 @@ test(`Does not render with class ${styles.modifiers.stickyFooter} when isStickyF
234
234
 
235
235
  expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyFooter);
236
236
  });
237
+
238
+ test(`Renders with class ${styles.modifiers.stickyFooterBase} when isStickyFooterBase is true`, () => {
239
+ render(<Table isStickyFooterBase aria-label="Test table" />);
240
+
241
+ expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.modifiers.stickyFooterBase);
242
+ });
243
+
244
+ test(`Does not render with class ${styles.modifiers.stickyFooterBase} when isStickyFooterBase is false`, () => {
245
+ render(<Table isStickyFooterBase={false} aria-label="Test table" />);
246
+
247
+ expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyFooterBase);
248
+ });
249
+
250
+ test(`Renders with class ${styles.modifiers.stickyFooterStuck} when isStickyFooterStuck is true`, () => {
251
+ render(<Table isStickyFooterStuck aria-label="Test table" />);
252
+
253
+ expect(screen.getByRole('grid', { name: 'Test table' })).toHaveClass(styles.modifiers.stickyFooterStuck);
254
+ });
255
+
256
+ test(`Does not render with class ${styles.modifiers.stickyFooterStuck} when isStickyFooterStuck is false`, () => {
257
+ render(<Table isStickyFooterStuck={false} aria-label="Test table" />);
258
+
259
+ expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyFooterStuck);
260
+ });
261
+
262
+ test(`Does not render with class ${styles.modifiers.stickyFooterBase} when isStickyFooterBase is undefined`, () => {
263
+ render(<Table aria-label="Test table" />);
264
+
265
+ expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyFooterBase);
266
+ });
267
+
268
+ test(`Does not render with class ${styles.modifiers.stickyFooterStuck} when isStickyFooterStuck is undefined`, () => {
269
+ render(<Table aria-label="Test table" />);
270
+
271
+ expect(screen.getByRole('grid', { name: 'Test table' })).not.toHaveClass(styles.modifiers.stickyFooterStuck);
272
+ });
@@ -489,6 +489,16 @@ Use `Tfoot` for semantic table footer rows. Set `isStickyFooter` on `Table` to k
489
489
 
490
490
  ```
491
491
 
492
+ ### Dynamic sticky footer
493
+
494
+ A sticky footer may alternatively be implemented with two properties: `isStickyFooterBase` and `isStickyFooterStuck` - which allows separate control of the sticky position and sticky styling. `isStickyFooterBase` should always be applied to make the footer position sticky, and `isStickyFooterStuck` may be applied dynamically to enable the sticky styling, such as when the sticky footer is not at the bottom of the scroll parent as shown in the example.
495
+
496
+ `isStickyFooter` acts as if both properties are present and true when applied, and is useful when dynamic sticky styling is not necessary.
497
+
498
+ ```ts file="TableStickyFooterDynamic.tsx"
499
+
500
+ ```
501
+
492
502
  ### Striped
493
503
 
494
504
  To apply striping to a basic table, add the `isStriped` property to `Table`.
@@ -0,0 +1,61 @@
1
+ import { useLayoutEffect, useRef, useState } from 'react';
2
+ import { getResizeObserver } from '@patternfly/react-core';
3
+ import { Table, Thead, Tfoot, Tr, Th, Tbody, Td, InnerScrollContainer } from '@patternfly/react-table';
4
+
5
+ const useIsStuckFromScrollParent = (scrollParentRef: React.RefObject<HTMLDivElement>): boolean => {
6
+ const [isStuck, setIsStuck] = useState(false);
7
+
8
+ useLayoutEffect(() => {
9
+ const scrollElement = scrollParentRef.current;
10
+ if (!scrollElement) {
11
+ return;
12
+ }
13
+
14
+ const syncFromScroll = () => {
15
+ setIsStuck(scrollElement.scrollTop + scrollElement.clientHeight < scrollElement.scrollHeight);
16
+ };
17
+ syncFromScroll();
18
+ scrollElement.addEventListener('scroll', syncFromScroll, { passive: true });
19
+ const observer = getResizeObserver(scrollElement, syncFromScroll, true);
20
+ return () => {
21
+ scrollElement.removeEventListener('scroll', syncFromScroll);
22
+ observer();
23
+ };
24
+ }, [scrollParentRef]);
25
+
26
+ return isStuck;
27
+ };
28
+
29
+ export const TableStickyFooterDynamic: React.FunctionComponent = () => {
30
+ const scrollContainerRef = useRef<HTMLDivElement>(null);
31
+ const isStuck = useIsStuckFromScrollParent(scrollContainerRef);
32
+ const rows = Array.from({ length: 12 }, (_, index) => index + 1);
33
+
34
+ return (
35
+ <div style={{ height: '400px' }}>
36
+ <InnerScrollContainer ref={scrollContainerRef}>
37
+ <Table aria-label="Dynamic sticky footer table" isStickyFooterBase isStickyFooterStuck={isStuck}>
38
+ <Thead>
39
+ <Tr>
40
+ <Th>Item</Th>
41
+ <Th>Value</Th>
42
+ </Tr>
43
+ </Thead>
44
+ <Tbody>
45
+ {rows.map((row) => (
46
+ <Tr key={row}>
47
+ <Td dataLabel="Item">Item {row}</Td>
48
+ <Td dataLabel="Value">Value {row}</Td>
49
+ </Tr>
50
+ ))}
51
+ </Tbody>
52
+ <Tfoot>
53
+ <Tr>
54
+ <Td colSpan={2}>Total: {rows.length} items</Td>
55
+ </Tr>
56
+ </Tfoot>
57
+ </Table>
58
+ </InnerScrollContainer>
59
+ </div>
60
+ );
61
+ };