Skip to content

Commit aaf5c81

Browse files
crisbetoandrewseguin
authored andcommitted
fix(overlay): global overlay incorrectly handling left/right position when RTL is set on body (#11412)
We use `justify-content` to position global overlay to the left or right, however `justify-content` gets inverted when the element is in RTL. Since our methods are called explicitly `left` and `right`, the expectation is that the element would stay to the left or right, no matter what the direction is. This is an issue if the `dir` is set on the `body` or `html` tags, because it'll end up propagating down to the overlay wrapper, causing its directions to be inverted. These changes invert `justify-content` in RTL, in order to ensure that the overlay behaves as expected. Relates to #11393.
1 parent 0c331c1 commit aaf5c81

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/cdk/overlay/position/global-position-strategy.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,25 @@ describe('GlobalPositonStrategy', () => {
270270
expect(elementStyle.height).toBe('300px');
271271
});
272272

273+
it('should invert `justify-content` when using `left` in RTL', () => {
274+
attachOverlay({
275+
positionStrategy: overlay.position().global().left('0'),
276+
direction: 'rtl'
277+
});
278+
279+
const parentStyle = (overlayRef.overlayElement.parentNode as HTMLElement).style;
280+
expect(parentStyle.justifyContent).toBe('flex-end');
281+
});
282+
283+
it('should invert `justify-content` when using `right` in RTL', () => {
284+
attachOverlay({
285+
positionStrategy: overlay.position().global().right('0'),
286+
direction: 'rtl'
287+
});
288+
289+
const parentStyle = (overlayRef.overlayElement.parentNode as HTMLElement).style;
290+
expect(parentStyle.justifyContent).toBe('flex-start');
291+
});
273292
});
274293

275294

src/cdk/overlay/position/global-position-strategy.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,22 @@ export class GlobalPositionStrategy implements PositionStrategy {
167167
styles.marginBottom = this._bottomOffset;
168168
styles.marginRight = this._rightOffset;
169169

170-
parentStyles.justifyContent = config.width === '100%' ? 'flex-start' : this._justifyContent;
170+
if (config.width === '100%') {
171+
parentStyles.justifyContent = 'flex-start';
172+
} else if (this._overlayRef.getConfig().direction === 'rtl') {
173+
// In RTL the browser will invert `flex-start` and `flex-end` automatically, but we
174+
// don't want that because our positioning is explicitly `left` and `right`, hence
175+
// why we do another inversion to ensure that the overlay stays in the same position.
176+
// TODO: reconsider this if we add `start` and `end` methods.
177+
if (this._justifyContent === 'flex-start') {
178+
parentStyles.justifyContent = 'flex-end';
179+
} else if (this._justifyContent === 'flex-end') {
180+
parentStyles.justifyContent = 'flex-start';
181+
}
182+
} else {
183+
parentStyles.justifyContent = this._justifyContent;
184+
}
185+
171186
parentStyles.alignItems = config.height === '100%' ? 'flex-start' : this._alignItems;
172187
}
173188

0 commit comments

Comments
 (0)