@kite-copilot/chat-panel 0.2.17 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/auto.cjs CHANGED
@@ -887,7 +887,7 @@ function DataRenderer({ type, data }) {
887
887
  // src/ChatPanel.tsx
888
888
  var import_jsx_runtime9 = require("react/jsx-runtime");
889
889
  var DEFAULT_AGENT_URL = "http://localhost:5002";
890
- var PANEL_WIDTH = 400;
890
+ var PANEL_WIDTH = 340;
891
891
  function renderMarkdown(text) {
892
892
  if (!text) return null;
893
893
  const lines = text.split("\n");
@@ -1266,6 +1266,7 @@ var initialMessages = [];
1266
1266
  function ChatPanel({
1267
1267
  isOpen = true,
1268
1268
  onClose,
1269
+ onOpen,
1269
1270
  onBack,
1270
1271
  onNavigate,
1271
1272
  onActionComplete,
@@ -1367,6 +1368,9 @@ function ChatPanel({
1367
1368
  const [pendingBulkSession, setPendingBulkSession] = React4.useState(null);
1368
1369
  const pendingBulkSessionRef = React4.useRef(null);
1369
1370
  const fileInputRef = React4.useRef(null);
1371
+ const [searchExpanded, setSearchExpanded] = React4.useState(false);
1372
+ const [searchInput, setSearchInput] = React4.useState("");
1373
+ const searchInputRef = React4.useRef(null);
1370
1374
  React4.useEffect(() => {
1371
1375
  if (!activeGuide || activeGuide.id !== "add-api-key" || activeGuide.stepIndex !== 2) {
1372
1376
  return;
@@ -1715,7 +1719,11 @@ function ChatPanel({
1715
1719
  const isRespondingToNotification = lastAssistantMessage?.isNotificationMessage === true;
1716
1720
  const now = Date.now();
1717
1721
  const userMessage = { id: now, role: "user", content: userText };
1718
- setMessages((prev) => [...prev, userMessage]);
1722
+ setMessages(
1723
+ (prev) => prev.map(
1724
+ (m) => m.followups && m.followups.length > 0 ? { ...m, followupSelected: true } : m
1725
+ ).concat(userMessage)
1726
+ );
1719
1727
  if (isRespondingToNotification) {
1720
1728
  const thankYouMessageId = Date.now() + 1;
1721
1729
  const thankYouMessage = {
@@ -2593,6 +2601,81 @@ ${userText}`
2593
2601
  ]);
2594
2602
  }
2595
2603
  }
2604
+ if (!isOpen) {
2605
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fixed bottom-6 left-1/2 -translate-x-1/2 z-50", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `flex items-center gap-3 rounded-xl bg-white border border-gray-200 shadow-lg px-4 py-3 hover:shadow-xl transition-all duration-300 ease-out ${searchExpanded ? "w-[480px]" : "w-[320px]"}`, children: !searchExpanded ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-3 w-full", children: [
2606
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2607
+ "button",
2608
+ {
2609
+ onClick: () => {
2610
+ setSearchExpanded(true);
2611
+ setTimeout(() => searchInputRef.current?.focus(), 100);
2612
+ },
2613
+ className: "flex items-center gap-3 flex-1 group",
2614
+ children: [
2615
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm text-gray-500 flex-1 text-left", children: "Ask a question..." }),
2616
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-xs text-gray-400 font-medium", children: "\u2318I" })
2617
+ ]
2618
+ }
2619
+ ),
2620
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2621
+ "button",
2622
+ {
2623
+ onClick: () => {
2624
+ onOpen?.();
2625
+ },
2626
+ className: "h-7 w-7 rounded-lg bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors",
2627
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" })
2628
+ }
2629
+ )
2630
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2631
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2632
+ "input",
2633
+ {
2634
+ ref: searchInputRef,
2635
+ type: "text",
2636
+ value: searchInput,
2637
+ onChange: (e) => setSearchInput(e.target.value),
2638
+ onKeyDown: (e) => {
2639
+ if (e.key === "Enter" && searchInput.trim()) {
2640
+ e.preventDefault();
2641
+ onOpen?.();
2642
+ startChatFlow(searchInput.trim());
2643
+ setSearchInput("");
2644
+ setSearchExpanded(false);
2645
+ } else if (e.key === "Escape") {
2646
+ setSearchExpanded(false);
2647
+ setSearchInput("");
2648
+ }
2649
+ },
2650
+ onBlur: () => {
2651
+ if (!searchInput.trim()) {
2652
+ setTimeout(() => setSearchExpanded(false), 200);
2653
+ }
2654
+ },
2655
+ placeholder: "Ask a question...",
2656
+ className: "flex-1 text-sm text-gray-700 outline-none bg-transparent"
2657
+ }
2658
+ ),
2659
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
2660
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-xs text-gray-400 font-medium", children: "\u21B5 Enter" }),
2661
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2662
+ "button",
2663
+ {
2664
+ onClick: () => {
2665
+ onOpen?.();
2666
+ if (searchInput.trim()) {
2667
+ setInput(searchInput);
2668
+ }
2669
+ setSearchInput("");
2670
+ setSearchExpanded(false);
2671
+ },
2672
+ className: "h-7 w-7 rounded-lg bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors cursor-pointer",
2673
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" })
2674
+ }
2675
+ )
2676
+ ] })
2677
+ ] }) }) });
2678
+ }
2596
2679
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2597
2680
  "section",
2598
2681
  {
@@ -2640,43 +2723,37 @@ ${userText}`
2640
2723
  {
2641
2724
  className: isEmpty ? "grid flex-1 place-items-center transition-all duration-300" : "flex flex-1 flex-col transition-all duration-300 min-h-0 overflow-hidden",
2642
2725
  children: isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "w-full overflow-y-auto px-4", children: [
2643
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "py-3 transition-all duration-300", children: [
2644
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { className: "text-center text-2xl font-semibold text-gray-900", children: panelView === "folder" ? folders.find((f) => f.id === currentFolderId)?.title || "" : "What can I help with?" }),
2645
- panelView === "landing" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "mt-1 text-center text-xs text-gray-500", children: "Ask me anything about your account" })
2646
- ] }),
2726
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "py-3 transition-all duration-300", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { className: "text-center text-2xl font-semibold text-gray-900", children: panelView === "folder" ? folders.find((f) => f.id === currentFolderId)?.title || "" : "How can I help?" }) }),
2647
2727
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "pb-4 px-4", children: [
2648
- panelView === "landing" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2649
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mb-2 text-[10px] font-semibold uppercase tracking-wider text-gray-400", children: "Suggested Questions" }),
2650
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-col gap-1", children: loadingQuestions ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Loader2, { className: "h-4 w-4 animate-spin text-gray-400" }) }) : startingQuestions.map((question, index) => {
2651
- const iconColors = [
2652
- "bg-blue-400",
2653
- "bg-green-400",
2654
- "bg-purple-400",
2655
- "bg-orange-400",
2656
- "bg-pink-400"
2657
- ];
2658
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2659
- Button,
2660
- {
2661
- type: "button",
2662
- size: "sm",
2663
- variant: "ghost",
2664
- className: "w-full justify-start rounded-lg px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-100 h-auto",
2665
- onClick: () => sendTopic(question.prompt),
2666
- children: [
2667
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2668
- "span",
2669
- {
2670
- className: `mr-2 inline-block h-1.5 w-1.5 rounded-full ${iconColors[index % iconColors.length]}`
2671
- }
2672
- ),
2673
- question.label
2674
- ]
2675
- },
2676
- question.id
2677
- );
2678
- }) })
2679
- ] }),
2728
+ panelView === "landing" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-col gap-1", children: loadingQuestions ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Loader2, { className: "h-4 w-4 animate-spin text-gray-400" }) }) : startingQuestions.map((question, index) => {
2729
+ const iconColors = [
2730
+ "bg-blue-400",
2731
+ "bg-green-400",
2732
+ "bg-purple-400",
2733
+ "bg-orange-400",
2734
+ "bg-pink-400"
2735
+ ];
2736
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2737
+ Button,
2738
+ {
2739
+ type: "button",
2740
+ size: "sm",
2741
+ variant: "ghost",
2742
+ className: "w-full justify-start rounded-lg px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-100 h-auto",
2743
+ onClick: () => sendTopic(question.prompt),
2744
+ children: [
2745
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2746
+ "span",
2747
+ {
2748
+ className: `mr-2 inline-block h-1.5 w-1.5 rounded-full ${iconColors[index % iconColors.length]}`
2749
+ }
2750
+ ),
2751
+ question.label
2752
+ ]
2753
+ },
2754
+ question.id
2755
+ );
2756
+ }) }) }),
2680
2757
  panelView === "folder" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2681
2758
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mb-3 flex items-center gap-2", children: [
2682
2759
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -2727,14 +2804,7 @@ ${userText}`
2727
2804
  return null;
2728
2805
  }
2729
2806
  if (isUser) {
2730
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2731
- "div",
2732
- {
2733
- className: `flex justify-end ${isRoleChange ? "mt-3" : ""}`,
2734
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "max-w-[280px] rounded-2xl rounded-br-md bg-gray-900 px-3.5 py-2.5 text-sm text-white shadow-sm", children: message.content })
2735
- },
2736
- message.id
2737
- );
2807
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `flex justify-end ${isRoleChange ? "mt-3" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "max-w-[260px] rounded-2xl rounded-br-md bg-gray-900 px-3.5 py-2.5 text-sm text-white shadow-sm", children: message.content }) }, message.id);
2738
2808
  }
2739
2809
  if (message.kind === "searchSummary") {
2740
2810
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -3841,10 +3911,14 @@ ${userText}`
3841
3911
  {
3842
3912
  placeholder: pendingFile ? "Describe what to do with this CSV..." : "Ask anything...",
3843
3913
  value: input,
3844
- onChange: (e) => {
3845
- setInput(e.target.value);
3846
- e.target.style.height = "24px";
3847
- e.target.style.height = `${Math.min(120, e.target.scrollHeight)}px`;
3914
+ onChange: (e) => setInput(e.target.value),
3915
+ rows: 1,
3916
+ className: "flex-1 border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 text-sm placeholder:text-gray-400 resize-none overflow-hidden outline-none",
3917
+ style: { minHeight: "20px", maxHeight: "120px" },
3918
+ onInput: (e) => {
3919
+ const target = e.target;
3920
+ target.style.height = "auto";
3921
+ target.style.height = Math.min(target.scrollHeight, 120) + "px";
3848
3922
  },
3849
3923
  onKeyDown: (e) => {
3850
3924
  if (e.key === "Enter" && !e.shiftKey && !e.metaKey && !e.ctrlKey) {
@@ -3914,26 +3988,6 @@ ${userText}`
3914
3988
  }
3915
3989
  );
3916
3990
  }
3917
- function PanelToggle({
3918
- isOpen,
3919
- onClick,
3920
- className = ""
3921
- }) {
3922
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3923
- "button",
3924
- {
3925
- type: "button",
3926
- onClick,
3927
- className: `fixed top-1/2 z-50 flex items-center justify-center w-6 h-16 bg-gray-100 hover:bg-gray-200 border border-gray-200 border-r-0 rounded-l-lg text-gray-600 hover:text-gray-800 shadow-md transition-all duration-300 ${className}`,
3928
- "aria-label": isOpen ? "Close help panel" : "Open help panel",
3929
- style: {
3930
- right: isOpen ? `${PANEL_WIDTH}px` : "0px",
3931
- transform: "translateY(-50%)"
3932
- },
3933
- children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.ChevronRight, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.ChevronLeft, { className: "h-4 w-4" })
3934
- }
3935
- );
3936
- }
3937
3991
  function ChatPanelWithToggle({
3938
3992
  onNavigate,
3939
3993
  onActionComplete,
@@ -3963,22 +4017,20 @@ function ChatPanelWithToggle({
3963
4017
  document.body.style.transition = originalTransition;
3964
4018
  };
3965
4019
  }, [isOpen]);
3966
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3967
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PanelToggle, { isOpen, onClick: () => setIsOpen(!isOpen) }),
3968
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3969
- ChatPanel,
3970
- {
3971
- isOpen,
3972
- onClose: () => setIsOpen(false),
3973
- onNavigate,
3974
- onActionComplete,
3975
- currentPage,
3976
- agentUrl,
3977
- startingQuestions,
3978
- startingQuestionsEndpoint
3979
- }
3980
- )
3981
- ] });
4020
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4021
+ ChatPanel,
4022
+ {
4023
+ isOpen,
4024
+ onClose: () => setIsOpen(false),
4025
+ onOpen: () => setIsOpen(true),
4026
+ onNavigate,
4027
+ onActionComplete,
4028
+ currentPage,
4029
+ agentUrl,
4030
+ startingQuestions,
4031
+ startingQuestionsEndpoint
4032
+ }
4033
+ );
3982
4034
  }
3983
4035
 
3984
4036
  // src/createKiteChat.tsx
package/dist/auto.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-BMLaQQQk.cjs';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-CyoN-YV4.cjs';
2
2
  import 'react/jsx-runtime';
3
3
 
4
4
  /**
package/dist/auto.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-BMLaQQQk.js';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-CyoN-YV4.js';
2
2
  import 'react/jsx-runtime';
3
3
 
4
4
  /**
package/dist/auto.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createKiteChat
3
- } from "./chunk-YUCUEKGB.js";
3
+ } from "./chunk-5SGUG45C.js";
4
4
 
5
5
  // src/auto.ts
6
6
  function mountKiteChat(config) {
@@ -883,24 +883,10 @@ function DataRenderer({ type, data }) {
883
883
 
884
884
  // src/ChatPanel.tsx
885
885
  import * as React4 from "react";
886
- import {
887
- ArrowLeft,
888
- ArrowUp,
889
- Command,
890
- CornerDownLeft,
891
- CheckCircle2 as CheckCircle23,
892
- SquarePen,
893
- Paperclip,
894
- X,
895
- FileSpreadsheet,
896
- Loader2 as Loader22,
897
- ChevronLeft,
898
- ChevronRight,
899
- Sparkles
900
- } from "lucide-react";
886
+ import { ArrowLeft, ArrowUp, Command, CornerDownLeft, CheckCircle2 as CheckCircle23, SquarePen, Paperclip, X, FileSpreadsheet, Loader2 as Loader22, ChevronLeft, ChevronRight, Sparkles } from "lucide-react";
901
887
  import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
902
888
  var DEFAULT_AGENT_URL = "http://localhost:5002";
903
- var PANEL_WIDTH = 400;
889
+ var PANEL_WIDTH = 340;
904
890
  function renderMarkdown(text) {
905
891
  if (!text) return null;
906
892
  const lines = text.split("\n");
@@ -1279,6 +1265,7 @@ var initialMessages = [];
1279
1265
  function ChatPanel({
1280
1266
  isOpen = true,
1281
1267
  onClose,
1268
+ onOpen,
1282
1269
  onBack,
1283
1270
  onNavigate,
1284
1271
  onActionComplete,
@@ -1380,6 +1367,9 @@ function ChatPanel({
1380
1367
  const [pendingBulkSession, setPendingBulkSession] = React4.useState(null);
1381
1368
  const pendingBulkSessionRef = React4.useRef(null);
1382
1369
  const fileInputRef = React4.useRef(null);
1370
+ const [searchExpanded, setSearchExpanded] = React4.useState(false);
1371
+ const [searchInput, setSearchInput] = React4.useState("");
1372
+ const searchInputRef = React4.useRef(null);
1383
1373
  React4.useEffect(() => {
1384
1374
  if (!activeGuide || activeGuide.id !== "add-api-key" || activeGuide.stepIndex !== 2) {
1385
1375
  return;
@@ -1728,7 +1718,11 @@ function ChatPanel({
1728
1718
  const isRespondingToNotification = lastAssistantMessage?.isNotificationMessage === true;
1729
1719
  const now = Date.now();
1730
1720
  const userMessage = { id: now, role: "user", content: userText };
1731
- setMessages((prev) => [...prev, userMessage]);
1721
+ setMessages(
1722
+ (prev) => prev.map(
1723
+ (m) => m.followups && m.followups.length > 0 ? { ...m, followupSelected: true } : m
1724
+ ).concat(userMessage)
1725
+ );
1732
1726
  if (isRespondingToNotification) {
1733
1727
  const thankYouMessageId = Date.now() + 1;
1734
1728
  const thankYouMessage = {
@@ -2606,6 +2600,81 @@ ${userText}`
2606
2600
  ]);
2607
2601
  }
2608
2602
  }
2603
+ if (!isOpen) {
2604
+ return /* @__PURE__ */ jsx9("div", { className: "fixed bottom-6 left-1/2 -translate-x-1/2 z-50", children: /* @__PURE__ */ jsx9("div", { className: `flex items-center gap-3 rounded-xl bg-white border border-gray-200 shadow-lg px-4 py-3 hover:shadow-xl transition-all duration-300 ease-out ${searchExpanded ? "w-[480px]" : "w-[320px]"}`, children: !searchExpanded ? /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3 w-full", children: [
2605
+ /* @__PURE__ */ jsxs5(
2606
+ "button",
2607
+ {
2608
+ onClick: () => {
2609
+ setSearchExpanded(true);
2610
+ setTimeout(() => searchInputRef.current?.focus(), 100);
2611
+ },
2612
+ className: "flex items-center gap-3 flex-1 group",
2613
+ children: [
2614
+ /* @__PURE__ */ jsx9("span", { className: "text-sm text-gray-500 flex-1 text-left", children: "Ask a question..." }),
2615
+ /* @__PURE__ */ jsx9("span", { className: "text-xs text-gray-400 font-medium", children: "\u2318I" })
2616
+ ]
2617
+ }
2618
+ ),
2619
+ /* @__PURE__ */ jsx9(
2620
+ "button",
2621
+ {
2622
+ onClick: () => {
2623
+ onOpen?.();
2624
+ },
2625
+ className: "h-7 w-7 rounded-lg bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors",
2626
+ children: /* @__PURE__ */ jsx9(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" })
2627
+ }
2628
+ )
2629
+ ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2630
+ /* @__PURE__ */ jsx9(
2631
+ "input",
2632
+ {
2633
+ ref: searchInputRef,
2634
+ type: "text",
2635
+ value: searchInput,
2636
+ onChange: (e) => setSearchInput(e.target.value),
2637
+ onKeyDown: (e) => {
2638
+ if (e.key === "Enter" && searchInput.trim()) {
2639
+ e.preventDefault();
2640
+ onOpen?.();
2641
+ startChatFlow(searchInput.trim());
2642
+ setSearchInput("");
2643
+ setSearchExpanded(false);
2644
+ } else if (e.key === "Escape") {
2645
+ setSearchExpanded(false);
2646
+ setSearchInput("");
2647
+ }
2648
+ },
2649
+ onBlur: () => {
2650
+ if (!searchInput.trim()) {
2651
+ setTimeout(() => setSearchExpanded(false), 200);
2652
+ }
2653
+ },
2654
+ placeholder: "Ask a question...",
2655
+ className: "flex-1 text-sm text-gray-700 outline-none bg-transparent"
2656
+ }
2657
+ ),
2658
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
2659
+ /* @__PURE__ */ jsx9("span", { className: "text-xs text-gray-400 font-medium", children: "\u21B5 Enter" }),
2660
+ /* @__PURE__ */ jsx9(
2661
+ "button",
2662
+ {
2663
+ onClick: () => {
2664
+ onOpen?.();
2665
+ if (searchInput.trim()) {
2666
+ setInput(searchInput);
2667
+ }
2668
+ setSearchInput("");
2669
+ setSearchExpanded(false);
2670
+ },
2671
+ className: "h-7 w-7 rounded-lg bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors cursor-pointer",
2672
+ children: /* @__PURE__ */ jsx9(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" })
2673
+ }
2674
+ )
2675
+ ] })
2676
+ ] }) }) });
2677
+ }
2609
2678
  return /* @__PURE__ */ jsxs5(
2610
2679
  "section",
2611
2680
  {
@@ -2653,43 +2722,37 @@ ${userText}`
2653
2722
  {
2654
2723
  className: isEmpty ? "grid flex-1 place-items-center transition-all duration-300" : "flex flex-1 flex-col transition-all duration-300 min-h-0 overflow-hidden",
2655
2724
  children: isEmpty ? /* @__PURE__ */ jsxs5("div", { className: "w-full overflow-y-auto px-4", children: [
2656
- /* @__PURE__ */ jsxs5("div", { className: "py-3 transition-all duration-300", children: [
2657
- /* @__PURE__ */ jsx9("h2", { className: "text-center text-2xl font-semibold text-gray-900", children: panelView === "folder" ? folders.find((f) => f.id === currentFolderId)?.title || "" : "What can I help with?" }),
2658
- panelView === "landing" && /* @__PURE__ */ jsx9("p", { className: "mt-1 text-center text-xs text-gray-500", children: "Ask me anything about your account" })
2659
- ] }),
2725
+ /* @__PURE__ */ jsx9("div", { className: "py-3 transition-all duration-300", children: /* @__PURE__ */ jsx9("h2", { className: "text-center text-2xl font-semibold text-gray-900", children: panelView === "folder" ? folders.find((f) => f.id === currentFolderId)?.title || "" : "How can I help?" }) }),
2660
2726
  /* @__PURE__ */ jsxs5("div", { className: "pb-4 px-4", children: [
2661
- panelView === "landing" && /* @__PURE__ */ jsxs5(Fragment2, { children: [
2662
- /* @__PURE__ */ jsx9("div", { className: "mb-2 text-[10px] font-semibold uppercase tracking-wider text-gray-400", children: "Suggested Questions" }),
2663
- /* @__PURE__ */ jsx9("div", { className: "flex flex-col gap-1", children: loadingQuestions ? /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsx9(Loader22, { className: "h-4 w-4 animate-spin text-gray-400" }) }) : startingQuestions.map((question, index) => {
2664
- const iconColors = [
2665
- "bg-blue-400",
2666
- "bg-green-400",
2667
- "bg-purple-400",
2668
- "bg-orange-400",
2669
- "bg-pink-400"
2670
- ];
2671
- return /* @__PURE__ */ jsxs5(
2672
- Button,
2673
- {
2674
- type: "button",
2675
- size: "sm",
2676
- variant: "ghost",
2677
- className: "w-full justify-start rounded-lg px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-100 h-auto",
2678
- onClick: () => sendTopic(question.prompt),
2679
- children: [
2680
- /* @__PURE__ */ jsx9(
2681
- "span",
2682
- {
2683
- className: `mr-2 inline-block h-1.5 w-1.5 rounded-full ${iconColors[index % iconColors.length]}`
2684
- }
2685
- ),
2686
- question.label
2687
- ]
2688
- },
2689
- question.id
2690
- );
2691
- }) })
2692
- ] }),
2727
+ panelView === "landing" && /* @__PURE__ */ jsx9(Fragment2, { children: /* @__PURE__ */ jsx9("div", { className: "flex flex-col gap-1", children: loadingQuestions ? /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsx9(Loader22, { className: "h-4 w-4 animate-spin text-gray-400" }) }) : startingQuestions.map((question, index) => {
2728
+ const iconColors = [
2729
+ "bg-blue-400",
2730
+ "bg-green-400",
2731
+ "bg-purple-400",
2732
+ "bg-orange-400",
2733
+ "bg-pink-400"
2734
+ ];
2735
+ return /* @__PURE__ */ jsxs5(
2736
+ Button,
2737
+ {
2738
+ type: "button",
2739
+ size: "sm",
2740
+ variant: "ghost",
2741
+ className: "w-full justify-start rounded-lg px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-100 h-auto",
2742
+ onClick: () => sendTopic(question.prompt),
2743
+ children: [
2744
+ /* @__PURE__ */ jsx9(
2745
+ "span",
2746
+ {
2747
+ className: `mr-2 inline-block h-1.5 w-1.5 rounded-full ${iconColors[index % iconColors.length]}`
2748
+ }
2749
+ ),
2750
+ question.label
2751
+ ]
2752
+ },
2753
+ question.id
2754
+ );
2755
+ }) }) }),
2693
2756
  panelView === "folder" && /* @__PURE__ */ jsxs5(Fragment2, { children: [
2694
2757
  /* @__PURE__ */ jsxs5("div", { className: "mb-3 flex items-center gap-2", children: [
2695
2758
  /* @__PURE__ */ jsx9(
@@ -2740,14 +2803,7 @@ ${userText}`
2740
2803
  return null;
2741
2804
  }
2742
2805
  if (isUser) {
2743
- return /* @__PURE__ */ jsx9(
2744
- "div",
2745
- {
2746
- className: `flex justify-end ${isRoleChange ? "mt-3" : ""}`,
2747
- children: /* @__PURE__ */ jsx9("div", { className: "max-w-[280px] rounded-2xl rounded-br-md bg-gray-900 px-3.5 py-2.5 text-sm text-white shadow-sm", children: message.content })
2748
- },
2749
- message.id
2750
- );
2806
+ return /* @__PURE__ */ jsx9("div", { className: `flex justify-end ${isRoleChange ? "mt-3" : ""}`, children: /* @__PURE__ */ jsx9("div", { className: "max-w-[260px] rounded-2xl rounded-br-md bg-gray-900 px-3.5 py-2.5 text-sm text-white shadow-sm", children: message.content }) }, message.id);
2751
2807
  }
2752
2808
  if (message.kind === "searchSummary") {
2753
2809
  return /* @__PURE__ */ jsx9(
@@ -3854,10 +3910,14 @@ ${userText}`
3854
3910
  {
3855
3911
  placeholder: pendingFile ? "Describe what to do with this CSV..." : "Ask anything...",
3856
3912
  value: input,
3857
- onChange: (e) => {
3858
- setInput(e.target.value);
3859
- e.target.style.height = "24px";
3860
- e.target.style.height = `${Math.min(120, e.target.scrollHeight)}px`;
3913
+ onChange: (e) => setInput(e.target.value),
3914
+ rows: 1,
3915
+ className: "flex-1 border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 text-sm placeholder:text-gray-400 resize-none overflow-hidden outline-none",
3916
+ style: { minHeight: "20px", maxHeight: "120px" },
3917
+ onInput: (e) => {
3918
+ const target = e.target;
3919
+ target.style.height = "auto";
3920
+ target.style.height = Math.min(target.scrollHeight, 120) + "px";
3861
3921
  },
3862
3922
  onKeyDown: (e) => {
3863
3923
  if (e.key === "Enter" && !e.shiftKey && !e.metaKey && !e.ctrlKey) {
@@ -3976,22 +4036,20 @@ function ChatPanelWithToggle({
3976
4036
  document.body.style.transition = originalTransition;
3977
4037
  };
3978
4038
  }, [isOpen]);
3979
- return /* @__PURE__ */ jsxs5(Fragment2, { children: [
3980
- /* @__PURE__ */ jsx9(PanelToggle, { isOpen, onClick: () => setIsOpen(!isOpen) }),
3981
- /* @__PURE__ */ jsx9(
3982
- ChatPanel,
3983
- {
3984
- isOpen,
3985
- onClose: () => setIsOpen(false),
3986
- onNavigate,
3987
- onActionComplete,
3988
- currentPage,
3989
- agentUrl,
3990
- startingQuestions,
3991
- startingQuestionsEndpoint
3992
- }
3993
- )
3994
- ] });
4039
+ return /* @__PURE__ */ jsx9(
4040
+ ChatPanel,
4041
+ {
4042
+ isOpen,
4043
+ onClose: () => setIsOpen(false),
4044
+ onOpen: () => setIsOpen(true),
4045
+ onNavigate,
4046
+ onActionComplete,
4047
+ currentPage,
4048
+ agentUrl,
4049
+ startingQuestions,
4050
+ startingQuestionsEndpoint
4051
+ }
4052
+ );
3995
4053
  }
3996
4054
  function HelpButton({ onClick, className = "" }) {
3997
4055
  return /* @__PURE__ */ jsx9(
@@ -87,6 +87,8 @@ interface ChatPanelProps {
87
87
  isOpen?: boolean;
88
88
  /** Callback when the panel should close */
89
89
  onClose?: () => void;
90
+ /** Callback when the panel should open */
91
+ onOpen?: () => void;
90
92
  onBack?: () => void;
91
93
  onNavigate?: (page: Page, subtab?: SettingsTab) => void;
92
94
  onActionComplete?: (actionType: ActionType, data: ActionData) => void;
@@ -97,7 +99,7 @@ interface ChatPanelProps {
97
99
  /** API endpoint to fetch starting questions */
98
100
  startingQuestionsEndpoint?: string;
99
101
  }
100
- declare function ChatPanel({ isOpen, onClose, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
102
+ declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
101
103
  /**
102
104
  * PanelToggle - An arrow button on the right edge that toggles the side panel
103
105
  * Shows left arrow when closed (click to open), right arrow when open (click to close)
@@ -87,6 +87,8 @@ interface ChatPanelProps {
87
87
  isOpen?: boolean;
88
88
  /** Callback when the panel should close */
89
89
  onClose?: () => void;
90
+ /** Callback when the panel should open */
91
+ onOpen?: () => void;
90
92
  onBack?: () => void;
91
93
  onNavigate?: (page: Page, subtab?: SettingsTab) => void;
92
94
  onActionComplete?: (actionType: ActionType, data: ActionData) => void;
@@ -97,7 +99,7 @@ interface ChatPanelProps {
97
99
  /** API endpoint to fetch starting questions */
98
100
  startingQuestionsEndpoint?: string;
99
101
  }
100
- declare function ChatPanel({ isOpen, onClose, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
102
+ declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
101
103
  /**
102
104
  * PanelToggle - An arrow button on the right edge that toggles the side panel
103
105
  * Shows left arrow when closed (click to open), right arrow when open (click to close)