@sampleapp.ai/sdk 1.0.25 → 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.
@@ -12,7 +12,6 @@ var __rest = (this && this.__rest) || function (s, e) {
12
12
  };
13
13
  import React from "react";
14
14
  import { useState, useEffect, useRef, forwardRef } from "react";
15
- import { motion, AnimatePresence } from "framer-motion";
16
15
  import { Textarea } from "../ui/textarea";
17
16
  export const TypingTextarea = forwardRef((_a, ref) => {
18
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"]);
@@ -22,11 +21,11 @@ export const TypingTextarea = forwardRef((_a, ref) => {
22
21
  const [isWaiting, setIsWaiting] = useState(false);
23
22
  const [showTabHint, setShowTabHint] = useState(false);
24
23
  const [isPausing, setIsPausing] = useState(false);
24
+ const [isAnimating, setIsAnimating] = useState(false);
25
25
  const localRef = useRef(null);
26
26
  const textareaRef = ref || localRef;
27
27
  const currentText = texts[textIndex];
28
28
  const isEmpty = value === "" || value === undefined;
29
- // const isFullTextDisplayed = displayText === currentText && !isDeleting;
30
29
  // Handle animation only when textarea is empty
31
30
  useEffect(() => {
32
31
  if (!isEmpty)
@@ -37,14 +36,16 @@ export const TypingTextarea = forwardRef((_a, ref) => {
37
36
  setIsWaiting(false);
38
37
  setIsPausing(true);
39
38
  setShowTabHint(true);
39
+ setIsAnimating(true);
40
40
  }, delayAfterText);
41
41
  return () => clearTimeout(timeout);
42
42
  }
43
43
  if (isPausing) {
44
- // Show tab hint for 3 seconds with fade animation
44
+ // Show tab hint for 3 seconds
45
45
  timeout = setTimeout(() => {
46
- setShowTabHint(false);
46
+ setIsAnimating(false);
47
47
  setTimeout(() => {
48
+ setShowTabHint(false);
48
49
  setIsPausing(false);
49
50
  setIsDeleting(true);
50
51
  }, 300); // Wait for fade out animation
@@ -120,25 +121,30 @@ export const TypingTextarea = forwardRef((_a, ref) => {
120
121
  paddingRight: "4px",
121
122
  paddingTop: "0",
122
123
  paddingBottom: "0",
123
- marginTop: "4px",
124
+ marginTop: "5px",
124
125
  } },
125
- React.createElement("p", { style: Object.assign({ color: "#a1a1aa", fontWeight: "500", lineHeight: "1.5" }, (placeholderClassName ? {} : {})) },
126
+ React.createElement("p", { style: Object.assign({ color: "#a1a1aa", fontWeight: "500", lineHeight: "1.25" }, (placeholderClassName ? {} : {})) },
126
127
  displayText,
127
- React.createElement(AnimatePresence, null, showTabHint && (React.createElement(motion.span, { initial: { opacity: 0, scale: 0.8 }, animate: { opacity: 1, scale: 1 }, exit: { opacity: 0, scale: 0.8 }, transition: { duration: 0.3 }, style: {
128
+ React.createElement("span", { style: {
128
129
  fontSize: "12px",
129
- color: "#d1d5db", // zinc-300 for dark mode
130
- backgroundColor: "#27272a", // zinc-800 for dark mode
130
+ color: "#d1d5db",
131
+ backgroundColor: "#27272a",
131
132
  paddingLeft: "6px",
132
133
  paddingRight: "6px",
133
134
  paddingTop: "2px",
134
135
  paddingBottom: "2px",
135
136
  borderRadius: "8px",
136
- border: "1px solid #3f3f46", // zinc-700 for dark mode
137
+ border: "1px solid #3f3f46",
137
138
  alignItems: "center",
138
139
  marginLeft: "8px",
139
140
  display: "inline-flex",
140
141
  whiteSpace: "nowrap",
141
- } }, "Tab to select")))))),
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")))),
142
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))));
143
149
  });
144
150
  TypingTextarea.displayName = "TypingTextarea";
@@ -1,26 +1,13 @@
1
1
  "use client";
2
2
  import React from "react";
3
3
  import { Button } from "../ui/button";
4
- import { VoiceIcon } from "./voice-button/voice-icon";
5
- export const VoiceButton = ({ isRecording, isTranscribing, onVoiceRecording, playgroundUid, // eslint-disable-line @typescript-eslint/no-unused-vars
6
- isLoggedIn = false, }) => {
4
+ import { VoiceIcon } from "../icons";
5
+ export const VoiceButton = ({ isRecording, isTranscribing, onVoiceRecording, }) => {
7
6
  // Don't show voice button for statsig playground
8
7
  // if (playgroundUid === "statsig") {
9
8
  // return null;
10
9
  // }
11
- const getTooltipText = () => {
12
- if (isTranscribing) {
13
- return "Transcribing your voice...";
14
- }
15
- if (isRecording) {
16
- return "Click to stop recording";
17
- }
18
- if (isLoggedIn) {
19
- return "Voice Mode – Build with voice (Ctrl/Cmd + /)";
20
- }
21
- return "Sign up to use voice mode";
22
- };
23
- return (React.createElement(Button, { size: "sm", variant: "ghostOutline", style: Object.assign(Object.assign({ height: "32px", paddingLeft: "8px", paddingRight: "8px", fontSize: "12px", fontWeight: "500", transition: "all 0.2s ease-in-out" }, (isRecording && {
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 && {
24
11
  backgroundColor: "#ef4444", // red-500
25
12
  borderColor: "#ef4444",
26
13
  boxShadow: "0 10px 15px -3px rgba(239, 68, 68, 0.25)",
@@ -31,12 +18,7 @@ isLoggedIn = false, }) => {
31
18
  boxShadow: "0 10px 15px -3px rgba(59, 130, 246, 0.25)",
32
19
  color: "white",
33
20
  })), onClick: () => {
34
- if (isLoggedIn && !isTranscribing) {
35
- onVoiceRecording();
36
- }
37
- else if (!isLoggedIn) {
38
- window.location.href = "/sign-up";
39
- }
21
+ onVoiceRecording();
40
22
  }, disabled: isTranscribing },
41
23
  React.createElement(VoiceIcon, { isRecording: isRecording, isTranscribing: isTranscribing })));
42
24
  };
@@ -2,22 +2,36 @@
2
2
  /* eslint-disable @next/next/no-img-element */
3
3
  import React from "react";
4
4
  import { useState, useRef, useEffect, useMemo } from "react";
5
- import { ArrowUp, Loader2, CircleStop } from "lucide-react";
6
- import { TypingTextarea } from "./chat-bar/typing-textarea";
7
5
  import { Textarea } from "./ui/textarea";
8
- import { VoiceButton } from "./chat-bar/voice-button";
9
- import { VoiceOverlay } from "./chat-bar/voice-overlay";
10
6
  import { Button } from "./ui/button";
11
7
  import { getTheme } from "../themes";
8
+ import { LoaderIcon, ArrowUpIcon } from "./icons";
9
+ import { TypingTextarea } from "./chat-bar/typing-textarea";
10
+ import { VoiceButton } from "./chat-bar/voice-button";
11
+ // Default fallback color scheme
12
+ const DEFAULT_COLOR_SCHEME = {
13
+ gradient: "linear-gradient(45deg, #3b82f6, #8b5cf6, #ec4899)",
14
+ shadow: {
15
+ dark: "rgba(0, 0, 0, 0.2)",
16
+ },
17
+ };
12
18
  const getColorScheme = (themeName, playgroundUid) => {
13
- // If theme is provided, use it directly
14
- if (themeName) {
15
- return getTheme(themeName);
19
+ try {
20
+ // If theme is provided, use it directly
21
+ if (themeName) {
22
+ const theme = getTheme(themeName);
23
+ return theme || DEFAULT_COLOR_SCHEME;
24
+ }
25
+ // Use default theme
26
+ const defaultTheme = getTheme();
27
+ return defaultTheme || DEFAULT_COLOR_SCHEME;
28
+ }
29
+ catch (error) {
30
+ console.warn("Theme system error, using fallback:", error);
31
+ return DEFAULT_COLOR_SCHEME;
16
32
  }
17
- // Use default theme
18
- return getTheme();
19
33
  };
20
- export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSubmit, isStreaming, height, hasPendingEnv, playgroundUid, hasTypingAnimation = false, isSubmitting, onCancel, typingTexts = [
34
+ export const ChatBar = ({ placeholder = "Ask anything...", onSubmit, hasPendingEnv, playgroundUid, isSubmitting, typingTexts = [
21
35
  "Build me an AI chatbot application using OpenAI API",
22
36
  "Build me an ecommerce website using Stripe API",
23
37
  "Build me a price tracking tool using AgentQL API",
@@ -25,31 +39,43 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
25
39
  "Build me a weather forecasting app using OpenWeather API",
26
40
  "Build me a SMS notification system using Twilio API",
27
41
  "Build me a travel booking platform using Skyscanner API",
28
- // "Build me an inventory management system using AWS S3",
29
- // "Build me a social media platform using Firebase",
30
- // "Build me a project management tool using Trello API",
31
- ], shouldFocusOnMount = true, showModelSelector = true, projectUid, theme, }) => {
42
+ ], shouldFocusOnMount = true, showModelSelector = true, projectUid, theme, height = "auto", // Add default for required height prop
43
+ }) => {
44
+ var _a;
32
45
  const [isFocused, setIsFocused] = useState(true);
33
46
  const [isRecording, setIsRecording] = useState(false);
34
47
  const [isTranscribing, setIsTranscribing] = useState(false);
35
48
  const [, setShowVoiceOverlay] = useState(false);
36
49
  const [recordingTimeout, setRecordingTimeout] = useState(null);
37
50
  const [recordingStartTime, setRecordingStartTime] = useState(null);
51
+ const [query, setQuery] = useState("");
38
52
  const mediaRecorderRef = useRef(null);
39
53
  const audioChunksRef = useRef([]);
40
- const fileInputRef = useRef(null);
41
54
  const textareaRef = useRef(null);
42
55
  const [isMounted, setIsMounted] = useState(false);
43
- // Get color scheme for gradient border
44
- const colorScheme = useMemo(() => getColorScheme(theme, playgroundUid), [theme, playgroundUid]);
56
+ // Get color scheme for gradient border with error handling
57
+ const colorScheme = useMemo(() => {
58
+ try {
59
+ return getColorScheme(theme, playgroundUid);
60
+ }
61
+ catch (error) {
62
+ console.warn("Error getting color scheme:", error);
63
+ return DEFAULT_COLOR_SCHEME;
64
+ }
65
+ }, [theme, playgroundUid]);
45
66
  useEffect(() => {
46
67
  setIsMounted(true);
47
68
  }, []);
48
69
  useEffect(() => {
49
70
  // Focus and select all text in the textarea when component mounts
50
71
  if (shouldFocusOnMount && textareaRef.current && isMounted) {
51
- textareaRef.current.focus();
52
- textareaRef.current.select();
72
+ try {
73
+ textareaRef.current.focus();
74
+ textareaRef.current.select();
75
+ }
76
+ catch (error) {
77
+ console.warn("Focus error:", error);
78
+ }
53
79
  }
54
80
  }, [isMounted, shouldFocusOnMount]);
55
81
  const handleFocus = () => {
@@ -62,11 +88,16 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
62
88
  const adjustTextareaHeight = () => {
63
89
  const textarea = textareaRef.current;
64
90
  if (textarea) {
65
- // Reset height to auto to get the correct scrollHeight
66
- textarea.style.height = "auto";
67
- // Set new height based on scrollHeight, with a maximum of 200px
68
- const newHeight = Math.min(textarea.scrollHeight, 200);
69
- textarea.style.height = `${newHeight}px`;
91
+ try {
92
+ // Reset height to auto to get the correct scrollHeight
93
+ textarea.style.height = "auto";
94
+ // Set new height based on scrollHeight, with a maximum of 200px
95
+ const newHeight = Math.min(textarea.scrollHeight, 200);
96
+ textarea.style.height = `${newHeight}px`;
97
+ }
98
+ catch (error) {
99
+ console.warn("Textarea height adjustment error:", error);
100
+ }
70
101
  }
71
102
  };
72
103
  // Update height whenever query changes
@@ -362,8 +393,26 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
362
393
  }
363
394
  }
364
395
  };
396
+ const handleSubmit = (e) => {
397
+ e.preventDefault();
398
+ if (!query.trim()) {
399
+ return;
400
+ }
401
+ try {
402
+ if (playgroundUid) {
403
+ const encodedQuery = encodeURIComponent(query.trim());
404
+ const url = `https://${playgroundUid}.sampleapp.ai?q=${encodedQuery}`;
405
+ window.open(url, "_blank");
406
+ }
407
+ if (onSubmit) {
408
+ onSubmit(e);
409
+ }
410
+ }
411
+ catch (error) {
412
+ console.error("Submit error:", error);
413
+ }
414
+ };
365
415
  return (React.createElement("div", null,
366
- React.createElement(VoiceOverlay, { isRecording: isRecording, isTranscribing: isTranscribing, onDismiss: handleVoiceOverlayDismiss }),
367
416
  React.createElement("div", { style: {
368
417
  position: "relative",
369
418
  padding: "2px",
@@ -373,7 +422,7 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
373
422
  marginRight: "auto",
374
423
  } },
375
424
  React.createElement("div", { style: {
376
- backgroundColor: colorScheme.shadow.dark,
425
+ backgroundColor: ((_a = colorScheme.shadow) === null || _a === void 0 ? void 0 : _a.dark) || "rgba(0, 0, 0, 0.2)",
377
426
  position: "absolute",
378
427
  top: "0",
379
428
  right: "0",
@@ -386,7 +435,7 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
386
435
  pointerEvents: "none",
387
436
  } }),
388
437
  React.createElement("div", { style: {
389
- background: colorScheme.gradient,
438
+ background: colorScheme.gradient || DEFAULT_COLOR_SCHEME.gradient,
390
439
  backgroundSize: "400% 400%",
391
440
  position: "absolute",
392
441
  top: "0",
@@ -402,7 +451,7 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
402
451
  animation: "gradient-bg 5s ease infinite",
403
452
  } }),
404
453
  React.createElement("div", { style: {
405
- background: colorScheme.gradient,
454
+ background: colorScheme.gradient || DEFAULT_COLOR_SCHEME.gradient,
406
455
  backgroundSize: "400% 400%",
407
456
  position: "absolute",
408
457
  top: "0",
@@ -437,7 +486,7 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
437
486
  paddingTop: "4px",
438
487
  paddingBottom: "4px",
439
488
  } },
440
- hasTypingAnimation && typingTexts.length > 0 ? (React.createElement(TypingTextarea, { texts: typingTexts, ref: textareaRef, style: {
489
+ typingTexts.length > 0 ? (React.createElement(TypingTextarea, { texts: typingTexts, ref: textareaRef, style: {
441
490
  flex: 1,
442
491
  width: "100%",
443
492
  border: "none",
@@ -464,8 +513,8 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
464
513
  e.preventDefault();
465
514
  return;
466
515
  }
467
- onSubmit(e);
468
- }, isStreaming: isStreaming, rows: 1 })) : (React.createElement(Textarea, { ref: textareaRef, placeholder: placeholder, style: {
516
+ handleSubmit(e);
517
+ }, rows: 1 })) : (React.createElement(Textarea, { ref: textareaRef, placeholder: placeholder, style: {
469
518
  flex: 1,
470
519
  width: "100%",
471
520
  border: "none",
@@ -492,30 +541,15 @@ export const ChatBar = ({ query, placeholder = "Ask anything...", setQuery, onSu
492
541
  return;
493
542
  }
494
543
  e.preventDefault();
495
- if (isStreaming) {
496
- return;
497
- }
498
- onSubmit(e);
544
+ handleSubmit(e);
499
545
  }
500
546
  }, rows: 1 })),
501
- React.createElement("div", null,
502
- React.createElement(VoiceButton, { isRecording: isRecording, isTranscribing: isTranscribing, onVoiceRecording: handleVoiceRecording, playgroundUid: playgroundUid }),
547
+ React.createElement("div", { style: { display: "flex", flexDirection: "row", gap: "4px" } },
548
+ React.createElement(VoiceButton, { isRecording: isRecording, isTranscribing: isTranscribing, onVoiceRecording: handleVoiceRecording }),
503
549
  React.createElement(Button, { style: {
504
550
  height: "32px",
505
551
  width: "32px",
506
- borderRadius: "6px",
507
- }, disabled: query.length === 0 || isSubmitting || hasPendingEnv, variant: isStreaming ? "outline" : "default", onClick: (e) => {
508
- if (isStreaming && onCancel) {
509
- onCancel();
510
- }
511
- else {
512
- onSubmit(e);
513
- }
514
- } }, isSubmitting ? (React.createElement(Loader2, { style: {
515
- height: "20px",
516
- width: "20px",
517
- animation: "spin 1s linear infinite",
518
- } })) : isStreaming ? (React.createElement(CircleStop, { style: { height: "24px", width: "24px" } })) : (React.createElement(ArrowUp, { style: { height: "20px", width: "20px" } }))))),
552
+ }, disabled: query.length === 0 || isSubmitting || hasPendingEnv, variant: "secondary", onClick: handleSubmit, size: "icon" }, isSubmitting ? (React.createElement(LoaderIcon, { size: 20, style: { animation: "spin 1s linear infinite" } })) : (React.createElement(ArrowUpIcon, { style: { width: "20px", height: "20px" } }))))),
519
553
  React.createElement("div", { style: {
520
554
  display: "flex",
521
555
  alignItems: "center",
@@ -0,0 +1,155 @@
1
+ "use client";
2
+ import React from "react";
3
+ // Loader/Spinner Icon Component
4
+ export const LoaderIcon = ({ size = 20, className = "", style = {}, }) => {
5
+ return (React.createElement(React.Fragment, null,
6
+ React.createElement("style", null, `
7
+ @keyframes icon-spin {
8
+ from { transform: rotate(0deg); }
9
+ to { transform: rotate(360deg); }
10
+ }
11
+ `),
12
+ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: `lucide lucide-loader-circle ${className}`, style: Object.assign({ animation: "icon-spin 1s linear infinite" }, style) },
13
+ React.createElement("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }))));
14
+ };
15
+ // Arrow Up Icon Component
16
+ export const ArrowUpIcon = ({ size = 20, className = "", style = {}, }) => {
17
+ return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: `lucide lucide-arrow-up ${className}`, style: Object.assign({}, style) },
18
+ React.createElement("path", { d: "m5 12 7-7 7 7" }),
19
+ React.createElement("path", { d: "M12 19V5" })));
20
+ };
21
+ export const VoiceIcon = ({ isRecording = false, isTranscribing = false, size = 20, style = {}, }) => {
22
+ const containerStyle = Object.assign({ position: "relative", width: `${size}px`, height: `${Math.floor(size * 0.8)}px`, display: "flex", alignItems: "center", justifyContent: "center" }, style);
23
+ if (isTranscribing) {
24
+ return (React.createElement(React.Fragment, null,
25
+ React.createElement("style", null, `
26
+ @keyframes icon-spin {
27
+ from { transform: rotate(0deg); }
28
+ to { transform: rotate(360deg); }
29
+ }
30
+ `),
31
+ React.createElement("div", { style: containerStyle },
32
+ React.createElement("div", { style: {
33
+ width: `${Math.floor(size * 0.6)}px`,
34
+ height: `${Math.floor(size * 0.6)}px`,
35
+ border: "2px solid currentColor",
36
+ borderTop: "2px solid transparent",
37
+ borderRadius: "50%",
38
+ animation: "icon-spin 1s linear infinite",
39
+ } }))));
40
+ }
41
+ if (isRecording) {
42
+ return (React.createElement(React.Fragment, null,
43
+ React.createElement("style", null, `
44
+ @keyframes icon-pulse {
45
+ 0%, 100% { transform: scale(1); }
46
+ 50% { transform: scale(0.95); }
47
+ }
48
+ `),
49
+ React.createElement("div", { style: containerStyle },
50
+ React.createElement("div", { style: {
51
+ width: `${Math.floor(size * 0.6)}px`,
52
+ height: `${Math.floor(size * 0.6)}px`,
53
+ backgroundColor: "currentColor",
54
+ borderRadius: "2px",
55
+ animation: "icon-pulse 1s ease-in-out infinite",
56
+ } }))));
57
+ }
58
+ // Default voice icon with sound wave animation
59
+ const barWidth = Math.max(1, Math.floor(size * 0.075));
60
+ const gap = Math.max(1, Math.floor(size * 0.1));
61
+ return (React.createElement(React.Fragment, null,
62
+ React.createElement("style", null, `
63
+ @keyframes wave1 {
64
+ 0%, 100% {
65
+ transform: scaleY(0.4);
66
+ opacity: 0.6;
67
+ }
68
+ 50% {
69
+ transform: scaleY(0.8);
70
+ opacity: 0.9;
71
+ }
72
+ }
73
+
74
+ @keyframes wave2 {
75
+ 0%, 100% {
76
+ transform: scaleY(0.5);
77
+ opacity: 0.7;
78
+ }
79
+ 50% {
80
+ transform: scaleY(1);
81
+ opacity: 1;
82
+ }
83
+ }
84
+
85
+ @keyframes wave3 {
86
+ 0%, 100% {
87
+ transform: scaleY(0.6);
88
+ opacity: 0.8;
89
+ }
90
+ 50% {
91
+ transform: scaleY(1);
92
+ opacity: 1;
93
+ }
94
+ }
95
+
96
+ @keyframes wave4 {
97
+ 0%, 100% {
98
+ transform: scaleY(0.5);
99
+ opacity: 0.7;
100
+ }
101
+ 50% {
102
+ transform: scaleY(0.9);
103
+ opacity: 1;
104
+ }
105
+ }
106
+
107
+ @keyframes wave5 {
108
+ 0%, 100% {
109
+ transform: scaleY(0.4);
110
+ opacity: 0.6;
111
+ }
112
+ 50% {
113
+ transform: scaleY(0.7);
114
+ opacity: 0.9;
115
+ }
116
+ }
117
+ `),
118
+ React.createElement("div", { style: containerStyle },
119
+ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: `${gap}px` } },
120
+ React.createElement("div", { style: {
121
+ width: `${barWidth}px`,
122
+ height: `${Math.floor(size * 0.4)}px`,
123
+ backgroundColor: "currentColor",
124
+ borderRadius: "999px",
125
+ animation: "wave1 1.8s ease-in-out infinite",
126
+ } }),
127
+ React.createElement("div", { style: {
128
+ width: `${barWidth}px`,
129
+ height: `${Math.floor(size * 0.6)}px`,
130
+ backgroundColor: "currentColor",
131
+ borderRadius: "999px",
132
+ animation: "wave2 2.1s ease-in-out infinite",
133
+ } }),
134
+ React.createElement("div", { style: {
135
+ width: `${barWidth}px`,
136
+ height: `${Math.floor(size * 0.8)}px`,
137
+ backgroundColor: "currentColor",
138
+ borderRadius: "999px",
139
+ animation: "wave3 1.6s ease-in-out infinite",
140
+ } }),
141
+ React.createElement("div", { style: {
142
+ width: `${barWidth}px`,
143
+ height: `${Math.floor(size * 0.6)}px`,
144
+ backgroundColor: "currentColor",
145
+ borderRadius: "999px",
146
+ animation: "wave4 1.9s ease-in-out infinite",
147
+ } }),
148
+ React.createElement("div", { style: {
149
+ width: `${barWidth}px`,
150
+ height: `${Math.floor(size * 0.4)}px`,
151
+ backgroundColor: "currentColor",
152
+ borderRadius: "999px",
153
+ animation: "wave5 2.2s ease-in-out infinite",
154
+ } })))));
155
+ };
@@ -0,0 +1,51 @@
1
+ // src/components/MinimalChatBar.tsx
2
+ import React, { useState } from "react";
3
+ export const MinimalChatBar = ({ placeholder = "Ask anything...", onSubmit, theme = "light", }) => {
4
+ const [message, setMessage] = useState("");
5
+ const handleSubmit = (e) => {
6
+ e.preventDefault();
7
+ if (message.trim()) {
8
+ onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(message.trim());
9
+ setMessage("");
10
+ }
11
+ };
12
+ return (React.createElement("div", { style: {
13
+ width: "100%",
14
+ maxWidth: "600px",
15
+ margin: "0 auto",
16
+ } },
17
+ React.createElement("form", { onSubmit: handleSubmit, style: {
18
+ display: "flex",
19
+ gap: "8px",
20
+ padding: "12px",
21
+ border: theme === "dark" ? "1px solid #333" : "1px solid #ccc",
22
+ borderRadius: "8px",
23
+ backgroundColor: theme === "dark" ? "#1a1a1a" : "#ffffff",
24
+ boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
25
+ } },
26
+ React.createElement("input", { type: "text", value: message, onChange: (e) => setMessage(e.target.value), placeholder: placeholder, style: {
27
+ flex: 1,
28
+ padding: "8px 12px",
29
+ border: "1px solid #ddd",
30
+ borderRadius: "4px",
31
+ fontSize: "14px",
32
+ outline: "none",
33
+ backgroundColor: theme === "dark" ? "#333" : "#fff",
34
+ color: theme === "dark" ? "#fff" : "#000",
35
+ } }),
36
+ React.createElement("button", { type: "submit", disabled: !message.trim(), style: {
37
+ padding: "8px 16px",
38
+ backgroundColor: message.trim() ? "#007bff" : "#ccc",
39
+ color: "white",
40
+ border: "none",
41
+ borderRadius: "4px",
42
+ cursor: message.trim() ? "pointer" : "not-allowed",
43
+ fontSize: "14px",
44
+ } }, "Send")),
45
+ React.createElement("p", { style: {
46
+ fontSize: "12px",
47
+ color: "#666",
48
+ textAlign: "center",
49
+ marginTop: "8px",
50
+ } }, "SDK Version: @sampleapp.ai/sdk v1.0.25")));
51
+ };