Popover
A floating panel that appears next to a trigger element, commonly used for displaying additional content or forms.
Anatomy
<script>
import {
Popover,
PopoverTrigger,
PopoverContent,
PopoverHeader,
PopoverBody,
PopoverFooter,
PopoverTitle,
PopoverDescription,
PopoverArrow,
PopoverCloseTrigger,
} from "@saas-ui/svelte/components/popover";
</script>
<Popover.Root>
<PopoverTrigger triggerText="Open Popover" />
<PopoverContent>
<PopoverArrow />
<PopoverHeader>
<PopoverTitle>Popover Title</PopoverTitle>
<PopoverCloseTrigger />
</PopoverHeader>
<PopoverBody>
<PopoverDescription>Popover content goes here.</PopoverDescription>
</PopoverBody>
<PopoverFooter>Footer content</PopoverFooter>
</PopoverContent>
</Popover.Root>Examples
Basic Accessibility
<Popover.Root>
<Popover.Trigger triggerText="Click me" />
<Popover.Content>
<Popover.Arrow />
<Popover.Body>
<Popover.Title>Naruto Form</Popover.Title>
<Text size="sm" class="my-4">
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
</Text>
<Input placeholder="Your fav. character" size="sm" />
</Popover.Body>
</Popover.Content>
</Popover.Root> Controlled Accessibility
open prop.
<HStack gap={4} align="center">
<Popover.Root bind:open={controlledOpen}>
<Popover.Trigger triggerText="Click me" />
<Popover.Content>
<Popover.Arrow />
<Popover.Body>
This is a controlled popover. Use the button to toggle.
</Popover.Body>
</Popover.Content>
</Popover.Root>
<Text size="sm" class="text-fg-muted">Open: {controlledOpen}</Text>
</HStack> Form Accessibility
<Popover.Root size="lg">
<Popover.Trigger triggerText="Click me" />
<Popover.Content class="w-80 rounded-xl">
<Popover.Arrow />
<Popover.Body>
<VStack gap={4}>
<Field.Root>
<Field.Label>Width</Field.Label>
<Input placeholder="40px" size="sm" />
</Field.Root>
<Field.Root>
<Field.Label>Height</Field.Label>
<Input placeholder="32px" size="sm" />
</Field.Root>
<Field.Root>
<Field.Label>Comments</Field.Label>
<Textarea placeholder="Start typing..." size="sm" />
</Field.Root>
</VStack>
</Popover.Body>
<Popover.CloseTrigger />
</Popover.Content>
</Popover.Root> Initial Focus Accessibility
initialFocusEl.
<Popover.Root initialFocusEl={() => inputRef}>
<Popover.Trigger triggerText="Click me" />
<Popover.Content>
<Popover.Header>
<Popover.Title>Manage Your Channels</Popover.Title>
</Popover.Header>
<Popover.Arrow />
<Popover.Body>
<Text size="sm" class="mb-4">
The input below will be focused when the popover opens.
</Text>
<Input
bind:ref={inputRef}
placeholder="I get focused"
size="sm"
/>
</Popover.Body>
<Popover.Footer>
<Box class="flex-1 text-sm">Step 2 of 4</Box>
<HStack gap={2}>
<Button size="sm" variant="ghost">Prev</Button>
<Button size="sm">Next</Button>
</HStack>
</Popover.Footer>
<Popover.CloseTrigger />
</Popover.Content>
</Popover.Root> Lazy Mounted Accessibility
<Popover.Root lazyMount unmountOnExit>
<Popover.Trigger triggerText="Click me" />
<Popover.Content>
<Popover.Arrow />
<Popover.Body>
<Popover.Title>Lazy Mounted</Popover.Title>
<Text size="sm" class="my-4">
This popover content is lazily mounted and unmounts when
closed.
</Text>
</Popover.Body>
</Popover.Content>
</Popover.Root> Nested Accessibility
<Popover.Root>
<Popover.Trigger triggerText="Click me" />
<Popover.Content>
<Popover.Arrow />
<Popover.Body>
<Text size="sm" class="mb-4">
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
</Text>
<Popover.Root
portalled={false}
positioning={{ placement: "bottom" }}
>
<Popover.Trigger
triggerText="Open Nested Popover"
triggerSize="xs"
/>
<Popover.Content>
<Popover.Arrow />
<Popover.Body>Some nested popover content</Popover.Body>
</Popover.Content>
</Popover.Root>
</Popover.Body>
</Popover.Content>
</Popover.Root> Offset Accessibility
<Popover.Root positioning={{ offset: { crossAxis: 0, mainAxis: 7 } }}>
<Popover.Trigger triggerText="Click me" />
<Popover.Content>
<Popover.Body>
This popover has a custom offset from the trigger.
</Popover.Body>
</Popover.Content>
</Popover.Root> Placement Accessibility
<Popover.Root positioning={{ placement: "bottom-end" }}>
<Popover.Trigger triggerText="Bottom End" />
<Popover.Content>
<Popover.Arrow />
<Popover.Body>
This popover is positioned at the bottom-end of the trigger.
</Popover.Body>
</Popover.Content>
</Popover.Root> Same Width Accessibility
<Popover.Root positioning={{ sameWidth: true }}>
<Popover.Trigger triggerText="Click me" triggerClass="min-w-xs" />
<Popover.Content class="w-auto!">
<Popover.Arrow />
<Popover.Body>
This popover has the same width as the trigger button.
</Popover.Body>
</Popover.Content>
</Popover.Root> Sizes Accessibility
xs, sm, md, lg.
<HStack gap={10} align="center">
{#each popoverSizes as size}
<Popover.Root {size}>
<Popover.Trigger
triggerText="Size: {size}"
triggerSize={size}
/>
<Popover.Content>
<Popover.Arrow />
<Popover.Body>
<Popover.Title>Naruto Form</Popover.Title>
<Text size="sm" class="my-4">
Naruto is a Japanese manga series written and
illustrated by Masashi Kishimoto.
</Text>
<Input placeholder="Your fav. character" {size} />
</Popover.Body>
</Popover.Content>
</Popover.Root>
{/each}
</HStack>Props
Popover.Root
The root container component for the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The popover content. |
id | string | - | The unique identifier for the popover. |
size | "xs" | "sm" | "md" | "lg" | "md" | The size of the popover. |
open | boolean | - | Whether the popover is open. |
onOpenChange | (details: { open: boolean }) => void | - | Handler called when the open state changes. |
autoFocus | boolean | true | Whether to automatically set focus on the first focusable content when opened. |
closeOnEscape | boolean | true | Whether to close when the escape key is pressed. |
closeOnInteractOutside | boolean | true | Whether to close when clicking outside. |
modal | boolean | false | Whether the popover should be modal. |
portalled | boolean | true | Whether the popover is portalled. |
lazyMount | boolean | false | Whether to enable lazy mounting. |
unmountOnExit | boolean | false | Whether to unmount on exit. |
positioning | PopoverRootProps['positioning'] | { placement: "bottom", gutter: 12 } | The positioning options for the popover. |
initialFocusEl | () => HTMLElement | null | - | Element to receive focus when the popover is opened. |
onPrefetch | () => void | - | Callback invoked when hovering over the trigger (for prefetching content). Similar to Astro's link prefetching, this allows preloading data before opening. |
Popover.Trigger
The trigger element that opens the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet<[{ props: () => Record<string, any> }]> | - | The trigger element. Receives trigger props that must be spread onto an interactive element. Optional when using triggerText or triggerIcon. |
triggerText | string | - | Simple text to display on the trigger button. |
triggerIcon | Component | - | Icon component to display on the trigger button. |
triggerVariant | "ghost" | "outline" | "solid" | "subtle" | "plain" | "outline" | Variant for the auto-generated trigger button. |
triggerSize | "xs" | "sm" | "md" | "lg" | "sm" | Size for the auto-generated trigger button. |
triggerClass | string | - | CSS classes to apply to the auto-generated trigger button. |
class | string | - | Additional CSS classes to apply. |
Popover.Content
The content container of the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The content to display in the popover. |
class | string | - | Additional CSS classes to apply. |
Popover.Header
The header section of the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The header content. |
class | string | - | Additional CSS classes to apply. |
Popover.Body
The body section of the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The body content. |
class | string | - | Additional CSS classes to apply. |
Popover.Footer
The footer section of the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The footer content. |
class | string | - | Additional CSS classes to apply. |
Popover.Title
The title element of the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The title content. |
class | string | - | Additional CSS classes to apply. |
Popover.Description
The description element of the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet | - | The description content. |
class | string | - | Additional CSS classes to apply. |
Popover.Arrow
The arrow element pointing to the trigger.
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes to apply. |
Popover.CloseTrigger
The close button for the popover.
| Prop | Type | Default | Description |
|---|---|---|---|
children | Snippet<[() => Record<string, unknown>]> | - | Custom content for the close trigger. Receives trigger props that must be spread onto an interactive element. |
buttonText | string | - | Simple text to display on the close button (creates a text button instead of icon). |
buttonVariant | "ghost" | "outline" | "solid" | "subtle" | "plain" | "ghost" | Variant for the auto-generated button when using buttonText. |
buttonSize | "xs" | "sm" | "md" | "lg" | "sm" | Size for the auto-generated button when using buttonText. |
class | string | - | Additional CSS classes to apply. |
aria-label | string | "Close" | Accessible label for the close button. |