import type { IndicatorOptions, OverlayOptions, PopoverOptions } from "../types"; export interface TourElementStep { /** No target: the popover is centered and the backdrop has no cutout. */ readonly detached?: boolean; readonly indicator?: IndicatorOptions; readonly overlay?: OverlayOptions; readonly popover?: PopoverOptions; } export default abstract class GlowTourElement { protected element: HTMLElement | SVGSVGElement; options?: { duration?: number; easing?: string; disabled?: boolean; } | undefined; private readonly animations; /** * Animations that ran to completion and whose `fill: "forwards"` still applies. * * They keep overriding the element's inline styles, so a presentation that writes its state * without animating would be painted with the previous animation's last frame instead. */ private readonly filledAnimations; private readonly cancelledAnimations; private released; constructor(element: HTMLElement | SVGSVGElement, options?: { duration?: number; easing?: string; disabled?: boolean; } | undefined); setAnimationOptions(options: { duration?: number; easing?: string; disabled?: boolean; }): void; protected _getAnimationOptions(): KeyframeAnimationOptions; protected _isAnimated(): boolean; protected _startAnimation(keyframes: Keyframe[] | PropertyIndexedKeyframes, options?: KeyframeAnimationOptions, target?: Element): Animation | null; /** * The document driving `animation.finished`, when there is one. * * `Animation.timeline` is the document timeline, and a hidden document * freezes it — see {@link _finishWhileDocumentHidden}. */ private _getDocument; /** * Ends an animation that cannot progress, and keeps ending it for as long as * the document stays hidden. * * A hidden document freezes its timeline: `currentTime` stops advancing, the * animation stays `running` forever, and `animation.finished` never settles. * Awaiting it would strand the caller — a tour transition would never * complete, leaving the controller stuck in `transitioning`. Finishing the * animation resolves `finished` even on a frozen timeline, so the transition * lands on its final state immediately instead of hanging. * * @returns A cleanup function removing the visibility listener. */ private _finishWhileDocumentHidden; protected _waitForAnimation(animation: Animation): Promise; /** * Drops what finished animations still impose on the element. * * Every animation is followed by the inline styles that record the state it landed on, so * releasing the fill leaves the element exactly as it looks. Without this, a fade-out that * finished keeps forcing `opacity: 0` over the inline `opacity: 1` of the next presentation, * and an unanimated one never starts an animation of its own to take the fill over. */ protected _releaseFilledAnimations(): void; protected abstract _disappear(hideFromAssistiveTechnology?: boolean): Promise; protected abstract _getNextStyles(position: DOMRect, step: TourElementStep): Keyframe; abstract updatePosition(nextPosition: DOMRect, step: TourElementStep): void; abstract initializeProps(): void; getElement(): HTMLElement | SVGSVGElement | null; /** * Fades the element out. The popover stays exposed to assistive technology when passed `false`, * for a step change: its live region then announces the new step and focus stays in it. */ disappear(hideFromAssistiveTechnology?: boolean): Promise; release(): void; cancelAnimations(): void; protected _cancelAnimation(animation: Animation): void; protected abstract _release(): void; }