@super_studio/ecforce-ai-agent-react 0.1.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/README.md ADDED
@@ -0,0 +1 @@
1
+ TODO
@@ -0,0 +1,32 @@
1
+ type MCP = {
2
+ name: string;
3
+ url: string;
4
+ headers?: Record<string, string>;
5
+ };
6
+ export type InitProps = {
7
+ mcps?: MCP[];
8
+ };
9
+ export type AgentFrameProps = {
10
+ agentId: string;
11
+ mcps?: MCP[];
12
+ appName?: string;
13
+ url?: string;
14
+ className?: string;
15
+ };
16
+ export type AgentElement = {
17
+ /**
18
+ * Push a new list of MCPs to the embedded agent.
19
+ */
20
+ setMcps: (mcps: MCP[]) => void;
21
+ /**
22
+ * Set the app name for the embedded agent.
23
+ */
24
+ setAppName: (appName: string) => void;
25
+ /**
26
+ * `true` once the iframe has sent the `CHATBOT_READY` handshake message.
27
+ */
28
+ isReady: boolean;
29
+ };
30
+ export declare const AgentFrame: import("react").ForwardRefExoticComponent<AgentFrameProps & import("react").RefAttributes<AgentElement>>;
31
+ export {};
32
+ //# sourceMappingURL=agent-frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-frame.d.ts","sourceRoot":"","sources":["../src/agent-frame.tsx"],"names":[],"mappings":"AAcA,KAAK,GAAG,GAAG;IACT,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;CACd,CAAC;AAiBF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB;;OAEG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAC/B;;OAEG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,UAAU,0GAmHtB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type AgentElement, type AgentFrameProps } from "./agent-frame";
2
+ export declare const ChatbotPopover: import("react").ForwardRefExoticComponent<AgentFrameProps & import("react").RefAttributes<AgentElement>>;
3
+ //# sourceMappingURL=chatbot-popover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatbot-popover.d.ts","sourceRoot":"","sources":["../src/chatbot-popover.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAGvB,eAAO,MAAM,cAAc,0GA2B1B,CAAC"}
@@ -0,0 +1,166 @@
1
+ /* Chatbot Trigger Button */
2
+ .chatbot-trigger {
3
+ position: fixed;
4
+ bottom: 1rem;
5
+ right: 1rem;
6
+ z-index: 50;
7
+ border-radius: 9999px;
8
+ border: 1px solid #f0f2f7;
9
+ background-color: #ffffff;
10
+ padding: 0.375rem;
11
+ color: #0061ff;
12
+ box-shadow:
13
+ 0 1px 3px 0 rgba(0, 0, 0, 0.1),
14
+ 0 1px 2px 0 rgba(0, 0, 0, 0.06);
15
+ transition: colors 200ms ease-in-out;
16
+ cursor: pointer;
17
+ }
18
+
19
+ .chatbot-trigger:hover {
20
+ background-color: #f0f2f7;
21
+ }
22
+
23
+ /* Popover Backdrop */
24
+ .chatbot-popover-backdrop {
25
+ position: fixed;
26
+ top: 0;
27
+ right: 0;
28
+ bottom: 0;
29
+ left: 0;
30
+ z-index: 30;
31
+ background-color: rgba(0, 0, 0, 0.5);
32
+ animation: fade-in 150ms ease-out;
33
+ }
34
+
35
+ /* Popover Content */
36
+ .chatbot-popover-content {
37
+ z-index: 50;
38
+ border-radius: 2rem;
39
+ background-color: #f7f9fa;
40
+ box-shadow:
41
+ 0 4px 6px -1px rgba(0, 0, 0, 0.1),
42
+ 0 2px 4px -1px rgba(0, 0, 0, 0.06);
43
+ outline: none;
44
+ overflow: hidden;
45
+ height: 80vh;
46
+ width: 600px;
47
+ }
48
+
49
+ /* Animation states */
50
+ .chatbot-popover-content[data-state="closed"] {
51
+ display: none;
52
+ }
53
+
54
+ .chatbot-popover-content[data-state="open"] {
55
+ animation:
56
+ zoom-in 150ms ease-out,
57
+ fade-in 150ms ease-out;
58
+ }
59
+
60
+ .chatbot-popover-content[data-state="closed"] {
61
+ animation:
62
+ zoom-out 150ms ease-in,
63
+ fade-out 150ms ease-in;
64
+ }
65
+
66
+ /* Side-specific slide animations */
67
+ .chatbot-popover-content[data-side="bottom"] {
68
+ animation:
69
+ zoom-in 150ms ease-out,
70
+ fade-in 150ms ease-out,
71
+ slide-in-from-top 150ms ease-out;
72
+ }
73
+
74
+ .chatbot-popover-content[data-side="top"] {
75
+ animation:
76
+ zoom-in 150ms ease-out,
77
+ fade-in 150ms ease-out,
78
+ slide-in-from-bottom 150ms ease-out;
79
+ }
80
+
81
+ .chatbot-popover-content[data-side="left"] {
82
+ animation:
83
+ zoom-in 150ms ease-out,
84
+ fade-in 150ms ease-out,
85
+ slide-in-from-right 150ms ease-out;
86
+ }
87
+
88
+ .chatbot-popover-content[data-side="right"] {
89
+ animation:
90
+ zoom-in 150ms ease-out,
91
+ fade-in 150ms ease-out,
92
+ slide-in-from-left 150ms ease-out;
93
+ }
94
+
95
+ /* Keyframe Animations */
96
+ @keyframes fade-in {
97
+ from {
98
+ opacity: 0;
99
+ }
100
+ to {
101
+ opacity: 1;
102
+ }
103
+ }
104
+
105
+ @keyframes fade-out {
106
+ from {
107
+ opacity: 1;
108
+ }
109
+ to {
110
+ opacity: 0;
111
+ }
112
+ }
113
+
114
+ @keyframes zoom-in {
115
+ from {
116
+ transform: scale(0.95);
117
+ }
118
+ to {
119
+ transform: scale(1);
120
+ }
121
+ }
122
+
123
+ @keyframes zoom-out {
124
+ from {
125
+ transform: scale(1);
126
+ }
127
+ to {
128
+ transform: scale(0.95);
129
+ }
130
+ }
131
+
132
+ @keyframes slide-in-from-top {
133
+ from {
134
+ transform: translateY(-0.5rem);
135
+ }
136
+ to {
137
+ transform: translateY(0);
138
+ }
139
+ }
140
+
141
+ @keyframes slide-in-from-bottom {
142
+ from {
143
+ transform: translateY(0.5rem);
144
+ }
145
+ to {
146
+ transform: translateY(0);
147
+ }
148
+ }
149
+
150
+ @keyframes slide-in-from-left {
151
+ from {
152
+ transform: translateX(-0.5rem);
153
+ }
154
+ to {
155
+ transform: translateX(0);
156
+ }
157
+ }
158
+
159
+ @keyframes slide-in-from-right {
160
+ from {
161
+ transform: translateX(0.5rem);
162
+ }
163
+ to {
164
+ transform: translateX(0);
165
+ }
166
+ }
@@ -0,0 +1,2 @@
1
+ export declare const PROD_CHATBOT_URL = "https://ecforce-ai-agent.vercel.app";
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,wCAAwC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./agent-frame";
2
+ export * from "./chatbot-popover";
3
+ export * from "./popover";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,252 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }"use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
33
+
34
+ // src/agent-frame.tsx
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+ var _react = require('react'); var React = _interopRequireWildcard(_react);
43
+
44
+ // src/constants.ts
45
+ var PROD_CHATBOT_URL = "https://ecforce-ai-agent.vercel.app";
46
+
47
+ // src/agent-frame.tsx
48
+ var _jsxruntime = require('react/jsx-runtime');
49
+ var AgentFrame = _react.forwardRef.call(void 0,
50
+ ({ agentId, mcps = [], appName, className, url }, ref) => {
51
+ var _a;
52
+ const chatbotUrl = (_a = url != null ? url : process.env.CHATBOT_URL) != null ? _a : PROD_CHATBOT_URL;
53
+ const iframeRef = _react.useRef.call(void 0, null);
54
+ const [isReady, setIsReady] = _react.useState.call(void 0, false);
55
+ const [hasInitialized, setHasInitialized] = _react.useState.call(void 0, false);
56
+ const [currentMcps, setCurrentMcps] = _react.useState.call(void 0, mcps);
57
+ const postMessage = _react.useCallback.call(void 0, (message) => {
58
+ var _a2;
59
+ if ((_a2 = iframeRef.current) == null ? void 0 : _a2.contentWindow) {
60
+ iframeRef.current.contentWindow.postMessage(message, "*");
61
+ }
62
+ }, []);
63
+ const init = _react.useCallback.call(void 0,
64
+ (props) => {
65
+ postMessage(__spreadValues({
66
+ type: "init"
67
+ }, props));
68
+ },
69
+ [postMessage]
70
+ );
71
+ const setMcps = _react.useCallback.call(void 0,
72
+ (mcps2) => {
73
+ postMessage({ type: "mcps", mcps: mcps2 });
74
+ },
75
+ [postMessage]
76
+ );
77
+ const setAppName = _react.useCallback.call(void 0,
78
+ (appName2) => {
79
+ postMessage({ type: "appName", appName: appName2 });
80
+ },
81
+ [postMessage]
82
+ );
83
+ _react.useImperativeHandle.call(void 0,
84
+ ref,
85
+ () => ({
86
+ setMcps,
87
+ setAppName,
88
+ get isReady() {
89
+ return isReady;
90
+ }
91
+ }),
92
+ [setMcps, setAppName, isReady]
93
+ );
94
+ _react.useEffect.call(void 0, () => {
95
+ const iframe = iframeRef.current;
96
+ if (!iframe) {
97
+ return;
98
+ }
99
+ const handleMessage = (event) => {
100
+ var _a2;
101
+ if (process.env.NODE_ENV === "development") {
102
+ console.log("iframe message", event.data);
103
+ }
104
+ if (((_a2 = event.data) == null ? void 0 : _a2.type) === "CHATBOT_READY") {
105
+ setIsReady(true);
106
+ }
107
+ };
108
+ const handleIframeLoad = () => {
109
+ window.addEventListener("message", handleMessage);
110
+ };
111
+ iframe.addEventListener("load", handleIframeLoad);
112
+ return () => {
113
+ window.removeEventListener("message", handleMessage);
114
+ iframe.removeEventListener("load", handleIframeLoad);
115
+ };
116
+ }, []);
117
+ _react.useEffect.call(void 0, () => {
118
+ if (isReady && !hasInitialized) {
119
+ setHasInitialized(true);
120
+ init({ mcps });
121
+ if (appName) {
122
+ setAppName(appName);
123
+ }
124
+ }
125
+ }, [isReady, init, mcps, appName, hasInitialized, setAppName]);
126
+ _react.useEffect.call(void 0, () => {
127
+ if (JSON.stringify(currentMcps) !== JSON.stringify(mcps)) {
128
+ setCurrentMcps(mcps);
129
+ setMcps(mcps);
130
+ }
131
+ }, [setMcps, mcps, currentMcps]);
132
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
133
+ "iframe",
134
+ {
135
+ ref: iframeRef,
136
+ src: `${chatbotUrl}/embed/${agentId}`,
137
+ className,
138
+ allow: "clipboard-write",
139
+ style: {
140
+ width: "100%",
141
+ height: "100%"
142
+ }
143
+ }
144
+ );
145
+ }
146
+ );
147
+ AgentFrame.displayName = "AgentFrame";
148
+
149
+ // src/chatbot-popover.tsx
150
+
151
+
152
+ // src/popover.tsx
153
+ var _reactpopover = require('@radix-ui/react-popover'); var PopoverPrimitive = _interopRequireWildcard(_reactpopover);
154
+
155
+
156
+ var Popover = PopoverPrimitive.Root;
157
+ var PopoverTrigger = React.forwardRef((_a, ref) => {
158
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
159
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
160
+ PopoverPrimitive.Trigger,
161
+ __spreadValues({
162
+ ref,
163
+ className: `chatbot-trigger ${className}`
164
+ }, props)
165
+ );
166
+ });
167
+ PopoverTrigger.displayName = PopoverPrimitive.Trigger.displayName;
168
+ var PopoverContent = React.forwardRef(
169
+ (_a, ref) => {
170
+ var _b = _a, {
171
+ className,
172
+ align = "center",
173
+ backdrop,
174
+ sideOffset = 4,
175
+ forceMount
176
+ } = _b, props = __objRest(_b, [
177
+ "className",
178
+ "align",
179
+ "backdrop",
180
+ "sideOffset",
181
+ "forceMount"
182
+ ]);
183
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverPrimitive.Portal, { forceMount, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
184
+ backdrop && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "chatbot-popover-backdrop" }),
185
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
186
+ PopoverPrimitive.Content,
187
+ __spreadValues({
188
+ ref,
189
+ align,
190
+ sideOffset,
191
+ forceMount,
192
+ className: `chatbot-popover-content ${className}`
193
+ }, props)
194
+ )
195
+ ] }) });
196
+ }
197
+ );
198
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
199
+
200
+ // src/chatbot-popover.tsx
201
+
202
+ var ChatbotPopover = _react.forwardRef.call(void 0,
203
+ (props, ref) => {
204
+ const [isOpen, setIsOpen] = _react.useState.call(void 0, false);
205
+ const [hasOpened, setHasOpened] = _react.useState.call(void 0, false);
206
+ const handleOpenChange = (open) => {
207
+ setIsOpen(open);
208
+ if (open && !hasOpened) {
209
+ setHasOpened(true);
210
+ }
211
+ };
212
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
213
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverTrigger, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EcforceAiIcon, {}) }),
214
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
215
+ PopoverContent,
216
+ {
217
+ align: "end",
218
+ backdrop: isOpen,
219
+ forceMount: hasOpened || void 0,
220
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AgentFrame, __spreadProps(__spreadValues({}, props), { ref }))
221
+ }
222
+ )
223
+ ] });
224
+ }
225
+ );
226
+ function EcforceAiIcon() {
227
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
228
+ "svg",
229
+ {
230
+ width: "24",
231
+ height: "24",
232
+ viewBox: "0 0 24 24",
233
+ xmlns: "http://www.w3.org/2000/svg",
234
+ fill: "currentColor",
235
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
236
+ "path",
237
+ {
238
+ fillRule: "evenodd",
239
+ clipRule: "evenodd",
240
+ d: "M9.2 13.704s3.7-.812 4.325-3.74c.624-2.93.76-3.364 1.112-3.364.352 0 .42.309.5.618.08.309.51 2.276.613 2.745.102.47.783 2.93 3.712 3.616 2.93.686 3.338.697 3.338 1.12 0 .459-2.361.859-3.338 1.122-.976.263-3.042 1.007-3.587 3.49-.534 2.482-.681 3.489-1.238 3.489-.556 0-.545-.584-.613-.87-.068-.286-.34-1.819-.5-2.494-.147-.675-1.044-2.837-2.962-3.363-1.93-.527-3.962-.847-3.962-1.373s2.134-.824 2.6-.995ZM2.462 4.613s1.785-.39 2.08-1.798c.296-1.409.365-1.615.535-1.615.17 0 .205.149.239.298s.25 1.088.296 1.317c.045.229.375 1.409 1.785 1.74 1.41.333 1.603.333 1.603.54 0 .217-1.137.412-1.603.538-.466.126-1.467.48-1.729 1.683C5.407 8.507 5.338 9 5.078 9c-.262 0-.262-.286-.296-.424-.035-.137-.16-.882-.24-1.202-.079-.321-.5-1.363-1.432-1.615-.932-.252-1.91-.413-1.91-.665 0-.252 1.023-.4 1.25-.48h.012Z"
241
+ }
242
+ )
243
+ }
244
+ );
245
+ }
246
+
247
+
248
+
249
+
250
+
251
+
252
+ exports.AgentFrame = AgentFrame; exports.ChatbotPopover = ChatbotPopover; exports.Popover = Popover; exports.PopoverContent = PopoverContent; exports.PopoverTrigger = PopoverTrigger;
package/dist/index.mjs ADDED
@@ -0,0 +1,252 @@
1
+ "use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
33
+
34
+ // src/agent-frame.tsx
35
+ import {
36
+ forwardRef,
37
+ useCallback,
38
+ useEffect,
39
+ useImperativeHandle,
40
+ useRef,
41
+ useState
42
+ } from "react";
43
+
44
+ // src/constants.ts
45
+ var PROD_CHATBOT_URL = "https://ecforce-ai-agent.vercel.app";
46
+
47
+ // src/agent-frame.tsx
48
+ import { jsx } from "react/jsx-runtime";
49
+ var AgentFrame = forwardRef(
50
+ ({ agentId, mcps = [], appName, className, url }, ref) => {
51
+ var _a;
52
+ const chatbotUrl = (_a = url != null ? url : process.env.CHATBOT_URL) != null ? _a : PROD_CHATBOT_URL;
53
+ const iframeRef = useRef(null);
54
+ const [isReady, setIsReady] = useState(false);
55
+ const [hasInitialized, setHasInitialized] = useState(false);
56
+ const [currentMcps, setCurrentMcps] = useState(mcps);
57
+ const postMessage = useCallback((message) => {
58
+ var _a2;
59
+ if ((_a2 = iframeRef.current) == null ? void 0 : _a2.contentWindow) {
60
+ iframeRef.current.contentWindow.postMessage(message, "*");
61
+ }
62
+ }, []);
63
+ const init = useCallback(
64
+ (props) => {
65
+ postMessage(__spreadValues({
66
+ type: "init"
67
+ }, props));
68
+ },
69
+ [postMessage]
70
+ );
71
+ const setMcps = useCallback(
72
+ (mcps2) => {
73
+ postMessage({ type: "mcps", mcps: mcps2 });
74
+ },
75
+ [postMessage]
76
+ );
77
+ const setAppName = useCallback(
78
+ (appName2) => {
79
+ postMessage({ type: "appName", appName: appName2 });
80
+ },
81
+ [postMessage]
82
+ );
83
+ useImperativeHandle(
84
+ ref,
85
+ () => ({
86
+ setMcps,
87
+ setAppName,
88
+ get isReady() {
89
+ return isReady;
90
+ }
91
+ }),
92
+ [setMcps, setAppName, isReady]
93
+ );
94
+ useEffect(() => {
95
+ const iframe = iframeRef.current;
96
+ if (!iframe) {
97
+ return;
98
+ }
99
+ const handleMessage = (event) => {
100
+ var _a2;
101
+ if (process.env.NODE_ENV === "development") {
102
+ console.log("iframe message", event.data);
103
+ }
104
+ if (((_a2 = event.data) == null ? void 0 : _a2.type) === "CHATBOT_READY") {
105
+ setIsReady(true);
106
+ }
107
+ };
108
+ const handleIframeLoad = () => {
109
+ window.addEventListener("message", handleMessage);
110
+ };
111
+ iframe.addEventListener("load", handleIframeLoad);
112
+ return () => {
113
+ window.removeEventListener("message", handleMessage);
114
+ iframe.removeEventListener("load", handleIframeLoad);
115
+ };
116
+ }, []);
117
+ useEffect(() => {
118
+ if (isReady && !hasInitialized) {
119
+ setHasInitialized(true);
120
+ init({ mcps });
121
+ if (appName) {
122
+ setAppName(appName);
123
+ }
124
+ }
125
+ }, [isReady, init, mcps, appName, hasInitialized, setAppName]);
126
+ useEffect(() => {
127
+ if (JSON.stringify(currentMcps) !== JSON.stringify(mcps)) {
128
+ setCurrentMcps(mcps);
129
+ setMcps(mcps);
130
+ }
131
+ }, [setMcps, mcps, currentMcps]);
132
+ return /* @__PURE__ */ jsx(
133
+ "iframe",
134
+ {
135
+ ref: iframeRef,
136
+ src: `${chatbotUrl}/embed/${agentId}`,
137
+ className,
138
+ allow: "clipboard-write",
139
+ style: {
140
+ width: "100%",
141
+ height: "100%"
142
+ }
143
+ }
144
+ );
145
+ }
146
+ );
147
+ AgentFrame.displayName = "AgentFrame";
148
+
149
+ // src/chatbot-popover.tsx
150
+ import { forwardRef as forwardRef3, useState as useState2 } from "react";
151
+
152
+ // src/popover.tsx
153
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
154
+ import * as React from "react";
155
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
156
+ var Popover = PopoverPrimitive.Root;
157
+ var PopoverTrigger = React.forwardRef((_a, ref) => {
158
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
159
+ return /* @__PURE__ */ jsx2(
160
+ PopoverPrimitive.Trigger,
161
+ __spreadValues({
162
+ ref,
163
+ className: `chatbot-trigger ${className}`
164
+ }, props)
165
+ );
166
+ });
167
+ PopoverTrigger.displayName = PopoverPrimitive.Trigger.displayName;
168
+ var PopoverContent = React.forwardRef(
169
+ (_a, ref) => {
170
+ var _b = _a, {
171
+ className,
172
+ align = "center",
173
+ backdrop,
174
+ sideOffset = 4,
175
+ forceMount
176
+ } = _b, props = __objRest(_b, [
177
+ "className",
178
+ "align",
179
+ "backdrop",
180
+ "sideOffset",
181
+ "forceMount"
182
+ ]);
183
+ return /* @__PURE__ */ jsx2(PopoverPrimitive.Portal, { forceMount, children: /* @__PURE__ */ jsxs("div", { children: [
184
+ backdrop && /* @__PURE__ */ jsx2("div", { className: "chatbot-popover-backdrop" }),
185
+ /* @__PURE__ */ jsx2(
186
+ PopoverPrimitive.Content,
187
+ __spreadValues({
188
+ ref,
189
+ align,
190
+ sideOffset,
191
+ forceMount,
192
+ className: `chatbot-popover-content ${className}`
193
+ }, props)
194
+ )
195
+ ] }) });
196
+ }
197
+ );
198
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
199
+
200
+ // src/chatbot-popover.tsx
201
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
202
+ var ChatbotPopover = forwardRef3(
203
+ (props, ref) => {
204
+ const [isOpen, setIsOpen] = useState2(false);
205
+ const [hasOpened, setHasOpened] = useState2(false);
206
+ const handleOpenChange = (open) => {
207
+ setIsOpen(open);
208
+ if (open && !hasOpened) {
209
+ setHasOpened(true);
210
+ }
211
+ };
212
+ return /* @__PURE__ */ jsxs2(Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
213
+ /* @__PURE__ */ jsx3(PopoverTrigger, { children: /* @__PURE__ */ jsx3(EcforceAiIcon, {}) }),
214
+ /* @__PURE__ */ jsx3(
215
+ PopoverContent,
216
+ {
217
+ align: "end",
218
+ backdrop: isOpen,
219
+ forceMount: hasOpened || void 0,
220
+ children: /* @__PURE__ */ jsx3(AgentFrame, __spreadProps(__spreadValues({}, props), { ref }))
221
+ }
222
+ )
223
+ ] });
224
+ }
225
+ );
226
+ function EcforceAiIcon() {
227
+ return /* @__PURE__ */ jsx3(
228
+ "svg",
229
+ {
230
+ width: "24",
231
+ height: "24",
232
+ viewBox: "0 0 24 24",
233
+ xmlns: "http://www.w3.org/2000/svg",
234
+ fill: "currentColor",
235
+ children: /* @__PURE__ */ jsx3(
236
+ "path",
237
+ {
238
+ fillRule: "evenodd",
239
+ clipRule: "evenodd",
240
+ d: "M9.2 13.704s3.7-.812 4.325-3.74c.624-2.93.76-3.364 1.112-3.364.352 0 .42.309.5.618.08.309.51 2.276.613 2.745.102.47.783 2.93 3.712 3.616 2.93.686 3.338.697 3.338 1.12 0 .459-2.361.859-3.338 1.122-.976.263-3.042 1.007-3.587 3.49-.534 2.482-.681 3.489-1.238 3.489-.556 0-.545-.584-.613-.87-.068-.286-.34-1.819-.5-2.494-.147-.675-1.044-2.837-2.962-3.363-1.93-.527-3.962-.847-3.962-1.373s2.134-.824 2.6-.995ZM2.462 4.613s1.785-.39 2.08-1.798c.296-1.409.365-1.615.535-1.615.17 0 .205.149.239.298s.25 1.088.296 1.317c.045.229.375 1.409 1.785 1.74 1.41.333 1.603.333 1.603.54 0 .217-1.137.412-1.603.538-.466.126-1.467.48-1.729 1.683C5.407 8.507 5.338 9 5.078 9c-.262 0-.262-.286-.296-.424-.035-.137-.16-.882-.24-1.202-.079-.321-.5-1.363-1.432-1.615-.932-.252-1.91-.413-1.91-.665 0-.252 1.023-.4 1.25-.48h.012Z"
241
+ }
242
+ )
243
+ }
244
+ );
245
+ }
246
+ export {
247
+ AgentFrame,
248
+ ChatbotPopover,
249
+ Popover,
250
+ PopoverContent,
251
+ PopoverTrigger
252
+ };
@@ -0,0 +1,9 @@
1
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
2
+ import * as React from "react";
3
+ declare const Popover: React.FC<PopoverPrimitive.PopoverProps>;
4
+ declare const PopoverTrigger: React.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
5
+ declare const PopoverContent: React.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
6
+ backdrop?: boolean;
7
+ } & React.RefAttributes<HTMLDivElement>>;
8
+ export { Popover, PopoverTrigger, PopoverContent };
9
+ //# sourceMappingURL=popover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../src/popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,QAAA,MAAM,OAAO,yCAAwB,CAAC;AAEtC,QAAA,MAAM,cAAc,sKASlB,CAAC;AAGH,QAAA,MAAM,cAAc;eAGL,OAAO;wCA4BrB,CAAC;AAGF,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@super_studio/ecforce-ai-agent-react",
3
+ "version": "0.1.0",
4
+ "main": "dist/index.js",
5
+ "module": "dist/index.mjs",
6
+ "types": "dist/index.d.ts",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist",
10
+ "src/**/*.ts",
11
+ "src/**/*.tsx",
12
+ "src/**/*.css"
13
+ ],
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.mjs",
17
+ "require": "./dist/index.js",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./chatbot.css": "./dist/chatbot.css"
21
+ },
22
+ "peerDependencies": {
23
+ "react": ">=16",
24
+ "react-dom": ">=16"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^20",
28
+ "@types/react": "^19",
29
+ "@types/react-dom": "^19",
30
+ "npm-run-all": "4.1.5",
31
+ "react": "19.1.0",
32
+ "react-dom": "19.1.0",
33
+ "tsup": "8.5.0"
34
+ },
35
+ "dependencies": {
36
+ "@radix-ui/react-popover": "1.1.14"
37
+ },
38
+ "scripts": {
39
+ "dev": "npm-run-all --parallel dev:main dev:types",
40
+ "dev:main": "tsup --watch",
41
+ "dev:types": "tsc -p tsconfig.build.json --watch",
42
+ "build": "tsup && tsc -p tsconfig.build.json"
43
+ }
44
+ }
@@ -0,0 +1,180 @@
1
+ import {
2
+ forwardRef,
3
+ useCallback,
4
+ useEffect,
5
+ useImperativeHandle,
6
+ useRef,
7
+ useState,
8
+ } from "react";
9
+ import { PROD_CHATBOT_URL } from "./constants";
10
+
11
+ type IframeMessage = {
12
+ type: "CHATBOT_READY";
13
+ };
14
+
15
+ type MCP = {
16
+ name: string;
17
+ url: string;
18
+ headers?: Record<string, string>;
19
+ };
20
+
21
+ export type InitProps = {
22
+ mcps?: MCP[];
23
+ };
24
+
25
+ type ParentMessage =
26
+ | {
27
+ type: "mcps";
28
+ mcps: MCP[];
29
+ }
30
+ | {
31
+ type: "appName";
32
+ appName: string;
33
+ }
34
+ | {
35
+ type: "init";
36
+ mcps?: MCP[];
37
+ appName?: string;
38
+ };
39
+
40
+ export type AgentFrameProps = {
41
+ agentId: string;
42
+ mcps?: MCP[];
43
+ appName?: string;
44
+ url?: string;
45
+ className?: string;
46
+ };
47
+
48
+ export type AgentElement = {
49
+ /**
50
+ * Push a new list of MCPs to the embedded agent.
51
+ */
52
+ setMcps: (mcps: MCP[]) => void;
53
+ /**
54
+ * Set the app name for the embedded agent.
55
+ */
56
+ setAppName: (appName: string) => void;
57
+ /**
58
+ * `true` once the iframe has sent the `CHATBOT_READY` handshake message.
59
+ */
60
+ isReady: boolean;
61
+ };
62
+
63
+ export const AgentFrame = forwardRef<AgentElement, AgentFrameProps>(
64
+ ({ agentId, mcps = [], appName, className, url }, ref) => {
65
+ const chatbotUrl = url ?? process.env.CHATBOT_URL ?? PROD_CHATBOT_URL;
66
+
67
+ const iframeRef = useRef<HTMLIFrameElement>(null);
68
+ const [isReady, setIsReady] = useState(false);
69
+ const [hasInitialized, setHasInitialized] = useState(false);
70
+ const [currentMcps, setCurrentMcps] = useState<MCP[]>(mcps);
71
+
72
+ // helper to post message to the iframe
73
+ const postMessage = useCallback((message: ParentMessage) => {
74
+ if (iframeRef.current?.contentWindow) {
75
+ iframeRef.current.contentWindow.postMessage(message, "*");
76
+ }
77
+ }, []);
78
+
79
+ const init = useCallback(
80
+ (props: InitProps) => {
81
+ postMessage({
82
+ type: "init",
83
+ ...props,
84
+ });
85
+ },
86
+ [postMessage],
87
+ );
88
+
89
+ const setMcps = useCallback(
90
+ (mcps: MCP[]) => {
91
+ postMessage({ type: "mcps", mcps });
92
+ },
93
+ [postMessage],
94
+ );
95
+
96
+ const setAppName = useCallback(
97
+ (appName: string) => {
98
+ postMessage({ type: "appName", appName });
99
+ },
100
+ [postMessage],
101
+ );
102
+
103
+ // Expose imperative API to parents.
104
+ useImperativeHandle(
105
+ ref,
106
+ () => ({
107
+ setMcps,
108
+ setAppName,
109
+ get isReady() {
110
+ return isReady;
111
+ },
112
+ }),
113
+ [setMcps, setAppName, isReady],
114
+ );
115
+
116
+ // Initialize and setup listeners
117
+ useEffect(() => {
118
+ const iframe = iframeRef.current;
119
+ if (!iframe) {
120
+ return;
121
+ }
122
+
123
+ const handleMessage = (event: MessageEvent<IframeMessage>) => {
124
+ if (process.env.NODE_ENV === "development") {
125
+ console.log("iframe message", event.data);
126
+ }
127
+ // When the iframe is ready, set isReady flag to kick off the initialization
128
+ if (event.data?.type === "CHATBOT_READY") {
129
+ setIsReady(true);
130
+ }
131
+ };
132
+
133
+ const handleIframeLoad = () => {
134
+ window.addEventListener("message", handleMessage);
135
+ };
136
+
137
+ iframe.addEventListener("load", handleIframeLoad);
138
+
139
+ return () => {
140
+ window.removeEventListener("message", handleMessage);
141
+ iframe.removeEventListener("load", handleIframeLoad);
142
+ };
143
+ // eslint-disable-next-line react-hooks/exhaustive-deps
144
+ }, []); // Only setup the message listeners once
145
+
146
+ // initialize the chatbot
147
+ useEffect(() => {
148
+ if (isReady && !hasInitialized) {
149
+ setHasInitialized(true);
150
+ init({ mcps });
151
+ if (appName) {
152
+ setAppName(appName);
153
+ }
154
+ }
155
+ }, [isReady, init, mcps, appName, hasInitialized, setAppName]);
156
+
157
+ // set mcps every time they change
158
+ useEffect(() => {
159
+ if (JSON.stringify(currentMcps) !== JSON.stringify(mcps)) {
160
+ setCurrentMcps(mcps);
161
+ setMcps(mcps);
162
+ }
163
+ }, [setMcps, mcps, currentMcps]);
164
+
165
+ return (
166
+ <iframe
167
+ ref={iframeRef}
168
+ src={`${chatbotUrl}/embed/${agentId}`}
169
+ className={className}
170
+ allow="clipboard-write"
171
+ style={{
172
+ width: "100%",
173
+ height: "100%",
174
+ }}
175
+ />
176
+ );
177
+ },
178
+ );
179
+
180
+ AgentFrame.displayName = "AgentFrame";
@@ -0,0 +1,54 @@
1
+ import { forwardRef, useState } from "react";
2
+ import {
3
+ AgentFrame,
4
+ type AgentElement,
5
+ type AgentFrameProps,
6
+ } from "./agent-frame";
7
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover";
8
+
9
+ export const ChatbotPopover = forwardRef<AgentElement, AgentFrameProps>(
10
+ (props, ref) => {
11
+ const [isOpen, setIsOpen] = useState(false);
12
+ const [hasOpened, setHasOpened] = useState(false);
13
+
14
+ const handleOpenChange = (open: boolean) => {
15
+ setIsOpen(open);
16
+ if (open && !hasOpened) {
17
+ setHasOpened(true);
18
+ }
19
+ };
20
+
21
+ return (
22
+ <Popover open={isOpen} onOpenChange={handleOpenChange}>
23
+ <PopoverTrigger>
24
+ <EcforceAiIcon />
25
+ </PopoverTrigger>
26
+ <PopoverContent
27
+ align="end"
28
+ backdrop={isOpen}
29
+ forceMount={hasOpened || undefined} // チャットのStateを保持するために必要
30
+ >
31
+ <AgentFrame {...props} ref={ref} />
32
+ </PopoverContent>
33
+ </Popover>
34
+ );
35
+ },
36
+ );
37
+
38
+ function EcforceAiIcon() {
39
+ return (
40
+ <svg
41
+ width="24"
42
+ height="24"
43
+ viewBox="0 0 24 24"
44
+ xmlns="http://www.w3.org/2000/svg"
45
+ fill="currentColor"
46
+ >
47
+ <path
48
+ fillRule="evenodd"
49
+ clipRule="evenodd"
50
+ d="M9.2 13.704s3.7-.812 4.325-3.74c.624-2.93.76-3.364 1.112-3.364.352 0 .42.309.5.618.08.309.51 2.276.613 2.745.102.47.783 2.93 3.712 3.616 2.93.686 3.338.697 3.338 1.12 0 .459-2.361.859-3.338 1.122-.976.263-3.042 1.007-3.587 3.49-.534 2.482-.681 3.489-1.238 3.489-.556 0-.545-.584-.613-.87-.068-.286-.34-1.819-.5-2.494-.147-.675-1.044-2.837-2.962-3.363-1.93-.527-3.962-.847-3.962-1.373s2.134-.824 2.6-.995ZM2.462 4.613s1.785-.39 2.08-1.798c.296-1.409.365-1.615.535-1.615.17 0 .205.149.239.298s.25 1.088.296 1.317c.045.229.375 1.409 1.785 1.74 1.41.333 1.603.333 1.603.54 0 .217-1.137.412-1.603.538-.466.126-1.467.48-1.729 1.683C5.407 8.507 5.338 9 5.078 9c-.262 0-.262-.286-.296-.424-.035-.137-.16-.882-.24-1.202-.079-.321-.5-1.363-1.432-1.615-.932-.252-1.91-.413-1.91-.665 0-.252 1.023-.4 1.25-.48h.012Z"
51
+ />
52
+ </svg>
53
+ );
54
+ }
@@ -0,0 +1,166 @@
1
+ /* Chatbot Trigger Button */
2
+ .chatbot-trigger {
3
+ position: fixed;
4
+ bottom: 1rem;
5
+ right: 1rem;
6
+ z-index: 50;
7
+ border-radius: 9999px;
8
+ border: 1px solid #f0f2f7;
9
+ background-color: #ffffff;
10
+ padding: 0.375rem;
11
+ color: #0061ff;
12
+ box-shadow:
13
+ 0 1px 3px 0 rgba(0, 0, 0, 0.1),
14
+ 0 1px 2px 0 rgba(0, 0, 0, 0.06);
15
+ transition: colors 200ms ease-in-out;
16
+ cursor: pointer;
17
+ }
18
+
19
+ .chatbot-trigger:hover {
20
+ background-color: #f0f2f7;
21
+ }
22
+
23
+ /* Popover Backdrop */
24
+ .chatbot-popover-backdrop {
25
+ position: fixed;
26
+ top: 0;
27
+ right: 0;
28
+ bottom: 0;
29
+ left: 0;
30
+ z-index: 30;
31
+ background-color: rgba(0, 0, 0, 0.5);
32
+ animation: fade-in 150ms ease-out;
33
+ }
34
+
35
+ /* Popover Content */
36
+ .chatbot-popover-content {
37
+ z-index: 50;
38
+ border-radius: 2rem;
39
+ background-color: #f7f9fa;
40
+ box-shadow:
41
+ 0 4px 6px -1px rgba(0, 0, 0, 0.1),
42
+ 0 2px 4px -1px rgba(0, 0, 0, 0.06);
43
+ outline: none;
44
+ overflow: hidden;
45
+ height: 80vh;
46
+ width: 600px;
47
+ }
48
+
49
+ /* Animation states */
50
+ .chatbot-popover-content[data-state="closed"] {
51
+ display: none;
52
+ }
53
+
54
+ .chatbot-popover-content[data-state="open"] {
55
+ animation:
56
+ zoom-in 150ms ease-out,
57
+ fade-in 150ms ease-out;
58
+ }
59
+
60
+ .chatbot-popover-content[data-state="closed"] {
61
+ animation:
62
+ zoom-out 150ms ease-in,
63
+ fade-out 150ms ease-in;
64
+ }
65
+
66
+ /* Side-specific slide animations */
67
+ .chatbot-popover-content[data-side="bottom"] {
68
+ animation:
69
+ zoom-in 150ms ease-out,
70
+ fade-in 150ms ease-out,
71
+ slide-in-from-top 150ms ease-out;
72
+ }
73
+
74
+ .chatbot-popover-content[data-side="top"] {
75
+ animation:
76
+ zoom-in 150ms ease-out,
77
+ fade-in 150ms ease-out,
78
+ slide-in-from-bottom 150ms ease-out;
79
+ }
80
+
81
+ .chatbot-popover-content[data-side="left"] {
82
+ animation:
83
+ zoom-in 150ms ease-out,
84
+ fade-in 150ms ease-out,
85
+ slide-in-from-right 150ms ease-out;
86
+ }
87
+
88
+ .chatbot-popover-content[data-side="right"] {
89
+ animation:
90
+ zoom-in 150ms ease-out,
91
+ fade-in 150ms ease-out,
92
+ slide-in-from-left 150ms ease-out;
93
+ }
94
+
95
+ /* Keyframe Animations */
96
+ @keyframes fade-in {
97
+ from {
98
+ opacity: 0;
99
+ }
100
+ to {
101
+ opacity: 1;
102
+ }
103
+ }
104
+
105
+ @keyframes fade-out {
106
+ from {
107
+ opacity: 1;
108
+ }
109
+ to {
110
+ opacity: 0;
111
+ }
112
+ }
113
+
114
+ @keyframes zoom-in {
115
+ from {
116
+ transform: scale(0.95);
117
+ }
118
+ to {
119
+ transform: scale(1);
120
+ }
121
+ }
122
+
123
+ @keyframes zoom-out {
124
+ from {
125
+ transform: scale(1);
126
+ }
127
+ to {
128
+ transform: scale(0.95);
129
+ }
130
+ }
131
+
132
+ @keyframes slide-in-from-top {
133
+ from {
134
+ transform: translateY(-0.5rem);
135
+ }
136
+ to {
137
+ transform: translateY(0);
138
+ }
139
+ }
140
+
141
+ @keyframes slide-in-from-bottom {
142
+ from {
143
+ transform: translateY(0.5rem);
144
+ }
145
+ to {
146
+ transform: translateY(0);
147
+ }
148
+ }
149
+
150
+ @keyframes slide-in-from-left {
151
+ from {
152
+ transform: translateX(-0.5rem);
153
+ }
154
+ to {
155
+ transform: translateX(0);
156
+ }
157
+ }
158
+
159
+ @keyframes slide-in-from-right {
160
+ from {
161
+ transform: translateX(0.5rem);
162
+ }
163
+ to {
164
+ transform: translateX(0);
165
+ }
166
+ }
@@ -0,0 +1 @@
1
+ export const PROD_CHATBOT_URL = "https://ecforce-ai-agent.vercel.app";
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./agent-frame";
2
+ export * from "./chatbot-popover";
3
+ export * from "./popover";
@@ -0,0 +1,54 @@
1
+ "use client";
2
+
3
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
4
+ import * as React from "react";
5
+
6
+ const Popover = PopoverPrimitive.Root;
7
+
8
+ const PopoverTrigger = React.forwardRef<
9
+ React.ElementRef<typeof PopoverPrimitive.Trigger>,
10
+ React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Trigger>
11
+ >(({ className, ...props }, ref) => (
12
+ <PopoverPrimitive.Trigger
13
+ ref={ref}
14
+ className={`chatbot-trigger ${className}`}
15
+ {...props}
16
+ />
17
+ ));
18
+ PopoverTrigger.displayName = PopoverPrimitive.Trigger.displayName;
19
+
20
+ const PopoverContent = React.forwardRef<
21
+ React.ElementRef<typeof PopoverPrimitive.Content>,
22
+ React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & {
23
+ backdrop?: boolean;
24
+ }
25
+ >(
26
+ (
27
+ {
28
+ className,
29
+ align = "center",
30
+ backdrop,
31
+ sideOffset = 4,
32
+ forceMount,
33
+ ...props
34
+ },
35
+ ref,
36
+ ) => (
37
+ <PopoverPrimitive.Portal forceMount={forceMount}>
38
+ <div>
39
+ {backdrop && <div className="chatbot-popover-backdrop" />}
40
+ <PopoverPrimitive.Content
41
+ ref={ref}
42
+ align={align}
43
+ sideOffset={sideOffset}
44
+ forceMount={forceMount}
45
+ className={`chatbot-popover-content ${className}`}
46
+ {...props}
47
+ />
48
+ </div>
49
+ </PopoverPrimitive.Portal>
50
+ ),
51
+ );
52
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
53
+
54
+ export { Popover, PopoverTrigger, PopoverContent };