A contextual floating component for displaying information and interactive content anchored to a trigger element. Uses Floating UI for intelligent positioning, with an arrow tying the panel to its trigger and click-outside-to-close behavior.
The default popover with a trigger button and positioned content.
---
// GENERATED from packages/demos/popover/default.demo.tsx — edit the source, not this file.
import Popover from "@pindoba/astro-popover";
import Button from "@pindoba/astro-button";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "md", direction: "column", align: "start" })}>
<Popover id="astro-demo-popover-default" title="Popover Title">
This is the popover content. Click outside to close.
</Popover>
<Button id="astro-demo-popover-default-trigger">Open Popover</Button>
</div>
<script>
import { usePopover } from "@pindoba/astro-popover/use-popover";
usePopover({
id: "astro-demo-popover-default",
trigger: document.getElementById("astro-demo-popover-default-trigger"),
});
</script>Every popover points back at its trigger. The arrow stays centred on the anchor
as the popover repositions and moves to the correct edge when the panel flips, and
it takes its fill and border from the panel itself — a recoloured or translucent
popover needs no extra configuration. Pass arrow={false} for surfaces that
shouldn’t read as tethered, such as a rail flyout or a submenu that overlaps the
panel it grows from.
---
// GENERATED from packages/demos/popover/arrow.demo.tsx — edit the source, not this file.
import Popover from "@pindoba/astro-popover";
import Button from "@pindoba/astro-button";
import { stack } from "@pindoba/styled-system/patterns";
---
<div
class={stack({
gap: "md",
direction: "row",
align: "center",
flexWrap: "wrap",
})}
>
<Popover id="astro-demo-popover-arrow-on" title="Tethered">
The arrow tracks the trigger and follows the panel through a flip.
</Popover>
<Button id="astro-demo-popover-arrow-on-trigger">With arrow</Button>
<Popover id="astro-demo-popover-arrow-off" title="Untethered" arrow={false}>
No arrow — the panel reads as its own surface.
</Popover>
<Button id="astro-demo-popover-arrow-off-trigger">
arrow={false}
</Button>
</div>
<script>
import { usePopover } from "@pindoba/astro-popover/use-popover";
usePopover({
id: "astro-demo-popover-arrow-on",
trigger: document.getElementById("astro-demo-popover-arrow-on-trigger"),
});
usePopover({
id: "astro-demo-popover-arrow-off",
trigger: document.getElementById("astro-demo-popover-arrow-off-trigger"),
});
</script>Use the placement prop to control where the popover appears relative to its trigger. Automatically flips and shifts when there is insufficient space.
---
// GENERATED from packages/demos/popover/placement.demo.tsx — edit the source, not this file.
import Popover from "@pindoba/astro-popover";
import Button from "@pindoba/astro-button";
import { stack } from "@pindoba/styled-system/patterns";
---
<div
class={stack({
gap: "md",
direction: "row",
align: "center",
flexWrap: "wrap",
})}
>
<Popover id="astro-demo-popover-top" title="Top">
Placed above the trigger.
</Popover>
<Button id="astro-demo-popover-top-trigger">Top</Button>
<Popover id="astro-demo-popover-bottom" title="Bottom">
Placed below the trigger.
</Popover>
<Button id="astro-demo-popover-bottom-trigger">Bottom</Button>
<Popover id="astro-demo-popover-left" title="Left">
Placed to the left.
</Popover>
<Button id="astro-demo-popover-left-trigger">Left</Button>
<Popover id="astro-demo-popover-right" title="Right">
Placed to the right.
</Popover>
<Button id="astro-demo-popover-right-trigger">Right</Button>
</div>
<script>
import { usePopover } from "@pindoba/astro-popover/use-popover";
usePopover({
id: "astro-demo-popover-top",
trigger: document.getElementById("astro-demo-popover-top-trigger"),
placement: "top",
});
usePopover({
id: "astro-demo-popover-bottom",
trigger: document.getElementById("astro-demo-popover-bottom-trigger"),
placement: "bottom",
});
usePopover({
id: "astro-demo-popover-left",
trigger: document.getElementById("astro-demo-popover-left-trigger"),
placement: "left",
});
usePopover({
id: "astro-demo-popover-right",
trigger: document.getElementById("astro-demo-popover-right-trigger"),
placement: "right",
});
</script>