Skip to content

Navigation

Popover

A floating overlay anchored to a trigger, for short content or small forms.

<script>
  import { Popover, Button } from "@codeatlasdev/ui";
</script>

<Popover side="bottom" align="start">
  {#snippet triggerChild(props)}<Button {...props}>Open</Button>{/snippet}
  Popover content
</Popover>

Escape closes the popover and returns focus to the trigger, and a press outside dismisses it. It is a popover layer in the browser top layer, positioned with CSS anchor positioning where supported, so it stays above a dialog it opens from. Pass an interactive trigger through triggerChild and spread the received props on it; use trigger only for non-interactive content. For a hint that appears on hover, use Tooltip instead.

To control it, bind:open reads and sets the open state, and onOpenChange fires when the user opens or closes it (not when your code sets the value). The children snippet receives close, which closes the popover and returns focus to the trigger: call it after a choice is made inside, the way DropdownMenu closes on selection.

<Popover bind:open>
  {#snippet triggerChild(props)}<Button {...props}>Pick a date</Button>{/snippet}
  {#snippet children({ close })}
    <Calendar onchange={() => close()} />
  {/snippet}
</Popover>
#160

Basic

Text and an action inside the popover.

Reference #160 · Pick in the gallery

Code
svelte
<script lang="ts">
  import { Popover, Button, Stack } from '@codeatlasdev/ui';
</script>

<Popover>
  {#snippet triggerChild(props)}<Button {...props}>Open popover</Button>{/snippet}
  <Stack gap="3">
    <p class="text">This is a basic popover with some content inside.</p>
    <Button size="sm" variant="filled">Confirm</Button>
  </Stack>
</Popover>

<style>
  .text { margin: 0; font-size: var(--ca-font-size-body2); color: var(--ca-text-secondary); }
</style>
#161

Form

A small form anchored to its trigger, aligned to the start.

Reference #161 · Pick in the gallery

Code
svelte
<script lang="ts">
  import { Popover, Button, TextField, Stack, Flex } from '@codeatlasdev/ui';
</script>

<Popover side="bottom" align="start">
  {#snippet triggerChild(props)}<Button variant="filled" {...props}>Edit label</Button>{/snippet}
  <Stack gap="3">
    <TextField label="Label name" placeholder="e.g. Priority" />
    <Flex gap="2" justify="end">
      <Button size="sm" variant="ghost">Cancel</Button>
      <Button size="sm" variant="filled">Save</Button>
    </Flex>
  </Stack>
</Popover>
#470

Close on pick

A calendar inside a popover that closes itself when a day is chosen.

Reference #470 · Pick in the gallery

Code
svelte
<script lang="ts">
  import { Popover, Button, Calendar, getLocalTimeZone, today, type DateValue } from '@codeatlasdev/ui';

  let open = $state(false);
  let value = $state<DateValue | undefined>(today(getLocalTimeZone()));
</script>

<Popover bind:open align="start">
  {#snippet triggerChild(props)}
    <Button {...props}>{value ? value.toString() : 'Pick a date'}</Button>
  {/snippet}
  {#snippet children({ close })}
    <Calendar bind:value label="Due date" locale="en-US" weekStartsOn={0} onchange={() => close()} />
  {/snippet}
</Popover>

Props

PropTypeDefaultDescription
triggerChildSnippet<[Record<string, unknown>]>–Interactive trigger. Receives the trigger props to spread onto your Button or IconButton.
triggerSnippet–Non-interactive trigger content (text, icon), wrapped in the popover's own button.
childrenSnippet<[{ close: () => void }]>–Popover content. Receives `close`, which closes the popover and returns focus to the trigger.
openbooleanfalseBindable. Whether the popover is open.
onOpenChange(open: boolean) => void–Called when the user opens or closes the popover, not when the bound value is set from code.
side'top' | 'right' | 'bottom' | 'left''bottom'Preferred side of the trigger.
align'start' | 'center' | 'end''center'Alignment against the trigger.
sideOffsetnumber8Distance from the trigger in pixels.
classstring''Extra CSS classes on the content.