/** * Theme utilities for config-driven CSS variable injection */ import type { ChatSettings, ChatTheme } from '../types' /** * Maps config.settings.colors to CSS custom properties. * Returns an object suitable for use as an inline style that sets CSS variables. * * @param colors - The colors object from ChatSettings * @returns A record of CSS variable names to their values * * @example * ```typescript * const style = configColorsToCssVariables({ * primaryColor: '#0b3694', * botMessageColor: '#f5f5f5', * }) * // Returns: { '--cc-primary-color': '#0b3694', '--cc-background-bot-message': '#f5f5f5' } * ``` */ export function configColorsToCssVariables( colors?: ChatSettings['colors'] ): Record { if (!colors) return {} const mapping: Record = { // Primary action colors '--cc-primary-color': colors.primaryColor, '--cc-primary-color-hover': colors.primaryColorHover, '--cc-primary-color-focus': colors.primaryColorFocus, '--cc-primary-color-disabled': colors.primaryColorDisabled, '--cc-primary-contrast-color': colors.primaryContrastColor, '--cc-secondary-color': colors.secondaryColor, // Message bubble backgrounds '--cc-background-bot-message': colors.botMessageColor, '--cc-bot-message-contrast-color': colors.botMessageContrastColor, '--cc-background-user-message': colors.userMessageColor, '--cc-user-message-contrast-color': colors.userMessageContrastColor, '--cc-background-agent-message': colors.agentMessageColor, '--cc-agent-message-contrast-color': colors.agentMessageContrastColor, // Message bubble borders '--cc-border-bot-message': colors.borderBotMessage, '--cc-border-user-message': colors.borderUserMessage, '--cc-border-agent-message': colors.borderAgentMessage, // Media card borders '--cc-border-media-card': colors.borderMediaCard, // List divider color '--cc-list-divider-color': colors.listDividerColor, // Link color '--cc-text-link-color': colors.textLinkColor, // Adaptive Card colors '--cc-adaptive-card-text-color': colors.adaptiveCardTextColor, '--cc-adaptive-card-input-color': colors.adaptiveCardInputColor, '--cc-adaptive-card-input-background': colors.adaptiveCardInputBackground, '--cc-adaptive-card-input-border': colors.adaptiveCardInputBorder, // File preview colors '--cc-file-preview-background': colors.filePreviewBackground, '--cc-file-preview-text-color': colors.filePreviewTextColor, '--cc-file-preview-secondary-text-color': colors.filePreviewSecondaryTextColor, // Chat event colors '--cc-chat-event-background': colors.chatEventBackground, '--cc-chat-event-text-color': colors.chatEventTextColor, // Message shadow '--cc-message-shadow': colors.messageShadow, } // Filter out undefined values and return only defined CSS variables return Object.fromEntries( Object.entries(mapping).filter(([, value]) => value !== undefined) ) as Record } /** * Maps a ChatTheme's fontFamily to the --cc-font-family CSS variable. * Consumers can set this to override the default Figtree font. * * Components should reference font-family as: * font-family: var(--cc-font-family, 'Figtree', sans-serif); * * @param theme - The ChatTheme object * @returns A record with the --cc-font-family CSS variable, or empty object */ export function themeFontToCssVariable( theme?: ChatTheme ): Record { if (!theme?.fontFamily) return {} return { '--cc-font-family': theme.fontFamily } } /** * Maps a ChatTheme's fontSize to the --cc-font-size CSS variable. * Consumers can set this to scale all text proportionally. * * Components should reference font-size as: * font-size: var(--cc-font-size, 14px); (for 14px base) * font-size: calc(var(--cc-font-size, 14px) * 1.2857); (for 18px base) * * @param theme - The ChatTheme object * @returns A record with the --cc-font-size CSS variable, or empty object */ export function themeFontSizeToCssVariable( theme?: ChatTheme ): Record { if (!theme?.fontSize) return {} return { '--cc-font-size': theme.fontSize } }