-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Popover] Set right position when preferred alignment is right. #2587
Conversation
@@ -52,7 +52,7 @@ $content-max-width: rem(400px); | |||
} | |||
|
|||
.positionedAbove { | |||
margin: spacing() 0 $visible-portion-of-arrow spacing(tight); | |||
margin: spacing() spacing(tight) $visible-portion-of-arrow; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why we needed to remove the right margin when positioned above.
left: horizontalPosition, | ||
left: | ||
preferredAlignment !== 'right' ? horizontalPosition : undefined, | ||
right: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're only going to go from the right if the preferred alignment is right.
@@ -298,7 +317,7 @@ function windowRect() { | |||
top: window.scrollY, | |||
left: window.scrollX, | |||
height: window.innerHeight, | |||
width: window.innerWidth, | |||
width: document.body.clientWidth, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
window.innerWidth includes the scrollbars, We don't want this when aligning from the right and it's shouldn't impact the left.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL! Will this change alone fix the measuring then and the other stuff in this PR is just a nice to have?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the right positioning is what is needed. I'll write it in the description.
@@ -98,13 +98,11 @@ export function calculateHorizontalPosition( | |||
Math.max(0, activatorRect.left - overlayMargins.horizontal), | |||
); | |||
} else if (preferredAlignment === 'right') { | |||
const activatorRight = activatorRect.left + activatorRect.width; | |||
const activatorRight = | |||
containerRect.width - (activatorRect.left + activatorRect.width); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the right position calculation.
@@ -57,6 +57,7 @@ export function Menu(props: MenuProps) { | |||
onClose={onClose} | |||
fixed | |||
fullHeight={isFullHeight} | |||
preferredAlignment="right" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The user menu was causing the issue. This fixed it.
121e07d
to
782d7b1
Compare
horizontal: parseFloat(nodeStyles.marginLeft || ''), | ||
activator: parseFloat(nodeStyles.marginTop || '0'), | ||
container: parseFloat(nodeStyles.marginBottom || '0'), | ||
horizontal: parseFloat(nodeStyles.marginLeft || '0'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defaulting to 0. an empty string didn't make sense for the tests.
|
||
expect((positionedOverlay.find('div').prop('style') as any).right).toBe( | ||
0, | ||
); | ||
expect( | ||
(positionedOverlay.find('div').prop('style') as any).left, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test didn't make sense. No matter whar left would be undefined, which it shouldn't be.
:( Just saw that safari still wraps for no good reason. |
Looks like this approach works perfectly on Chrome, but Firefox and Safari do not resize the parent |
Yeah, been there with these changes 😞 Every approach we tried was inconsistent across browsers. Only idea I have left is to start from scratch with this component... I feel like a lot of the logic is unnecessary, but because it's unclear what some of it is meant to do, refactoring it while trying to fix this just kept breaking it in other ways 😣. |
@chloerice I thought of redoing it but after wrapping my head around it it's actually pretty good and I fear we'll end up in the same spot. The only thing I can think of is to add complexity and measure whether or not the content will cause scrollbars, then measure the scrollbar, then add the scrollbar width to the container. The math is all correct. I asked @tmlayton to take a look and see if he can see something we're missing. It works perfectly in Chrome right now. It's almost tempting to ship this. |
We could always revert this when we have a better fix. Getting something out that'll work for the majority of consumers seems like a win to me. |
I made this PR #2362 that starts the logic again from scratch, removing the confusing As Tim mentioned it needs tests to make sure it doesn't break anything. |
5db1747
to
a3998fa
Compare
Alright, this should be good now. When content can be scrolled in a Always on scrollbarsAlways on scrollbars with non-scrolling contentFloating scrollbars (does not apply to Edge) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🌟 🙌
@tmlayton you are a 🌟 🙇 |
WHY are these changes introduced?
Fixes #1673
WHAT is this pull request doing?
From what I can tell the issue is that the Scrollable scrollbars appear inside the Popover after the PositionOverlay has done its calculations and since the content is responsive, once the scrollbars are added the content wraps.
For example. If the window is 1000px wide, the overlay 100px wide, the left position will be calculated at 900px. Once the scrollbars appear, the left position does not get recalculated because the content is responsive. The left position pushed the overlay against the right side of the browser and when too close to the chrome causes the content to wrap. This occurs only when the popover is too close to the right of the window.
This is one of a few attempts at fixing this issue. When a popover has a preferred right, we go from the right instead of the left. That way, even if scrollbars appear, the right position stays the same, and the left does not counter it.
It also contains a change that when content can be scrolled in a Scrollable container, it sets
overflow-y: scroll
then reverts toauto
when the content cannot be scrolled. This forces the layout engines to set the element width properly.How to 🎩
🖥 Local development instructions
🗒 General tophatting guidelines
📄 Changelog guidelines
Copy-paste this code in
playground/Playground.tsx
:🎩 checklist
README.md
with documentation changes