@ngneat/helipopper 9.2.0 → 10.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,8 +38,12 @@ If you're using v1 and don't want to migrate, you can find it [here](https://git
38
38
 
39
39
  ### Installation
40
40
 
41
- ```
42
- npm install @ngneat/helipopper
41
+ ```sh
42
+ $ npm i @ngneat/helipopper
43
+ # Or if you're using yarn
44
+ $ yarn add @ngneat/helipopper
45
+ # Or if you're using pnpm
46
+ $ pnpm i @ngneat/helipopper
43
47
  ```
44
48
 
45
49
  Configure it as shown below:
@@ -50,22 +54,33 @@ import { provideTippyConfig, tooltipVariation, popperVariation } from '@ngneat/h
50
54
  bootstrapApplication(AppComponent, {
51
55
  providers: [
52
56
  provideTippyConfig({
57
+ loader: () => import('tippy.js'),
53
58
  defaultVariation: 'tooltip',
54
59
  variations: {
55
60
  tooltip: tooltipVariation,
56
61
  popper: popperVariation,
57
- }
58
- })
59
- ]
60
- })
62
+ },
63
+ }),
64
+ ],
65
+ });
66
+ ```
67
+
68
+ Please note that the `loader` property is required, as it specifies how Tippy is loaded - either synchronously or asynchronously. When dynamic import is used, the library will load only when the first Tippy directive is rendered. If we want it to load synchronously, we use the following:
69
+
70
+ ```ts
71
+ import tippy from 'tippy.js';
72
+
73
+ provideTippyConfig({
74
+ loader: () => tippy,
75
+ });
61
76
  ```
62
77
 
63
78
  Add the styles you want to `styles.scss`:
64
79
 
65
80
  ```scss
66
- @import '~tippy.js/dist/tippy.css';
67
- @import '~tippy.js/themes/light.css';
68
- @import '~tippy.js/animations/scale.css';
81
+ @import 'tippy.js/dist/tippy.css';
82
+ @import 'tippy.js/themes/light.css';
83
+ @import 'tippy.js/animations/scale.css';
69
84
  ```
70
85
 
71
86
  You have the freedom to [customize](https://atomiks.github.io/tippyjs/v6/themes/) it if you need to.
@@ -73,9 +88,7 @@ You have the freedom to [customize](https://atomiks.github.io/tippyjs/v6/themes/
73
88
  Import the standalone `TippyDirective` and use it in your templates:
74
89
 
75
90
  ```html
76
- <button tp="Helpful Message">
77
- I have a tooltip
78
- </button>
91
+ <button tp="Helpful Message">I have a tooltip</button>
79
92
  ```
80
93
 
81
94
  The library exposes default variations for `tooltip` and `popper`. You can use them, extend them, or pass your own
@@ -88,16 +101,14 @@ export const tooltipVariation = {
88
101
  arrow: false,
89
102
  animation: 'scale',
90
103
  trigger: 'mouseenter',
91
- offset: [0, 5]
104
+ offset: [0, 5],
92
105
  };
93
106
  ```
94
107
 
95
108
  ### Use `TemplateRef` as content
96
109
 
97
110
  ```html
98
- <button [tp]="tpl" tpVariation="popper">
99
- Click Me
100
- </button>
111
+ <button [tp]="tpl" tpVariation="popper">Click Me</button>
101
112
 
102
113
  <ng-template #tpl let-hide>
103
114
  <h6>Popover title</h6>
@@ -117,9 +128,7 @@ class MyComponent {
117
128
  ```
118
129
 
119
130
  ```html
120
- <button [tp]="MyComponent">
121
- Click Me
122
- </button>
131
+ <button [tp]="MyComponent">Click Me</button>
123
132
  ```
124
133
 
125
134
  ### Text Overflow
@@ -128,9 +137,7 @@ You can pass the `onlyTextOverflow` input to show the tooltip only when the host
128
137
 
129
138
  ```html
130
139
  <div style="max-width: 100px;" class="overflow-hidden flex">
131
- <p class="ellipsis" [tp]="text" tpPlacement="right" [tpOnlyTextOverflow]="true">
132
- {{ text }}
133
- </p>
140
+ <p class="ellipsis" [tp]="text" tpPlacement="right" [tpOnlyTextOverflow]="true">{{ text }}</p>
134
141
  </div>
135
142
  ```
136
143
 
@@ -140,7 +147,14 @@ You might have cases where the host has a static width and the content is dynami
140
147
 
141
148
  ```html
142
149
  <div style="max-width: 100px;" class="overflow-hidden flex">
143
- <p style="width: 100px" class="ellipsis" [tp]="dynamicText" tpPlacement="right" [tpOnlyTextOverflow]="true" tpStaticWidthHost>
150
+ <p
151
+ style="width: 100px"
152
+ class="ellipsis"
153
+ [tp]="dynamicText"
154
+ tpPlacement="right"
155
+ [tpOnlyTextOverflow]="true"
156
+ tpStaticWidthHost
157
+ >
144
158
  {{ dynamicText }}
145
159
  </p>
146
160
  </div>
@@ -153,34 +167,25 @@ Note: when using `tpStaticWidthHost` you can't use `tpUseTextContent`, you need
153
167
  You can instruct tippy to use the element textContent as the tooltip content:
154
168
 
155
169
  ```html
156
- <p tp tpUseTextContent>
157
- {{ text }}
158
- </p>
170
+ <p tp tpUseTextContent>{{ text }}</p>
159
171
  ```
160
172
 
161
-
162
173
  ### Lazy
163
174
 
164
175
  You can pass the `tpIsLazy` input when you want to defer the creation of tippy only when the element is in the view:
165
176
 
166
177
  ```html
167
- <div *ngFor="let item of items"
168
- [tp]="item.label"
169
- [tpIsLazy]="true">{{ item.label }}
170
- </div>
178
+ <div *ngFor="let item of items" [tp]="item.label" [tpIsLazy]="true">{{ item.label }}</div>
171
179
  ```
172
180
 
173
181
  Note that it's using [`IntersectionObserver`](https://caniuse.com/intersectionobserver) api.
174
182
 
175
183
  ### Context Menu
184
+
176
185
  First, define the `contextMenu` variation:
186
+
177
187
  ```ts
178
- import {
179
- popperVariation,
180
- tooltipVariation,
181
- provideTippyConfig,
182
- withContextMenuVariation
183
- } from '@ngneat/helipopper';
188
+ import { popperVariation, tooltipVariation, provideTippyConfig, withContextMenuVariation } from '@ngneat/helipopper';
184
189
 
185
190
  bootstrapApplication(AppComponent, {
186
191
  providers: [
@@ -190,10 +195,10 @@ bootstrapApplication(AppComponent, {
190
195
  tooltip: tooltipVariation,
191
196
  popper: popperVariation,
192
197
  contextMenu: withContextMenuVariation(popperVariation),
193
- }
194
- })
195
- ]
196
- })
198
+ },
199
+ }),
200
+ ],
201
+ });
197
202
  ```
198
203
 
199
204
  Now you can use it in your template:
@@ -207,21 +212,14 @@ Now you can use it in your template:
207
212
  </ng-template>
208
213
 
209
214
  <ul>
210
- <li *ngFor="let item of list"
211
- [tp]="contextMenu"
212
- [tpData]="item"
213
- tpVariation="contextMenu">
214
- {{ item.label }}
215
- </li>
215
+ <li *ngFor="let item of list" [tp]="contextMenu" [tpData]="item" tpVariation="contextMenu">{{ item.label }}</li>
216
216
  </ul>
217
217
  ```
218
218
 
219
219
  ### Manual Trigger
220
220
 
221
221
  ```html
222
- <div tp="Helpful Message" tpTrigger="manual" #tooltip="tippy">
223
- Click Open to see me
224
- </div>
222
+ <div tp="Helpful Message" tpTrigger="manual" #tooltip="tippy">Click Open to see me</div>
225
223
 
226
224
  <button (click)="tooltip.show()">Open</button>
227
225
  <button (click)="tooltip.hide()">Close</button>
@@ -232,9 +230,7 @@ Now you can use it in your template:
232
230
  Use isVisible to trigger show and hide. Set trigger to manual.
233
231
 
234
232
  ```html
235
- <div tp="Helpful Message" tpTrigger="manual" [tpIsVisible]="visibility">
236
- Click Open to see me
237
- </div>
233
+ <div tp="Helpful Message" tpTrigger="manual" [tpIsVisible]="visibility">Click Open to see me</div>
238
234
 
239
235
  <button (click)="visibility = true">Open</button>
240
236
  <button (click)="visibility = false">Close</button>
@@ -286,7 +282,8 @@ tpVisible = new EventEmitter<boolean>();
286
282
  ```
287
283
 
288
284
  ### Global Config
289
- - You can pass any `tippy` option at global config level.
285
+
286
+ - You can pass any `tippy` option at global config level.
290
287
  - `beforeRender` - Hook that'll be called before rendering the tooltip content ( applies only for string )
291
288
 
292
289
  ### Create `tippy` Programmatically
@@ -300,7 +297,7 @@ class Component {
300
297
  private tippyService = inject(TippyService);
301
298
 
302
299
  show() {
303
- if(!this.tippy) {
300
+ if (!this.tippy) {
304
301
  this.tippy = this.tippyService.create(this.inputName, 'this field is required');
305
302
  }
306
303
 
@@ -0,0 +1,10 @@
1
+ import { booleanAttribute as originalBooleanAttribute } from '@angular/core';
2
+ /**
3
+ * Transforms a value (typically a string) to a boolean.
4
+ * Intended to be used as a transform function of an input.
5
+ *
6
+ * @see https://material.angular.io/cdk/coercion/overview
7
+ */
8
+ const coerceBooleanAttribute = originalBooleanAttribute;
9
+ export { coerceBooleanAttribute };
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29lcmNpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ25lYXQvaGVsaXBvcHBlci9zcmMvbGliL2NvZXJjaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsSUFBSSx3QkFBd0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUk3RTs7Ozs7R0FLRztBQUNILE1BQU0sc0JBQXNCLEdBQXFDLHdCQUF3QixDQUFDO0FBRTFGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYm9vbGVhbkF0dHJpYnV0ZSBhcyBvcmlnaW5hbEJvb2xlYW5BdHRyaWJ1dGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxudHlwZSBCb29sZWFuSW5wdXQgPSBib29sZWFuIHwgYCR7Ym9vbGVhbn1gIHwgJycgfCBudWxsIHwgdW5kZWZpbmVkO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYSB2YWx1ZSAodHlwaWNhbGx5IGEgc3RyaW5nKSB0byBhIGJvb2xlYW4uXG4gKiBJbnRlbmRlZCB0byBiZSB1c2VkIGFzIGEgdHJhbnNmb3JtIGZ1bmN0aW9uIG9mIGFuIGlucHV0LlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9tYXRlcmlhbC5hbmd1bGFyLmlvL2Nkay9jb2VyY2lvbi9vdmVydmlld1xuICovXG5jb25zdCBjb2VyY2VCb29sZWFuQXR0cmlidXRlOiAodmFsdWU6IEJvb2xlYW5JbnB1dCkgPT4gYm9vbGVhbiA9IG9yaWdpbmFsQm9vbGVhbkF0dHJpYnV0ZTtcblxuZXhwb3J0IHsgY29lcmNlQm9vbGVhbkF0dHJpYnV0ZSB9O1xuIl19
@@ -0,0 +1,9 @@
1
+ // Let's retrieve the native `IntersectionObserver` implementation hidden by
2
+ // `__zone_symbol__IntersectionObserver`. This would be the unpatched version of
3
+ // the observer present in zone.js environments.
4
+ // Otherwise, if the user is using zoneless change detection (and zone.js is not included),
5
+ // we fall back to the native implementation. Accessing the native implementation
6
+ // allows us to remove `runOutsideAngular` calls and reduce indentation,
7
+ // making the code a bit more readable.
8
+ export const IntersectionObserver = globalThis['__zone_symbol__IntersectionObserver'] || globalThis.IntersectionObserver;
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJzZWN0aW9uLW9ic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmduZWF0L2hlbGlwb3BwZXIvc3JjL2xpYi9pbnRlcnNlY3Rpb24tb2JzZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNEVBQTRFO0FBQzVFLGdGQUFnRjtBQUNoRixnREFBZ0Q7QUFDaEQsMkZBQTJGO0FBQzNGLGlGQUFpRjtBQUNqRix3RUFBd0U7QUFDeEUsdUNBQXVDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUMvQixVQUFVLENBQUMscUNBQXFDLENBQUMsSUFBSSxVQUFVLENBQUMsb0JBQW9CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBMZXQncyByZXRyaWV2ZSB0aGUgbmF0aXZlIGBJbnRlcnNlY3Rpb25PYnNlcnZlcmAgaW1wbGVtZW50YXRpb24gaGlkZGVuIGJ5XG4vLyBgX196b25lX3N5bWJvbF9fSW50ZXJzZWN0aW9uT2JzZXJ2ZXJgLiBUaGlzIHdvdWxkIGJlIHRoZSB1bnBhdGNoZWQgdmVyc2lvbiBvZlxuLy8gdGhlIG9ic2VydmVyIHByZXNlbnQgaW4gem9uZS5qcyBlbnZpcm9ubWVudHMuXG4vLyBPdGhlcndpc2UsIGlmIHRoZSB1c2VyIGlzIHVzaW5nIHpvbmVsZXNzIGNoYW5nZSBkZXRlY3Rpb24gKGFuZCB6b25lLmpzIGlzIG5vdCBpbmNsdWRlZCksXG4vLyB3ZSBmYWxsIGJhY2sgdG8gdGhlIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbi4gQWNjZXNzaW5nIHRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb25cbi8vIGFsbG93cyB1cyB0byByZW1vdmUgYHJ1bk91dHNpZGVBbmd1bGFyYCBjYWxscyBhbmQgcmVkdWNlIGluZGVudGF0aW9uLFxuLy8gbWFraW5nIHRoZSBjb2RlIGEgYml0IG1vcmUgcmVhZGFibGUuXG5leHBvcnQgY29uc3QgSW50ZXJzZWN0aW9uT2JzZXJ2ZXI6IHR5cGVvZiBnbG9iYWxUaGlzLkludGVyc2VjdGlvbk9ic2VydmVyID1cbiAgZ2xvYmFsVGhpc1snX196b25lX3N5bWJvbF9fSW50ZXJzZWN0aW9uT2JzZXJ2ZXInXSB8fCBnbG9iYWxUaGlzLkludGVyc2VjdGlvbk9ic2VydmVyO1xuIl19
@@ -1,6 +1,6 @@
1
1
  import { inject, makeEnvironmentProviders } from '@angular/core';
2
2
  import { TIPPY_CONFIG, TIPPY_REF } from './tippy.types';
3
- export function provideTippyConfig(config = {}) {
3
+ export function provideTippyConfig(config) {
4
4
  return makeEnvironmentProviders([{ provide: TIPPY_CONFIG, useValue: config }]);
5
5
  }
6
6
  export function injectTippyRef() {
@@ -10,4 +10,4 @@ export function injectTippyRef() {
10
10
  }
11
11
  throw new Error('tp is not provided in the current context or on one of its ancestors');
12
12
  }
13
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmduZWF0L2hlbGlwb3BwZXIvc3JjL2xpYi9wcm92aWRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBOEIsTUFBTSxlQUFlLENBQUM7QUFFcEYsTUFBTSxVQUFVLGtCQUFrQixDQUFDLFNBQStCLEVBQUU7SUFDbEUsT0FBTyx3QkFBd0IsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pGLENBQUM7QUFFRCxNQUFNLFVBQVUsY0FBYztJQUM1QixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFdkQsSUFBSSxRQUFRLEVBQUU7UUFDWixPQUFPLFFBQVEsQ0FBQztLQUNqQjtJQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztBQUMxRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRJUFBZX0NPTkZJRywgVElQUFlfUkVGLCBUaXBweUNvbmZpZywgVGlwcHlJbnN0YW5jZSB9IGZyb20gJy4vdGlwcHkudHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZVRpcHB5Q29uZmlnKGNvbmZpZzogUGFydGlhbDxUaXBweUNvbmZpZz4gPSB7fSkge1xuICByZXR1cm4gbWFrZUVudmlyb25tZW50UHJvdmlkZXJzKFt7IHByb3ZpZGU6IFRJUFBZX0NPTkZJRywgdXNlVmFsdWU6IGNvbmZpZyB9XSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RUaXBweVJlZigpOiBUaXBweUluc3RhbmNlIHtcbiAgY29uc3QgaW5zdGFuY2UgPSBpbmplY3QoVElQUFlfUkVGLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gIGlmIChpbnN0YW5jZSkge1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcigndHAgaXMgbm90IHByb3ZpZGVkIGluIHRoZSBjdXJyZW50IGNvbnRleHQgb3Igb24gb25lIG9mIGl0cyBhbmNlc3RvcnMnKTtcbn1cbiJdfQ==
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmduZWF0L2hlbGlwb3BwZXIvc3JjL2xpYi9wcm92aWRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBOEIsTUFBTSxlQUFlLENBQUM7QUFFcEYsTUFBTSxVQUFVLGtCQUFrQixDQUFDLE1BQW1CO0lBQ3BELE9BQU8sd0JBQXdCLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNqRixDQUFDO0FBRUQsTUFBTSxVQUFVLGNBQWM7SUFDNUIsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFNBQVMsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBRXZELElBQUksUUFBUSxFQUFFLENBQUM7UUFDYixPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO0FBQzFGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVElQUFlfQ09ORklHLCBUSVBQWV9SRUYsIFRpcHB5Q29uZmlnLCBUaXBweUluc3RhbmNlIH0gZnJvbSAnLi90aXBweS50eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlVGlwcHlDb25maWcoY29uZmlnOiBUaXBweUNvbmZpZykge1xuICByZXR1cm4gbWFrZUVudmlyb25tZW50UHJvdmlkZXJzKFt7IHByb3ZpZGU6IFRJUFBZX0NPTkZJRywgdXNlVmFsdWU6IGNvbmZpZyB9XSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RUaXBweVJlZigpOiBUaXBweUluc3RhbmNlIHtcbiAgY29uc3QgaW5zdGFuY2UgPSBpbmplY3QoVElQUFlfUkVGLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gIGlmIChpbnN0YW5jZSkge1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcigndHAgaXMgbm90IHByb3ZpZGVkIGluIHRoZSBjdXJyZW50IGNvbnRleHQgb3Igb24gb25lIG9mIGl0cyBhbmNlc3RvcnMnKTtcbn1cbiJdfQ==