CirclonGroup / angular-tree-component

A simple yet powerful tree component for Angular (>=2)
https://angular2-tree.readme.io/docs
MIT License
1.1k stars 491 forks source link

How do I show truncated text on hover using angular-tree-component? #757

Open Pradhyo opened 5 years ago

Pradhyo commented 5 years ago

I need to limit the width of the angular-tree-component - this results in some nodes having text bigger than the width. I'm truncating this text but would like it to expand on hover in a single line.

Here's the behavior I want (hover over any node to see full text appear) - https://stackblitz.com/edit/angular-eqhwwm?file=src%2Fstyles.css But since I am using position: fixed, scrolling the page a little bit and hovering over it makes the node appear where it would have been without scrolling.

I have this working code to display truncated text across lines but the requirement is to have it show up on the same line

.node-content-wrapper:hover {
  text-overflow: clip;
  white-space: normal;
  word-break: break-word;
}
yarinsa commented 3 years ago

I applied a tooltip on the nodes template. I defined a resize observer on the elements that contains the text. This resize observer turn on /off the tooltip (you can use title attribute). Here is my logic that runs every time the observer is called. (I tweaked it a bit to work with title attribute)

(runs on ngAfterViewInit)

new (<any>window).MutationObserver((entries: MutationRecord[]) => {
        if (!entries.length) return;

        this.reconsiderAppearance();
      }).observe(el, {
        attributes: false,
        subtree: el.childNodes.length > 3 ? false : true, // detect changes in sub nodes, but limit it for performance reasons
        characterData: true,
      });

  private reconsiderAppearance() {
    const el: HTMLElement = this.ref?.nativeElement;
    if (!el) return;

    const isTruncated = el.offsetWidth.toFixed(0) < el.scrollWidth.toFixed(0);

    if (isTruncated && !this.show !== !isTruncated) {
      el.setAttribute('title',el.innerText)
      this.show = true;
    } else if (!isTruncated && this.disabled === false) {
      el.removeAttribute('title')
      this.show = false;
    }
  }