Components/FlatDropdown

FlatDropdown

A floating dropdown panel whose trigger and content come from slots.

Since 0.3.9BETA

This page was migrated by AI, please review carefully

Migration is complete, but please validate against source code and manual review.

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 closeDelay for it.
  • Set teleport="false" when the panel must inherit its container's stacking or clipping context; inline, it is clipped by ancestor overflow: hidden.
  • When the panel flips to the other side of the trigger, use the side slot 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

PropTypeDefaultDescription
modelValuebooleanundefinedOpen state (v-model); omit it to leave the panel uncontrolled.
trigger'hover' | 'click' | 'manual''hover'How the panel is summoned.
placementPlacement'bottom-start'Floating placement relative to the trigger.
offsetnumber10Gap between trigger and panel, in px.
openDelaynumber0Delay before opening on hover or focus, in ms.
closeDelaynumber600Delay before closing after the pointer leaves, in ms.
exitDurationnumber280Duration of the scale + blur exit animation, in ms.
disabledbooleanfalseDisables every interaction.
teleportboolean | string'body'Teleport target; false renders inline.
matchTriggerWidthbooleanfalseMatches the panel's min-width to the trigger width.
widthnumber | stringundefinedFixed panel width, as px or any CSS length; overrides matchTriggerWidth.
closeOnClickOutsidebooleantrueCloses on a click outside the trigger, panel, and hover bridge; ignored under manual.
closeOnEscbooleantrueCloses on Escape.
closeOnContentClickbooleanfalseCloses after any click inside the panel.
panelClassTxFlatDropdownClassundefinedExtra classes merged onto the panel element.

Events

EventPayloadDescription
update:modelValuebooleanFires when the open state changes.
open—Fires when the panel opens.
close—Fires when the panel closes.

Slots

SlotPropsDescription
trigger{ open, toggle, show, hide }The anchor element.
default{ open, close, side }Panel body; side is the resolved side after flip.

Overview

  • hover opens on pointer enter or focus and closes after closeDelay. click toggles on click without closeDelay. manual never opens by itself; v-model drives 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; closeDelay starts 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 / close still fire.
  • disabled blocks every opening path, including the trigger slot's show().
  • 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 an aria-controls that 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/.