@sampleapp.ai/sdk 1.0.17 → 1.0.19
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/components/ChatButton.js +59 -0
- package/dist/components/ModalSearchAndChat.js +207 -0
- package/dist/index.js +65 -0
- package/dist/index.umd.d.ts +15 -0
- package/dist/types.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
export const ChatButton = ({ settings, onClick }) => {
|
|
3
|
+
var _a;
|
|
4
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
5
|
+
const handleClick = () => {
|
|
6
|
+
// Emit custom event for SDK usage
|
|
7
|
+
const event = new CustomEvent("chatButtonClick", {
|
|
8
|
+
detail: { settings },
|
|
9
|
+
});
|
|
10
|
+
document.dispatchEvent(event);
|
|
11
|
+
// Call onClick prop if provided (for direct React usage)
|
|
12
|
+
onClick === null || onClick === void 0 ? void 0 : onClick();
|
|
13
|
+
};
|
|
14
|
+
return (React.createElement("button", { style: {
|
|
15
|
+
// Layout & Position
|
|
16
|
+
position: "fixed",
|
|
17
|
+
bottom: "20px",
|
|
18
|
+
right: "20px",
|
|
19
|
+
zIndex: 1000,
|
|
20
|
+
// Colors
|
|
21
|
+
backgroundColor: settings.baseSettings.primaryBrandColor,
|
|
22
|
+
color: "white",
|
|
23
|
+
// Typography
|
|
24
|
+
fontSize: "14px",
|
|
25
|
+
fontWeight: "bold",
|
|
26
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
27
|
+
// Spacing
|
|
28
|
+
padding: "15px 20px",
|
|
29
|
+
// Border & Shape
|
|
30
|
+
border: "none",
|
|
31
|
+
borderRadius: "50px",
|
|
32
|
+
// Visual Effects
|
|
33
|
+
boxShadow: isHovered
|
|
34
|
+
? "0 6px 20px rgba(0,0,0,0.2)"
|
|
35
|
+
: "0 4px 12px rgba(0,0,0,0.15)",
|
|
36
|
+
cursor: "pointer",
|
|
37
|
+
// Animations
|
|
38
|
+
transition: "all 0.2s ease-in-out",
|
|
39
|
+
transform: isHovered ? "scale(1.05)" : "scale(1)",
|
|
40
|
+
// Layout for icon + text
|
|
41
|
+
display: "flex",
|
|
42
|
+
alignItems: "center",
|
|
43
|
+
gap: "8px",
|
|
44
|
+
// Interaction
|
|
45
|
+
outline: "none",
|
|
46
|
+
userSelect: "none",
|
|
47
|
+
}, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onClick: handleClick, onFocus: () => setIsHovered(true), onBlur: () => setIsHovered(false) },
|
|
48
|
+
((_a = settings.aiChatSettings) === null || _a === void 0 ? void 0 : _a.aiAssistantAvatar) && (React.createElement("img", { src: settings.aiChatSettings.aiAssistantAvatar, alt: "AI Assistant", style: {
|
|
49
|
+
width: "20px",
|
|
50
|
+
height: "20px",
|
|
51
|
+
borderRadius: "50%",
|
|
52
|
+
objectFit: "cover",
|
|
53
|
+
flexShrink: 0,
|
|
54
|
+
}, onError: (e) => {
|
|
55
|
+
// Hide image if it fails to load
|
|
56
|
+
e.currentTarget.style.display = "none";
|
|
57
|
+
} })),
|
|
58
|
+
"Ask AI"));
|
|
59
|
+
};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
export const ModalSearchAndChat = ({ settings, onClose, }) => {
|
|
3
|
+
var _a, _b;
|
|
4
|
+
const [isVisible, setIsVisible] = useState(true);
|
|
5
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
6
|
+
const handleClose = () => {
|
|
7
|
+
setIsVisible(false);
|
|
8
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
9
|
+
};
|
|
10
|
+
const handleExampleQuestionClick = (question) => {
|
|
11
|
+
setSearchQuery(question);
|
|
12
|
+
};
|
|
13
|
+
// Handle escape key
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const handleEscape = (e) => {
|
|
16
|
+
if (e.key === "Escape") {
|
|
17
|
+
handleClose();
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
if (isVisible) {
|
|
21
|
+
document.addEventListener("keydown", handleEscape);
|
|
22
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
23
|
+
}
|
|
24
|
+
}, [isVisible]);
|
|
25
|
+
// Prevent body scroll when modal is open
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (isVisible) {
|
|
28
|
+
document.body.style.overflow = "hidden";
|
|
29
|
+
return () => {
|
|
30
|
+
document.body.style.overflow = "";
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}, [isVisible]);
|
|
34
|
+
if (!isVisible)
|
|
35
|
+
return null;
|
|
36
|
+
return (React.createElement(React.Fragment, null,
|
|
37
|
+
React.createElement("div", { style: {
|
|
38
|
+
position: "fixed",
|
|
39
|
+
top: 0,
|
|
40
|
+
left: 0,
|
|
41
|
+
right: 0,
|
|
42
|
+
bottom: 0,
|
|
43
|
+
backgroundColor: "rgba(0, 0, 0, 0.6)",
|
|
44
|
+
backdropFilter: "blur(4px)",
|
|
45
|
+
zIndex: 999,
|
|
46
|
+
animation: "fadeIn 0.2s ease-out",
|
|
47
|
+
}, onClick: handleClose }),
|
|
48
|
+
React.createElement("div", { style: {
|
|
49
|
+
position: "fixed",
|
|
50
|
+
top: "50%",
|
|
51
|
+
left: "50%",
|
|
52
|
+
transform: "translate(-50%, -50%)",
|
|
53
|
+
backgroundColor: "white",
|
|
54
|
+
borderRadius: "16px",
|
|
55
|
+
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
|
|
56
|
+
zIndex: 1000,
|
|
57
|
+
width: "90%",
|
|
58
|
+
maxWidth: "500px",
|
|
59
|
+
maxHeight: "80vh",
|
|
60
|
+
overflow: "hidden",
|
|
61
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
62
|
+
animation: "slideIn 0.3s ease-out",
|
|
63
|
+
}, onClick: (e) => e.stopPropagation() },
|
|
64
|
+
React.createElement("div", { style: {
|
|
65
|
+
padding: "24px 24px 20px 24px",
|
|
66
|
+
borderBottom: "1px solid #f1f5f9",
|
|
67
|
+
display: "flex",
|
|
68
|
+
justifyContent: "space-between",
|
|
69
|
+
alignItems: "center",
|
|
70
|
+
background: `linear-gradient(135deg, ${settings.baseSettings.primaryBrandColor}10, ${settings.baseSettings.primaryBrandColor}05)`,
|
|
71
|
+
} },
|
|
72
|
+
React.createElement("div", { style: { display: "flex", alignItems: "center", gap: "12px" } },
|
|
73
|
+
((_a = settings.aiChatSettings) === null || _a === void 0 ? void 0 : _a.aiAssistantAvatar) && (React.createElement("img", { src: settings.aiChatSettings.aiAssistantAvatar, alt: "AI Assistant", style: {
|
|
74
|
+
width: "32px",
|
|
75
|
+
height: "32px",
|
|
76
|
+
borderRadius: "50%",
|
|
77
|
+
objectFit: "cover",
|
|
78
|
+
}, onError: (e) => {
|
|
79
|
+
e.currentTarget.style.display = "none";
|
|
80
|
+
} })),
|
|
81
|
+
React.createElement("h3", { style: {
|
|
82
|
+
margin: 0,
|
|
83
|
+
color: settings.baseSettings.primaryBrandColor,
|
|
84
|
+
fontSize: "18px",
|
|
85
|
+
fontWeight: "600",
|
|
86
|
+
letterSpacing: "-0.025em",
|
|
87
|
+
} }, settings.baseSettings.organizationDisplayName)),
|
|
88
|
+
React.createElement("button", { onClick: handleClose, style: {
|
|
89
|
+
background: "none",
|
|
90
|
+
border: "none",
|
|
91
|
+
fontSize: "20px",
|
|
92
|
+
cursor: "pointer",
|
|
93
|
+
color: "#64748b",
|
|
94
|
+
padding: "8px",
|
|
95
|
+
borderRadius: "6px",
|
|
96
|
+
display: "flex",
|
|
97
|
+
alignItems: "center",
|
|
98
|
+
justifyContent: "center",
|
|
99
|
+
transition: "all 0.15s ease",
|
|
100
|
+
}, onMouseEnter: (e) => {
|
|
101
|
+
e.currentTarget.style.backgroundColor = "#f1f5f9";
|
|
102
|
+
e.currentTarget.style.color = "#334155";
|
|
103
|
+
}, onMouseLeave: (e) => {
|
|
104
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
105
|
+
e.currentTarget.style.color = "#64748b";
|
|
106
|
+
} }, "\u00D7")),
|
|
107
|
+
React.createElement("div", { style: {
|
|
108
|
+
padding: "24px",
|
|
109
|
+
maxHeight: "60vh",
|
|
110
|
+
overflowY: "auto",
|
|
111
|
+
} },
|
|
112
|
+
React.createElement("div", { style: { position: "relative", marginBottom: "24px" } },
|
|
113
|
+
React.createElement("input", { type: "text", placeholder: "Ask a question...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), style: {
|
|
114
|
+
width: "100%",
|
|
115
|
+
padding: "14px 16px",
|
|
116
|
+
border: "2px solid #e2e8f0",
|
|
117
|
+
borderRadius: "12px",
|
|
118
|
+
fontSize: "16px",
|
|
119
|
+
fontFamily: "inherit",
|
|
120
|
+
outline: "none",
|
|
121
|
+
boxSizing: "border-box",
|
|
122
|
+
transition: "border-color 0.15s ease",
|
|
123
|
+
backgroundColor: "#fafafa",
|
|
124
|
+
}, onFocus: (e) => {
|
|
125
|
+
e.currentTarget.style.borderColor =
|
|
126
|
+
settings.baseSettings.primaryBrandColor;
|
|
127
|
+
e.currentTarget.style.backgroundColor = "white";
|
|
128
|
+
}, onBlur: (e) => {
|
|
129
|
+
e.currentTarget.style.borderColor = "#e2e8f0";
|
|
130
|
+
e.currentTarget.style.backgroundColor = "#fafafa";
|
|
131
|
+
}, autoFocus: true }),
|
|
132
|
+
React.createElement("button", { style: {
|
|
133
|
+
position: "absolute",
|
|
134
|
+
right: "8px",
|
|
135
|
+
top: "50%",
|
|
136
|
+
transform: "translateY(-50%)",
|
|
137
|
+
backgroundColor: settings.baseSettings.primaryBrandColor,
|
|
138
|
+
color: "white",
|
|
139
|
+
border: "none",
|
|
140
|
+
borderRadius: "8px",
|
|
141
|
+
padding: "8px 12px",
|
|
142
|
+
cursor: "pointer",
|
|
143
|
+
fontSize: "14px",
|
|
144
|
+
fontWeight: "500",
|
|
145
|
+
transition: "opacity 0.15s ease",
|
|
146
|
+
}, onMouseEnter: (e) => {
|
|
147
|
+
e.currentTarget.style.opacity = "0.9";
|
|
148
|
+
}, onMouseLeave: (e) => {
|
|
149
|
+
e.currentTarget.style.opacity = "1";
|
|
150
|
+
}, onClick: () => {
|
|
151
|
+
console.log("Search for:", searchQuery);
|
|
152
|
+
// Handle search logic here
|
|
153
|
+
} }, "Search")),
|
|
154
|
+
((_b = settings.aiChatSettings) === null || _b === void 0 ? void 0 : _b.exampleQuestions) &&
|
|
155
|
+
settings.aiChatSettings.exampleQuestions.length > 0 && (React.createElement("div", null,
|
|
156
|
+
React.createElement("p", { style: {
|
|
157
|
+
margin: "0 0 16px 0",
|
|
158
|
+
fontWeight: "600",
|
|
159
|
+
fontSize: "14px",
|
|
160
|
+
color: "#475569",
|
|
161
|
+
letterSpacing: "-0.025em",
|
|
162
|
+
} }, "Popular questions:"),
|
|
163
|
+
React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: "8px" } }, settings.aiChatSettings.exampleQuestions.map((question, index) => (React.createElement("button", { key: index, onClick: () => handleExampleQuestionClick(question), style: {
|
|
164
|
+
display: "block",
|
|
165
|
+
width: "100%",
|
|
166
|
+
padding: "12px 16px",
|
|
167
|
+
border: "1px solid #e2e8f0",
|
|
168
|
+
backgroundColor: "white",
|
|
169
|
+
borderRadius: "10px",
|
|
170
|
+
cursor: "pointer",
|
|
171
|
+
textAlign: "left",
|
|
172
|
+
fontSize: "14px",
|
|
173
|
+
fontFamily: "inherit",
|
|
174
|
+
color: "#334155",
|
|
175
|
+
transition: "all 0.15s ease",
|
|
176
|
+
lineHeight: "1.4",
|
|
177
|
+
}, onMouseEnter: (e) => {
|
|
178
|
+
e.currentTarget.style.backgroundColor = "#f8fafc";
|
|
179
|
+
e.currentTarget.style.borderColor =
|
|
180
|
+
settings.baseSettings.primaryBrandColor;
|
|
181
|
+
e.currentTarget.style.transform = "translateY(-1px)";
|
|
182
|
+
e.currentTarget.style.boxShadow =
|
|
183
|
+
"0 4px 12px rgba(0,0,0,0.1)";
|
|
184
|
+
}, onMouseLeave: (e) => {
|
|
185
|
+
e.currentTarget.style.backgroundColor = "white";
|
|
186
|
+
e.currentTarget.style.borderColor = "#e2e8f0";
|
|
187
|
+
e.currentTarget.style.transform = "translateY(0)";
|
|
188
|
+
e.currentTarget.style.boxShadow = "none";
|
|
189
|
+
} }, question)))))))),
|
|
190
|
+
React.createElement("style", null, `
|
|
191
|
+
@keyframes fadeIn {
|
|
192
|
+
from { opacity: 0; }
|
|
193
|
+
to { opacity: 1; }
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@keyframes slideIn {
|
|
197
|
+
from {
|
|
198
|
+
opacity: 0;
|
|
199
|
+
transform: translate(-50%, -45%) scale(0.95);
|
|
200
|
+
}
|
|
201
|
+
to {
|
|
202
|
+
opacity: 1;
|
|
203
|
+
transform: translate(-50%, -50%) scale(1);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
`)));
|
|
207
|
+
};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import { ChatButton } from "./components/ChatButton";
|
|
4
|
+
import { ModalSearchAndChat } from "./components/ModalSearchAndChat";
|
|
5
|
+
// Export React components for direct JSX usage
|
|
6
|
+
export { ChatButton, ModalSearchAndChat };
|
|
7
|
+
// SDK class for loadScript programmatic usage
|
|
8
|
+
class SampleAppSDK {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.ModalSearchAndChat = (settings, container) => {
|
|
11
|
+
const targetContainer = container || document.body;
|
|
12
|
+
const modalContainer = document.createElement("div");
|
|
13
|
+
modalContainer.id = "sampleapp-modal-" + Date.now();
|
|
14
|
+
targetContainer.appendChild(modalContainer);
|
|
15
|
+
const root = ReactDOM.createRoot(modalContainer);
|
|
16
|
+
const component = React.createElement(ModalSearchAndChat, {
|
|
17
|
+
settings,
|
|
18
|
+
onClose: () => {
|
|
19
|
+
root.unmount();
|
|
20
|
+
modalContainer.remove();
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
root.render(component);
|
|
24
|
+
return {
|
|
25
|
+
unmount: () => {
|
|
26
|
+
root.unmount();
|
|
27
|
+
modalContainer.remove();
|
|
28
|
+
},
|
|
29
|
+
show: () => {
|
|
30
|
+
modalContainer.style.display = "block";
|
|
31
|
+
},
|
|
32
|
+
hide: () => {
|
|
33
|
+
modalContainer.style.display = "none";
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
this.ChatButton = (settings, container) => {
|
|
38
|
+
const targetContainer = container || this.createButtonContainer();
|
|
39
|
+
const root = ReactDOM.createRoot(targetContainer);
|
|
40
|
+
const component = React.createElement(ChatButton, { settings });
|
|
41
|
+
root.render(component);
|
|
42
|
+
return {
|
|
43
|
+
unmount: () => {
|
|
44
|
+
root.unmount();
|
|
45
|
+
targetContainer.remove();
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
createButtonContainer() {
|
|
51
|
+
const container = document.createElement("div");
|
|
52
|
+
container.id = "sampleapp-button-" + Date.now();
|
|
53
|
+
document.body.appendChild(container);
|
|
54
|
+
return container;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Create singleton instance
|
|
58
|
+
const sdk = new SampleAppSDK();
|
|
59
|
+
// Default export for both usage patterns
|
|
60
|
+
export default sdk;
|
|
61
|
+
// For UMD builds, also attach individual methods to the default export
|
|
62
|
+
// This ensures they're accessible as SampleApp.ChatButton, etc.
|
|
63
|
+
if (typeof window !== "undefined") {
|
|
64
|
+
window.SampleApp = sdk;
|
|
65
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SDKSettings } from "./types";
|
|
2
|
+
declare function initModalSearchAndChat(settings: SDKSettings, container?: HTMLElement): {
|
|
3
|
+
unmount: () => void;
|
|
4
|
+
show: () => void;
|
|
5
|
+
hide: () => void;
|
|
6
|
+
};
|
|
7
|
+
declare function initChatButton(settings: SDKSettings, container?: HTMLElement): {
|
|
8
|
+
unmount: () => void;
|
|
9
|
+
};
|
|
10
|
+
export { initModalSearchAndChat as ModalSearchAndChat, initChatButton as ChatButton, };
|
|
11
|
+
declare const _default: {
|
|
12
|
+
ModalSearchAndChat: typeof initModalSearchAndChat;
|
|
13
|
+
ChatButton: typeof initChatButton;
|
|
14
|
+
};
|
|
15
|
+
export default _default;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|