Skip to content

Commit 288d727

Browse files
committed
clean up measurement logic
1 parent 388be48 commit 288d727

File tree

2 files changed

+12
-51
lines changed

2 files changed

+12
-51
lines changed

src/lib/select/select.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#origin="cdkOverlayOrigin"
66
#trigger>
77
<div class="mat-select-value">
8-
<div #measureFontSize class="mat-select-measure-font-size" aria-hidden="true"></div>
98
<ng-container *ngIf="empty">&nbsp;</ng-container>
109
<span class="mat-select-value-text" *ngIf="!empty" [ngSwitch]="!!customTrigger">
1110
<span *ngSwitchDefault>{{ triggerValue }}</span>
@@ -24,7 +23,7 @@
2423
[origin]="origin"
2524
[open]="panelOpen"
2625
[positions]="_positions"
27-
[minWidth]="_triggerWidth"
26+
[minWidth]="_triggerRect?.width"
2827
[offsetY]="_offsetY"
2928
(backdropClick)="close()"
3029
(attach)="_onAttached()"

src/lib/select/select.ts

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,6 @@ export const SELECT_MULTIPLE_PANEL_PADDING_X = SELECT_PANEL_PADDING_X * 1.5 + 20
105105
*/
106106
export const SELECT_PANEL_VIEWPORT_PADDING = 8;
107107

108-
/**
109-
* Default minimum width of the trigger based on the CSS.
110-
* Used as a fallback for server-side rendering.
111-
* @docs-private
112-
*/
113-
const SELECT_TRIGGER_MIN_WIDTH = 112;
114-
115108
/** Injection token that determines the scroll handling while a select is open. */
116109
export const MD_SELECT_SCROLL_STRATEGY =
117110
new InjectionToken<() => ScrollStrategy>('md-select-scroll-strategy');
@@ -219,8 +212,8 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
219212
/** Unique id for this input. */
220213
private _uid = `mat-select-${nextUniqueId++}`;
221214

222-
/** The cached height of the trigger element. */
223-
private _triggerHeight: number;
215+
/** The last measured value for the trigger's client bounding rect. */
216+
_triggerRect: ClientRect;
224217

225218
/** The aria-describedby attribute on the select for improved a11y. */
226219
_ariaDescribedby: string;
@@ -231,12 +224,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
231224
/** Deals with the selection logic. */
232225
_selectionModel: SelectionModel<MdOption>;
233226

234-
/**
235-
* The width of the trigger. Must be saved to set the min width of the overlay panel
236-
* and the width of the selected value.
237-
*/
238-
_triggerWidth: number;
239-
240227
/** Manages keyboard events for options in the panel. */
241228
_keyManager: FocusKeyManager<MdOption>;
242229

@@ -301,9 +288,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
301288
/** Trigger that opens the select. */
302289
@ViewChild('trigger') trigger: ElementRef;
303290

304-
/** Element used to measure the font-size of the trigger element. */
305-
@ViewChild('measureFontSize') _measureFontSizeEl: ElementRef;
306-
307291
/** Overlay pane containing the options. */
308292
@ViewChild(ConnectedOverlayDirective) overlayDir: ConnectedOverlayDirective;
309293

@@ -325,9 +309,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
325309
set placeholder(value: string) {
326310
this._placeholder = value;
327311
this.stateChanges.next();
328-
329-
// Must wait to record the trigger width to ensure placeholder width is included.
330-
Promise.resolve(null).then(() => this._setTriggerWidth());
331312
}
332313

333314
/** Whether the component is required. */
@@ -424,7 +405,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
424405
constructor(
425406
private _viewportRuler: ViewportRuler,
426407
private _changeDetectorRef: ChangeDetectorRef,
427-
private _platform: Platform,
428408
private _ngZone: NgZone,
429409
renderer: Renderer2,
430410
elementRef: ElementRef,
@@ -478,9 +458,10 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
478458
return;
479459
}
480460

481-
if (!this._triggerWidth) {
482-
this._setTriggerWidth();
483-
}
461+
this._triggerRect = this.trigger.nativeElement.getBoundingClientRect();
462+
// Note: The computed font-size will be a string pixel value (e.g. "16px").
463+
// `parseInt` ignores the trailing 'px' and converts this to a number.
464+
this._triggerFontSize = parseInt(getComputedStyle(this.trigger.nativeElement)['font-size']);
484465

485466
this._calculateOverlayPosition();
486467
this._panelOpen = true;
@@ -585,17 +566,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
585566
return this._dir ? this._dir.value === 'rtl' : false;
586567
}
587568

588-
/**
589-
* Sets the width of the trigger element. This is necessary to match
590-
* the overlay width to the trigger width.
591-
*/
592-
private _setTriggerWidth(): void {
593-
this._triggerWidth = this._platform.isBrowser ? this._getTriggerRect().width :
594-
SELECT_TRIGGER_MIN_WIDTH;
595-
596-
this._changeDetectorRef.markForCheck();
597-
}
598-
599569
/** Handles the keyboard interactions of a closed select. */
600570
_handleClosedKeydown(event: KeyboardEvent): void {
601571
if (!this.disabled) {
@@ -777,10 +747,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
777747
this.stateChanges.next();
778748
}
779749

780-
private _getTriggerRect(): ClientRect {
781-
return this.trigger.nativeElement.getBoundingClientRect();
782-
}
783-
784750
/** Sets up a key manager to listen to keyboard events on the overlay panel. */
785751
private _initKeyManager() {
786752
this._keyManager = new FocusKeyManager<MdOption>(this.options).withTypeAhead();
@@ -923,9 +889,6 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
923889

924890
/** Calculates the scroll position and x- and y-offsets of the overlay panel. */
925891
private _calculateOverlayPosition(): void {
926-
this._triggerHeight = this.trigger.nativeElement.getBoundingClientRect().height;
927-
this._triggerFontSize = this._measureFontSizeEl.nativeElement.getBoundingClientRect().height;
928-
929892
const itemHeight = this._triggerFontSize * SELECT_ITEM_HEIGHT_EM;
930893

931894
const items = this._getItemCount();
@@ -1033,7 +996,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
1033996
private _calculateOverlayOffsetY(selectedIndex: number, scrollBuffer: number,
1034997
maxScroll: number): number {
1035998
const itemHeight = this._triggerFontSize * SELECT_ITEM_HEIGHT_EM;
1036-
const optionHeightAdjustment = (itemHeight - this._triggerHeight) / 2;
999+
const optionHeightAdjustment = (itemHeight - this._triggerRect.height) / 2;
10371000
const maxOptionsDisplayed = Math.floor(SELECT_PANEL_MAX_HEIGHT / itemHeight);
10381001
let optionOffsetFromPanelTop: number;
10391002

@@ -1075,16 +1038,15 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
10751038
private _checkOverlayWithinViewport(maxScroll: number): void {
10761039
const itemHeight = this._triggerFontSize * SELECT_ITEM_HEIGHT_EM;
10771040
const viewportRect = this._viewportRuler.getViewportRect();
1078-
const triggerRect = this._getTriggerRect();
10791041

1080-
const topSpaceAvailable = triggerRect.top - SELECT_PANEL_VIEWPORT_PADDING;
1042+
const topSpaceAvailable = this._triggerRect.top - SELECT_PANEL_VIEWPORT_PADDING;
10811043
const bottomSpaceAvailable =
1082-
viewportRect.height - triggerRect.bottom - SELECT_PANEL_VIEWPORT_PADDING;
1044+
viewportRect.height - this._triggerRect.bottom - SELECT_PANEL_VIEWPORT_PADDING;
10831045

10841046
const panelHeightTop = Math.abs(this._offsetY);
10851047
const totalPanelHeight =
10861048
Math.min(this._getItemCount() * itemHeight, SELECT_PANEL_MAX_HEIGHT);
1087-
const panelHeightBottom = totalPanelHeight - panelHeightTop - triggerRect.height;
1049+
const panelHeightBottom = totalPanelHeight - panelHeightTop - this._triggerRect.height;
10881050

10891051
if (panelHeightBottom > bottomSpaceAvailable) {
10901052
this._adjustPanelUp(panelHeightBottom, bottomSpaceAvailable);
@@ -1142,7 +1104,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
11421104
/** Sets the transform origin point based on the selected option. */
11431105
private _getOriginBasedOnOption(): string {
11441106
const itemHeight = this._triggerFontSize * SELECT_ITEM_HEIGHT_EM;
1145-
const optionHeightAdjustment = (itemHeight - this._triggerHeight) / 2;
1107+
const optionHeightAdjustment = (itemHeight - this._triggerRect.height) / 2;
11461108
const originY = Math.abs(this._offsetY) - optionHeightAdjustment + itemHeight / 2;
11471109
return `50% ${originY}px 0px`;
11481110
}

0 commit comments

Comments
 (0)