import{type PropertyValues,type TemplateResult}from'lit';import type{Placement}from'@floating-ui/dom';import{LyraElement}from'../../../internal/lyra-element.js';import type{PlaceStrategy}from'../../../internal/positioner.js';import{type LyraArrowPlacement}from'./overlay-arrow.js';import{type OverlayVirtualRect}from'./overlay-shared.js'; /** One keyword of the space-separated `trigger` list. */ export type LyraTooltipTrigger='hover'|'focus'|'click'|'manual';export type{LyraArrowPlacement,OverlayVirtualRect,PlaceStrategy};export interface LyraTooltipEventMap{'lr-show':CustomEvent;'lr-after-show':CustomEvent;'lr-hide':CustomEvent;'lr-after-hide':CustomEvent;} /** * `` — a localized tooltip for a consumer-owned trigger. It accepts both mapped * light-DOM shapes without ambiguity: a Web Awesome-style named `trigger` plus default content, * or a Shoelace-style default trigger plus `content`/`slot="content"` content. * Plain content uses tooltip semantics. When the active content slot contains an actionable descendant * (including native controls, authored sequential focus stops, explicit ARIA widgets, and controls * inside a nested custom element's open shadow root), the popup promotes to a named * dialog and remains open while pointer or focus is inside so its controls can be reached. Escape * from popup content closes it and restores focus to the trigger. Prefer `` when * click-to-open ownership is desired. * Forwarding slots are followed through their live composed assignments: reassignment, descendant * text/actionability changes, and restoration of a forwarding slot's fallback all update the * description and popup role. Image alternatives and bounded, cycle-safe `aria-labelledby` * traversal participate too; referenced roots are observed for text and identity changes even * when a target is external or not yet present. A host `aria-label` wins by attribute presence, so * an explicit empty label suppresses both derived content text and the localized actionable-popup * fallback. * * Interaction/ARIA ownership is independent of positioning. A slotted trigger wins; without one, * a live HTML element resolved by `for` receives the configured interaction listeners and * `aria-describedby`. A direct `.anchor` is positioning-only. `showAt()`'s virtual anchor wins * positioning and deliberately has no DOM interaction/ARIA owner while active. Losing the sole * live positioning anchor force-closes the tooltip, while a remaining slotted/`for` fallback is * rebound and keeps the tooltip open. * * `trigger` is a space-separated list of `hover`, `focus`, `click` and `manual`, defaulting to * `"hover focus"`. `manual` (in the list, or the standalone `manual` boolean) means only * `show()`/`hide()`/`open` move it. `show-delay` and `hide-delay` are independent, so a tooltip * can linger after the pointer leaves without also being slow to appear. * Motion resolves through `tooltip.show`/`tooltip.hide` in the public animation registry. * Content/trigger observers and delayed transitions bind to the current owner window; disconnect * and cross-document adoption cancel the old realm before reconnect creates replacements. * * While open, the trigger's `aria-describedby` targets a hidden text proxy in this component's * light DOM rather than the shadow-private popup. Native triggers can resolve that ID directly. * A description is only announced on the node that actually holds focus, so a custom-element * trigger also has the proxy applied to its first focusable descendant (through slots and nested * open shadow roots) — reaching ``, ``, `` and consumer-authored * wrappers, not only the components that forward their own host `aria-describedby`. Descendants * inside a shadow root are linked through `ariaDescribedByElements`, where the serialized internal * attribute is intentionally empty; descriptions the control already had are kept and restored. * Bubbling `focusin`/`focusout` observes those real composed targets, and moving focus within the * trigger or between interactive popup controls does not spuriously close the tooltip. * * Open popovers, dropdowns and tooltips reposition when their effective host or inherited text direction changes, preserving open state and lifecycle events. Removing content safely omits tooltip fallback text. * * @customElement lr-tooltip * @slot trigger - Web Awesome shape: the highest-priority interaction/ARIA owner. * @slot - Web Awesome shape: tooltip content; Shoelace shape: the trigger when no named trigger * is present. * @slot content - Shoelace shape: tooltip content when the default slot owns the trigger. * @event lr-show - The tooltip is about to open. Cancelable — `preventDefault()` keeps it closed. * @event lr-after-show - The tooltip is open and its transition has finished. * @event lr-hide - The tooltip is about to close. Cancelable — `preventDefault()` keeps it open. * @event lr-after-hide - The tooltip is closed and its transition has finished. * @method show - `show(): Promise` — open immediately and settle after `lr-after-show`. * @method hide - `hide(): Promise` — close immediately and settle after `lr-after-hide`. * @csspart trigger - The trigger wrapper. * @csspart base - Compatibility name for the tooltip popup wrapper; it is the same node as * `tooltip`. * @csspart tooltip - The tooltip popup wrapper. It is the same node as `base`. * @csspart popup - The tooltip popup. It is the same node as `base` and `tooltip`. * @csspart base__popup - Shoelace exported popup alias on the same node. * @csspart body - Tooltip content wrapper. * @csspart arrow - The arrow element, rendered only when `arrow` is set. Its part name also * carries the resolved side (`arrow-top`, `arrow-bottom`, `arrow-left`, `arrow-right`). * @csspart base__arrow - Shoelace exported alias on the arrow. * @cssprop [--max-width=var(--lr-tooltip-max-inline-size,var(--lr-size-20rem))] - Maximum inline * size of the tooltip. * @cssprop --lr-tooltip-max-inline-size - Retained Lyra fallback for `--max-width`. * @cssprop --lr-tooltip-background - Tooltip background color (default `--lr-color-neutral`). * @cssprop --lr-tooltip-color - Tooltip text color (default `--lr-color-on-neutral`). * @cssprop [--arrow-size=var(--lr-tooltip-arrow-size,var(--lr-size-0-375rem))] - Half-width of the * arrow square. * @cssprop --lr-tooltip-arrow-size - Retained Lyra fallback for `--arrow-size`. * @cssprop [--show-delay=150ms] - Interaction show delay when `show-delay` is not explicit. * @cssprop [--hide-delay=0ms] - Interaction hide delay when `hide-delay` is not explicit. * @cssprop --lr-overlay-surface - Shared floating-surface fill. Advertised here because this tag's * rules live in the stylesheet module `lr-popover` also composes; a tooltip bubble is a * high-contrast label, not a panel, so it paints from `--lr-tooltip-background` and is * deliberately outside the overlay-surface family. * @cssprop --lr-overlay-border - Shared floating-surface edge colour. Same deliberate exclusion as * `--lr-overlay-surface` above: the bubble draws no border. * @cssprop --lr-overlay-radius - Shared floating-surface corner radius. Same deliberate exclusion: * the bubble keeps the tighter `--lr-radius-xs` a label-sized box reads best with. * @cssprop --lr-positioning-strategy - Cascading `absolute`/`fixed` override for * {@link positioningStrategy}/`hoist`, read from computed style when the bubble is * (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every * unset tooltip beneath it instead of authoring `positioning-strategy`/`hoist` on each instance; * an explicit value on the instance always wins over it. * @status stable * @since 4.0.0 */ export declare class LyraTooltip extends LyraElement{static styles:import("lit").CSSResultGroup[];private _open; /** Whether the tooltip is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle; * assigning `false` also cancels a delayed open that has not fired yet. * @default false */ get open():boolean;set open(next:boolean); /** * Space-separated interaction list: any of `hover`, `focus`, `click`, `manual`. `manual` (or an * empty list) leaves the tooltip entirely under programmatic control. */ trigger:string; /** Equivalent to including `manual` in `trigger`; kept because it reads better as a boolean * attribute on a tooltip that is only ever driven from script. */ manual:boolean; /** Delay (ms) before an interaction opens the tooltip. NaN/negative/oversized all normalize * through `finiteDuration`. */ showDelay:number; /** Delay (ms) before an interaction closes the tooltip again. `0` by default, so leaving the * trigger closes it at once. */ hideDelay:number;placement:Placement; /** Anchor-offset distance (px) passed to Floating UI's `offset()` middleware -- identical * semantics to `.distance` (can legitimately be negative for overlap). */ distance:number; /** Offset along the anchor's edge, in pixels — Floating UI's cross-axis offset. */ skidding:number; /** * Id of an element elsewhere in this tooltip's own root. It participates in positioning behind * a direct `.anchor`; when it resolves to a live HTML element and no trigger is slotted, that * element also owns the configured interactions and `aria-describedby`. A slotted trigger wins * interaction ownership, while `showAt()` wins positioning and suppresses every DOM owner. */ private _for;get for():string;set for(next:string|null); /** Positioning-only element anchor. Takes precedence over `for` and the interaction owner, but * never receives interaction listeners or generated ARIA. */ anchor:Element|null; /** Prevents interaction/programmatic opening and closes an open tooltip. */ disabled:boolean;private _positioningStrategy?; /** * CSS positioning scheme the popup is laid out with -- the same property, spelled the same way, * as on ``, `` and ``. `absolute` (this component's mirrored * default) positions against the nearest containing block and scrolls with it; `fixed` positions * against the viewport and escapes most clipping ancestors. An unsupported value resolves back * to the default. Changes apply live while open. * This property reports only the instance's own authored value (or the mirrored default); the * popup is actually placed with the `--lr-positioning-strategy` cascading custom property * honored ahead of that default when the instance itself sets nothing -- see that `@cssprop`. * @default 'absolute' */ get positioningStrategy():PlaceStrategy;set positioningStrategy(next:PlaceStrategy); /** * Retained boolean alias of {@link positioningStrategy}: `hoist` is exactly * `positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two * attributes can never disagree in the DOM. It is this component's established name (and * Shoelace's own spelling on `sl-tooltip`), so it keeps working indefinitely; prefer * `positioning-strategy` in new code, which reads the same on every anchored surface. * @default false */ get hoist():boolean;set hoist(next:boolean); /** Render an arrow that points at the anchor. Defaults on for mapped tooltip markup. */ arrow:boolean; /** Positive mapped spelling for suppressing the default arrow. */ withoutArrow:boolean; /** Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre. */ arrowPlacement:LyraArrowPlacement; /** Keeps the arrow this far from the popup's corners, in pixels. */ arrowPadding:number;content:string;accessibleLabel:string;private triggerElement?;private slottedTriggerElement?; /** True when the default slot is tooltip content (WA mode). False only when an explicit * Shoelace content source makes the default slot unambiguously the trigger. */ private namedTriggerMode;private interactiveContent;private resolvedSide;private anchorPositioned;private positionedAnchor?;private positioningDirection?;private directionChanged;private observedDirectAnchor?;private observedDirectAnchorWasConnected;private stopAnchorIdentityObservation?;private triggerAria?;private accessibleTriggerAria?; /** The virtual anchor set by `showAt()`, taking priority over `for`/`trigger` for positioning * while set. Cleared whenever the tooltip closes, so a later `open = true` with no fresh * `showAt()` call reverts to plain trigger-based behavior. */ private virtualAnchor?; /** `options.returnFocusTo` from the `showAt()` call that opened the tooltip, if any -- see * `showAt()`'s doc comment and `activateTooltipOverlay()`'s `onEscape` callback. */ private returnFocusTo?;private cleanup?; /** True only while the deferred runtime intentionally conceals an otherwise-open popup. */ private placementPending;private timer?;private timerView?;private pendingDirection?;private restoreFocusOnClose; /** Focus restoration after Escape is synchronous. Suppress only that focus event so returning * to the trigger does not immediately reopen the tooltip; a later genuine focus still opens. */ private suppressTriggerFocusOpen; /** True while the current open state was driven by the pointer (a `mouseenter` on the trigger) * rather than by focus, click, or `manual`. Only a pointer-held tooltip has to be re-derived * when the trigger element is swapped out from under it -- see `adoptTrigger`. */ private openedByPointer; /** Registered with the shared overlay manager while a virtual-anchor or actionable tooltip is * open, so Escape ownership and focus return remain topmost-stack-aware. */ private overlayHandle?;private readonly tooltipId;private readonly descriptionId;private descriptionProxy?;private contentObserver?;private triggerSyncGeneration;private stopLabelReferenceIdentityObservation?;private readonly contentSlotListeners; /** While an open tooltip contains a rootless custom element, rescan for a bounded initialization * grace period. Later observable content mutations start a fresh grace period. */ private shadowContentScanFrame?;private shadowContentScanView?;private shadowContentScanAttempts; /** Invalidates an in-flight `lr-after-*` wait when the opposite transition interrupts it. */ private transitionToken;private transitionAnimation?;private readonly transitionGate;private get rendersArrow();private get activeContentSlot();private syncNamedTriggerMode; /** The resolved interaction keywords. An empty list behaves like `manual`. */ private get triggerKeywords();private get isManual();private opensOn;protected willUpdate(changed:PropertyValues):void;protected updated(changed:PropertyValues):void;connectedCallback():void;disconnectedCallback():void;adoptedCallback():void;private syncAnchorIdentityObservation;private resolveForTrigger;private syncInteractionTrigger; /** Registers a virtual-anchor or actionable tooltip with the shared overlay manager * (`internal/overlay-manager.ts`) so Escape is routed only to the topmost overlay in the stack, * instead of every open virtual-anchor popover/tooltip reacting to its own unscoped * `document`-level keydown listener. Non-modal and non-focus-trapping: a virtual anchor has no * DOM node to own focus, so background inerting and Tab trapping (both opt-in via `modal`/ * `trapFocus`) would be meaningless here -- only Escape ownership is needed. */ private activateTooltipOverlay;private shouldRestoreFocusAfterEscape;private get requiresOverlayManager(); /** * Opens the tooltip anchored to an arbitrary rectangle instead of any DOM anchor -- for * anchoring to a graph node, a canvas pixel, a chart datum, or any other non-DOM location. * `width`/`height` default to `0` (a point). Positions exactly as `place()` would against a real * element (flip/shift/RTL all apply unchanged). Opens immediately, bypassing `show-delay` and * `trigger` (both are interaction-debounce concerns for a DOM trigger, not relevant to a * deliberate programmatic `showAt()` call). * * A virtual anchor has no DOM node, so `autoUpdate()` can't track it moving on its own -- call * `showAt()` again with fresh coordinates to re-anchor an already-open tooltip (e.g. on a graph * pan/zoom tick); the tooltip stays open across such a call, it does not toggle. Close it with * `hide()` or `open = false`. Pass `rect.contextElement` (a real, still-connected element near * the virtual point) when available so `autoUpdate()` has something to observe for * ancestor-scroll/resize tracking; omitting it still works, it just means only explicit * re-`showAt()` calls keep the tooltip anchored. * * While the virtual anchor is active, no slotted/`for` element owns interactions or generated * ARIA. A virtual anchor also has no `.focus()`. Escape returns focus to * `options.returnFocusTo` when * supplied, or skips focus-return entirely otherwise -- refocusing the right place after a * virtual anchor closes is the host's responsibility, since Lyra can't assume how e.g. a graph * node's own keyboard model wants focus back. * Non-finite coordinates or dimensions are ignored and leave the current open/anchor state * unchanged. */ showAt(rect:OverlayVirtualRect,options?:{returnFocusTo?:HTMLElement;}):void; /** Open immediately, bypassing `show-delay` and whatever `trigger` allows. Emits `lr-show` * first — vetoing it leaves the tooltip closed — then `lr-after-show`. */ show():Promise; /** Close immediately, bypassing `hide-delay`. Emits `lr-hide` first — vetoing it leaves the * tooltip open — then `lr-after-hide`. `restoreFocus` is used by the Escape path, which has to * put focus back on the trigger it took it from. */ hide(options?:{restoreFocus?:boolean;}):Promise; /** Structural teardown cannot be vetoed: no open tooltip may remain after its final live * positioning anchor disappears. */ private forceClose;private applyOpenState; /** A vetoed transition must leave the reflected attribute agreeing with the property; Lit only * reflects properties it saw change. */ private syncOpenAttribute;private cancelTransitionAnimation; /** Resolves once the registry-backed popup animation has finished, then emits the matching * `lr-after-*` event. A disabled registration retains the lifecycle without native motion. */ private settleTransition; /** Resolves what the popup is positioned against: an explicit virtual anchor first, then the * direct `anchor`, then the `for` idref, then the slotted trigger. Shared with ``, * which resolves the identical chain. */ private resolveAnchor;private position;private syncTriggerA11y;private get accessibleTrigger();private releaseTriggerA11y; /** Runs `show()`/`hide()` after the matching delay, replacing whatever was pending. */ private requestTransition;private interactionDelay;private cancelPendingTransition;private bindTrigger;private unbindTrigger; /** Whether `trigger` is currently held open by a real user interaction -- the pointer resting * over it, or focus sitting inside it. `:hover` is the browser's own post-layout hover state, * which is exactly the question being asked ("is the pointer over THIS node") and needs no * pointer-coordinate bookkeeping of our own. Both are wrapped because a detached or * not-yet-laid-out node can throw on `matches()` in some engines. */ private isTriggerHeld;private adoptTrigger;private onTriggerSlotChange;private onEnter;private onLeave;private onTriggerClick;private onPopupEnter;private onPopupLeave;private isPopupTarget;private onContentSlotChange;private clearContentSlotListeners;private syncContentSlotListeners;private inspectContent;private observeContentNode;private bindContentObservation;private updateInteractiveContent;private scheduleShadowContentScan;private cancelShadowContentScan;private ensureDescriptionProxy;private updateDescriptionProxy;private onTriggerKeyDown;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-tooltip':LyraTooltip;}}