import { useState, useRef, type CSSProperties } from "react"; import { useMountEffect } from "../hooks/useMountEffect"; import { type AgentModalAnchorPoint, clampNumber } from "../utils/studioHelpers"; function getAgentModalPositionStyle( anchorPoint: AgentModalAnchorPoint | null, ): CSSProperties | undefined { if (!anchorPoint || typeof window === "undefined") return undefined; const modalWidth = 480; const estimatedModalHeight = 270; const margin = 16; const left = clampNumber( anchorPoint.x, margin + modalWidth / 2, window.innerWidth - margin - modalWidth / 2, ); const top = clampNumber( anchorPoint.y + 12, margin, window.innerHeight - margin - estimatedModalHeight, ); return { left, top, transform: "translateX(-50%)" }; } export function AskAgentModal({ selectionLabel, contextPreview, anchorPoint = null, onSubmit, onClose, }: { selectionLabel: string; contextPreview?: string; anchorPoint?: AgentModalAnchorPoint | null; onSubmit: (instruction: string) => void; onClose: () => void; }) { const [value, setValue] = useState(""); const inputRef = useRef(null); const modalPositionStyle = getAgentModalPositionStyle(anchorPoint); useMountEffect(() => { requestAnimationFrame(() => inputRef.current?.focus()); }); const handleSubmit = () => { if (!value.trim()) return; onSubmit(value.trim()); }; return (
e.stopPropagation()} >

Copy prompt to AI agent

{selectionLabel.length > 50 ? `${selectionLabel.slice(0, 49)}…` : selectionLabel}