-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[Popover] Set right position when preferred alignment is right. #2587
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
Changes from all commits
231b77e
e819b92
210ab4e
a3998fa
771a635
7339c8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,8 @@ export {PreferredPosition, PreferredAlignment}; | |
export type Positioning = 'above' | 'below'; | ||
|
||
export interface OverlayDetails { | ||
left: number; | ||
left?: number; | ||
right?: number; | ||
desiredHeight: number; | ||
positioning: Positioning; | ||
measuring: boolean; | ||
|
@@ -44,7 +45,8 @@ export interface PositionedOverlayProps { | |
interface State { | ||
measuring: boolean; | ||
activatorRect: Rect; | ||
left: number; | ||
left?: number; | ||
right?: number; | ||
top: number; | ||
height: number; | ||
width: number | null; | ||
|
@@ -63,7 +65,8 @@ export class PositionedOverlay extends React.PureComponent< | |
state: State = { | ||
measuring: true, | ||
activatorRect: getRectForNode(this.props.activator), | ||
left: 0, | ||
right: undefined, | ||
left: undefined, | ||
top: 0, | ||
height: 0, | ||
width: null, | ||
|
@@ -118,12 +121,13 @@ export class PositionedOverlay extends React.PureComponent< | |
} | ||
|
||
render() { | ||
const {left, top, zIndex, width} = this.state; | ||
const {left, right, top, zIndex, width} = this.state; | ||
const {render, fixed, classNames: propClassNames} = this.props; | ||
|
||
const style = { | ||
top: top == null || isNaN(top) ? undefined : top, | ||
left: left == null || isNaN(left) ? undefined : left, | ||
right: right == null || isNaN(right) ? undefined : right, | ||
width: width == null || isNaN(width) ? undefined : width, | ||
zIndex: zIndex == null || isNaN(zIndex) ? undefined : zIndex, | ||
}; | ||
|
@@ -143,11 +147,19 @@ export class PositionedOverlay extends React.PureComponent< | |
} | ||
|
||
private overlayDetails = (): OverlayDetails => { | ||
const {measuring, left, positioning, height, activatorRect} = this.state; | ||
const { | ||
measuring, | ||
left, | ||
right, | ||
positioning, | ||
height, | ||
activatorRect, | ||
} = this.state; | ||
|
||
return { | ||
measuring, | ||
left, | ||
right, | ||
desiredHeight: height, | ||
positioning, | ||
activatorRect, | ||
|
@@ -164,8 +176,9 @@ export class PositionedOverlay extends React.PureComponent< | |
this.observer.disconnect(); | ||
|
||
this.setState( | ||
({left, top}) => ({ | ||
({left, top, right}) => ({ | ||
left, | ||
right, | ||
top, | ||
height: 0, | ||
positioning: 'below', | ||
|
@@ -209,6 +222,7 @@ export class PositionedOverlay extends React.PureComponent< | |
const overlayMargins = this.overlay.firstElementChild | ||
? getMarginsForNode(this.overlay.firstElementChild as HTMLElement) | ||
: {activator: 0, container: 0, horizontal: 0}; | ||
|
||
const containerRect = windowRect(); | ||
const zIndexForLayer = getZIndexForLayerFromNode(activator); | ||
const zIndex = | ||
|
@@ -234,7 +248,10 @@ export class PositionedOverlay extends React.PureComponent< | |
{ | ||
measuring: false, | ||
activatorRect: getRectForNode(activator), | ||
left: horizontalPosition, | ||
left: | ||
preferredAlignment !== 'right' ? horizontalPosition : undefined, | ||
right: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
preferredAlignment === 'right' ? horizontalPosition : undefined, | ||
top: lockPosition ? top : verticalPosition.top, | ||
lockPosition: Boolean(fixed), | ||
height: verticalPosition.height || 0, | ||
|
@@ -278,9 +295,9 @@ export function intersectionWithViewport( | |
function getMarginsForNode(node: HTMLElement) { | ||
const nodeStyles = window.getComputedStyle(node); | ||
return { | ||
activator: parseFloat(nodeStyles.marginTop || ''), | ||
container: parseFloat(nodeStyles.marginBottom || ''), | ||
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 commentThe 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. |
||
}; | ||
} | ||
|
||
|
@@ -298,7 +315,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 commentThe 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 commentThe 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 commentThe 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. |
||
}); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,6 +70,20 @@ describe('<PositionedOverlay />', () => { | |
<PositionedOverlay {...mockProps} preferredAlignment="left" />, | ||
); | ||
|
||
expect((positionedOverlay.find('div').prop('style') as any).left).toBe(0); | ||
expect( | ||
(positionedOverlay.find('div').prop('style') as any).right, | ||
).toBeUndefined(); | ||
}); | ||
|
||
it('aligns right if preferredAlignment is given', () => { | ||
const positionedOverlay = mountWithAppProvider( | ||
<PositionedOverlay {...mockProps} preferredAlignment="right" />, | ||
); | ||
|
||
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 commentThe 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. |
||
).toBeUndefined(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,13 +98,12 @@ 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 commentThe reason will be displayed to describe this comment to others. Learn more. the right position calculation. |
||
|
||
return Math.min( | ||
maximum, | ||
Math.max( | ||
0, | ||
activatorRight - overlayRect.width + overlayMargins.horizontal, | ||
), | ||
Math.max(0, activatorRight - overlayMargins.horizontal), | ||
); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 commentThe reason will be displayed to describe this comment to others. Learn more. The user menu was causing the issue. This fixed it. |
||
> | ||
<ActionList onActionAnyItem={onClose} sections={actions} /> | ||
{messageMarkup} | ||
|
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.