Search code examples
javascriptangulartypescriptangular-materialtooltip

Angular Material MatToolTip show up only when the element is truncated


(Edit: Please help guys I'm dying. This problem is not completely resolved, please refer to the comments)

I want to have the matTooltip show up only when the labels are actually overflown. like: when text is overflown, and when they are not, no tooltips.

Here is my broken code with trying to use matTooltipDisabled:

HTML (There are some code that I eliminated with "..." since I don't think they are necessary for the issue. Basically in the HTML, some labels will not be displayed unless you click on the dropdown, which is also a concern for tooltips):

<div *ngFor="...; let i = index">
            <div class="panel-container-label">
              <div *ngIf="i < 5" fxLayout="row" fxLayoutAlign="space-between center">
                <div>
                  <span matTooltip="..." [matTooltipPosition]="'after'" [matTooltipDisabled]="!ifOverflow(toolTip)" #toolTip>
                    <mat-checkbox class="search-facet-checkboxes" ...>
                      ...
                    </mat-checkbox>
                  </span>
                </div>
              </div>
              <div *ngIf="i >= 5 &&..." fxLayout="row" fxLayoutAlign="space-between center">
                <div class="container-name-oflw">
                  <span matTooltip="..." [matTooltipPosition]="'after'" [matTooltipDisabled]="!ifOverflow(toolTip)" #toolTip>
                    <mat-checkbox class="search-facet-checkboxes" ...>
                      ...
                    </mat-checkbox>
                  </span>
                </div>
              </div>
            </div>
          </div>

CSS:

.search-facet-checkboxes .mat-checkbox-layout .mat-checkbox-label {
  font-weight: normal !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}

div.panel-container-label {
  background-color: #ffffff;
  color: #487980;
  padding: 0 10px;
  clear: both;
  overflow: hidden;
  .container-name-oflw {
    width: 170px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

TS:

ifOverflow(e){
    console.log(e.scrollWidth + " and " + e.clientWidth)
    return e.scrollWidth > e.clientWidth;
  }

The console then prints 0 for both scrollWidth and ClientWidth, I have no idea why.

I also tried something with ViewChild with local reference #toolTip, but it didn't work out either, I got an error on the console saying that Cannot read property 'native-element' of undefined.

I didn't really want to use directive without Angular Material like this: https://medium.com/@anup.bangale/showing-tooltip-only-when-text-overflow-ellipsis-active-angular8-bd5e9d7667a9, because that will involve creating a new file, and I need to use Angular Material.

I pretty much went through all Stack Overflow posts related to this problem. Please send help, thank you!


Solution

  • It looks like you have the right idea. But I think you need to use a div instead of span, or change the display to be block or inline-block in the CSS. Because with inline elements the width is 0. I've implemented this same idea before, so I put together a simple example in case it helps:

    https://stackblitz.com/edit/angular-material-tooltip-overflow

    Info about inline element width: clientWidth and clientHeight report zero while getBoundingClientRect is correct