@lattice-ui/popover Part of the stable direction toward v1.0.
What It Is For
Use Popover for anchored surfaces that should stay connected to a trigger or anchor without taking over the full interaction mode like a dialog.
It is the right fit for inline help, quick settings, or compact secondary editors.
import { PortalProvider } from "@lattice-ui/layer";
import { Popover } from "@lattice-ui/popover";
import React from "@rbxts/react";
type Props = {
playerGui: PlayerGui;
};
function PopoverDemo() {
const [open, setOpen] = React.useState(false);
return (
<Popover.Root onOpenChange={setOpen} open={open}>
<Popover.Trigger asChild>
<textbutton
AutoButtonColor={false}
BackgroundColor3={Color3.fromRGB(53, 104, 196)}
BorderSizePixel={0}
Size={UDim2.fromOffset(190, 40)}
Text="Toggle popover"
TextColor3={Color3.fromRGB(240, 244, 250)}
TextSize={14}
>
<uicorner CornerRadius={new UDim(0, 8)} />
</textbutton>
</Popover.Trigger>
<Popover.Portal>
<Popover.Content asChild offset={new Vector2(0, 8)} placement="bottom">
<frame
BackgroundColor3={Color3.fromRGB(34, 41, 54)}
BorderSizePixel={0}
Size={UDim2.fromOffset(280, 146)}
>
<uicorner CornerRadius={new UDim(0, 10)} />
<textlabel
BackgroundTransparency={1}
Position={UDim2.fromOffset(14, 14)}
Size={UDim2.fromOffset(252, 54)}
Text="Use Popover when the surface should stay anchored to the trigger instead of taking over the whole interaction mode."
TextColor3={Color3.fromRGB(236, 240, 248)}
TextSize={14}
TextWrapped={true}
TextXAlignment={Enum.TextXAlignment.Left}
TextYAlignment={Enum.TextYAlignment.Top}
/>
<Popover.Close asChild>
<textbutton
AutoButtonColor={false}
BackgroundColor3={Color3.fromRGB(60, 76, 104)}
BorderSizePixel={0}
Position={UDim2.fromOffset(14, 96)}
Size={UDim2.fromOffset(100, 32)}
Text="Close"
TextColor3={Color3.fromRGB(236, 240, 248)}
TextSize={14}
>
<uicorner CornerRadius={new UDim(0, 8)} />
</textbutton>
</Popover.Close>
</frame>
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);
}
export function PopoverExample(props: Props) {
return (
<PortalProvider container={props.playerGui}>
<PopoverDemo />
</PortalProvider>
);
} Live demo is experimental and may contain bugs.
Install
Global CLI command: lattice add popover
Monorepo local script
Use your package manager wrapper when running the local lattice command.
pnpm lattice add popoverPublic Exports
-
Popover -
Popover.Root -
Popover.Trigger -
Popover.Portal -
Popover.Content -
Popover.Anchor -
Popover.Close -
PopoverAnchor -
PopoverClose -
PopoverContent -
PopoverPortal -
PopoverRoot -
PopoverTrigger
State Model
Popover.Rootmanages controlled or uncontrolledopenstate and optionalmodalbehavior.- Trigger, anchor, and content refs are part of the shared context so positioning stays synchronized.
- Content uses popper placement data plus layer dismissal semantics rather than in-place layout flow.
Key API
Popover.Root
Use open, defaultOpen, onOpenChange, and modal to define how heavy the overlay interaction model should be.
Popover.Anchor
Use an explicit anchor when the positioned content should attach to something other than the trigger itself.
Popover.Content
Use placement, offset, padding, and outside-interaction hooks to control geometry and dismissal.
Popover.Close
Attach dismiss behavior to any host element inside the content without introducing extra state plumbing.
Composition Patterns
Quick settings panel
Use a trigger for entry, then place short form controls inside Popover.Content when the edit surface should remain lightweight.
Detached anchor workflows
Use Popover.Anchor when the UI affordance that opens the surface is not the same visual target the surface should align to.
Cautions / Limits
- Because popovers are anchored overlays, they still benefit from a shared
PortalProvidernear the app root. - Use
Dialoginstead when the content should trap attention or own a stronger modal interaction contract. - Let
Popperown placement andmotionown the animated wrapper so anchor geometry and transition state do not fight.
Decision Guides
- Choosing between controls
Compare Dialog vs Popover when deciding between lightweight anchors and full overlays.
- Overlay and state pitfalls
Review PortalProvider, stacking, and focus limits before using anchored overlays.