Popinfo
A card-style bubble overlay used to display rich information or interactive content. Compared to simple tooltips, Popinfo supports titles, icons, complex custom content (such as forms or lists), and multiple visual styles.
Basic Usage
Wrap the trigger element with the <TuiPopinfo> component. Set the title to display a standard header, and use content for text descriptions.
<template>
<div class="demo-box">
<TuiPopinfo
title="Title Information"
content="This is a detailed description that can contain a large amount of text."
>
<TuiButton>Component Trigger</TuiButton>
</TuiPopinfo>
<TuiPopinfo
title="Favorites"
titleIcon="tui-icon tis-star"
content="Successfully added to your favorites."
>
<TuiButton>Title with Icon</TuiButton>
</TuiPopinfo>
</div>
</template>Directive Usage
Use the v-tui-popover directive to quickly bind a bubble to any element.
Note: When using the directive, be sure to specify
appearance: 'popinfo'to enable the card style.
<template>
<TuiButton
v-tui-popover="{
appearance: 'popinfo',
title: 'Directive Call',
titleIcon: 'tui-icon ti-info-circle',
content: 'A card bubble generated via directive.',
placement: 'right'
}"
>
Directive Trigger
</TuiButton>
</template>Embedding Components
The core capability of Popinfo is hosting complex content. You can embed any Vue component via Slots or the Component Prop.
Method 1: Using Slots (Component Mode)
The most intuitive way, suitable for writing directly within templates.
<script setup>
import ColorSelect from './ColorSelect.vue'
</script>
<template>
<TuiPopinfo
title="Color Configuration"
trigger="click"
:enterable="true"
>
<TuiButton>Select Color</TuiButton>
<template #content>
<div style="padding: 10px;">
<p style="margin-bottom: 10px;">Please select a label color:</p>
<ColorSelect />
</div>
</template>
</TuiPopinfo>
</template>Method 2: Using the Component Prop (Directive/Function Mode)
When using directives or functional calls, you can pass the component object to the component property.
<script setup>
import { markRaw } from 'vue'
import ColorSelect from './ColorSelect.vue'
const popConfig = {
appearance: 'popinfo',
title: 'Dynamic Component',
// Use markRaw to avoid unnecessary reactive performance overhead
component: markRaw(ColorSelect),
trigger: 'click',
enterable: true
}
</script>
<template>
<TuiButton v-tui-popover="popConfig">
Pass Component Object
</TuiButton>
</template>Visual Styles
Popinfo is deeply integrated with the design system's tone functionality. Use type to define semantic colors, tone to control intensity, and you can even enable a frosted glass effect.
<template>
<div class="style-demo">
<TuiPopinfo
title="Operation Successful"
content="Data has been saved to the server."
type="success"
tone="strong"
>
<TuiButton type="success">Success Strong</TuiButton>
</TuiPopinfo>
<TuiPopinfo
title="Risk Warning"
content="This operation is irreversible, please proceed with caution."
type="warning"
tone="strongInvert"
>
<TuiButton type="warning">Warning Invert</TuiButton>
</TuiPopinfo>
<TuiPopinfo
title="Glass Effect"
content="A translucent effect with background blur."
:transparent="true"
:backgroundBlur="true"
tone="weak"
>
<TuiButton>Frosted Style</TuiButton>
</TuiPopinfo>
</div>
</template>Functional Call
In scenarios where DOM binding is not possible (such as Canvas drawing or asynchronous callbacks), you can use the globally injected $tPopover method to manually invoke the bubble.
<script setup>
import { inject } from 'vue'
const $tPopover = inject('$tPopover')
const openManualPopover = (event) => {
$tPopover({
event: event, // Must pass the event object or target DOM for position calculation
appearance: 'popinfo',
title: 'Functional Call',
titleIcon: 'tui-icon ti-code',
content: 'This is a Popinfo created dynamically via JS.',
type: 'primary',
trigger: 'click',
showTrigger: true // Displays the click ripple animation
})
}
</script>
<template>
<div class="manual-trigger" @click="openManualPopover">
Click this area to trigger functional Popinfo
</div>
</template>API Reference
Props
| Property | Description | Type | Optional Values (Full List) | Default |
|---|---|---|---|---|
| title | Title text | String | — | — |
| titleIcon V0.0.3+ | Icon class for the left side of the title | String | — | — |
| content | Content text (Optional if using slots or components) | String | — | — |
| component | Custom component object to render | Object | — | null |
| placement | Placement position | String | 'top', 'top-start', 'top-end', 'right', 'right-start', 'right-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end' | 'top' |
| trigger | Trigger method | String | 'hover', 'click' | 'hover' |
| type | Semantic type | String | 'default', 'invert', 'primary', 'success', 'warning', 'danger', 'info', 'emphasis' | null |
| tone | Tone intensity | String | 'base', 'weak', 'strong', 'strongInvert', 'extremeInvert' | 'base' |
| shadowColor | Shadow intensity | String | 'weakest', 'weaker', 'weak', 'base', 'strong', 'stronger', 'strongest', 'match' | 'weak' |
| enterable | Whether the mouse can enter the bubble (Required for interactive components) | Boolean | — | false |
| autoClose | Whether to close automatically when clicking outside | Boolean | — | true |
| transparent | Whether to enable background transparency | Boolean | — | true |
| backgroundBlur | Whether to enable background blur (Requires transparent) | Boolean | — | true |
| disabled | Whether it is disabled | Boolean | — | false |
| offset | Offset distance for the popover (px) | Number | — | 8 |
| showArrow | Whether to show the arrow | Boolean | — | true |
| delay | Display delay (ms) | Number | — | 500 |
| duration | Auto-close duration (ms), 0 for persistent | Number | 0 or specific ms | 3000 |
| hasShadow | Whether to display shadow | Boolean | — | true |
Slots (Component Mode)
| Slot Name | Description |
|---|---|
| default | Trigger element |
| content | Main bubble content area, used for complex HTML or components |
Global Methods
| Method | Description | Parameters |
|---|---|---|
| $tPopover | Creates a Popover instance | (options: Object) => void |
| $tPopoverCloseAll | Closes all instances created via JS/events | () => void |
| $tPopoverDirectiveCloseAll | Closes all instances created via directives | () => void |
Global ESC Monitoring
To provide a unified and elegant keyboard interaction experience, all floating components are deeply integrated with TechUI's global service (TuiService).
The component internally monitors the global EscCounter parameter in real-time. When a user presses the Esc key, the global service updates this counter, and the component triggers its hide logic upon detecting the change. This mechanism ensures that no matter how many independent overlays are on the page, they all respond to a unified close command without requiring developers to manually bind keyboard events.
Positioning Dependencies
The positioning of TechUI's bubble and overlay components relies entirely on the industry-standard Floating UI library.
This means you don't need to worry about complex geometric calculations; the component automatically handles the following scenarios:
- Collision Detection (Flip): Automatically flips to the opposite side when there is insufficient space in the preset position (e.g., at screen edges).
- Viewport Correction (Shift): Ensures the bubble remains within the visible viewport and is not truncated.
- Precise Offsetting: Achieves pixel-level precise positioning through the
offsetproperty.
You only need to specify the desired orientation via the placement prop, and the underlying engine handles all complex calculations.