Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(select): wrong panel width if element is hidden initially #3647

Merged
merged 1 commit into from
Apr 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion src/lib/select/select.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ describe('MdSelect', () => {
BasicSelectOnPush,
BasicSelectOnPushPreselected,
SelectWithPlainTabindex,
SelectEarlyAccessSibling
SelectEarlyAccessSibling,
BasicSelectInitiallyHidden,
BasicSelectNoPlaceholder
],
providers: [
{provide: OverlayContainer, useFactory: () => {
Expand Down Expand Up @@ -159,6 +161,25 @@ describe('MdSelect', () => {
});
}));

it('should set the width of the overlay if the element was hidden initially', async(() => {
let initiallyHidden = TestBed.createComponent(BasicSelectInitiallyHidden);

initiallyHidden.detectChanges();
trigger = initiallyHidden.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
trigger.style.width = '200px';

initiallyHidden.componentInstance.isVisible = true;
initiallyHidden.detectChanges();

initiallyHidden.whenStable().then(() => {
trigger.click();
initiallyHidden.detectChanges();

const pane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
expect(pane.style.minWidth).toBe('200px');
});
}));

it('should not attempt to open a select that does not have any options', () => {
fixture.componentInstance.foods = [];
fixture.detectChanges();
Expand All @@ -169,6 +190,21 @@ describe('MdSelect', () => {
expect(fixture.componentInstance.select.panelOpen).toBe(false);
});

it('should set the width of the overlay if there is no placeholder', async(() => {
let noPlaceholder = TestBed.createComponent(BasicSelectNoPlaceholder);

noPlaceholder.detectChanges();
trigger = noPlaceholder.debugElement.query(By.css('.mat-select-trigger')).nativeElement;

noPlaceholder.whenStable().then(() => {
trigger.click();
noPlaceholder.detectChanges();

const pane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
expect(parseInt(pane.style.minWidth)).toBeGreaterThan(0);
});
}));

});

describe('selection logic', () => {
Expand Down Expand Up @@ -1957,6 +1993,27 @@ class SelectWithPlainTabindex { }
})
class SelectEarlyAccessSibling { }

@Component({
selector: 'basic-select-initially-hidden',
template: `
<md-select [style.display]="isVisible ? 'block' : 'none'">
<md-option value="value">There are no other options</md-option>
</md-select>
`
})
class BasicSelectInitiallyHidden {
isVisible = false;
}

@Component({
selector: 'basic-select-no-placeholder',
template: `
<md-select>
<md-option value="value">There are no other options</md-option>
</md-select>
`
})
class BasicSelectNoPlaceholder { }

class FakeViewportRuler {
getViewportRect() {
Expand Down
14 changes: 10 additions & 4 deletions src/lib/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export class MdSelect implements AfterContentInit, OnDestroy, OnInit, ControlVal
this._placeholder = value;

// Must wait to record the trigger width to ensure placeholder width is included.
Promise.resolve(null).then(() => this._triggerWidth = this._getWidth());
Promise.resolve(null).then(() => this._setTriggerWidth());
}

/** Whether the component is disabled. */
Expand Down Expand Up @@ -352,6 +352,11 @@ export class MdSelect implements AfterContentInit, OnDestroy, OnInit, ControlVal
if (this.disabled || !this.options.length) {
return;
}

if (!this._triggerWidth) {
this._setTriggerWidth();
}

this._calculateOverlayPosition();
this._placeholderState = this._floatPlaceholderState();
this._panelOpen = true;
Expand Down Expand Up @@ -443,11 +448,12 @@ export class MdSelect implements AfterContentInit, OnDestroy, OnInit, ControlVal
return this._dir ? this._dir.value === 'rtl' : false;
}

/** The width of the trigger element. This is necessary to match
/**
* Sets the width of the trigger element. This is necessary to match
* the overlay width to the trigger width.
*/
_getWidth(): number {
return this._getTriggerRect().width;
private _setTriggerWidth(): void {
this._triggerWidth = this._getTriggerRect().width;
}

/** Ensures the panel opens if activated by the keyboard. */
Expand Down