Skip to content

Commit 17ba514

Browse files
authored
Updated flyout layout logic to set hight of flyout. Updated people-picker to support scrolling (#853)
1 parent 0ae5594 commit 17ba514

File tree

3 files changed

+76
-45
lines changed

3 files changed

+76
-45
lines changed

packages/mgt-components/src/components/mgt-people-picker/mgt-people-picker.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ mgt-people-picker .root {
141141
text-align: left;
142142
list-style-type: none;
143143
background-color: $dropdown__background-color;
144-
144+
max-height: var(--mgt-flyout-set-height, unset);
145145
li {
146146
cursor: pointer;
147147
}

packages/mgt-components/src/components/mgt-people-picker/mgt-people-picker.ts

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
485485
return html`
486486
<mgt-flyout light-dismiss class="flyout">
487487
${anchor}
488-
<div slot="flyout" class="flyout-root">
488+
<div slot="flyout" class="flyout-root" @wheel=${(e: WheelEvent) => this.handleSectionScroll(e)}>
489489
${this.renderFlyoutContent()}
490490
</div>
491491
</mgt-flyout>
@@ -980,38 +980,31 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
980980
* @param event - tracks user key selection
981981
*/
982982
private handleArrowSelection(event: KeyboardEvent): void {
983-
if (this._foundPeople.length) {
983+
const peopleList = this.renderRoot.querySelector('.people-list');
984+
if (peopleList && peopleList.children.length) {
984985
// update arrow count
985986
if (event.keyCode === 38) {
986987
// up arrow
987-
if (this._arrowSelectionCount > 0) {
988-
this._arrowSelectionCount--;
989-
} else {
990-
this._arrowSelectionCount = 0;
991-
}
988+
this._arrowSelectionCount =
989+
(this._arrowSelectionCount - 1 + peopleList.children.length) % peopleList.children.length;
992990
}
993991
if (event.keyCode === 40) {
994992
// down arrow
995-
if (
996-
this._arrowSelectionCount + 1 !== this._foundPeople.length &&
997-
this._arrowSelectionCount + 1 < this.showMax
998-
) {
999-
this._arrowSelectionCount++;
1000-
} else {
1001-
this._arrowSelectionCount = 0;
1002-
}
993+
this._arrowSelectionCount = (this._arrowSelectionCount + 1) % peopleList.children.length;
1003994
}
1004995

1005-
const peopleList = this.renderRoot.querySelector('.people-list');
1006996
// reset background color
1007-
if (peopleList) {
1008-
// tslint:disable-next-line: prefer-for-of
1009-
for (let i = 0; i < peopleList.children.length; i++) {
1010-
peopleList.children[i].classList.remove('focused');
1011-
}
997+
// tslint:disable-next-line: prefer-for-of
998+
for (let i = 0; i < peopleList.children.length; i++) {
999+
peopleList.children[i].classList.remove('focused');
10121000
}
1001+
10131002
// set selected background
1014-
peopleList.children[this._arrowSelectionCount].classList.add('focused');
1003+
const focusedItem = peopleList.children[this._arrowSelectionCount];
1004+
if (focusedItem) {
1005+
focusedItem.classList.add('focused');
1006+
focusedItem.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });
1007+
}
10151008
}
10161009
}
10171010

@@ -1040,4 +1033,17 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
10401033
return filtered;
10411034
}
10421035
}
1036+
1037+
// stop propagating wheel event to flyout so mouse scrolling works
1038+
private handleSectionScroll(e: WheelEvent) {
1039+
const target = this.renderRoot.querySelector('.flyout-root') as HTMLElement;
1040+
if (target) {
1041+
if (
1042+
!(e.deltaY < 0 && target.scrollTop === 0) &&
1043+
!(e.deltaY > 0 && target.clientHeight + target.scrollTop >= target.scrollHeight - 1)
1044+
) {
1045+
e.stopPropagation();
1046+
}
1047+
}
1048+
}
10431049
}

packages/mgt-components/src/components/sub-components/mgt-flyout/mgt-flyout.ts

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ export class MgtFlyout extends MgtBaseComponent {
8181
// reset style for next update
8282
flyout.style.width = null;
8383
flyout.style.setProperty('--mgt-flyout-set-width', null);
84-
flyout.style.height = null;
84+
flyout.style.setProperty('--mgt-flyout-set-height', null);
85+
flyout.style.maxHeight = null;
8586
flyout.style.top = null;
8687
flyout.style.left = null;
8788
flyout.style.bottom = null;
@@ -299,29 +300,47 @@ export class MgtFlyout extends MgtBaseComponent {
299300
left = anchorRect.left;
300301
}
301302

302-
if (flyoutRect.height + 2 * this._edgePadding > windowRect.height) {
303-
if (flyoutRect.height >= windowRect.height) {
304-
height = windowRect.height;
305-
top = 0;
306-
} else {
307-
top = (windowRect.height - flyoutRect.height) / 2;
308-
}
309-
} else if (
310-
this.avoidHidingAnchor &&
311-
anchorRect.top + anchorRect.height + flyoutRect.height + this._edgePadding > windowRect.height &&
312-
anchorRect.top - flyoutRect.height - this._edgePadding > 0
313-
) {
314-
if (windowRect.height - anchorRect.top + flyoutRect.height < 0) {
315-
bottom = windowRect.height - flyoutRect.height - this._edgePadding;
303+
const anchorRectBottomToWindowBottom = windowRect.height - (anchorRect.top + anchorRect.height);
304+
const anchorRectTopToWindowTop = anchorRect.top;
305+
306+
if (this.avoidHidingAnchor) {
307+
if (anchorRectBottomToWindowBottom <= flyoutRect.height) {
308+
if (anchorRectTopToWindowTop < flyoutRect.height) {
309+
if (anchorRectTopToWindowTop > anchorRectBottomToWindowBottom) {
310+
// more room top than bottom - render above
311+
bottom = windowRect.height - anchorRect.top;
312+
height = anchorRectTopToWindowTop;
313+
} else {
314+
// more room bottom than top
315+
top = anchorRect.bottom;
316+
height = anchorRectBottomToWindowBottom;
317+
}
318+
} else {
319+
// render above anchor
320+
bottom = windowRect.height - anchorRect.top;
321+
height = anchorRectTopToWindowTop;
322+
}
316323
} else {
317-
bottom = Math.max(windowRect.height - anchorRect.top, this._edgePadding);
324+
top = anchorRect.bottom;
325+
height = anchorRectBottomToWindowBottom;
318326
}
319327
} else {
320-
if (anchorRect.top + anchorRect.height + flyoutRect.height + this._edgePadding > windowRect.height) {
321-
// it will render offscreen bellow, move it up a bit
322-
top = windowRect.height - flyoutRect.height - this._edgePadding;
328+
if (flyoutRect.height + 2 * this._edgePadding > windowRect.height) {
329+
// flyout wants to be higher than the window hight, and we don't need to avoid hiding the anchor
330+
// make the flyout height the height of the window
331+
if (flyoutRect.height >= windowRect.height) {
332+
height = windowRect.height;
333+
top = 0;
334+
} else {
335+
top = (windowRect.height - flyoutRect.height) / 2;
336+
}
323337
} else {
324-
top = Math.max(anchorRect.top + anchorRect.height, this._edgePadding);
338+
if (anchorRect.top + anchorRect.height + flyoutRect.height + this._edgePadding > windowRect.height) {
339+
// it will render offscreen bellow, move it up a bit
340+
top = windowRect.height - flyoutRect.height - this._edgePadding;
341+
} else {
342+
top = Math.max(anchorRect.top + anchorRect.height, this._edgePadding);
343+
}
325344
}
326345
}
327346

@@ -342,14 +361,20 @@ export class MgtFlyout extends MgtBaseComponent {
342361
flyout.style.top = `${top + windowRect.top}px`;
343362
}
344363

345-
flyout.style.height = height ? `${height}px` : null;
346-
347364
if (width) {
348365
// if we had to set the width, recalculate since the height could have changed
349366
flyout.style.width = `${width}px`;
350367
flyout.style.setProperty('--mgt-flyout-set-width', `${width}px`);
351368
window.requestAnimationFrame(() => this.updateFlyout());
352369
}
370+
371+
if (height) {
372+
flyout.style.maxHeight = `${height}px`;
373+
flyout.style.setProperty('--mgt-flyout-set-height', `${height}px`);
374+
} else {
375+
flyout.style.maxHeight = null;
376+
flyout.style.setProperty('--mgt-flyout-set-height', `unset`);
377+
}
353378
}
354379
}
355380

0 commit comments

Comments
 (0)