"use client"; import { ArrowUp, ChevronDown, X } from "lucide-react"; import { AnimatePresence, motion, useReducedMotion } from "motion/react"; import { type KeyboardEvent, type ReactNode, useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react"; import { EASE_OUT, SPRING_PANEL } from "@/lib/ease"; import { cn } from "@/lib/utils"; export { ComposerAutonomyDial } from "./autonomy-dial"; export { ComposerEffortSlider } from "./effort-slider"; export interface ComposerProps { className?: string; children?: ReactNode; } /** * Composer shell — a translucent, rounded card that hosts a textarea and a * toolbar row. Renders `children` directly (auto-height textarea and toolbar * are stacked by the caller); the hairline shadow trio and glass surface use * the same `--composer-hairline` CSS-variable technique as * `WorkbenchSummaryCard`, so the right shade is picked per color scheme. * Sits at `z-10` so it stacks above a sibling `ComposerContextBar`. */ export function Composer({ className, children }: ComposerProps) { return (
{children}
); } export interface ComposerContextBarProps { className?: string; children?: ReactNode; } /** * Optional context bar meant to sit as a sibling right above `` in * markup order. Its bottom padding is taller than its visible height and * pulled up with a negative margin, so `Composer` (rendered after it, at * `z-10`) sits on top and hides the lower half — the bar reads as tucked in * "behind" the composer shell. */ export function ComposerContextBar({ className, children }: ComposerContextBarProps) { return (
{children}
); } export interface ComposerChipProps { icon?: ReactNode; /** Swapped in for `icon` on hover/focus (opacity crossfade, no layout shift). * Only meaningful on interactive chips — pair it with `onClick`. */ hoverIcon?: ReactNode; /** Makes the chip a ` ); } return ( {iconSlot} {children} ); } export interface ComposerTextareaProps { value: string; onChange: (next: string) => void; placeholder?: string; /** Fires when Enter is pressed without Shift — the caller owns what "submit" means. */ onSubmit?: () => void; "aria-label"?: string; className?: string; } /** * Auto-growing message field. A real `