Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ngneat/helipopper

🚁 A Powerful Tooltip and Popover for Angular Applications
https://github.com/ngneat/helipopper

angular popover tippyjs tooltip

Last synced: 3 months ago
JSON representation

🚁 A Powerful Tooltip and Popover for Angular Applications

Awesome Lists containing this project

README

        




[![MIT](https://img.shields.io/packagist/l/doctrine/orm.svg?style=flat-square)]()
[![commitizen](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square)]()
[![PRs](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)]()
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)
[![ngneat](https://img.shields.io/badge/@-ngneat-383636?style=flat-square&labelColor=8f68d4)](https://github.com/ngneat/)
[![spectator](https://img.shields.io/badge/tested%20with-spectator-2196F3.svg?style=flat-square)]()
[![@ngneat/helipopper](https://github.com/ngneat/helipopper/workflows/@ngneat/helipopper/badge.svg)]()

> A Powerful Tooltip and Popover for Angular Applications

[Tippy.js](https://atomiks.github.io/tippyjs/v6/getting-started/) is the complete tooltip, popover, dropdown, and menu
solution for the web, powered by Popper.js.

It is an abstraction over Popper that provides the logic and optionally the styling involved in all types of elements
that pop out from the flow of the document and get overlaid on top of the UI, positioned next to a reference element.

This is a lightweight wrapper with additional features that lets you use it declaratively in Angular. Tippy has
virtually no restrictions over Popper and gives you limitless control while providing useful behavior and defaults.

If you're using v1 and don't want to migrate, you can find it [here](https://github.com/ngneat/helipopper/tree/v1).

## Features

✅ Position Tooltips, Menus, Dropdowns, and Popovers

✅ Predefined Variations

✅ TemplateRef/Component Support

✅ Lazy Registration

✅ Manual Trigger Support

✅ Text Overflow Support

✅ Context Menu Support

### Installation

```
npm install @ngneat/helipopper
```

Configure it as shown below:

```ts
import { provideTippyConfig, tooltipVariation, popperVariation } from '@ngneat/helipopper';

bootstrapApplication(AppComponent, {
providers: [
provideTippyConfig({
defaultVariation: 'tooltip',
variations: {
tooltip: tooltipVariation,
popper: popperVariation,
}
})
]
})
```

Add the styles you want to `styles.scss`:

```scss
@import '~tippy.js/dist/tippy.css';
@import '~tippy.js/themes/light.css';
@import '~tippy.js/animations/scale.css';
```

You have the freedom to [customize](https://atomiks.github.io/tippyjs/v6/themes/) it if you need to.

Import the standalone `TippyDirective` and use it in your templates:

```html

I have a tooltip

```

The library exposes default variations for `tooltip` and `popper`. You can use them, extend them, or pass your own
variations. A `variation` is a set of predefined `tippy` properties. For example, here's how the built-in `tooltip`
variation looks like:

```ts
export const tooltipVariation = {
theme: null,
arrow: false,
animation: 'scale',
trigger: 'mouseenter',
offset: [0, 5]
};
```

### Use `TemplateRef` as content

```html

Click Me

Popover title

And here's some amazing content. It's very engaging. Right?

```

### Use `Component` as content

```ts
import { TIPPY_REF, TippyInstance } from '@ngneat/helipopper';

@Component()
class MyComponent {
tippy = inject(TIPPY_REF);
}
```

```html

Click Me

```

### Text Overflow

You can pass the `onlyTextOverflow` input to show the tooltip only when the host overflows its container:

```html



{{ text }}



```

Note: this feature is using [`ResizeObserver`](https://caniuse.com/resizeobserver) api.

You might have cases where the host has a static width and the content is dynamic. In this case, use the `tpStaticWidthHost` input with combination with `tpOnlyTextOverflow`:

```html



{{ dynamicText }}



```

Note: when using `tpStaticWidthHost` you can't use `tpUseTextContent`, you need to explicitly pass the content to `tp` in order to trigger content change.

### Use Text Content

You can instruct tippy to use the element textContent as the tooltip content:

```html


{{ text }}


```

### Lazy

You can pass the `tpIsLazy` input when you want to defer the creation of tippy only when the element is in the view:

```html

{{ item.label }}

```

Note that it's using [`IntersectionObserver`](https://caniuse.com/intersectionobserver) api.

### Context Menu
First, define the `contextMenu` variation:
```ts
import {
popperVariation,
tooltipVariation,
provideTippyConfig,
withContextMenuVariation
} from '@ngneat/helipopper';

bootstrapApplication(AppComponent, {
providers: [
provideTippyConfig({
defaultVariation: 'tooltip',
variations: {
tooltip: tooltipVariation,
popper: popperVariation,
contextMenu: withContextMenuVariation(popperVariation),
}
})
]
})
```

Now you can use it in your template:

```html


  • Copy

  • Duplicate



  • {{ item.label }}


```

### Manual Trigger

```html


Click Open to see me

Open
Close
```

### Declarative show/hide

Use isVisible to trigger show and hide. Set trigger to manual.

```html


Click Open to see me

Open
Close
```

You can see more examples in
our [playground](https://github.com/ngneat/helipopper/blob/master/src/app/app.component.html), or
live [here](https://ngneat.github.io/helipopper/).

### Inputs

```ts
tp: string | TemplateRef | Type | undefined | null;
tpAppendTo: TippyProps['appendTo'];
tpDelay: TippyProps['delay'];
tpDuration: TippyProps['duration'];
tpHideOnClick: TippyProps['hideOnClick'];
tpInteractive: TippyProps['interactive'];
tpInteractiveBorder: TippyProps['interactiveBorder'];
tpMaxWidth: TippyProps['maxWidth'];
tpOffset: TippyProps['offset'];
tpPlacement: TippyProps['placement'];
tpPopperOptions: TippyProps['popperOptions'];
tpShowOnCreate: TippyProps['showOnCreate'];
tpTrigger: TippyProps['trigger'];
tpTriggerTarget: TippyProps['triggerTarget'];
tpZIndex: TippyProps['zIndex'];
tpAnimation: TippyProps['animation'];
tpUseTextContent: boolean;
tpIsLazy: boolean;
tpVariation: string;
tpIsEnabled: boolean;
tpIsVisible: boolean;
tpClassName: string;
tpOnlyTextOverflow: boolean;
tpData: any;
tpUseHostWidth: boolean;
tpHideOnEscape: boolean;
tpDetectChangesComponent: boolean;
tpPopperWidth: number | string;
tpHost: HTMLElement;
tpIsVisible: boolean;
```

### Outputs

```ts
tpVisible = new EventEmitter();
```

### Global Config
- You can pass any `tippy` option at global config level.
- `beforeRender` - Hook that'll be called before rendering the tooltip content ( applies only for string )

### Create `tippy` Programmatically

```typescript
import { TippyService, TippyInstance } from '@ngneat/helipopper';

class Component {
@ViewChild('inputName') inputName: ElementRef;
tippy: TippyInstance;
private tippyService = inject(TippyService);

show() {
if(!this.tippy) {
this.tippy = this.tippyService.create(this.inputName, 'this field is required');
}

this.tippy.show();
}

ngOnDestroy() {
this.tippy?.destroy();
}
}
```

## Contributors ✨

Thank goes to all these wonderful [people who contributed](https://github.com/ngneat/helipopper/graphs/contributors) ❤️