Skip to content

Commit 332081a

Browse files
committed
Address PR Feedback
- remove unneeded css class - respect reduced motion settings in scrollTo function - use lazy ref for sticky manager - fix: scroll hint happens at max once per mount - fix: invoke callback when scrolled to bottom of container
1 parent 410a38a commit 332081a

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

polaris-react/src/components/Scrollable/Scrollable.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@
2727
overflow-y: auto;
2828
}
2929

30-
.verticalHasScrolling {
31-
overflow-y: scroll;
32-
}
33-
3430
.hasTopShadow {
3531
box-shadow: var(--pc-scrollable-shadow-top);
3632
}

polaris-react/src/components/Scrollable/Scrollable.tsx

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
StickyManagerContext,
88
} from '../../utilities/sticky-manager';
99
import {scrollable} from '../shared';
10+
import {useLazyRef} from '../../utilities/use-lazy-ref';
11+
import {useComponentDidMount} from '../../utilities/use-component-did-mount';
1012

1113
import {ScrollTo} from './components';
1214
import {ScrollableContext} from './context';
@@ -49,17 +51,18 @@ export function Scrollable({
4951
}: ScrollableProps) {
5052
const [topShadow, setTopShadow] = useState(false);
5153
const [bottomShadow, setBottomShadow] = useState(false);
52-
const stickyManager = useRef(new StickyManager());
54+
const stickyManager = useLazyRef(() => new StickyManager());
5355
const scrollArea = useRef<HTMLDivElement>(null);
5456
const scrollTo = useCallback((scrollY: number) => {
55-
scrollArea.current?.scrollTo({top: scrollY, behavior: 'smooth'});
57+
const behavior = prefersReducedMotion() ? 'auto' : 'smooth';
58+
scrollArea.current?.scrollTo({top: scrollY, behavior});
5659
}, []);
5760

58-
useEffect(() => {
61+
useComponentDidMount(() => {
5962
if (hint) {
6063
performScrollHint(scrollArea.current);
6164
}
62-
}, [hint]);
65+
});
6366

6467
useEffect(() => {
6568
const currentScrollArea = scrollArea.current;
@@ -70,11 +73,17 @@ export function Scrollable({
7073

7174
const handleScroll = () => {
7275
const {scrollTop, clientHeight, scrollHeight} = currentScrollArea;
73-
74-
setBottomShadow(
75-
Boolean(shadow && !(scrollTop + clientHeight >= scrollHeight)),
76+
const isBelowTopOfScroll = Boolean(scrollTop > 0);
77+
const isAtBottomOfScroll = Boolean(
78+
scrollTop + clientHeight >= scrollHeight - LOW_RES_BUFFER,
7679
);
77-
setTopShadow(Boolean(shadow && scrollTop > 0));
80+
81+
setTopShadow(isBelowTopOfScroll);
82+
setBottomShadow(!isAtBottomOfScroll);
83+
84+
if (isAtBottomOfScroll && onScrolledToBottom) {
85+
onScrolledToBottom();
86+
}
7887
};
7988

8089
const handleResize = debounce(handleScroll, 50, {trailing: true});
@@ -89,15 +98,15 @@ export function Scrollable({
8998
currentScrollArea.removeEventListener('scroll', handleScroll);
9099
globalThis.removeEventListener('resize', handleResize);
91100
};
92-
}, [shadow]);
101+
}, [stickyManager, onScrolledToBottom]);
93102

94103
const finalClassName = classNames(
95104
className,
96105
styles.Scrollable,
97106
vertical && styles.vertical,
98107
horizontal && styles.horizontal,
99-
topShadow && styles.hasTopShadow,
100-
bottomShadow && styles.hasBottomShadow,
108+
shadow && topShadow && styles.hasTopShadow,
109+
shadow && bottomShadow && styles.hasBottomShadow,
101110
);
102111

103112
return (

0 commit comments

Comments
 (0)