nui-chatbot-pkg 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.
- package/README.md +43 -0
- package/dist/index.d.mts +133 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +24 -0
- package/dist/index.mjs +24 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# NUI Chatbot Package
|
|
2
|
+
|
|
3
|
+
A customizable, meaningful, and easy-to-integrate Chatbot component for React applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install nui-chatbot-pkg
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { ChatBot } from 'nui-chatbot-pkg';
|
|
15
|
+
|
|
16
|
+
function App() {
|
|
17
|
+
return (
|
|
18
|
+
<ChatBot
|
|
19
|
+
strapiUrl="https://your-strapi-url.com"
|
|
20
|
+
cardRegistry={[]} // Your card registry
|
|
21
|
+
theme={{
|
|
22
|
+
primaryColor: "#2999d6",
|
|
23
|
+
secondaryColor: "#179fa3",
|
|
24
|
+
accentColor: "#07a372"
|
|
25
|
+
}}
|
|
26
|
+
title="My Assistant"
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Props
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Description |
|
|
35
|
+
|------|------|-------------|
|
|
36
|
+
| `strapiUrl` | `string` | The URL of your Strapi backend. |
|
|
37
|
+
| `cardRegistry` | `Array` | Registry for custom card components. |
|
|
38
|
+
| `theme` | `object` | Custom colors for the chatbot. |
|
|
39
|
+
| `title` | `string` | Title of the chatbot window. |
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type TourRecord = {
|
|
4
|
+
tourName?: string;
|
|
5
|
+
origin?: string;
|
|
6
|
+
destination?: string;
|
|
7
|
+
fare?: string | number;
|
|
8
|
+
};
|
|
9
|
+
type EmployeeRecord = {
|
|
10
|
+
name?: string;
|
|
11
|
+
doj?: string;
|
|
12
|
+
mailId?: string;
|
|
13
|
+
};
|
|
14
|
+
type CollectionRecord = {
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
};
|
|
17
|
+
type Deal = Record<string, string | number>;
|
|
18
|
+
type Message = {
|
|
19
|
+
id: number;
|
|
20
|
+
role: "user" | "assistant";
|
|
21
|
+
content: string;
|
|
22
|
+
record?: TourRecord | EmployeeRecord | CollectionRecord | null;
|
|
23
|
+
recordType?: "deal" | "employee" | "collection" | null;
|
|
24
|
+
loading?: boolean;
|
|
25
|
+
items?: {
|
|
26
|
+
items: CollectionRecord[];
|
|
27
|
+
schema?: string[];
|
|
28
|
+
collection?: string;
|
|
29
|
+
title?: string;
|
|
30
|
+
cardStyle?: string;
|
|
31
|
+
} | null;
|
|
32
|
+
};
|
|
33
|
+
type ApiResponse = {
|
|
34
|
+
answer: string;
|
|
35
|
+
deal: Deal | null;
|
|
36
|
+
allowedFields: string[];
|
|
37
|
+
};
|
|
38
|
+
type CardRegistryItem = {
|
|
39
|
+
id: string;
|
|
40
|
+
component: React.ComponentType<any>;
|
|
41
|
+
};
|
|
42
|
+
type ChatBotProps = {
|
|
43
|
+
strapiUrl: string;
|
|
44
|
+
theme?: ChatTheme;
|
|
45
|
+
cardRegistry: CardRegistryItem[];
|
|
46
|
+
title?: string;
|
|
47
|
+
streamSpeed?: number;
|
|
48
|
+
};
|
|
49
|
+
type ChatTheme = {
|
|
50
|
+
primaryColor?: string;
|
|
51
|
+
secondaryColor?: string;
|
|
52
|
+
accentColor?: string;
|
|
53
|
+
container?: string;
|
|
54
|
+
header?: string;
|
|
55
|
+
input?: string;
|
|
56
|
+
showGradient?: boolean;
|
|
57
|
+
welcomeMessage?: string;
|
|
58
|
+
welcomeDescription?: string;
|
|
59
|
+
};
|
|
60
|
+
type ChatTheming = {
|
|
61
|
+
container?: string;
|
|
62
|
+
header?: string;
|
|
63
|
+
input?: string;
|
|
64
|
+
showGradient?: boolean;
|
|
65
|
+
welcomeMessage?: string;
|
|
66
|
+
welcomeDescription?: string;
|
|
67
|
+
primaryColor?: string;
|
|
68
|
+
secondaryColor?: string;
|
|
69
|
+
accentColor?: string;
|
|
70
|
+
};
|
|
71
|
+
type ChatInputProps = {
|
|
72
|
+
input: string;
|
|
73
|
+
onInputChange: (value: string) => void;
|
|
74
|
+
onSendMessage: () => void;
|
|
75
|
+
isLoading: boolean;
|
|
76
|
+
theming?: ChatTheming;
|
|
77
|
+
};
|
|
78
|
+
type MessageBubbleProps = {
|
|
79
|
+
message: Message;
|
|
80
|
+
cardRegistry: CardRegistryItem[];
|
|
81
|
+
themeStyles?: React.CSSProperties;
|
|
82
|
+
theming?: ChatTheming;
|
|
83
|
+
};
|
|
84
|
+
type CustomRecord = {
|
|
85
|
+
__collectionUid?: string;
|
|
86
|
+
[key: string]: any;
|
|
87
|
+
};
|
|
88
|
+
type SuggestionsProps = {
|
|
89
|
+
strapiUrl: string;
|
|
90
|
+
onSelectQuestion: (question: string) => void;
|
|
91
|
+
variant: "floating" | "pills";
|
|
92
|
+
theming?: ChatTheming;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
declare const ChatBot: ({ strapiUrl, cardRegistry, theme, title, streamSpeed, }: ChatBotProps) => react_jsx_runtime.JSX.Element;
|
|
96
|
+
|
|
97
|
+
declare const ChatHeader: ({ onClose, title, theming, strapiUrl, }: {
|
|
98
|
+
onClose: () => void;
|
|
99
|
+
title?: string;
|
|
100
|
+
theming?: ChatTheming;
|
|
101
|
+
strapiUrl?: string;
|
|
102
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
103
|
+
|
|
104
|
+
declare const ChatInput: ({ input, onInputChange, onSendMessage, isLoading, theming, }: ChatInputProps) => react_jsx_runtime.JSX.Element;
|
|
105
|
+
|
|
106
|
+
declare const MessageBubble: ({ message, cardRegistry, themeStyles, theming, }: MessageBubbleProps) => react_jsx_runtime.JSX.Element;
|
|
107
|
+
|
|
108
|
+
declare const Suggestions: ({ strapiUrl, onSelectQuestion, variant, theming, }: SuggestionsProps) => react_jsx_runtime.JSX.Element;
|
|
109
|
+
|
|
110
|
+
declare const ICONS: {
|
|
111
|
+
MessageCircle: ({ size, className }: {
|
|
112
|
+
size?: number | undefined;
|
|
113
|
+
className?: string | undefined;
|
|
114
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
115
|
+
Bot: ({ size, className }: {
|
|
116
|
+
size?: number | undefined;
|
|
117
|
+
className?: string | undefined;
|
|
118
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
119
|
+
X: ({ size, className }: {
|
|
120
|
+
size?: number | undefined;
|
|
121
|
+
className?: string | undefined;
|
|
122
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
123
|
+
Sparkles: ({ size, className }: {
|
|
124
|
+
size?: number | undefined;
|
|
125
|
+
className?: string | undefined;
|
|
126
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
127
|
+
Send: ({ size, className }: {
|
|
128
|
+
size?: number | undefined;
|
|
129
|
+
className?: string | undefined;
|
|
130
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export { type ApiResponse, type CardRegistryItem, ChatBot, type ChatBotProps, ChatHeader, ChatInput, type ChatInputProps, type ChatTheme, type ChatTheming, type CollectionRecord, type CustomRecord, type Deal, type EmployeeRecord, ICONS, type Message, MessageBubble, type MessageBubbleProps, Suggestions, type SuggestionsProps, type TourRecord };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type TourRecord = {
|
|
4
|
+
tourName?: string;
|
|
5
|
+
origin?: string;
|
|
6
|
+
destination?: string;
|
|
7
|
+
fare?: string | number;
|
|
8
|
+
};
|
|
9
|
+
type EmployeeRecord = {
|
|
10
|
+
name?: string;
|
|
11
|
+
doj?: string;
|
|
12
|
+
mailId?: string;
|
|
13
|
+
};
|
|
14
|
+
type CollectionRecord = {
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
};
|
|
17
|
+
type Deal = Record<string, string | number>;
|
|
18
|
+
type Message = {
|
|
19
|
+
id: number;
|
|
20
|
+
role: "user" | "assistant";
|
|
21
|
+
content: string;
|
|
22
|
+
record?: TourRecord | EmployeeRecord | CollectionRecord | null;
|
|
23
|
+
recordType?: "deal" | "employee" | "collection" | null;
|
|
24
|
+
loading?: boolean;
|
|
25
|
+
items?: {
|
|
26
|
+
items: CollectionRecord[];
|
|
27
|
+
schema?: string[];
|
|
28
|
+
collection?: string;
|
|
29
|
+
title?: string;
|
|
30
|
+
cardStyle?: string;
|
|
31
|
+
} | null;
|
|
32
|
+
};
|
|
33
|
+
type ApiResponse = {
|
|
34
|
+
answer: string;
|
|
35
|
+
deal: Deal | null;
|
|
36
|
+
allowedFields: string[];
|
|
37
|
+
};
|
|
38
|
+
type CardRegistryItem = {
|
|
39
|
+
id: string;
|
|
40
|
+
component: React.ComponentType<any>;
|
|
41
|
+
};
|
|
42
|
+
type ChatBotProps = {
|
|
43
|
+
strapiUrl: string;
|
|
44
|
+
theme?: ChatTheme;
|
|
45
|
+
cardRegistry: CardRegistryItem[];
|
|
46
|
+
title?: string;
|
|
47
|
+
streamSpeed?: number;
|
|
48
|
+
};
|
|
49
|
+
type ChatTheme = {
|
|
50
|
+
primaryColor?: string;
|
|
51
|
+
secondaryColor?: string;
|
|
52
|
+
accentColor?: string;
|
|
53
|
+
container?: string;
|
|
54
|
+
header?: string;
|
|
55
|
+
input?: string;
|
|
56
|
+
showGradient?: boolean;
|
|
57
|
+
welcomeMessage?: string;
|
|
58
|
+
welcomeDescription?: string;
|
|
59
|
+
};
|
|
60
|
+
type ChatTheming = {
|
|
61
|
+
container?: string;
|
|
62
|
+
header?: string;
|
|
63
|
+
input?: string;
|
|
64
|
+
showGradient?: boolean;
|
|
65
|
+
welcomeMessage?: string;
|
|
66
|
+
welcomeDescription?: string;
|
|
67
|
+
primaryColor?: string;
|
|
68
|
+
secondaryColor?: string;
|
|
69
|
+
accentColor?: string;
|
|
70
|
+
};
|
|
71
|
+
type ChatInputProps = {
|
|
72
|
+
input: string;
|
|
73
|
+
onInputChange: (value: string) => void;
|
|
74
|
+
onSendMessage: () => void;
|
|
75
|
+
isLoading: boolean;
|
|
76
|
+
theming?: ChatTheming;
|
|
77
|
+
};
|
|
78
|
+
type MessageBubbleProps = {
|
|
79
|
+
message: Message;
|
|
80
|
+
cardRegistry: CardRegistryItem[];
|
|
81
|
+
themeStyles?: React.CSSProperties;
|
|
82
|
+
theming?: ChatTheming;
|
|
83
|
+
};
|
|
84
|
+
type CustomRecord = {
|
|
85
|
+
__collectionUid?: string;
|
|
86
|
+
[key: string]: any;
|
|
87
|
+
};
|
|
88
|
+
type SuggestionsProps = {
|
|
89
|
+
strapiUrl: string;
|
|
90
|
+
onSelectQuestion: (question: string) => void;
|
|
91
|
+
variant: "floating" | "pills";
|
|
92
|
+
theming?: ChatTheming;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
declare const ChatBot: ({ strapiUrl, cardRegistry, theme, title, streamSpeed, }: ChatBotProps) => react_jsx_runtime.JSX.Element;
|
|
96
|
+
|
|
97
|
+
declare const ChatHeader: ({ onClose, title, theming, strapiUrl, }: {
|
|
98
|
+
onClose: () => void;
|
|
99
|
+
title?: string;
|
|
100
|
+
theming?: ChatTheming;
|
|
101
|
+
strapiUrl?: string;
|
|
102
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
103
|
+
|
|
104
|
+
declare const ChatInput: ({ input, onInputChange, onSendMessage, isLoading, theming, }: ChatInputProps) => react_jsx_runtime.JSX.Element;
|
|
105
|
+
|
|
106
|
+
declare const MessageBubble: ({ message, cardRegistry, themeStyles, theming, }: MessageBubbleProps) => react_jsx_runtime.JSX.Element;
|
|
107
|
+
|
|
108
|
+
declare const Suggestions: ({ strapiUrl, onSelectQuestion, variant, theming, }: SuggestionsProps) => react_jsx_runtime.JSX.Element;
|
|
109
|
+
|
|
110
|
+
declare const ICONS: {
|
|
111
|
+
MessageCircle: ({ size, className }: {
|
|
112
|
+
size?: number | undefined;
|
|
113
|
+
className?: string | undefined;
|
|
114
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
115
|
+
Bot: ({ size, className }: {
|
|
116
|
+
size?: number | undefined;
|
|
117
|
+
className?: string | undefined;
|
|
118
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
119
|
+
X: ({ size, className }: {
|
|
120
|
+
size?: number | undefined;
|
|
121
|
+
className?: string | undefined;
|
|
122
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
123
|
+
Sparkles: ({ size, className }: {
|
|
124
|
+
size?: number | undefined;
|
|
125
|
+
className?: string | undefined;
|
|
126
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
127
|
+
Send: ({ size, className }: {
|
|
128
|
+
size?: number | undefined;
|
|
129
|
+
className?: string | undefined;
|
|
130
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export { type ApiResponse, type CardRegistryItem, ChatBot, type ChatBotProps, ChatHeader, ChatInput, type ChatInputProps, type ChatTheme, type ChatTheming, type CollectionRecord, type CustomRecord, type Deal, type EmployeeRecord, ICONS, type Message, MessageBubble, type MessageBubbleProps, Suggestions, type SuggestionsProps, type TourRecord };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";"use client";var q=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var me=Object.prototype.hasOwnProperty;var fe=(e,t)=>{for(var r in t)q(e,r,{get:t[r],enumerable:!0})},pe=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ue(t))!me.call(e,a)&&a!==r&&q(e,a,{get:()=>t[a],enumerable:!(o=de(t,a))||o.enumerable});return e};var ge=e=>pe(q({},"__esModule",{value:!0}),e);var ke={};fe(ke,{ChatBot:()=>oe,ChatHeader:()=>W,ChatInput:()=>_,ICONS:()=>E,MessageBubble:()=>F,Suggestions:()=>Q});module.exports=ge(ke);function j(e,{insertAt:t}={}){if(!e||typeof document>"u")return;let r=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css",t==="top"&&r.firstChild?r.insertBefore(o,r.firstChild):r.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}j(`@tailwind components;@tailwind utilities;
|
|
2
|
+
`);j(`:root{--background: #ffffff;--foreground: #171717}@theme inline{ --color-background: var(--background); --color-foreground: var(--foreground); --font-sans: var(--font-geist-sans); --font-mono: var(--font-geist-mono); }@media(prefers-color-scheme:dark){:root{--background: #0a0a0a;--foreground: #ededed}}body{background:var(--background);color:var(--foreground);font-family:Arial,Helvetica,sans-serif}@keyframes scaleIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.animate-scaleIn{animation:scaleIn .2s ease-out}.glow-container{position:absolute;width:120%;height:300%}@keyframes spin-slow{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin-slow{animation:spin-slow 10s linear infinite}
|
|
3
|
+
`);var C=require("react");var h=require("react/jsx-runtime"),E={MessageCircle:({size:e=24,className:t=""})=>(0,h.jsx)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:(0,h.jsx)("path",{d:"M7.9 20A9 9 0 1 0 4 16.1L2 22Z"})}),Bot:({size:e=24,className:t=""})=>(0,h.jsx)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:(0,h.jsx)("path",{d:"M12 8V4m8 4V4M4 8V4M2 11h20m-1 0v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V11m5 5v2m8-2v2"})}),X:({size:e=24,className:t=""})=>(0,h.jsx)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:(0,h.jsx)("path",{d:"M18 6 6 18M6 6l12 12"})}),Sparkles:({size:e=24,className:t=""})=>(0,h.jsx)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:(0,h.jsx)("path",{d:"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"})}),Send:({size:e=24,className:t=""})=>(0,h.jsxs)("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:[(0,h.jsx)("path",{d:"m22 2-7 20-4-9-9-4Z"}),(0,h.jsx)("path",{d:"M22 2 11 13"})]})};var M=require("react/jsx-runtime"),he=({isExpanded:e,onOpen:t,theming:r})=>(0,M.jsx)("div",{onClick:t,className:`relative w-16 h-16 sm:w-20 h-20 group cursor-pointer transition-all duration-500 ease-in-out
|
|
4
|
+
${e?"scale-0 opacity-0 pointer-events-none":"scale-100 opacity-100 hover:scale-110"}`,children:(0,M.jsxs)("div",{className:"seamless-border relative h-full w-full rounded-full overflow-hidden shadow-2xl bg-zinc-900",children:[r?.showGradient===!1&&(0,M.jsx)("div",{className:"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[200%] h-[200%] animate-[spin_3s_linear_infinite]",style:{background:r?.showGradient===!1?"var(--cb-primary), var(--cb-secondary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary))"}}),(0,M.jsxs)("div",{className:"absolute inset-0 m-auto w-[85%] h-[85%] z-10 rounded-full flex items-center justify-center text-white overflow-hidden bg-zinc-900",children:[(0,M.jsx)("div",{className:"absolute inset-0",style:{background:r?.showGradient===!1?"var(--cb-primary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary))"}}),(0,M.jsx)(E.MessageCircle,{size:30,className:"relative z-20 group-hover:rotate-12 transition-transform duration-300"})]})]})}),X=he;var z=require("react");var T=(e,t)=>t?`${e} ${t}`:e;var w=require("react/jsx-runtime"),ve=({onClose:e,title:t,theming:r,strapiUrl:o})=>{let[a,s]=(0,z.useState)(null);(0,z.useEffect)(()=>{if(!o)return;(async()=>{try{let u=await(await fetch(`${o}/api/faqchatbot/suggestion-and-logo`)).json();u?.logoUrl&&s(`${o}${u.logoUrl}`)}catch(f){console.error("Failed to fetch logo",f)}})()},[o]);let d=T("flex items-center justify-between px-6 py-4 sticky top-0 z-10",r?.header);return(0,w.jsxs)("header",{className:d,children:[(0,w.jsxs)("div",{className:"flex items-center gap-3",children:[a?(0,w.jsx)("img",{src:a,alt:"Bot Logo",className:"w-12 h-12 rounded-full "}):(0,w.jsx)("div",{className:"w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center",children:(0,w.jsx)(E.Bot,{size:20,className:"text-gray-600"})}),(0,w.jsx)("div",{className:"flex flex-col",children:(0,w.jsx)("span",{className:"font-semibold text-gray-900 text-sm leading-none",children:t})})]}),(0,w.jsx)("div",{className:"flex items-center gap-2",children:(0,w.jsx)("button",{onClick:e,className:"p-1.5 rounded-full text-gray-400 hover:bg-gray-100 hover:text-gray-600 transition-colors duration-200","aria-label":"Close chat",children:(0,w.jsx)(E.X,{size:20})})})]})},W=ve;var G=require("react");var v=require("react/jsx-runtime"),ye=({input:e,onInputChange:t,onSendMessage:r,isLoading:o,theming:a})=>{let s=a?.showGradient===!1?"var(--cb-primary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary), var(--cb-accent))",n=(0,G.useRef)(null),c=T("relative flex items-center bg-white rounded-2xl border border-zinc-200 shadow-lg w-full",a?.input);return(0,G.useEffect)(()=>{o||n.current?.focus()},[o]),(0,v.jsx)("div",{className:"p-4 flex justify-center w-full",children:(0,v.jsxs)("div",{className:"relative group w-full max-w-2xl",children:[(0,v.jsx)("div",{style:{background:s},className:"absolute -inset-[3px] rounded-2xl blur-xl opacity-70 group-hover:opacity-100 transition-opacity duration-700 animate-pulse"}),(0,v.jsx)("div",{style:{background:s},className:"absolute -inset-[1px] rounded-2xl blur-sm group-hover:blur-none transition-all duration-500"}),(0,v.jsx)("div",{className:c,children:(0,v.jsxs)("div",{className:"relative flex w-full items-center px-6 py-1",children:[(0,v.jsx)("input",{ref:n,type:"text",className:"flex-1 text-base outline-none py-3 text-zinc-800 bg-transparent",placeholder:o?"AI is thinking...":"Ask anything...",value:e,onChange:u=>t(u.target.value),onKeyDown:u=>{u.key==="Enter"&&!u.nativeEvent.isComposing&&e.trim()&&!o&&r()},disabled:o,"aria-label":"User message"}),(0,v.jsx)("div",{className:"absolute -right-3 flex items-center justify-center",children:(0,v.jsx)("button",{onClick:r,disabled:o||!e.trim(),style:{background:s},className:"relative z-20 flex items-center justify-center h-14 w-14 rounded-full border-4 border-white text-white shadow-lg transition-all transform active:scale-90 enabled:hover:scale-110 enabled:hover:rotate-12 disabled:opacity-80 disabled:cursor-not-allowed","aria-label":"Send message",children:o?(0,v.jsx)("div",{className:"h-5 w-5 border-2 border-white border-t-transparent animate-spin rounded-full"}):(0,v.jsx)(E.Send,{className:"text-xl"})})})]})})]})})},_=ye;var y=require("react/jsx-runtime"),be=({message:e,cardRegistry:t,themeStyles:r,theming:o})=>{let a=n=>{let d=n?.__collectionUid?.split(".").pop()?.toLowerCase();return t.find(c=>c.id===d)||t.find(c=>c.id==="default")};console.log("\u{1F535} MESSAGE BUBBLE:",e),console.log("\u{1F7E2} CARD REGISTRY IN BUBBLE:",t);let s=e.record?a(e.record)?.component:null;if(e.items?.items?.length){console.log("\u{1F7E5} RENDERING REALTIME CARDS:",e.items);let n=e.items.cardStyle?.toLowerCase()||e.items.collection?.toLowerCase()||e.items.title?.toLowerCase();console.log("\u{1F7E3} COLLECTION/STYLE ID:",n);let d=t.find(f=>f.id===n);d||console.log("\u274C CARD NOT FOUND:",n);let c=d?.component;return(0,y.jsxs)("div",{className:"flex flex-col gap-4 w-full",children:[e.content&&(0,y.jsx)("div",{className:"bg-gray-100 p-4 rounded-2xl text-sm",children:e.content}),c&&e.items.items.map((f,u)=>(0,y.jsx)(c,{items:f,style:r},u))]})}return(0,y.jsx)("div",{className:`flex w-full ${e.role==="user"?"justify-end":"justify-start"}`,children:s&&e.record?(0,y.jsx)("div",{className:"max-w-[90%] animate-in fade-in slide-in-from-bottom-2 duration-300",children:(0,y.jsx)(s,{record:e.record,style:r})}):(0,y.jsx)("div",{style:e.role==="user"?{background:o?.showGradient===!1?"var(--cb-primary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary), var(--cb-accent))"}:{},className:`max-w-[85%] p-4 text-sm rounded-2xl shadow-sm transition-all animate-in fade-in slide-in-from-bottom-2 duration-300 ${e.role==="user"?"text-white rounded-tr-none":"bg-gray-100 text-zinc-800 rounded-tl-none"} whitespace-pre-wrap break-words`,children:e.loading&&!e.content?(0,y.jsxs)("div",{className:"flex gap-1 py-1 px-2",children:[(0,y.jsx)("span",{className:"w-1.5 h-1.5 bg-current rounded-full animate-bounce [animation-delay:-0.3s]"}),(0,y.jsx)("span",{className:"w-1.5 h-1.5 bg-current rounded-full animate-bounce [animation-delay:-0.15s]"}),(0,y.jsx)("span",{className:"w-1.5 h-1.5 bg-current rounded-full animate-bounce"})]}):e.content})})},F=be;var D=require("react"),l=require("react/jsx-runtime"),we=({strapiUrl:e,onSelectQuestion:t,variant:r,theming:o})=>{let[a,s]=(0,D.useState)([]),[n,d]=(0,D.useState)(!0),[c,f]=(0,D.useState)(!1);(0,D.useEffect)(()=>{let i=new AbortController;return d(!0),fetch(`${e}/api/faqchatbot/suggestion-and-logo`,{signal:i.signal}).then(p=>p.json()).then(p=>{s(p.suggestedQuestions||[]),d(!1)}).catch(p=>{p.name!=="AbortError"&&(console.error("Suggestions fetch failed",p),d(!1))}),()=>i.abort()},[e]);let u=()=>r==="floating"?(0,l.jsxs)("div",{className:"flex flex-col items-center gap-3 px-4 pt-1 w-full animate-pulse",children:[[1,2].map(i=>(0,l.jsx)("div",{className:"h-10 w-[70%] rounded-lg",style:{backgroundColor:o?.primaryColor?`${o.primaryColor}20`:"rgba(0,0,0,0.05)",transform:i%2===0?"rotate(1deg)":"rotate(-1deg)"}},i)),(0,l.jsx)("div",{className:"h-6 w-12 rounded-full mt-2"})]}):(0,l.jsx)("div",{className:"flex gap-2 overflow-x-auto no-scrollbar justify-start sm:justify-center py-2 animate-pulse",children:[1,2,3].map(i=>(0,l.jsx)("div",{className:"h-8 w-24 bg-gray-100 rounded-lg whitespace-nowrap"},i))});if(n&&a.length===0)return(0,l.jsx)(u,{});if(r==="floating"){let i=c?a:a.slice(0,2),p=!c&&a.length>2;return(0,l.jsxs)("div",{className:"flex flex-col items-center gap-3 px-4 pt-2 pb-4 w-full",children:[(0,l.jsx)("style",{children:`
|
|
5
|
+
@keyframes fadeInUp {
|
|
6
|
+
from { opacity: 0; transform: translateY(10px) scale(0.95); }
|
|
7
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
8
|
+
}
|
|
9
|
+
`}),i.map((I,O)=>{let K=O%2===0?"rotate(-1deg)":"rotate(1deg)";return(0,l.jsx)("button",{onClick:()=>t(I),className:"bg-white border-2 px-6 py-2.5 rounded-xl shadow-sm text-sm font-medium hover:shadow-md hover:scale-[1.02] transition-all active:scale-95 cursor-pointer max-w-[85%] w-fit",style:{borderColor:o?.primaryColor||"var(--cb-primary)",color:"inherit",transform:K,animation:"fadeInUp 0.4s ease-out forwards",animationDelay:`${O*.1}s`,opacity:0},children:(0,l.jsx)("span",{className:"text-gray-700",children:I})},`float-${O}-${I}`)}),p&&(0,l.jsx)("button",{onClick:()=>f(!0),"aria-label":"Show more suggestions",title:"Show more suggestions",className:"mt-1 bg-gray-100 px-5 py-1.5 rounded-full hover:bg-gray-200 transition-colors active:scale-95 cursor-pointer shadow-sm",style:{animation:"fadeInUp 0.4s ease-out forwards",animationDelay:`${i.length*.1}s`,opacity:0},children:(0,l.jsxs)("div",{className:"flex items-center gap-1",style:{color:o?.secondaryColor||"var(--cb-secondary)"},children:[(0,l.jsx)("div",{className:"w-1.5 h-1.5 rounded-full bg-current"}),(0,l.jsx)("div",{className:"w-1.5 h-1.5 rounded-full bg-current"}),(0,l.jsx)("div",{className:"w-1.5 h-1.5 rounded-full bg-current"})]})})]})}return(0,l.jsxs)("div",{className:"flex gap-2 overflow-x-auto no-scrollbar justify-start sm:justify-center py-2",children:[(0,l.jsx)("style",{children:`
|
|
10
|
+
@keyframes fadeIn {
|
|
11
|
+
from { opacity: 0; }
|
|
12
|
+
to { opacity: 1; }
|
|
13
|
+
}
|
|
14
|
+
`}),a.map((i,p)=>(0,l.jsx)("button",{onClick:()=>t(i),className:"whitespace-nowrap border border-gray-200 px-4 py-1.5 rounded-lg text-xs text-gray-600 hover:bg-gray-50 transition-colors bg-white shadow-sm",style:{animation:"fadeIn 0.3s ease-out forwards",animationDelay:`${p*.05}s`,opacity:0},children:i},`list-${p}-${i}`))]})},Q=we;var x=require("react/jsx-runtime"),xe=({messages:e,scrollRef:t,sendMessage:r,strapiUrl:o,resolvedRegistry:a,theming:s})=>{let n=s?.showGradient===!1?"var(--cb-primary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary), var(--cb-accent))",d=s?.welcomeMessage||"How can I help you?",c=s?.welcomeDescription||"Select a common question below or type your own.";return(0,x.jsxs)("div",{ref:t,className:"flex-1 overflow-y-auto px-6 py-3 space-y-6 bg-transparent no-scrollbar",style:{scrollbarWidth:"none",msOverflowStyle:"none"},children:[e.length===0&&(0,x.jsxs)("div",{className:"flex flex-col items-center justify-center min-h-full text-center space-y-6",children:[(0,x.jsx)("div",{className:"w-20 h-20 rounded-full flex items-center justify-center text-white shadow-xl animate-[float_4s_ease-in-out_infinite]",style:{background:n},children:(0,x.jsx)(E.MessageCircle,{size:40})}),(0,x.jsxs)("div",{children:[(0,x.jsx)("h3",{className:"text-2xl font-bold text-black tracking-tight",children:d}),(0,x.jsx)("p",{className:"text-sm text-gray-500 px-10",children:c})]}),(0,x.jsx)("div",{className:" w-full",children:(0,x.jsx)(Q,{onSelectQuestion:r,strapiUrl:o,variant:"floating",theming:s})})]}),e.map(f=>(0,x.jsx)(F,{message:f,cardRegistry:a,theming:s},f.id))]})},ee=xe;var k=require("react/jsx-runtime"),Ce=({isExpanded:e,setIsExpanded:t,messages:r,scrollRef:o,sendMessage:a,strapiUrl:s,resolvedRegistry:n,input:d,setInput:c,isLoading:f,title:u,theming:i})=>{let I=T(`
|
|
15
|
+
relative flex flex-col bg-white border border-white/40 rounded-[2rem] shadow-2xl overflow-hidden
|
|
16
|
+
transition-all duration-500 cubic-bezier(0.4, 0, 0.2, 1) origin-bottom-right
|
|
17
|
+
w-[90vw] sm:w-[450px]
|
|
18
|
+
${e?"h-[70vh] md:h-[600px] sm:h-[750px] opacity-100 scale-100 translate-y-0":"h-0 opacity-0 scale-95 translate-y-10 pointer-events-none"}
|
|
19
|
+
max-h-[800px]
|
|
20
|
+
`,i?.container);return(0,k.jsxs)("div",{className:I,children:[(0,k.jsx)("div",{className:"flex-none z-20 bg-white/60 backdrop-blur-md border-b border-white/20",children:(0,k.jsx)(W,{title:u,onClose:()=>t(!1),theming:i,strapiUrl:s})}),(0,k.jsx)(ee,{messages:r,scrollRef:o,sendMessage:a,strapiUrl:s,resolvedRegistry:n,theming:i}),(0,k.jsxs)("div",{className:"flex-none bg-white p-3 sm:p-4 border-t border-white/20",children:[(0,k.jsx)(_,{input:d,onInputChange:c,onSendMessage:a,isLoading:f,theming:i}),(0,k.jsx)("div",{className:"text-center mt-2",children:(0,k.jsxs)("span",{className:"text-[10px] text-gray-400 uppercase tracking-widest",children:["Powered by"," ",(0,k.jsx)("a",{href:"https://numentica-ui.com",className:"text-gray-400 font-semibold transition-colors hover:text-blue-600",children:"Numentica-UI"})]})})]})]})},te=Ce;var A=require("react/jsx-runtime"),Ne=({strapiUrl:e,cardRegistry:t,theme:r,title:o,streamSpeed:a})=>{let[s,n]=(0,C.useState)([]),[d,c]=(0,C.useState)(""),[f,u]=(0,C.useState)(!1),[i,p]=(0,C.useState)(!1),I=(0,C.useRef)(null),[O,K]=(0,C.useState)([]),re=(0,C.useRef)(null),ae={"--cb-primary":r?.primaryColor||"#2999d6","--cb-secondary":r?.secondaryColor||"#179fa3","--cb-accent":r?.accentColor||"#07a372"};return(0,C.useEffect)(()=>{t.length>0&&K(t)},[t]),(0,C.useEffect)(()=>()=>I.current?.abort(),[]),(0,A.jsxs)("div",{className:"fixed bottom-4 right-4 sm:bottom-6 sm:right-6 z-50 flex flex-col items-end font-sans",style:ae,children:[(0,A.jsx)(X,{isExpanded:i,onOpen:()=>p(!0),theming:r}),(0,A.jsx)(te,{isExpanded:i,setIsExpanded:p,messages:s,scrollRef:re,sendMessage:async se=>{let V=se||d;if(!V.trim())return;I.current?.abort(),I.current=new AbortController,p(!0),c(""),u(!0);let ne={role:"user",content:V,id:Date.now()},L=Date.now()+1;n(S=>[...S,ne,{role:"assistant",content:"",items:null,loading:!0,id:L}]);try{let S=await fetch(`${e}/api/faqchatbot/ask`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({question:V,history:s.slice(-4).map(g=>({role:g.role,content:g.content}))}),signal:I.current.signal});if(!S.ok)throw new Error("Network response was not ok");let U=S.body?.getReader(),P=new TextDecoder;if(!U)throw new Error("No reader available");let $=[],Z=!1,ie=(async()=>{for(;!Z||$.length>0;)if($.length>0){let g=$.shift();if(g?.type==="text")if(a&&a>0)for(let m of g.content)n(b=>b.map(N=>N.id===L?{...N,content:N.content+m}:N)),await new Promise(b=>setTimeout(b,a));else n(m=>m.map(b=>b.id===L?{...b,content:b.content+g.content}:b));else if(g?.type==="card")try{let m=g.data;n(b=>b.map(N=>N.id===L?{...N,items:{items:m.items,schema:m.schema,collection:m.title,title:m.title,cardStyle:m.cardStyle}}:N))}catch(m){console.error("Error processing card data:",m)}}else await new Promise(g=>setTimeout(g,20));u(!1),n(g=>g.map(m=>m.id===L?{...m,loading:!1}:m))})(),Y="";for(;;){let{value:g,done:m}=await U.read();if(m)break;let b=P.decode(g,{stream:!0});Y+=b;let N=Y.split(`
|
|
21
|
+
|
|
22
|
+
`);Y=N.pop()||"";for(let le of N){let ce=le.split(`
|
|
23
|
+
`),J="message",B="";for(let R of ce)if(R.startsWith("event:"))J=R.slice(6).trim();else if(R.startsWith("data:")){let H=R.slice(5);H.startsWith(" ")&&(H=H.slice(1)),B+=(B?`
|
|
24
|
+
`:"")+H}if(B.trim()!=="[DONE]")if(J==="cards")try{let R=JSON.parse(B);$.push({type:"card",data:R})}catch(R){console.error("Error parsing card data:",R)}else B&&$.push({type:"text",content:B})}}Z=!0,await ie}catch(S){S.name!=="AbortError"&&(console.error("Chat Error:",S),n(U=>U.map(P=>P.id===L?{...P,content:"I'm sorry, I'm having trouble connecting right now.",loading:!1}:P))),u(!1)}},strapiUrl:e,resolvedRegistry:O,input:d,setInput:c,isLoading:f,title:o,theming:r})]})},oe=Ne;0&&(module.exports={ChatBot,ChatHeader,ChatInput,ICONS,MessageBubble,Suggestions});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";function O(e,{insertAt:t}={}){if(!e||typeof document>"u")return;let r=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css",t==="top"&&r.firstChild?r.insertBefore(o,r.firstChild):r.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}O(`@tailwind components;@tailwind utilities;
|
|
2
|
+
`);O(`:root{--background: #ffffff;--foreground: #171717}@theme inline{ --color-background: var(--background); --color-foreground: var(--foreground); --font-sans: var(--font-geist-sans); --font-mono: var(--font-geist-mono); }@media(prefers-color-scheme:dark){:root{--background: #0a0a0a;--foreground: #ededed}}body{background:var(--background);color:var(--foreground);font-family:Arial,Helvetica,sans-serif}@keyframes scaleIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.animate-scaleIn{animation:scaleIn .2s ease-out}.glow-container{position:absolute;width:120%;height:300%}@keyframes spin-slow{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin-slow{animation:spin-slow 10s linear infinite}
|
|
3
|
+
`);import{useState as P,useEffect as se,useRef as ne}from"react";import{jsx as b,jsxs as ge}from"react/jsx-runtime";var w={MessageCircle:({size:e=24,className:t=""})=>b("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:b("path",{d:"M7.9 20A9 9 0 1 0 4 16.1L2 22Z"})}),Bot:({size:e=24,className:t=""})=>b("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:b("path",{d:"M12 8V4m8 4V4M4 8V4M2 11h20m-1 0v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V11m5 5v2m8-2v2"})}),X:({size:e=24,className:t=""})=>b("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:b("path",{d:"M18 6 6 18M6 6l12 12"})}),Sparkles:({size:e=24,className:t=""})=>b("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:b("path",{d:"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"})}),Send:({size:e=24,className:t=""})=>ge("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:t,children:[b("path",{d:"m22 2-7 20-4-9-9-4Z"}),b("path",{d:"M22 2 11 13"})]})};import{jsx as A,jsxs as J}from"react/jsx-runtime";var he=({isExpanded:e,onOpen:t,theming:r})=>A("div",{onClick:t,className:`relative w-16 h-16 sm:w-20 h-20 group cursor-pointer transition-all duration-500 ease-in-out
|
|
4
|
+
${e?"scale-0 opacity-0 pointer-events-none":"scale-100 opacity-100 hover:scale-110"}`,children:J("div",{className:"seamless-border relative h-full w-full rounded-full overflow-hidden shadow-2xl bg-zinc-900",children:[r?.showGradient===!1&&A("div",{className:"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[200%] h-[200%] animate-[spin_3s_linear_infinite]",style:{background:r?.showGradient===!1?"var(--cb-primary), var(--cb-secondary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary))"}}),J("div",{className:"absolute inset-0 m-auto w-[85%] h-[85%] z-10 rounded-full flex items-center justify-center text-white overflow-hidden bg-zinc-900",children:[A("div",{className:"absolute inset-0",style:{background:r?.showGradient===!1?"var(--cb-primary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary))"}}),A(w.MessageCircle,{size:30,className:"relative z-20 group-hover:rotate-12 transition-transform duration-300"})]})]})}),X=he;import{useEffect as ve,useState as ye}from"react";var S=(e,t)=>t?`${e} ${t}`:e;import{jsx as k,jsxs as ee}from"react/jsx-runtime";var be=({onClose:e,title:t,theming:r,strapiUrl:o})=>{let[a,s]=ye(null);ve(()=>{if(!o)return;(async()=>{try{let d=await(await fetch(`${o}/api/faqchatbot/suggestion-and-logo`)).json();d?.logoUrl&&s(`${o}${d.logoUrl}`)}catch(m){console.error("Failed to fetch logo",m)}})()},[o]);let c=S("flex items-center justify-between px-6 py-4 sticky top-0 z-10",r?.header);return ee("header",{className:c,children:[ee("div",{className:"flex items-center gap-3",children:[a?k("img",{src:a,alt:"Bot Logo",className:"w-12 h-12 rounded-full "}):k("div",{className:"w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center",children:k(w.Bot,{size:20,className:"text-gray-600"})}),k("div",{className:"flex flex-col",children:k("span",{className:"font-semibold text-gray-900 text-sm leading-none",children:t})})]}),k("div",{className:"flex items-center gap-2",children:k("button",{onClick:e,className:"p-1.5 rounded-full text-gray-400 hover:bg-gray-100 hover:text-gray-600 transition-colors duration-200","aria-label":"Close chat",children:k(w.X,{size:20})})})]})},G=be;import{useRef as we,useEffect as xe}from"react";import{jsx as x,jsxs as te}from"react/jsx-runtime";var Ce=({input:e,onInputChange:t,onSendMessage:r,isLoading:o,theming:a})=>{let s=a?.showGradient===!1?"var(--cb-primary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary), var(--cb-accent))",n=we(null),l=S("relative flex items-center bg-white rounded-2xl border border-zinc-200 shadow-lg w-full",a?.input);return xe(()=>{o||n.current?.focus()},[o]),x("div",{className:"p-4 flex justify-center w-full",children:te("div",{className:"relative group w-full max-w-2xl",children:[x("div",{style:{background:s},className:"absolute -inset-[3px] rounded-2xl blur-xl opacity-70 group-hover:opacity-100 transition-opacity duration-700 animate-pulse"}),x("div",{style:{background:s},className:"absolute -inset-[1px] rounded-2xl blur-sm group-hover:blur-none transition-all duration-500"}),x("div",{className:l,children:te("div",{className:"relative flex w-full items-center px-6 py-1",children:[x("input",{ref:n,type:"text",className:"flex-1 text-base outline-none py-3 text-zinc-800 bg-transparent",placeholder:o?"AI is thinking...":"Ask anything...",value:e,onChange:d=>t(d.target.value),onKeyDown:d=>{d.key==="Enter"&&!d.nativeEvent.isComposing&&e.trim()&&!o&&r()},disabled:o,"aria-label":"User message"}),x("div",{className:"absolute -right-3 flex items-center justify-center",children:x("button",{onClick:r,disabled:o||!e.trim(),style:{background:s},className:"relative z-20 flex items-center justify-center h-14 w-14 rounded-full border-4 border-white text-white shadow-lg transition-all transform active:scale-90 enabled:hover:scale-110 enabled:hover:rotate-12 disabled:opacity-80 disabled:cursor-not-allowed","aria-label":"Send message",children:o?x("div",{className:"h-5 w-5 border-2 border-white border-t-transparent animate-spin rounded-full"}):x(w.Send,{className:"text-xl"})})})]})})]})})},_=Ce;import{jsx as C,jsxs as oe}from"react/jsx-runtime";var Ne=({message:e,cardRegistry:t,themeStyles:r,theming:o})=>{let a=n=>{let c=n?.__collectionUid?.split(".").pop()?.toLowerCase();return t.find(l=>l.id===c)||t.find(l=>l.id==="default")};console.log("\u{1F535} MESSAGE BUBBLE:",e),console.log("\u{1F7E2} CARD REGISTRY IN BUBBLE:",t);let s=e.record?a(e.record)?.component:null;if(e.items?.items?.length){console.log("\u{1F7E5} RENDERING REALTIME CARDS:",e.items);let n=e.items.cardStyle?.toLowerCase()||e.items.collection?.toLowerCase()||e.items.title?.toLowerCase();console.log("\u{1F7E3} COLLECTION/STYLE ID:",n);let c=t.find(m=>m.id===n);c||console.log("\u274C CARD NOT FOUND:",n);let l=c?.component;return oe("div",{className:"flex flex-col gap-4 w-full",children:[e.content&&C("div",{className:"bg-gray-100 p-4 rounded-2xl text-sm",children:e.content}),l&&e.items.items.map((m,d)=>C(l,{items:m,style:r},d))]})}return C("div",{className:`flex w-full ${e.role==="user"?"justify-end":"justify-start"}`,children:s&&e.record?C("div",{className:"max-w-[90%] animate-in fade-in slide-in-from-bottom-2 duration-300",children:C(s,{record:e.record,style:r})}):C("div",{style:e.role==="user"?{background:o?.showGradient===!1?"var(--cb-primary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary), var(--cb-accent))"}:{},className:`max-w-[85%] p-4 text-sm rounded-2xl shadow-sm transition-all animate-in fade-in slide-in-from-bottom-2 duration-300 ${e.role==="user"?"text-white rounded-tr-none":"bg-gray-100 text-zinc-800 rounded-tl-none"} whitespace-pre-wrap break-words`,children:e.loading&&!e.content?oe("div",{className:"flex gap-1 py-1 px-2",children:[C("span",{className:"w-1.5 h-1.5 bg-current rounded-full animate-bounce [animation-delay:-0.3s]"}),C("span",{className:"w-1.5 h-1.5 bg-current rounded-full animate-bounce [animation-delay:-0.15s]"}),C("span",{className:"w-1.5 h-1.5 bg-current rounded-full animate-bounce"})]}):e.content})})},F=Ne;import{useState as Q,useEffect as ke}from"react";import{jsx as g,jsxs as U}from"react/jsx-runtime";var Ie=({strapiUrl:e,onSelectQuestion:t,variant:r,theming:o})=>{let[a,s]=Q([]),[n,c]=Q(!0),[l,m]=Q(!1);ke(()=>{let i=new AbortController;return c(!0),fetch(`${e}/api/faqchatbot/suggestion-and-logo`,{signal:i.signal}).then(f=>f.json()).then(f=>{s(f.suggestedQuestions||[]),c(!1)}).catch(f=>{f.name!=="AbortError"&&(console.error("Suggestions fetch failed",f),c(!1))}),()=>i.abort()},[e]);let d=()=>r==="floating"?U("div",{className:"flex flex-col items-center gap-3 px-4 pt-1 w-full animate-pulse",children:[[1,2].map(i=>g("div",{className:"h-10 w-[70%] rounded-lg",style:{backgroundColor:o?.primaryColor?`${o.primaryColor}20`:"rgba(0,0,0,0.05)",transform:i%2===0?"rotate(1deg)":"rotate(-1deg)"}},i)),g("div",{className:"h-6 w-12 rounded-full mt-2"})]}):g("div",{className:"flex gap-2 overflow-x-auto no-scrollbar justify-start sm:justify-center py-2 animate-pulse",children:[1,2,3].map(i=>g("div",{className:"h-8 w-24 bg-gray-100 rounded-lg whitespace-nowrap"},i))});if(n&&a.length===0)return g(d,{});if(r==="floating"){let i=l?a:a.slice(0,2),f=!l&&a.length>2;return U("div",{className:"flex flex-col items-center gap-3 px-4 pt-2 pb-4 w-full",children:[g("style",{children:`
|
|
5
|
+
@keyframes fadeInUp {
|
|
6
|
+
from { opacity: 0; transform: translateY(10px) scale(0.95); }
|
|
7
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
8
|
+
}
|
|
9
|
+
`}),i.map((y,B)=>{let H=B%2===0?"rotate(-1deg)":"rotate(1deg)";return g("button",{onClick:()=>t(y),className:"bg-white border-2 px-6 py-2.5 rounded-xl shadow-sm text-sm font-medium hover:shadow-md hover:scale-[1.02] transition-all active:scale-95 cursor-pointer max-w-[85%] w-fit",style:{borderColor:o?.primaryColor||"var(--cb-primary)",color:"inherit",transform:H,animation:"fadeInUp 0.4s ease-out forwards",animationDelay:`${B*.1}s`,opacity:0},children:g("span",{className:"text-gray-700",children:y})},`float-${B}-${y}`)}),f&&g("button",{onClick:()=>m(!0),"aria-label":"Show more suggestions",title:"Show more suggestions",className:"mt-1 bg-gray-100 px-5 py-1.5 rounded-full hover:bg-gray-200 transition-colors active:scale-95 cursor-pointer shadow-sm",style:{animation:"fadeInUp 0.4s ease-out forwards",animationDelay:`${i.length*.1}s`,opacity:0},children:U("div",{className:"flex items-center gap-1",style:{color:o?.secondaryColor||"var(--cb-secondary)"},children:[g("div",{className:"w-1.5 h-1.5 rounded-full bg-current"}),g("div",{className:"w-1.5 h-1.5 rounded-full bg-current"}),g("div",{className:"w-1.5 h-1.5 rounded-full bg-current"})]})})]})}return U("div",{className:"flex gap-2 overflow-x-auto no-scrollbar justify-start sm:justify-center py-2",children:[g("style",{children:`
|
|
10
|
+
@keyframes fadeIn {
|
|
11
|
+
from { opacity: 0; }
|
|
12
|
+
to { opacity: 1; }
|
|
13
|
+
}
|
|
14
|
+
`}),a.map((i,f)=>g("button",{onClick:()=>t(i),className:"whitespace-nowrap border border-gray-200 px-4 py-1.5 rounded-lg text-xs text-gray-600 hover:bg-gray-50 transition-colors bg-white shadow-sm",style:{animation:"fadeIn 0.3s ease-out forwards",animationDelay:`${f*.05}s`,opacity:0},children:i},`list-${f}-${i}`))]})},K=Ie;import{jsx as E,jsxs as V}from"react/jsx-runtime";var Ee=({messages:e,scrollRef:t,sendMessage:r,strapiUrl:o,resolvedRegistry:a,theming:s})=>{let n=s?.showGradient===!1?"var(--cb-primary)":"linear-gradient(to top right, var(--cb-primary), var(--cb-secondary), var(--cb-accent))",c=s?.welcomeMessage||"How can I help you?",l=s?.welcomeDescription||"Select a common question below or type your own.";return V("div",{ref:t,className:"flex-1 overflow-y-auto px-6 py-3 space-y-6 bg-transparent no-scrollbar",style:{scrollbarWidth:"none",msOverflowStyle:"none"},children:[e.length===0&&V("div",{className:"flex flex-col items-center justify-center min-h-full text-center space-y-6",children:[E("div",{className:"w-20 h-20 rounded-full flex items-center justify-center text-white shadow-xl animate-[float_4s_ease-in-out_infinite]",style:{background:n},children:E(w.MessageCircle,{size:40})}),V("div",{children:[E("h3",{className:"text-2xl font-bold text-black tracking-tight",children:c}),E("p",{className:"text-sm text-gray-500 px-10",children:l})]}),E("div",{className:" w-full",children:E(K,{onSelectQuestion:r,strapiUrl:o,variant:"floating",theming:s})})]}),e.map(m=>E(F,{message:m,cardRegistry:a,theming:s},m.id))]})},re=Ee;import{jsx as L,jsxs as Y}from"react/jsx-runtime";var Re=({isExpanded:e,setIsExpanded:t,messages:r,scrollRef:o,sendMessage:a,strapiUrl:s,resolvedRegistry:n,input:c,setInput:l,isLoading:m,title:d,theming:i})=>{let y=S(`
|
|
15
|
+
relative flex flex-col bg-white border border-white/40 rounded-[2rem] shadow-2xl overflow-hidden
|
|
16
|
+
transition-all duration-500 cubic-bezier(0.4, 0, 0.2, 1) origin-bottom-right
|
|
17
|
+
w-[90vw] sm:w-[450px]
|
|
18
|
+
${e?"h-[70vh] md:h-[600px] sm:h-[750px] opacity-100 scale-100 translate-y-0":"h-0 opacity-0 scale-95 translate-y-10 pointer-events-none"}
|
|
19
|
+
max-h-[800px]
|
|
20
|
+
`,i?.container);return Y("div",{className:y,children:[L("div",{className:"flex-none z-20 bg-white/60 backdrop-blur-md border-b border-white/20",children:L(G,{title:d,onClose:()=>t(!1),theming:i,strapiUrl:s})}),L(re,{messages:r,scrollRef:o,sendMessage:a,strapiUrl:s,resolvedRegistry:n,theming:i}),Y("div",{className:"flex-none bg-white p-3 sm:p-4 border-t border-white/20",children:[L(_,{input:c,onInputChange:l,onSendMessage:a,isLoading:m,theming:i}),L("div",{className:"text-center mt-2",children:Y("span",{className:"text-[10px] text-gray-400 uppercase tracking-widest",children:["Powered by"," ",L("a",{href:"https://numentica-ui.com",className:"text-gray-400 font-semibold transition-colors hover:text-blue-600",children:"Numentica-UI"})]})})]})]})},ae=Re;import{jsx as ie,jsxs as Le}from"react/jsx-runtime";var Me=({strapiUrl:e,cardRegistry:t,theme:r,title:o,streamSpeed:a})=>{let[s,n]=P([]),[c,l]=P(""),[m,d]=P(!1),[i,f]=P(!1),y=ne(null),[B,H]=P([]),le=ne(null),ce={"--cb-primary":r?.primaryColor||"#2999d6","--cb-secondary":r?.secondaryColor||"#179fa3","--cb-accent":r?.accentColor||"#07a372"};return se(()=>{t.length>0&&H(t)},[t]),se(()=>()=>y.current?.abort(),[]),Le("div",{className:"fixed bottom-4 right-4 sm:bottom-6 sm:right-6 z-50 flex flex-col items-end font-sans",style:ce,children:[ie(X,{isExpanded:i,onOpen:()=>f(!0),theming:r}),ie(ae,{isExpanded:i,setIsExpanded:f,messages:s,scrollRef:le,sendMessage:async de=>{let z=de||c;if(!z.trim())return;y.current?.abort(),y.current=new AbortController,f(!0),l(""),d(!0);let ue={role:"user",content:z,id:Date.now()},R=Date.now()+1;n(I=>[...I,ue,{role:"assistant",content:"",items:null,loading:!0,id:R}]);try{let I=await fetch(`${e}/api/faqchatbot/ask`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({question:z,history:s.slice(-4).map(p=>({role:p.role,content:p.content}))}),signal:y.current.signal});if(!I.ok)throw new Error("Network response was not ok");let $=I.body?.getReader(),T=new TextDecoder;if(!$)throw new Error("No reader available");let D=[],q=!1,me=(async()=>{for(;!q||D.length>0;)if(D.length>0){let p=D.shift();if(p?.type==="text")if(a&&a>0)for(let u of p.content)n(h=>h.map(v=>v.id===R?{...v,content:v.content+u}:v)),await new Promise(h=>setTimeout(h,a));else n(u=>u.map(h=>h.id===R?{...h,content:h.content+p.content}:h));else if(p?.type==="card")try{let u=p.data;n(h=>h.map(v=>v.id===R?{...v,items:{items:u.items,schema:u.schema,collection:u.title,title:u.title,cardStyle:u.cardStyle}}:v))}catch(u){console.error("Error processing card data:",u)}}else await new Promise(p=>setTimeout(p,20));d(!1),n(p=>p.map(u=>u.id===R?{...u,loading:!1}:u))})(),W="";for(;;){let{value:p,done:u}=await $.read();if(u)break;let h=T.decode(p,{stream:!0});W+=h;let v=W.split(`
|
|
21
|
+
|
|
22
|
+
`);W=v.pop()||"";for(let fe of v){let pe=fe.split(`
|
|
23
|
+
`),Z="message",M="";for(let N of pe)if(N.startsWith("event:"))Z=N.slice(6).trim();else if(N.startsWith("data:")){let j=N.slice(5);j.startsWith(" ")&&(j=j.slice(1)),M+=(M?`
|
|
24
|
+
`:"")+j}if(M.trim()!=="[DONE]")if(Z==="cards")try{let N=JSON.parse(M);D.push({type:"card",data:N})}catch(N){console.error("Error parsing card data:",N)}else M&&D.push({type:"text",content:M})}}q=!0,await me}catch(I){I.name!=="AbortError"&&(console.error("Chat Error:",I),n($=>$.map(T=>T.id===R?{...T,content:"I'm sorry, I'm having trouble connecting right now.",loading:!1}:T))),d(!1)}},strapiUrl:e,resolvedRegistry:B,input:c,setInput:l,isLoading:m,title:o,theming:r})]})},Se=Me;export{Se as ChatBot,G as ChatHeader,_ as ChatInput,w as ICONS,F as MessageBubble,K as Suggestions};
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nui-chatbot-pkg",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"module": "./dist/index.mjs",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --minify --clean --inject-style",
|
|
12
|
+
"dev": "tsup src/index.ts --format cjs,esm --watch --dts",
|
|
13
|
+
"lint": "tsc"
|
|
14
|
+
},
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"react": ">=18",
|
|
17
|
+
"react-dom": ">=18",
|
|
18
|
+
"tailwindcss": ">=3"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/react": "^19.0.0",
|
|
22
|
+
"@types/react-dom": "^19.0.0",
|
|
23
|
+
"tsup": "^8.5.1",
|
|
24
|
+
"typescript": "^5.7.0",
|
|
25
|
+
"tailwindcss": "^3.4.0",
|
|
26
|
+
"postcss": "^8.4.0",
|
|
27
|
+
"autoprefixer": "^10.4.0"
|
|
28
|
+
}
|
|
29
|
+
}
|