AnchoredPopper
A lightweight popper component that positions content relative to an anchor element, with click-away-to-close behavior and optional Paper styling. Built on MUI's Popper, ClickAwayListener, and Paper.
Features
- Anchor-based positioning: Positions content relative to any element via a ref
- Click-away to close: Closes when the user clicks outside the popper (via ClickAwayListener)
- Placement control: Configurable placement (e.g.
bottom-end,top-start) using MUI's Popper placement types - Paper styling: Content is wrapped in a Paper with configurable elevation and minimum width
- Controlled open state: Fully controlled via
openandonCloseprops
Basic Usage
Use a ref for the anchor element and control visibility with open and onClose. The popper content is rendered in a Paper and closes when clicking outside.
Toggle with a button
import { useRef, useState } from 'react';
import { Button } from '@mui/material';
import AnchoredPopper from '@myunisoft/design-system';
function Example() {
const anchorRef = useRef<HTMLButtonElement>(null);
const [open, setOpen] = useState<boolean>(false);
return (
<>
<Button ref={anchorRef} variant="contained" onClick={() => setOpen((v) => !v)}>
{open ? 'Close popper' : 'Open popper'}
</Button>
<AnchoredPopper open={open} anchorRef={anchorRef} onClose={() => setOpen(false)}>
<div>Popper content here. Click outside to close.</div>
</AnchoredPopper>
</>
);
}
Placement
The placement prop controls where the popper appears relative to the anchor. Default is bottom-end. Valid values follow MUI's Popper placement (e.g. bottom-start, bottom, top-end, top, left, right).
import { useRef, useState } from 'react';
const anchorRef = useRef<HTMLButtonElement>(null);
const [open, setOpen] = useState<boolean>(false);
<AnchoredPopper
open={open}
anchorRef={anchorRef}
onClose={() => setOpen(false)}
placement="top-start"
>
Content aligned to top-start of the anchor
</AnchoredPopper>
Customization
Minimum width and elevation
- minWidth: Minimum width of the Paper (default
200). Use a number (px) or a string (e.g.'20rem'). - elevation: MUI Paper elevation (default
2). - zIndex: z-index of the popper (default
9999).
import { useRef, useState } from 'react';
const anchorRef = useRef<HTMLElement>(null);
const [open, setOpen] = useState<boolean>(false);
<AnchoredPopper
open={open}
anchorRef={anchorRef}
onClose={() => setOpen(false)}
minWidth={320}
elevation={4}
zIndex={1300}
>
Wider, more elevated popper
</AnchoredPopper>
Use case: menu or dropdown content
AnchoredPopper is well suited for custom dropdowns, action panels, or small forms that should close when the user clicks outside—for example, a toolbar action that opens a small panel (filters, export options, etc.) anchored to a button.
import { useRef, useState } from 'react';
import { Button, List, ListItem } from '@mui/material';
import AnchoredPopper from '@myunisoft/design-system';
const anchorRef = useRef<HTMLButtonElement>(null);
const [open, setOpen] = useState<boolean>(false);
<Button ref={anchorRef} onClick={() => setOpen(true)}>Actions</Button>
<AnchoredPopper open={open} anchorRef={anchorRef} onClose={() => setOpen(false)} placement="bottom-end">
<List>
<ListItem button onClick={handleAction1}>Option 1</ListItem>
<ListItem button onClick={handleAction2}>Option 2</ListItem>
</List>
</AnchoredPopper>
Use case: open popper next to a chosen element (button X, anchor Y)
You can open the popper when clicking a control button (e.g. "Open popper") and have it appear next to a different element (the anchor). The anchor is chosen by ref: pass the ref of the element you want the popper to sit next to. Typical pattern: one or more possible anchors each have a ref; a control (dropdown, button) selects which ref to use and optionally the placement; clicking "Open" sets open={true} and passes the selected anchorRef and placement.
Try the demo below: pick which element (Apple, Berry, or Leaf) the popper should anchor to, pick a placement (e.g. top-start, bottom-end), then click Open popper. The popper opens next to the chosen element with the chosen placement. Click outside to close.
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
open | boolean | Yes | - | Whether the popper is visible |
anchorRef | RefObject<HTMLElement | null> | Yes | - | Ref to the anchor element (e.g. a button) |
onClose | () => void | Yes | - | Called when the user clicks away (used by ClickAwayListener) |
placement | PopperPlacementType | No | 'bottom-end' | Placement of the popper relative to the anchor |
children | ReactNode | Yes | - | Content rendered inside the Paper |
minWidth | number | string | No | 200 | Minimum width of the Paper (px if number) |
zIndex | number | No | 9999 | z-index applied to the popper |
elevation | number | No | 2 | MUI Paper elevation |
Import
import AnchoredPopper from '@myunisoft/design-system';
// or
import { AnchoredPopper } from '@myunisoft/design-system';