@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.
@@ -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 {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sampleapp.ai/sdk",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "type": "module",
5
5
  "description": "TypeScript SDK for your components",
6
6
  "main": "./dist/index.umd.js",