Skip to content

fix(drawer): tolerate fractional scroll metrics - #36520

Open
Mohd Saif (mohd-saif-1850) wants to merge 1 commit into
microsoft:masterfrom
mohd-saif-1850:fix-drawer-scroll-bottom-divider
Open

fix(drawer): tolerate fractional scroll metrics#36520
Mohd Saif (mohd-saif-1850) wants to merge 1 commit into
microsoft:masterfrom
mohd-saif-1850:fix-drawer-scroll-bottom-divider

Conversation

@mohd-saif-1850

Copy link
Copy Markdown

Description

This PR fixes the scroll-bottom detection in DrawerBody.

Previously, the component checked whether the drawer had reached the bottom using an exact equality comparison:

scrollTop + clientHeight === scrollHeight

* @param element - HTMLElement to check scroll state of
*/
const getScrollState = ({ scrollTop, scrollHeight, clientHeight }: HTMLElement): DrawerScrollState => {
const epsilon = 1;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change is reasonable, browser layout values can be fractional, so strict equality may fail near the bottom.

Main criticisms:

epsilon = 1 is unexplained and could classify the drawer as bottom while still 1px away. Name it descriptively or document why 1px is acceptable.

The top check remains strict. For consistency, consider scrollTop <= epsilon, especially if fractional or slightly negative values can occur.

Prefer comparing the remaining distance

I'd suggest

const scrollTolerance = 1;

if (scrollHeight <= clientHeight) return 'none';
if (scrollTop <= scrollTolerance) return 'top';
if (scrollHeight - clientHeight - scrollTop <= scrollTolerance) return 'bottom';
return 'middle';

Tests should be added to cover fractional values, exact boundaries, and values within/outside the tolerance.

@PaulGMardling PaulGMardling left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes to make the scroll tolerance explicit and consistently applied at both boundaries, with tests added to cover fractional values, exact boundaries, and values within/outside the tolerance.

@PaulGMardling

Copy link
Copy Markdown
Contributor

#36333
Duplicate PR

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-components
react-components: entire library
1.295 MB
326.559 kB
1.295 MB
326.562 kB
1 B
3 B
react-headless-components-preview
react-headless-components-preview: entire library
228.973 kB
65.756 kB
228.974 kB
65.761 kB
1 B
5 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-components
react-components: Button, FluentProvider & webLightTheme
66.297 kB
19.006 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
226.106 kB
68.067 kB
react-components
react-components: FluentProvider & webLightTheme
39.52 kB
13.116 kB
react-headless-components-preview
@fluentui/react-headless-components-preview/tag-picker
62.147 kB
20.587 kB
react-headless-components-preview
@fluentui/react-headless-components-preview/teaching-popover
35.416 kB
11.745 kB
react-portal-compat
PortalCompatProvider
5.341 kB
2.146 kB
react-timepicker-compat
TimePicker
140.991 kB
46.069 kB
🤖 This report was generated against fb77d56db3daa54062b30eb6679763ecd2990eeb

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Pull request demo site: URL

@@ -23,6 +23,7 @@ import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts
* @param element - HTMLElement to check scroll state of

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/Avatar Converged 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Avatar Converged.badgeMask.normal.chromium.png 5 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 882 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 16 Changed
vr-tests-react-components/ProgressBar converged 3 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - Dark Mode.default.chromium.png 59 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - High Contrast.default.chromium.png 69 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness.default.chromium.png 27 Changed
vr-tests-react-components/Skeleton converged 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Skeleton converged.Opaque Skeleton with rectangle - Dark Mode.default.chromium.png 9 Changed
vr-tests-react-components/TagPicker 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - RTL.disabled input hover.chromium.png 635 Changed
vr-tests-react-components/TagPicker.disabled - Dark Mode.disabled input hover.chromium.png 658 Changed

There were 2 duplicate changes discarded. Check the build logs for more information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants