import { Renderable, TNode, Value, Prop } from '@tempots/dom'; import { Placement } from '@tempots/ui'; /** * Built-in trigger modes that control how the {@link Flyout} is shown. * * - `'hover'` - Shows on mouse enter, hides on mouse leave. * - `'focus'` - Shows on focus, hides on blur. * - `'hover-focus'` - Combines both hover and focus triggers. * - `'click'` - Shows on click, hides on clicking outside. * - `'never'` - Never shows automatically; must be controlled programmatically via a custom trigger function. */ export type FlyoutTrigger = 'hover' | 'focus' | 'hover-focus' | 'click' | 'never'; /** * Custom trigger function for the {@link Flyout} component. * Receives the open state signal and returns trigger content that controls * when the flyout appears and disappears. * * @param open - Writable signal representing the flyout's open state. Set to `true` to show, `false` to hide. * @returns A renderable node containing the trigger logic */ export type FlyoutTriggerFunction = (open: Prop) => TNode; /** * Positioning data for a popover arrow element, provided by the PopOver positioning engine. */ export interface PopOverArrowOptions { /** The computed placement of the popover (e.g., `'top'`, `'bottom-start'`). */ placement: string; /** Horizontal offset of the arrow in pixels relative to the popover container. */ x?: number; /** Vertical offset of the arrow in pixels relative to the popover container. */ y?: number; /** Offset from the center of the reference element, used for arrow alignment. */ centerOffset: number; /** Width of the popover container in pixels. */ containerWidth: number; /** Height of the popover container in pixels. */ containerHeight: number; } /** * Configuration options for the {@link Flyout} component. */ export interface FlyoutOptions { /** * Factory function that returns the flyout content to display. * Called lazily when the flyout opens. */ content: () => TNode; /** * Placement of the flyout relative to the trigger element. * Uses the Floating UI placement model (e.g., `'top'`, `'bottom-start'`, `'right-end'`). * @default 'top' */ placement?: Value; /** * Delay in milliseconds before showing the flyout after trigger activation. * @default 250 */ showDelay?: Value; /** * Delay in milliseconds before hiding the flyout after trigger deactivation. * @default 500 */ hideDelay?: Value; /** * Offset in pixels from the main axis (vertical for top/bottom placements, * horizontal for left/right placements). * @default 8 */ mainAxisOffset?: Value; /** * Offset in pixels from the cross axis (horizontal for top/bottom placements, * vertical for left/right placements). * @default 0 */ crossAxisOffset?: Value; /** * How the flyout is triggered to show and hide. Accepts a built-in {@link FlyoutTrigger} * string or a custom {@link FlyoutTriggerFunction} for programmatic control. * @default 'hover-focus' */ showOn?: Value | FlyoutTriggerFunction; /** * Whether the flyout can be closed with the Escape key or by clicking outside. * @default true */ closable?: Value; /** * Optional arrow renderer. Receives a signal with {@link PopOverArrowOptions} positioning * data and returns a TNode to render as the arrow element. */ arrow?: (signal: any) => TNode; /** * ARIA role attribute applied to the flyout container. * @default 'dialog' */ role?: Value; /** * Value for the `aria-haspopup` attribute on the trigger element. * Indicates the type of popup that the trigger controls. * @default 'dialog' */ hasPopup?: Value; /** * External signal controlling the flyout's open/closed state. * When provided, this signal becomes the single source of truth: * - Setting it to `true` opens the flyout (respecting `showDelay`) * - Setting it to `false` closes the flyout (respecting `hideDelay`) * - Internal close paths (click-outside, Escape) set this signal to `false` * - Built-in and custom triggers toggle this signal * * When omitted, the flyout manages its own internal open state. */ open?: Prop; } /** * Flexible popover component with configurable trigger modes, animated transitions, * and accessibility support. * * Unlike wrapper-based flyout libraries, this component is designed to be rendered as a * **child** of the trigger element. It attaches event listeners to the parent element * and manages the popover lifecycle (show/hide with delays, animation, keyboard dismissal). * * This is the base component that powers {@link Tooltip}, {@link Menu}, and other * positioned overlay components. * * Uses `@tempots/ui` PopOver for Floating UI-based positioning. * * @param options - Configuration options controlling content, placement, triggers, delays, and accessibility * @returns A renderable node to be placed inside the trigger element * * @example * ```typescript * // Hover-triggered flyout * html.button( * 'Hover me', * Flyout({ * content: () => html.div('Flyout content'), * placement: 'bottom', * showOn: 'hover', * showDelay: 200, * hideDelay: 300, * }) * ) * ``` * * @example * ```typescript * // Click-triggered flyout with custom trigger function * html.button( * 'Click me', * Flyout({ * content: () => html.div('Custom content'), * showOn: (show, hide) => on.click(() => show()), * }) * ) * ``` */ export declare function Flyout(options: FlyoutOptions): Renderable;