# Popover

Small overlay panels positioned relative to a trigger.

```tsx
import { Avatar, Popover, Portal } from '@skeletonlabs/skeleton-react';
import { XIcon } from 'lucide-react';

export default function Default() {
	return (
		<Popover>
			<Popover.Trigger className="btn preset-filled">Trigger</Popover.Trigger>
			<Portal>
				<Popover.Positioner>
					<Popover.Content className="card w-96 p-4 bg-surface-100-900 shadow-xl">
						<div className="space-y-4">
							<header className="grid grid-cols-[auto_1fr_auto] gap-4 items-center">
								<Avatar>
									<Avatar.Image
										src="https://cdn.bsky.app/img/avatar/plain/did:plc:whtgi5zx7ylmdw2i76vq7vq4/bafkreibgoxuqahwcpiah22yfovqszh33x2u4sysmqoyuk5j54aoakt7364@jpeg"
										alt="Skeleton Labs"
									/>
								</Avatar>
								<div>
									<Popover.Title className="text-lg font-bold">Skeleton Labs</Popover.Title>
									<a href="https://bsky.app/profile/skeleton.dev" target="_blank" rel="noopener noreferrer" className="anchor">
										@skeletonlabs.dev
									</a>
								</div>
								<Popover.CloseTrigger className="btn-icon hover:preset-tonal self-start">
									<XIcon className="size-4" />
								</Popover.CloseTrigger>
							</header>
							<Popover.Description>Your friendly neighborhood open source maintainers. Creators of Skeleton.</Popover.Description>
							<div className="flex gap-4">
								<p className="text-sm">
									800 <span className="opacity-60">Followers</span>
								</p>
								<p className="text-sm">
									120 <span className="opacity-60">Following</span>
								</p>
								<p className="text-sm">
									100 <span className="opacity-60">Posts</span>
								</p>
							</div>
						</div>
						<Popover.Arrow className="[--arrow-size:--spacing(2)] [--arrow-background:var(--color-surface-100-900)]">
							<Popover.ArrowTip />
						</Popover.Arrow>
					</Popover.Content>
				</Popover.Positioner>
			</Portal>
		</Popover>
	);
}

```

Breaking convention in Skeleton, this component is provided "headless". Meaning no default styles are applied out of the box. This ensures you retain full control of all styling for maximum flexibility.

## Anchor

Use the `Anchor` component to position the popover contents relative to an element other than the trigger.

```tsx
import { Avatar, Popover, Portal } from '@skeletonlabs/skeleton-react';
import { XIcon } from 'lucide-react';

export default function Anchor() {
	return (
		<Popover>
			<div className="flex items-center gap-4">
				<Popover.Anchor>
					<Avatar>
						<Avatar.Image
							src="https://cdn.bsky.app/img/avatar/plain/did:plc:whtgi5zx7ylmdw2i76vq7vq4/bafkreibgoxuqahwcpiah22yfovqszh33x2u4sysmqoyuk5j54aoakt7364@jpeg"
							alt="Skeleton Labs"
						/>
					</Avatar>
				</Popover.Anchor>
				<Popover.Trigger className="btn preset-filled">Show Profile</Popover.Trigger>
			</div>
			<Portal>
				<Popover.Positioner>
					<Popover.Content className="card w-96 p-4 bg-surface-100-900 shadow-xl">
						<div className="space-y-4">
							<header className="grid grid-cols-[auto_1fr_auto] gap-4 items-center">
								<Avatar>
									<Avatar.Image
										src="https://cdn.bsky.app/img/avatar/plain/did:plc:whtgi5zx7ylmdw2i76vq7vq4/bafkreibgoxuqahwcpiah22yfovqszh33x2u4sysmqoyuk5j54aoakt7364@jpeg"
										alt="Skeleton Labs"
									/>
								</Avatar>
								<div>
									<Popover.Title className="text-lg font-bold">Skeleton Labs</Popover.Title>
									<a href="https://bsky.app/profile/skeleton.dev" target="_blank" rel="noopener noreferrer" className="anchor">
										@skeletonlabs.dev
									</a>
								</div>
								<Popover.CloseTrigger className="btn-icon hover:preset-tonal self-start">
									<XIcon className="size-4" />
								</Popover.CloseTrigger>
							</header>
							<Popover.Description>Your friendly neighborhood open source maintainers. Creators of Skeleton.</Popover.Description>
							<div className="flex gap-4">
								<p className="text-sm">
									800 <span className="opacity-60">Followers</span>
								</p>
								<p className="text-sm">
									120 <span className="opacity-60">Following</span>
								</p>
								<p className="text-sm">
									100 <span className="opacity-60">Posts</span>
								</p>
							</div>
						</div>
						<Popover.Arrow className="[--arrow-size:--spacing(2)] [--arrow-background:var(--color-surface-100-900)]">
							<Popover.ArrowTip />
						</Popover.Arrow>
					</Popover.Content>
				</Popover.Positioner>
			</Portal>
		</Popover>
	);
}

```

## Arrow

Visually connects the popover content to the trigger element. Will automatically align based on the selected side.

```tsx
import { Popover, Portal } from '@skeletonlabs/skeleton-react';

export default function Arrow() {
	return (
		<Popover>
			<Popover.Trigger className="btn preset-filled">Trigger</Popover.Trigger>
			<Portal>
				<Popover.Positioner>
					<Popover.Content className="card max-w-md p-4 bg-surface-100-900 shadow-xl">
						<Popover.Description>This example will have a small arrow.</Popover.Description>
						<Popover.Arrow className="[--arrow-size:--spacing(2)] [--arrow-background:var(--color-surface-100-900)]">
							<Popover.ArrowTip />
						</Popover.Arrow>
					</Popover.Content>
				</Popover.Positioner>
			</Portal>
		</Popover>
	);
}

```

## Z-Index

By default Skeleton does not take an opinionated stance regarding z-index stacking. The result is the component can sometimes be occluded beneath other elements with a higher index. The Z-Index can controlled by applying a utility class to the `Positioner` component.

```tsx
import { Popover, Portal } from '@skeletonlabs/skeleton-react';

export default function ZIndex() {
	return (
		<div className="grid grid-cols-2 gap-4">
			<Popover>
				<Popover.Trigger className="btn preset-filled">Default (auto)</Popover.Trigger>
				<Portal>
					<Popover.Positioner>
						<Popover.Content className="card max-w-md p-4 bg-surface-100-900 space-y-2">
							<Popover.Description>This example will be below the sibling.</Popover.Description>
						</Popover.Content>
					</Popover.Positioner>
				</Portal>
			</Popover>

			<Popover>
				<Popover.Trigger className="btn preset-filled">Above (20)</Popover.Trigger>
				<Portal>
					<Popover.Positioner className="z-20!">
						<Popover.Content className="card max-w-md p-4 bg-surface-100-900 shadow-xl space-y-2">
							<Popover.Description>This example will be above the sibling.</Popover.Description>
						</Popover.Content>
					</Popover.Positioner>
				</Portal>
			</Popover>

			<div className="col-span-2 h-[100px] relative">
				<div className="rounded bg-primary-200-800/75 w-full h-full z-10 flex justify-center items-center absolute">Sibling (10)</div>
			</div>
		</div>
	);
}

```

## Provider Pattern

Use the [Provider Pattern](/docs/\[framework]/get-started/fundamentals#provider-pattern) to gain access to the inner component APIs.

```tsx
import { Popover, Portal, usePopover } from '@skeletonlabs/skeleton-react';

export default function Default() {
	const popover = usePopover({
		closeOnInteractOutside: false,
	});

	function showAndHide() {
		popover.setOpen(true);
		setTimeout(() => {
			popover.setOpen(false);
		}, 3000);
	}
	return (
		<div className="flex flex-col gap-4">
			<button className="btn preset-filled" onClick={showAndHide}>
				Show for 3 seconds
			</button>

			<Popover.Provider value={popover}>
				<Popover.Trigger className="btn preset-tonal">Anchor</Popover.Trigger>
				<Portal>
					<Popover.Positioner>
						<Popover.Content className="card max-w-sm p-4 bg-surface-100-900 shadow-xl space-y-2">
							<Popover.Description>This popover will appear, stay open for three seconds, then close on it's own.</Popover.Description>
						</Popover.Content>
					</Popover.Positioner>
				</Portal>
			</Popover.Provider>
		</div>
	);
}

```

## Direction

Set the text direction (`ltr` or `rtl`) using the `dir` prop.

```tsx
import { Popover, Portal } from '@skeletonlabs/skeleton-react';

export default function Dir() {
	return (
		<Popover dir="rtl">
			<Popover.Trigger className="btn preset-filled">Trigger</Popover.Trigger>
			<Portal>
				<Popover.Positioner>
					<Popover.Content className="card max-w-md p-4 bg-surface-100-900 shadow-xl space-y-2">
						<Popover.Title className="font-bold">Title</Popover.Title>
						<Popover.Description>
							Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sapiente magni distinctio explicabo quisquam. Rerum impedit culpa
							nesciunt enim.
						</Popover.Description>
						<Popover.CloseTrigger className="btn preset-tonal">Close</Popover.CloseTrigger>
					</Popover.Content>
				</Popover.Positioner>
			</Portal>
		</Popover>
	);
}

```

## Anatomy

Here's an overview of how the Popover component is structured in code:

```tsx
import { Popover, Portal } from '@skeletonlabs/skeleton-react';

export default function Anatomy() {
	return (
		<Popover>
			<Popover.Anchor />
			<Popover.Trigger />
			<Portal>
				<Popover.Positioner>
					<Popover.Content>
						<Popover.Title />
						<Popover.Description />
						<Popover.CloseTrigger />
						<Popover.Arrow>
							<Popover.ArrowTip />
						</Popover.Arrow>
					</Popover.Content>
				</Popover.Positioner>
			</Portal>
		</Popover>
	);
}
```

## API Reference

<ApiReference id="react/popover" />
