feat(Popover): add reference prop

This commit is contained in:
Benjamin Canac
2025-07-01 15:19:35 +02:00
parent 5c573b37b6
commit b00e07f13d
5 changed files with 66 additions and 6 deletions

View File

@@ -0,0 +1,43 @@
<script setup lang="ts">
const open = ref(false)
const anchor = ref({ x: 0, y: 0 })
const reference = computed(() => ({
getBoundingClientRect: () =>
({
width: 0,
height: 0,
left: anchor.value.x,
right: anchor.value.x,
top: anchor.value.y,
bottom: anchor.value.y,
...anchor.value
} as DOMRect)
}))
</script>
<template>
<UPopover
:open="open"
:reference="reference"
:content="{ side: 'top', sideOffset: 16, updatePositionStrategy: 'always' }"
>
<div
class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"
@pointerenter="open = true"
@pointerleave="open = false"
@pointermove="(ev) => {
anchor.x = ev.clientX
anchor.y = ev.clientY
}"
>
Hover me
</div>
<template #content>
<div class="p-4">
{{ anchor.x.toFixed(0) }} - {{ anchor.y.toFixed(0) }}
</div>
</template>
</UPopover>
</template>

View File

@@ -202,6 +202,16 @@ name: 'popover-command-palette-example'
---
::
### With following cursor :badge{label="Soon" class="align-text-top"}
You can make the Popover follow the cursor when hovering over an element using the [`reference`](https://reka-ui.com/docs/components/tooltip#trigger) prop:
::component-example
---
name: 'popover-cursor-example'
---
::
### With anchor slot
You can use the `#anchor` slot to position the Popover against a custom element.

View File

@@ -196,10 +196,6 @@ name: 'tooltip-cursor-example'
---
::
::note
This example is based on Reka UI's [Tooltip Cursor](https://reka-ui.com/examples/tooltip-cursor) example.
::
## API
### Props

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import type { PopoverRootProps, HoverCardRootProps, PopoverRootEmits, PopoverContentProps, PopoverContentEmits, PopoverArrowProps } from 'reka-ui'
import type { PopoverRootProps, HoverCardRootProps, PopoverRootEmits, PopoverContentProps, PopoverContentEmits, PopoverArrowProps, HoverCardTriggerProps } from 'reka-ui'
import type { AppConfig } from '@nuxt/schema'
import theme from '#build/ui/popover'
import type { EmitsToProps, ComponentConfig } from '../types/utils'
@@ -27,6 +27,12 @@ export interface PopoverProps extends PopoverRootProps, Pick<HoverCardRootProps,
* @defaultValue true
*/
portal?: boolean | string | HTMLElement
/**
* The reference (or anchor) element that is being referred to for positioning.
*
* If not provided will use the current component as anchor.
*/
reference?: HoverCardTriggerProps['reference']
/**
* When `false`, the popover will not close when clicking outside or pressing escape.
* @defaultValue true
@@ -100,7 +106,7 @@ const Component = computed(() => props.mode === 'hover' ? HoverCard : Popover)
<template>
<Component.Root v-slot="{ open }" v-bind="rootProps">
<Component.Trigger v-if="!!slots.default" as-child :class="props.class">
<Component.Trigger v-if="!!slots.default || !!reference" as-child :reference="reference" :class="props.class">
<slot :open="open" />
</Component.Trigger>

View File

@@ -27,6 +27,11 @@ export interface TooltipProps extends TooltipRootProps {
* @defaultValue true
*/
portal?: boolean | string | HTMLElement
/**
* The reference (or anchor) element that is being referred to for positioning.
*
* If not provided will use the current component as anchor.
*/
reference?: TooltipTriggerProps['reference']
class?: any
ui?: Tooltip['slots']