Skip to content

Commit 619f7f8

Browse files
authored
fix(autocomplete): provide horizontal fallback positions (#18906)
The positions for the autocomplete dropdown are set up assuming that the panel's width will match the input so they don't provide fallbacks along the x axis. Since we have a `panelWidth` input, the consumer might've overwritten the width to something different so we need to provide the fallbacks to ensure that the panel is always inside the viewport. Fixes #18854.
1 parent 92bbc77 commit 619f7f8

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

src/material/autocomplete/autocomplete-trigger.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -694,32 +694,30 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, AfterViewIn
694694

695695
/** Sets the positions on a position strategy based on the directive's input state. */
696696
private _setStrategyPositions(positionStrategy: FlexibleConnectedPositionStrategy) {
697-
const belowPosition: ConnectedPosition = {
698-
originX: 'start',
699-
originY: 'bottom',
700-
overlayX: 'start',
701-
overlayY: 'top'
702-
};
703-
const abovePosition: ConnectedPosition = {
704-
originX: 'start',
705-
originY: 'top',
706-
overlayX: 'start',
707-
overlayY: 'bottom',
708-
709-
// The overlay edge connected to the trigger should have squared corners, while
710-
// the opposite end has rounded corners. We apply a CSS class to swap the
711-
// border-radius based on the overlay position.
712-
panelClass: 'mat-autocomplete-panel-above'
713-
};
697+
// Note that we provide horizontal fallback positions, even though by default the dropdown
698+
// width matches the input, because consumers can override the width. See #18854.
699+
const belowPositions: ConnectedPosition[] = [
700+
{originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top'},
701+
{originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top'}
702+
];
703+
704+
// The overlay edge connected to the trigger should have squared corners, while
705+
// the opposite end has rounded corners. We apply a CSS class to swap the
706+
// border-radius based on the overlay position.
707+
const panelClass = 'mat-autocomplete-panel-above';
708+
const abovePositions: ConnectedPosition[] = [
709+
{originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', panelClass},
710+
{originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', panelClass}
711+
];
714712

715713
let positions: ConnectedPosition[];
716714

717715
if (this.position === 'above') {
718-
positions = [abovePosition];
716+
positions = abovePositions;
719717
} else if (this.position === 'below') {
720-
positions = [belowPosition];
718+
positions = belowPositions;
721719
} else {
722-
positions = [belowPosition, abovePosition];
720+
positions = [...belowPositions, ...abovePositions];
723721
}
724722

725723
positionStrategy.withPositions(positions);

0 commit comments

Comments
 (0)