Skip to content

Commit c8f5a08

Browse files
committed
Made util out of scroll helper in examples
1 parent 560db7a commit c8f5a08

7 files changed

Lines changed: 70 additions & 143 deletions

File tree

packages/react-core/src/components/Pagination/examples/Pagination.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@ import { Fragment, useState, useRef, useLayoutEffect } from 'react';
2424

2525
### Plain top
2626

27+
To apply plain styling to a pagination, use `isPlain`. Plain styling removes the background and border, which is useful when the pagination is placed inside another component with its own background.
28+
2729
```ts file="./PaginationPlainTop.tsx"
2830

2931
```
3032

3133
### Plain bottom
3234

35+
To apply plain styling to a bottom pagination, use `isPlain` along with `variant={PaginationVariant.bottom}`.
36+
3337
```ts file="./PaginationPlainBottom.tsx"
3438

3539
```
@@ -80,12 +84,16 @@ By not passing `itemCount` and passing `toggleTemplate` you can customize the to
8084

8185
### Dynamic sticky top
8286

87+
A pagination may alternatively be made sticky with two properties: `isStickyBase` and `isStickyStuck`, which allows separate control of the sticky position and sticky styling respectively. In this example, `isStickyStuck` is only applied when the pagination is not at the top of the scroll parent container.
88+
8389
```ts isFullscreen file="./PaginationDynamicStickyTop.tsx"
8490

8591
```
8692

8793
### Dynamic sticky bottom
8894

95+
A bottom pagination may alternatively be made sticky with two properties: `isStickyBase` and `isStickyStuck`, which allows separate control of the sticky position and sticky styling respectively. In this example, `isStickyStuck` is only applied when the pagination is not at the bottom of the scroll parent container.
96+
8997
```ts isFullscreen file="./PaginationDynamicStickyBottom.tsx"
9098

9199
```

packages/react-core/src/components/Pagination/examples/PaginationDynamicStickyBottom.tsx

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,13 @@
1-
import { useLayoutEffect, useState, useRef } from 'react';
2-
import { Pagination, PaginationVariant, Gallery, GalleryItem, Card, CardBody } from '@patternfly/react-core';
3-
4-
const useIsStuckFromScrollParent = ({
5-
shouldTrack,
6-
scrollParentRef
7-
}: {
8-
/** Indicates whether to track the scroll top position of the scroll parent element */
9-
shouldTrack: boolean;
10-
/** Reference to the scroll parent element */
11-
scrollParentRef: React.RefObject<any>;
12-
}): boolean => {
13-
const [isStuck, setIsStuck] = useState(false);
14-
15-
useLayoutEffect(() => {
16-
if (!shouldTrack) {
17-
setIsStuck(false);
18-
return;
19-
}
20-
21-
const scrollElement = scrollParentRef.current;
22-
if (!scrollElement) {
23-
setIsStuck(false);
24-
return;
25-
}
26-
27-
const syncFromScroll = () => {
28-
setIsStuck(scrollElement.scrollTop > 0);
29-
};
30-
syncFromScroll();
31-
scrollElement.addEventListener('scroll', syncFromScroll, { passive: true });
32-
return () => scrollElement.removeEventListener('scroll', syncFromScroll);
33-
}, [shouldTrack, scrollParentRef]);
34-
35-
return isStuck;
36-
};
1+
import { useState, useRef } from 'react';
2+
import {
3+
Pagination,
4+
PaginationVariant,
5+
Gallery,
6+
GalleryItem,
7+
Card,
8+
CardBody,
9+
useIsStuckFromScrollParent
10+
} from '@patternfly/react-core';
3711

3812
export const PaginationDynamicStickyBottom: React.FunctionComponent = () => {
3913
const scrollParentRef = useRef<HTMLDivElement>(null);

packages/react-core/src/components/Pagination/examples/PaginationDynamicStickyTop.tsx

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,5 @@
1-
import { useLayoutEffect, useState, useRef } from 'react';
2-
import { Pagination, Gallery, GalleryItem, Card, CardBody } from '@patternfly/react-core';
3-
4-
const useIsStuckFromScrollParent = ({
5-
shouldTrack,
6-
scrollParentRef
7-
}: {
8-
/** Indicates whether to track the scroll top position of the scroll parent element */
9-
shouldTrack: boolean;
10-
/** Reference to the scroll parent element */
11-
scrollParentRef: React.RefObject<any>;
12-
}): boolean => {
13-
const [isStuck, setIsStuck] = useState(false);
14-
15-
useLayoutEffect(() => {
16-
if (!shouldTrack) {
17-
setIsStuck(false);
18-
return;
19-
}
20-
21-
const scrollElement = scrollParentRef.current;
22-
if (!scrollElement) {
23-
setIsStuck(false);
24-
return;
25-
}
26-
27-
const syncFromScroll = () => {
28-
setIsStuck(scrollElement.scrollTop > 0);
29-
};
30-
syncFromScroll();
31-
scrollElement.addEventListener('scroll', syncFromScroll, { passive: true });
32-
return () => scrollElement.removeEventListener('scroll', syncFromScroll);
33-
}, [shouldTrack, scrollParentRef]);
34-
35-
return isStuck;
36-
};
1+
import { useState, useRef } from 'react';
2+
import { Pagination, Gallery, GalleryItem, Card, CardBody, useIsStuckFromScrollParent } from '@patternfly/react-core';
373

384
export const PaginationDynamicStickyTop: React.FunctionComponent = () => {
395
const scrollParentRef = useRef<HTMLDivElement>(null);

packages/react-core/src/components/Toolbar/examples/ToolbarDynamicSticky.tsx

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,12 @@
1-
import { useLayoutEffect, useState, useRef } from 'react';
2-
import { Toolbar, ToolbarItem, ToolbarContent, SearchInput, Checkbox } from '@patternfly/react-core';
3-
4-
const useIsStuckFromScrollParent = ({
5-
shouldTrack,
6-
scrollParentRef
7-
}: {
8-
/** Indicates whether to track the scroll top position of the scroll parent element */
9-
shouldTrack: boolean;
10-
/** Reference to the scroll parent element */
11-
scrollParentRef: React.RefObject<any>;
12-
}): boolean => {
13-
const [isStuck, setIsStuck] = useState(false);
14-
15-
useLayoutEffect(() => {
16-
if (!shouldTrack) {
17-
setIsStuck(false);
18-
return;
19-
}
20-
21-
const scrollElement = scrollParentRef.current;
22-
if (!scrollElement) {
23-
setIsStuck(false);
24-
return;
25-
}
26-
27-
const syncFromScroll = () => {
28-
setIsStuck(scrollElement.scrollTop > 0);
29-
};
30-
syncFromScroll();
31-
scrollElement.addEventListener('scroll', syncFromScroll, { passive: true });
32-
return () => scrollElement.removeEventListener('scroll', syncFromScroll);
33-
}, [shouldTrack, scrollParentRef]);
34-
35-
return isStuck;
36-
};
1+
import { useState, useRef } from 'react';
2+
import {
3+
Toolbar,
4+
ToolbarItem,
5+
ToolbarContent,
6+
SearchInput,
7+
Checkbox,
8+
useIsStuckFromScrollParent
9+
} from '@patternfly/react-core';
3710

3811
export const ToolbarDynamicSticky = () => {
3912
const scrollParentRef = useRef<HTMLDivElement>(null);

packages/react-core/src/helpers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ export * from './SSRSafeIds/SSRSafeIds';
1313
export * from './KeyboardHandler';
1414
export * from './resizeObserver';
1515
export * from './useInterval';
16+
export * from './useIsStuckFromScrollParent';
1617
export * from './datetimeUtils';
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/** Custom React hook to track whether a scroll parent has been scrolled (scrollTop > 0).
2+
* Useful for applying dynamic sticky styling when an element becomes "stuck" in a scroll container.
3+
*/
4+
import { useLayoutEffect, useState } from 'react';
5+
6+
export function useIsStuckFromScrollParent({
7+
shouldTrack,
8+
scrollParentRef
9+
}: {
10+
/** Indicates whether to track the scroll top position of the scroll parent element */
11+
shouldTrack: boolean;
12+
/** Reference to the scroll parent element */
13+
scrollParentRef: React.RefObject<any>;
14+
}): boolean {
15+
const [isStuck, setIsStuck] = useState(false);
16+
17+
useLayoutEffect(() => {
18+
if (!shouldTrack) {
19+
setIsStuck(false);
20+
return;
21+
}
22+
23+
const scrollElement = scrollParentRef.current;
24+
if (!scrollElement) {
25+
setIsStuck(false);
26+
return;
27+
}
28+
29+
const syncFromScroll = () => {
30+
setIsStuck(scrollElement.scrollTop > 0);
31+
};
32+
syncFromScroll();
33+
scrollElement.addEventListener('scroll', syncFromScroll, { passive: true });
34+
return () => scrollElement.removeEventListener('scroll', syncFromScroll);
35+
}, [shouldTrack, scrollParentRef]);
36+
37+
return isStuck;
38+
}

packages/react-table/src/components/Table/examples/TableStickyHeaderDynamic.tsx

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { useLayoutEffect, useRef, useState } from 'react';
1+
import { useRef } from 'react';
22
import { Table, Thead, Tr, Th, Tbody, Td, InnerScrollContainer } from '@patternfly/react-table';
33
import RhUiBlueprintIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-blueprint-icon';
4+
import { useIsStuckFromScrollParent } from '@patternfly/react-core';
45

56
interface Fact {
67
name: string;
@@ -14,40 +15,6 @@ interface Fact {
1415
detail7: string;
1516
}
1617

17-
const useIsStuckFromScrollParent = ({
18-
shouldTrack,
19-
scrollParentRef
20-
}: {
21-
/** Indicates whether to track the scroll top position of the scroll parent element */
22-
shouldTrack: boolean;
23-
/** Reference to the scroll parent element */
24-
scrollParentRef: React.RefObject<any>;
25-
}): boolean => {
26-
const [isStuck, setIsStuck] = useState(false);
27-
28-
useLayoutEffect(() => {
29-
if (!shouldTrack) {
30-
setIsStuck(false);
31-
return;
32-
}
33-
34-
const scrollElement = scrollParentRef.current;
35-
if (!scrollElement) {
36-
setIsStuck(false);
37-
return;
38-
}
39-
40-
const syncFromScroll = () => {
41-
setIsStuck(scrollElement.scrollTop > 0);
42-
};
43-
syncFromScroll();
44-
scrollElement.addEventListener('scroll', syncFromScroll, { passive: true });
45-
return () => scrollElement.removeEventListener('scroll', syncFromScroll);
46-
}, [shouldTrack, scrollParentRef]);
47-
48-
return isStuck;
49-
};
50-
5118
export const TableStickyHeaderDynamic: React.FunctionComponent = () => {
5219
const scrollContainerRef = useRef<HTMLDivElement>(null);
5320
const isStuck = useIsStuckFromScrollParent({ shouldTrack: true, scrollParentRef: scrollContainerRef });

0 commit comments

Comments
 (0)