material-components-web
material-components-web copied to clipboard
[MDCList] List doesn't account for scrollbar width when it is applied
Bug report
If you create a list with text elements for use in a menu the list is nicely expanded horizontally to accommodate the widest text. If, however, the list 'runs out of room' then a vertical scrollbar is appropriately added. However, the scrollbar is 'in' the content area of the list and whatever lengthy text determined the width gets truncated with an ellipsis.
Steps to reproduce
- Create a menu
<div class="mdc-select__menu mdc-menu mdc-menu-surface mdc-menu-surface--fixed">
<ul class="mdc-list">
<li role="option">
<span class="mdc-list-item__ripple"></span>
<span class="mdc-list-item__text">Ascending</span>
</li>
<li role="option">
<span class="mdc-list-item__ripple"></span>
<span class="mdc-list-item__text">Descending</span>
</li>
<li role="option">
<span class="mdc-list-item__ripple"></span>
<span class="mdc-list-item__text">Ascending</span>
</li>
<li role="option">
<span class="mdc-list-item__ripple"></span>
<span class="mdc-list-item__text">DescendingWithAVeryWideWidth</span>
</li>
</ul>
</div>
- Instantiate the menu and observe a nicely formatted menu with plenty of room for the widest element.
- Add a bunch of menu items to force a menu that would exceed the window boundary
<li role="option">
<span class="mdc-list-item__ripple"></span>
<span class="mdc-list-item__text">DescendingWithAVeryWideWidth</span>
</li>
- Instantiate the menu
Actual behavior
Observe the truncated text:
Expected behavior
The menu should have the scroll width added in to avoid the truncation
Screenshots
Your Environment:
| Software | Version(s) |
| ---------------- | ---------- |
| MDC Web | 8.0.0
| Browser | Chrome 87
| Operating System | Windows 10
Additional context
Possible solution
Seems that it's not an MDC issue as such, but rather ellipsis + scrollbar HTML one. I managed to workaround this by "resetting" the menu width after opening. Not sure if there's better solution
// do this after open
menuElement.style.width = '0';
setTimeout(() => menuElement.style.width = '', 1);
The width "reset" worked only in Chrome. A better solution is to display the scrollbar before getting inner dimensions.
As a workaround menu-surface
adapter could be monkey patched with the following
getInnerDimensions: () => {
const firstChild = this.root.firstElementChild as HTMLElement;
this.root.style.overflowY = this.root.offsetHeight < firstChild.offsetHeight ? 'scroll' : '';
return {
width: this.root.offsetWidth,
height: this.root.offsetHeight
};
}