Skip to content

Latest commit

 

History

History
671 lines (520 loc) · 15.5 KB

README-v2.x.x.md

File metadata and controls

671 lines (520 loc) · 15.5 KB
Logo

Angular 8+ wrapper for Tippy.js

Build Status codecov npm GitHub

Demo

Example application

Code playground

Run demo locally

Installation

Install from npm:

npm i ngx-tippy-wrapper --save

Importing

Import NgxTippyModule:

import { NgxTippyModule } from 'ngx-tippy-wrapper';

Then in your base module:

@NgModule({
    imports: [
        ...,
        NgxTippyModule
    ],
    ...
})

Import tippy.css style file to your main style file:

@import 'tippy.js/dist/tippy.css';

or angular.json:

"architect": {
"build": {
  ...,
  "options": {
    ...,
    "styles": [..., "./node_modules/tippy.js/dist/tippy.css"]
  }

Usage

Basic usage

Apply ngxTippy directive for element and pass content through data-tippy-content attribute:

<button
  ngxTippy
  data-tippy-content="Tooltip content"
>
  Element with tooltip
</button>

Applying props

You can apply props with tippyProps binding

In template:

<button
  ngxTippy
  data-tippy-content="Tooltip content"
  [tippyProps]="{
    arrow: false,
    placement: 'bottom'
  }"
>
  Element with tooltip
</button>

Or pass props from component:

<span
  ngxTippy
  data-tippy-content="Tooltip content"
  [tippyProps]="tippyProps"
>
  Element with tooltip
</span>

...
import { NgxTippyProps } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements OnInit {
  tippyProps: NgxTippyProps = {
    trigger: 'click',
    allowHTML: true,
  };
  ...
}

Implemented props

Prop name Type Example
tippyProps NgxTippyProps [tippyProps]="{ arrow: false, placement: 'bottom' }"
tippyName string tippyName="awesomeName"
tippyClassName string tippyClassName="new-class"
or
tippyClassName="new-class another-class"

tippyProps - list of all props

tippyName - name for tippy instance, required for accessing and control specific instance

tippyClassName - add custom class to the tippy-box element, support multiple classes passed as words separated by space

Initializing on condition

In some cases tooltip should be initialized conditionally. For example in case optional @Input property passed or not. So, if tooltip should not initialize - you can explicitly pass null through ngxTippy directive or bind possible undefined property:

...
import { NgxTippyService } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements OnInit, AfterViewInit {
  @Input() inputContent?: string;
}
<button
  class="t-demo__btn"
  [ngxTippy]="someCondition ? 'Content' : null"
>
  Element with tooltip
</button>

or

<button
  class="t-demo__btn"
  [ngxTippy]="inputContent"
>
  Element with tooltip
</button>

Applying content

You can pass tooltip content through:

  1. data attribute:
<button
  ngxTippy
  data-tippy-content="Tooltip content"
>
  Element with tooltip
</button>
  1. content prop :
<button
  ngxTippy
  [tippyProps]="{
    allowHTML: true,
    content: '<p>Tooltip <strong>HTML</strong> content</p>'
  }"
>
  Element with tooltip
</button>
  1. passing string directly:
<button ngxTippy="Directly passed content">Element with tooltip</button>
  1. setContent()* method :
<button
  ngxTippy
  tippyName="content"
>
  Element with tooltip
</button>

...
import { NgxTippyService } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements OnInit, AfterViewInit {
  bindedContent: string = 'Binded tooltip content';

  constructor(private tippyService: NgxTippyService) {}

  ...

  ngAfterViewInit() {
    this.setContentForTooltip();
  }

  setContentForTooltip() {
    this.tippyService.setContent('content', this.bindedContent);
  }
}

*For this method tippyName should be defined

*This method can be used for dynamic applying content at any time, not only in lifecycle hooks

  1. tippyProps:
<button
  ngxTippy
  [tippyProps]="tippyProps"
>
  Element with tooltip
</button>

...
@Component({ ... })
export class DemoComponent implements OnInit {
  tippyProps: NgxTippyProps = { ... }

  ...

  ngOnInit() {
    this.setContentForTooltip();
  }

  setContentForTooltip() {
    this.tippyProps.content = 'Initial tooltip content'
  }
}
  1. template:
  • Pass template reference directly
<button
  [ngxTippy]="tippyTemplate"
  tippyName="content"
  [tippyProps]="tippyContent"
>
  Element with tooltip
</button>

<div #tippyTemplate>
  <h4>Caption</h4>
  <p>Some content</p>
  <button (click)="...">Action</button>
  ...
</div>
  • Pass element, element.innerHTML
<div>
  <button
    ngxTippy
    tippyName="content"
    [tippyProps]="tippyProps"
  >
    Element with tooltip
  </button>

  <!-- If passing element itself -->
  <div #tippyTemplate>
    <h4>Caption</h4>
    <p>Some content</p>
    <button (click)="...">Action</button>
    ...
  </div>

  <!-- If passing element `innerHTML` -->
  <div #tippyTemplate style="display: none;">
    <h4>Caption</h4>
    <p>Some content</p>
    ...
  </div>
</div>

...
import { NgxTippyProps } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements AfterViewInit {
  @ViewChild('tippyTemplate', { read: ElementRef, static: true }) tippyTemplate: ElementRef;
  tippyContent: NgxTippyProps = { ... };

  constructor(private ngxTippyService: NgxTippyService) {}

  ngAfterViewInit() {
    this.setContentForTooltip();
  }

  setContentForTooltip() {
    const template = this.tippyTemplate.nativeElement;

    // Pass element itself
    this.ngxTippyService.setContent('content', template);

    // or

    // Pass element `innerHTML`
    this.ngxTippyService.setContent('content', template.innerHTML);
  }
  ...
}

Methods

Import and provide NgxTippyService:

...
import { NgxTippyService } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements OnInit {
  constructor(private tippyService: NgxTippyService) {}
  ...
}

For accessing and control specific tippy instance tippyName should be defined

Through service you can use all methods described here and some additional

Implemented methods

Get instance(s)

Method name Method parameter/parameters Method short description
getInstance() name: string Get specific instance
getInstances() - Get all tippy instances

Instance methods

Method name Method parameter/parameters Method short description
show() name: string Programmatically show the tippy
hide() name: string Programmatically hide the tippy
hideWithInteractivity() name: string, mouseEvent: MouseEvent Will hide the tippy only if the cursor is outside of the tippy's interactive region
disable() name: string Temporarily prevent a tippy from showing or hiding
enable() name: string Re-enable a tippy
setProps() name: string, tippyProps: NgxTippyProps Set/update any tippy props
setContent() name: string, tippyContent: NgxTippyContent Set/update the content
setTriggerTarget() name: string, triggerTarget: Element | Element[] Set/update the trigger source
unmount() name: string Unmount the tippy from the DOM
clearDelayTimeouts() name: string Clears the instances delay timeouts
destroy() name: string Permanently destroy and clean up the tippy instance

Static methods

Method name Method parameter/parameters Method short description
setDefaultProps() tippyProps: NgxTippyProps Set the default props for each new tippy instance
showAll() - Show all tippies
hideAll() options?: NgxHideAllOptions Hide all tippies or hide all except a particular one, additional hide them with duration

Subscription for tippy instances change

...
import { Subscription } from 'rxjs';
import { NgxTippyService } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements OnInit, OnDestroy {
  private instancesChanges$: Subscription;

  constructor(private tippyService: NgxTippyService) {}

  ngOnInit() {
    this.subToInstancesChanges();
  }

  ngOnDestroy() {
    this.instancesChanges$ && this.instancesChanges$.unsubscribe();
  }

  subToInstancesChanges() {
    this.instancesChanges$ =
      this.ngxTippyService.instancesChanges.subscribe((changes: InstancesChanges) => { ... });
  }

  ...
}

It provides information in format:

{
  name: string;
  reason: InstanceChangeReason;
  instance: NgxTippyInstance;
}

type InstanceChangeReason =
  | 'setInstance'
  | 'show'
  | 'hide'
  | 'hideWithInteractivity'
  | 'disable'
  | 'enable'
  | 'setProps'
  | 'setContent'
  | 'setTriggerTarget'
  | 'unmount'
  | 'clearDelayTimeouts'
  | 'destroy';

Grouped tooltips

If you want to give different tooltip content to many different elements, while only needing to initialize once with shared props use ngx-tippy-group component:

<ngx-tippy-group [tippyProps]="tippyProps">

  <button data-grouped data-tippy-content="Tooltip content">Element with tooltip</button>

  <button data-grouped data-tippy-content="Tooltip content">Element with tooltip</button>

</ngx-tippy-group>

For each tooltip within component you should pass data-grouped attribute

Also you can pass new content and props for every tooltip element, see customization:

<ngx-tippy-group [tippyProps]="tippyPropsEx13">
  <button
    data-grouped
    data-tippy-content="Tooltip content"
  >
    Group
  </button>

  <button
    data-grouped
    data-tippy-content="Tooltip content"
  >
    Group
  </button>

  <button
    data-grouped
    data-tippy-content="Tooltip content"
  >
    Group
  </button>
</ngx-tippy-group>

...
import { NgxTippyProps } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements OnInit {
  bindedContent: string = 'Binded tooltip content';
  bindedHTMLContent: string = '<p>Binded <strong>HTML</strong> content</p>';

  tippyProps: NgxTippyProps = { ... };
  ...
}

Multiple tooltips on a single element

For multiple tooltips on a single element - use nest elements with applied ngxTippy directive:

<div
  ngxTippy
  data-tippy-content="First tooltip content"
  [tippyProps]="{ ... }"
>
  <div
    ngxTippy
    data-tippy-content="Second tooltip content"
    [tippyProps]="{ ... }"
  >
    <button
      ngxTippy
      data-tippy-content="Third tooltip content"
      [tippyProps]="{ ... }"
    >
      Element with tooltips
    </button>
  </div>
</div>

Singleton

For singleton - provide tooltips elements within ngx-tippy-singleton component:

<ngx-tippy-singleton [tippyProps]="{ ... }">
  <button
    data-singleton
    data-tippy-content="First tooltip content"
  >
    Singleton
  </button>

  <button
    data-singleton
    data-tippy-content="Second tooltip content"
  >
    Singleton
  </button>

  <button
    data-singleton
    data-tippy-content="Third tooltip content"
  >
    Singleton
  </button>
</ngx-tippy-singleton>

For each tooltip you should pass data-singleton attribute

To overrides general tippyProps by the individual tippy props:

<ngx-tippy-singleton [tippyProps]="tippyProps">
  <button
    data-singleton
    data-tippy-content="First tooltip content"
    data-tippy-placement="bottom"
  >
    Singleton
  </button>

  <button
    data-singleton
    data-tippy-content="Second tooltip content"
    data-tippy-arrow="false"
  >
    Singleton
  </button>

  <button
    data-singleton
    data-tippy-content="Third tooltip content"
  >
    Singleton
  </button>
</ngx-tippy-singleton>

...
import { NgxSingletonProps } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements OnInit {

  tippyProps: NgxSingletonProps = {
    ...,
    overrides: ['arrow', 'placement'],
  };
  ...
}

Smooth transitions

Use the moveTransition prop, which is the transition between moves:

...
import { NgxSingletonProps } from 'ngx-tippy-wrapper';

@Component({ ... })
export class DemoComponent implements OnInit {

  tippyProps: NgxSingletonProps = {
    ...,
    moveTransition: 'transform 0.4s linear',
  };
  ...
}

Documentation for v1.0.1