/** Where the sparkle is: on first show, while an action runs, as it lands. */ export type AiSparkleState = 'intro' | 'working' | 'landed'; export declare const SHIMMER_CLASS: Record; export declare const COMET_CLASS: Record; export declare const COMET_WRAPPER_CLASS = "ds:pointer-events-none ds:absolute ds:[inset-block-start:0] ds:[inset-inline-start:0] ds:opacity-0 ds:[offset-path:inset(0_round_var(--radius-full))] ds:[offset-rotate:0deg]"; export declare const COMET_TAIL: readonly [{ readonly key: 1; readonly lag: "ds:[animation-delay:calc(var(--animation-duration)*0.2)]"; readonly dot: "ds:size-2.5 ds:opacity-[var(--opacity-90)]"; }, { readonly key: 2; readonly lag: "ds:[animation-delay:calc(var(--animation-duration)*0.4)]"; readonly dot: "ds:size-2 ds:opacity-[var(--opacity-70)]"; }, { readonly key: 3; readonly lag: "ds:[animation-delay:calc(var(--animation-duration)*0.6)]"; readonly dot: "ds:size-2 ds:opacity-[var(--opacity-50)]"; }, { readonly key: 4; readonly lag: "ds:[animation-delay:calc(var(--animation-duration)*0.8)]"; readonly dot: "ds:size-1.5 ds:opacity-[var(--opacity-30)]"; }, { readonly key: 5; readonly lag: "ds:[animation-delay:calc(var(--animation-duration)*1)]"; readonly dot: "ds:size-1.5 ds:opacity-[var(--opacity-20)]"; }, { readonly key: 6; readonly lag: "ds:[animation-delay:calc(var(--animation-duration)*1.2)]"; readonly dot: "ds:size-1 ds:opacity-[var(--opacity-10)]"; }]; export interface UseAiSparkleOptions { /** * Whether the sparkle is available at all. Read once, at mount, to seed * the initial `'intro'` phase — matches how the RichTextEditor's * `aiSparkle` prop only ever gated the very first render. Default `true`. */ enabled?: boolean; /** * `'auto'` (default) reads `prefers-reduced-motion` via * `usePrefersReducedMotion`. `'off'` forces full motion regardless of the * OS preference — useful for a story that wants to show the animated * states side by side with a reduced one. */ reducedMotion?: 'auto' | 'off'; } export interface UseAiSparkleProps { /** Spread (or picked) onto the host element as a pure styling hook. */ 'data-ai-sparkle': AiSparkleState | undefined; /** * The shimmer animation class for the current state — empty when at rest. * Layer it over the host's own base positioning classes; the comet layer * needs real DOM and lives in the `AiSparkle` component instead. */ className: string; } export interface UseAiSparkleReturn { /** `null` at rest — nothing to render for the comet layer either. */ state: AiSparkleState | null; props: UseAiSparkleProps; /** An AI action started: swap to the looping `'working'` phase. */ start: () => void; /** An action's result landed: swap to the one-off `'landed'` phase. */ land: () => void; /** * Settle after an action ends. Clears back to rest only when still * `'working'` (the action errored or was cancelled before `land()`); * leaves `'landed'` alone so the one-off animation gets to play out. */ reset: () => void; } /** * Drives the AI-pill sparkle: lit on first show, looping while an action * runs, and a one-off flourish as the result lands. * * The hook owns the state machine and the timing only — it paints nothing. * `props['data-ai-sparkle']` is a plain styling hook for the host element; * `props.className` carries the shimmer layer's animation class from the * same lookup table the RichTextEditor's pill originally inlined. The * comet layer needs actual DOM (a head and a tail of dots), so it lives in * the sibling `AiSparkle` component, keyed off the same `state`. * * Both `intro` and `landed` are one-off: this hook clears them back to * `null` on a timer sized to the comet's lap plus a small buffer, at the * default 200ms `--animation-duration`. Under reduced * motion (`prefers-reduced-motion` or `reducedMotion: 'auto'`'s system * read) the CSS animations already collapse to 0ms, so the clear fires at * the next tick instead of waiting out the full lap — the pill still gets * its `data-ai-sparkle` attribute for a moment, but nothing visibly moves. */ export declare function useAiSparkle(options?: UseAiSparkleOptions): UseAiSparkleReturn; //# sourceMappingURL=use-ai-sparkle.d.ts.map