@useknest/widget-react 0.1.0-beta.1 → 0.1.0-beta.11
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 +220 -111
- 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":"AAmBA,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,2CA2ajB"}
|
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
|
|
4
|
-
import { formatContent as O, DEFAULT_AVATAR_URL 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-reset-row{display:flex;justify-content:center;margin-top:.5rem}.knest-reset-btn{background:none;border:none;padding:0;font-size:.75rem;color:#9ca3af;cursor:pointer;transition:color .15s}.knest-reset-btn:hover{color:#6b7280}.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 d, useRef as q, useEffect as E } from "react";
|
|
4
|
+
import { formatContent as K, DEFAULT_BRAND_COLOR as O, DEFAULT_AVATAR_URL as X, DEFAULT_EXAMPLE_QUESTIONS as Y, initWidgetSentry as T, PUBLIC_SUPABASE_URL as $, PUBLIC_SUPABASE_ANON_KEY as J, initWidgetAuth as Z, saveChatStateDebounced as ee, subscribeToThread as te, AUTH_ERROR_MESSAGE as ne, fetchWidgetConfig as se, loadChatState as re, DEFAULT_WELCOME_MESSAGE as R, streamChatMessage as ae, captureWidgetException as oe, clearChatState as ce } from "@useknest/widget-core";
|
|
5
|
+
function le({
|
|
6
|
+
message: a,
|
|
7
|
+
isLoading: M = !1,
|
|
8
|
+
avatarUrl: y = "/default-avatar.svg",
|
|
9
|
+
brandColor: h = O,
|
|
10
10
|
showAvatar: v = !0
|
|
11
11
|
}) {
|
|
12
|
-
const [
|
|
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 [L, k] = d(!1), x = () => {
|
|
13
|
+
k(!0);
|
|
14
|
+
}, A = a.content ? K(a.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: a.role === "assistant" ? L ? /* @__PURE__ */ e("div", { className: "knest-user-avatar", style: { backgroundColor: h }, children: "AI" }) : /* @__PURE__ */ e(
|
|
17
17
|
"img",
|
|
18
18
|
{
|
|
19
|
-
src:
|
|
19
|
+
src: y,
|
|
20
20
|
alt: "Avatar",
|
|
21
21
|
className: "knest-avatar-img",
|
|
22
|
-
onError:
|
|
22
|
+
onError: x
|
|
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: h }, children: "U" }) }),
|
|
25
|
+
/* @__PURE__ */ r("div", { className: "knest-message-content", children: [
|
|
26
|
+
!a.content && M && a.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: A } }),
|
|
31
|
+
a.sources && a.sources.length > 0 && /* @__PURE__ */ r("div", { className: "knest-sources", children: [
|
|
32
32
|
/* @__PURE__ */ e("div", { className: "knest-sources-label", children: "Sources" }),
|
|
33
|
-
|
|
33
|
+
a.sources.slice(0, 1).map((C, f) => /* @__PURE__ */ r(
|
|
34
34
|
"a",
|
|
35
35
|
{
|
|
36
|
-
href:
|
|
36
|
+
href: C.url,
|
|
37
37
|
target: "_blank",
|
|
38
38
|
rel: "noopener noreferrer",
|
|
39
39
|
className: "knest-source-item",
|
|
@@ -56,146 +56,176 @@ 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
|
+
C.breadcrumb && /* @__PURE__ */ e("div", { className: "knest-source-breadcrumb", children: C.breadcrumb }),
|
|
61
|
+
/* @__PURE__ */ e("div", { className: "knest-source-title", children: C.title })
|
|
62
62
|
] })
|
|
63
63
|
]
|
|
64
64
|
},
|
|
65
|
-
|
|
65
|
+
f
|
|
66
66
|
))
|
|
67
67
|
] })
|
|
68
68
|
] })
|
|
69
69
|
] }) });
|
|
70
70
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
function ue({
|
|
72
|
+
publishableApiKey: a,
|
|
73
|
+
mode: M = "inline",
|
|
74
|
+
defaultOpen: y = !1,
|
|
75
|
+
_internal: h
|
|
76
|
+
}) {
|
|
77
|
+
const [v, L] = d(null), [k, x] = d(!0), [A, C] = d(null), [f, D] = d(!1), [l, i] = d([]), [g, b] = d(""), [p, B] = d(!1), [m, U] = d(void 0), [w, P] = d(y), S = q(null), j = v?.avatarUrl || X, F = v?.exampleQuestions || Y, W = v?.brandColor || O;
|
|
78
|
+
E(() => {
|
|
79
|
+
typeof requestIdleCallback < "u" ? requestIdleCallback(() => T()) : setTimeout(() => T(), 0);
|
|
80
|
+
const t = h?.supabaseUrl || $, s = h?.supabaseAnonKey || J, u = Z(t, s);
|
|
81
|
+
(async () => {
|
|
82
|
+
const n = await se(
|
|
83
|
+
a,
|
|
84
|
+
h?.baseUrl,
|
|
85
|
+
(V) => {
|
|
86
|
+
L(V);
|
|
87
|
+
}
|
|
88
|
+
);
|
|
76
89
|
if (n.error) {
|
|
77
|
-
|
|
90
|
+
C(n.error), x(!1);
|
|
78
91
|
return;
|
|
79
92
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
n.config.supabaseAnonKey
|
|
84
|
-
);
|
|
85
|
-
h || console.warn("Widget auth initialization failed"), i(h);
|
|
86
|
-
}
|
|
87
|
-
p(!1), u([
|
|
93
|
+
L(n.config), x(!1);
|
|
94
|
+
const o = re(a);
|
|
95
|
+
o && o.messages.length > 0 ? (i(o.messages), U(o.threadId), b(o.input)) : i([
|
|
88
96
|
{
|
|
89
97
|
role: "assistant",
|
|
90
|
-
content: n.config?.welcomeMessage ||
|
|
98
|
+
content: n.config?.welcomeMessage || R
|
|
91
99
|
}
|
|
92
100
|
]);
|
|
101
|
+
const c = await u;
|
|
102
|
+
c || console.warn("Widget auth initialization failed"), D(c);
|
|
93
103
|
})();
|
|
94
|
-
}, [
|
|
95
|
-
|
|
96
|
-
}, [
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
}, [a, h]), E(() => {
|
|
105
|
+
l.length > 0 && S.current && S.current.scrollIntoView({ behavior: "smooth" });
|
|
106
|
+
}, [l]), E(() => {
|
|
107
|
+
l.length <= 1 && !g || ee(a, {
|
|
108
|
+
threadId: m,
|
|
109
|
+
messages: l,
|
|
110
|
+
input: g,
|
|
111
|
+
savedAt: Date.now()
|
|
112
|
+
});
|
|
113
|
+
}, [l, m, g, a]), E(() => !m || !f ? void 0 : te(m, (s) => {
|
|
114
|
+
s.role === "human" && i(
|
|
115
|
+
(u) => u.some((N) => N.id === s.id) ? u : [...u, { id: s.id, role: "assistant", content: s.content }]
|
|
116
|
+
);
|
|
117
|
+
}), [m, f]);
|
|
118
|
+
const I = async () => {
|
|
119
|
+
if (!g.trim() || p || !f) return;
|
|
120
|
+
const t = g.trim();
|
|
121
|
+
b(""), B(!0), i((n) => [...n, { role: "user", content: t }]);
|
|
122
|
+
const s = l.length + 1;
|
|
123
|
+
i((n) => [...n, { role: "assistant", content: "" }]);
|
|
124
|
+
let u = "", N = [];
|
|
125
|
+
await ae({
|
|
126
|
+
publishableApiKey: a,
|
|
106
127
|
content: t,
|
|
107
|
-
threadId:
|
|
108
|
-
baseUrl:
|
|
128
|
+
threadId: m,
|
|
129
|
+
baseUrl: h?.baseUrl,
|
|
109
130
|
callbacks: {
|
|
110
|
-
onInit: (
|
|
111
|
-
|
|
131
|
+
onInit: (n) => {
|
|
132
|
+
m || U(n);
|
|
112
133
|
},
|
|
113
|
-
onContent: (
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
return
|
|
134
|
+
onContent: (n) => {
|
|
135
|
+
u += n, i((o) => {
|
|
136
|
+
const c = [...o];
|
|
137
|
+
return c[s] = {
|
|
117
138
|
role: "assistant",
|
|
118
|
-
content:
|
|
119
|
-
},
|
|
139
|
+
content: u
|
|
140
|
+
}, c;
|
|
120
141
|
});
|
|
121
142
|
},
|
|
122
|
-
onComplete: (
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
return
|
|
143
|
+
onComplete: (n) => {
|
|
144
|
+
N = n, i((o) => {
|
|
145
|
+
const c = [...o];
|
|
146
|
+
return c[s] = {
|
|
126
147
|
role: "assistant",
|
|
127
|
-
content:
|
|
128
|
-
sources:
|
|
129
|
-
},
|
|
148
|
+
content: u,
|
|
149
|
+
sources: N
|
|
150
|
+
}, c;
|
|
130
151
|
});
|
|
131
152
|
},
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
153
|
+
onDone: ({ humanTakeover: n }) => {
|
|
154
|
+
n && i((o) => [
|
|
155
|
+
...o.slice(0, s),
|
|
156
|
+
...o.slice(s + 1)
|
|
157
|
+
]);
|
|
158
|
+
},
|
|
159
|
+
onError: (n) => {
|
|
160
|
+
oe(n, { userMessage: t, threadId: m, baseUrl: h?.baseUrl }), i((o) => {
|
|
161
|
+
const c = [...o];
|
|
162
|
+
return c[s] = {
|
|
136
163
|
role: "assistant",
|
|
137
|
-
content: `Error: ${
|
|
138
|
-
},
|
|
164
|
+
content: `Error: ${n}`
|
|
165
|
+
}, c;
|
|
139
166
|
});
|
|
140
167
|
}
|
|
141
168
|
}
|
|
142
|
-
}),
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
169
|
+
}), B(!1);
|
|
170
|
+
}, Q = () => {
|
|
171
|
+
ce(a), U(void 0), i([
|
|
172
|
+
{ role: "assistant", content: v?.welcomeMessage || R }
|
|
173
|
+
]), b("");
|
|
174
|
+
}, z = (t) => {
|
|
175
|
+
t.key === "Enter" && !t.shiftKey && (t.preventDefault(), I());
|
|
176
|
+
}, G = async (t) => {
|
|
177
|
+
b(t), setTimeout(() => I(), 0);
|
|
178
|
+
}, _ = k ? /* @__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
179
|
/* @__PURE__ */ e("div", { className: "knest-spinner-ring" }),
|
|
150
180
|
/* @__PURE__ */ e("p", { className: "knest-loading-text", children: "Loading chat..." })
|
|
151
|
-
] }) }) }) :
|
|
152
|
-
/* @__PURE__ */
|
|
153
|
-
|
|
181
|
+
] }) }) }) : A === "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: ne }) }) }) }) : /* @__PURE__ */ r("div", { className: "knest-chat-card", children: [
|
|
182
|
+
/* @__PURE__ */ r("div", { className: "knest-messages-container", children: [
|
|
183
|
+
l.map((t, s) => /* @__PURE__ */ r("div", { children: [
|
|
154
184
|
/* @__PURE__ */ e(
|
|
155
|
-
|
|
185
|
+
le,
|
|
156
186
|
{
|
|
157
187
|
message: t,
|
|
158
|
-
isLoading: !t.content &&
|
|
159
|
-
avatarUrl:
|
|
160
|
-
brandColor:
|
|
188
|
+
isLoading: !t.content && p && t.role === "assistant",
|
|
189
|
+
avatarUrl: j,
|
|
190
|
+
brandColor: W
|
|
161
191
|
}
|
|
162
192
|
),
|
|
163
|
-
|
|
164
|
-
] },
|
|
165
|
-
|
|
193
|
+
s < l.length - 1 && /* @__PURE__ */ e("div", { className: "knest-separator" })
|
|
194
|
+
] }, s)),
|
|
195
|
+
l.length === 1 && !k && /* @__PURE__ */ r("div", { className: "knest-examples", children: [
|
|
166
196
|
/* @__PURE__ */ e("h3", { children: "Example Questions" }),
|
|
167
|
-
|
|
197
|
+
F.map((t, s) => /* @__PURE__ */ e(
|
|
168
198
|
"button",
|
|
169
199
|
{
|
|
170
|
-
onClick: () =>
|
|
200
|
+
onClick: () => G(t),
|
|
171
201
|
className: "knest-example-btn",
|
|
172
|
-
style:
|
|
202
|
+
style: s === 0 ? { borderColor: W, borderWidth: "2px" } : {},
|
|
173
203
|
children: t
|
|
174
204
|
},
|
|
175
|
-
|
|
205
|
+
s
|
|
176
206
|
))
|
|
177
207
|
] }),
|
|
178
|
-
/* @__PURE__ */ e("div", { ref:
|
|
208
|
+
/* @__PURE__ */ e("div", { ref: S })
|
|
179
209
|
] }),
|
|
180
|
-
/* @__PURE__ */
|
|
181
|
-
/* @__PURE__ */
|
|
210
|
+
/* @__PURE__ */ r("div", { className: "knest-input-section", children: [
|
|
211
|
+
/* @__PURE__ */ r("div", { className: "knest-input-wrapper", children: [
|
|
182
212
|
/* @__PURE__ */ e(
|
|
183
213
|
"input",
|
|
184
214
|
{
|
|
185
215
|
type: "text",
|
|
186
|
-
value:
|
|
187
|
-
onChange: (t) =>
|
|
188
|
-
onKeyPress:
|
|
216
|
+
value: g,
|
|
217
|
+
onChange: (t) => b(t.target.value),
|
|
218
|
+
onKeyPress: z,
|
|
189
219
|
placeholder: "Ask me anything...",
|
|
190
|
-
disabled:
|
|
220
|
+
disabled: p || !f,
|
|
191
221
|
className: "knest-input-field"
|
|
192
222
|
}
|
|
193
223
|
),
|
|
194
224
|
/* @__PURE__ */ e(
|
|
195
225
|
"button",
|
|
196
226
|
{
|
|
197
|
-
onClick:
|
|
198
|
-
disabled:
|
|
227
|
+
onClick: I,
|
|
228
|
+
disabled: p || !g.trim() || !f,
|
|
199
229
|
className: "knest-send-btn",
|
|
200
230
|
"aria-label": "Send message",
|
|
201
231
|
children: /* @__PURE__ */ e("svg", { className: "knest-send-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e(
|
|
@@ -210,7 +240,8 @@ function Z({ publishableApiKey: r, baseUrl: d }) {
|
|
|
210
240
|
}
|
|
211
241
|
)
|
|
212
242
|
] }),
|
|
213
|
-
/* @__PURE__ */ e("div", { className: "knest-
|
|
243
|
+
l.length > 1 && !p && /* @__PURE__ */ e("div", { className: "knest-reset-row", children: /* @__PURE__ */ e("button", { onClick: Q, className: "knest-reset-btn", children: "Clear chat" }) }),
|
|
244
|
+
/* @__PURE__ */ e("div", { className: "knest-footer", children: /* @__PURE__ */ r(
|
|
214
245
|
"a",
|
|
215
246
|
{
|
|
216
247
|
href: "https://useknest.com",
|
|
@@ -219,7 +250,7 @@ function Z({ publishableApiKey: r, baseUrl: d }) {
|
|
|
219
250
|
className: "knest-powered-by",
|
|
220
251
|
children: [
|
|
221
252
|
/* @__PURE__ */ e("span", { children: "Powered by" }),
|
|
222
|
-
/* @__PURE__ */
|
|
253
|
+
/* @__PURE__ */ r(
|
|
223
254
|
"svg",
|
|
224
255
|
{
|
|
225
256
|
width: "14",
|
|
@@ -286,8 +317,86 @@ function Z({ publishableApiKey: r, baseUrl: d }) {
|
|
|
286
317
|
) })
|
|
287
318
|
] })
|
|
288
319
|
] });
|
|
320
|
+
if (M === "inline")
|
|
321
|
+
return _;
|
|
322
|
+
const H = k ? "#9ca3af" : W;
|
|
323
|
+
return /* @__PURE__ */ r("div", { className: "knest-bubble-container", children: [
|
|
324
|
+
w && /* @__PURE__ */ e("div", { className: "knest-bubble-panel", children: _ }),
|
|
325
|
+
/* @__PURE__ */ e(
|
|
326
|
+
"button",
|
|
327
|
+
{
|
|
328
|
+
className: ["knest-bubble-button", k && "knest-bubble-loading"].filter(Boolean).join(" "),
|
|
329
|
+
onClick: () => P(!w),
|
|
330
|
+
"aria-label": k ? "Loading chat" : w ? "Close chat" : "Open chat",
|
|
331
|
+
style: { backgroundColor: H },
|
|
332
|
+
children: k ? /* @__PURE__ */ r(
|
|
333
|
+
"svg",
|
|
334
|
+
{
|
|
335
|
+
width: "24",
|
|
336
|
+
height: "24",
|
|
337
|
+
viewBox: "0 0 24 24",
|
|
338
|
+
fill: "none",
|
|
339
|
+
className: "knest-bubble-spinner",
|
|
340
|
+
children: [
|
|
341
|
+
/* @__PURE__ */ e(
|
|
342
|
+
"circle",
|
|
343
|
+
{
|
|
344
|
+
cx: "12",
|
|
345
|
+
cy: "12",
|
|
346
|
+
r: "9",
|
|
347
|
+
stroke: "currentColor",
|
|
348
|
+
strokeOpacity: "0.25",
|
|
349
|
+
strokeWidth: "3",
|
|
350
|
+
fill: "none"
|
|
351
|
+
}
|
|
352
|
+
),
|
|
353
|
+
/* @__PURE__ */ e(
|
|
354
|
+
"path",
|
|
355
|
+
{
|
|
356
|
+
d: "M12 3a9 9 0 0 1 9 9",
|
|
357
|
+
stroke: "currentColor",
|
|
358
|
+
strokeWidth: "3",
|
|
359
|
+
strokeLinecap: "round",
|
|
360
|
+
fill: "none"
|
|
361
|
+
}
|
|
362
|
+
)
|
|
363
|
+
]
|
|
364
|
+
}
|
|
365
|
+
) : w ? /* @__PURE__ */ e(
|
|
366
|
+
"svg",
|
|
367
|
+
{
|
|
368
|
+
width: "24",
|
|
369
|
+
height: "24",
|
|
370
|
+
viewBox: "0 0 24 24",
|
|
371
|
+
fill: "none",
|
|
372
|
+
stroke: "currentColor",
|
|
373
|
+
strokeWidth: "2",
|
|
374
|
+
children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
|
|
375
|
+
}
|
|
376
|
+
) : /* @__PURE__ */ e(
|
|
377
|
+
"svg",
|
|
378
|
+
{
|
|
379
|
+
width: "24",
|
|
380
|
+
height: "24",
|
|
381
|
+
viewBox: "0 0 24 24",
|
|
382
|
+
fill: "none",
|
|
383
|
+
stroke: "currentColor",
|
|
384
|
+
strokeWidth: "2",
|
|
385
|
+
children: /* @__PURE__ */ e(
|
|
386
|
+
"path",
|
|
387
|
+
{
|
|
388
|
+
strokeLinecap: "round",
|
|
389
|
+
strokeLinejoin: "round",
|
|
390
|
+
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"
|
|
391
|
+
}
|
|
392
|
+
)
|
|
393
|
+
}
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
)
|
|
397
|
+
] });
|
|
289
398
|
}
|
|
290
399
|
export {
|
|
291
|
-
|
|
292
|
-
|
|
400
|
+
le as ChatMessage,
|
|
401
|
+
ue as ChatWidget
|
|
293
402
|
};
|
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.11",
|
|
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.11"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/react": "^18.3.3",
|