0
# Popover Component
1
2
The `VPopover` component provides advanced popover functionality with Vue component slots for complex interactive content. It supports extensive customization, event handling, and programmatic control.
3
4
## Capabilities
5
6
### Component Registration
7
8
Register the VPopover component for use in templates.
9
10
```javascript { .api }
11
// Global registration via plugin
12
Vue.use(VTooltip);
13
14
// Manual component registration
15
import { VPopover } from 'v-tooltip';
16
Vue.component('v-popover', VPopover);
17
18
// Local component registration
19
export default {
20
components: {
21
VPopover
22
}
23
};
24
```
25
26
### Basic Popover Usage
27
28
Simple popover with slot-based content.
29
30
```javascript { .api }
31
// Template usage
32
<v-popover>
33
<!-- Trigger element -->
34
<button>Click me</button>
35
36
<!-- Popover content -->
37
<template slot="popover">
38
<h3>Popover Title</h3>
39
<p>Complex content goes here</p>
40
</template>
41
</v-popover>
42
```
43
44
**Usage Examples:**
45
46
```html
47
<template>
48
<div>
49
<!-- Basic popover -->
50
<v-popover>
51
<button class="btn">Show Info</button>
52
<template slot="popover">
53
<div class="popover-content">
54
<h3>Information</h3>
55
<p>This is a popover with complex content.</p>
56
<button @click="handleAction">Action</button>
57
</div>
58
</template>
59
</v-popover>
60
61
<!-- Popover with form -->
62
<v-popover trigger="click">
63
<button>Edit Settings</button>
64
<template slot="popover">
65
<form @submit.prevent="saveSettings">
66
<input v-model="settings.name" placeholder="Name" />
67
<input v-model="settings.email" placeholder="Email" />
68
<button type="submit">Save</button>
69
</form>
70
</template>
71
</v-popover>
72
</div>
73
</template>
74
75
<script>
76
export default {
77
data() {
78
return {
79
settings: {
80
name: '',
81
email: ''
82
}
83
};
84
},
85
methods: {
86
handleAction() {
87
console.log('Action clicked');
88
},
89
saveSettings() {
90
console.log('Settings saved:', this.settings);
91
}
92
}
93
};
94
</script>
95
```
96
97
### Component Props
98
99
Comprehensive configuration through component props.
100
101
```javascript { .api }
102
interface VPopoverProps {
103
/** Boolean that shows or hide the popover */
104
open?: boolean;
105
106
/** Boolean that disables the popover */
107
disabled?: boolean;
108
109
/** Popover placement position */
110
placement?: 'auto' | 'auto-start' | 'auto-end' | 'top' | 'top-start' | 'top-end' |
111
'right' | 'right-start' | 'right-end' | 'bottom' | 'bottom-start' |
112
'bottom-end' | 'left' | 'left-start' | 'left-end';
113
114
/** Show/Hide delay in milliseconds or object with show/hide properties */
115
delay?: number | string | { show?: number; hide?: number };
116
117
/** Position offset in pixels */
118
offset?: number | string;
119
120
/** Events triggering the popover: 'hover', 'click', 'focus', 'manual', or combinations */
121
trigger?: string;
122
123
/** Container where the popover will be appended */
124
container?: string | HTMLElement | boolean;
125
126
/** DOM element for the popover boundaries */
127
boundariesElement?: string | HTMLElement;
128
129
/** Popper.js options object */
130
popperOptions?: any;
131
132
/** Classes applied to the popover element for theming */
133
popoverClass?: string | string[];
134
135
/** Base classes applied to the popover element */
136
popoverBaseClass?: string | string[];
137
138
/** Wrapper class containing arrow and inner content */
139
popoverWrapperClass?: string | string[];
140
141
/** Arrow element class */
142
popoverArrowClass?: string | string[];
143
144
/** Inner content element class */
145
popoverInnerClass?: string | string[];
146
147
/** Hide the popover if clicked outside */
148
autoHide?: boolean;
149
150
/** Automatically update popover position if its size changes */
151
handleResize?: boolean;
152
153
/** Close all open popovers with different open-group values */
154
openGroup?: string;
155
156
/** Class put on the popover when it's open */
157
openClass?: string | string[];
158
159
/** Custom aria ID for accessibility */
160
ariaId?: string;
161
}
162
```
163
164
**Usage Examples:**
165
166
```html
167
<template>
168
<div>
169
<!-- Configured popover -->
170
<v-popover
171
:open="isPopoverOpen"
172
placement="bottom-start"
173
:delay="{ show: 200, hide: 100 }"
174
trigger="click"
175
:offset="10"
176
popover-class="custom-popover"
177
:auto-hide="true"
178
open-group="main-menu"
179
>
180
<button>Configured Popover</button>
181
<template slot="popover">
182
<div>Popover with custom configuration</div>
183
</template>
184
</v-popover>
185
186
<!-- Disabled popover -->
187
<v-popover :disabled="isDisabled">
188
<button :class="{ disabled: isDisabled }">
189
{{ isDisabled ? 'Disabled' : 'Enabled' }} Popover
190
</button>
191
<template slot="popover">
192
<div>This popover can be disabled</div>
193
</template>
194
</v-popover>
195
</div>
196
</template>
197
198
<script>
199
export default {
200
data() {
201
return {
202
isPopoverOpen: false,
203
isDisabled: false
204
};
205
}
206
};
207
</script>
208
```
209
210
### Component Events
211
212
Comprehensive event system for popover lifecycle management.
213
214
```javascript { .api }
215
interface VPopoverEvents {
216
/** Emitted when open state changes, enables .sync modifier */
217
'update:open': (isOpen: boolean) => void;
218
219
/** Emitted when popover starts showing */
220
'show': () => void;
221
222
/** Emitted after the show delay */
223
'apply-show': () => void;
224
225
/** Emitted when popover starts hiding */
226
'hide': () => void;
227
228
/** Emitted after the hide delay */
229
'apply-hide': () => void;
230
231
/** Emitted when popover is disposed */
232
'dispose': () => void;
233
234
/** Emitted when popover is closed by clicking outside */
235
'auto-hide': () => void;
236
237
/** Emitted when popover is closed with close directive */
238
'close-directive': () => void;
239
240
/** Emitted when popover is closed because another group was shown */
241
'close-group': () => void;
242
243
/** Emitted when content size changes (requires handleResize: true) */
244
'resize': () => void;
245
}
246
```
247
248
**Usage Examples:**
249
250
```html
251
<template>
252
<div>
253
<!-- Event handling -->
254
<v-popover
255
:open.sync="isOpen"
256
@show="onShow"
257
@hide="onHide"
258
@apply-show="onApplyShow"
259
@apply-hide="onApplyHide"
260
@auto-hide="onAutoHide"
261
@close-directive="onCloseDirective"
262
@resize="onResize"
263
:handle-resize="true"
264
>
265
<button>Event Popover</button>
266
<template slot="popover">
267
<div>
268
<p>Popover with event handling</p>
269
<button v-close-popover>Close</button>
270
</div>
271
</template>
272
</v-popover>
273
274
<!-- Sync modifier example -->
275
<v-popover :open.sync="syncedOpen">
276
<button>Synced Popover ({{ syncedOpen ? 'Open' : 'Closed' }})</button>
277
<template slot="popover">
278
<div>Open state is synced with parent component</div>
279
</template>
280
</v-popover>
281
</div>
282
</template>
283
284
<script>
285
export default {
286
data() {
287
return {
288
isOpen: false,
289
syncedOpen: false
290
};
291
},
292
methods: {
293
onShow() {
294
console.log('Popover starting to show');
295
},
296
onHide() {
297
console.log('Popover starting to hide');
298
},
299
onApplyShow() {
300
console.log('Popover fully shown after delay');
301
},
302
onApplyHide() {
303
console.log('Popover fully hidden after delay');
304
},
305
onAutoHide() {
306
console.log('Popover auto-hidden by clicking outside');
307
},
308
onCloseDirective() {
309
console.log('Popover closed via close directive');
310
},
311
onResize() {
312
console.log('Popover content resized');
313
}
314
}
315
};
316
</script>
317
```
318
319
### Component Methods
320
321
Programmatic control methods for popover instances.
322
323
```javascript { .api }
324
interface VPopoverMethods {
325
/**
326
* Manually show the popover
327
* @param options - Show options
328
*/
329
show(options?: { event?: Event; skipDelay?: boolean; force?: boolean }): void;
330
331
/**
332
* Manually hide the popover
333
* @param options - Hide options
334
*/
335
hide(options?: { event?: Event; skipDelay?: boolean }): void;
336
337
/**
338
* Dispose the popover instance
339
*/
340
dispose(): void;
341
}
342
```
343
344
**Usage Examples:**
345
346
```html
347
<template>
348
<div>
349
<!-- Method control -->
350
<v-popover ref="controlledPopover" trigger="manual" :open="false">
351
<button @click="showPopover">Show Popover</button>
352
<template slot="popover">
353
<div>
354
<p>Programmatically controlled popover</p>
355
<button @click="hidePopover">Hide</button>
356
<button @click="disposePopover">Dispose</button>
357
</div>
358
</template>
359
</v-popover>
360
361
<!-- External controls -->
362
<div class="controls">
363
<button @click="$refs.controlledPopover.show()">External Show</button>
364
<button @click="$refs.controlledPopover.hide()">External Hide</button>
365
<button @click="$refs.controlledPopover.show({ force: true })">Force Show</button>
366
</div>
367
</div>
368
</template>
369
370
<script>
371
export default {
372
methods: {
373
showPopover() {
374
this.$refs.controlledPopover.show({ skipDelay: true });
375
},
376
hidePopover() {
377
this.$refs.controlledPopover.hide({ skipDelay: true });
378
},
379
disposePopover() {
380
this.$refs.controlledPopover.dispose();
381
}
382
}
383
};
384
</script>
385
```
386
387
### Slot System
388
389
Advanced slot-based content with reactive capabilities.
390
391
```javascript { .api }
392
interface VPopoverSlots {
393
/** Default slot for trigger element */
394
default: any;
395
396
/** Named slot for popover content */
397
popover: {
398
/** Whether the popover is currently open */
399
isOpen: boolean;
400
};
401
}
402
```
403
404
**Usage Examples:**
405
406
```html
407
<template>
408
<div>
409
<!-- Scoped slot with state -->
410
<v-popover>
411
<!-- Trigger slot -->
412
<button class="trigger">Click for Details</button>
413
414
<!-- Popover content with scoped data -->
415
<template slot="popover" slot-scope="{ isOpen }">
416
<div class="popover-content">
417
<h3>Dynamic Content</h3>
418
<p>Popover is {{ isOpen ? 'open' : 'closed' }}</p>
419
<ul>
420
<li v-for="item in dynamicItems" :key="item.id">
421
{{ item.name }}
422
</li>
423
</ul>
424
<div class="actions">
425
<button @click="refreshData">Refresh</button>
426
<button v-close-popover>Close</button>
427
</div>
428
</div>
429
</template>
430
</v-popover>
431
432
<!-- Component in popover -->
433
<v-popover>
434
<button>Show Component</button>
435
<template slot="popover">
436
<UserProfile :user-id="selectedUserId" @close="closePopover" />
437
</template>
438
</v-popover>
439
</div>
440
</template>
441
442
<script>
443
export default {
444
data() {
445
return {
446
dynamicItems: [
447
{ id: 1, name: 'Item 1' },
448
{ id: 2, name: 'Item 2' }
449
],
450
selectedUserId: 123
451
};
452
},
453
methods: {
454
refreshData() {
455
// Simulate data refresh
456
this.dynamicItems = this.dynamicItems.map(item => ({
457
...item,
458
name: `${item.name} (updated)`
459
}));
460
},
461
closePopover() {
462
// Custom close logic
463
this.$refs.popover.hide();
464
}
465
}
466
};
467
</script>
468
```
469
470
### Close Directive Integration
471
472
Use the `v-close-popover` directive within popover content.
473
474
```javascript { .api }
475
// Close directive usage
476
v-close-popover // Basic close
477
v-close-popover="true" // Explicit enable
478
v-close-popover="false" // Disable
479
v-close-popover="condition" // Conditional
480
v-close-popover.all // Close all popovers
481
```
482
483
**Usage Examples:**
484
485
```html
486
<template>
487
<v-popover>
488
<button>Open Menu</button>
489
<template slot="popover">
490
<div class="menu">
491
<div class="menu-header">
492
<h3>Menu</h3>
493
<button v-close-popover class="close-btn">×</button>
494
</div>
495
<div class="menu-content">
496
<a href="#" v-close-popover>Link 1</a>
497
<a href="#" v-close-popover>Link 2</a>
498
<button v-close-popover="shouldClose" @click="handleAction">
499
Conditional Close
500
</button>
501
<button v-close-popover.all>Close All Popovers</button>
502
</div>
503
</div>
504
</template>
505
</v-popover>
506
</template>
507
508
<script>
509
export default {
510
data() {
511
return {
512
shouldClose: true
513
};
514
},
515
methods: {
516
handleAction() {
517
// Perform action
518
console.log('Action performed');
519
// Close will happen automatically if shouldClose is true
520
}
521
}
522
};
523
</script>
524
```
525
526
### Styling and Theming
527
528
Advanced styling options and theme customization.
529
530
```javascript { .api }
531
interface PopoverStyling {
532
/** Custom theme classes */
533
popoverClass: string | string[];
534
535
/** Base structural classes */
536
popoverBaseClass: string | string[];
537
538
/** Wrapper element classes */
539
popoverWrapperClass: string | string[];
540
541
/** Inner content classes */
542
popoverInnerClass: string | string[];
543
544
/** Arrow element classes */
545
popoverArrowClass: string | string[];
546
547
/** Classes applied when open */
548
openClass: string | string[];
549
}
550
```
551
552
**Usage Examples:**
553
554
```html
555
<template>
556
<div>
557
<!-- Themed popover -->
558
<v-popover
559
popover-class="dark-theme large-popover"
560
popover-inner-class="custom-inner"
561
popover-arrow-class="custom-arrow"
562
open-class="popover-visible"
563
>
564
<button>Themed Popover</button>
565
<template slot="popover">
566
<div>Custom themed content</div>
567
</template>
568
</v-popover>
569
</div>
570
</template>
571
572
<style>
573
.dark-theme {
574
background: #333;
575
color: white;
576
border-radius: 8px;
577
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
578
}
579
580
.large-popover .custom-inner {
581
padding: 20px;
582
min-width: 300px;
583
}
584
585
.custom-arrow {
586
border-color: #333;
587
}
588
589
.popover-visible {
590
opacity: 1;
591
transform: scale(1);
592
transition: all 0.2s ease;
593
}
594
</style>
595
```