FlatDropdown
A floating dropdown panel whose trigger and content come from slots.
Usage
Basic
Hovering the trigger opens the panel; close-on-content-click dismisses it after any click inside.
Loading demo...
Best Practices
- Use
trigger="click"for destructive or state-changing menus; hover-opened panels are easy to trip on a trackpad. - The hover bridge and safe triangle handle diagonal travel into the panel, so don't raise
closeDelayfor it. - Set
teleport="false"when the panel must inherit its container's stacking or clipping context; inline, it is clipped by ancestoroverflow: hidden. - When the panel flips to the other side of the trigger, use the
sideslot prop to flip your own decorations, such as arrows and shadows. - Placement is written back asynchronously after opening; measure absolute geometry in a
requestAnimationFrame.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | undefined | Open state (v-model); omit it to leave the panel uncontrolled. |
trigger | 'hover' | 'click' | 'manual' | 'hover' | How the panel is summoned. |
placement | Placement | 'bottom-start' | Floating placement relative to the trigger. |
offset | number | 10 | Gap between trigger and panel, in px. |
openDelay | number | 0 | Delay before opening on hover or focus, in ms. |
closeDelay | number | 600 | Delay before closing after the pointer leaves, in ms. |
exitDuration | number | 280 | Duration of the scale + blur exit animation, in ms. |
disabled | boolean | false | Disables every interaction. |
teleport | boolean | string | 'body' | Teleport target; false renders inline. |
matchTriggerWidth | boolean | false | Matches the panel's min-width to the trigger width. |
width | number | string | undefined | Fixed panel width, as px or any CSS length; overrides matchTriggerWidth. |
closeOnClickOutside | boolean | true | Closes on a click outside the trigger, panel, and hover bridge; ignored under manual. |
closeOnEsc | boolean | true | Closes on Escape. |
closeOnContentClick | boolean | false | Closes after any click inside the panel. |
panelClass | TxFlatDropdownClass | undefined | Extra classes merged onto the panel element. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | boolean | Fires when the open state changes. |
open | — | Fires when the panel opens. |
close | — | Fires when the panel closes. |
Slots
| Slot | Props | Description |
|---|---|---|
trigger | { open, toggle, show, hide } | The anchor element. |
default | { open, close, side } | Panel body; side is the resolved side after flip. |
Overview
hoveropens on pointer enter or focus and closes aftercloseDelay.clicktoggles on click withoutcloseDelay.manualnever opens by itself;v-modeldrives it, for panels that follow app state, such as a shortcut.- A hover bridge covers the gap between trigger and panel. The safe triangle keeps the panel open while the pointer heads for it;
closeDelaystarts only when the pointer strays, stops, or leaves away from the panel. - Without
v-model, the component tracks its own open state. With it, the host writes the value back;open/closestill fire. disabledblocks every opening path, including the trigger slot'sshow().- Outside click, Escape, and content click are independent dismissal paths; under
manual, an outside click does not close. - The trigger wrapper carries
aria-haspopup,aria-expanded, and anaria-controlsthat points at the panel's id.
Technologies
- The hover bridge and safe triangle come from
packages/tuffex/packages/utils/hover-intent.ts, shared with the anchor family. The last Floating UI middleware computes the bridge, which renders as the panel's sibling. - Source:
packages/tuffex/packages/components/src/flat-dropdown/.