@useknest/widget-react 0.1.0-beta.1 → 0.1.0-beta.10
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 +25 -19
- package/dist/ChatMessage.d.ts.map +1 -1
- package/dist/ChatWidget.d.ts +14 -3
- package/dist/ChatWidget.d.ts.map +1 -1
- package/dist/index.js +202 -107
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ import { ChatWidget } from '@useknest/widget-react';
|
|
|
22
22
|
function App() {
|
|
23
23
|
return (
|
|
24
24
|
<div>
|
|
25
|
-
<ChatWidget publishableApiKey="
|
|
25
|
+
<ChatWidget publishableApiKey="pk_your_public_key_here" />
|
|
26
26
|
</div>
|
|
27
27
|
);
|
|
28
28
|
}
|
|
@@ -34,9 +34,11 @@ function App() {
|
|
|
34
34
|
|
|
35
35
|
### ChatWidget
|
|
36
36
|
|
|
37
|
-
| Prop | Type
|
|
38
|
-
| ------------------- |
|
|
39
|
-
| `publishableApiKey` | `string`
|
|
37
|
+
| Prop | Type | Required | Default | Description |
|
|
38
|
+
| ------------------- | ---------------------- | -------- | ---------- | ---------------------------------------------------------- |
|
|
39
|
+
| `publishableApiKey` | `string` | Yes | - | Your project's publishable API key |
|
|
40
|
+
| `mode` | `'inline' \| 'bubble'` | No | `'inline'` | Display mode: inline or floating bubble button |
|
|
41
|
+
| `defaultOpen` | `boolean` | No | `false` | Whether the chat starts open (only applies to bubble mode) |
|
|
40
42
|
|
|
41
43
|
## Features
|
|
42
44
|
|
|
@@ -44,7 +46,7 @@ function App() {
|
|
|
44
46
|
- ✅ **Streaming Support** - Real-time message streaming via Server-Sent Events (SSE)
|
|
45
47
|
- ✅ **TypeScript** - Full TypeScript support with exported types
|
|
46
48
|
- ✅ **Customizable** - Fetches branding (avatar, colors, welcome message) from your project config
|
|
47
|
-
- ✅ **Lightweight** - ~
|
|
49
|
+
- ✅ **Lightweight** - ~17KB minified (~4.4KB gzipped)
|
|
48
50
|
- ✅ **Framework-Agnostic Core** - Shares business logic with other platform packages
|
|
49
51
|
|
|
50
52
|
## TypeScript
|
|
@@ -57,7 +59,7 @@ import { ChatWidget, type ChatWidgetProps, type Message } from '@useknest/widget
|
|
|
57
59
|
|
|
58
60
|
## Customization
|
|
59
61
|
|
|
60
|
-
The widget automatically loads customization from your project's configuration:
|
|
62
|
+
The widget automatically loads customization from your project's configuration at useknest.com:
|
|
61
63
|
|
|
62
64
|
- Avatar image
|
|
63
65
|
- Brand color
|
|
@@ -89,12 +91,11 @@ This package uses `@useknest/widget-core` for all business logic (API calls, str
|
|
|
89
91
|
|
|
90
92
|
```tsx
|
|
91
93
|
import { ChatWidget } from '@useknest/widget-react';
|
|
92
|
-
import '@useknest/widget-react/dist/widget-react.css';
|
|
93
94
|
|
|
94
95
|
function FullPageChat() {
|
|
95
96
|
return (
|
|
96
97
|
<div style={{ height: '100vh', width: '100vw' }}>
|
|
97
|
-
<ChatWidget publishableApiKey="
|
|
98
|
+
<ChatWidget publishableApiKey="pk_your_public_key_here" />
|
|
98
99
|
</div>
|
|
99
100
|
);
|
|
100
101
|
}
|
|
@@ -104,35 +105,40 @@ function FullPageChat() {
|
|
|
104
105
|
|
|
105
106
|
```tsx
|
|
106
107
|
import { ChatWidget } from '@useknest/widget-react';
|
|
107
|
-
import '@useknest/widget-react/dist/widget-react.css';
|
|
108
108
|
|
|
109
109
|
function ChatContainer() {
|
|
110
110
|
return (
|
|
111
111
|
<div style={{ maxWidth: '900px', height: '600px', margin: '0 auto' }}>
|
|
112
|
-
<ChatWidget publishableApiKey="
|
|
112
|
+
<ChatWidget publishableApiKey="pk_your_public_key_here" />
|
|
113
113
|
</div>
|
|
114
114
|
);
|
|
115
115
|
}
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
### Floating Bubble Mode
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
```tsx
|
|
121
|
+
import { ChatWidget } from '@useknest/widget-react';
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
function App() {
|
|
124
|
+
return <ChatWidget publishableApiKey="pk_your_public_key_here" mode="bubble" />;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
123
127
|
|
|
124
|
-
###
|
|
128
|
+
### Bubble Mode (Auto-Open)
|
|
125
129
|
|
|
126
|
-
|
|
130
|
+
```tsx
|
|
131
|
+
import { ChatWidget } from '@useknest/widget-react';
|
|
127
132
|
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
function App() {
|
|
134
|
+
return <ChatWidget publishableApiKey="pk_your_public_key_here" mode="bubble" defaultOpen />;
|
|
135
|
+
}
|
|
130
136
|
```
|
|
131
137
|
|
|
132
138
|
## License
|
|
133
139
|
|
|
134
|
-
|
|
140
|
+
Proprietary - All rights reserved. This software is for use by authorized Knest customers only.
|
|
135
141
|
|
|
136
142
|
## Support
|
|
137
143
|
|
|
138
|
-
For issues and questions, please
|
|
144
|
+
For issues and questions, please email us at useknest@gmail.com
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../src/ChatMessage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAC3B,OAAO,EACP,SAAiB,EACjB,SAAiC,EACjC,
|
|
1
|
+
{"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../src/ChatMessage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAC3B,OAAO,EACP,SAAiB,EACjB,SAAiC,EACjC,UAAgC,EAChC,UAAiB,EACjB,EAAE,gBAAgB,2CAkFlB"}
|
package/dist/ChatWidget.d.ts
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
import { WidgetMode } from '@useknest/widget-core';
|
|
2
|
+
/** Internal config for testing/development - not part of the public API. */
|
|
3
|
+
export interface InternalConfig {
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
supabaseUrl?: string;
|
|
6
|
+
supabaseAnonKey?: string;
|
|
7
|
+
}
|
|
1
8
|
export interface ChatWidgetProps {
|
|
2
9
|
publishableApiKey: string;
|
|
3
|
-
/**
|
|
4
|
-
|
|
10
|
+
/** Display mode: 'inline' renders in place, 'bubble' shows floating button. Defaults to 'inline'. */
|
|
11
|
+
mode?: WidgetMode;
|
|
12
|
+
/** Whether to auto-open the chat in bubble mode. Defaults to false. */
|
|
13
|
+
defaultOpen?: boolean;
|
|
14
|
+
/** Internal config for testing/development - not part of the public API. */
|
|
15
|
+
_internal?: InternalConfig;
|
|
5
16
|
}
|
|
6
|
-
export declare function ChatWidget({ publishableApiKey,
|
|
17
|
+
export declare function ChatWidget({ publishableApiKey, mode, defaultOpen, _internal }: ChatWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
7
18
|
//# sourceMappingURL=ChatWidget.d.ts.map
|
package/dist/ChatWidget.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../src/ChatWidget.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../src/ChatWidget.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAKX,UAAU,EACV,MAAM,uBAAuB,CAAC;AAK/B,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qGAAqG;IACrG,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,wBAAgB,UAAU,CAAC,EAC1B,iBAAiB,EACjB,IAAe,EACf,WAAmB,EACnB,SAAS,EACT,EAAE,eAAe,2CAyYjB"}
|
package/dist/index.js
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".knest-chat-card{display:flex;flex-direction:column;height:100%;background:#fff;border-radius:1rem;box-shadow:0 10px 15px -3px #0000001a;overflow:hidden;font-family:system-ui,-apple-system,sans-serif}.knest-loading-container{display:flex;align-items:center;justify-content:center;height:100%;background:linear-gradient(135deg,#fdfbf7,#fff)}.knest-loading-content{display:flex;flex-direction:column;align-items:center;gap:1.5rem}.knest-spinner-ring{width:3rem;height:3rem;border:3px solid #f3f4f6;border-top-color:#
|
|
2
|
-
import { jsx as e, jsxs as
|
|
3
|
-
import { useState as c, useRef as
|
|
4
|
-
import { formatContent as
|
|
5
|
-
function
|
|
6
|
-
message:
|
|
7
|
-
isLoading:
|
|
8
|
-
avatarUrl:
|
|
9
|
-
brandColor:
|
|
1
|
+
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".knest-chat-card{display:flex;flex-direction:column;height:100%;background:#fff;color:#374151;border-radius:1rem;box-shadow:0 10px 15px -3px #0000001a;overflow:hidden;font-family:system-ui,-apple-system,sans-serif}.knest-loading-container{display:flex;align-items:center;justify-content:center;height:100%;background:linear-gradient(135deg,#fdfbf7,#fff)}.knest-loading-content{display:flex;flex-direction:column;align-items:center;gap:1.5rem}.knest-spinner-ring{width:3rem;height:3rem;border:3px solid #f3f4f6;border-top-color:#3b82f6;border-radius:50%;animation:knest-spin .8s linear infinite}@keyframes knest-spin{to{transform:rotate(360deg)}}.knest-loading-text{font-size:.875rem;font-weight:500;color:#6b7280;margin:0}.knest-error-container{display:flex;align-items:center;justify-content:center;height:100%;background:linear-gradient(135deg,#fef2f2,#fff);padding:2rem}.knest-error-content{text-align:center;max-width:300px}.knest-error-text{font-size:.875rem;color:#991b1b;margin:0;line-height:1.5}.knest-header{border-bottom:1px solid #f3f4f6;padding:1rem}.knest-header-content{display:flex;align-items:center;gap:.75rem}.knest-avatar-img{width:2rem;height:2rem;object-fit:cover;border-radius:.25rem}.knest-header h2{font-size:1.125rem;font-weight:600;color:#111827;margin:0 0 .25rem}.knest-badge{display:inline-block;padding:.25rem .5rem;border-radius:9999px;font-size:.75rem;font-weight:500;color:#fff}.knest-messages-container{flex:1;overflow-y:auto}.knest-separator{margin:0 1.5rem;border-bottom:1px solid #e5e7eb}.knest-message-wrapper{display:flex;flex-direction:column}.knest-message{display:flex;gap:1rem;padding:1.25rem 1.5rem;align-items:center}.knest-message-avatar{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;flex-shrink:0}.knest-message-avatar .knest-avatar-img{width:100%;height:100%;border-radius:.25rem;object-fit:cover}.knest-user-avatar{width:2rem;height:2rem;border-radius:.25rem;display:flex;align-items:center;justify-content:center;color:#fff;font-size:.875rem;font-weight:500}.knest-message-content{flex:1;min-width:0}.knest-message-content p{margin:0 0 .5rem;font-size:.875rem;line-height:1.625;color:inherit;word-wrap:break-word}.knest-message-content p:last-child{margin-bottom:0}.knest-message-content code{background-color:#f3f4f6;padding:.125rem .375rem;border-radius:.25rem;font-family:ui-monospace,monospace;font-size:.8125rem;color:#ef4444}.knest-message-content pre{background-color:#1f2937;color:#f9fafb;padding:12px;border-radius:6px;overflow-x:auto;margin:8px 0}.knest-message-content pre code{background-color:transparent;padding:0;color:inherit;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.8125rem;line-height:1.5}.knest-message-content .token.keyword,.knest-message-content .token.builtin,.knest-message-content .token.tag{color:#ff7b72}.knest-message-content .token.string,.knest-message-content .token.attr-value{color:#a5d6ff}.knest-message-content .token.number,.knest-message-content .token.boolean{color:#79c0ff}.knest-message-content .token.function,.knest-message-content .token.class-name{color:#d2a8ff}.knest-message-content .token.comment{color:#8b949e;font-style:italic}.knest-message-content .token.variable,.knest-message-content .token.property{color:#ffa657}.knest-message-content .token.operator,.knest-message-content .token.punctuation{color:#c9d1d9}.knest-message-content a{color:inherit;text-decoration:underline}.knest-message-content ul,.knest-message-content ol{margin:8px 0;padding-left:24px}.knest-message-content li{margin:4px 0;color:inherit}.knest-message-content strong{font-weight:600;color:inherit}.knest-message-content em{font-style:italic}.knest-loading{display:flex;gap:.25rem;align-items:center}.knest-dot{width:.5rem;height:.5rem;background:#9ca3af;border-radius:50%;animation:knest-bounce 1.4s infinite ease-in-out both}.knest-dot:nth-child(2){animation-delay:.16s}.knest-dot:nth-child(3){animation-delay:.32s}@keyframes knest-bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}.knest-sources{margin-top:.75rem}.knest-sources-label{font-size:.75rem;font-weight:500;color:#6b7280;margin-bottom:.5rem}.knest-source-item{display:flex;gap:.5rem;padding:.5rem .75rem;margin-bottom:.25rem;border:1px solid #e5e7eb;border-radius:.375rem;background:#f9fafb;text-decoration:none;transition:all .15s}.knest-source-item:hover{border-color:#d1d5db;background:#f3f4f6}.knest-source-icon{width:1rem;height:1rem;color:#6b7280;flex-shrink:0}.knest-source-text{flex:1;min-width:0}.knest-source-breadcrumb{font-size:.75rem;color:#6b7280;margin-bottom:.125rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.knest-source-title{font-size:.875rem;font-weight:500;color:#374151;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.knest-examples{border-top:1px solid #e5e7eb;padding:1.25rem 1.5rem}.knest-examples h3{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#6b7280;margin:0 0 1rem}.knest-example-btn{width:100%;padding:.75rem;margin-bottom:.75rem;border:1px solid #e5e7eb;border-radius:.5rem;background:#fff;text-align:left;font-size:.875rem;color:#374151;cursor:pointer;transition:background .15s}.knest-example-btn:hover{background:#f9fafb}.knest-input-section{border-top:1px solid #f3f4f6;padding:1rem}.knest-input-wrapper{display:flex;align-items:center;gap:.5rem}.knest-input-field{flex:1;padding:.75rem 1rem;border:1px solid #e5e7eb;border-radius:.5rem;background:#f9fafb;font-size:.875rem;color:#374151;outline:none}.knest-input-field:focus{background:#fff;border-color:#d1d5db}.knest-input-field:disabled{opacity:.5}.knest-send-btn{width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;border:none;border-radius:.5rem;background:#e5e7eb;color:#6b7280;cursor:pointer;transition:background .15s}.knest-send-btn:hover:not(:disabled){background:#d1d5db}.knest-send-btn:disabled{opacity:.5;cursor:not-allowed}.knest-send-icon{width:1rem;height:1rem}.knest-footer{margin-top:.75rem;display:flex;justify-content:center}.knest-powered-by{display:flex;align-items:center;gap:.125rem;font-size:.75rem;color:#6b7280;text-decoration:none;transition:color .15s}.knest-powered-by:hover{color:#374151;text-decoration:underline}.knest-bubble-container{position:fixed;bottom:24px;right:24px;z-index:9999;display:flex;flex-direction:column;align-items:flex-end;gap:16px;font-family:system-ui,-apple-system,sans-serif}.knest-bubble-button{width:56px;height:56px;border-radius:50%;border:none;color:#fff;cursor:pointer;box-shadow:0 4px 12px #00000026;display:flex;align-items:center;justify-content:center;transition:transform .2s,box-shadow .2s}.knest-bubble-button:hover{transform:scale(1.05);box-shadow:0 6px 16px #0003}.knest-bubble-spinner{animation:knest-spin 1s linear infinite}.knest-bubble-panel{width:380px;height:520px;max-width:calc(100vw - 48px);max-height:calc(100vh - 100px);border-radius:1rem;border:1px solid rgba(0,0,0,.1);box-shadow:0 10px 15px -3px #0000001a;overflow:hidden}.knest-bubble-panel .knest-chat-card{height:100%}@media (max-width: 440px){.knest-bubble-container{bottom:16px;right:16px}.knest-bubble-panel{width:calc(100vw - 32px);height:calc(100vh - 100px)}}")),document.head.appendChild(e)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}})();
|
|
2
|
+
import { jsx as e, jsxs as r } from "react/jsx-runtime";
|
|
3
|
+
import { useState as c, useRef as z, useEffect as I } from "react";
|
|
4
|
+
import { formatContent as G, DEFAULT_BRAND_COLOR as T, DEFAULT_AVATAR_URL as H, DEFAULT_EXAMPLE_QUESTIONS as V, initWidgetSentry as _, PUBLIC_SUPABASE_URL as q, PUBLIC_SUPABASE_ANON_KEY as X, initWidgetAuth as Y, subscribeToThread as $, AUTH_ERROR_MESSAGE as J, fetchWidgetConfig as Z, DEFAULT_WELCOME_MESSAGE as ee, streamChatMessage as te, captureWidgetException as ne } from "@useknest/widget-core";
|
|
5
|
+
function se({
|
|
6
|
+
message: o,
|
|
7
|
+
isLoading: y = !1,
|
|
8
|
+
avatarUrl: E = "/default-avatar.svg",
|
|
9
|
+
brandColor: i = T,
|
|
10
10
|
showAvatar: v = !0
|
|
11
11
|
}) {
|
|
12
|
-
const [p,
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
return /* @__PURE__ */ e("div", { className: "knest-message-wrapper", children: /* @__PURE__ */
|
|
16
|
-
v && /* @__PURE__ */ e("div", { className: "knest-message-avatar", children:
|
|
12
|
+
const [p, u] = c(!1), C = () => {
|
|
13
|
+
u(!0);
|
|
14
|
+
}, w = o.content ? G(o.content) : "";
|
|
15
|
+
return /* @__PURE__ */ e("div", { className: "knest-message-wrapper", children: /* @__PURE__ */ r("div", { className: "knest-message", children: [
|
|
16
|
+
v && /* @__PURE__ */ e("div", { className: "knest-message-avatar", children: o.role === "assistant" ? p ? /* @__PURE__ */ e("div", { className: "knest-user-avatar", style: { backgroundColor: i }, children: "AI" }) : /* @__PURE__ */ e(
|
|
17
17
|
"img",
|
|
18
18
|
{
|
|
19
|
-
src:
|
|
19
|
+
src: E,
|
|
20
20
|
alt: "Avatar",
|
|
21
21
|
className: "knest-avatar-img",
|
|
22
|
-
onError:
|
|
22
|
+
onError: C
|
|
23
23
|
}
|
|
24
|
-
) : /* @__PURE__ */ e("div", { className: "knest-user-avatar", style: { backgroundColor:
|
|
25
|
-
/* @__PURE__ */
|
|
26
|
-
!
|
|
24
|
+
) : /* @__PURE__ */ e("div", { className: "knest-user-avatar", style: { backgroundColor: i }, children: "U" }) }),
|
|
25
|
+
/* @__PURE__ */ r("div", { className: "knest-message-content", children: [
|
|
26
|
+
!o.content && y && o.role === "assistant" ? /* @__PURE__ */ r("div", { className: "knest-loading", children: [
|
|
27
27
|
/* @__PURE__ */ e("div", { className: "knest-dot" }),
|
|
28
28
|
/* @__PURE__ */ e("div", { className: "knest-dot" }),
|
|
29
29
|
/* @__PURE__ */ e("div", { className: "knest-dot" })
|
|
30
|
-
] }) :
|
|
31
|
-
|
|
30
|
+
] }) : /* @__PURE__ */ e("div", { dangerouslySetInnerHTML: { __html: w } }),
|
|
31
|
+
o.sources && o.sources.length > 0 && /* @__PURE__ */ r("div", { className: "knest-sources", children: [
|
|
32
32
|
/* @__PURE__ */ e("div", { className: "knest-sources-label", children: "Sources" }),
|
|
33
|
-
|
|
33
|
+
o.sources.slice(0, 1).map((m, k) => /* @__PURE__ */ r(
|
|
34
34
|
"a",
|
|
35
35
|
{
|
|
36
|
-
href:
|
|
36
|
+
href: m.url,
|
|
37
37
|
target: "_blank",
|
|
38
38
|
rel: "noopener noreferrer",
|
|
39
39
|
className: "knest-source-item",
|
|
@@ -56,146 +56,163 @@ function X({
|
|
|
56
56
|
)
|
|
57
57
|
}
|
|
58
58
|
),
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
-
|
|
61
|
-
/* @__PURE__ */ e("div", { className: "knest-source-title", children:
|
|
59
|
+
/* @__PURE__ */ r("div", { className: "knest-source-text", children: [
|
|
60
|
+
m.breadcrumb && /* @__PURE__ */ e("div", { className: "knest-source-breadcrumb", children: m.breadcrumb }),
|
|
61
|
+
/* @__PURE__ */ e("div", { className: "knest-source-title", children: m.title })
|
|
62
62
|
] })
|
|
63
63
|
]
|
|
64
64
|
},
|
|
65
|
-
|
|
65
|
+
k
|
|
66
66
|
))
|
|
67
67
|
] })
|
|
68
68
|
] })
|
|
69
69
|
] }) });
|
|
70
70
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
function le({
|
|
72
|
+
publishableApiKey: o,
|
|
73
|
+
mode: y = "inline",
|
|
74
|
+
defaultOpen: E = !1,
|
|
75
|
+
_internal: i
|
|
76
|
+
}) {
|
|
77
|
+
const [v, p] = c(null), [u, C] = c(!0), [w, m] = c(null), [k, R] = c(!1), [f, h] = c([]), [N, A] = c(""), [L, S] = c(!1), [g, O] = c(void 0), [x, P] = c(E), M = z(null), j = v?.avatarUrl || H, D = v?.exampleQuestions || V, U = v?.brandColor || T;
|
|
78
|
+
I(() => {
|
|
79
|
+
typeof requestIdleCallback < "u" ? requestIdleCallback(() => _()) : setTimeout(() => _(), 0);
|
|
80
|
+
const t = i?.supabaseUrl || q, s = i?.supabaseAnonKey || X, d = Y(t, s);
|
|
81
|
+
(async () => {
|
|
82
|
+
const n = await Z(
|
|
83
|
+
o,
|
|
84
|
+
i?.baseUrl,
|
|
85
|
+
(l) => {
|
|
86
|
+
p(l);
|
|
87
|
+
}
|
|
88
|
+
);
|
|
76
89
|
if (n.error) {
|
|
77
|
-
|
|
90
|
+
m(n.error), C(!1);
|
|
78
91
|
return;
|
|
79
92
|
}
|
|
80
|
-
|
|
81
|
-
const h = await z(
|
|
82
|
-
n.config.supabaseUrl,
|
|
83
|
-
n.config.supabaseAnonKey
|
|
84
|
-
);
|
|
85
|
-
h || console.warn("Widget auth initialization failed"), i(h);
|
|
86
|
-
}
|
|
87
|
-
p(!1), u([
|
|
93
|
+
p(n.config), C(!1), h([
|
|
88
94
|
{
|
|
89
95
|
role: "assistant",
|
|
90
|
-
content: n.config?.welcomeMessage ||
|
|
96
|
+
content: n.config?.welcomeMessage || ee
|
|
91
97
|
}
|
|
92
98
|
]);
|
|
99
|
+
const a = await d;
|
|
100
|
+
a || console.warn("Widget auth initialization failed"), R(a);
|
|
93
101
|
})();
|
|
94
|
-
}, [
|
|
95
|
-
|
|
96
|
-
}, [
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
}, [o, i]), I(() => {
|
|
103
|
+
f.length > 0 && M.current && M.current.scrollIntoView({ behavior: "smooth" });
|
|
104
|
+
}, [f]), I(() => !g || !k ? void 0 : $(g, (s) => {
|
|
105
|
+
s.role === "human" && h(
|
|
106
|
+
(d) => d.some((b) => b.id === s.id) ? d : [...d, { id: s.id, role: "assistant", content: s.content }]
|
|
107
|
+
);
|
|
108
|
+
}), [g, k]);
|
|
109
|
+
const W = async () => {
|
|
110
|
+
if (!N.trim() || L || !k) return;
|
|
111
|
+
const t = N.trim();
|
|
112
|
+
A(""), S(!0), h((n) => [...n, { role: "user", content: t }]);
|
|
113
|
+
const s = f.length + 1;
|
|
114
|
+
h((n) => [...n, { role: "assistant", content: "" }]);
|
|
115
|
+
let d = "", b = [];
|
|
116
|
+
await te({
|
|
117
|
+
publishableApiKey: o,
|
|
106
118
|
content: t,
|
|
107
|
-
threadId:
|
|
108
|
-
baseUrl:
|
|
119
|
+
threadId: g,
|
|
120
|
+
baseUrl: i?.baseUrl,
|
|
109
121
|
callbacks: {
|
|
110
|
-
onInit: (
|
|
111
|
-
|
|
122
|
+
onInit: (n) => {
|
|
123
|
+
g || O(n);
|
|
112
124
|
},
|
|
113
|
-
onContent: (
|
|
114
|
-
|
|
115
|
-
const l = [...
|
|
116
|
-
return l[
|
|
125
|
+
onContent: (n) => {
|
|
126
|
+
d += n, h((a) => {
|
|
127
|
+
const l = [...a];
|
|
128
|
+
return l[s] = {
|
|
117
129
|
role: "assistant",
|
|
118
|
-
content:
|
|
130
|
+
content: d
|
|
119
131
|
}, l;
|
|
120
132
|
});
|
|
121
133
|
},
|
|
122
|
-
onComplete: (
|
|
123
|
-
|
|
124
|
-
const l = [...
|
|
125
|
-
return l[
|
|
134
|
+
onComplete: (n) => {
|
|
135
|
+
b = n, h((a) => {
|
|
136
|
+
const l = [...a];
|
|
137
|
+
return l[s] = {
|
|
126
138
|
role: "assistant",
|
|
127
|
-
content:
|
|
128
|
-
sources:
|
|
139
|
+
content: d,
|
|
140
|
+
sources: b
|
|
129
141
|
}, l;
|
|
130
142
|
});
|
|
131
143
|
},
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
144
|
+
onDone: ({ humanTakeover: n }) => {
|
|
145
|
+
n && h((a) => [
|
|
146
|
+
...a.slice(0, s),
|
|
147
|
+
...a.slice(s + 1)
|
|
148
|
+
]);
|
|
149
|
+
},
|
|
150
|
+
onError: (n) => {
|
|
151
|
+
ne(n, { userMessage: t, threadId: g, baseUrl: i?.baseUrl }), h((a) => {
|
|
152
|
+
const l = [...a];
|
|
153
|
+
return l[s] = {
|
|
136
154
|
role: "assistant",
|
|
137
|
-
content: `Error: ${
|
|
155
|
+
content: `Error: ${n}`
|
|
138
156
|
}, l;
|
|
139
157
|
});
|
|
140
158
|
}
|
|
141
159
|
}
|
|
142
|
-
}),
|
|
143
|
-
},
|
|
144
|
-
t.key === "Enter" && !t.shiftKey && (t.preventDefault(),
|
|
145
|
-
},
|
|
146
|
-
A(t), setTimeout(() =>
|
|
147
|
-
}
|
|
148
|
-
return v ? /* @__PURE__ */ e("div", { className: "knest-chat-card", children: /* @__PURE__ */ e("div", { className: "knest-loading-container", children: /* @__PURE__ */ s("div", { className: "knest-loading-content", children: [
|
|
160
|
+
}), S(!1);
|
|
161
|
+
}, K = (t) => {
|
|
162
|
+
t.key === "Enter" && !t.shiftKey && (t.preventDefault(), W());
|
|
163
|
+
}, F = async (t) => {
|
|
164
|
+
A(t), setTimeout(() => W(), 0);
|
|
165
|
+
}, B = u ? /* @__PURE__ */ e("div", { className: "knest-chat-card", children: /* @__PURE__ */ e("div", { className: "knest-loading-container", children: /* @__PURE__ */ r("div", { className: "knest-loading-content", children: [
|
|
149
166
|
/* @__PURE__ */ e("div", { className: "knest-spinner-ring" }),
|
|
150
167
|
/* @__PURE__ */ e("p", { className: "knest-loading-text", children: "Loading chat..." })
|
|
151
|
-
] }) }) }) :
|
|
152
|
-
/* @__PURE__ */
|
|
153
|
-
|
|
168
|
+
] }) }) }) : w === "auth" ? /* @__PURE__ */ e("div", { className: "knest-chat-card", children: /* @__PURE__ */ e("div", { className: "knest-error-container", children: /* @__PURE__ */ e("div", { className: "knest-error-content", children: /* @__PURE__ */ e("p", { className: "knest-error-text", children: J }) }) }) }) : /* @__PURE__ */ r("div", { className: "knest-chat-card", children: [
|
|
169
|
+
/* @__PURE__ */ r("div", { className: "knest-messages-container", children: [
|
|
170
|
+
f.map((t, s) => /* @__PURE__ */ r("div", { children: [
|
|
154
171
|
/* @__PURE__ */ e(
|
|
155
|
-
|
|
172
|
+
se,
|
|
156
173
|
{
|
|
157
174
|
message: t,
|
|
158
|
-
isLoading: !t.content &&
|
|
159
|
-
avatarUrl:
|
|
160
|
-
brandColor:
|
|
175
|
+
isLoading: !t.content && L && t.role === "assistant",
|
|
176
|
+
avatarUrl: j,
|
|
177
|
+
brandColor: U
|
|
161
178
|
}
|
|
162
179
|
),
|
|
163
|
-
|
|
164
|
-
] },
|
|
165
|
-
|
|
180
|
+
s < f.length - 1 && /* @__PURE__ */ e("div", { className: "knest-separator" })
|
|
181
|
+
] }, s)),
|
|
182
|
+
f.length === 1 && !u && /* @__PURE__ */ r("div", { className: "knest-examples", children: [
|
|
166
183
|
/* @__PURE__ */ e("h3", { children: "Example Questions" }),
|
|
167
|
-
|
|
184
|
+
D.map((t, s) => /* @__PURE__ */ e(
|
|
168
185
|
"button",
|
|
169
186
|
{
|
|
170
|
-
onClick: () =>
|
|
187
|
+
onClick: () => F(t),
|
|
171
188
|
className: "knest-example-btn",
|
|
172
|
-
style:
|
|
189
|
+
style: s === 0 ? { borderColor: U, borderWidth: "2px" } : {},
|
|
173
190
|
children: t
|
|
174
191
|
},
|
|
175
|
-
|
|
192
|
+
s
|
|
176
193
|
))
|
|
177
194
|
] }),
|
|
178
|
-
/* @__PURE__ */ e("div", { ref:
|
|
195
|
+
/* @__PURE__ */ e("div", { ref: M })
|
|
179
196
|
] }),
|
|
180
|
-
/* @__PURE__ */
|
|
181
|
-
/* @__PURE__ */
|
|
197
|
+
/* @__PURE__ */ r("div", { className: "knest-input-section", children: [
|
|
198
|
+
/* @__PURE__ */ r("div", { className: "knest-input-wrapper", children: [
|
|
182
199
|
/* @__PURE__ */ e(
|
|
183
200
|
"input",
|
|
184
201
|
{
|
|
185
202
|
type: "text",
|
|
186
|
-
value:
|
|
203
|
+
value: N,
|
|
187
204
|
onChange: (t) => A(t.target.value),
|
|
188
|
-
onKeyPress:
|
|
205
|
+
onKeyPress: K,
|
|
189
206
|
placeholder: "Ask me anything...",
|
|
190
|
-
disabled:
|
|
207
|
+
disabled: L || !k,
|
|
191
208
|
className: "knest-input-field"
|
|
192
209
|
}
|
|
193
210
|
),
|
|
194
211
|
/* @__PURE__ */ e(
|
|
195
212
|
"button",
|
|
196
213
|
{
|
|
197
|
-
onClick:
|
|
198
|
-
disabled:
|
|
214
|
+
onClick: W,
|
|
215
|
+
disabled: L || !N.trim() || !k,
|
|
199
216
|
className: "knest-send-btn",
|
|
200
217
|
"aria-label": "Send message",
|
|
201
218
|
children: /* @__PURE__ */ e("svg", { className: "knest-send-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e(
|
|
@@ -210,7 +227,7 @@ function Z({ publishableApiKey: r, baseUrl: d }) {
|
|
|
210
227
|
}
|
|
211
228
|
)
|
|
212
229
|
] }),
|
|
213
|
-
/* @__PURE__ */ e("div", { className: "knest-footer", children: /* @__PURE__ */
|
|
230
|
+
/* @__PURE__ */ e("div", { className: "knest-footer", children: /* @__PURE__ */ r(
|
|
214
231
|
"a",
|
|
215
232
|
{
|
|
216
233
|
href: "https://useknest.com",
|
|
@@ -219,7 +236,7 @@ function Z({ publishableApiKey: r, baseUrl: d }) {
|
|
|
219
236
|
className: "knest-powered-by",
|
|
220
237
|
children: [
|
|
221
238
|
/* @__PURE__ */ e("span", { children: "Powered by" }),
|
|
222
|
-
/* @__PURE__ */
|
|
239
|
+
/* @__PURE__ */ r(
|
|
223
240
|
"svg",
|
|
224
241
|
{
|
|
225
242
|
width: "14",
|
|
@@ -286,8 +303,86 @@ function Z({ publishableApiKey: r, baseUrl: d }) {
|
|
|
286
303
|
) })
|
|
287
304
|
] })
|
|
288
305
|
] });
|
|
306
|
+
if (y === "inline")
|
|
307
|
+
return B;
|
|
308
|
+
const Q = u ? "#9ca3af" : U;
|
|
309
|
+
return /* @__PURE__ */ r("div", { className: "knest-bubble-container", children: [
|
|
310
|
+
x && /* @__PURE__ */ e("div", { className: "knest-bubble-panel", children: B }),
|
|
311
|
+
/* @__PURE__ */ e(
|
|
312
|
+
"button",
|
|
313
|
+
{
|
|
314
|
+
className: ["knest-bubble-button", u && "knest-bubble-loading"].filter(Boolean).join(" "),
|
|
315
|
+
onClick: () => P(!x),
|
|
316
|
+
"aria-label": u ? "Loading chat" : x ? "Close chat" : "Open chat",
|
|
317
|
+
style: { backgroundColor: Q },
|
|
318
|
+
children: u ? /* @__PURE__ */ r(
|
|
319
|
+
"svg",
|
|
320
|
+
{
|
|
321
|
+
width: "24",
|
|
322
|
+
height: "24",
|
|
323
|
+
viewBox: "0 0 24 24",
|
|
324
|
+
fill: "none",
|
|
325
|
+
className: "knest-bubble-spinner",
|
|
326
|
+
children: [
|
|
327
|
+
/* @__PURE__ */ e(
|
|
328
|
+
"circle",
|
|
329
|
+
{
|
|
330
|
+
cx: "12",
|
|
331
|
+
cy: "12",
|
|
332
|
+
r: "9",
|
|
333
|
+
stroke: "currentColor",
|
|
334
|
+
strokeOpacity: "0.25",
|
|
335
|
+
strokeWidth: "3",
|
|
336
|
+
fill: "none"
|
|
337
|
+
}
|
|
338
|
+
),
|
|
339
|
+
/* @__PURE__ */ e(
|
|
340
|
+
"path",
|
|
341
|
+
{
|
|
342
|
+
d: "M12 3a9 9 0 0 1 9 9",
|
|
343
|
+
stroke: "currentColor",
|
|
344
|
+
strokeWidth: "3",
|
|
345
|
+
strokeLinecap: "round",
|
|
346
|
+
fill: "none"
|
|
347
|
+
}
|
|
348
|
+
)
|
|
349
|
+
]
|
|
350
|
+
}
|
|
351
|
+
) : x ? /* @__PURE__ */ e(
|
|
352
|
+
"svg",
|
|
353
|
+
{
|
|
354
|
+
width: "24",
|
|
355
|
+
height: "24",
|
|
356
|
+
viewBox: "0 0 24 24",
|
|
357
|
+
fill: "none",
|
|
358
|
+
stroke: "currentColor",
|
|
359
|
+
strokeWidth: "2",
|
|
360
|
+
children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
|
|
361
|
+
}
|
|
362
|
+
) : /* @__PURE__ */ e(
|
|
363
|
+
"svg",
|
|
364
|
+
{
|
|
365
|
+
width: "24",
|
|
366
|
+
height: "24",
|
|
367
|
+
viewBox: "0 0 24 24",
|
|
368
|
+
fill: "none",
|
|
369
|
+
stroke: "currentColor",
|
|
370
|
+
strokeWidth: "2",
|
|
371
|
+
children: /* @__PURE__ */ e(
|
|
372
|
+
"path",
|
|
373
|
+
{
|
|
374
|
+
strokeLinecap: "round",
|
|
375
|
+
strokeLinejoin: "round",
|
|
376
|
+
d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
|
377
|
+
}
|
|
378
|
+
)
|
|
379
|
+
}
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
)
|
|
383
|
+
] });
|
|
289
384
|
}
|
|
290
385
|
export {
|
|
291
|
-
|
|
292
|
-
|
|
386
|
+
se as ChatMessage,
|
|
387
|
+
le as ChatWidget
|
|
293
388
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useknest/widget-react",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Native React component for Knest chat widget",
|
|
6
6
|
"files": [
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@useknest/widget-core": "0.1.0-beta.
|
|
25
|
+
"@useknest/widget-core": "0.1.0-beta.10"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/react": "^18.3.3",
|