Skip to content

Commit

Permalink
fix(select): menu positioning logic incorrect when select appears nea…
Browse files Browse the repository at this point in the history
…r viewport edge #671 (#680)

* Update foundation.js

Correct logic when Select Menu overflows at Bottom of screen, simplify code, and remove redundant object. Resolves LukeBergen's comment.
  • Loading branch information
tranrate authored and bwobrien committed Jul 26, 2017
1 parent f08fbc3 commit 874f043
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 16 deletions.
23 changes: 9 additions & 14 deletions packages/mdc-select/foundation.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,13 @@ export default class MDCSelectFoundation extends MDCFoundation {
open_() {
const {OPEN} = MDCSelectFoundation.cssClasses;
const focusIndex = this.selectedIndex_ < 0 ? 0 : this.selectedIndex_;
const {left, top, transformOrigin} = this.computeMenuStylesForOpenAtIndex_(focusIndex);

this.adapter_.setMenuElStyle('left', left);
this.adapter_.setMenuElStyle('top', top);
this.adapter_.setMenuElStyle('transform-origin', transformOrigin);
this.setMenuStylesForOpenAtIndex_(focusIndex);
this.adapter_.addClass(OPEN);
this.adapter_.openMenu(focusIndex);
}

computeMenuStylesForOpenAtIndex_(index) {
setMenuStylesForOpenAtIndex_(index) {
const innerHeight = this.adapter_.getWindowInnerHeight();
const {left, top} = this.adapter_.computeBoundingRect();

Expand All @@ -206,20 +203,17 @@ export default class MDCSelectFoundation extends MDCFoundation {
this.adapter_.rmMenuElAttr('aria-hidden');

let adjustedTop = top - itemOffsetTop;
const adjustedHeight = menuHeight - itemOffsetTop;
const overflowsTop = adjustedTop < 0;
const overflowsBottom = adjustedTop + adjustedHeight > innerHeight;
const overflowsBottom = adjustedTop + menuHeight > innerHeight;
if (overflowsTop) {
adjustedTop = 0;
} else if (overflowsBottom) {
adjustedTop = Math.max(0, adjustedTop - adjustedHeight);
}

return {
left: `${left}px`,
top: `${adjustedTop}px`,
transformOrigin: `center ${itemOffsetTop}px`,
adjustedTop = Math.max(0, innerHeight - menuHeight);
};

this.adapter_.setMenuElStyle('left', `${left}px`);
this.adapter_.setMenuElStyle('top', `${adjustedTop}px`);
this.adapter_.setMenuElStyle('transform-origin', `center ${itemOffsetTop}px`);
}

close_() {
Expand Down Expand Up @@ -250,3 +244,4 @@ export default class MDCSelectFoundation extends MDCFoundation {
}
}
}

4 changes: 2 additions & 2 deletions test/unit/mdc-select/foundation-events.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,15 @@ test('when opened clamps the menu position to the bottom of the window if it wou
foundation.setSelectedIndex(1);
td.when(mockAdapter.computeBoundingRect()).thenReturn({
left: 100,
top: mockInnerHeight,
top: mockInnerHeight-40,
});
td.when(mockAdapter.getOffsetTopForOptionAtIndex(1)).thenReturn(20);
handlers.click(createEvent());

const mockLocation = mockAdapter.computeBoundingRect();
td.verify(mockAdapter.setMenuElStyle('left', `${mockLocation.left}px`));
td.verify(
mockAdapter.setMenuElStyle('top', `${mockLocation.top - mockMenuHeight}px`)
mockAdapter.setMenuElStyle('top', `${mockInnerHeight - mockMenuHeight}px`)
);
});

Expand Down

0 comments on commit 874f043

Please sign in to comment.