0
# Plugins
1
2
Built-in plugin system with four official plugins for advanced behaviors and effects, plus a framework for creating custom plugins.
3
4
## Capabilities
5
6
### Plugin System
7
8
Extensible plugin architecture allowing custom behaviors and lifecycle hook modifications.
9
10
```typescript { .api }
11
interface Plugin<TProps = Props> {
12
/** Optional plugin name for identification */
13
name?: string;
14
/** Default value when plugin property is not specified */
15
defaultValue?: any;
16
/** Plugin function that returns lifecycle hooks */
17
fn(instance: Instance<TProps>): Partial<LifecycleHooks<TProps>>;
18
}
19
20
// Usage in props
21
interface Props {
22
/** Array of plugins to apply to the instance */
23
plugins: Plugin[];
24
}
25
```
26
27
**Usage Examples:**
28
29
```typescript
30
import tippy, { animateFill, followCursor } from "tippy.js";
31
32
// Using built-in plugins
33
tippy('.animated', {
34
content: 'Animated tooltip',
35
plugins: [animateFill, followCursor],
36
animateFill: true,
37
followCursor: true
38
});
39
40
// Custom plugin example
41
const customPlugin = {
42
name: 'customBehavior',
43
defaultValue: false,
44
fn(instance) {
45
return {
46
onShow() {
47
console.log('Custom plugin: tooltip showing');
48
},
49
onHide() {
50
console.log('Custom plugin: tooltip hiding');
51
}
52
};
53
}
54
};
55
56
tippy('#custom', {
57
content: 'Custom plugin tooltip',
58
plugins: [customPlugin]
59
});
60
```
61
62
### Animate Fill Plugin
63
64
Creates a backdrop fill animation effect that fills the tooltip background before showing content.
65
66
```typescript { .api }
67
interface AnimateFill extends Plugin {
68
name: 'animateFill';
69
defaultValue: false;
70
}
71
72
const animateFill: AnimateFill;
73
74
// Props extension
75
interface Props {
76
/** Enable animate fill effect */
77
animateFill: boolean;
78
}
79
```
80
81
**Usage Examples:**
82
83
```typescript
84
import tippy, { animateFill } from "tippy.js";
85
86
// Basic animate fill
87
tippy('.fill-animation', {
88
content: 'Filling tooltip',
89
plugins: [animateFill],
90
animateFill: true,
91
animation: 'shift-away' // Required for proper effect
92
});
93
94
// Animate fill with custom styling
95
tippy('.custom-fill', {
96
content: 'Custom fill effect',
97
plugins: [animateFill],
98
animateFill: true,
99
theme: 'custom-fill', // Style the backdrop in CSS
100
duration: 500
101
});
102
103
// Note: animateFill requires the default render function
104
// It automatically sets arrow: false and animation: 'shift-away'
105
```
106
107
### Follow Cursor Plugin
108
109
Makes the tooltip follow the mouse cursor with various tracking modes.
110
111
```typescript { .api }
112
interface FollowCursor extends Plugin {
113
name: 'followCursor';
114
defaultValue: false;
115
}
116
117
const followCursor: FollowCursor;
118
119
// Props extension
120
interface Props {
121
/** Follow cursor behavior */
122
followCursor: boolean | 'horizontal' | 'vertical' | 'initial';
123
}
124
```
125
126
**Usage Examples:**
127
128
```typescript
129
import tippy, { followCursor } from "tippy.js";
130
131
// Full cursor following
132
tippy('.follow-cursor', {
133
content: 'Follows cursor',
134
plugins: [followCursor],
135
followCursor: true
136
});
137
138
// Horizontal only
139
tippy('.follow-horizontal', {
140
content: 'Follows horizontally',
141
plugins: [followCursor],
142
followCursor: 'horizontal'
143
});
144
145
// Vertical only
146
tippy('.follow-vertical', {
147
content: 'Follows vertically',
148
plugins: [followCursor],
149
followCursor: 'vertical'
150
});
151
152
// Initial position then fixed
153
tippy('.follow-initial', {
154
content: 'Initial position only',
155
plugins: [followCursor],
156
followCursor: 'initial' // Follows until shown, then stays
157
});
158
159
// Follow cursor with boundaries
160
tippy('.bounded-follow', {
161
content: 'Bounded following',
162
plugins: [followCursor],
163
followCursor: true,
164
boundary: 'viewport' // Respect viewport boundaries
165
});
166
```
167
168
### Inline Positioning Plugin
169
170
Improves positioning for inline elements like text selections and inline spans.
171
172
```typescript { .api }
173
interface InlinePositioning extends Plugin {
174
name: 'inlinePositioning';
175
defaultValue: false;
176
}
177
178
const inlinePositioning: InlinePositioning;
179
180
// Props extension
181
interface Props {
182
/** Enable inline positioning improvements */
183
inlinePositioning: boolean;
184
}
185
```
186
187
**Usage Examples:**
188
189
```typescript
190
import tippy, { inlinePositioning } from "tippy.js";
191
192
// Better positioning for inline elements
193
tippy('span.inline-tooltip', {
194
content: 'Inline element tooltip',
195
plugins: [inlinePositioning],
196
inlinePositioning: true,
197
placement: 'top'
198
});
199
200
// Text selection tooltips
201
tippy('.text-content', {
202
content: 'Text selection tooltip',
203
plugins: [inlinePositioning],
204
inlinePositioning: true,
205
trigger: 'manual', // Control manually
206
getReferenceClientRect() {
207
const selection = window.getSelection();
208
return selection.getRangeAt(0).getBoundingClientRect();
209
}
210
});
211
212
// Inline code elements
213
tippy('code', {
214
content: 'Code documentation',
215
plugins: [inlinePositioning],
216
inlinePositioning: true,
217
placement: 'bottom',
218
delay: 500
219
});
220
```
221
222
### Sticky Plugin
223
224
Keeps the tooltip positioned relative to its reference element during scrolling or element movement.
225
226
```typescript { .api }
227
interface Sticky extends Plugin {
228
name: 'sticky';
229
defaultValue: false;
230
}
231
232
const sticky: Sticky;
233
234
// Props extension
235
interface Props {
236
/** Sticky behavior */
237
sticky: boolean | 'reference' | 'popper';
238
}
239
```
240
241
**Usage Examples:**
242
243
```typescript
244
import tippy, { sticky } from "tippy.js";
245
246
// Stick to both reference and popper
247
tippy('.sticky-tooltip', {
248
content: 'Sticky tooltip',
249
plugins: [sticky],
250
sticky: true // Monitor both reference and popper positions
251
});
252
253
// Stick only to reference element
254
tippy('.sticky-reference', {
255
content: 'Sticks to reference',
256
plugins: [sticky],
257
sticky: 'reference' // Only monitor reference element
258
});
259
260
// Stick only to popper element
261
tippy('.sticky-popper', {
262
content: 'Sticks to popper',
263
plugins: [sticky],
264
sticky: 'popper' // Only monitor popper element
265
});
266
267
// Sticky with scrollable containers
268
tippy('.scrollable-content .tooltip-trigger', {
269
content: 'Scrollable sticky tooltip',
270
plugins: [sticky],
271
sticky: true,
272
boundary: 'scrollParent' // Respect scroll boundaries
273
});
274
```
275
276
### Combining Plugins
277
278
Using multiple plugins together for complex behaviors.
279
280
**Usage Examples:**
281
282
```typescript
283
import tippy, { followCursor, sticky, inlinePositioning } from "tippy.js";
284
285
// Follow cursor with sticky behavior
286
tippy('.advanced-tooltip', {
287
content: 'Advanced behavior',
288
plugins: [followCursor, sticky],
289
followCursor: 'initial', // Initial follow, then stick
290
sticky: true,
291
duration: 200
292
});
293
294
// Inline positioning with animate fill
295
tippy('span.highlighted', {
296
content: 'Highlighted text tooltip',
297
plugins: [inlinePositioning, animateFill],
298
inlinePositioning: true,
299
animateFill: true,
300
theme: 'highlight'
301
});
302
303
// All plugins combined
304
tippy('.kitchen-sink', {
305
content: 'All features tooltip',
306
plugins: [followCursor, sticky, inlinePositioning, animateFill],
307
followCursor: 'horizontal',
308
sticky: 'reference',
309
inlinePositioning: true,
310
animateFill: true,
311
interactive: true
312
});
313
```
314
315
### Custom Plugin Development
316
317
Framework for creating custom plugins with lifecycle hooks.
318
319
**Usage Examples:**
320
321
```typescript
322
import tippy from "tippy.js";
323
324
// Simple logging plugin
325
const loggingPlugin = {
326
name: 'logging',
327
defaultValue: false,
328
fn(instance) {
329
return {
330
onCreate() {
331
console.log(`Tooltip created for:`, instance.reference);
332
},
333
onShow() {
334
console.log(`Tooltip showing:`, instance.props.content);
335
},
336
onHide() {
337
console.log(`Tooltip hiding:`, instance.reference);
338
}
339
};
340
}
341
};
342
343
// Analytics plugin
344
const analyticsPlugin = {
345
name: 'analytics',
346
defaultValue: false,
347
fn(instance) {
348
return {
349
onShow() {
350
if (instance.props.analytics) {
351
analytics.track('tooltip_shown', {
352
content: instance.props.content,
353
element: instance.reference.tagName
354
});
355
}
356
}
357
};
358
}
359
};
360
361
// Auto-hide plugin
362
const autoHidePlugin = {
363
name: 'autoHide',
364
defaultValue: 0,
365
fn(instance) {
366
let timeoutId;
367
368
return {
369
onShow() {
370
if (instance.props.autoHide > 0) {
371
timeoutId = setTimeout(() => {
372
instance.hide();
373
}, instance.props.autoHide);
374
}
375
},
376
onHide() {
377
if (timeoutId) {
378
clearTimeout(timeoutId);
379
}
380
}
381
};
382
}
383
};
384
385
// Usage of custom plugins
386
tippy('.custom-behavior', {
387
content: 'Custom plugin tooltip',
388
plugins: [loggingPlugin, analyticsPlugin, autoHidePlugin],
389
analytics: true,
390
autoHide: 3000 // Auto-hide after 3 seconds
391
});
392
393
// Plugin with state management
394
const counterPlugin = {
395
name: 'counter',
396
defaultValue: false,
397
fn(instance) {
398
let showCount = 0;
399
400
return {
401
onShow() {
402
if (instance.props.counter) {
403
showCount++;
404
instance.setContent(`Shown ${showCount} times`);
405
}
406
}
407
};
408
}
409
};
410
```