@enjoys/react-chatbot-plugin 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/context/ChatContext.ts","../src/styles/theme.ts","../src/components/Launcher.tsx","../src/components/ChatHeader.tsx","../src/components/WelcomeScreen.tsx","../src/components/forms/TextField.tsx","../src/components/forms/SelectField.tsx","../src/components/forms/RadioField.tsx","../src/components/forms/CheckboxField.tsx","../src/components/forms/FileUploadField.tsx","../src/components/forms/DynamicForm.tsx","../src/components/LoginScreen.tsx","../src/components/MessageBubble.tsx","../src/components/QuickReplies.tsx","../src/components/TypingIndicator.tsx","../src/components/MessageList.tsx","../src/components/ChatInput.tsx","../src/engine/FlowEngine.ts","../src/utils/helpers.ts","../src/hooks/useChat.ts","../src/components/ChatWindow.tsx","../src/components/ChatBot.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\r\nimport type { ChatMessage, ChatBotProps } from '../types';\r\n\r\nexport interface ChatState {\r\n isOpen: boolean;\r\n messages: ChatMessage[];\r\n isTyping: boolean;\r\n showWelcome: boolean;\r\n currentStepId: string | null;\r\n collectedData: Record<string, unknown>;\r\n isLoggedIn: boolean;\r\n}\r\n\r\nexport type ChatAction =\r\n | { type: 'TOGGLE_OPEN' }\r\n | { type: 'SET_OPEN'; payload: boolean }\r\n | { type: 'ADD_MESSAGE'; payload: ChatMessage }\r\n | { type: 'ADD_MESSAGES'; payload: ChatMessage[] }\r\n | { type: 'SET_TYPING'; payload: boolean }\r\n | { type: 'DISMISS_WELCOME' }\r\n | { type: 'SET_STEP'; payload: string | null }\r\n | { type: 'SET_DATA'; payload: Record<string, unknown> }\r\n | { type: 'SET_LOGGED_IN'; payload: boolean }\r\n | { type: 'CLEAR_QUICK_REPLIES' };\r\n\r\nexport function chatReducer(state: ChatState, action: ChatAction): ChatState {\r\n switch (action.type) {\r\n case 'TOGGLE_OPEN':\r\n return { ...state, isOpen: !state.isOpen };\r\n case 'SET_OPEN':\r\n return { ...state, isOpen: action.payload };\r\n case 'ADD_MESSAGE':\r\n return { ...state, messages: [...state.messages, action.payload] };\r\n case 'ADD_MESSAGES':\r\n return { ...state, messages: [...state.messages, ...action.payload] };\r\n case 'SET_TYPING':\r\n return { ...state, isTyping: action.payload };\r\n case 'DISMISS_WELCOME':\r\n return { ...state, showWelcome: false };\r\n case 'SET_STEP':\r\n return { ...state, currentStepId: action.payload };\r\n case 'SET_DATA':\r\n return { ...state, collectedData: { ...state.collectedData, ...action.payload } };\r\n case 'SET_LOGGED_IN':\r\n return { ...state, isLoggedIn: action.payload };\r\n case 'CLEAR_QUICK_REPLIES':\r\n return {\r\n ...state,\r\n messages: state.messages.map((m) =>\r\n m.quickReplies ? { ...m, quickReplies: undefined } : m,\r\n ),\r\n };\r\n default:\r\n return state;\r\n }\r\n}\r\n\r\nexport const initialState = (props: ChatBotProps): ChatState => ({\r\n isOpen: props.defaultOpen ?? false,\r\n messages: props.initialMessages ?? [],\r\n isTyping: false,\r\n showWelcome: !!props.welcomeScreen,\r\n currentStepId: null,\r\n collectedData: {},\r\n isLoggedIn: !props.loginForm,\r\n});\r\n\r\ninterface ChatContextValue {\r\n state: ChatState;\r\n dispatch: React.Dispatch<ChatAction>;\r\n props: ChatBotProps;\r\n}\r\n\r\nexport const ChatContext = createContext<ChatContextValue | null>(null);\r\n\r\nexport function useChatContext(): ChatContextValue {\r\n const ctx = useContext(ChatContext);\r\n if (!ctx) throw new Error('useChatContext must be used within ChatProvider');\r\n return ctx;\r\n}\r\n","import type { ChatTheme, ChatStyle } from '../types';\r\nimport type { CSSProperties } from 'react';\r\n\r\nconst defaults: Required<ChatTheme> = {\r\n primaryColor: '#0066FF',\r\n headerBg: '#0066FF',\r\n headerText: '#FFFFFF',\r\n bubbleBg: '#F1F1F1',\r\n bubbleText: '#333333',\r\n userBubbleBg: '#0066FF',\r\n userBubbleText: '#FFFFFF',\r\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n fontSize: '14px',\r\n borderRadius: '12px',\r\n windowWidth: '380px',\r\n windowHeight: '550px',\r\n};\r\n\r\nexport function resolveTheme(theme?: ChatTheme): Required<ChatTheme> {\r\n return { ...defaults, ...theme };\r\n}\r\n\r\nexport function buildStyles(\r\n theme: Required<ChatTheme>,\r\n overrides?: ChatStyle,\r\n) {\r\n const styles = {\r\n root: {\r\n fontFamily: theme.fontFamily,\r\n fontSize: theme.fontSize,\r\n lineHeight: '1.5',\r\n } satisfies CSSProperties,\r\n\r\n launcher: {\r\n position: 'fixed',\r\n width: '60px',\r\n height: '60px',\r\n borderRadius: '50%',\r\n backgroundColor: theme.primaryColor,\r\n color: '#fff',\r\n border: 'none',\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\r\n transition: 'transform 0.2s ease',\r\n zIndex: 9998,\r\n ...overrides?.launcher,\r\n } satisfies CSSProperties,\r\n\r\n window: {\r\n position: 'fixed',\r\n width: theme.windowWidth,\r\n height: theme.windowHeight,\r\n maxHeight: '80vh',\r\n borderRadius: theme.borderRadius,\r\n overflow: 'hidden',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n boxShadow: '0 8px 32px rgba(0,0,0,0.15)',\r\n backgroundColor: '#FFFFFF',\r\n zIndex: 9999,\r\n ...overrides?.window,\r\n } satisfies CSSProperties,\r\n\r\n header: {\r\n backgroundColor: theme.headerBg,\r\n color: theme.headerText,\r\n padding: '16px 20px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n gap: '12px',\r\n flexShrink: 0,\r\n ...overrides?.header,\r\n } satisfies CSSProperties,\r\n\r\n messageList: {\r\n flex: 1,\r\n overflowY: 'auto',\r\n padding: '16px',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '8px',\r\n ...overrides?.messageList,\r\n } satisfies CSSProperties,\r\n\r\n inputArea: {\r\n padding: '12px 16px',\r\n borderTop: '1px solid #E8E8E8',\r\n display: 'flex',\r\n gap: '8px',\r\n alignItems: 'flex-end',\r\n flexShrink: 0,\r\n ...overrides?.inputArea,\r\n } satisfies CSSProperties,\r\n\r\n botBubble: {\r\n backgroundColor: theme.bubbleBg,\r\n color: theme.bubbleText,\r\n padding: '10px 14px',\r\n borderRadius: '16px 16px 16px 4px',\r\n maxWidth: '80%',\r\n alignSelf: 'flex-start',\r\n wordBreak: 'break-word',\r\n whiteSpace: 'pre-wrap',\r\n } satisfies CSSProperties,\r\n\r\n userBubble: {\r\n backgroundColor: theme.userBubbleBg,\r\n color: theme.userBubbleText,\r\n padding: '10px 14px',\r\n borderRadius: '16px 16px 4px 16px',\r\n maxWidth: '80%',\r\n alignSelf: 'flex-end',\r\n wordBreak: 'break-word',\r\n whiteSpace: 'pre-wrap',\r\n } satisfies CSSProperties,\r\n };\r\n\r\n return styles;\r\n}\r\n\r\nexport type ChatStyles = ReturnType<typeof buildStyles>;\r\n","import React from 'react';\r\nimport type { CSSProperties } from 'react';\r\nimport type { ChatStyles } from '../styles/theme';\r\n\r\ninterface LauncherProps {\r\n onClick: () => void;\r\n isOpen: boolean;\r\n position: 'bottom-right' | 'bottom-left';\r\n styles: ChatStyles;\r\n icon?: React.ReactNode;\r\n closeIcon?: React.ReactNode;\r\n zIndex?: number;\r\n}\r\n\r\nexport const Launcher: React.FC<LauncherProps> = ({\r\n onClick,\r\n isOpen,\r\n position,\r\n styles,\r\n icon,\r\n closeIcon,\r\n zIndex,\r\n}) => {\r\n const posStyle: CSSProperties =\r\n position === 'bottom-left'\r\n ? { bottom: '20px', left: '20px' }\r\n : { bottom: '20px', right: '20px' };\r\n\r\n return (\r\n <button\r\n onClick={onClick}\r\n aria-label={isOpen ? 'Close chat' : 'Open chat'}\r\n style={{\r\n ...styles.launcher,\r\n ...posStyle,\r\n ...(zIndex != null ? { zIndex } : {}),\r\n transform: isOpen ? 'scale(0.9)' : 'scale(1)',\r\n }}\r\n >\r\n {isOpen\r\n ? closeIcon ?? <CloseIcon />\r\n : icon ?? <ChatIcon />}\r\n </button>\r\n );\r\n};\r\n\r\nconst ChatIcon: React.FC = () => (\r\n <svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\r\n </svg>\r\n);\r\n\r\nconst CloseIcon: React.FC = () => (\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n);\r\n","import React from 'react';\r\nimport type { HeaderConfig } from '../types';\r\nimport type { ChatStyles as ThemeStyles } from '../styles/theme';\r\n\r\ninterface ChatHeaderProps {\r\n config: HeaderConfig;\r\n styles: ThemeStyles;\r\n onClose: () => void;\r\n}\r\n\r\nexport const ChatHeader: React.FC<ChatHeaderProps> = ({ config, styles, onClose }) => {\r\n return (\r\n <div style={styles.header}>\r\n <div style={{ display: 'flex', alignItems: 'center', gap: '10px', flex: 1 }}>\r\n {config.avatar && (\r\n <img\r\n src={config.avatar}\r\n alt=\"\"\r\n style={{ width: '36px', height: '36px', borderRadius: '50%', objectFit: 'cover' }}\r\n />\r\n )}\r\n <div>\r\n <div style={{ fontWeight: 600, fontSize: '15px' }}>\r\n {config.title ?? 'Chat with us'}\r\n </div>\r\n {config.subtitle && (\r\n <div style={{ fontSize: '12px', opacity: 0.85 }}>{config.subtitle}</div>\r\n )}\r\n </div>\r\n </div>\r\n {config.showClose !== false && (\r\n <button\r\n onClick={onClose}\r\n aria-label=\"Close chat\"\r\n style={{\r\n background: 'none',\r\n border: 'none',\r\n color: 'inherit',\r\n cursor: 'pointer',\r\n padding: '4px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { ReactNode } from 'react';\r\n\r\ninterface WelcomeScreenProps {\r\n content: ReactNode;\r\n onDismiss: () => void;\r\n primaryColor: string;\r\n}\r\n\r\nexport const WelcomeScreen: React.FC<WelcomeScreenProps> = ({ content, onDismiss, primaryColor }) => {\r\n return (\r\n <div\r\n style={{\r\n flex: 1,\r\n display: 'flex',\r\n flexDirection: 'column',\r\n overflow: 'auto',\r\n }}\r\n >\r\n <div style={{ flex: 1, padding: '20px', overflow: 'auto' }}>\r\n {content}\r\n </div>\r\n <div style={{ padding: '12px 16px', borderTop: '1px solid #E8E8E8', flexShrink: 0 }}>\r\n <button\r\n onClick={onDismiss}\r\n style={{\r\n width: '100%',\r\n padding: '12px',\r\n backgroundColor: primaryColor,\r\n color: '#fff',\r\n border: 'none',\r\n borderRadius: '8px',\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n cursor: 'pointer',\r\n }}\r\n >\r\n Start Chat\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface TextFieldProps {\r\n field: FormFieldConfig;\r\n value: string;\r\n onChange: (value: string) => void;\r\n error?: string;\r\n}\r\n\r\nexport const TextField: React.FC<TextFieldProps> = ({ field, value, onChange, error }) => {\r\n const isTextarea = field.type === 'textarea';\r\n const inputType = field.type === 'textarea' ? undefined : field.type;\r\n\r\n const baseStyle: React.CSSProperties = {\r\n width: '100%',\r\n padding: '8px 12px',\r\n border: `1px solid ${error ? '#E53E3E' : '#D1D5DB'}`,\r\n borderRadius: '8px',\r\n fontSize: '13px',\r\n fontFamily: 'inherit',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n transition: 'border-color 0.15s ease',\r\n };\r\n\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n {isTextarea ? (\r\n <textarea\r\n value={value}\r\n onChange={(e) => onChange(e.target.value)}\r\n placeholder={field.placeholder}\r\n required={field.required}\r\n rows={3}\r\n style={{ ...baseStyle, resize: 'vertical' }}\r\n minLength={field.validation?.minLength}\r\n maxLength={field.validation?.maxLength}\r\n />\r\n ) : (\r\n <input\r\n type={inputType}\r\n value={value}\r\n onChange={(e) => onChange(e.target.value)}\r\n placeholder={field.placeholder}\r\n required={field.required}\r\n style={baseStyle}\r\n min={field.validation?.min}\r\n max={field.validation?.max}\r\n minLength={field.validation?.minLength}\r\n maxLength={field.validation?.maxLength}\r\n pattern={field.validation?.pattern}\r\n />\r\n )}\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface SelectFieldProps {\r\n field: FormFieldConfig;\r\n value: string | string[];\r\n onChange: (value: string | string[]) => void;\r\n error?: string;\r\n}\r\n\r\nexport const SelectField: React.FC<SelectFieldProps> = ({ field, value, onChange, error }) => {\r\n const isMulti = field.type === 'multiselect' || field.multiple;\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\r\n if (isMulti) {\r\n const selected = Array.from(e.target.selectedOptions, (opt) => opt.value);\r\n onChange(selected);\r\n } else {\r\n onChange(e.target.value);\r\n }\r\n };\r\n\r\n const selectValue = isMulti\r\n ? Array.isArray(value) ? value : [value].filter(Boolean)\r\n : typeof value === 'string' ? value : '';\r\n\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n <select\r\n value={selectValue}\r\n onChange={handleChange}\r\n multiple={isMulti}\r\n required={field.required}\r\n style={{\r\n width: '100%',\r\n padding: '8px 12px',\r\n border: `1px solid ${error ? '#E53E3E' : '#D1D5DB'}`,\r\n borderRadius: '8px',\r\n fontSize: '13px',\r\n fontFamily: 'inherit',\r\n outline: 'none',\r\n backgroundColor: '#fff',\r\n boxSizing: 'border-box',\r\n ...(isMulti ? { minHeight: '80px' } : {}),\r\n }}\r\n >\r\n {!isMulti && <option value=\"\">Select...</option>}\r\n {field.options?.map((opt) => (\r\n <option key={opt.value} value={opt.value}>\r\n {opt.label}\r\n </option>\r\n ))}\r\n </select>\r\n {isMulti && (\r\n <div style={{ fontSize: '11px', color: '#888', marginTop: '2px' }}>\r\n Hold Ctrl/Cmd to select multiple\r\n </div>\r\n )}\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface RadioFieldProps {\r\n field: FormFieldConfig;\r\n value: string;\r\n onChange: (value: string) => void;\r\n error?: string;\r\n}\r\n\r\nexport const RadioField: React.FC<RadioFieldProps> = ({ field, value, onChange, error }) => {\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '6px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\r\n {field.options?.map((opt) => (\r\n <label\r\n key={opt.value}\r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n }}\r\n >\r\n <input\r\n type=\"radio\"\r\n name={field.name}\r\n value={opt.value}\r\n checked={value === opt.value}\r\n onChange={() => onChange(opt.value)}\r\n style={{ margin: 0 }}\r\n />\r\n {opt.label}\r\n </label>\r\n ))}\r\n </div>\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface CheckboxFieldProps {\r\n field: FormFieldConfig;\r\n value: string[];\r\n onChange: (value: string[]) => void;\r\n error?: string;\r\n}\r\n\r\nexport const CheckboxField: React.FC<CheckboxFieldProps> = ({ field, value, onChange, error }) => {\r\n const handleToggle = (optValue: string) => {\r\n if (value.includes(optValue)) {\r\n onChange(value.filter((v) => v !== optValue));\r\n } else {\r\n onChange([...value, optValue]);\r\n }\r\n };\r\n\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '6px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\r\n {field.options?.map((opt) => (\r\n <label\r\n key={opt.value}\r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n }}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={value.includes(opt.value)}\r\n onChange={() => handleToggle(opt.value)}\r\n style={{ margin: 0 }}\r\n />\r\n {opt.label}\r\n </label>\r\n ))}\r\n </div>\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React, { useRef } from 'react';\r\nimport type { FormFieldConfig } from '../../types';\r\n\r\ninterface FileUploadFieldProps {\r\n field: FormFieldConfig;\r\n value: FileList | null;\r\n onChange: (files: FileList | null) => void;\r\n error?: string;\r\n primaryColor: string;\r\n}\r\n\r\nexport const FileUploadField: React.FC<FileUploadFieldProps> = ({\r\n field,\r\n value,\r\n onChange,\r\n error,\r\n primaryColor,\r\n}) => {\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n\r\n const fileNames = value ? Array.from(value).map((f) => f.name).join(', ') : '';\r\n\r\n return (\r\n <div style={{ marginBottom: '12px' }}>\r\n {field.label && (\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '13px', fontWeight: 500 }}>\r\n {field.label}\r\n {field.required && <span style={{ color: '#E53E3E', marginLeft: '2px' }}>*</span>}\r\n </label>\r\n )}\r\n <input\r\n ref={inputRef}\r\n type=\"file\"\r\n accept={field.accept}\r\n multiple={field.multiple}\r\n onChange={(e) => onChange(e.target.files)}\r\n style={{ display: 'none' }}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => inputRef.current?.click()}\r\n style={{\r\n padding: '8px 16px',\r\n border: `1px dashed ${error ? '#E53E3E' : '#D1D5DB'}`,\r\n borderRadius: '8px',\r\n backgroundColor: '#FAFAFA',\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n color: '#555',\r\n width: '100%',\r\n textAlign: 'left',\r\n }}\r\n >\r\n {fileNames || field.placeholder || 'Choose file(s)...'}\r\n </button>\r\n {fileNames && (\r\n <div style={{ fontSize: '12px', color: primaryColor, marginTop: '4px' }}>\r\n {Array.from(value!).length} file(s) selected\r\n </div>\r\n )}\r\n {error && <div style={{ color: '#E53E3E', fontSize: '12px', marginTop: '2px' }}>{error}</div>}\r\n </div>\r\n );\r\n};\r\n","import React, { useState, useCallback } from 'react';\r\nimport type { FormConfig, FormFieldConfig } from '../../types';\r\nimport { TextField } from './TextField';\r\nimport { SelectField } from './SelectField';\r\nimport { RadioField } from './RadioField';\r\nimport { CheckboxField } from './CheckboxField';\r\nimport { FileUploadField } from './FileUploadField';\r\n\r\ninterface DynamicFormProps {\r\n config: FormConfig;\r\n onSubmit: (data: Record<string, unknown>) => void;\r\n primaryColor: string;\r\n}\r\n\r\nexport const DynamicForm: React.FC<DynamicFormProps> = ({ config, onSubmit, primaryColor }) => {\r\n const [values, setValues] = useState<Record<string, unknown>>(() => {\r\n const init: Record<string, unknown> = {};\r\n for (const field of config.fields) {\r\n if (field.defaultValue !== undefined) {\r\n init[field.name] = field.defaultValue;\r\n } else if (field.type === 'checkbox' || field.type === 'multiselect') {\r\n init[field.name] = [];\r\n } else if (field.type === 'file') {\r\n init[field.name] = null;\r\n } else {\r\n init[field.name] = '';\r\n }\r\n }\r\n return init;\r\n });\r\n\r\n const [errors, setErrors] = useState<Record<string, string>>({});\r\n const [submitted, setSubmitted] = useState(false);\r\n\r\n const setValue = useCallback((name: string, value: unknown) => {\r\n setValues((prev) => ({ ...prev, [name]: value }));\r\n setErrors((prev) => {\r\n const next = { ...prev };\r\n delete next[name];\r\n return next;\r\n });\r\n }, []);\r\n\r\n const validate = (): boolean => {\r\n const newErrors: Record<string, string> = {};\r\n\r\n for (const field of config.fields) {\r\n const val = values[field.name];\r\n\r\n // Required check\r\n if (field.required) {\r\n if (\r\n val === '' ||\r\n val === null ||\r\n val === undefined ||\r\n (Array.isArray(val) && val.length === 0)\r\n ) {\r\n newErrors[field.name] = field.validation?.message ?? `${field.label || field.name} is required`;\r\n continue;\r\n }\r\n }\r\n\r\n // Pattern check\r\n if (field.validation?.pattern && typeof val === 'string' && val) {\r\n const regex = new RegExp(field.validation.pattern);\r\n if (!regex.test(val)) {\r\n newErrors[field.name] = field.validation.message ?? 'Invalid format';\r\n }\r\n }\r\n }\r\n\r\n setErrors(newErrors);\r\n return Object.keys(newErrors).length === 0;\r\n };\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (!validate()) return;\r\n setSubmitted(true);\r\n onSubmit(values);\r\n };\r\n\r\n if (submitted) {\r\n return (\r\n <div\r\n style={{\r\n padding: '12px',\r\n backgroundColor: '#F0FFF4',\r\n borderRadius: '8px',\r\n fontSize: '13px',\r\n color: '#276749',\r\n textAlign: 'center',\r\n }}\r\n >\r\n Submitted successfully\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <form\r\n onSubmit={handleSubmit}\r\n style={{\r\n backgroundColor: '#FAFAFA',\r\n borderRadius: '10px',\r\n padding: '16px',\r\n border: '1px solid #E8E8E8',\r\n }}\r\n >\r\n {config.title && (\r\n <div style={{ fontWeight: 600, fontSize: '14px', marginBottom: '4px' }}>\r\n {config.title}\r\n </div>\r\n )}\r\n {config.description && (\r\n <div style={{ fontSize: '12px', color: '#888', marginBottom: '12px' }}>\r\n {config.description}\r\n </div>\r\n )}\r\n\r\n {config.fields.map((field) => (\r\n <FormField\r\n key={field.name}\r\n field={field}\r\n value={values[field.name]}\r\n onChange={(v) => setValue(field.name, v)}\r\n error={errors[field.name]}\r\n primaryColor={primaryColor}\r\n />\r\n ))}\r\n\r\n <button\r\n type=\"submit\"\r\n style={{\r\n width: '100%',\r\n padding: '10px',\r\n backgroundColor: primaryColor,\r\n color: '#fff',\r\n border: 'none',\r\n borderRadius: '8px',\r\n fontSize: '14px',\r\n fontWeight: 600,\r\n cursor: 'pointer',\r\n marginTop: '4px',\r\n }}\r\n >\r\n {config.submitLabel ?? 'Submit'}\r\n </button>\r\n </form>\r\n );\r\n};\r\n\r\n// ─── Field Router ────────────────────────────────────────────────\r\n\r\ninterface FormFieldProps {\r\n field: FormFieldConfig;\r\n value: unknown;\r\n onChange: (value: unknown) => void;\r\n error?: string;\r\n primaryColor: string;\r\n}\r\n\r\nconst FormField: React.FC<FormFieldProps> = ({ field, value, onChange, error, primaryColor }) => {\r\n switch (field.type) {\r\n case 'text':\r\n case 'email':\r\n case 'password':\r\n case 'number':\r\n case 'tel':\r\n case 'url':\r\n case 'textarea':\r\n case 'date':\r\n case 'time':\r\n return (\r\n <TextField\r\n field={field}\r\n value={String(value ?? '')}\r\n onChange={onChange as (v: string) => void}\r\n error={error}\r\n />\r\n );\r\n case 'select':\r\n case 'multiselect':\r\n return (\r\n <SelectField\r\n field={field}\r\n value={value as string | string[]}\r\n onChange={onChange as (v: string | string[]) => void}\r\n error={error}\r\n />\r\n );\r\n case 'radio':\r\n return (\r\n <RadioField\r\n field={field}\r\n value={String(value ?? '')}\r\n onChange={onChange as (v: string) => void}\r\n error={error}\r\n />\r\n );\r\n case 'checkbox':\r\n return (\r\n <CheckboxField\r\n field={field}\r\n value={(value as string[]) ?? []}\r\n onChange={onChange as (v: string[]) => void}\r\n error={error}\r\n />\r\n );\r\n case 'file':\r\n return (\r\n <FileUploadField\r\n field={field}\r\n value={value as FileList | null}\r\n onChange={onChange as (v: FileList | null) => void}\r\n error={error}\r\n primaryColor={primaryColor}\r\n />\r\n );\r\n case 'hidden':\r\n return <input type=\"hidden\" name={field.name} value={String(value ?? '')} />;\r\n default:\r\n return null;\r\n }\r\n};\r\n","import React from 'react';\r\nimport type { FormConfig } from '../types';\r\nimport { DynamicForm } from './forms/DynamicForm';\r\n\r\ninterface LoginScreenProps {\r\n config: FormConfig;\r\n onLogin: (data: Record<string, unknown>) => void;\r\n primaryColor: string;\r\n}\r\n\r\nexport const LoginScreen: React.FC<LoginScreenProps> = ({ config, onLogin, primaryColor }) => {\r\n return (\r\n <div\r\n style={{\r\n flex: 1,\r\n display: 'flex',\r\n flexDirection: 'column',\r\n justifyContent: 'center',\r\n padding: '20px',\r\n overflow: 'auto',\r\n }}\r\n >\r\n <DynamicForm config={config} onSubmit={onLogin} primaryColor={primaryColor} />\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { ChatMessage } from '../types';\r\nimport type { ChatStyles } from '../styles/theme';\r\n\r\ninterface MessageBubbleProps {\r\n message: ChatMessage;\r\n styles: ChatStyles;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message, styles }) => {\r\n const isBot = message.sender === 'bot';\r\n const bubbleStyle = isBot ? styles.botBubble : styles.userBubble;\r\n\r\n if (!message.text && !message.attachment) return null;\r\n\r\n return (\r\n <div style={bubbleStyle}>\r\n {message.text && <span>{message.text}</span>}\r\n {message.attachment && (\r\n <div style={{ marginTop: message.text ? '6px' : 0 }}>\r\n <a\r\n href={message.attachment.url}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n style={{ color: 'inherit', textDecoration: 'underline', fontSize: '13px' }}\r\n >\r\n 📎 {message.attachment.name}\r\n </a>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { FlowQuickReply } from '../types';\r\n\r\ninterface QuickRepliesProps {\r\n replies: FlowQuickReply[];\r\n onSelect: (value: string, label: string) => void;\r\n primaryColor: string;\r\n}\r\n\r\nexport const QuickReplies: React.FC<QuickRepliesProps> = ({ replies, onSelect, primaryColor }) => {\r\n return (\r\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', alignSelf: 'flex-start', maxWidth: '90%' }}>\r\n {replies.map((reply) => (\r\n <button\r\n key={reply.value}\r\n onClick={() => onSelect(reply.value, reply.label)}\r\n style={{\r\n padding: '6px 14px',\r\n borderRadius: '18px',\r\n border: `1px solid ${primaryColor}`,\r\n backgroundColor: 'transparent',\r\n color: primaryColor,\r\n cursor: 'pointer',\r\n fontSize: '13px',\r\n fontWeight: 500,\r\n transition: 'all 0.15s ease',\r\n }}\r\n onMouseEnter={(e) => {\r\n e.currentTarget.style.backgroundColor = primaryColor;\r\n e.currentTarget.style.color = '#fff';\r\n }}\r\n onMouseLeave={(e) => {\r\n e.currentTarget.style.backgroundColor = 'transparent';\r\n e.currentTarget.style.color = primaryColor;\r\n }}\r\n >\r\n {reply.label}\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\n\r\ninterface TypingIndicatorProps {\r\n color: string;\r\n}\r\n\r\nexport const TypingIndicator: React.FC<TypingIndicatorProps> = ({ color }) => {\r\n const dotStyle: React.CSSProperties = {\r\n width: '8px',\r\n height: '8px',\r\n borderRadius: '50%',\r\n backgroundColor: color,\r\n opacity: 0.4,\r\n animation: 'chatbot-typing-bounce 1.4s infinite ease-in-out',\r\n };\r\n\r\n return (\r\n <>\r\n <style>{`\r\n @keyframes chatbot-typing-bounce {\r\n 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }\r\n 40% { transform: scale(1); opacity: 1; }\r\n }\r\n `}</style>\r\n <div\r\n style={{\r\n display: 'flex',\r\n gap: '4px',\r\n padding: '12px 16px',\r\n backgroundColor: '#F1F1F1',\r\n borderRadius: '16px 16px 16px 4px',\r\n alignSelf: 'flex-start',\r\n alignItems: 'center',\r\n }}\r\n >\r\n <span style={{ ...dotStyle, animationDelay: '0s' }} />\r\n <span style={{ ...dotStyle, animationDelay: '0.2s' }} />\r\n <span style={{ ...dotStyle, animationDelay: '0.4s' }} />\r\n </div>\r\n </>\r\n );\r\n};\r\n","import React, { useRef, useEffect } from 'react';\r\nimport type { ChatMessage } from '../types';\r\nimport type { ChatStyles } from '../styles/theme';\r\nimport { MessageBubble } from './MessageBubble';\r\nimport { QuickReplies } from './QuickReplies';\r\nimport { TypingIndicator } from './TypingIndicator';\r\nimport { DynamicForm } from './forms/DynamicForm';\r\n\r\ninterface MessageListProps {\r\n messages: ChatMessage[];\r\n isTyping: boolean;\r\n styles: ChatStyles;\r\n primaryColor: string;\r\n onQuickReply: (value: string, label: string) => void;\r\n onFormSubmit: (formId: string, data: Record<string, unknown>) => void;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({\r\n messages,\r\n isTyping,\r\n styles,\r\n primaryColor,\r\n onQuickReply,\r\n onFormSubmit,\r\n}) => {\r\n const bottomRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isTyping]);\r\n\r\n return (\r\n <div style={styles.messageList}>\r\n {messages.map((msg) => (\r\n <React.Fragment key={msg.id}>\r\n <MessageBubble message={msg} styles={styles} />\r\n {msg.quickReplies && msg.quickReplies.length > 0 && (\r\n <QuickReplies\r\n replies={msg.quickReplies}\r\n onSelect={onQuickReply}\r\n primaryColor={primaryColor}\r\n />\r\n )}\r\n {msg.form && (\r\n <div style={{ alignSelf: 'flex-start', width: '90%' }}>\r\n <DynamicForm\r\n config={msg.form}\r\n onSubmit={(data) => onFormSubmit(msg.form!.id, data)}\r\n primaryColor={primaryColor}\r\n />\r\n </div>\r\n )}\r\n </React.Fragment>\r\n ))}\r\n {isTyping && <TypingIndicator color={primaryColor} />}\r\n <div ref={bottomRef} />\r\n </div>\r\n );\r\n};\r\n","import React, { useState, useRef } from 'react';\r\nimport type { CSSProperties } from 'react';\r\n\r\ninterface ChatInputProps {\r\n onSend: (text: string) => void;\r\n placeholder?: string;\r\n primaryColor: string;\r\n disabled?: boolean;\r\n styleOverride?: CSSProperties;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({\r\n onSend,\r\n placeholder = 'Type a message...',\r\n primaryColor,\r\n disabled,\r\n styleOverride,\r\n}) => {\r\n const [text, setText] = useState('');\r\n const inputRef = useRef<HTMLTextAreaElement>(null);\r\n\r\n const handleSend = () => {\r\n const trimmed = text.trim();\r\n if (!trimmed) return;\r\n onSend(trimmed);\r\n setText('');\r\n inputRef.current?.focus();\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div style={{ display: 'flex', gap: '8px', alignItems: 'flex-end', ...styleOverride }}>\r\n <textarea\r\n ref={inputRef}\r\n value={text}\r\n onChange={(e) => setText(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder={placeholder}\r\n disabled={disabled}\r\n rows={1}\r\n style={{\r\n flex: 1,\r\n padding: '10px 14px',\r\n border: '1px solid #E0E0E0',\r\n borderRadius: '20px',\r\n outline: 'none',\r\n resize: 'none',\r\n fontFamily: 'inherit',\r\n fontSize: '14px',\r\n lineHeight: '1.4',\r\n maxHeight: '100px',\r\n overflowY: 'auto',\r\n }}\r\n />\r\n <button\r\n onClick={handleSend}\r\n disabled={disabled || !text.trim()}\r\n aria-label=\"Send message\"\r\n style={{\r\n width: '38px',\r\n height: '38px',\r\n borderRadius: '50%',\r\n backgroundColor: text.trim() ? primaryColor : '#CCC',\r\n color: '#fff',\r\n border: 'none',\r\n cursor: text.trim() ? 'pointer' : 'default',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n flexShrink: 0,\r\n transition: 'background-color 0.15s ease',\r\n }}\r\n >\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\r\n </svg>\r\n </button>\r\n </div>\r\n );\r\n};\r\n","import type { FlowConfig, FlowStep, ChatMessage, FlowQuickReply } from '../types';\r\n\r\nlet idCounter = 0;\r\nconst uid = (): string => `msg_${Date.now()}_${++idCounter}`;\r\n\r\nexport class FlowEngine {\r\n private steps: Map<string, FlowStep>;\r\n private startStep: string;\r\n private collectedData: Record<string, unknown> = {};\r\n\r\n constructor(flow: FlowConfig) {\r\n this.startStep = flow.startStep;\r\n this.steps = new Map(flow.steps.map((s) => [s.id, s]));\r\n }\r\n\r\n getStartStepId(): string {\r\n return this.startStep;\r\n }\r\n\r\n getStep(id: string): FlowStep | undefined {\r\n return this.steps.get(id);\r\n }\r\n\r\n getData(): Record<string, unknown> {\r\n return { ...this.collectedData };\r\n }\r\n\r\n setData(key: string, value: unknown): void {\r\n this.collectedData[key] = value;\r\n }\r\n\r\n mergeData(data: Record<string, unknown>): void {\r\n Object.assign(this.collectedData, data);\r\n }\r\n\r\n resolveNext(step: FlowStep, userValue?: string): string | undefined {\r\n // Conditional branching\r\n if (step.condition) {\r\n const { field, operator, value, then: thenStep, else: elseStep } = step.condition;\r\n const fieldVal = this.collectedData[field];\r\n const match = this.evaluate(fieldVal, operator, value);\r\n return match ? thenStep : elseStep;\r\n }\r\n\r\n // Quick-reply selected → find the reply's next\r\n if (userValue && step.quickReplies) {\r\n const reply = step.quickReplies.find((r) => r.value === userValue);\r\n if (reply?.next) return reply.next;\r\n }\r\n\r\n return step.next;\r\n }\r\n\r\n buildMessages(step: FlowStep): ChatMessage[] {\r\n const messages: ChatMessage[] = [];\r\n\r\n const texts = step.messages ?? (step.message ? [step.message] : []);\r\n for (const text of texts) {\r\n messages.push({\r\n id: uid(),\r\n sender: 'bot',\r\n text,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n // Attach quick replies to the last message\r\n if (step.quickReplies && messages.length > 0) {\r\n messages[messages.length - 1]!.quickReplies = step.quickReplies;\r\n }\r\n\r\n // If step has a form, create a form message\r\n if (step.form) {\r\n messages.push({\r\n id: uid(),\r\n sender: 'bot',\r\n timestamp: Date.now(),\r\n form: step.form,\r\n });\r\n }\r\n\r\n return messages;\r\n }\r\n\r\n private evaluate(\r\n fieldVal: unknown,\r\n operator: string,\r\n value: string | number,\r\n ): boolean {\r\n switch (operator) {\r\n case 'eq':\r\n return String(fieldVal) === String(value);\r\n case 'neq':\r\n return String(fieldVal) !== String(value);\r\n case 'contains':\r\n return String(fieldVal).includes(String(value));\r\n case 'gt':\r\n return Number(fieldVal) > Number(value);\r\n case 'lt':\r\n return Number(fieldVal) < Number(value);\r\n default:\r\n return false;\r\n }\r\n }\r\n}\r\n\r\nexport function createQuickReplyMessage(\r\n replies: FlowQuickReply[],\r\n): ChatMessage {\r\n return {\r\n id: uid(),\r\n sender: 'bot',\r\n timestamp: Date.now(),\r\n quickReplies: replies,\r\n };\r\n}\r\n","let counter = 0;\r\n\r\nexport const uid = (): string => `msg_${Date.now()}_${++counter}`;\r\n\r\nexport const classNames = (...args: (string | false | null | undefined)[]): string =>\r\n args.filter(Boolean).join(' ');\r\n\r\nexport const delay = (ms: number): Promise<void> =>\r\n new Promise((resolve) => setTimeout(resolve, ms));\r\n","import { useCallback, useRef, useEffect } from 'react';\r\nimport { useChatContext } from '../context/ChatContext';\r\nimport { FlowEngine } from '../engine/FlowEngine';\r\nimport { uid, delay } from '../utils/helpers';\r\nimport type { ChatMessage, FormConfig } from '../types';\r\n\r\nexport function useChat() {\r\n const { state, dispatch, props } = useChatContext();\r\n const flowRef = useRef<FlowEngine | null>(null);\r\n const flowStartedRef = useRef(false);\r\n\r\n // Initialize flow engine\r\n useEffect(() => {\r\n if (props.flow) {\r\n flowRef.current = new FlowEngine(props.flow);\r\n flowStartedRef.current = false;\r\n }\r\n }, [props.flow]);\r\n\r\n const addBotMessage = useCallback(\r\n async (text: string, extras?: Partial<ChatMessage>) => {\r\n dispatch({ type: 'SET_TYPING', payload: true });\r\n await delay(400);\r\n const msg: ChatMessage = {\r\n id: uid(),\r\n sender: 'bot',\r\n text,\r\n timestamp: Date.now(),\r\n ...extras,\r\n };\r\n dispatch({ type: 'SET_TYPING', payload: false });\r\n dispatch({ type: 'ADD_MESSAGE', payload: msg });\r\n props.callbacks?.onMessageReceive?.(msg);\r\n },\r\n [dispatch, props.callbacks],\r\n );\r\n\r\n const sendMessage = useCallback(\r\n (text: string) => {\r\n const msg: ChatMessage = {\r\n id: uid(),\r\n sender: 'user',\r\n text,\r\n timestamp: Date.now(),\r\n };\r\n dispatch({ type: 'ADD_MESSAGE', payload: msg });\r\n props.callbacks?.onMessageSend?.(msg);\r\n props.callbacks?.onSubmit?.({ message: text });\r\n\r\n // Process flow\r\n if (flowRef.current && state.currentStepId) {\r\n const step = flowRef.current.getStep(state.currentStepId);\r\n if (step) {\r\n flowRef.current.setData(step.id, text);\r\n const nextId = flowRef.current.resolveNext(step, text);\r\n if (nextId) {\r\n processFlowStep(nextId);\r\n } else {\r\n props.callbacks?.onFlowEnd?.(flowRef.current.getData());\r\n dispatch({ type: 'SET_STEP', payload: null });\r\n }\r\n }\r\n }\r\n },\r\n [dispatch, props.callbacks, state.currentStepId],\r\n );\r\n\r\n const processFlowStep = useCallback(\r\n async (stepId: string) => {\r\n const engine = flowRef.current;\r\n if (!engine) return;\r\n\r\n const step = engine.getStep(stepId);\r\n if (!step) return;\r\n\r\n dispatch({ type: 'SET_STEP', payload: stepId });\r\n dispatch({ type: 'SET_TYPING', payload: true });\r\n await delay(step.delay ?? 500);\r\n\r\n const messages = engine.buildMessages(step);\r\n dispatch({ type: 'SET_TYPING', payload: false });\r\n dispatch({ type: 'ADD_MESSAGES', payload: messages });\r\n\r\n messages.forEach((m) => props.callbacks?.onMessageReceive?.(m));\r\n\r\n // Auto-advance if no user input required\r\n if (!step.quickReplies && !step.form && step.next) {\r\n await delay(300);\r\n processFlowStep(step.next);\r\n }\r\n },\r\n [dispatch, props.callbacks],\r\n );\r\n\r\n const startFlow = useCallback(() => {\r\n const engine = flowRef.current;\r\n if (!engine || flowStartedRef.current) return;\r\n flowStartedRef.current = true;\r\n processFlowStep(engine.getStartStepId());\r\n }, [processFlowStep]);\r\n\r\n // Auto-start flow when all conditions are met\r\n useEffect(() => {\r\n if (\r\n props.flow &&\r\n !state.showWelcome &&\r\n state.isLoggedIn &&\r\n !flowStartedRef.current\r\n ) {\r\n startFlow();\r\n }\r\n }, [props.flow, state.showWelcome, state.isLoggedIn, startFlow]);\r\n\r\n const handleQuickReply = useCallback(\r\n (value: string, label: string) => {\r\n dispatch({ type: 'CLEAR_QUICK_REPLIES' });\r\n // Add user message\r\n const msg: ChatMessage = {\r\n id: uid(),\r\n sender: 'user',\r\n text: label,\r\n timestamp: Date.now(),\r\n };\r\n dispatch({ type: 'ADD_MESSAGE', payload: msg });\r\n props.callbacks?.onQuickReply?.(value, label);\r\n\r\n // Continue flow\r\n if (flowRef.current && state.currentStepId) {\r\n const step = flowRef.current.getStep(state.currentStepId);\r\n if (step) {\r\n flowRef.current.setData(step.id, value);\r\n const nextId = flowRef.current.resolveNext(step, value);\r\n if (nextId) {\r\n processFlowStep(nextId);\r\n } else {\r\n props.callbacks?.onFlowEnd?.(flowRef.current.getData());\r\n dispatch({ type: 'SET_STEP', payload: null });\r\n }\r\n }\r\n }\r\n },\r\n [dispatch, props.callbacks, state.currentStepId, processFlowStep],\r\n );\r\n\r\n const handleFormSubmit = useCallback(\r\n async (formId: string, data: Record<string, unknown>) => {\r\n dispatch({ type: 'SET_DATA', payload: data });\r\n if (flowRef.current) {\r\n flowRef.current.mergeData(data);\r\n }\r\n\r\n // Summary message\r\n const summaryLines = Object.entries(data)\r\n .filter(([, v]) => v !== undefined && v !== '')\r\n .map(([k, v]) => `${k}: ${String(v)}`)\r\n .join('\\n');\r\n const msg: ChatMessage = {\r\n id: uid(),\r\n sender: 'user',\r\n text: summaryLines,\r\n formData: data,\r\n timestamp: Date.now(),\r\n };\r\n dispatch({ type: 'ADD_MESSAGE', payload: msg });\r\n\r\n await props.callbacks?.onFormSubmit?.(formId, data);\r\n\r\n // Advance flow\r\n if (flowRef.current && state.currentStepId) {\r\n const step = flowRef.current.getStep(state.currentStepId);\r\n if (step) {\r\n const nextId = flowRef.current.resolveNext(step);\r\n if (nextId) {\r\n processFlowStep(nextId);\r\n } else {\r\n props.callbacks?.onFlowEnd?.(flowRef.current.getData());\r\n dispatch({ type: 'SET_STEP', payload: null });\r\n }\r\n }\r\n }\r\n },\r\n [dispatch, props.callbacks, state.currentStepId, processFlowStep],\r\n );\r\n\r\n const handleLogin = useCallback(\r\n async (data: Record<string, unknown>) => {\r\n await props.callbacks?.onLogin?.(data);\r\n dispatch({ type: 'SET_LOGGED_IN', payload: true });\r\n },\r\n [dispatch, props.callbacks],\r\n );\r\n\r\n const toggleChat = useCallback(() => {\r\n const willOpen = !state.isOpen;\r\n dispatch({ type: 'TOGGLE_OPEN' });\r\n if (willOpen) {\r\n props.callbacks?.onOpen?.();\r\n } else {\r\n props.callbacks?.onClose?.();\r\n }\r\n }, [dispatch, state.isOpen, props.callbacks]);\r\n\r\n const dismissWelcome = useCallback(() => {\r\n dispatch({ type: 'DISMISS_WELCOME' });\r\n }, [dispatch]);\r\n\r\n return {\r\n state,\r\n sendMessage,\r\n addBotMessage,\r\n handleQuickReply,\r\n handleFormSubmit,\r\n handleLogin,\r\n toggleChat,\r\n dismissWelcome,\r\n startFlow,\r\n processFlowStep,\r\n };\r\n}\r\n","import React from 'react';\r\nimport type { CSSProperties } from 'react';\r\nimport type { ChatStyles } from '../styles/theme';\r\nimport { ChatHeader } from './ChatHeader';\r\nimport { WelcomeScreen } from './WelcomeScreen';\r\nimport { LoginScreen } from './LoginScreen';\r\nimport { MessageList } from './MessageList';\r\nimport { ChatInput } from './ChatInput';\r\nimport { useChat } from '../hooks/useChat';\r\nimport { useChatContext } from '../context/ChatContext';\r\nimport { resolveTheme } from '../styles/theme';\r\n\r\ninterface ChatWindowProps {\r\n styles: ChatStyles;\r\n position: 'bottom-right' | 'bottom-left';\r\n zIndex?: number;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({ styles, position, zIndex }) => {\r\n const { props } = useChatContext();\r\n const theme = resolveTheme(props.theme);\r\n const {\r\n state,\r\n sendMessage,\r\n handleQuickReply,\r\n handleFormSubmit,\r\n handleLogin,\r\n toggleChat,\r\n dismissWelcome,\r\n } = useChat();\r\n\r\n const posStyle: CSSProperties =\r\n position === 'bottom-left'\r\n ? { bottom: '90px', left: '20px' }\r\n : { bottom: '90px', right: '20px' };\r\n\r\n return (\r\n <div\r\n style={{\r\n ...styles.window,\r\n ...posStyle,\r\n ...(zIndex != null ? { zIndex } : {}),\r\n }}\r\n >\r\n <ChatHeader\r\n config={props.header ?? { title: 'Chat with us' }}\r\n styles={styles}\r\n onClose={toggleChat}\r\n />\r\n\r\n {/* Welcome Screen */}\r\n {state.showWelcome && props.welcomeScreen ? (\r\n <WelcomeScreen\r\n content={props.welcomeScreen}\r\n onDismiss={dismissWelcome}\r\n primaryColor={theme.primaryColor}\r\n />\r\n ) : /* Login Screen */\r\n !state.isLoggedIn && props.loginForm ? (\r\n <LoginScreen\r\n config={props.loginForm}\r\n onLogin={handleLogin}\r\n primaryColor={theme.primaryColor}\r\n />\r\n ) : (\r\n /* Chat Area */\r\n <>\r\n <MessageList\r\n messages={state.messages}\r\n isTyping={state.isTyping}\r\n styles={styles}\r\n primaryColor={theme.primaryColor}\r\n onQuickReply={handleQuickReply}\r\n onFormSubmit={handleFormSubmit}\r\n />\r\n <div style={styles.inputArea}>\r\n <ChatInput\r\n onSend={sendMessage}\r\n placeholder={props.inputPlaceholder}\r\n primaryColor={theme.primaryColor}\r\n />\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { useReducer } from 'react';\r\nimport type { ChatBotProps } from '../types';\r\nimport { ChatContext, chatReducer, initialState } from '../context/ChatContext';\r\nimport { resolveTheme, buildStyles } from '../styles/theme';\r\nimport { Launcher } from './Launcher';\r\nimport { ChatWindow } from './ChatWindow';\r\n\r\nexport const ChatBot: React.FC<ChatBotProps> = (props) => {\r\n const [state, dispatch] = useReducer(chatReducer, props, initialState);\r\n const theme = resolveTheme(props.theme);\r\n const styles = buildStyles(theme, props.style);\r\n const position = props.position ?? 'bottom-right';\r\n const showLauncher = props.showLauncher !== false;\r\n\r\n\r\n\r\n return (\r\n <ChatContext.Provider value={{ state, dispatch, props }}>\r\n <div style={styles.root} className={props.className}>\r\n {state.isOpen && (\r\n <ChatWindow styles={styles} position={position} zIndex={props.zIndex} />\r\n )}\r\n {showLauncher && (\r\n <Launcher\r\n onClick={() => {\r\n const willOpen = !state.isOpen;\r\n dispatch({ type: 'TOGGLE_OPEN' });\r\n if (willOpen) props.callbacks?.onOpen?.();\r\n else props.callbacks?.onClose?.();\r\n }}\r\n isOpen={state.isOpen}\r\n position={position}\r\n styles={styles}\r\n icon={props.launcherIcon}\r\n closeIcon={props.closeIcon}\r\n zIndex={props.zIndex}\r\n />\r\n )}\r\n </div>\r\n </ChatContext.Provider>\r\n );\r\n};\r\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@enjoys/react-chatbot-plugin",
3
+ "version": "1.0.0",
4
+ "description": "A customizable, plugin-based chatbot widget for React — like tawk.to",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.cjs",
13
+ "types": "./dist/index.d.ts"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "dev": "vite --config vite.demo.config.ts",
21
+ "build": "vite build",
22
+ "build:demo": "vite build --config vite.demo.config.ts"
23
+ },
24
+ "peerDependencies": {
25
+ "react": ">=18.0.0",
26
+ "react-dom": ">=18.0.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/bun": "latest",
30
+ "@types/react": "^19.2.14",
31
+ "@types/react-dom": "^19.2.3",
32
+ "@vitejs/plugin-react": "^6.0.1",
33
+ "esbuild": "^0.27.4",
34
+ "typescript": "^5.9.3",
35
+ "vite": "^8.0.1",
36
+ "vite-plugin-dts": "^4.5.4"
37
+ },
38
+ "dependencies": {
39
+ "react": "^19.2.4",
40
+ "react-dom": "^19.2.4"
41
+ },
42
+ "license": "MIT",
43
+ "keywords": ["chatbot", "react", "widget", "tawk", "chat", "plugin"]
44
+ }