@yak-io/react 0.5.0 → 0.7.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/dist/YakProvider.d.ts +10 -4
- package/dist/YakProvider.d.ts.map +1 -1
- package/dist/YakProvider.js +55 -385
- package/dist/YakWidget.d.ts +2 -1
- package/dist/YakWidget.d.ts.map +1 -1
- package/dist/YakWidget.js +4 -220
- package/dist/context.d.ts +2 -9
- package/dist/context.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/YakProvider.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type React from "react";
|
|
2
|
-
import { type
|
|
2
|
+
import { type TriggerButtonConfig, type ChatConfigProvider, type ToolCallHandler, type GraphQLSchemaHandler, type RESTSchemaHandler, type Theme } from "@yak-io/javascript";
|
|
3
3
|
/**
|
|
4
4
|
* Props for YakProvider
|
|
5
5
|
*/
|
|
@@ -31,12 +31,18 @@ export type YakProviderProps = {
|
|
|
31
31
|
onRedirect?: (path: string) => void;
|
|
32
32
|
/** Disable the restart session button in the header */
|
|
33
33
|
disableRestartButton?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Trigger button configuration. Pass `false` to disable the built-in trigger button
|
|
36
|
+
* (useful when using `<YakWidget />` separately). Defaults to `false`.
|
|
37
|
+
*/
|
|
38
|
+
trigger?: boolean | TriggerButtonConfig;
|
|
34
39
|
/** Children components */
|
|
35
40
|
children: React.ReactNode;
|
|
36
41
|
};
|
|
37
42
|
/**
|
|
38
|
-
* YakProvider sets up the context, message handling, and renders the chat
|
|
39
|
-
*
|
|
43
|
+
* YakProvider sets up the context, message handling, and renders the chat widget.
|
|
44
|
+
* All DOM rendering (panel, iframe, styles, optional trigger) is delegated to YakEmbed
|
|
45
|
+
* from the JavaScript SDK.
|
|
40
46
|
*/
|
|
41
|
-
export declare function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall, onRESTSchemaCall, theme, onRedirect, disableRestartButton, children, }: YakProviderProps): React.JSX.Element;
|
|
47
|
+
export declare function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall, onRESTSchemaCall, theme, onRedirect, disableRestartButton, trigger, children, }: YakProviderProps): React.JSX.Element;
|
|
42
48
|
//# sourceMappingURL=YakProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YakProvider.d.ts","sourceRoot":"","sources":["../src/YakProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAEL,KAAK,
|
|
1
|
+
{"version":3,"file":"YakProvider.d.ts","sourceRoot":"","sources":["../src/YakProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EAEpB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,KAAK,EACX,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;OAEG;IACH,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAC3C;;OAEG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC,mCAAmC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IACxC,0BAA0B;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,SAAS,EACT,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,EACL,UAAU,EACV,oBAAoB,EACpB,OAAe,EACf,QAAQ,GACT,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAoJtC"}
|
package/dist/YakProvider.js
CHANGED
|
@@ -1,214 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback, useMemo, useEffect, useRef } from "react";
|
|
4
4
|
import { YakContext } from "./context.js";
|
|
5
|
-
import {
|
|
5
|
+
import { YakEmbed, } from "@yak-io/javascript";
|
|
6
6
|
import { logger } from "./internal/logger.js";
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* YakProvider sets up the context, message handling, and renders the chat widget.
|
|
9
|
+
* All DOM rendering (panel, iframe, styles, optional trigger) is delegated to YakEmbed
|
|
10
|
+
* from the JavaScript SDK.
|
|
9
11
|
*/
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
/* ===========================================
|
|
13
|
-
YAK IFRAME STYLES (rendered by provider)
|
|
14
|
-
=========================================== */
|
|
15
|
-
|
|
16
|
-
/* ===========================================
|
|
17
|
-
ROOT LAYER (full viewport, pointer-events pass-through)
|
|
18
|
-
=========================================== */
|
|
19
|
-
.yak-panel-root {
|
|
20
|
-
position: fixed;
|
|
21
|
-
top: 0;
|
|
22
|
-
left: 0;
|
|
23
|
-
right: 0;
|
|
24
|
-
bottom: 0;
|
|
25
|
-
width: 100vw;
|
|
26
|
-
height: 100vh;
|
|
27
|
-
pointer-events: none;
|
|
28
|
-
z-index: 9998;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/* ===========================================
|
|
32
|
-
CONTAINER
|
|
33
|
-
=========================================== */
|
|
34
|
-
.yak-panel-container {
|
|
35
|
-
position: absolute;
|
|
36
|
-
width: 500px;
|
|
37
|
-
height: 600px;
|
|
38
|
-
max-width: calc(100vw - 40px);
|
|
39
|
-
max-height: calc(100vh - 120px);
|
|
40
|
-
border-radius: 15px;
|
|
41
|
-
overflow: hidden;
|
|
42
|
-
background-color: transparent;
|
|
43
|
-
pointer-events: auto;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/* Container position variants (chatbox mode) - all 9 positions */
|
|
47
|
-
.yak-panel-container[data-position="top-left"]:not(.yak-panel-drawer) {
|
|
48
|
-
top: 16px;
|
|
49
|
-
left: 16px;
|
|
50
|
-
}
|
|
51
|
-
.yak-panel-container[data-position="top-center"]:not(.yak-panel-drawer) {
|
|
52
|
-
top: 16px;
|
|
53
|
-
left: 50%;
|
|
54
|
-
transform: translateX(-50%);
|
|
55
|
-
}
|
|
56
|
-
.yak-panel-container[data-position="top-right"]:not(.yak-panel-drawer) {
|
|
57
|
-
top: 16px;
|
|
58
|
-
right: 16px;
|
|
59
|
-
}
|
|
60
|
-
.yak-panel-container[data-position="left-center"]:not(.yak-panel-drawer) {
|
|
61
|
-
top: 50%;
|
|
62
|
-
left: 16px;
|
|
63
|
-
transform: translateY(-50%);
|
|
64
|
-
}
|
|
65
|
-
.yak-panel-container[data-position="right-center"]:not(.yak-panel-drawer) {
|
|
66
|
-
top: 50%;
|
|
67
|
-
right: 16px;
|
|
68
|
-
transform: translateY(-50%);
|
|
69
|
-
}
|
|
70
|
-
.yak-panel-container[data-position="bottom-left"]:not(.yak-panel-drawer) {
|
|
71
|
-
bottom: 16px;
|
|
72
|
-
left: 16px;
|
|
73
|
-
}
|
|
74
|
-
.yak-panel-container[data-position="bottom-center"]:not(.yak-panel-drawer) {
|
|
75
|
-
bottom: 16px;
|
|
76
|
-
left: 50%;
|
|
77
|
-
transform: translateX(-50%);
|
|
78
|
-
}
|
|
79
|
-
.yak-panel-container[data-position="bottom-right"]:not(.yak-panel-drawer) {
|
|
80
|
-
bottom: 16px;
|
|
81
|
-
right: 16px;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/* Container visibility (chatbox mode) */
|
|
85
|
-
.yak-panel-container:not(.yak-panel-drawer) {
|
|
86
|
-
display: none;
|
|
87
|
-
}
|
|
88
|
-
.yak-panel-container:not(.yak-panel-drawer)[data-open="true"] {
|
|
89
|
-
display: block;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/* ===========================================
|
|
93
|
-
EXPANDED MODE (full viewport for data table)
|
|
94
|
-
=========================================== */
|
|
95
|
-
.yak-panel-container[data-expanded="true"] {
|
|
96
|
-
width: calc(100vw - 32px) !important;
|
|
97
|
-
height: calc(100vh - 32px) !important;
|
|
98
|
-
max-width: none !important;
|
|
99
|
-
max-height: none !important;
|
|
100
|
-
top: 16px !important;
|
|
101
|
-
left: 16px !important;
|
|
102
|
-
right: 16px !important;
|
|
103
|
-
bottom: 16px !important;
|
|
104
|
-
border-radius: 15px !important;
|
|
105
|
-
border: 1px solid rgba(0, 0, 0, 0.1) !important;
|
|
106
|
-
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15) !important;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
@media (prefers-color-scheme: dark) {
|
|
110
|
-
.yak-panel-container[data-expanded="true"]:not(.yak-panel-light) {
|
|
111
|
-
border-color: rgba(255, 255, 255, 0.1) !important;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.yak-panel-container.yak-panel-dark[data-expanded="true"] {
|
|
116
|
-
border-color: rgba(255, 255, 255, 0.1) !important;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
.yak-panel-container.yak-panel-light[data-expanded="true"] {
|
|
120
|
-
border-color: rgba(0, 0, 0, 0.1) !important;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/* ===========================================
|
|
124
|
-
DRAWER MODE
|
|
125
|
-
=========================================== */
|
|
126
|
-
.yak-panel-container.yak-panel-drawer {
|
|
127
|
-
height: calc(100% - 32px);
|
|
128
|
-
max-width: 100vw;
|
|
129
|
-
max-height: none;
|
|
130
|
-
border-radius: 15px;
|
|
131
|
-
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* Drawer position - only left-center and right-center are relevant for drawer mode */
|
|
135
|
-
.yak-panel-container.yak-panel-drawer[data-position="left-center"],
|
|
136
|
-
.yak-panel-container.yak-panel-drawer[data-position="top-left"],
|
|
137
|
-
.yak-panel-container.yak-panel-drawer[data-position="bottom-left"] {
|
|
138
|
-
top: 16px;
|
|
139
|
-
left: 16px;
|
|
140
|
-
bottom: 16px;
|
|
141
|
-
transform: translateX(calc(-100% - 16px));
|
|
142
|
-
}
|
|
143
|
-
.yak-panel-container.yak-panel-drawer[data-position="right-center"],
|
|
144
|
-
.yak-panel-container.yak-panel-drawer[data-position="top-right"],
|
|
145
|
-
.yak-panel-container.yak-panel-drawer[data-position="bottom-right"] {
|
|
146
|
-
top: 16px;
|
|
147
|
-
right: 16px;
|
|
148
|
-
bottom: 16px;
|
|
149
|
-
transform: translateX(calc(100% + 16px));
|
|
150
|
-
}
|
|
151
|
-
/* Center positions default to right side for drawer */
|
|
152
|
-
.yak-panel-container.yak-panel-drawer[data-position="top-center"],
|
|
153
|
-
.yak-panel-container.yak-panel-drawer[data-position="bottom-center"] {
|
|
154
|
-
top: 16px;
|
|
155
|
-
right: 16px;
|
|
156
|
-
bottom: 16px;
|
|
157
|
-
transform: translateX(calc(100% + 16px));
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/* Drawer open state */
|
|
161
|
-
.yak-panel-container.yak-panel-drawer[data-open="true"] {
|
|
162
|
-
transform: translateX(0);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/* ===========================================
|
|
166
|
-
IFRAME
|
|
167
|
-
=========================================== */
|
|
168
|
-
.yak-panel-iframe {
|
|
169
|
-
position: absolute;
|
|
170
|
-
inset: 0;
|
|
171
|
-
width: 100%;
|
|
172
|
-
height: 100%;
|
|
173
|
-
border: none;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/* ===========================================
|
|
177
|
-
MOBILE RESPONSIVE
|
|
178
|
-
=========================================== */
|
|
179
|
-
@media (max-width: 640px) {
|
|
180
|
-
.yak-panel-container:not(.yak-panel-drawer) {
|
|
181
|
-
width: 100% !important;
|
|
182
|
-
height: 100% !important;
|
|
183
|
-
height: 100dvh !important;
|
|
184
|
-
max-width: none !important;
|
|
185
|
-
max-height: none !important;
|
|
186
|
-
top: 0 !important;
|
|
187
|
-
left: 0 !important;
|
|
188
|
-
right: 0 !important;
|
|
189
|
-
bottom: 0 !important;
|
|
190
|
-
border-radius: 0 !important;
|
|
191
|
-
}
|
|
192
|
-
.yak-panel-container.yak-panel-drawer {
|
|
193
|
-
width: 100% !important;
|
|
194
|
-
max-width: none !important;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
`;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* YakProvider sets up the context, message handling, and renders the chat iframe.
|
|
201
|
-
* The iframe is rendered as a fixed-position panel that can be opened/closed.
|
|
202
|
-
*/
|
|
203
|
-
export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall, onRESTSchemaCall, theme, onRedirect, disableRestartButton, children, }) {
|
|
204
|
-
const [iframeWindow, setIframeWindow] = useState(null);
|
|
205
|
-
const [chatConfig, setChatConfig] = useState(null);
|
|
206
|
-
const [isWidgetOpen, setIsWidgetOpen] = useState(false);
|
|
207
|
-
const [pendingPrompt, setPendingPrompt] = useState(null);
|
|
12
|
+
export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall, onRESTSchemaCall, theme, onRedirect, disableRestartButton, trigger = false, children, }) {
|
|
13
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
208
14
|
const [isIframeReady, setIsIframeReady] = useState(false);
|
|
209
|
-
const [hasBeenOpened, setHasBeenOpened] = useState(false);
|
|
210
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
211
|
-
const iframeRef = useRef(null);
|
|
212
15
|
// Store event subscribers for tool call events
|
|
213
16
|
const toolEventSubscribersRef = useRef(new Set());
|
|
214
17
|
// Handler that notifies all subscribers when a tool call completes
|
|
@@ -227,37 +30,54 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
227
30
|
}
|
|
228
31
|
}
|
|
229
32
|
}, []);
|
|
230
|
-
//
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
33
|
+
// Resolve redirect handler
|
|
34
|
+
const resolvedRedirect = useMemo(() => {
|
|
35
|
+
if (onRedirect)
|
|
36
|
+
return onRedirect;
|
|
37
|
+
if (typeof window === "undefined")
|
|
38
|
+
return undefined;
|
|
39
|
+
return (path) => {
|
|
40
|
+
window.location.assign(path);
|
|
41
|
+
};
|
|
42
|
+
}, [onRedirect]);
|
|
43
|
+
// Initialize YakEmbed — created once, never recreated
|
|
44
|
+
const embedRef = useRef(null);
|
|
45
|
+
if (!embedRef.current) {
|
|
46
|
+
embedRef.current = new YakEmbed({
|
|
234
47
|
appId,
|
|
48
|
+
theme,
|
|
49
|
+
trigger,
|
|
235
50
|
onToolCall,
|
|
236
51
|
onGraphQLSchemaCall,
|
|
237
52
|
onRESTSchemaCall,
|
|
238
|
-
|
|
239
|
-
onRedirect,
|
|
53
|
+
onRedirect: resolvedRedirect,
|
|
240
54
|
options: { disableRestartButton },
|
|
241
|
-
onClose: () => setIsWidgetOpen(false),
|
|
242
|
-
onReady: () => setIsIframeReady(true),
|
|
243
55
|
onToolCallComplete: handleToolCallComplete,
|
|
244
56
|
});
|
|
245
57
|
}
|
|
246
|
-
const
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
58
|
+
const embed = embedRef.current;
|
|
59
|
+
// Mount/unmount embed and subscribe to state changes
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
embed.mount();
|
|
62
|
+
const unsubscribe = embed.onStateChange((state) => {
|
|
63
|
+
setIsOpen(state.isOpen);
|
|
64
|
+
setIsIframeReady(state.isReady);
|
|
65
|
+
});
|
|
66
|
+
return () => {
|
|
67
|
+
unsubscribe();
|
|
68
|
+
embed.destroy();
|
|
69
|
+
};
|
|
70
|
+
}, [embed]);
|
|
71
|
+
// Update embed config when props change (exclude onReady/onClose which are managed by YakEmbed)
|
|
251
72
|
useEffect(() => {
|
|
252
|
-
|
|
73
|
+
embed.getClient().updateConfig({
|
|
253
74
|
appId,
|
|
254
75
|
onToolCall,
|
|
255
76
|
onGraphQLSchemaCall,
|
|
256
77
|
onRESTSchemaCall,
|
|
257
78
|
theme,
|
|
258
|
-
onRedirect,
|
|
79
|
+
onRedirect: resolvedRedirect,
|
|
259
80
|
options: { disableRestartButton },
|
|
260
|
-
chatConfig: chatConfig ?? undefined,
|
|
261
81
|
onToolCallComplete: handleToolCallComplete,
|
|
262
82
|
});
|
|
263
83
|
}, [
|
|
@@ -266,89 +86,14 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
266
86
|
onGraphQLSchemaCall,
|
|
267
87
|
onRESTSchemaCall,
|
|
268
88
|
theme,
|
|
269
|
-
|
|
89
|
+
resolvedRedirect,
|
|
270
90
|
disableRestartButton,
|
|
271
|
-
|
|
272
|
-
client,
|
|
91
|
+
embed,
|
|
273
92
|
handleToolCallComplete,
|
|
274
93
|
]);
|
|
275
|
-
//
|
|
276
|
-
useEffect(() => {
|
|
277
|
-
client.setIframeWindow(iframeWindow);
|
|
278
|
-
}, [iframeWindow, client]);
|
|
279
|
-
// Update client widget open state
|
|
280
|
-
useEffect(() => {
|
|
281
|
-
client.setWidgetOpen(isWidgetOpen);
|
|
282
|
-
}, [isWidgetOpen, client]);
|
|
283
|
-
// Mount/Unmount client listeners
|
|
94
|
+
// Fetch chat config when widget is opened
|
|
284
95
|
useEffect(() => {
|
|
285
|
-
|
|
286
|
-
return () => client.unmount();
|
|
287
|
-
}, [client]);
|
|
288
|
-
// Track when widget is first opened
|
|
289
|
-
useEffect(() => {
|
|
290
|
-
if (isWidgetOpen && !hasBeenOpened) {
|
|
291
|
-
setHasBeenOpened(true);
|
|
292
|
-
}
|
|
293
|
-
}, [isWidgetOpen, hasBeenOpened]);
|
|
294
|
-
// Register iframe window when loaded
|
|
295
|
-
useEffect(() => {
|
|
296
|
-
if (!hasBeenOpened)
|
|
297
|
-
return;
|
|
298
|
-
const iframe = iframeRef.current;
|
|
299
|
-
if (!iframe)
|
|
300
|
-
return;
|
|
301
|
-
const handleLoad = () => {
|
|
302
|
-
if (iframe.contentWindow) {
|
|
303
|
-
logger.debug("Iframe window registered");
|
|
304
|
-
setIframeWindow(iframe.contentWindow);
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
iframe.addEventListener("load", handleLoad);
|
|
308
|
-
return () => {
|
|
309
|
-
iframe.removeEventListener("load", handleLoad);
|
|
310
|
-
logger.debug("Iframe window unregistered");
|
|
311
|
-
setIframeWindow(null);
|
|
312
|
-
};
|
|
313
|
-
}, [hasBeenOpened]);
|
|
314
|
-
// Listen for expansion messages from iframe
|
|
315
|
-
useEffect(() => {
|
|
316
|
-
const handleMessage = (event) => {
|
|
317
|
-
const iframe = iframeRef.current;
|
|
318
|
-
if (!iframe)
|
|
319
|
-
return;
|
|
320
|
-
// Check for expansion control messages
|
|
321
|
-
if (event.data?.type === "YAK_SET_EXPANDED") {
|
|
322
|
-
setIsExpanded(Boolean(event.data.expanded));
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
window.addEventListener("message", handleMessage);
|
|
326
|
-
return () => window.removeEventListener("message", handleMessage);
|
|
327
|
-
}, []);
|
|
328
|
-
// Detect mobile/fullscreen and notify iframe
|
|
329
|
-
useEffect(() => {
|
|
330
|
-
if (!isIframeReady)
|
|
331
|
-
return;
|
|
332
|
-
const mobileQuery = window.matchMedia("(max-width: 640px)");
|
|
333
|
-
const notifyFullscreen = (isFullscreen) => {
|
|
334
|
-
const msg = {
|
|
335
|
-
type: "yak:viewport",
|
|
336
|
-
payload: { fullscreen: isFullscreen },
|
|
337
|
-
};
|
|
338
|
-
iframeWindow?.postMessage(msg, iframeOrigin);
|
|
339
|
-
};
|
|
340
|
-
// Send initial state
|
|
341
|
-
notifyFullscreen(mobileQuery.matches);
|
|
342
|
-
// Listen for changes
|
|
343
|
-
const handleChange = (e) => {
|
|
344
|
-
notifyFullscreen(e.matches);
|
|
345
|
-
};
|
|
346
|
-
mobileQuery.addEventListener("change", handleChange);
|
|
347
|
-
return () => mobileQuery.removeEventListener("change", handleChange);
|
|
348
|
-
}, [isIframeReady, iframeWindow, iframeOrigin]);
|
|
349
|
-
// Get chat config when widget is opened
|
|
350
|
-
useEffect(() => {
|
|
351
|
-
if (typeof window === "undefined" || !isWidgetOpen || !getConfig)
|
|
96
|
+
if (typeof window === "undefined" || !isOpen || !getConfig)
|
|
352
97
|
return;
|
|
353
98
|
logger.debug("Getting chat config");
|
|
354
99
|
let cancelled = false;
|
|
@@ -357,7 +102,7 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
357
102
|
const config = await getConfig();
|
|
358
103
|
if (!cancelled) {
|
|
359
104
|
logger.debug(`Chat config loaded with ${config.tools?.tools.length ?? 0} tools and ${config.routes?.routes.length ?? 0} routes`);
|
|
360
|
-
|
|
105
|
+
embed.getClient().updateConfig({ chatConfig: config });
|
|
361
106
|
}
|
|
362
107
|
}
|
|
363
108
|
catch (err) {
|
|
@@ -367,105 +112,30 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
367
112
|
return () => {
|
|
368
113
|
cancelled = true;
|
|
369
114
|
};
|
|
370
|
-
}, [getConfig,
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
return undefined;
|
|
376
|
-
return (path) => {
|
|
377
|
-
window.location.assign(path);
|
|
378
|
-
};
|
|
379
|
-
}, [onRedirect]);
|
|
380
|
-
const config = useMemo(() => ({
|
|
381
|
-
appId,
|
|
382
|
-
theme,
|
|
383
|
-
chatConfig,
|
|
384
|
-
onRedirect: resolvedRedirect,
|
|
385
|
-
}), [appId, theme, chatConfig, resolvedRedirect]);
|
|
386
|
-
// Methods to get URLs from the client
|
|
387
|
-
const getIframeOrigin = useCallback(() => client.getIframeOrigin(), [client]);
|
|
388
|
-
const getEmbedUrl = useCallback(() => client.getEmbedUrl(), [client]);
|
|
389
|
-
const sendMessage = useCallback((message) => {
|
|
390
|
-
iframeWindow?.postMessage(message, iframeOrigin);
|
|
391
|
-
}, [iframeWindow, iframeOrigin]);
|
|
392
|
-
const open = useCallback(() => {
|
|
393
|
-
setIsWidgetOpen(true);
|
|
394
|
-
}, []);
|
|
395
|
-
const close = useCallback(() => {
|
|
396
|
-
setIsWidgetOpen(false);
|
|
397
|
-
}, []);
|
|
398
|
-
const openWithPrompt = useCallback((prompt) => {
|
|
399
|
-
logger.debug("Opening widget with prompt:", prompt);
|
|
400
|
-
setPendingPrompt(prompt);
|
|
401
|
-
setIsWidgetOpen(true);
|
|
402
|
-
}, []);
|
|
403
|
-
// Effect to send pending prompt when iframe becomes ready
|
|
404
|
-
useEffect(() => {
|
|
405
|
-
if (isIframeReady && pendingPrompt && iframeWindow) {
|
|
406
|
-
logger.debug("Sending pending prompt to iframe:", pendingPrompt);
|
|
407
|
-
const promptMessage = {
|
|
408
|
-
type: "yak:prompt",
|
|
409
|
-
payload: { prompt: pendingPrompt },
|
|
410
|
-
};
|
|
411
|
-
iframeWindow.postMessage(promptMessage, iframeOrigin);
|
|
412
|
-
setPendingPrompt(null);
|
|
413
|
-
}
|
|
414
|
-
}, [isIframeReady, pendingPrompt, iframeWindow, iframeOrigin]);
|
|
415
|
-
// Effect to send focus message when widget is opened
|
|
416
|
-
useEffect(() => {
|
|
417
|
-
if (isWidgetOpen && iframeWindow && isIframeReady) {
|
|
418
|
-
logger.debug("Sending focus request to iframe");
|
|
419
|
-
const focusMessage = {
|
|
420
|
-
type: "yak:focus",
|
|
421
|
-
};
|
|
422
|
-
iframeWindow.postMessage(focusMessage, iframeOrigin);
|
|
423
|
-
}
|
|
424
|
-
}, [isWidgetOpen, iframeWindow, isIframeReady, iframeOrigin]);
|
|
115
|
+
}, [getConfig, isOpen, embed]);
|
|
116
|
+
// Open/close methods
|
|
117
|
+
const open = useCallback(() => embed.open(), [embed]);
|
|
118
|
+
const close = useCallback(() => embed.close(), [embed]);
|
|
119
|
+
const openWithPrompt = useCallback((prompt) => embed.openWithPrompt(prompt), [embed]);
|
|
425
120
|
// Subscribe to tool call completion events
|
|
426
121
|
const subscribeToToolEvents = useCallback((handler) => {
|
|
427
122
|
toolEventSubscribersRef.current.add(handler);
|
|
428
123
|
logger.debug("Tool event subscriber added, total:", toolEventSubscribersRef.current.size);
|
|
429
|
-
// Return unsubscribe function
|
|
430
124
|
return () => {
|
|
431
125
|
toolEventSubscribersRef.current.delete(handler);
|
|
432
126
|
logger.debug("Tool event subscriber removed, total:", toolEventSubscribersRef.current.size);
|
|
433
127
|
};
|
|
434
128
|
}, []);
|
|
129
|
+
// Expose iframe origin for YakWidget
|
|
130
|
+
const getIframeOrigin = useCallback(() => embed.getClient().getIframeOrigin(), [embed]);
|
|
435
131
|
const contextValue = useMemo(() => ({
|
|
436
|
-
|
|
437
|
-
getIframeOrigin,
|
|
438
|
-
getEmbedUrl,
|
|
439
|
-
sendMessage,
|
|
440
|
-
isOpen: isWidgetOpen,
|
|
132
|
+
isOpen,
|
|
441
133
|
isIframeReady,
|
|
442
134
|
open,
|
|
443
135
|
close,
|
|
444
136
|
openWithPrompt,
|
|
445
|
-
setIsIframeReady,
|
|
446
137
|
subscribeToToolEvents,
|
|
447
|
-
}), [
|
|
448
|
-
config,
|
|
449
138
|
getIframeOrigin,
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
isWidgetOpen,
|
|
453
|
-
isIframeReady,
|
|
454
|
-
open,
|
|
455
|
-
close,
|
|
456
|
-
openWithPrompt,
|
|
457
|
-
subscribeToToolEvents,
|
|
458
|
-
]);
|
|
459
|
-
// Determine position styles based on theme
|
|
460
|
-
const position = theme?.position ?? "bottom-right";
|
|
461
|
-
const colorMode = theme?.colorMode;
|
|
462
|
-
const displayMode = theme?.displayMode ?? "chatbox";
|
|
463
|
-
const isDrawer = displayMode === "drawer";
|
|
464
|
-
// Determine color mode class for the container
|
|
465
|
-
const colorModeClass = colorMode === "light" ? "yak-panel-light" : colorMode === "dark" ? "yak-panel-dark" : "";
|
|
466
|
-
// Build container class names
|
|
467
|
-
const containerClasses = ["yak-panel-container", isDrawer && "yak-panel-drawer", colorModeClass]
|
|
468
|
-
.filter(Boolean)
|
|
469
|
-
.join(" ");
|
|
470
|
-
return (_jsxs(YakContext.Provider, { value: contextValue, children: [children, _jsx("style", { children: getIframeStyles() }), hasBeenOpened && (_jsx("div", { className: "yak-panel-root", "data-expanded": isExpanded, children: _jsx("div", { className: containerClasses, "data-position": position, "data-open": isWidgetOpen && isIframeReady, "data-expanded": isExpanded, children: _jsx("iframe", { ref: iframeRef, src: iframeSrc, className: "yak-panel-iframe", title: "yak-chat-host" }) }) }))] }));
|
|
139
|
+
}), [isOpen, isIframeReady, open, close, openWithPrompt, subscribeToToolEvents, getIframeOrigin]);
|
|
140
|
+
return _jsx(YakContext.Provider, { value: contextValue, children: children });
|
|
471
141
|
}
|
package/dist/YakWidget.d.ts
CHANGED
|
@@ -25,7 +25,8 @@ export type YakWidgetProps = {
|
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
27
27
|
* YakWidget renders a fixed-position launcher button.
|
|
28
|
-
*
|
|
28
|
+
* Trigger CSS is injected by YakEmbed (via YakProvider) — this component
|
|
29
|
+
* only provides the React button element using those shared class names.
|
|
29
30
|
*/
|
|
30
31
|
export declare function YakWidget({ triggerLabel, position, colorMode, lightButton, darkButton, }?: YakWidgetProps): React.JSX.Element;
|
|
31
32
|
//# sourceMappingURL=YakWidget.d.ts.map
|
package/dist/YakWidget.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YakWidget.d.ts","sourceRoot":"","sources":["../src/YakWidget.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"YakWidget.d.ts","sourceRoot":"","sources":["../src/YakWidget.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACxC,0CAA0C;IAC1C,WAAW,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,yCAAyC;IACzC,UAAU,CAAC,EAAE;QACX,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAwCF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACxB,YAA4B,EAC5B,QAAyB,EACzB,SAAS,EACT,WAAW,EACX,UAAU,GACX,GAAE,cAAmB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAoCzC"}
|
package/dist/YakWidget.js
CHANGED
|
@@ -1,224 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useContext } from "react";
|
|
4
4
|
import { YakContext, useYak } from "./context.js";
|
|
5
|
-
/**
|
|
6
|
-
* All button styles consolidated in one place
|
|
7
|
-
*/
|
|
8
|
-
function getButtonStyles() {
|
|
9
|
-
return `
|
|
10
|
-
/* ===========================================
|
|
11
|
-
YAK WIDGET BUTTON STYLES
|
|
12
|
-
=========================================== */
|
|
13
|
-
|
|
14
|
-
/* Trigger Button Base */
|
|
15
|
-
.yak-widget-trigger {
|
|
16
|
-
position: fixed;
|
|
17
|
-
z-index: 9997;
|
|
18
|
-
display: flex;
|
|
19
|
-
align-items: center;
|
|
20
|
-
gap: 12px;
|
|
21
|
-
border: none;
|
|
22
|
-
border-radius: 30px;
|
|
23
|
-
padding: 0 5px 0 20px;
|
|
24
|
-
height: 45px;
|
|
25
|
-
min-width: 45px;
|
|
26
|
-
width: auto;
|
|
27
|
-
cursor: pointer;
|
|
28
|
-
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
|
29
|
-
overflow: hidden;
|
|
30
|
-
background-color: #000;
|
|
31
|
-
color: #fff;
|
|
32
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/* Trigger position variants - all 9 positions */
|
|
36
|
-
.yak-widget-trigger[data-position="top-left"] {
|
|
37
|
-
top: 28px;
|
|
38
|
-
left: 28px;
|
|
39
|
-
flex-direction: row-reverse;
|
|
40
|
-
}
|
|
41
|
-
.yak-widget-trigger[data-position="top-center"] {
|
|
42
|
-
top: 28px;
|
|
43
|
-
left: 50%;
|
|
44
|
-
transform: translateX(-50%);
|
|
45
|
-
flex-direction: row;
|
|
46
|
-
}
|
|
47
|
-
.yak-widget-trigger[data-position="top-right"] {
|
|
48
|
-
top: 28px;
|
|
49
|
-
right: 28px;
|
|
50
|
-
flex-direction: row;
|
|
51
|
-
}
|
|
52
|
-
.yak-widget-trigger[data-position="left-center"] {
|
|
53
|
-
top: 50%;
|
|
54
|
-
left: 28px;
|
|
55
|
-
transform: translateY(-50%);
|
|
56
|
-
flex-direction: row-reverse;
|
|
57
|
-
}
|
|
58
|
-
.yak-widget-trigger[data-position="right-center"] {
|
|
59
|
-
top: 50%;
|
|
60
|
-
right: 28px;
|
|
61
|
-
transform: translateY(-50%);
|
|
62
|
-
flex-direction: row;
|
|
63
|
-
}
|
|
64
|
-
.yak-widget-trigger[data-position="bottom-left"] {
|
|
65
|
-
bottom: 28px;
|
|
66
|
-
left: 28px;
|
|
67
|
-
flex-direction: row-reverse;
|
|
68
|
-
}
|
|
69
|
-
.yak-widget-trigger[data-position="bottom-center"] {
|
|
70
|
-
bottom: 28px;
|
|
71
|
-
left: 50%;
|
|
72
|
-
transform: translateX(-50%);
|
|
73
|
-
flex-direction: row;
|
|
74
|
-
}
|
|
75
|
-
.yak-widget-trigger[data-position="bottom-right"] {
|
|
76
|
-
bottom: 28px;
|
|
77
|
-
right: 28px;
|
|
78
|
-
flex-direction: row;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.yak-widget-trigger-label {
|
|
82
|
-
font-size: 14px;
|
|
83
|
-
font-weight: 600;
|
|
84
|
-
white-space: nowrap;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
.yak-widget-icon-bg {
|
|
88
|
-
display: flex;
|
|
89
|
-
align-items: center;
|
|
90
|
-
justify-content: center;
|
|
91
|
-
width: 36px;
|
|
92
|
-
height: 36px;
|
|
93
|
-
border-radius: 50%;
|
|
94
|
-
background-color: rgba(255, 255, 255, 0.1);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.yak-widget-icon {
|
|
98
|
-
width: 20px;
|
|
99
|
-
height: 20px;
|
|
100
|
-
color: currentColor;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/* Invert logo for dark mode */
|
|
104
|
-
@media (prefers-color-scheme: dark) {
|
|
105
|
-
.yak-widget-trigger:not(.yak-widget-light) .yak-widget-icon {
|
|
106
|
-
filter: invert(1);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
.yak-widget-trigger.yak-widget-dark .yak-widget-icon {
|
|
110
|
-
filter: invert(1);
|
|
111
|
-
}
|
|
112
|
-
.yak-widget-trigger.yak-widget-light .yak-widget-icon {
|
|
113
|
-
filter: none;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/* Spinner animation for loading state */
|
|
117
|
-
.yak-widget-spinner {
|
|
118
|
-
width: 20px;
|
|
119
|
-
height: 20px;
|
|
120
|
-
border: 2px solid currentColor;
|
|
121
|
-
border-top-color: transparent;
|
|
122
|
-
border-radius: 50%;
|
|
123
|
-
animation: yak-widget-spin 0.8s linear infinite;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
@keyframes yak-widget-spin {
|
|
127
|
-
to {
|
|
128
|
-
transform: rotate(360deg);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/* Loading/disabled state for trigger button */
|
|
133
|
-
.yak-widget-trigger:disabled {
|
|
134
|
-
cursor: wait;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/* Custom button styles for forced light mode */
|
|
138
|
-
.yak-widget-trigger.yak-widget-custom-light {
|
|
139
|
-
background-color: var(--yak-btn-light-bg, #fff);
|
|
140
|
-
color: var(--yak-btn-light-color, #000);
|
|
141
|
-
border: 1px solid var(--yak-btn-light-border, transparent);
|
|
142
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/* Custom button styles for forced dark mode */
|
|
146
|
-
.yak-widget-trigger.yak-widget-custom-dark {
|
|
147
|
-
background-color: var(--yak-btn-dark-bg, #000);
|
|
148
|
-
color: var(--yak-btn-dark-color, #fff);
|
|
149
|
-
border: 1px solid var(--yak-btn-dark-border, transparent);
|
|
150
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/* System mode with custom light colors */
|
|
154
|
-
@media (prefers-color-scheme: light) {
|
|
155
|
-
.yak-widget-trigger[data-has-light-custom]:not(.yak-widget-dark) {
|
|
156
|
-
background-color: var(--yak-btn-light-bg, #fff);
|
|
157
|
-
color: var(--yak-btn-light-color, #000);
|
|
158
|
-
border: 1px solid var(--yak-btn-light-border, transparent);
|
|
159
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/* System mode with custom dark colors */
|
|
164
|
-
@media (prefers-color-scheme: dark) {
|
|
165
|
-
.yak-widget-trigger[data-has-dark-custom]:not(.yak-widget-light) {
|
|
166
|
-
background-color: var(--yak-btn-dark-bg, #000);
|
|
167
|
-
color: var(--yak-btn-dark-color, #fff);
|
|
168
|
-
border: 1px solid var(--yak-btn-dark-border, transparent);
|
|
169
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/* Light mode via system preference (default styling without custom) */
|
|
174
|
-
@media (prefers-color-scheme: light) {
|
|
175
|
-
.yak-widget-trigger:not(.yak-widget-dark):not([data-has-light-custom]) {
|
|
176
|
-
background-color: #fff;
|
|
177
|
-
color: #000;
|
|
178
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
179
|
-
border: 1px solid #e5e5e5;
|
|
180
|
-
}
|
|
181
|
-
.yak-widget-trigger:not(.yak-widget-dark):not([data-has-light-custom]) .yak-widget-icon-bg {
|
|
182
|
-
background-color: rgba(0, 0, 0, 0.05);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/* Dark mode via system preference (default styling without custom) */
|
|
187
|
-
@media (prefers-color-scheme: dark) {
|
|
188
|
-
.yak-widget-trigger:not(.yak-widget-light):not([data-has-dark-custom]) {
|
|
189
|
-
background-color: #000;
|
|
190
|
-
color: #fff;
|
|
191
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
192
|
-
border: none;
|
|
193
|
-
}
|
|
194
|
-
.yak-widget-trigger:not(.yak-widget-light):not([data-has-dark-custom]) .yak-widget-icon-bg {
|
|
195
|
-
background-color: rgba(255, 255, 255, 0.1);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/* Forced light mode (default styling) */
|
|
200
|
-
.yak-widget-trigger.yak-widget-light:not(.yak-widget-custom-light) {
|
|
201
|
-
background-color: #fff;
|
|
202
|
-
color: #000;
|
|
203
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
204
|
-
border: 1px solid #e5e5e5;
|
|
205
|
-
}
|
|
206
|
-
.yak-widget-trigger.yak-widget-light:not(.yak-widget-custom-light) .yak-widget-icon-bg {
|
|
207
|
-
background-color: rgba(0, 0, 0, 0.05);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/* Forced dark mode (default styling) */
|
|
211
|
-
.yak-widget-trigger.yak-widget-dark:not(.yak-widget-custom-dark) {
|
|
212
|
-
background-color: #000;
|
|
213
|
-
color: #fff;
|
|
214
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
215
|
-
border: none;
|
|
216
|
-
}
|
|
217
|
-
.yak-widget-trigger.yak-widget-dark:not(.yak-widget-custom-dark) .yak-widget-icon-bg {
|
|
218
|
-
background-color: rgba(255, 255, 255, 0.1);
|
|
219
|
-
}
|
|
220
|
-
`;
|
|
221
|
-
}
|
|
222
5
|
/**
|
|
223
6
|
* Compute button CSS variables from custom button color props
|
|
224
7
|
*/
|
|
@@ -254,7 +37,8 @@ function buildButtonClasses(colorMode, hasLightCustom, hasDarkCustom) {
|
|
|
254
37
|
}
|
|
255
38
|
/**
|
|
256
39
|
* YakWidget renders a fixed-position launcher button.
|
|
257
|
-
*
|
|
40
|
+
* Trigger CSS is injected by YakEmbed (via YakProvider) — this component
|
|
41
|
+
* only provides the React button element using those shared class names.
|
|
258
42
|
*/
|
|
259
43
|
export function YakWidget({ triggerLabel = "Ask with AI", position = "bottom-right", colorMode, lightButton, darkButton, } = {}) {
|
|
260
44
|
const { open, isOpen, isIframeReady } = useYak();
|
|
@@ -265,5 +49,5 @@ export function YakWidget({ triggerLabel = "Ask with AI", position = "bottom-rig
|
|
|
265
49
|
const hasDarkCustom = darkButton?.background || darkButton?.color || darkButton?.border;
|
|
266
50
|
const buttonStyle = buildButtonStyle(lightButton, darkButton);
|
|
267
51
|
const buttonClasses = buildButtonClasses(colorMode, hasLightCustom, hasDarkCustom);
|
|
268
|
-
return (_jsxs(
|
|
52
|
+
return (_jsxs("button", { type: "button", onClick: open, className: buttonClasses, style: Object.keys(buttonStyle).length > 0 ? buttonStyle : undefined, "data-position": position, "data-has-light-custom": hasLightCustom || undefined, "data-has-dark-custom": hasDarkCustom || undefined, "aria-label": isLoading ? "Loading chat" : "Open chat", disabled: isLoading, children: [_jsx("span", { className: "yak-widget-trigger-label", children: triggerLabel }), _jsx("div", { className: "yak-widget-icon-bg", children: isLoading ? (_jsx("div", { className: "yak-widget-spinner", "aria-hidden": "true" })) : (_jsx("img", { src: logoUrl, alt: "", width: 20, height: 20, className: "yak-widget-icon" })) })] }));
|
|
269
53
|
}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Theme, ChatConfig, ToolCallEvent
|
|
1
|
+
import type { Theme, ChatConfig, ToolCallEvent } from "@yak-io/javascript";
|
|
2
2
|
/**
|
|
3
3
|
* Configuration for the yak provider
|
|
4
4
|
*/
|
|
@@ -31,19 +31,12 @@ export type YakContextValue = {
|
|
|
31
31
|
subscribeToToolEvents: (handler: ToolCallEventHandler) => () => void;
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
|
-
* Internal context with additional methods for
|
|
34
|
+
* Internal context with additional methods for widget internals.
|
|
35
35
|
* Not exposed to consumers - only used by provider internals.
|
|
36
36
|
*/
|
|
37
37
|
export type YakInternalContextValue = YakContextValue & {
|
|
38
|
-
config: YakConfig;
|
|
39
38
|
/** Get the iframe origin URL (determined by environment) */
|
|
40
39
|
getIframeOrigin: () => string;
|
|
41
|
-
/** Get the full iframe embed URL */
|
|
42
|
-
getEmbedUrl: () => string;
|
|
43
|
-
/** Send a message to the iframe */
|
|
44
|
-
sendMessage: (message: IframeMessageFromHost) => void;
|
|
45
|
-
/** Set iframe ready state (called by provider) */
|
|
46
|
-
setIsIframeReady: (ready: boolean) => void;
|
|
47
40
|
};
|
|
48
41
|
export declare const YakContext: import("react").Context<YakInternalContextValue | null>;
|
|
49
42
|
/**
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,gDAAgD;IAChD,MAAM,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,aAAa,EAAE,OAAO,CAAC;IACvB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,yDAAyD;IACzD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,+CAA+C;IAC/C,qBAAqB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,IAAI,CAAC;CACtE,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG;IACtD,4DAA4D;IAC5D,eAAe,EAAE,MAAM,MAAM,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,UAAU,yDAAsD,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,IAAI,eAAe,CAcxC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,uBAAuB,CAMxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAkBnE"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export { YakProvider } from "./YakProvider.js";
|
|
|
4
4
|
export type { YakProviderProps } from "./YakProvider.js";
|
|
5
5
|
export { YakWidget } from "./YakWidget.js";
|
|
6
6
|
export type { YakWidgetProps } from "./YakWidget.js";
|
|
7
|
-
export type { GraphQLSchemaHandler, RESTSchemaHandler, GraphQLRequest, RESTRequest, ToolCallHandler, ToolCallEvent, SchemaSource, GraphQLSchemaSource, OpenAPISchemaSource, Theme, ThemeColors,
|
|
7
|
+
export type { GraphQLSchemaHandler, RESTSchemaHandler, GraphQLRequest, RESTRequest, ToolCallHandler, ToolCallEvent, SchemaSource, GraphQLSchemaSource, OpenAPISchemaSource, Theme, ThemeColors, TriggerButtonConfig, WidgetPosition, } from "@yak-io/javascript";
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,eAAe,EACf,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,EACL,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,eAAe,EACf,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,EACL,WAAW,EACX,mBAAmB,EACnB,cAAc,GACf,MAAM,oBAAoB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yak-io/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "React SDK for embedding yak chatbot",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"./package.json": "./package.json"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@yak-io/javascript": "0.
|
|
44
|
+
"@yak-io/javascript": "0.6.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"react": "^18.0.0 || ^19.0.0",
|