"use client" /** * AiThinkingOverlay / AiThinkingSurface — ambient "AI is thinking" indicator. * * Drops a soft, drifting dot cloud onto any surface to signal the assistant * is working. Intentionally decorative — pair with a visible text/sr-only * status so screen readers still hear "Leo is thinking" / "Generating…". * * Two ways to use: * * 1) **Overlay** — drop inside an existing `relative` container: * *
* * *
* * 2) **Surface** — wraps children and handles positioning for you: * * * * * * Accessibility: the overlay is `aria-hidden` and `pointer-events-none`; * always render a live status element next to it, e.g. * Generating… */ import * as React from "react" import { cn } from "@/lib/utils" import { DotPattern } from "@/components/ui/dot-pattern" export interface AiThinkingOverlayProps extends React.HTMLAttributes { /** When false (default), nothing renders. Flip to true while the AI is working. */ active?: boolean /** Number of drifting soft clouds. Keep small (1–2) for most surfaces. */ cloudCount?: number /** Radius of each cloud in px — scale up for large surfaces. */ cloudRadius?: number /** Grid tile size (both width and height of the repeating dot tile). */ gridSize?: number /** Per-dot radius. */ dotRadius?: number /** Tailwind utility for the dot fill (e.g. `"fill-foreground/35"`). */ fillClassName?: string } /** * Absolute overlay. The parent must be `position: relative` and should usually * clip overflow (e.g. `rounded-xl overflow-hidden`) so the drifting clouds * don't paint outside the surface. */ export function AiThinkingOverlay({ active = false, cloudCount = 2, cloudRadius = 260, gridSize = 14, dotRadius = 0.8, fillClassName = "fill-foreground/35 dark:fill-foreground/45", className, ...props }: AiThinkingOverlayProps) { if (!active) return null return (
) } export interface AiThinkingSurfaceProps extends React.HTMLAttributes, Pick { /** Optional className applied to the content wrapper (above the overlay). */ contentClassName?: string } /** * Wrapper that adds `relative overflow-hidden`, renders the overlay, and * stacks children above it. Use when you'd otherwise have to manually wire * positioning around ``. */ export function AiThinkingSurface({ active, cloudCount, cloudRadius, gridSize, dotRadius, fillClassName, className, contentClassName, children, ...props }: AiThinkingSurfaceProps) { return (
{children}
) }