Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script lang="ts" setup>
const open = ref(false)
</script>

<template>
<UPopover
v-model:open="open"
:dismissible="false"
:ui="{ content: 'w-(--reka-popper-anchor-width) p-4' }"
>
<template #anchor>
<UInput placeholder="Focus to open" @focus="open = true" @blur="open = false" />
</template>

<template #content>
<Placeholder class="w-full aspect-square" />
</template>
</UPopover>
</template>
15 changes: 15 additions & 0 deletions docs/content/3.components/popover.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,21 @@ name: 'popover-command-palette-example'
---
::

### With anchor slot

You can use the `#anchor` slot to position the Popover against a custom element.

::warning
This slot only works when `mode` is `click`.
::

::component-example
---
collapse: true
name: 'popover-anchor-slot-example'
---
::

## API

### Props
Expand Down
16 changes: 16 additions & 0 deletions playground/app/pages/components/popover.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
const open = ref(false)
const openCustomAnchor = ref(false)
const loading = ref(false)

function send() {
Expand Down Expand Up @@ -51,6 +52,21 @@ function send() {
</div>
</template>
</UPopover>

<div class="mt-8 relative">
<UPopover
v-model:open="openCustomAnchor"
:dismissible="false"
>
<template #anchor>
<UInput placeholder="Search" class="w-56" @focus="openCustomAnchor = true" />
</template>

<template #content>
<Placeholder class="size-48 m-4 inline-flex" />
</template>
</UPopover>
</div>
</div>

<div class="mt-24">
Expand Down
5 changes: 5 additions & 0 deletions src/runtime/components/Popover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface PopoverEmits extends PopoverRootEmits {
export interface PopoverSlots {
default(props: { open: boolean }): any
content(props?: {}): any
anchor(props?: {}): any
}
</script>

Expand Down Expand Up @@ -103,6 +104,10 @@ const Component = computed(() => props.mode === 'hover' ? HoverCard : Popover)
<slot :open="open" />
</Component.Trigger>

<Component.Anchor v-if="'Anchor' in Component && !!slots.anchor" as-child>
<slot name="anchor" />
</Component.Anchor>

<Component.Portal v-bind="portalProps">
<Component.Content v-bind="contentProps" :class="ui.content({ class: [!slots.default && props.class, props.ui?.content] })" v-on="contentEvents">
<slot name="content" />
Expand Down
3 changes: 2 additions & 1 deletion test/components/Popover.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ describe('Popover', () => {
['with ui', { props: { ...props, ui: { content: 'shadow-xl' } } }],
// Slots
['with default slot', { props, slots: { default: () => 'Default slot' } }],
['with content slot', { props, slots: { content: () => 'Content slot' } }]
['with content slot', { props, slots: { content: () => 'Content slot' } }],
['with anchor slot', { props, slots: { anchor: () => 'Anchor slot' } }]
])('renders %s correctly', async (nameOrHtml: string, options: { props?: PopoverProps, slots?: Partial<PopoverSlots> }) => {
const html = await ComponentRender(nameOrHtml, options, Popover)
expect(html).toMatchSnapshot()
Expand Down
20 changes: 20 additions & 0 deletions test/components/__snapshots__/Popover-vue.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Popover > renders with anchor slot correctly 1`] = `
"<!--v-if-->
Anchor slot
<!--teleport start-->


<div data-reka-popper-content-wrapper="" style="position: fixed; left: 0px; top: 0px; transform: translate(0, -200%); min-width: max-content;">
<div id="reka-popover-content-v-0" data-state="open" aria-labelledby="" style="--reka-popover-content-transform-origin: var(--reka-popper-transform-origin); --reka-popover-content-available-width: var(--reka-popper-available-width); --reka-popover-content-available-height: var(--reka-popper-available-height); --reka-popover-trigger-width: var(--reka-popper-anchor-width); --reka-popover-trigger-height: var(--reka-popper-anchor-height); animation: none;" role="dialog" data-dismissable-layer="" tabindex="-1" class="bg-default shadow-lg rounded-md ring ring-default data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-popover-content-transform-origin) focus:outline-none pointer-events-auto" data-side="bottom" data-align="center"></div>
</div>


<!--teleport end-->"
`;

exports[`Popover > renders with arrow correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand All @@ -15,6 +30,7 @@ exports[`Popover > renders with arrow correctly 1`] = `

exports[`Popover > renders with class correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand All @@ -28,6 +44,7 @@ exports[`Popover > renders with class correctly 1`] = `

exports[`Popover > renders with content slot correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand All @@ -43,6 +60,7 @@ exports[`Popover > renders with content slot correctly 1`] = `

exports[`Popover > renders with default slot correctly 1`] = `
"Default slot
<!--v-if-->
<!--teleport start-->


Expand All @@ -56,6 +74,7 @@ exports[`Popover > renders with default slot correctly 1`] = `

exports[`Popover > renders with open correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand All @@ -69,6 +88,7 @@ exports[`Popover > renders with open correctly 1`] = `

exports[`Popover > renders with ui correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand Down
20 changes: 20 additions & 0 deletions test/components/__snapshots__/Popover.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Popover > renders with anchor slot correctly 1`] = `
"<!--v-if-->
Anchor slot
<!--teleport start-->


<div data-reka-popper-content-wrapper="" style="position: fixed; left: 0px; top: 0px; transform: translate(0, -200%); min-width: max-content;">
<div id="reka-popover-content-v-0-0-0" data-state="open" aria-labelledby="" style="--reka-popover-content-transform-origin: var(--reka-popper-transform-origin); --reka-popover-content-available-width: var(--reka-popper-available-width); --reka-popover-content-available-height: var(--reka-popper-available-height); --reka-popover-trigger-width: var(--reka-popper-anchor-width); --reka-popover-trigger-height: var(--reka-popper-anchor-height); animation: none;" role="dialog" data-dismissable-layer="" tabindex="-1" class="bg-default shadow-lg rounded-md ring ring-default data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-popover-content-transform-origin) focus:outline-none pointer-events-auto" data-side="bottom" data-align="center"></div>
</div>


<!--teleport end-->"
`;

exports[`Popover > renders with arrow correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand All @@ -15,6 +30,7 @@ exports[`Popover > renders with arrow correctly 1`] = `

exports[`Popover > renders with class correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand All @@ -28,6 +44,7 @@ exports[`Popover > renders with class correctly 1`] = `

exports[`Popover > renders with content slot correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand All @@ -43,6 +60,7 @@ exports[`Popover > renders with content slot correctly 1`] = `

exports[`Popover > renders with default slot correctly 1`] = `
"Default slot
<!--v-if-->
<!--teleport start-->


Expand All @@ -56,6 +74,7 @@ exports[`Popover > renders with default slot correctly 1`] = `

exports[`Popover > renders with open correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand All @@ -69,6 +88,7 @@ exports[`Popover > renders with open correctly 1`] = `

exports[`Popover > renders with ui correctly 1`] = `
"<!--v-if-->
<!--v-if-->
<!--teleport start-->


Expand Down