@sampleapp.ai/sdk 1.0.24 → 1.0.26

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,150 @@
1
+ "use client";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ import React from "react";
14
+ import { useState, useEffect, useRef, forwardRef } from "react";
15
+ import { Textarea } from "../ui/textarea";
16
+ export const TypingTextarea = forwardRef((_a, ref) => {
17
+ var { texts, typingSpeed = 30, deletingSpeed = 15, delayAfterText = 800, onSubmit, isStreaming = false, className = "", placeholderClassName = "", value, onChange, onFocus, onBlur, onKeyDown, onPaste, placeholder: originalPlaceholder, rows = 1 } = _a, props = __rest(_a, ["texts", "typingSpeed", "deletingSpeed", "delayAfterText", "onSubmit", "isStreaming", "className", "placeholderClassName", "value", "onChange", "onFocus", "onBlur", "onKeyDown", "onPaste", "placeholder", "rows"]);
18
+ const [displayText, setDisplayText] = useState("");
19
+ const [isDeleting, setIsDeleting] = useState(false);
20
+ const [textIndex, setTextIndex] = useState(0);
21
+ const [isWaiting, setIsWaiting] = useState(false);
22
+ const [showTabHint, setShowTabHint] = useState(false);
23
+ const [isPausing, setIsPausing] = useState(false);
24
+ const [isAnimating, setIsAnimating] = useState(false);
25
+ const localRef = useRef(null);
26
+ const textareaRef = ref || localRef;
27
+ const currentText = texts[textIndex];
28
+ const isEmpty = value === "" || value === undefined;
29
+ // Handle animation only when textarea is empty
30
+ useEffect(() => {
31
+ if (!isEmpty)
32
+ return;
33
+ let timeout;
34
+ if (isWaiting) {
35
+ timeout = setTimeout(() => {
36
+ setIsWaiting(false);
37
+ setIsPausing(true);
38
+ setShowTabHint(true);
39
+ setIsAnimating(true);
40
+ }, delayAfterText);
41
+ return () => clearTimeout(timeout);
42
+ }
43
+ if (isPausing) {
44
+ // Show tab hint for 3 seconds
45
+ timeout = setTimeout(() => {
46
+ setIsAnimating(false);
47
+ setTimeout(() => {
48
+ setShowTabHint(false);
49
+ setIsPausing(false);
50
+ setIsDeleting(true);
51
+ }, 300); // Wait for fade out animation
52
+ }, 3000);
53
+ return () => clearTimeout(timeout);
54
+ }
55
+ if (isDeleting) {
56
+ if (displayText === "") {
57
+ setIsDeleting(false);
58
+ setTextIndex((prevIndex) => (prevIndex + 1) % texts.length);
59
+ }
60
+ else {
61
+ timeout = setTimeout(() => {
62
+ setDisplayText((prevText) => prevText.slice(0, -1));
63
+ }, deletingSpeed);
64
+ }
65
+ }
66
+ else {
67
+ if (displayText === currentText) {
68
+ setIsWaiting(true);
69
+ }
70
+ else {
71
+ timeout = setTimeout(() => {
72
+ setDisplayText(currentText.slice(0, displayText.length + 1));
73
+ }, typingSpeed);
74
+ }
75
+ }
76
+ return () => clearTimeout(timeout);
77
+ }, [
78
+ displayText,
79
+ isDeleting,
80
+ textIndex,
81
+ isWaiting,
82
+ isPausing,
83
+ currentText,
84
+ texts,
85
+ typingSpeed,
86
+ deletingSpeed,
87
+ delayAfterText,
88
+ isEmpty,
89
+ ]);
90
+ const handleKeyDown = (e) => {
91
+ if (e.key === "Tab" && isEmpty) {
92
+ e.preventDefault();
93
+ onChange === null || onChange === void 0 ? void 0 : onChange({
94
+ target: { value: currentText },
95
+ });
96
+ return;
97
+ }
98
+ if (e.key === "Enter") {
99
+ if (e.shiftKey) {
100
+ return;
101
+ }
102
+ e.preventDefault();
103
+ if (isStreaming) {
104
+ return;
105
+ }
106
+ onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(e);
107
+ }
108
+ onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
109
+ };
110
+ return (React.createElement("div", { style: { position: "relative", width: "100%" } },
111
+ isEmpty && (React.createElement("div", { style: {
112
+ position: "absolute",
113
+ top: 0,
114
+ right: 0,
115
+ bottom: 0,
116
+ left: 0,
117
+ pointerEvents: "none",
118
+ display: "flex",
119
+ alignItems: "flex-start",
120
+ paddingLeft: "4px",
121
+ paddingRight: "4px",
122
+ paddingTop: "0",
123
+ paddingBottom: "0",
124
+ marginTop: "5px",
125
+ } },
126
+ React.createElement("p", { style: Object.assign({ color: "#a1a1aa", fontWeight: "500", lineHeight: "1.25" }, (placeholderClassName ? {} : {})) },
127
+ displayText,
128
+ React.createElement("span", { style: {
129
+ fontSize: "12px",
130
+ color: "#d1d5db",
131
+ backgroundColor: "#27272a",
132
+ paddingLeft: "6px",
133
+ paddingRight: "6px",
134
+ paddingTop: "2px",
135
+ paddingBottom: "2px",
136
+ borderRadius: "8px",
137
+ border: "1px solid #3f3f46",
138
+ alignItems: "center",
139
+ marginLeft: "8px",
140
+ display: "inline-flex",
141
+ whiteSpace: "nowrap",
142
+ opacity: isAnimating ? 1 : 0,
143
+ transform: isAnimating ? "scale(1)" : "scale(0.8)",
144
+ transition: "opacity 0.3s ease, transform 0.3s ease",
145
+ visibility: showTabHint ? "visible" : "hidden",
146
+ verticalAlign: "middle",
147
+ } }, "Tab to select")))),
148
+ React.createElement(Textarea, Object.assign({ ref: textareaRef, placeholder: originalPlaceholder, style: className ? {} : {}, value: value, onFocus: onFocus, onBlur: onBlur, onChange: onChange, onKeyDown: handleKeyDown, onPaste: onPaste, rows: rows }, props))));
149
+ });
150
+ TypingTextarea.displayName = "TypingTextarea";
@@ -0,0 +1,129 @@
1
+ "use client";
2
+ import React from "react";
3
+ import { motion } from "framer-motion";
4
+ export const VoiceIcon = ({ isRecording, isTranscribing }) => {
5
+ if (isTranscribing) {
6
+ return (React.createElement("div", { style: {
7
+ position: "relative",
8
+ width: "20px",
9
+ height: "16px",
10
+ display: "flex",
11
+ alignItems: "center",
12
+ justifyContent: "center",
13
+ } },
14
+ React.createElement(motion.div, { style: {
15
+ width: "12px",
16
+ height: "12px",
17
+ border: "2px solid white",
18
+ borderTop: "2px solid transparent",
19
+ borderRadius: "50%",
20
+ }, animate: {
21
+ rotate: 360,
22
+ }, transition: {
23
+ duration: 1,
24
+ repeat: Infinity,
25
+ ease: "linear",
26
+ } })));
27
+ }
28
+ if (isRecording) {
29
+ return (React.createElement("div", { style: {
30
+ position: "relative",
31
+ width: "20px",
32
+ height: "16px",
33
+ display: "flex",
34
+ alignItems: "center",
35
+ justifyContent: "center",
36
+ } },
37
+ React.createElement(motion.div, { style: {
38
+ width: "12px",
39
+ height: "12px",
40
+ backgroundColor: "white",
41
+ borderRadius: "2px",
42
+ }, animate: {
43
+ scale: [1, 0.95, 1],
44
+ }, transition: {
45
+ duration: 1,
46
+ repeat: Infinity,
47
+ ease: "easeInOut",
48
+ } })));
49
+ }
50
+ return (React.createElement("div", { style: {
51
+ position: "relative",
52
+ width: "20px",
53
+ height: "16px",
54
+ display: "flex",
55
+ alignItems: "center",
56
+ justifyContent: "center",
57
+ } },
58
+ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: "2px" } },
59
+ React.createElement(motion.div, { style: {
60
+ width: "1.5px",
61
+ height: "8px",
62
+ backgroundColor: "currentColor",
63
+ borderRadius: "999px",
64
+ }, animate: {
65
+ scaleY: [0.4, 0.8, 0.4],
66
+ opacity: [0.6, 0.9, 0.6],
67
+ }, transition: {
68
+ duration: 1.8,
69
+ repeat: Infinity,
70
+ ease: "easeInOut",
71
+ delay: 0,
72
+ } }),
73
+ React.createElement(motion.div, { style: {
74
+ width: "1.5px",
75
+ height: "12px",
76
+ backgroundColor: "currentColor",
77
+ borderRadius: "999px",
78
+ }, animate: {
79
+ scaleY: [0.5, 1, 0.5],
80
+ opacity: [0.7, 1, 0.7],
81
+ }, transition: {
82
+ duration: 2.1,
83
+ repeat: Infinity,
84
+ ease: "easeInOut",
85
+ delay: 0.2,
86
+ } }),
87
+ React.createElement(motion.div, { style: {
88
+ width: "1.5px",
89
+ height: "16px",
90
+ backgroundColor: "currentColor",
91
+ borderRadius: "999px",
92
+ }, animate: {
93
+ scaleY: [0.6, 1, 0.6],
94
+ opacity: [0.8, 1, 0.8],
95
+ }, transition: {
96
+ duration: 1.6,
97
+ repeat: Infinity,
98
+ ease: "easeInOut",
99
+ delay: 0.4,
100
+ } }),
101
+ React.createElement(motion.div, { style: {
102
+ width: "1.5px",
103
+ height: "12px",
104
+ backgroundColor: "currentColor",
105
+ borderRadius: "999px",
106
+ }, animate: {
107
+ scaleY: [0.5, 0.9, 0.5],
108
+ opacity: [0.7, 1, 0.7],
109
+ }, transition: {
110
+ duration: 1.9,
111
+ repeat: Infinity,
112
+ ease: "easeInOut",
113
+ delay: 0.6,
114
+ } }),
115
+ React.createElement(motion.div, { style: {
116
+ width: "1.5px",
117
+ height: "8px",
118
+ backgroundColor: "currentColor",
119
+ borderRadius: "999px",
120
+ }, animate: {
121
+ scaleY: [0.4, 0.7, 0.4],
122
+ opacity: [0.6, 0.9, 0.6],
123
+ }, transition: {
124
+ duration: 2.2,
125
+ repeat: Infinity,
126
+ ease: "easeInOut",
127
+ delay: 0.8,
128
+ } }))));
129
+ };
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import React from "react";
3
+ import { Button } from "../ui/button";
4
+ import { VoiceIcon } from "../icons";
5
+ export const VoiceButton = ({ isRecording, isTranscribing, onVoiceRecording, }) => {
6
+ // Don't show voice button for statsig playground
7
+ // if (playgroundUid === "statsig") {
8
+ // return null;
9
+ // }
10
+ return (React.createElement(Button, { size: "icon", variant: "outline", style: Object.assign(Object.assign({ height: "32px", paddingLeft: "8px", paddingRight: "8px", fontSize: "12px", fontWeight: "500", transition: "all 0.2s ease-in-out" }, (isRecording && {
11
+ backgroundColor: "#ef4444", // red-500
12
+ borderColor: "#ef4444",
13
+ boxShadow: "0 10px 15px -3px rgba(239, 68, 68, 0.25)",
14
+ color: "white",
15
+ })), (isTranscribing && {
16
+ backgroundColor: "#3b82f6", // blue-500
17
+ borderColor: "#3b82f6",
18
+ boxShadow: "0 10px 15px -3px rgba(59, 130, 246, 0.25)",
19
+ color: "white",
20
+ })), onClick: () => {
21
+ onVoiceRecording();
22
+ }, disabled: isTranscribing },
23
+ React.createElement(VoiceIcon, { isRecording: isRecording, isTranscribing: isTranscribing })));
24
+ };
@@ -0,0 +1,190 @@
1
+ import React from "react";
2
+ // Removed cn import as we're using inline styles
3
+ import { motion } from "framer-motion";
4
+ // Voice Recording Overlay Component
5
+ export const VoiceOverlay = ({ isRecording, isTranscribing, onDismiss, }) => {
6
+ // const pathname = usePathname();
7
+ // Enable overlay on main playground pages (/pg/) and subdomain playgrounds (*.sampleapp.ai),
8
+ // // but disable on chat building pages (/chat/)
9
+ // const isLocalhost =
10
+ // typeof window !== "undefined" &&
11
+ // (window.location.hostname === "localhost" ||
12
+ // window.location.hostname.endsWith(".localhost"));
13
+ // const isSubdomainPlayground =
14
+ // typeof window !== "undefined" &&
15
+ // window.location.hostname.endsWith(".sampleapp.ai") &&
16
+ // window.location.hostname !== "sampleapp.ai"; // exclude main domain
17
+ // const isPlaygroundPath =
18
+ // pathname.startsWith("/pg/") && !pathname.includes("/chat");
19
+ // const overlayEnabled =
20
+ // isPlaygroundPath ||
21
+ // isSubdomainPlayground ||
22
+ // (isLocalhost && !pathname.includes("/chat"));
23
+ const overlayEnabled = true;
24
+ const isVisible = overlayEnabled && (isRecording || isTranscribing);
25
+ const isDark = true;
26
+ if (!isVisible)
27
+ return null;
28
+ return (React.createElement(motion.div, { style: {
29
+ position: "fixed",
30
+ top: 0,
31
+ right: 0,
32
+ bottom: 0,
33
+ left: 0,
34
+ zIndex: 50,
35
+ display: "flex",
36
+ alignItems: "center",
37
+ justifyContent: "center",
38
+ backgroundColor: isDark
39
+ ? "rgba(0, 0, 0, 0.2)"
40
+ : "rgba(255, 255, 255, 0.2)",
41
+ }, onClick: isTranscribing ? undefined : onDismiss },
42
+ React.createElement(motion.div, { style: {
43
+ backdropFilter: "blur(4px)",
44
+ borderRadius: "16px",
45
+ padding: "32px",
46
+ border: "1px solid",
47
+ borderColor: isDark
48
+ ? "rgba(255, 255, 255, 0.15)"
49
+ : "rgba(0, 0, 0, 0.15)",
50
+ backgroundColor: isDark
51
+ ? "rgba(255, 255, 255, 0.12)"
52
+ : "rgba(0, 0, 0, 0.12)",
53
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
54
+ }, onClick: (e) => e.stopPropagation() },
55
+ React.createElement("div", { style: {
56
+ display: "flex",
57
+ flexDirection: "column",
58
+ alignItems: "center",
59
+ gap: "24px",
60
+ } }, isTranscribing ? (React.createElement(React.Fragment, null,
61
+ React.createElement(motion.div, { style: {
62
+ width: "64px",
63
+ height: "64px",
64
+ border: "4px solid",
65
+ borderColor: isDark
66
+ ? "rgba(255, 255, 255, 0.3)"
67
+ : "rgba(0, 0, 0, 0.3)",
68
+ borderTopColor: isDark ? "white" : "black",
69
+ borderRadius: "50%",
70
+ }, animate: { rotate: 360 }, transition: { duration: 1, repeat: Infinity, ease: "linear" } }),
71
+ React.createElement("div", { style: { textAlign: "center" } },
72
+ React.createElement("h3", { style: {
73
+ fontSize: "20px",
74
+ fontWeight: "600",
75
+ marginBottom: "8px",
76
+ color: isDark ? "white" : "black",
77
+ } }, "Just a sec..."),
78
+ React.createElement("p", { style: {
79
+ color: isDark
80
+ ? "rgba(255, 255, 255, 0.7)"
81
+ : "rgba(0, 0, 0, 0.7)",
82
+ } }, "Let me write that down for you")))) : (React.createElement(React.Fragment, null,
83
+ React.createElement("div", { style: {
84
+ position: "relative",
85
+ display: "flex",
86
+ alignItems: "center",
87
+ justifyContent: "center",
88
+ width: "128px",
89
+ height: "64px",
90
+ } },
91
+ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: "8px" } },
92
+ React.createElement(motion.div, { style: {
93
+ width: "8px",
94
+ height: "32px",
95
+ borderRadius: "999px",
96
+ backgroundColor: isDark ? "white" : "black",
97
+ }, animate: {
98
+ scaleY: [0.4, 0.8, 0.4],
99
+ opacity: [0.6, 0.9, 0.6],
100
+ }, transition: {
101
+ duration: 1.8,
102
+ repeat: Infinity,
103
+ ease: "easeInOut",
104
+ delay: 0,
105
+ } }),
106
+ React.createElement(motion.div, { style: {
107
+ width: "8px",
108
+ height: "48px",
109
+ borderRadius: "999px",
110
+ backgroundColor: isDark ? "white" : "black",
111
+ }, animate: {
112
+ scaleY: [0.5, 1, 0.5],
113
+ opacity: [0.7, 1, 0.7],
114
+ }, transition: {
115
+ duration: 2.1,
116
+ repeat: Infinity,
117
+ ease: "easeInOut",
118
+ delay: 0.2,
119
+ } }),
120
+ React.createElement(motion.div, { style: {
121
+ width: "8px",
122
+ height: "64px",
123
+ borderRadius: "999px",
124
+ backgroundColor: isDark ? "white" : "black",
125
+ }, animate: {
126
+ scaleY: [0.6, 1, 0.6],
127
+ opacity: [0.8, 1, 0.8],
128
+ }, transition: {
129
+ duration: 1.6,
130
+ repeat: Infinity,
131
+ ease: "easeInOut",
132
+ delay: 0.4,
133
+ } }),
134
+ React.createElement(motion.div, { style: {
135
+ width: "8px",
136
+ height: "48px",
137
+ borderRadius: "999px",
138
+ backgroundColor: isDark ? "white" : "black",
139
+ }, animate: {
140
+ scaleY: [0.5, 0.9, 0.5],
141
+ opacity: [0.7, 1, 0.7],
142
+ }, transition: {
143
+ duration: 1.9,
144
+ repeat: Infinity,
145
+ ease: "easeInOut",
146
+ delay: 0.6,
147
+ } }),
148
+ React.createElement(motion.div, { style: {
149
+ width: "8px",
150
+ height: "32px",
151
+ borderRadius: "999px",
152
+ backgroundColor: isDark ? "white" : "black",
153
+ }, animate: {
154
+ scaleY: [0.4, 0.7, 0.4],
155
+ opacity: [0.6, 0.9, 0.6],
156
+ }, transition: {
157
+ duration: 2.2,
158
+ repeat: Infinity,
159
+ ease: "easeInOut",
160
+ delay: 0.8,
161
+ } }))),
162
+ React.createElement("div", { style: { textAlign: "center" } },
163
+ React.createElement("h3", { style: {
164
+ fontSize: "20px",
165
+ fontWeight: "600",
166
+ marginBottom: "8px",
167
+ color: isDark ? "white" : "black",
168
+ } }, "I'm listening..."),
169
+ React.createElement("p", { style: {
170
+ color: isDark
171
+ ? "rgba(255, 255, 255, 0.7)"
172
+ : "rgba(0, 0, 0, 0.7)",
173
+ } }, "Tell me what you'd like to build today")),
174
+ React.createElement(motion.button, { style: {
175
+ paddingLeft: "24px",
176
+ paddingRight: "24px",
177
+ paddingTop: "12px",
178
+ paddingBottom: "12px",
179
+ backdropFilter: "blur(4px)",
180
+ borderRadius: "12px",
181
+ fontWeight: "500",
182
+ transition: "all 0.15s ease",
183
+ backgroundColor: isDark
184
+ ? "rgba(255, 255, 255, 0.2)"
185
+ : "rgba(0, 0, 0, 0.2)",
186
+ border: `1px solid ${isDark ? "rgba(255, 255, 255, 0.3)" : "rgba(0, 0, 0, 0.3)"}`,
187
+ color: isDark ? "white" : "black",
188
+ cursor: "pointer",
189
+ }, onClick: onDismiss, whileHover: { scale: 1.05 }, whileTap: { scale: 0.95 } }, "Stop")))))));
190
+ };