@@ -55,7 +55,6 @@ import {SelectionModel} from '../core/selection/selection';
55
55
import { getMdSelectDynamicMultipleError , getMdSelectNonArrayValueError } from './select-errors' ;
56
56
import { CanDisable , mixinDisabled } from '../core/common-behaviors/disabled' ;
57
57
import { MdOptgroup , MdOption , MdOptionSelectionChange } from '../core/option/index' ;
58
- import { Platform } from '@angular/cdk/platform' ;
59
58
import { MdFormFieldControl } from '../form-field/index' ;
60
59
import { Subject } from 'rxjs/Subject' ;
61
60
@@ -95,13 +94,6 @@ export const SELECT_MULTIPLE_PANEL_PADDING_X = SELECT_PANEL_PADDING_X * 1.5 + 20
95
94
*/
96
95
export const SELECT_PANEL_VIEWPORT_PADDING = 8 ;
97
96
98
- /**
99
- * Default minimum width of the trigger based on the CSS.
100
- * Used as a fallback for server-side rendering.
101
- * @docs -private
102
- */
103
- const SELECT_TRIGGER_MIN_WIDTH = 112 ;
104
-
105
97
/** Injection token that determines the scroll handling while a select is open. */
106
98
export const MD_SELECT_SCROLL_STRATEGY =
107
99
new InjectionToken < ( ) => ScrollStrategy > ( 'md-select-scroll-strategy' ) ;
@@ -208,8 +200,8 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
208
200
/** Tab index for the element. */
209
201
private _tabIndex : number ;
210
202
211
- /** The cached height of the trigger element . */
212
- private _triggerHeight : number ;
203
+ /** The last measured value for the trigger's client bounding rect . */
204
+ _triggerRect : ClientRect ;
213
205
214
206
/** The aria-describedby attribute on the select for improved a11y. */
215
207
_ariaDescribedby : string ;
@@ -220,12 +212,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
220
212
/** Deals with the selection logic. */
221
213
_selectionModel : SelectionModel < MdOption > ;
222
214
223
- /**
224
- * The width of the trigger. Must be saved to set the min width of the overlay panel
225
- * and the width of the selected value.
226
- */
227
- _triggerWidth : number ;
228
-
229
215
/** Manages keyboard events for options in the panel. */
230
216
_keyManager : FocusKeyManager < MdOption > ;
231
217
@@ -290,9 +276,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
290
276
/** Trigger that opens the select. */
291
277
@ViewChild ( 'trigger' ) trigger : ElementRef ;
292
278
293
- /** Element used to measure the font-size of the trigger element. */
294
- @ViewChild ( 'measureFontSize' ) _measureFontSizeEl : ElementRef ;
295
-
296
279
/** Overlay pane containing the options. */
297
280
@ViewChild ( ConnectedOverlayDirective ) overlayDir : ConnectedOverlayDirective ;
298
281
@@ -314,9 +297,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
314
297
set placeholder ( value : string ) {
315
298
this . _placeholder = value ;
316
299
this . stateChanges . next ( ) ;
317
-
318
- // Must wait to record the trigger width to ensure placeholder width is included.
319
- Promise . resolve ( null ) . then ( ( ) => this . _setTriggerWidth ( ) ) ;
320
300
}
321
301
322
302
/** Whether the component is required. */
@@ -404,7 +384,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
404
384
constructor (
405
385
private _viewportRuler : ViewportRuler ,
406
386
private _changeDetectorRef : ChangeDetectorRef ,
407
- private _platform : Platform ,
408
387
private _ngZone : NgZone ,
409
388
renderer : Renderer2 ,
410
389
elementRef : ElementRef ,
@@ -469,9 +448,10 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
469
448
return ;
470
449
}
471
450
472
- if ( ! this . _triggerWidth ) {
473
- this . _setTriggerWidth ( ) ;
474
- }
451
+ this . _triggerRect = this . trigger . nativeElement . getBoundingClientRect ( ) ;
452
+ // Note: The computed font-size will be a string pixel value (e.g. "16px").
453
+ // `parseInt` ignores the trailing 'px' and converts this to a number.
454
+ this . _triggerFontSize = parseInt ( getComputedStyle ( this . trigger . nativeElement ) [ 'font-size' ] ) ;
475
455
476
456
this . _calculateOverlayPosition ( ) ;
477
457
this . _panelOpen = true ;
@@ -572,17 +552,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
572
552
return this . _dir ? this . _dir . value === 'rtl' : false ;
573
553
}
574
554
575
- /**
576
- * Sets the width of the trigger element. This is necessary to match
577
- * the overlay width to the trigger width.
578
- */
579
- private _setTriggerWidth ( ) : void {
580
- this . _triggerWidth = this . _platform . isBrowser ? this . _getTriggerRect ( ) . width :
581
- SELECT_TRIGGER_MIN_WIDTH ;
582
-
583
- this . _changeDetectorRef . markForCheck ( ) ;
584
- }
585
-
586
555
/** Handles the keyboard interactions of a closed select. */
587
556
_handleClosedKeydown ( event : KeyboardEvent ) : void {
588
557
if ( ! this . disabled ) {
@@ -746,10 +715,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
746
715
this . stateChanges . next ( ) ;
747
716
}
748
717
749
- private _getTriggerRect ( ) : ClientRect {
750
- return this . trigger . nativeElement . getBoundingClientRect ( ) ;
751
- }
752
-
753
718
/** Sets up a key manager to listen to keyboard events on the overlay panel. */
754
719
private _initKeyManager ( ) {
755
720
this . _keyManager = new FocusKeyManager < MdOption > ( this . options ) . withTypeAhead ( ) ;
@@ -895,9 +860,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
895
860
896
861
/** Calculates the scroll position and x- and y-offsets of the overlay panel. */
897
862
private _calculateOverlayPosition ( ) : void {
898
- this . _triggerHeight = this . trigger . nativeElement . getBoundingClientRect ( ) . height ;
899
- this . _triggerFontSize = this . _measureFontSizeEl . nativeElement . getBoundingClientRect ( ) . height ;
900
-
901
863
const itemHeight = this . _triggerFontSize * SELECT_ITEM_HEIGHT_EM ;
902
864
903
865
const items = this . _getItemCount ( ) ;
@@ -1004,7 +966,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
1004
966
private _calculateOverlayOffsetY ( selectedIndex : number , scrollBuffer : number ,
1005
967
maxScroll : number ) : number {
1006
968
const itemHeight = this . _triggerFontSize * SELECT_ITEM_HEIGHT_EM ;
1007
- const optionHeightAdjustment = ( itemHeight - this . _triggerHeight ) / 2 ;
969
+ const optionHeightAdjustment = ( itemHeight - this . _triggerRect . height ) / 2 ;
1008
970
const maxOptionsDisplayed = Math . floor ( SELECT_PANEL_MAX_HEIGHT / itemHeight ) ;
1009
971
let optionOffsetFromPanelTop : number ;
1010
972
@@ -1042,20 +1004,21 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
1042
1004
* If it will not fit, tries to adjust the scroll position and the associated
1043
1005
* y-offset so the panel can open fully on-screen. If it still won't fit,
1044
1006
* sets the offset back to 0 to allow the fallback position to take over.
1007
+ *
1008
+ * Note: This method
1045
1009
*/
1046
1010
private _checkOverlayWithinViewport ( maxScroll : number ) : void {
1047
1011
const itemHeight = this . _triggerFontSize * SELECT_ITEM_HEIGHT_EM ;
1048
1012
const viewportRect = this . _viewportRuler . getViewportRect ( ) ;
1049
- const triggerRect = this . _getTriggerRect ( ) ;
1050
1013
1051
- const topSpaceAvailable = triggerRect . top - SELECT_PANEL_VIEWPORT_PADDING ;
1014
+ const topSpaceAvailable = this . _triggerRect . top - SELECT_PANEL_VIEWPORT_PADDING ;
1052
1015
const bottomSpaceAvailable =
1053
- viewportRect . height - triggerRect . bottom - SELECT_PANEL_VIEWPORT_PADDING ;
1016
+ viewportRect . height - this . _triggerRect . bottom - SELECT_PANEL_VIEWPORT_PADDING ;
1054
1017
1055
1018
const panelHeightTop = Math . abs ( this . _offsetY ) ;
1056
1019
const totalPanelHeight =
1057
1020
Math . min ( this . _getItemCount ( ) * itemHeight , SELECT_PANEL_MAX_HEIGHT ) ;
1058
- const panelHeightBottom = totalPanelHeight - panelHeightTop - triggerRect . height ;
1021
+ const panelHeightBottom = totalPanelHeight - panelHeightTop - this . _triggerRect . height ;
1059
1022
1060
1023
if ( panelHeightBottom > bottomSpaceAvailable ) {
1061
1024
this . _adjustPanelUp ( panelHeightBottom , bottomSpaceAvailable ) ;
@@ -1113,7 +1076,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
1113
1076
/** Sets the transform origin point based on the selected option. */
1114
1077
private _getOriginBasedOnOption ( ) : string {
1115
1078
const itemHeight = this . _triggerFontSize * SELECT_ITEM_HEIGHT_EM ;
1116
- const optionHeightAdjustment = ( itemHeight - this . _triggerHeight ) / 2 ;
1079
+ const optionHeightAdjustment = ( itemHeight - this . _triggerRect . height ) / 2 ;
1117
1080
const originY = Math . abs ( this . _offsetY ) - optionHeightAdjustment + itemHeight / 2 ;
1118
1081
return `50% ${ originY } px 0px` ;
1119
1082
}
0 commit comments