@formmy.app/chat 0.0.1-alpha.1

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,162 @@
1
+ /**
2
+ * @formmy.app/chat/react - useFormmyChat Hook
3
+ *
4
+ * Headless hook for chat functionality, wrapping Vercel AI SDK's useChat.
5
+ *
6
+ * Usage:
7
+ * ```tsx
8
+ * import { useFormmyChat } from '@formmy.app/chat/react';
9
+ *
10
+ * function Chat() {
11
+ * const { messages, sendMessage, status } = useFormmyChat({
12
+ * agentId: 'agent_123',
13
+ * });
14
+ *
15
+ * return (
16
+ * <div>
17
+ * {messages.map(m => <div key={m.id}>{getMessageText(m)}</div>)}
18
+ * <button onClick={() => sendMessage('Hello!')}>Send</button>
19
+ * </div>
20
+ * );
21
+ * }
22
+ * ```
23
+ */
24
+ import { useChat } from "@ai-sdk/react";
25
+ import { DefaultChatTransport } from "ai";
26
+ import { useMemo, useCallback, useState, useEffect } from "react";
27
+ import { useFormmy } from "../ui/provider";
28
+ // Session ID storage key prefix
29
+ const SESSION_KEY_PREFIX = "formmy_session_";
30
+ /**
31
+ * Extract text content from a message's parts
32
+ */
33
+ export function getMessageText(message) {
34
+ if (!message.parts)
35
+ return "";
36
+ return message.parts
37
+ .filter((p) => p.type === "text" && typeof p.text === "string")
38
+ .map((p) => p.text)
39
+ .join("");
40
+ }
41
+ /**
42
+ * Headless chat hook - provides all chat functionality without UI
43
+ */
44
+ export function useFormmyChat(options) {
45
+ const { agentId, onError, onFinish } = options;
46
+ const { publishableKey, baseUrl } = useFormmy();
47
+ // Generate or retrieve session ID (crypto-secure)
48
+ const [sessionId] = useState(() => {
49
+ // SSR safety
50
+ if (typeof window === "undefined") {
51
+ return `sdk_${agentId}_${Date.now()}`;
52
+ }
53
+ try {
54
+ const storageKey = `${SESSION_KEY_PREFIX}${agentId}`;
55
+ const existing = localStorage.getItem(storageKey);
56
+ if (existing) {
57
+ return existing;
58
+ }
59
+ // Use crypto.getRandomValues for secure random ID
60
+ const bytes = new Uint8Array(16);
61
+ crypto.getRandomValues(bytes);
62
+ const randomPart = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
63
+ const newSessionId = `sdk_${agentId}_${randomPart}`;
64
+ localStorage.setItem(storageKey, newSessionId);
65
+ return newSessionId;
66
+ }
67
+ catch {
68
+ // Fallback if localStorage is disabled
69
+ const bytes = new Uint8Array(16);
70
+ crypto.getRandomValues(bytes);
71
+ const randomPart = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
72
+ return `sdk_${agentId}_${randomPart}`;
73
+ }
74
+ });
75
+ // Create transport with SDK authentication
76
+ const transport = useMemo(() => {
77
+ return new DefaultChatTransport({
78
+ api: `${baseUrl}/api/v2/sdk?intent=chat&agentId=${agentId}`,
79
+ headers: {
80
+ "X-Publishable-Key": publishableKey || "",
81
+ },
82
+ // "Last Message Only" pattern - only send the new message
83
+ prepareSendMessagesRequest({ messages, id }) {
84
+ return {
85
+ body: {
86
+ message: messages[messages.length - 1],
87
+ id: id || sessionId,
88
+ },
89
+ };
90
+ },
91
+ });
92
+ }, [baseUrl, agentId, publishableKey, sessionId]);
93
+ // Use Vercel AI SDK's useChat with our transport
94
+ const chat = useChat({
95
+ id: sessionId,
96
+ transport,
97
+ onError: (error) => {
98
+ console.error("[useFormmyChat] Error:", error);
99
+ onError?.(error);
100
+ },
101
+ onFinish: () => {
102
+ onFinish?.();
103
+ },
104
+ });
105
+ // Load historical messages on mount
106
+ useEffect(() => {
107
+ async function loadHistory() {
108
+ try {
109
+ const response = await fetch(`${baseUrl}/api/v2/sdk?intent=chat.history&agentId=${agentId}&sessionId=${sessionId}`, {
110
+ headers: {
111
+ "X-Publishable-Key": publishableKey || "",
112
+ },
113
+ });
114
+ if (response.ok) {
115
+ const data = await response.json();
116
+ if (data.messages?.length > 0) {
117
+ chat.setMessages(data.messages);
118
+ }
119
+ }
120
+ }
121
+ catch (error) {
122
+ console.warn("[useFormmyChat] Failed to load history:", error);
123
+ }
124
+ }
125
+ loadHistory();
126
+ // Only run on mount
127
+ // eslint-disable-next-line react-hooks/exhaustive-deps
128
+ }, []);
129
+ // Simplified sendMessage wrapper
130
+ const sendMessage = useCallback(async (text) => {
131
+ await chat.sendMessage({
132
+ role: "user",
133
+ parts: [{ type: "text", text }],
134
+ });
135
+ }, [chat]);
136
+ // Reset conversation (clear local storage and messages)
137
+ const reset = useCallback(() => {
138
+ if (typeof window !== "undefined") {
139
+ localStorage.removeItem(`${SESSION_KEY_PREFIX}${agentId}`);
140
+ }
141
+ chat.setMessages([]);
142
+ }, [agentId, chat]);
143
+ return {
144
+ // State
145
+ messages: chat.messages,
146
+ status: chat.status,
147
+ error: chat.error,
148
+ // Metadata
149
+ sessionId,
150
+ agentId,
151
+ // Actions
152
+ sendMessage,
153
+ reset,
154
+ stop: chat.stop,
155
+ setMessages: chat.setMessages,
156
+ // Utility
157
+ getMessageText,
158
+ // Raw chat object for advanced use cases
159
+ _chat: chat,
160
+ };
161
+ }
162
+ //# sourceMappingURL=use-formmy-chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-formmy-chat.js","sourceRoot":"","sources":["../../src/hooks/use-formmy-chat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @formmy.app/chat - Official SDK for Formmy Chat
3
+ *
4
+ * This is the core client for backend usage (no React dependency).
5
+ *
6
+ * @example Backend Usage
7
+ * ```typescript
8
+ * import { Formmy } from '@formmy.app/chat';
9
+ *
10
+ * const formmy = new Formmy({ secretKey: 'sk_live_xxx' });
11
+ *
12
+ * // Create agent
13
+ * const agent = await formmy.agents.create({ name: 'My Agent' });
14
+ *
15
+ * // List agents
16
+ * const { agents } = await formmy.agents.list();
17
+ * ```
18
+ *
19
+ * For React components and hooks, use:
20
+ * ```tsx
21
+ * import { FormmyProvider, ChatBubble, useFormmyChat } from '@formmy.app/chat/react';
22
+ * ```
23
+ */
24
+ export * from "./core/client";
25
+ export * from "./core/types";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @formmy.app/chat - Official SDK for Formmy Chat
3
+ *
4
+ * This is the core client for backend usage (no React dependency).
5
+ *
6
+ * @example Backend Usage
7
+ * ```typescript
8
+ * import { Formmy } from '@formmy.app/chat';
9
+ *
10
+ * const formmy = new Formmy({ secretKey: 'sk_live_xxx' });
11
+ *
12
+ * // Create agent
13
+ * const agent = await formmy.agents.create({ name: 'My Agent' });
14
+ *
15
+ * // List agents
16
+ * const { agents } = await formmy.agents.list();
17
+ * ```
18
+ *
19
+ * For React components and hooks, use:
20
+ * ```tsx
21
+ * import { FormmyProvider, ChatBubble, useFormmyChat } from '@formmy.app/chat/react';
22
+ * ```
23
+ */
24
+ // Re-export everything from core client
25
+ export * from "./core/client";
26
+ export * from "./core/types";
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,wCAAwC;AACxC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @formmy.app/chat/react - React components and hooks
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { FormmyProvider, ChatBubble, useFormmyChat } from '@formmy.app/chat/react';
7
+ *
8
+ * function App() {
9
+ * return (
10
+ * <FormmyProvider publishableKey="pk_live_xxx">
11
+ * <YourApp />
12
+ * <ChatBubble agentId="agent_123" />
13
+ * </FormmyProvider>
14
+ * );
15
+ * }
16
+ * ```
17
+ */
18
+ export type { FormmyConfig, FormmyProviderProps, UseFormmyChatOptions, Message, MessagePart, ChatBubbleProps, ChatTheme, } from "./core/types";
19
+ export { FormmyProvider, useFormmy, useFormmyOptional } from "./ui/provider";
20
+ export { useFormmyChat, getMessageText } from "./hooks/use-formmy-chat";
21
+ export { ChatBubble } from "./ui/chat-bubble";
22
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,EACpB,OAAO,EACP,WAAW,EACX,eAAe,EACf,SAAS,GACV,MAAM,cAAc,CAAC;AAKtB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAK7E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAKxE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/react.js ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @formmy.app/chat/react - React components and hooks
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { FormmyProvider, ChatBubble, useFormmyChat } from '@formmy.app/chat/react';
7
+ *
8
+ * function App() {
9
+ * return (
10
+ * <FormmyProvider publishableKey="pk_live_xxx">
11
+ * <YourApp />
12
+ * <ChatBubble agentId="agent_123" />
13
+ * </FormmyProvider>
14
+ * );
15
+ * }
16
+ * ```
17
+ */
18
+ // ═══════════════════════════════════════════════════════════════════════════
19
+ // Provider & Context
20
+ // ═══════════════════════════════════════════════════════════════════════════
21
+ export { FormmyProvider, useFormmy, useFormmyOptional } from "./ui/provider";
22
+ // ═══════════════════════════════════════════════════════════════════════════
23
+ // Hooks
24
+ // ═══════════════════════════════════════════════════════════════════════════
25
+ export { useFormmyChat, getMessageText } from "./hooks/use-formmy-chat";
26
+ // ═══════════════════════════════════════════════════════════════════════════
27
+ // UI Components
28
+ // ═══════════════════════════════════════════════════════════════════════════
29
+ export { ChatBubble } from "./ui/chat-bubble";
30
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAeH,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAC9E,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE7E,8EAA8E;AAC9E,QAAQ;AACR,8EAA8E;AAC9E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAExE,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @formmy.app/react - ChatBubble Component
3
+ *
4
+ * Ready-to-use floating chat widget.
5
+ *
6
+ * Usage:
7
+ * ```tsx
8
+ * import { FormmyProvider, ChatBubble } from '@formmy.app/react';
9
+ *
10
+ * function App() {
11
+ * return (
12
+ * <FormmyProvider publishableKey="pk_live_xxx">
13
+ * <YourApp />
14
+ * <ChatBubble
15
+ * agentId="agent_123"
16
+ * position="bottom-right"
17
+ * theme={{ primaryColor: '#9A99EA' }}
18
+ * />
19
+ * </FormmyProvider>
20
+ * );
21
+ * }
22
+ * ```
23
+ */
24
+ import type { ChatBubbleProps } from "../core/types";
25
+ export declare function ChatBubble({ agentId, position, theme, defaultOpen, onOpenChange, }: ChatBubbleProps): import("react/jsx-runtime").JSX.Element;
26
+ //# sourceMappingURL=chat-bubble.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-bubble.d.ts","sourceRoot":"","sources":["../../src/ui/chat-bubble.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAa,MAAM,eAAe,CAAC;AAiChE,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,QAAyB,EACzB,KAAU,EACV,WAAmB,EACnB,YAAY,GACb,EAAE,eAAe,2CA8RjB"}
@@ -0,0 +1,206 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * @formmy.app/react - ChatBubble Component
4
+ *
5
+ * Ready-to-use floating chat widget.
6
+ *
7
+ * Usage:
8
+ * ```tsx
9
+ * import { FormmyProvider, ChatBubble } from '@formmy.app/react';
10
+ *
11
+ * function App() {
12
+ * return (
13
+ * <FormmyProvider publishableKey="pk_live_xxx">
14
+ * <YourApp />
15
+ * <ChatBubble
16
+ * agentId="agent_123"
17
+ * position="bottom-right"
18
+ * theme={{ primaryColor: '#9A99EA' }}
19
+ * />
20
+ * </FormmyProvider>
21
+ * );
22
+ * }
23
+ * ```
24
+ */
25
+ import { useState, useRef, useEffect } from "react";
26
+ import { useFormmyChat, getMessageText } from "../hooks/use-formmy-chat";
27
+ // ═══════════════════════════════════════════════════════════════════════════
28
+ // Styles (inline to avoid external dependencies)
29
+ // ═══════════════════════════════════════════════════════════════════════════
30
+ const defaultTheme = {
31
+ primaryColor: "#9A99EA",
32
+ backgroundColor: "#ffffff",
33
+ textColor: "#1a1a1a",
34
+ borderRadius: "16px",
35
+ };
36
+ function getPositionStyles(position = "bottom-right") {
37
+ const base = { position: "fixed", zIndex: 9999 };
38
+ switch (position) {
39
+ case "bottom-left":
40
+ return { ...base, bottom: "24px", left: "24px" };
41
+ case "top-right":
42
+ return { ...base, top: "24px", right: "24px" };
43
+ case "top-left":
44
+ return { ...base, top: "24px", left: "24px" };
45
+ case "bottom-right":
46
+ default:
47
+ return { ...base, bottom: "24px", right: "24px" };
48
+ }
49
+ }
50
+ // ═══════════════════════════════════════════════════════════════════════════
51
+ // Component
52
+ // ═══════════════════════════════════════════════════════════════════════════
53
+ export function ChatBubble({ agentId, position = "bottom-right", theme = {}, defaultOpen = false, onOpenChange, }) {
54
+ const [isOpen, setIsOpen] = useState(defaultOpen);
55
+ const [input, setInput] = useState("");
56
+ const messagesEndRef = useRef(null);
57
+ const inputRef = useRef(null);
58
+ const { messages, sendMessage, status } = useFormmyChat({ agentId });
59
+ const mergedTheme = { ...defaultTheme, ...theme };
60
+ const positionStyles = getPositionStyles(position);
61
+ const isLoading = status === "streaming" || status === "submitted";
62
+ // Handle open/close
63
+ const handleToggle = () => {
64
+ const newState = !isOpen;
65
+ setIsOpen(newState);
66
+ onOpenChange?.(newState);
67
+ };
68
+ // Auto-scroll to bottom on new messages
69
+ useEffect(() => {
70
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
71
+ }, [messages]);
72
+ // Focus input when opened
73
+ useEffect(() => {
74
+ if (isOpen) {
75
+ setTimeout(() => inputRef.current?.focus(), 100);
76
+ }
77
+ }, [isOpen]);
78
+ // Handle send
79
+ const handleSubmit = async (e) => {
80
+ e.preventDefault();
81
+ if (!input.trim() || isLoading)
82
+ return;
83
+ const message = input.trim();
84
+ setInput("");
85
+ await sendMessage(message);
86
+ };
87
+ // Handle Enter key
88
+ const handleKeyDown = (e) => {
89
+ if (e.key === "Enter" && !e.shiftKey) {
90
+ e.preventDefault();
91
+ handleSubmit(e);
92
+ }
93
+ };
94
+ return (_jsxs("div", { style: positionStyles, children: [isOpen && (_jsxs("div", { style: {
95
+ position: "absolute",
96
+ bottom: "70px",
97
+ right: "0",
98
+ width: "380px",
99
+ maxWidth: "calc(100vw - 48px)",
100
+ height: "500px",
101
+ maxHeight: "calc(100vh - 120px)",
102
+ backgroundColor: mergedTheme.backgroundColor,
103
+ borderRadius: mergedTheme.borderRadius,
104
+ boxShadow: "0 8px 32px rgba(0, 0, 0, 0.15)",
105
+ display: "flex",
106
+ flexDirection: "column",
107
+ overflow: "hidden",
108
+ }, children: [_jsxs("div", { style: {
109
+ padding: "16px",
110
+ backgroundColor: mergedTheme.primaryColor,
111
+ color: "#fff",
112
+ fontWeight: 600,
113
+ display: "flex",
114
+ justifyContent: "space-between",
115
+ alignItems: "center",
116
+ }, children: [_jsx("span", { children: "Chat" }), _jsx("button", { onClick: handleToggle, style: {
117
+ background: "none",
118
+ border: "none",
119
+ color: "#fff",
120
+ cursor: "pointer",
121
+ fontSize: "20px",
122
+ lineHeight: 1,
123
+ }, "aria-label": "Close chat", children: "\u00D7" })] }), _jsxs("div", { style: {
124
+ flex: 1,
125
+ overflowY: "auto",
126
+ padding: "16px",
127
+ display: "flex",
128
+ flexDirection: "column",
129
+ gap: "12px",
130
+ }, children: [messages.length === 0 && (_jsx("div", { style: {
131
+ textAlign: "center",
132
+ color: "#666",
133
+ marginTop: "40px",
134
+ }, children: "Send a message to start the conversation" })), messages.map((msg) => {
135
+ const text = getMessageText(msg);
136
+ if (!text)
137
+ return null;
138
+ const isUser = msg.role === "user";
139
+ return (_jsx("div", { style: {
140
+ display: "flex",
141
+ justifyContent: isUser ? "flex-end" : "flex-start",
142
+ }, children: _jsx("div", { style: {
143
+ maxWidth: "80%",
144
+ padding: "10px 14px",
145
+ borderRadius: "12px",
146
+ backgroundColor: isUser
147
+ ? mergedTheme.primaryColor
148
+ : "#f0f0f0",
149
+ color: isUser ? "#fff" : mergedTheme.textColor,
150
+ fontSize: "14px",
151
+ lineHeight: 1.5,
152
+ whiteSpace: "pre-wrap",
153
+ wordBreak: "break-word",
154
+ }, children: text }) }, msg.id));
155
+ }), isLoading && (_jsx("div", { style: { display: "flex", justifyContent: "flex-start" }, children: _jsxs("div", { style: {
156
+ padding: "10px 14px",
157
+ borderRadius: "12px",
158
+ backgroundColor: "#f0f0f0",
159
+ color: "#666",
160
+ fontSize: "14px",
161
+ }, children: [_jsx("span", { style: { animation: "pulse 1.5s infinite" }, children: "\u25CF" }), _jsx("span", { style: { animation: "pulse 1.5s infinite 0.2s" }, children: "\u25CF" }), _jsx("span", { style: { animation: "pulse 1.5s infinite 0.4s" }, children: "\u25CF" })] }) })), _jsx("div", { ref: messagesEndRef })] }), _jsxs("form", { onSubmit: handleSubmit, style: {
162
+ padding: "12px 16px",
163
+ borderTop: "1px solid #eee",
164
+ display: "flex",
165
+ gap: "8px",
166
+ }, children: [_jsx("input", { ref: inputRef, type: "text", value: input, onChange: (e) => setInput(e.target.value), onKeyDown: handleKeyDown, placeholder: "Type a message...", disabled: isLoading, style: {
167
+ flex: 1,
168
+ padding: "10px 14px",
169
+ borderRadius: "8px",
170
+ border: "1px solid #ddd",
171
+ fontSize: "14px",
172
+ outline: "none",
173
+ } }), _jsx("button", { type: "submit", disabled: !input.trim() || isLoading, style: {
174
+ padding: "10px 16px",
175
+ borderRadius: "8px",
176
+ border: "none",
177
+ backgroundColor: mergedTheme.primaryColor,
178
+ color: "#fff",
179
+ fontSize: "14px",
180
+ fontWeight: 500,
181
+ cursor: input.trim() && !isLoading ? "pointer" : "not-allowed",
182
+ opacity: input.trim() && !isLoading ? 1 : 0.6,
183
+ }, children: "Send" })] })] })), _jsx("button", { onClick: handleToggle, style: {
184
+ width: "56px",
185
+ height: "56px",
186
+ borderRadius: "50%",
187
+ backgroundColor: mergedTheme.primaryColor,
188
+ border: "none",
189
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
190
+ cursor: "pointer",
191
+ display: "flex",
192
+ alignItems: "center",
193
+ justifyContent: "center",
194
+ transition: "transform 0.2s",
195
+ }, "aria-label": isOpen ? "Close chat" : "Open chat", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "#fff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: isOpen ? (
196
+ // X icon
197
+ _jsxs(_Fragment, { children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] })) : (
198
+ // Chat icon
199
+ _jsx(_Fragment, { children: _jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })) }) }), _jsx("style", { children: `
200
+ @keyframes pulse {
201
+ 0%, 100% { opacity: 0.4; }
202
+ 50% { opacity: 1; }
203
+ }
204
+ ` })] }));
205
+ }
206
+ //# sourceMappingURL=chat-bubble.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-bubble.js","sourceRoot":"","sources":["../../src/ui/chat-bubble.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @formmy.app/react - Provider Component
3
+ *
4
+ * Provides Formmy configuration to all child components.
5
+ *
6
+ * Usage:
7
+ * ```tsx
8
+ * import { FormmyProvider } from '@formmy.app/react';
9
+ *
10
+ * function App() {
11
+ * return (
12
+ * <FormmyProvider publishableKey="pk_live_xxx">
13
+ * <YourApp />
14
+ * </FormmyProvider>
15
+ * );
16
+ * }
17
+ * ```
18
+ */
19
+ import type { FormmyConfig, FormmyProviderProps } from "../core/types";
20
+ interface FormmyContextValue extends FormmyConfig {
21
+ baseUrl: string;
22
+ }
23
+ export declare function FormmyProvider({ publishableKey, secretKey, baseUrl, children, }: FormmyProviderProps): import("react/jsx-runtime").JSX.Element;
24
+ /**
25
+ * Hook to access Formmy configuration from context
26
+ * @throws Error if used outside FormmyProvider
27
+ */
28
+ export declare function useFormmy(): FormmyContextValue;
29
+ /**
30
+ * Hook to access Formmy configuration, returns null if not in provider
31
+ * Useful for optional Formmy integration
32
+ */
33
+ export declare function useFormmyOptional(): FormmyContextValue | null;
34
+ export {};
35
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/ui/provider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAIvE,UAAU,kBAAmB,SAAQ,YAAY;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,SAAS,EACT,OAA0B,EAC1B,QAAQ,GACT,EAAE,mBAAmB,2CAarB;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,kBAAkB,CAQ9C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,kBAAkB,GAAG,IAAI,CAE7D"}
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * @formmy.app/react - Provider Component
4
+ *
5
+ * Provides Formmy configuration to all child components.
6
+ *
7
+ * Usage:
8
+ * ```tsx
9
+ * import { FormmyProvider } from '@formmy.app/react';
10
+ *
11
+ * function App() {
12
+ * return (
13
+ * <FormmyProvider publishableKey="pk_live_xxx">
14
+ * <YourApp />
15
+ * </FormmyProvider>
16
+ * );
17
+ * }
18
+ * ```
19
+ */
20
+ import { createContext, useContext, useMemo } from "react";
21
+ const DEFAULT_BASE_URL = "https://formmy.app";
22
+ const FormmyContext = createContext(null);
23
+ export function FormmyProvider({ publishableKey, secretKey, baseUrl = DEFAULT_BASE_URL, children, }) {
24
+ const value = useMemo(() => ({
25
+ publishableKey,
26
+ secretKey,
27
+ baseUrl,
28
+ }), [publishableKey, secretKey, baseUrl]);
29
+ return (_jsx(FormmyContext.Provider, { value: value, children: children }));
30
+ }
31
+ /**
32
+ * Hook to access Formmy configuration from context
33
+ * @throws Error if used outside FormmyProvider
34
+ */
35
+ export function useFormmy() {
36
+ const context = useContext(FormmyContext);
37
+ if (!context) {
38
+ throw new Error("useFormmy must be used within a FormmyProvider");
39
+ }
40
+ return context;
41
+ }
42
+ /**
43
+ * Hook to access Formmy configuration, returns null if not in provider
44
+ * Useful for optional Formmy integration
45
+ */
46
+ export function useFormmyOptional() {
47
+ return useContext(FormmyContext);
48
+ }
49
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/ui/provider.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAG3D,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAM9C,MAAM,aAAa,GAAG,aAAa,CAA4B,IAAI,CAAC,CAAC;AAErE,MAAM,UAAU,cAAc,CAAC,EAC7B,cAAc,EACd,SAAS,EACT,OAAO,GAAG,gBAAgB,EAC1B,QAAQ,GACY;IACpB,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC;QACL,cAAc;QACd,SAAS;QACT,OAAO;KACR,CAAC,EACF,CAAC,cAAc,EAAE,SAAS,EAAE,OAAO,CAAC,CACrC,CAAC;IAEF,OAAO,CACL,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA0B,CAC1E,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAE1C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC"}