BaseAnchor
A primitive that anchors a floating panel to a trigger element.
Usage
Basic
Expand Motion
The default expand springs open from the corner nearest the reference and folds back on close.
Placement
placement is the preferred side; the panel flips when space runs out, and the expand origin follows the final side.
Animation Modes
animation.type takes expand (default), transfer, boom, opacity, or none.
Drip
drip pours the panel out of its trigger like a drop; items marked data-liquid-item appear one by one as the panel grows.
Bead
bead shares the drip engine and pinches its sides by speed; beadPinch sets the peak pinch per side in px.
Custom Ease
Duration and easing live in animation; the component has no top-level duration or ease props.
Panel Surfaces
panelBackground picks the material; surfaceMotionAdaptation decides whether it degrades while the panel moves.
Best Practices
- Reach for
TxPopover,TxDropdownMenu, orTxContextMenufirst; useTxBaseAnchordirectly only to build a new anchored primitive or to position against a virtual reference. - When you use it directly, supply the roles, focus handling, and keyboard navigation your content needs.
- Keep panels light; move multi-step forms, destructive confirmations, and full-screen flows to a Drawer or Dialog.
- For coordinate menus, pass
virtualReferenceand callupdatePosition()after the pointer or canvas transform changes. eagerandkeepAliveContentkeep content measurable, not positioned: measure size while closed, and take coordinates from the reference or an open panel.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | undefined | Whether the panel is open (v-model); omit it for uncontrolled use. |
disabled | boolean | false | Blocks opening and closes an open panel. |
eager | boolean | false | Mounts the panel before the first open so its content can be measured. |
placement | BaseAnchorPlacement | 'bottom-start' | Preferred side; flips when space runs out. |
offset | number | 8 | Gap to the reference in px. |
width | number | 0 | Panel width; 0 sizes to content. |
minWidth | number | 0 | Minimum width. |
maxWidth | number | 360 | Maximum width. |
maxHeight | number | 420 | Maximum height, shrunk to the space left in the viewport. |
unlimitedHeight | boolean | false | Removes the height limit; maxHeight <= 0 does the same. |
matchReferenceWidth | boolean | false | Matches the reference width when width is 0. |
referenceClass | BaseAnchorClassValue | undefined | Class for the reference wrapper; all other attrs go to the panel. |
virtualReference | BaseAnchorVirtualReference | undefined | Positions against a virtual reference, such as a cursor point; the reference slot still renders. |
disableFlip | boolean | false | Keeps the requested side but still shifts into view; for a host-measured virtualReference. |
animation | BaseAnchorAnimationOptions | {} | Animation config; omitted fields take the type's defaults. |
useCard | boolean | true | Wraps content in the built-in TxCard. |
panelVariant | 'solid' | 'dashed' | 'plain' | 'plain' | Border style of the TxCard. |
panelBackground | 'pure' | 'mask' | 'blur' | 'glass' | 'refraction' | 'refraction' | Panel background. |
panelShadow | 'none' | 'soft' | 'medium' | 'soft' | Panel shadow. |
panelRadius | number | 18 | Panel corner radius in px. |
panelPadding | number | 10 | Panel padding in px. |
panelCard | BaseAnchorPanelCardProps | undefined | Advanced TxCard props, such as maskOpacity or refraction*. |
surfaceMotionAdaptation | 'auto' | 'manual' | 'off' | 'auto' | Surface downgrade while moving: auto follows the animation, manual reads panelCard.surfaceMoving, off never downgrades. |
showArrow | boolean | false | Shows an arrow that follows the placement. |
arrowSize | number | 10 | Arrow size in px. |
keepAliveContent | boolean | false | Keeps content mounted after close, with its state. |
closeOnClickOutside | boolean | true | Closes on an outside click. |
closeOnEsc | boolean | true | Closes on Escape. |
toggleOnReferenceClick | boolean | true | Toggles on reference click; turn it off for references that handle their own clicks. |
hoverBridge | boolean | false | While open, fills the gap to the reference with an invisible hit area; TxTooltip enables it when needed. |
Events
| Event | Params | Description |
|---|---|---|
open | - | Fires when the panel opens. |
close | - | Fires when the panel closes. |
update:modelValue | boolean | Fires when the open state changes. |
floating-enter | MouseEvent | The pointer entered the floating layer: the panel or the hover bridge. |
floating-leave | MouseEvent | The pointer left the floating layer. |
Slots
| Slot | Description |
|---|---|
reference | The trigger element. |
default | Panel content; receives the final side as { side }. |
Exposed Methods
| Method | Params | Description |
|---|---|---|
close | - | Closes the panel. |
toggle | - | Toggles the panel. |
updatePosition | - | Recomputes the position. |
getPanelRect | - | The panel's rect as drawn (DOMRect), or null before it mounts. |
containsFloating | (target: Node) | Whether target is inside the floating layer, hover bridge included. |
getSide | - | The final side: top, right, bottom, or left. |
Types
BaseAnchorAnimationOptions
| Field | Type | Default | Description |
|---|---|---|---|
type | 'expand' | 'transfer' | 'boom' | 'opacity' | 'none' | 'drip' | 'bead' | 'expand' | expand springs open, transfer slides along the side, boom scales out of a blur, opacity fades, none is instant; drip / bead are liquid. |
closeType | Same values as type | Same as type | Type used while closing. Liquid types must match at both ends; a mixed pair falls back to symmetric and warns in dev. |
duration | number | per type (expand 400 / classic 432 / liquid 260) | Open duration in ms. |
closeDuration | number | per close type (expand 240 / classic: open duration × 0.45 / liquid 150) | Close duration in ms. |
ease | string | per type (expand: a spring solved for the panel's height, spring(10, 0.6) up to about 63px / classic back.out(2) / liquid linear) | Open ease: a GSAP ease, cubic-bezier(...), or spring(omega, zeta), run as written; liquid types take only linear or cubic-bezier(...). |
closeEase | string | per close type (expand power2.in / classic power3.in / liquid cubic-bezier(0.25, 0.46, 0.45, 0.94)) | Close ease; same forms as ease. |
distance | number | per type (expand 12 / transfer 30) | expand drift and transfer travel in px. |
scale | number | per type (expand 0.88 / boom 0.94 / transfer 0.92) | Starting scale of the open. |
blur | number | 12 | Starting blur radius of boom in px. |
opacity | number | 0 | Starting opacity of expand, boom, and opacity. |
exit | { scale?, distance?, blur?, opacity? } | See description | Close-only geometry; each field falls back to the shared field of the same name, then to closeType's default. |
gooBlur | number | 4.5 | drip / bead only. Goo blur radius; decides how wide a gap the neck survives. |
gooThreshold | number | 20 | drip / bead only. Slope of the alpha threshold. |
gooThresholdOffset | number | -9 | drip / bead only. Offset of the alpha threshold. |
outlineColor | string | --tx-border-color | drip / bead only. Outline ring color; follows the theme by default. |
triggerRadius | number | measured | drip / bead only. Trigger corner radius; measured from the reference when omitted. |
seedHeight | number | 12 | drip / bead only. Panel height at the start, in px. |
itemSelector | string | '[data-liquid-item]' | drip / bead only. Items revealed one by one; with no match, the content reveals as a whole. |
beadPinch | number | 60 | bead only. Peak pinch per side in px; decays to 0 as the motion settles. |
beadVelocityRef | number | 4 | bead only. Speed at which the pinch peaks. |
Overview
- With
modelValueit is controlled; otherwise it keeps its own open state. Each change emitsopenorclose. maxHeightshrinks to the space left in the viewport; overflow scrolls inside the card body, so read the scroll position from the body.- The anchor family draws no arrow by default: BaseAnchor, Tooltip, Popover, and the DropdownMenu, ContextMenu, and Select built on them. A
showArrowarrow moves with the panel's content layer. drip/beadwork on vertical placements only; side placements fall back toopacity. They need a measurable height, sounlimitedHeightshows and hides instantly.drip/beadpaint their own surface: noTxCardand no arrow, so panel background, shadow, and variant do not apply. The trigger needs an opaque background.- Under reduced motion, every animation jumps to its end state.
Technologies
- The panel is teleported to
<body>and positioned by Floating UI in document coordinates; GSAP drives the classic types and a rAF loop drivesdrip/bead. - Source:
packages/tuffex/packages/components/src/base-anchor/.