UIPackage
Menu

Framework

Change language

Boilerplate repo

Popover

popoverui

Click-triggered floating panel anchored to a trigger element. Supports optional localStorage persistence and configurable dismissal (click-outside, escape, manual). Built on reka-ui with collision detection.

Also available for React ->

When to use which

Decision Guide

Dialogs capture immediate user focus for critical actions. Sheets slide in from screen edges for deep secondary forms, while Popovers provide lightweight contextual cards.

ComponentRole
Dialog

Critical confirmations, destructive warnings, or focused single-purpose tasks requiring user resolution.

Modal Window
Sheet

Complex edit forms, filter panes, or shopping carts that retain underlying page context.

Off-Canvas Slide-Over
Drawer

Mobile bottom sheets, touch-friendly sliding panels, or secondary inspection trays.

Edge Panel / Bottom Sheet
Popovercurrent

Small contextual dropdowns, color pickers, date pickers, or inline configuration flyouts.

Contextual Floating Card
  • Urgent confirmation or focused prompt → Dialog (view)
  • Side panel for deep form editing → Sheet (view)
  • Mobile bottom sheet or gesture tray → Drawer (view)
  • Anchored contextual flyout or controls → Popover

Installation

$npx shadcn-vue@latest add https://uipkge.dev/r/vue/popover.json
Named registry:npx shadcn-vue@latest add @uipkge/popoverInstalls to:app/components/ui/popover/

Examples

Loading interactive previews…

Props

NameType / ValuesDefaultRequired
persiststring | booleanfalseoptional
closeBehaviorPopoverCloseBehavior'auto'optional

Schema

Type aliases from this item's source — use them to shape the data you pass in.

PopoverContext
interface PopoverContext {
  closeBehavior: Ref<PopoverCloseBehavior>
}

npm dependencies

Used by

Files installed (6)

  • app/components/ui/popover/Popover.vue1.8 kB
    <script setup lang="ts">
    import type { PopoverRootEmits, PopoverRootProps } from 'reka-ui'
    import { PopoverRoot, useForwardPropsEmits } from 'reka-ui'
    import { computed, onMounted, provide, ref, toRef, useId, watch } from 'vue'
    import { POPOVER_INJECTION_KEY, type PopoverCloseBehavior } from './context'
    
    const props = withDefaults(
      defineProps<
        PopoverRootProps & {
          persist?: string | boolean
          closeBehavior?: PopoverCloseBehavior
        }
      >(),
      {
        persist: false,
        closeBehavior: 'auto',
      },
    )
    
    const emits = defineEmits<PopoverRootEmits>()
    
    provide(POPOVER_INJECTION_KEY, {
      closeBehavior: toRef(props, 'closeBehavior'),
    })
    
    const autoId = useId()
    const storageKey = computed(() => {
      if (props.persist === false) return null
      if (props.persist === true) return `uipkge-popover-${autoId}`
      return props.persist
    })
    
    const localOpen = ref<boolean>(props.defaultOpen ?? false)
    
    onMounted(() => {
      if (!storageKey.value || typeof localStorage === 'undefined') return
      if (localStorage.getItem(storageKey.value) === '1') {
        localOpen.value = true
        if (props.open === undefined) {
          emits('update:open', true)
        }
      }
    })
    
    watch(
      () => (props.open === undefined ? localOpen.value : props.open),
      (v) => {
        if (!storageKey.value || typeof localStorage === 'undefined') return
        if (v) localStorage.setItem(storageKey.value, '1')
        else localStorage.removeItem(storageKey.value)
      },
    )
    
    const forwarded = useForwardPropsEmits(
      computed(() => ({
        open: props.open,
        defaultOpen: props.defaultOpen,
        modal: props.modal,
      })),
      emits,
    )
    
    function onUpdateOpen(value: boolean) {
      localOpen.value = value
      emits('update:open', value)
    }
    </script>
    
    <template>
      <PopoverRoot v-slot="slotProps" data-uipkge data-slot="popover" v-bind="forwarded" @update:open="onUpdateOpen">
        <slot v-bind="slotProps" />
      </PopoverRoot>
    </template>
    
  • app/components/ui/popover/PopoverAnchor.vue0.3 kB
  • app/components/ui/popover/PopoverContent.vue2.5 kB
  • app/components/ui/popover/PopoverTrigger.vue0.3 kB
  • app/components/ui/popover/context.ts0.3 kB
  • app/components/ui/popover/index.ts0.2 kB

Raw manifest:https://uipkge.dev/r/vue/popover.json