React context providing chat panel affordances to deeply nested descendants without prop drilling. ## Key Components | Export | Type | Description | |--------|------|-------------| | `ChatPanelHandle` | Interface | Shape of the context value; exposes `closeChat()` | | `ChatPanelContext` | `Context` | Raw context object; defaults to `null` when no provider is mounted | | `useChatPanel` | Hook | Optional consumer; returns `null` safely outside a provider | ## Usage Example **Provider** (in `EmbeddableChat` or equivalent shell): ```typescript import { ChatPanelContext } from './chat-panel-context' function EmbeddableChat() { const handleClose = () => { /* dismiss panel */ } return ( {/* card dispatcher and all descendants */} ) } ``` **Consumer** (e.g. `BlogCard`, `ProgramCard`, any inline card): ```typescript import { useChatPanel } from './chat-panel-context' function BlogCard({ href }: { href: string }) { const chatPanel = useChatPanel() const handleClick = (e: React.MouseEvent) => { const isSameTab = !e.metaKey && !e.ctrlKey if (isSameTab) { chatPanel?.closeChat() // null-safe — works outside provider too } } return Read more } ``` ## Notes - Returns `null` when consumed outside a provider (tests, standalone card renders) — always use optional chaining (`chatPanel?.closeChat()`). - Intentionally minimal; add new affordances to `ChatPanelHandle` only when multiple card types need the same panel-level behavior.