Components/Popover
Since 1.0.0BETA

Popover

Semantic popover built directly on BaseAnchor.

This page was migrated by AI, please review carefully

Migration is complete, but please validate against source code and manual review.

Popover

TxPopover builds trigger semantics directly on TxBaseAnchor, which owns positioning, collision handling, outside click / Escape closing, and motion.

Popover panels use TxCard; use panelVariant/panelBackground/panelShadow/panelRadius/panelPadding to control border, background, and shadow. keepAliveContent controls whether inner state is preserved after close.

Basic Usage

Popover

Demo will load when visible.
<template>
  <TxPopover v-model="open">
    <template #reference>
      <TxButton>Click</TxButton>
    </template>

    Popover content
  </TxPopover>
</template>

Visual Effects (split / fusion / mask)

Popover (visual effects)

Demo will load when visible.
<script setup lang="ts">
import { ref } from 'vue'

const open = ref(false)
const background = ref<'blur' | 'glass' | 'mask'>('blur')
const fusion = ref(false)
const motion = ref<'fade' | 'split'>('split')
const placement = ref<'bottom-start' | 'bottom' | 'top' | 'right'>('bottom-start')
const showArrow = ref(true)
</script>

<template>
  <div class="tx-demo tx-demo__col" style="gap: 12px; max-width: 860px;">
    <TxCard variant="plain" background="mask" :padding="14" :radius="14">
      <div class="tx-demo__row" style="gap: 10px; flex-wrap: wrap;">
        <label class="tx-demo__row" style="gap: 8px;">
          <span class="tx-demo__label">background</span>
          <TuffSelect v-model="background" style="min-width: 160px;">
            <TuffSelectItem value="blur" label="blur" />
            <TuffSelectItem value="glass" label="glass" />
            <TuffSelectItem value="mask" label="mask" />
          </TuffSelect>
        </label>

        <label class="tx-demo__row" style="gap: 8px;">
          <span class="tx-demo__label">motion</span>
          <TuffSelect v-model="motion" style="min-width: 160px;">
            <TuffSelectItem value="split" label="split" />
            <TuffSelectItem value="fade" label="fade" />
          </TuffSelect>
        </label>

        <label class="tx-demo__row" style="gap: 8px;">
          <span class="tx-demo__label">placement</span>
          <TuffSelect v-model="placement" style="min-width: 200px;">
            <TuffSelectItem value="bottom-start" label="bottom-start" />
            <TuffSelectItem value="bottom" label="bottom" />
            <TuffSelectItem value="top" label="top" />
            <TuffSelectItem value="right" label="right" />
          </TuffSelect>
        </label>

        <label class="tx-demo__row" style="gap: 8px;">
          <span class="tx-demo__label">arrow</span>
          <TxSwitch v-model="showArrow" />
        </label>

        <label class="tx-demo__row" style="gap: 8px;">
          <span class="tx-demo__label">fusion</span>
          <TxSwitch v-model="fusion" />
        </label>

        <label class="tx-demo__row" style="gap: 8px;">
          <span class="tx-demo__label">trigger</span>
          <TxButton size="small" @click="open = !open">Toggle</TxButton>
        </label>
      </div>
    </TxCard>

    <div style="display: flex; justify-content: center; padding: 48px 0;">
      <TxPopover
        v-model="open"
        :placement="placement"
        :show-arrow="showArrow"
        :motion="motion"
        :fusion="fusion"
        :panel-background="background"
        panel-shadow="soft"
        :panel-padding="12"
      >
        <template #reference>
          <TxButton>Click me</TxButton>
        </template>

        <div style="width: 260px; display: grid; gap: 8px;">
          <div style="font-weight: 600;">
            Split out popover
          </div>
          <div style="color: var(--tx-text-color-secondary); font-size: 12px;">
            Blur/Glass/Mask + Fusion + Arrow
          </div>
          <TxButton size="small">
            Action
          </TxButton>
        </div>
      </TxPopover>
    </div>
  </div>
</template>

API

TxPopover Props

PropTypeDefaultDescription
modelValueboolean-Open state (v-model)
disabledbooleanfalseDisable interaction
placementPopoverPlacement'bottom-start'Floating placement
offsetnumberautoGap (computed from arrowSize when arrow is enabled; otherwise 2)
widthnumber0Panel width (0 follows reference width)
minWidthnumber0Minimum panel width
maxWidthnumber360Maximum panel width
referenceFullWidthbooleanfalseStretch reference container to full width
showArrowbooleantrueShow arrow
arrowSizenumber12Arrow size
trigger'click' | 'hover''click'Trigger mode
openDelaynumber120Hover open delay (ms)
closeDelaynumber100Hover close delay (ms)
keepAliveContentbooleantrueKeep floating content mounted between open/close
toggleOnReferenceClickbooleantrigger === 'click'Toggle by clicking reference
panelVariant'solid' | 'dashed' | 'plain''solid'Card border variant
panelBackground'pure' | 'mask' | 'blur' | 'glass' | 'refraction''refraction'Card background style
panelShadow'none' | 'soft' | 'medium''soft'Card shadow style
panelRadiusnumber18Card radius
panelPaddingnumber10Card padding
closeOnClickOutsidebooleantrueClose on outside click (click trigger only)
closeOnEscbooleantrueClose on ESC

Events

EventParamsDescription
open-Emitted when uncontrolled or internal state opens.
close-Emitted when uncontrolled or internal state closes.
update:modelValuebooleanEmitted whenever Popover requests a controlled or uncontrolled open state change.