66import { FocusMonitor } from '@angular/cdk/a11y' ;
77import { Direction , Directionality } from '@angular/cdk/bidi' ;
88import { DOWN_ARROW , ENTER , ESCAPE , SPACE , TAB , UP_ARROW } from '@angular/cdk/keycodes' ;
9- import { CdkConnectedOverlay , CdkOverlayOrigin , ConnectedOverlayPositionChange } from '@angular/cdk/overlay' ;
9+ import {
10+ CdkConnectedOverlay ,
11+ CdkOverlayOrigin ,
12+ ConnectedOverlayPositionChange ,
13+ ConnectionPositionPair
14+ } from '@angular/cdk/overlay' ;
1015import { Platform } from '@angular/cdk/platform' ;
1116import {
1217 AfterContentInit ,
@@ -40,6 +45,7 @@ import { slideMotion } from 'ng-zorro-antd/core/animation';
4045import { NzConfigKey , NzConfigService , WithConfig } from 'ng-zorro-antd/core/config' ;
4146import { NzFormNoStatusService , NzFormStatusService } from 'ng-zorro-antd/core/form' ;
4247import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation' ;
48+ import { getPlacementName , POSITION_MAP , POSITION_TYPE } from 'ng-zorro-antd/core/overlay' ;
4349import { cancelRequestAnimationFrame , reqAnimFrame } from 'ng-zorro-antd/core/polyfill' ;
4450import { NzDestroyService } from 'ng-zorro-antd/core/services' ;
4551import {
@@ -56,7 +62,13 @@ import { getStatusClassNames, InputBoolean, isNotNil } from 'ng-zorro-antd/core/
5662import { NzOptionGroupComponent } from './option-group.component' ;
5763import { NzOptionComponent } from './option.component' ;
5864import { NzSelectTopControlComponent } from './select-top-control.component' ;
59- import { NzFilterOptionType , NzSelectItemInterface , NzSelectModeType , NzSelectOptionInterface } from './select.types' ;
65+ import {
66+ NzFilterOptionType ,
67+ NzSelectItemInterface ,
68+ NzSelectModeType ,
69+ NzSelectOptionInterface ,
70+ NzSelectPlacementType
71+ } from './select.types' ;
6072
6173const defaultFilterOption : NzFilterOptionType = ( searchValue : string , item : NzSelectItemInterface ) : boolean => {
6274 if ( item && item . nzLabel ) {
@@ -137,6 +149,7 @@ export type NzSelectSizeType = 'large' | 'default' | 'small';
137149 [cdkConnectedOverlayTransformOriginOn]="'.ant-select-dropdown'"
138150 [cdkConnectedOverlayPanelClass]="nzDropdownClassName!"
139151 [cdkConnectedOverlayOpen]="nzOpen"
152+ [cdkConnectedOverlayPositions]="positions"
140153 (overlayOutsideClick)="onClickOutside($event)"
141154 (detach)="setOpenState(false)"
142155 (positionChange)="onPositionChange($event)"
@@ -146,8 +159,10 @@ export type NzSelectSizeType = 'large' | 'default' | 'small';
146159 [itemSize]="nzOptionHeightPx"
147160 [maxItemLength]="nzOptionOverflowSize"
148161 [matchWidth]="nzDropdownMatchSelectWidth"
149- [class.ant-select-dropdown-placement-bottomLeft]="dropDownPosition === 'bottom'"
150- [class.ant-select-dropdown-placement-topLeft]="dropDownPosition === 'top'"
162+ [class.ant-select-dropdown-placement-bottomLeft]="dropDownPosition === 'bottomLeft'"
163+ [class.ant-select-dropdown-placement-topLeft]="dropDownPosition === 'topLeft'"
164+ [class.ant-select-dropdown-placement-bottomRight]="dropDownPosition === 'bottomRight'"
165+ [class.ant-select-dropdown-placement-topRight]="dropDownPosition === 'topRight'"
151166 [@slideMotion]="'enter'"
152167 [@.disabled]="noAnimation?.nzNoAnimation"
153168 [nzNoAnimation]="noAnimation?.nzNoAnimation"
@@ -205,6 +220,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
205220 @Input ( ) nzDropdownStyle : { [ key : string ] : string } | null = null ;
206221 @Input ( ) nzNotFoundContent : string | TemplateRef < NzSafeAny > | undefined = undefined ;
207222 @Input ( ) nzPlaceHolder : string | TemplateRef < NzSafeAny > | null = null ;
223+ @Input ( ) nzPlacement : NzSelectPlacementType | null = null ;
208224 @Input ( ) nzMaxTagCount = Infinity ;
209225 @Input ( ) nzDropdownRender : TemplateRef < NzSafeAny > | null = null ;
210226 @Input ( ) nzCustomTemplate : TemplateRef < { $implicit : NzSelectItemInterface } > | null = null ;
@@ -264,14 +280,15 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
264280 private requestId : number = - 1 ;
265281 onChange : OnChangeType = ( ) => { } ;
266282 onTouched : OnTouchedType = ( ) => { } ;
267- dropDownPosition : 'top' | 'center' | 'bottom' = 'bottom ' ;
283+ dropDownPosition : NzSelectPlacementType = 'bottomLeft ' ;
268284 triggerWidth : number | null = null ;
269285 listOfContainerItem : NzSelectItemInterface [ ] = [ ] ;
270286 listOfTopItem : NzSelectItemInterface [ ] = [ ] ;
271287 activatedValue : NzSafeAny | null = null ;
272288 listOfValue : NzSafeAny [ ] = [ ] ;
273289 focused = false ;
274290 dir : Direction = 'ltr' ;
291+ positions : ConnectionPositionPair [ ] = [ ] ;
275292
276293 // status
277294 prefixCls : string = 'ant-select' ;
@@ -500,7 +517,8 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
500517 }
501518
502519 onPositionChange ( position : ConnectedOverlayPositionChange ) : void {
503- this . dropDownPosition = position . connectionPair . originY ;
520+ const placement = getPlacementName ( position ) ;
521+ this . dropDownPosition = placement as NzSelectPlacementType ;
504522 }
505523
506524 updateCdkConnectedOverlayStatus ( ) : void {
@@ -579,7 +597,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
579597 }
580598
581599 ngOnChanges ( changes : SimpleChanges ) : void {
582- const { nzOpen, nzDisabled, nzOptions, nzStatus } = changes ;
600+ const { nzOpen, nzDisabled, nzOptions, nzStatus, nzPlacement } = changes ;
583601 if ( nzOpen ) {
584602 this . onOpenChange ( ) ;
585603 }
@@ -607,6 +625,16 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
607625 if ( nzStatus ) {
608626 this . setStatusStyles ( this . nzStatus , this . hasFeedback ) ;
609627 }
628+ if ( nzPlacement ) {
629+ const { currentValue } = nzPlacement ;
630+ this . dropDownPosition = currentValue as NzSelectPlacementType ;
631+ const listOfPlacement = [ 'bottomLeft' , 'topLeft' , 'bottomRight' , 'topRight' ] ;
632+ if ( currentValue && listOfPlacement . includes ( currentValue ) ) {
633+ this . positions = [ POSITION_MAP [ currentValue as POSITION_TYPE ] ] ;
634+ } else {
635+ this . positions = listOfPlacement . map ( e => POSITION_MAP [ e as POSITION_TYPE ] ) ;
636+ }
637+ }
610638 }
611639
612640 ngOnInit ( ) : void {
0 commit comments