import{type TemplateResult,type PropertyValues}from'lit';import type{Placement}from'@floating-ui/dom';import{LyraElement}from'../../../internal/lyra-element.js'; /** * Resolves the element a step spotlights/anchors to. A `string` is resolved via * `this.ownerDocument.querySelector(target)` (top-level light DOM only -- CSS * selectors can't pierce a closed shadow root); pass a direct `HTMLElement` or a resolver * function for anything else (inside a shadow root, not yet mounted, computed dynamically). * Resolved exactly once whenever this step becomes active, then retained as one connected * snapshot for that activation so rendering, focus routing, positioning, and the spotlight all * agree on the same element. It resolves again on a later activation/reconnect, so a target that * mounts later can still be found when its step is reached. Invalid selectors, throwing * resolvers, non-`HTMLElement` results, and detached elements all follow the documented * target-missing path instead of rejecting the component update. */ export type LyraTourTarget=string|HTMLElement|(()=>HTMLElement|null);export interface LyraTourStep{ /** Stable business id for this step, never shown to the user. Collection occurrences remain * unambiguous through the public `index`/`activeIndex` contract even when ids repeat. A step * object still carrying the pre-rename `id` field (this property's former name) is accepted as * a fallback when `stepId` itself is absent -- see `snapshotTourSteps()`. */ readonly stepId:string; /** The element this step spotlights and anchors its popover to. */ readonly target:LyraTourTarget; /** Visible step heading -- becomes the popover panel's accessible name via `aria-labelledby`. * Plain text; not localized by this component (caller-supplied data, per the library's i18n * exception for app content). A blank/whitespace heading is tolerated defensively and falls * back to the localized step-progress text for the dialog name. */ readonly heading:string; /** Visible step body copy. Rendered as plain text (Lit auto-escapes -- no HTML/markdown * parsing). Ignored for the currently active step if the default slot carries real content * (see the class doc's Slots section) -- the slot wins when both are present. */ readonly content?:string; /** Per-step Floating UI placement override. Falls back to the tour-level `placement` prop * (`'bottom'`) when omitted. Resolved through `rtlAwarePlacement()` before being passed to * `place()`, same as `lr-menu`/`lr-popover`. */ readonly placement?:Placement; /** Per-step override of the tour-level `spotlightPadding` prop (`4`). Extra px between the * target's own box and the spotlight cutout/ring. `distance` (the offset between the target * and the popover itself) is a tour-level-only setting -- it has no per-step override. */ readonly spotlightPadding?:number; /** Opts this step's target OUT of the tour's default non-interactive-spotlight behavior -- * see the class doc's "Target interactivity" section. Defaults to `false`. */ readonly interactiveTarget?:boolean; /** Hides the Previous control outright (not just disables it) for this step -- e.g. a step * reached only via a side effect that can't be cleanly reversed. Defaults to `false`; compare * with the first step, whose Previous control is disabled-but-visible instead, for a stable * footer layout across steps. */ readonly hidePrevious?:boolean;} /** * Reason a tour ended, forwarded as the `lr-tour-end` event detail. * `'completed'`/`'skip'`/`'escape'` are emitted by the tour's own built-in dismiss triggers; * `'unmount'` is emitted when the tour is removed from the DOM while still open by something * other than its own `end()` (mirrors `lr-dialog`'s identical `'unmount'` case); any other * string is whatever a caller passes to `end()` directly. */ export type LyraTourEndReason='completed'|'skip'|'escape'|'api'|'unmount'|(string&Record);export interface LyraTourEventMap{'lr-tour-start':CustomEvent<{readonly index:number;}>;'lr-tour-step-change':CustomEvent<{readonly index:number;readonly previousIndex:number;readonly step:Readonly;readonly via:'next'|'back'|'goto';}>;'lr-tour-end':CustomEvent;'lr-tour-target-missing':CustomEvent<{readonly index:number;readonly step:Readonly;}>;} /** * `` -- a spotlight-and-step guided walkthrough for first-run onboarding. A sequence * of steps, each anchored to a target element elsewhere in the page via the shared Floating UI * positioner, shown against a dimmed full-viewport backdrop with a cutout/ring highlighting the * current target, with Next/Previous/Skip controls and a step-progress indicator. First-party * invention (no Web Awesome equivalent) -- nearest precedent in shape is `lr-dialog` (overlay * lifecycle/focus trap) + `lr-carousel` (index-based navigation) + `lr-stepper` * (progress/RTL arrow-key nav). * * **Not a form-associated control.** A tour is a walkthrough, not a field -- it deliberately has * no `label`/`hint`/`error` chrome and no `FormAssociated` mixin. * * **Controlled component.** `steps` is never mutated by this component (mirrors * `lr-stepper`'s `steps`); only `activeIndex` and `open` are self-managed, mirroring * `lr-carousel`'s `index`. * * **Target interactivity.** By default, the step's spotlighted target is non-interactive while * its step is active: it stays visually revealed but is outside the modal interaction model * and cannot be clicked -- every pointer event over the full * viewport, including directly over the visually-revealed target, is captured by the backdrop * (CSS `mask` does not affect hit-testing, only `clip-path` does) -- and cannot be reached by Tab * (the shared overlay focus trap confines Tab to the popover panel). Set `step.interactiveTarget` * to opt a step's target out of this: the backdrop additionally clips itself (via `clip-path`, * which *does* affect hit-testing) around the same rect, so pointer/click events fall through to * the live target underneath. The panel also becomes nonmodal and an explicit Tab route connects * its controls with the live target. * * **Focus management.** Default steps exclusively own interaction: the shared overlay manager * marks outside content inert, traps Tab, and the panel reports `aria-modal="true"`. * `interactiveTarget` steps instead use a nonmodal overlay, report `aria-modal="false"`, and * treat the panel plus the external target's live composed focusables as one bounded Tab scope. * * Each step transition mounts a genuinely new popover DOM node (keyed on occurrence index plus * the step's `stepId`) so duplicate business ids cannot collapse distinct occurrences and focus * reliably re-enters the panel every time, even though the Previous/Next button that triggered * the transition lives inside that same persistent-looking region. Every step-related event * exposes the occurrence index; it is the authoritative collection identity. * * No `Home`/`End` jump-to-first/last-step shortcut and no click-to-jump progress dots, unlike * `lr-stepper` -- a tour's steps are tied to live DOM targets that may not exist until an * earlier step's side effect (opening a menu, navigating a route) has run, so free jumping is * unsafe by default. `goToStep()` remains available for a host that knows what it's doing (e.g. * a "restart tour" affordance elsewhere). * * @customElement lr-tour * @slot - Rich content overriding the currently active step's plain-text `content` for that step * only. When real content is assigned, it's shown instead of `step.content`; when empty, * `step.content` renders as plain text. Not scoped per step by this component itself -- a * consumer that needs different rich content per step swaps the slotted children (or listens * for `lr-tour-step-change` and re-renders them) itself, the same "consumer owns slotted * content" pattern `lr-dialog`'s default slot already uses. * @event lr-tour-start - Fired by `start()`. `detail: { index }`. Not cancelable. * @event lr-tour-step-change - Fired by `next()`/`back()`/`goToStep()` before `activeIndex` * changes. `detail: { index, previousIndex, step, via }`. Cancelable -- a listener calling * `preventDefault()` leaves `activeIndex` unchanged, letting a tour gate advancement on a real * action (e.g. an onboarding step demonstrating "click this button" shouldn't let Next silently * skip past it). This is a deliberate departure from `lr-carousel`'s non-cancelable * `lr-slide-change`. * @event lr-tour-end - Fired by `end()` (and by `next()` on the last step, with reason * `'completed'`). `detail: LyraTourEndReason`. Conditionally cancelable: every ordinary end can be * vetoed, while `'unmount'` cannot because the element is already being removed -- mirrors * `lr-dialog`'s own `lr-close` exactly. * @event lr-tour-target-missing - The active step's `target` did not resolve to a connected * element. `detail: { index, step }`. Not cancelable -- informational. The tour does not * auto-end; it renders that step's popover unanchored (viewport-centered, no spotlight cutout) * instead of throwing. A host can listen and decide to `skip()`/`goToStep()` in response. * @csspart backdrop - The full-viewport dimmed scrim with the spotlight cutout, an inline ``. * `aria-hidden="true"`. * @csspart spotlight - The decorative highlight ring drawn around the current target's (padded) * rect. `pointer-events: none`, `aria-hidden="true"`. * @csspart popover - The step panel itself. `role="dialog"`. * @csspart heading - The step's visible heading text element -- the `aria-labelledby` target. * @csspart body - Wrapper around the step's content (slotted or `step.content`). * @csspart progress - Wrapper around the built-in step-progress indicator (dots + text). * @csspart progress-dot - An individual decorative dot within `progress`. `aria-hidden="true"`. * @csspart progress-text - The visible "Step X of Y" text -- one of the popover's * `aria-describedby` targets. * @csspart footer - Wrapper around the Previous/Skip/Next-or-Done control row. * @csspart skip-button - The Skip control. * @csspart previous-button - The Previous control. * @csspart next-button - The Next/Done control (label switches on the last step). * @cssprop --lr-tour-backdrop-color - Backdrop scrim fill. Defaults to `--lr-color-overlay`. * @cssprop --lr-tour-spotlight-radius - Corner radius shared by the cutout and the ring. * Defaults to `--lr-radius`. * @cssprop --lr-tour-spotlight-ring-color - Spotlight ring color. Defaults to `--lr-color-brand`. * @cssprop --lr-tour-spotlight-ring-width - Spotlight ring thickness. Defaults to * `--lr-border-width-medium`. * @cssprop --lr-tour-popover-max-width - Maximum popover inline size. Defaults to `--lr-size-22rem`. * @cssprop [--lr-tour-progress-dot-current-bg=var(--lr-color-brand)] - Background of * `progress-dot` for the current step, without repainting every other component that reuses the * shared brand token. * @cssprop --lr-positioning-strategy - Cascading `absolute`/`fixed` override for the step * popover's `fixed` default, read from computed style when a step is (re)positioned. Set it * once on `:root`, a theme, or one clipping ancestor to change every unset tour beneath it; an * unrecognized value falls back to `fixed`. * @status stable * @since 4.0.0 */ export declare class LyraTour extends LyraElement{static styles:import("lit").CSSResultGroup[];static properties:{steps:{attribute:boolean;noAccessor:boolean;};}; /** Whether the tour is open. Set this (or call `start()`/`end()`) -- there is no separate * `show()`/`hide()` pair. */ open:boolean;private _steps; /** Ordered step data. Assignment clone-normalizes at most 256 own-data records into a frozen * snapshot, omitting malformed/accessor rows and invalid optional fields, so later caller * mutation cannot silently change rendering or an emitted event. Empty (the default) renders * nothing. */ get steps():readonly Readonly[];set steps(next:readonly LyraTourStep[]); /** Index of the currently active step, clamped to `[0, steps.length - 1]` by `goToStep()` -- * and, for a direct property/attribute assignment that bypasses that method (e.g. two-way * binding an external store, or a bad `active-index` attribute), normalized the same way in * `willUpdate()` below. */ activeIndex:number; /** Tour-level default Floating UI placement, overridable per step via `LyraTourStep.placement`. */ placement:Placement; /** Distance (px) between the target and the popover, passed straight to Floating UI's * `offset()` middleware -- a tour-level-only setting, mirroring `lr-popover`'s `distance` * prop exactly (can legitimately be negative for overlap). */ distance:number; /** Tour-level default extra px between a target's own box and the spotlight cutout/ring, * overridable per step via `LyraTourStep.spotlightPadding`. Non-negative. */ spotlightPadding:number; /** Whether a backdrop click dismisses the tour (`end('skip')`). Defaults to `false`, matching * `lr-dialog`/`lr-lightbox`'s `lightDismiss`: a guided tour's backdrop click doing nothing by * default avoids losing onboarding progress to a stray click. Set it to opt in. */ lightDismiss:boolean; /** Whether the built-in "Step X of Y" progress indicator (dots + text) renders in the footer. */ showProgress:boolean; /** Host-level `aria-label` override for every step popover's accessible name -- wins over each * step's own `heading`, matching `lr-dialog`'s `accessibleLabel` pattern. Most consumers * won't need this since each step already has a meaningful name via `heading`; setting it * makes the *same* string name every step's panel. Set as a plain `aria-label` attribute on * `` itself, not a public JS property. An explicitly empty `aria-label=""` suppresses * the panel's accessible name outright rather than falling back to the heading or step count -- * again as `lr-dialog` does. */ private accessibleLabel;private unanchored;private hasSlotContent;private spotlightPositioned;private overlay?;private placeCleanup?;private spotlightCleanup?;private interactiveKeyboardTarget?;private interactiveKeyboardDocument?;private overlayInteractive?;private activeTargetSnapshot;private focusReturnTarget;private readonly maskId;private readonly headingId;private readonly bodyId;private readonly progressTextId;protected willUpdate(changed:PropertyValues):void;protected updated(changed:PropertyValues):void;connectedCallback():void;disconnectedCallback():void; /** Opens the tour at `index` (default `0`), clamped to `[0, steps.length - 1]`. Equivalent to * `this.activeIndex = index; this.open = true;` plus the `lr-tour-start` event. */ start(index?:number):void; /** Advances to the next step. On the last step, ends the tour instead (`end('completed')`) -- * the built-in Next/Done button calls this same method, so a custom control wired to `next()` * behaves identically to the built-in one. Cancelable via `lr-tour-step-change` (or * `lr-tour-end` when it triggers completion). */ next():void; /** Moves to the previous step. No-op on the first step (`activeIndex === 0`). */ back():void; /** Jumps directly to `index`, clamped to `[0, steps.length - 1]`. */ goToStep(index:number):void; /** Sugar for `end('skip')`. What the built-in Skip button calls. */ skip():void; /** Ends the tour. `reason` is forwarded as the `lr-tour-end` detail. Cancelable (except in * practice for `'unmount'`) -- mirrors `LyraDialog.close(reason)` exactly. */ end(reason?:LyraTourEndReason):void;private clampIndex;private transitionTo;private resolveTarget;private canPreserveInteractiveTargetFocus;private activateStep;private focusAfterPlacement;private paintSpotlight;private resetSpotlightGeometry;private disposePositioning;private activateOverlayInternal;private deactivateOverlayInternal;private onBackdropClick;private onDefaultSlotChange;private ownsDirectionalKeys;private onInteractiveScopeKeyDown;private onPopoverKeyDown;private formatProgressNumber;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-tour':LyraTour;}}