Skip to content

Popover

A neo-brutalist popover component for displaying floating content anchored to a trigger element. Built on reka-ui's PopoverRoot, supporting modal/non-modal modes and custom anchor positioning.

Demo

Preview

基础用法

对齐方式 (align)

偏移距离 (sideOffset=20)

Installation

pnpm dlx brutx-vue@latest add popover

Usage

vue
<script setup>
import { PopoverRoot as Popover, PopoverTrigger, PopoverAnchor } from 'reka-ui'
import { PopoverContent, Button } from 'brutx-ui-vue'
</script>

<template>
    <Popover>
        <PopoverTrigger as-child>
            <Button variant="outline">Open Popover</Button>
        </PopoverTrigger>
        <PopoverContent>
            <div class="grid gap-4">
                <div class="space-y-2">
                    <h4 class="font-black leading-none">Dimensions</h4>
                    <p class="text-sm text-brutal-muted-foreground">
                        Set the dimensions for the layer.
                    </p>
                </div>
            </div>
        </PopoverContent>
    </Popover>
</template>

Sub-components

ComponentDescription
PopoverRoot component (re-exported from reka-ui's PopoverRoot)
PopoverTriggerButton that opens the popover
PopoverContentPopover content panel
PopoverAnchorAnchor element for positioning

Props

Popover (Root Component)

Re-exported from reka-ui's PopoverRoot. Manages the open/close state of the popover.

PropTypeDefaultDescription
openbooleanControlled open state
defaultOpenbooleanfalseInitial open state in uncontrolled mode
modalbooleanfalseModal mode; when enabled, disables interaction with external elements

PopoverTrigger

Trigger component, renders as a button element by default.

PropTypeDefaultDescription
asstring | Component'button'Element type to render
asChildbooleanRender styles onto the child element

PopoverContent

Popover content panel with neo-brutalist styling.

PropTypeDefaultDescription
align'start' | 'center' | 'end''center'Alignment relative to the trigger
sideOffsetnumber8Distance from the trigger (in pixels)
classstringCustom CSS class

PopoverAnchor

Custom anchor element for precise popover positioning.

PropTypeDefaultDescription
referenceReferenceElementCustom positioning reference element

Events

Popover (Root Component)

EventPayloadDescription
update:openvalue: booleanEmitted when the open state changes

PopoverContent

EventPayloadDescription
openAutoFocusEventEmitted on auto-focus when opening, can be prevented
closeAutoFocusEventEmitted on auto-focus when closing, can be prevented
pointerDownOutsideEventEmitted when pressing a pointer outside
interactOutsideEventEmitted when interacting outside
escapeKeyDownEventEmitted when the Escape key is pressed
focusOutsideEventEmitted when focus moves outside

Slots

Popover (Root Component)

SlotScopeDescription
default{ open: boolean, close: () => void }Scoped slot, provides current state and close method

PopoverTrigger / PopoverContent / PopoverAnchor

SlotScopeDescription
defaultDefault slot content

Accessibility

  • Keyboard: Press Escape to close the popover
  • ARIA Attributes: The popover uses role="dialog" semantics and automatically links aria-labelledby to the trigger
  • Focus Management: The popover auto-focuses when opened
  • Interaction Behavior: Clicking outside closes the popover; in modal mode, interaction with external elements is disabled

Relationship with Popconfirm

Popconfirm is essentially a Popover + confirm/cancel button combination. It internally uses Popover/PopoverTrigger/PopoverContent directly, adding a TriangleAlert warning icon and confirm/cancel button logic.

When to use Popconfirm

  • Simple "confirm/cancel" binary operations
  • Out-of-the-box usage without assembling buttons and events manually
  • Consistent dangerous action confirmation experience

When to use Popover manually

  • Custom button text, styling, or layout
  • Complex content like forms or lists inside the popover
  • Fine-grained control over open/close timing
vue
<!-- Popconfirm: one-line confirm action -->
<Popconfirm title="Are you sure to delete?" @confirm="handleDelete">
    <Button variant="destructive">Delete</Button>
</Popconfirm>

<!-- Popover manual combination: fully custom -->
<Popover>
    <PopoverTrigger as-child>
        <Button variant="outline">Custom</Button>
    </PopoverTrigger>
    <PopoverContent>
        <!-- Any content: forms, lists, custom buttons, etc. -->
    </PopoverContent>
</Popover>

Brute force builds.