import { createContext, useContext, type Accessor, type JSX } from 'solid-js'; export type ProseSize = 'xs' | 'sm' | 'base' | 'lg'; export interface ChatConfigValue { /** Prose/text size for messages, markdown, and UI elements */ proseSize: Accessor; /** Shiki theme for code blocks */ codeTheme: Accessor; /** Node the kit's overlays portal into; undefined → document.body */ portalMount: Accessor; /** Whether code blocks are syntax-highlighted; false → plain text, no Shiki loaded */ codeHighlight: Accessor; } const defaultConfig: ChatConfigValue = { proseSize: () => 'sm' as ProseSize, codeTheme: () => 'github-dark-dimmed', portalMount: () => undefined, codeHighlight: () => true, }; const ChatConfigContext = createContext(defaultConfig); export interface ChatConfigProps { proseSize?: ProseSize; codeTheme?: string; portalMount?: HTMLElement; codeHighlight?: boolean; children: JSX.Element; } /** * Provides chat-wide appearance settings to all child components. * Set once at the top level — MessageContent, Markdown, CodeBlock, * ConversationList, and PromptInput all read from this. */ export function ChatConfig(props: ChatConfigProps) { const value: ChatConfigValue = { proseSize: () => props.proseSize ?? 'sm', codeTheme: () => props.codeTheme ?? 'github-dark-dimmed', portalMount: () => props.portalMount, codeHighlight: () => props.codeHighlight ?? true, }; return ( {props.children} ); } /** Read the current chat config. Returns defaults if no provider is present. */ export function useChatConfig(): ChatConfigValue { return useContext(ChatConfigContext)!; } /** Maps prose size to Tailwind prose class */ export function proseClass(size: ProseSize): string { switch (size) { case 'xs': return 'prose-sm text-xs'; case 'sm': return 'prose-sm'; case 'base': return ''; case 'lg': return 'prose-lg'; } } /** Maps prose size to a text class for non-prose elements (sidebar, input) */ export function textClass(size: ProseSize): string { switch (size) { case 'xs': return 'text-xs'; case 'sm': return 'text-sm'; case 'base': return 'text-base'; case 'lg': return 'text-lg'; } }