diff --git a/.changeset/healthy-clouds-design.md b/.changeset/healthy-clouds-design.md new file mode 100644 index 00000000000..a8d4b9037f6 --- /dev/null +++ b/.changeset/healthy-clouds-design.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris': major +--- + +Added flushSync call to state updates in Scrollable component. This would probably be a breaking change? :( diff --git a/polaris-react/src/components/Scrollable/Scrollable.tsx b/polaris-react/src/components/Scrollable/Scrollable.tsx index 8dd5a468538..0317d50d270 100644 --- a/polaris-react/src/components/Scrollable/Scrollable.tsx +++ b/polaris-react/src/components/Scrollable/Scrollable.tsx @@ -1,4 +1,5 @@ import React, {Component} from 'react'; +import {flushSync} from 'react-dom'; import {debounce} from '../../utilities/debounce'; import {classNames} from '../../utilities/css'; @@ -96,8 +97,15 @@ export class Scrollable extends Component { } componentDidUpdate() { + if (!this.scrollArea) { + return; + } + const {scrollPosition} = this.state; - if (scrollPosition && this.scrollArea && scrollPosition > 0) { + const availableScrollHeight = + this.scrollArea.scrollHeight - this.scrollArea.clientHeight; + + if (scrollPosition > 0 && scrollPosition < availableScrollHeight) { this.scrollArea.scrollTop = scrollPosition; } } @@ -171,11 +179,13 @@ export class Scrollable extends Component { onScrolledToBottom(); } - this.setState({ - topShadow: shouldTopShadow, - bottomShadow: shouldBottomShadow, - scrollPosition: scrollTop, - canScroll, + flushSync(() => { + this.setState({ + topShadow: shouldTopShadow, + bottomShadow: shouldBottomShadow, + scrollPosition: scrollTop, + canScroll, + }); }); };