@schmitech/chatbot-widget 0.4.2 → 0.4.3
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.
- package/dist/ChatWidget.d.ts +11 -0
- package/dist/chatbot-widget.bundle.js +765 -0
- package/dist/chatbot-widget.css +1 -0
- package/dist/chatbot-widget.es.js +24356 -0
- package/dist/chatbot-widget.umd.js +755 -0
- package/dist/config/index.d.ts +71 -0
- package/dist/config.d.ts +42 -0
- package/dist/hooks/useAnimationManagement.d.ts +16 -0
- package/dist/hooks/useInputManagement.d.ts +21 -0
- package/dist/hooks/useScrollManagement.d.ts +17 -0
- package/dist/index.d.ts +19 -0
- package/dist/shared/ChatIcon.d.ts +12 -0
- package/dist/shared/MarkdownComponents.d.ts +18 -0
- package/dist/shared/styles.d.ts +76 -0
- package/dist/store/chatStore.d.ts +17 -0
- package/dist/ui/ChatInput.d.ts +17 -0
- package/dist/ui/Message.d.ts +26 -0
- package/dist/ui/MessagesList.d.ts +35 -0
- package/dist/ui/TypingEffect.d.ts +17 -0
- package/dist/utils/sessionManager.d.ts +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export interface ChatConfig {
|
|
2
|
+
header: {
|
|
3
|
+
title: string;
|
|
4
|
+
};
|
|
5
|
+
theme: {
|
|
6
|
+
primary: string;
|
|
7
|
+
secondary: string;
|
|
8
|
+
background: string;
|
|
9
|
+
text: {
|
|
10
|
+
primary: string;
|
|
11
|
+
inverse: string;
|
|
12
|
+
};
|
|
13
|
+
input: {
|
|
14
|
+
background: string;
|
|
15
|
+
border: string;
|
|
16
|
+
};
|
|
17
|
+
message: {
|
|
18
|
+
user: string;
|
|
19
|
+
userText: string;
|
|
20
|
+
assistant: string;
|
|
21
|
+
};
|
|
22
|
+
suggestedQuestions: {
|
|
23
|
+
background: string;
|
|
24
|
+
text: string;
|
|
25
|
+
hoverBackground: string;
|
|
26
|
+
};
|
|
27
|
+
chatButton: {
|
|
28
|
+
background: string;
|
|
29
|
+
hoverBackground?: string;
|
|
30
|
+
};
|
|
31
|
+
iconColor?: string;
|
|
32
|
+
};
|
|
33
|
+
welcome: {
|
|
34
|
+
title: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
suggestedQuestions: Array<{
|
|
38
|
+
text: string;
|
|
39
|
+
query: string;
|
|
40
|
+
}>;
|
|
41
|
+
icon?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare const defaultTheme: {
|
|
44
|
+
primary: string;
|
|
45
|
+
secondary: string;
|
|
46
|
+
background: string;
|
|
47
|
+
text: {
|
|
48
|
+
primary: string;
|
|
49
|
+
inverse: string;
|
|
50
|
+
};
|
|
51
|
+
input: {
|
|
52
|
+
background: string;
|
|
53
|
+
border: string;
|
|
54
|
+
};
|
|
55
|
+
message: {
|
|
56
|
+
user: string;
|
|
57
|
+
userText: string;
|
|
58
|
+
assistant: string;
|
|
59
|
+
};
|
|
60
|
+
suggestedQuestions: {
|
|
61
|
+
background: string;
|
|
62
|
+
text: string;
|
|
63
|
+
hoverBackground: string;
|
|
64
|
+
};
|
|
65
|
+
chatButton: {
|
|
66
|
+
background: string;
|
|
67
|
+
hoverBackground: string;
|
|
68
|
+
};
|
|
69
|
+
iconColor: string;
|
|
70
|
+
};
|
|
71
|
+
export declare const getChatConfig: () => ChatConfig;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ThemeConfig {
|
|
2
|
+
primary: string;
|
|
3
|
+
secondary: string;
|
|
4
|
+
background: string;
|
|
5
|
+
text: {
|
|
6
|
+
primary: string;
|
|
7
|
+
secondary: string;
|
|
8
|
+
inverse: string;
|
|
9
|
+
};
|
|
10
|
+
input: {
|
|
11
|
+
background: string;
|
|
12
|
+
border: string;
|
|
13
|
+
};
|
|
14
|
+
message: {
|
|
15
|
+
user: string;
|
|
16
|
+
assistant: string;
|
|
17
|
+
userText: string;
|
|
18
|
+
};
|
|
19
|
+
suggestedQuestions: {
|
|
20
|
+
background: string;
|
|
21
|
+
hoverBackground: string;
|
|
22
|
+
text: string;
|
|
23
|
+
};
|
|
24
|
+
iconColor: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const defaultTheme: ThemeConfig;
|
|
27
|
+
export type IconType = 'heart' | 'message-square' | 'message-circle' | 'help-circle' | 'info' | 'bot' | 'sparkles';
|
|
28
|
+
export interface ChatConfig {
|
|
29
|
+
header: {
|
|
30
|
+
title: string;
|
|
31
|
+
};
|
|
32
|
+
welcome: {
|
|
33
|
+
title: string;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
suggestedQuestions: Array<{
|
|
37
|
+
text: string;
|
|
38
|
+
query: string;
|
|
39
|
+
}>;
|
|
40
|
+
theme: ThemeConfig;
|
|
41
|
+
icon?: IconType;
|
|
42
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface AnimationManagementReturn {
|
|
2
|
+
isAnimating: boolean;
|
|
3
|
+
animatedMessagesRef: React.MutableRefObject<Set<number>>;
|
|
4
|
+
typingProgressRef: React.MutableRefObject<Map<number, number>>;
|
|
5
|
+
isTypingRef: React.MutableRefObject<boolean>;
|
|
6
|
+
lastMessageRef: React.RefObject<HTMLDivElement>;
|
|
7
|
+
markMessageAnimated: (index: number, messagesLength: number, scrollToBottom: () => void) => void;
|
|
8
|
+
hasBeenAnimated: (index: number) => boolean;
|
|
9
|
+
clearAnimationTrackers: () => void;
|
|
10
|
+
setIsAnimating: (value: boolean) => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Custom hook for managing typing animations and animation state
|
|
14
|
+
* Handles message animation tracking, progress persistence, and animation lifecycle
|
|
15
|
+
*/
|
|
16
|
+
export declare const useAnimationManagement: () => AnimationManagementReturn;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface InputManagementReturn {
|
|
2
|
+
message: string;
|
|
3
|
+
isFocused: boolean;
|
|
4
|
+
inputRef: React.RefObject<HTMLTextAreaElement>;
|
|
5
|
+
handleMessageChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
6
|
+
handleKeyDown: (e: React.KeyboardEvent) => void;
|
|
7
|
+
handleSendMessage: () => void;
|
|
8
|
+
setIsFocused: (focused: boolean) => void;
|
|
9
|
+
clearMessage: () => void;
|
|
10
|
+
focusInput: () => void;
|
|
11
|
+
}
|
|
12
|
+
export interface InputManagementProps {
|
|
13
|
+
onSendMessage: (message: string) => void;
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
isOpen: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Custom hook for managing message input state and interactions
|
|
19
|
+
* Handles input validation, keyboard shortcuts, and focus management
|
|
20
|
+
*/
|
|
21
|
+
export declare const useInputManagement: ({ onSendMessage, isLoading, isOpen }: InputManagementProps) => InputManagementReturn;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ScrollManagementReturn {
|
|
2
|
+
showScrollTop: boolean;
|
|
3
|
+
showScrollBottom: boolean;
|
|
4
|
+
isScrolling: boolean;
|
|
5
|
+
messagesContainerRef: React.RefObject<HTMLDivElement>;
|
|
6
|
+
messagesEndRef: React.RefObject<HTMLDivElement>;
|
|
7
|
+
shouldScrollRef: React.MutableRefObject<boolean>;
|
|
8
|
+
scrollTimeoutRef: React.MutableRefObject<number | undefined>;
|
|
9
|
+
scrollToBottom: (immediate?: boolean) => void;
|
|
10
|
+
scrollToTop: () => void;
|
|
11
|
+
handleScroll: () => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Custom hook for managing scroll behavior in the chat messages container
|
|
15
|
+
* Handles scroll buttons visibility, smooth scrolling, and scroll position tracking
|
|
16
|
+
*/
|
|
17
|
+
export declare const useScrollManagement: (isAnimating: boolean) => ScrollManagementReturn;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ChatWidget, ChatWidgetProps } from './ChatWidget';
|
|
2
|
+
import { useChatStore } from './store/chatStore';
|
|
3
|
+
import './index.css';
|
|
4
|
+
import { getChatConfig, ChatConfig } from './config/index';
|
|
5
|
+
export { ChatWidget, useChatStore, getChatConfig };
|
|
6
|
+
export type { ChatWidgetProps, ChatConfig };
|
|
7
|
+
export default ChatWidget;
|
|
8
|
+
export declare function getApiUrl(): string;
|
|
9
|
+
export declare function getApiKey(): string;
|
|
10
|
+
export declare function setApiUrl(url: string): void;
|
|
11
|
+
export declare function setApiKey(key: string): void;
|
|
12
|
+
export declare function updateWidgetConfig(config: Partial<ChatConfig>): void;
|
|
13
|
+
export declare function injectChatWidget(config: {
|
|
14
|
+
apiUrl: string;
|
|
15
|
+
apiKey: string;
|
|
16
|
+
sessionId?: string;
|
|
17
|
+
containerSelector?: string;
|
|
18
|
+
widgetConfig?: Partial<ChatConfig>;
|
|
19
|
+
}): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ChatIconProps {
|
|
3
|
+
iconName?: string;
|
|
4
|
+
size?: number;
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* ChatIcon component renders different icons based on the iconName prop
|
|
10
|
+
* Supports various chat-related icons with consistent sizing and styling
|
|
11
|
+
*/
|
|
12
|
+
export declare const ChatIcon: React.FC<ChatIconProps>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import 'katex/dist/katex.min.css';
|
|
3
|
+
/**
|
|
4
|
+
* Preprocesses markdown content to handle common formatting issues
|
|
5
|
+
*/
|
|
6
|
+
export declare const preprocessMarkdown: (content: string) => string;
|
|
7
|
+
/**
|
|
8
|
+
* Custom link component for ReactMarkdown that opens links in new tabs
|
|
9
|
+
*/
|
|
10
|
+
export declare const MarkdownLink: React.FC<React.AnchorHTMLAttributes<HTMLAnchorElement>>;
|
|
11
|
+
export interface MarkdownRendererProps {
|
|
12
|
+
content: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Enhanced Markdown renderer with better formatting and spacing control
|
|
17
|
+
*/
|
|
18
|
+
export declare const MarkdownRenderer: React.FC<MarkdownRendererProps>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export declare const DEFAULT_MAX_SUGGESTED_QUESTION_LENGTH = 50;
|
|
2
|
+
export declare const DEFAULT_MAX_SUGGESTED_QUESTION_QUERY_LENGTH = 200;
|
|
3
|
+
export declare let CHAT_CONSTANTS: {
|
|
4
|
+
MAX_MESSAGE_LENGTH: number;
|
|
5
|
+
MAX_SUGGESTED_QUESTION_LENGTH: number;
|
|
6
|
+
MAX_SUGGESTED_QUESTION_QUERY_LENGTH: number;
|
|
7
|
+
WINDOW_DIMENSIONS: {
|
|
8
|
+
readonly HEIGHT: "600px";
|
|
9
|
+
readonly MAX_HEIGHT: "calc(100vh - 80px)";
|
|
10
|
+
readonly BREAKPOINTS: {
|
|
11
|
+
readonly SM: 640;
|
|
12
|
+
readonly MD: 768;
|
|
13
|
+
readonly LG: 1024;
|
|
14
|
+
};
|
|
15
|
+
readonly WIDTHS: {
|
|
16
|
+
readonly SM: "480px";
|
|
17
|
+
readonly MD: "600px";
|
|
18
|
+
readonly LG: "700px";
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
SCROLL_THRESHOLDS: {
|
|
22
|
+
readonly BOTTOM_THRESHOLD: 10;
|
|
23
|
+
readonly TOP_THRESHOLD: 10;
|
|
24
|
+
readonly SHOW_SCROLL_TOP_OFFSET: 200;
|
|
25
|
+
};
|
|
26
|
+
ANIMATIONS: {
|
|
27
|
+
readonly SCROLL_TIMEOUT: 300;
|
|
28
|
+
readonly TOGGLE_DELAY: 100;
|
|
29
|
+
readonly ANIMATION_SCROLL_INTERVAL: 100;
|
|
30
|
+
readonly COPY_FEEDBACK_DURATION: 2000;
|
|
31
|
+
readonly VISIBILITY_SKIP_THRESHOLD: 1000;
|
|
32
|
+
};
|
|
33
|
+
BUTTON_SIZES: {
|
|
34
|
+
readonly CHAT_BUTTON: {
|
|
35
|
+
readonly width: "68px";
|
|
36
|
+
readonly height: "68px";
|
|
37
|
+
};
|
|
38
|
+
readonly SEND_BUTTON: {
|
|
39
|
+
readonly width: "52px";
|
|
40
|
+
readonly height: "52px";
|
|
41
|
+
};
|
|
42
|
+
readonly ICON_SIZES: {
|
|
43
|
+
readonly HEADER: 28;
|
|
44
|
+
readonly WELCOME: 56;
|
|
45
|
+
readonly BUTTON: 20;
|
|
46
|
+
readonly SEND: 24;
|
|
47
|
+
readonly MINIMIZE: 28;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Global CSS styles for the ChatWidget component
|
|
53
|
+
*/
|
|
54
|
+
export declare const CHAT_WIDGET_STYLES = "\n @import url('https://fonts.googleapis.com/css2?family=Mona+Sans:ital,wght@0,200..900;1,200..900&display=swap');\n \n body, button, input, textarea {\n font-family: 'Mona Sans', -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n }\n \n /* Complete focus ring removal - covers all browsers and scenarios */\n textarea,\n textarea:focus,\n textarea:focus-visible,\n input,\n input:focus,\n input:focus-visible {\n outline: none !important;\n box-shadow: none !important;\n border-color: inherit !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n -webkit-tap-highlight-color: transparent !important;\n }\n \n /* Alternative: Uncomment for subtle light focus ring instead of complete removal */\n /*\n textarea:focus,\n textarea:focus-visible {\n outline: 2px solid rgba(203, 213, 225, 0.4) !important;\n outline-offset: -1px !important;\n box-shadow: 0 0 0 1px rgba(203, 213, 225, 0.2) !important;\n }\n */\n \n /* Remove webkit/safari specific styling */\n textarea::-webkit-input-placeholder,\n input::-webkit-input-placeholder {\n -webkit-appearance: none;\n }\n \n /* Ensure buttons also don't show focus rings */\n button:focus,\n button:focus-visible {\n outline: none !important;\n box-shadow: none !important;\n }\n\n /* Enhanced animations for modern feel */\n @keyframes slideInUp {\n 0% { \n opacity: 0; \n transform: translateY(20px) scale(0.95); \n }\n 100% { \n opacity: 1; \n transform: translateY(0) scale(1); \n }\n }\n\n @keyframes slideOutDown {\n 0% { \n opacity: 1; \n transform: translateY(0) scale(1); \n }\n 100% { \n opacity: 0; \n transform: translateY(20px) scale(0.95); \n }\n }\n\n .animate-slide-in-up {\n animation: slideInUp 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n }\n\n .animate-slide-out-down {\n animation: slideOutDown 0.2s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n }\n\n @keyframes pulseGlow {\n 0%, 100% { \n box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);\n }\n 50% { \n box-shadow: 0 0 0 8px rgba(59, 130, 246, 0);\n }\n }\n\n .animate-pulse-glow {\n animation: pulseGlow 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n }\n\n @keyframes messageEntry {\n 0% { \n opacity: 0; \n transform: translateY(10px) scale(0.98);\n }\n 100% { \n opacity: 1; \n transform: translateY(0) scale(1);\n }\n }\n\n .animate-message-entry {\n animation: messageEntry 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n }\n\n @keyframes buttonHover {\n 0% { transform: translateY(0) scale(1); }\n 100% { transform: translateY(-2px) scale(1.05); }\n }\n\n .animate-button-hover:hover {\n animation: buttonHover 0.2s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n }\n \n @keyframes fadeInOut {\n 0% { opacity: 0; transform: translateY(4px); }\n 20% { opacity: 1; transform: translateY(0); }\n 80% { opacity: 1; transform: translateY(0); }\n 100% { opacity: 0; transform: translateY(-4px); }\n }\n .animate-fade-in-out {\n animation: fadeInOut 2s ease-in-out forwards;\n }\n \n @keyframes bounce-gentle {\n 0%, 100% { transform: translateY(0); }\n 50% { transform: translateY(-8px); }\n }\n .animate-bounce-gentle {\n animation: bounce-gentle 3s ease-in-out infinite;\n animation-delay: 2s;\n }\n\n @keyframes float {\n 0%, 100% { transform: translateY(0px) rotate(0deg); }\n 33% { transform: translateY(-3px) rotate(1deg); }\n 66% { transform: translateY(2px) rotate(-1deg); }\n }\n .animate-float {\n animation: float 6s ease-in-out infinite;\n }\n \n @keyframes dotBlink {\n 0%, 50%, 100% { opacity: 0.3; }\n 25%, 75% { opacity: 1; }\n }\n .animate-dots {\n display: inline-flex;\n margin-left: 4px;\n }\n .animate-dots .dot {\n font-size: 1.2em;\n line-height: 0.5;\n opacity: 0.3;\n animation: dotBlink 1.6s infinite;\n color: #6b7280;\n }\n .animate-dots .dot:nth-child(1) {\n animation-delay: 0s;\n }\n .animate-dots .dot:nth-child(2) {\n animation-delay: 0.3s;\n }\n .animate-dots .dot:nth-child(3) {\n animation-delay: 0.6s;\n }\n\n /* Glassmorphism effects */\n .glass-effect {\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n background: rgba(255, 255, 255, 0.8);\n border: 1px solid rgba(255, 255, 255, 0.3);\n }\n\n .glass-effect-dark {\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n background: rgba(30, 41, 59, 0.8);\n border: 1px solid rgba(255, 255, 255, 0.1);\n }\n\n /* Custom scrollbar */\n .custom-scrollbar::-webkit-scrollbar {\n width: 6px;\n }\n\n .custom-scrollbar::-webkit-scrollbar-track {\n background: rgba(0, 0, 0, 0.05);\n border-radius: 3px;\n }\n\n .custom-scrollbar::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.2);\n border-radius: 3px;\n transition: background 0.2s ease;\n }\n\n .custom-scrollbar::-webkit-scrollbar-thumb:hover {\n background: rgba(0, 0, 0, 0.3);\n }\n\n /* Enhanced shadows */\n .shadow-elegant {\n box-shadow: \n 0 10px 25px -5px rgba(0, 0, 0, 0.1),\n 0 8px 10px -6px rgba(0, 0, 0, 0.1),\n 0 0 0 1px rgba(255, 255, 255, 0.05);\n }\n\n .shadow-soft {\n box-shadow: \n 0 4px 6px -1px rgba(0, 0, 0, 0.1),\n 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n }\n\n .shadow-floating {\n box-shadow: \n 0 20px 25px -5px rgba(0, 0, 0, 0.1),\n 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n }\n \n .prose {\n max-width: 100%;\n }\n \n .prose > * {\n margin-top: 0 !important;\n margin-bottom: 0.5em !important;\n }\n \n .prose p {\n margin: 0 0 0.5em 0 !important;\n padding: 0;\n line-height: 1.6;\n }\n \n .prose p:last-child {\n margin-bottom: 0 !important;\n }\n \n .prose ul,\n .prose ol {\n margin-top: 0.5em !important;\n margin-bottom: 0.5em !important;\n padding-left: 1.5em !important;\n }\n \n .prose li {\n margin-bottom: 0.25em !important;\n padding-left: 0.25em !important;\n line-height: 1.5;\n }\n \n .prose li p {\n margin: 0 !important;\n }\n \n .prose li + li {\n margin-top: 0.1em !important;\n }\n \n .prose h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6 {\n margin-top: 1em !important;\n margin-bottom: 0.5em !important;\n font-weight: 600;\n }\n\n /* Button enhancements */\n .btn-modern {\n position: relative;\n overflow: hidden;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .btn-modern::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0));\n opacity: 0;\n transition: opacity 0.3s ease;\n }\n\n .btn-modern:hover::before {\n opacity: 1;\n }\n\n /* Input enhancements */\n .input-modern {\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .input-modern:focus {\n transform: translateY(-1px);\n }\n ";
|
|
55
|
+
/**
|
|
56
|
+
* Helper functions for responsive window dimensions
|
|
57
|
+
*/
|
|
58
|
+
export declare const getResponsiveWidth: (windowWidth: number) => string;
|
|
59
|
+
export declare const getResponsiveMinWidth: (windowWidth: number) => string;
|
|
60
|
+
/**
|
|
61
|
+
* Font family constant for consistent typography
|
|
62
|
+
*/
|
|
63
|
+
export declare const FONT_FAMILY = "Mona Sans, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif";
|
|
64
|
+
/**
|
|
65
|
+
* Character count styling helper
|
|
66
|
+
*/
|
|
67
|
+
export declare const getCharacterCountStyle: (length: number, maxLength: number) => {
|
|
68
|
+
color: string;
|
|
69
|
+
backgroundColor: string;
|
|
70
|
+
fontSize: string;
|
|
71
|
+
};
|
|
72
|
+
export declare function setChatConstants(config: Partial<{
|
|
73
|
+
MAX_MESSAGE_LENGTH?: number;
|
|
74
|
+
MAX_SUGGESTED_QUESTION_LENGTH?: number;
|
|
75
|
+
MAX_SUGGESTED_QUESTION_QUERY_LENGTH?: number;
|
|
76
|
+
}>): void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type MessageRole = 'user' | 'assistant' | 'system';
|
|
2
|
+
export interface Message {
|
|
3
|
+
role: MessageRole;
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
interface ChatState {
|
|
7
|
+
messages: Message[];
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
error: string | null;
|
|
10
|
+
sessionId: string;
|
|
11
|
+
sendMessage: (content: string) => Promise<void>;
|
|
12
|
+
appendToLastMessage: (content: string) => void;
|
|
13
|
+
clearMessages: () => void;
|
|
14
|
+
getSessionId: () => string;
|
|
15
|
+
}
|
|
16
|
+
export declare const useChatStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ChatState>>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ChatInputProps {
|
|
3
|
+
message: string;
|
|
4
|
+
isFocused: boolean;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
theme: any;
|
|
7
|
+
inputRef: React.RefObject<HTMLTextAreaElement>;
|
|
8
|
+
handleMessageChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
9
|
+
handleKeyDown: (e: React.KeyboardEvent) => void;
|
|
10
|
+
handleSendMessage: () => void;
|
|
11
|
+
setIsFocused: (focused: boolean) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* ChatInput component handles the message input area
|
|
15
|
+
* Includes textarea, character counter, and send button with proper styling
|
|
16
|
+
*/
|
|
17
|
+
export declare const ChatInput: React.FC<ChatInputProps>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Message as MessageType } from '../store/chatStore';
|
|
3
|
+
export interface MessageProps {
|
|
4
|
+
message: MessageType;
|
|
5
|
+
index: number;
|
|
6
|
+
isLatestAssistantMessage: boolean;
|
|
7
|
+
showTypingAnimation: boolean;
|
|
8
|
+
theme: any;
|
|
9
|
+
copiedMessageId: number | null;
|
|
10
|
+
onCopyToClipboard: (text: string, messageIndex: number) => void;
|
|
11
|
+
onMarkMessageAnimated: (index: number, messagesLength: number, scrollToBottom: () => void) => void;
|
|
12
|
+
messagesLength: number;
|
|
13
|
+
scrollToBottom: () => void;
|
|
14
|
+
inputRef: React.RefObject<HTMLTextAreaElement>;
|
|
15
|
+
hasBeenAnimated: (index: number) => boolean;
|
|
16
|
+
typingProgressRef: React.MutableRefObject<Map<number, number>>;
|
|
17
|
+
isTypingRef: React.MutableRefObject<boolean>;
|
|
18
|
+
setIsAnimating: (value: boolean) => void;
|
|
19
|
+
formatTime: (date: Date) => string;
|
|
20
|
+
lastMessageRef: React.RefObject<HTMLDivElement>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Message component handles individual message rendering
|
|
24
|
+
* Supports both user and assistant messages with different styling
|
|
25
|
+
*/
|
|
26
|
+
export declare const Message: React.FC<MessageProps>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Message as MessageType } from '../store/chatStore';
|
|
3
|
+
export interface MessagesListProps {
|
|
4
|
+
messages: MessageType[];
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
theme: any;
|
|
7
|
+
currentConfig: any;
|
|
8
|
+
showScrollTop: boolean;
|
|
9
|
+
showScrollBottom: boolean;
|
|
10
|
+
isAnimating: boolean;
|
|
11
|
+
messagesContainerRef: React.RefObject<HTMLDivElement>;
|
|
12
|
+
messagesEndRef: React.RefObject<HTMLDivElement>;
|
|
13
|
+
scrollToTop: () => void;
|
|
14
|
+
scrollToBottom: () => void;
|
|
15
|
+
handleScroll: () => void;
|
|
16
|
+
sendMessage: (message: string) => void;
|
|
17
|
+
focusInput: () => void;
|
|
18
|
+
copiedMessageId: number | null;
|
|
19
|
+
onCopyToClipboard: (text: string, messageIndex: number) => void;
|
|
20
|
+
onMarkMessageAnimated: (index: number, messagesLength: number, scrollToBottom: () => void) => void;
|
|
21
|
+
inputRef: React.RefObject<HTMLTextAreaElement>;
|
|
22
|
+
hasBeenAnimated: (index: number) => boolean;
|
|
23
|
+
typingProgressRef: React.MutableRefObject<Map<number, number>>;
|
|
24
|
+
isTypingRef: React.MutableRefObject<boolean>;
|
|
25
|
+
setIsAnimating: (value: boolean) => void;
|
|
26
|
+
formatTime: (date: Date) => string;
|
|
27
|
+
lastMessageRef: React.RefObject<HTMLDivElement>;
|
|
28
|
+
maxSuggestedQuestionLength?: number;
|
|
29
|
+
maxSuggestedQuestionQueryLength?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* MessagesList component handles the messages container area
|
|
33
|
+
* Includes empty state, scroll buttons, loading states, and message rendering
|
|
34
|
+
*/
|
|
35
|
+
export declare const MessagesList: React.FC<MessagesListProps>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface TypingEffectProps {
|
|
3
|
+
content: string;
|
|
4
|
+
onComplete: () => void;
|
|
5
|
+
messageIndex: number;
|
|
6
|
+
inputRef: React.RefObject<HTMLTextAreaElement>;
|
|
7
|
+
hasBeenAnimated: (index: number) => boolean;
|
|
8
|
+
typingProgressRef: React.MutableRefObject<Map<number, number>>;
|
|
9
|
+
isTypingRef: React.MutableRefObject<boolean>;
|
|
10
|
+
setIsAnimating: (value: boolean) => void;
|
|
11
|
+
scrollToBottom: () => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* TypingEffect component handles the character-by-character typing animation
|
|
15
|
+
* for assistant messages with support for pausing, resuming, and skipping
|
|
16
|
+
*/
|
|
17
|
+
export declare const TypingEffect: React.FC<TypingEffectProps>;
|