material-components / material-components-web

Modular and customizable Material Design UI components for the web
https://material.io/develop/web
MIT License
17.14k stars 2.15k forks source link

[MDCList] List doesn't account for scrollbar width when it is applied #6709

Open MarkStega opened 3 years ago

MarkStega commented 3 years ago

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

  1. 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>
  2. Instantiate the menu and observe a nicely formatted menu with plenty of room for the widest element.
  3. 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>
  4. Instantiate the menu

Actual behavior

Observe the truncated text:

chrome_2020-12-21_13-40-28

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

MaximBalaganskiy commented 3 years ago

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);
MaximBalaganskiy commented 3 years ago

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
        };
      }