@usecrow/ui 0.1.44 → 0.1.45

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/index.d.cts CHANGED
@@ -1075,13 +1075,24 @@ declare function WidgetHeader({ isVerifiedUser, showConversationList, onNewChat,
1075
1075
 
1076
1076
  /**
1077
1077
  * CopilotToggleButton - Edge toggle button for floating copilot
1078
+ *
1079
+ * Supports dual interaction:
1080
+ * - Click: toggle sidebar open/close
1081
+ * - Drag: resize sidebar width (when open)
1082
+ *
1083
+ * Forwards ref to the <button> so CopilotContainer can directly
1084
+ * manipulate its style.transition during drag for zero-lag resizing.
1078
1085
  */
1079
1086
  interface CopilotToggleButtonProps {
1080
1087
  isOpen: boolean;
1081
1088
  position: "left" | "right";
1082
1089
  onClick: () => void;
1090
+ /** Called on mousedown to initiate potential drag-to-resize */
1091
+ onMouseDown?: (e: React.MouseEvent) => void;
1092
+ /** Whether the user is actively dragging to resize */
1093
+ isDragging?: boolean;
1083
1094
  }
1084
- declare function CopilotToggleButton({ isOpen, position, onClick, }: CopilotToggleButtonProps): react_jsx_runtime.JSX.Element;
1095
+ declare const CopilotToggleButton: react.ForwardRefExoticComponent<CopilotToggleButtonProps & react.RefAttributes<HTMLButtonElement>>;
1085
1096
 
1086
1097
  interface CopilotContainerProps {
1087
1098
  position: "left" | "right";
@@ -1089,8 +1100,9 @@ interface CopilotContainerProps {
1089
1100
  defaultOpen: boolean;
1090
1101
  children: (controls: {
1091
1102
  close: () => void;
1103
+ currentWidth: number;
1092
1104
  }) => ReactNode;
1093
1105
  }
1094
- declare function CopilotContainer({ position, width, defaultOpen, children, }: CopilotContainerProps): react_jsx_runtime.JSX.Element;
1106
+ declare function CopilotContainer({ position, width: initialWidth, defaultOpen, children, }: CopilotContainerProps): react_jsx_runtime.JSX.Element;
1095
1107
 
1096
1108
  export { AVAILABLE_MODELS, type ActiveWorkflow, type AnimationsConfig, CSS_VAR_NAMES, ChatBubble, type Citation, type ClientToolHandler, type ColorsConfig, type Conversation, ConversationList, type CopilotBrandingConfig, CopilotContainer, type CopilotDimensionsConfig, type CopilotPositionConfig, type CopilotStyleConfig, CopilotStyleProvider, CopilotToggleButton, CrowCopilot, type CrowCopilotProps, CrowProvider, CrowWidget, type CrowWidgetProps, DEFAULT_COPILOT_STYLES, DEFAULT_MODEL, DEFAULT_WELCOME_MESSAGE, DEFAULT_WIDGET_STYLES, type IdentifyData, type IdentifyFunction, type JourneyEvent, LoadingHistory, MESSAGES_CONTAINER_ID, type Message, MessageBubble, MessageList, MessagesContainer, type Model, ModelSelector, PoweredByBadge, PromptInputBox, ReasoningTrace, type ResolvedCopilotStyles, type ResolvedWidgetStyles, ShadowContainer, StreamingText, ThinkingIndicator, type ToolCall, type ToolHandler, type ToolRenderers, type ToolsMap, type TypographyConfig, WIDGET_CSS, type WidgetBrandingConfig, type WidgetBubbleConfig, type WidgetConfigResponse, type WidgetDimensionsConfig, WidgetHeader, type WidgetPositionConfig, type WidgetProps, type WidgetShadowsConfig, WidgetShell, type WidgetStyleConfig, WidgetStyleProvider, WorkflowPanel, type WorkflowTodo, clearStyleCache, getCssVar, injectStyles, mergeCopilotStyles, mergeWidgetStyles, stylesToCSSVariables, stylesToCssVars, useChat, useConversations, useCopilotStyleContext, useCopilotStyles$1 as useCopilotStyles, useCopilotStyles as useCopilotStylesContext, useCrowAPI, usePreviewCopilotStyles, usePreviewWidgetStyles, useWidgetStyleContext, useWidgetStyles$1 as useWidgetStyles, useWidgetStyles as useWidgetStylesContext, useWorkflow };
package/dist/index.d.ts CHANGED
@@ -1075,13 +1075,24 @@ declare function WidgetHeader({ isVerifiedUser, showConversationList, onNewChat,
1075
1075
 
1076
1076
  /**
1077
1077
  * CopilotToggleButton - Edge toggle button for floating copilot
1078
+ *
1079
+ * Supports dual interaction:
1080
+ * - Click: toggle sidebar open/close
1081
+ * - Drag: resize sidebar width (when open)
1082
+ *
1083
+ * Forwards ref to the <button> so CopilotContainer can directly
1084
+ * manipulate its style.transition during drag for zero-lag resizing.
1078
1085
  */
1079
1086
  interface CopilotToggleButtonProps {
1080
1087
  isOpen: boolean;
1081
1088
  position: "left" | "right";
1082
1089
  onClick: () => void;
1090
+ /** Called on mousedown to initiate potential drag-to-resize */
1091
+ onMouseDown?: (e: React.MouseEvent) => void;
1092
+ /** Whether the user is actively dragging to resize */
1093
+ isDragging?: boolean;
1083
1094
  }
1084
- declare function CopilotToggleButton({ isOpen, position, onClick, }: CopilotToggleButtonProps): react_jsx_runtime.JSX.Element;
1095
+ declare const CopilotToggleButton: react.ForwardRefExoticComponent<CopilotToggleButtonProps & react.RefAttributes<HTMLButtonElement>>;
1085
1096
 
1086
1097
  interface CopilotContainerProps {
1087
1098
  position: "left" | "right";
@@ -1089,8 +1100,9 @@ interface CopilotContainerProps {
1089
1100
  defaultOpen: boolean;
1090
1101
  children: (controls: {
1091
1102
  close: () => void;
1103
+ currentWidth: number;
1092
1104
  }) => ReactNode;
1093
1105
  }
1094
- declare function CopilotContainer({ position, width, defaultOpen, children, }: CopilotContainerProps): react_jsx_runtime.JSX.Element;
1106
+ declare function CopilotContainer({ position, width: initialWidth, defaultOpen, children, }: CopilotContainerProps): react_jsx_runtime.JSX.Element;
1095
1107
 
1096
1108
  export { AVAILABLE_MODELS, type ActiveWorkflow, type AnimationsConfig, CSS_VAR_NAMES, ChatBubble, type Citation, type ClientToolHandler, type ColorsConfig, type Conversation, ConversationList, type CopilotBrandingConfig, CopilotContainer, type CopilotDimensionsConfig, type CopilotPositionConfig, type CopilotStyleConfig, CopilotStyleProvider, CopilotToggleButton, CrowCopilot, type CrowCopilotProps, CrowProvider, CrowWidget, type CrowWidgetProps, DEFAULT_COPILOT_STYLES, DEFAULT_MODEL, DEFAULT_WELCOME_MESSAGE, DEFAULT_WIDGET_STYLES, type IdentifyData, type IdentifyFunction, type JourneyEvent, LoadingHistory, MESSAGES_CONTAINER_ID, type Message, MessageBubble, MessageList, MessagesContainer, type Model, ModelSelector, PoweredByBadge, PromptInputBox, ReasoningTrace, type ResolvedCopilotStyles, type ResolvedWidgetStyles, ShadowContainer, StreamingText, ThinkingIndicator, type ToolCall, type ToolHandler, type ToolRenderers, type ToolsMap, type TypographyConfig, WIDGET_CSS, type WidgetBrandingConfig, type WidgetBubbleConfig, type WidgetConfigResponse, type WidgetDimensionsConfig, WidgetHeader, type WidgetPositionConfig, type WidgetProps, type WidgetShadowsConfig, WidgetShell, type WidgetStyleConfig, WidgetStyleProvider, WorkflowPanel, type WorkflowTodo, clearStyleCache, getCssVar, injectStyles, mergeCopilotStyles, mergeWidgetStyles, stylesToCSSVariables, stylesToCssVars, useChat, useConversations, useCopilotStyleContext, useCopilotStyles$1 as useCopilotStyles, useCopilotStyles as useCopilotStylesContext, useCrowAPI, usePreviewCopilotStyles, usePreviewWidgetStyles, useWidgetStyleContext, useWidgetStyles$1 as useWidgetStyles, useWidgetStyles as useWidgetStylesContext, useWorkflow };
package/dist/index.js CHANGED
@@ -3457,40 +3457,88 @@ function MessageIcon() {
3457
3457
  }
3458
3458
  );
3459
3459
  }
3460
- function CopilotToggleButton({
3461
- isOpen,
3462
- position,
3463
- onClick
3464
- }) {
3465
- const renderIcon = () => {
3466
- if (!isOpen) return /* @__PURE__ */ jsx(MessageIcon, {});
3467
- if (position === "right") return /* @__PURE__ */ jsx(ChevronRight2, {});
3468
- return /* @__PURE__ */ jsx(ChevronLeft, {});
3469
- };
3470
- return /* @__PURE__ */ jsx(
3471
- "button",
3472
- {
3473
- onClick,
3474
- className: `crow-copilot-toggle crow-copilot-toggle-${position} ${isOpen ? "open" : ""}`,
3475
- "aria-label": isOpen ? "Close Copilot" : "Open Copilot",
3476
- title: isOpen ? "Close Copilot" : "Open Copilot",
3477
- children: renderIcon()
3478
- }
3479
- );
3480
- }
3460
+ var CopilotToggleButton = forwardRef(
3461
+ function CopilotToggleButton2({ isOpen, position, onClick, onMouseDown, isDragging }, ref) {
3462
+ const renderIcon = () => {
3463
+ if (!isOpen) return /* @__PURE__ */ jsx(MessageIcon, {});
3464
+ if (position === "right") return /* @__PURE__ */ jsx(ChevronRight2, {});
3465
+ return /* @__PURE__ */ jsx(ChevronLeft, {});
3466
+ };
3467
+ return /* @__PURE__ */ jsx(
3468
+ "button",
3469
+ {
3470
+ ref,
3471
+ onClick,
3472
+ onMouseDown,
3473
+ className: `crow-copilot-toggle crow-copilot-toggle-${position} ${isOpen ? "open" : ""} ${isDragging ? "dragging" : ""}`,
3474
+ style: {
3475
+ cursor: isOpen ? "col-resize" : void 0
3476
+ },
3477
+ "aria-label": isOpen ? "Close Copilot" : "Open Copilot",
3478
+ title: isOpen ? "Close Copilot" : "Open Copilot",
3479
+ children: renderIcon()
3480
+ }
3481
+ );
3482
+ }
3483
+ );
3484
+ var DRAG_THRESHOLD = 5;
3485
+ var MIN_WIDTH = 280;
3486
+ var MAX_WIDTH = 800;
3481
3487
  function CopilotContainer({
3482
3488
  position,
3483
- width,
3489
+ width: initialWidth,
3484
3490
  defaultOpen,
3485
3491
  children
3486
3492
  }) {
3487
- const [isOpen, setIsOpen] = useState(defaultOpen);
3493
+ const [isOpen, setIsOpen] = useState(() => {
3494
+ try {
3495
+ const stored = sessionStorage.getItem("crow_copilot_open");
3496
+ if (stored !== null) return stored === "true";
3497
+ } catch {
3498
+ }
3499
+ return defaultOpen;
3500
+ });
3501
+ const [currentWidth, setCurrentWidth] = useState(() => {
3502
+ try {
3503
+ const stored = sessionStorage.getItem("crow_copilot_width");
3504
+ if (stored) {
3505
+ const parsed = parseInt(stored, 10);
3506
+ if (parsed >= MIN_WIDTH && parsed <= MAX_WIDTH) return parsed;
3507
+ }
3508
+ } catch {
3509
+ }
3510
+ return initialWidth;
3511
+ });
3512
+ const [isDragging, setIsDragging] = useState(false);
3513
+ useEffect(() => {
3514
+ try {
3515
+ sessionStorage.setItem("crow_copilot_open", String(isOpen));
3516
+ } catch {
3517
+ }
3518
+ }, [isOpen]);
3519
+ useEffect(() => {
3520
+ try {
3521
+ sessionStorage.setItem("crow_copilot_width", String(currentWidth));
3522
+ } catch {
3523
+ }
3524
+ }, [currentWidth]);
3525
+ const sidebarRef = useRef(null);
3526
+ const toggleRef = useRef(null);
3527
+ const dragStartXRef = useRef(0);
3528
+ const dragStartWidthRef = useRef(0);
3529
+ const hasDraggedRef = useRef(false);
3530
+ const liveWidthRef = useRef(initialWidth);
3531
+ const positionRef = useRef(position);
3532
+ positionRef.current = position;
3533
+ useEffect(() => {
3534
+ liveWidthRef.current = currentWidth;
3535
+ }, [currentWidth]);
3488
3536
  useEffect(() => {
3489
3537
  document.documentElement.style.setProperty(
3490
3538
  "--crow-copilot-width",
3491
- `${width}px`
3539
+ `${currentWidth}px`
3492
3540
  );
3493
- }, [width]);
3541
+ }, [currentWidth]);
3494
3542
  useEffect(() => {
3495
3543
  const className = `crow-copilot-open-${position}`;
3496
3544
  if (isOpen) {
@@ -3512,21 +3560,97 @@ function CopilotContainer({
3512
3560
  delete window.crowCopilot;
3513
3561
  };
3514
3562
  }, []);
3563
+ const handleMouseMove = useCallback(
3564
+ (e) => {
3565
+ const deltaX = e.clientX - dragStartXRef.current;
3566
+ if (!hasDraggedRef.current && Math.abs(deltaX) >= DRAG_THRESHOLD) {
3567
+ hasDraggedRef.current = true;
3568
+ document.body.style.transition = "none";
3569
+ document.body.style.cursor = "col-resize";
3570
+ document.body.style.userSelect = "none";
3571
+ document.body.classList.add("crow-copilot-resizing");
3572
+ if (sidebarRef.current) {
3573
+ sidebarRef.current.style.transition = "none";
3574
+ }
3575
+ if (toggleRef.current) {
3576
+ toggleRef.current.style.transition = "none";
3577
+ }
3578
+ setIsDragging(true);
3579
+ }
3580
+ if (!hasDraggedRef.current) return;
3581
+ const widthDelta = positionRef.current === "right" ? -deltaX : deltaX;
3582
+ const newWidth = Math.min(
3583
+ MAX_WIDTH,
3584
+ Math.max(MIN_WIDTH, dragStartWidthRef.current + widthDelta)
3585
+ );
3586
+ liveWidthRef.current = newWidth;
3587
+ const px = `${newWidth}px`;
3588
+ document.documentElement.style.setProperty("--crow-copilot-width", px);
3589
+ if (sidebarRef.current) {
3590
+ sidebarRef.current.style.width = px;
3591
+ }
3592
+ },
3593
+ []
3594
+ // no deps — we use refs for everything to avoid stale closures
3595
+ );
3596
+ const handleMouseUp = useCallback(() => {
3597
+ document.removeEventListener("mousemove", handleMouseMove);
3598
+ document.removeEventListener("mouseup", handleMouseUp);
3599
+ document.body.style.transition = "";
3600
+ document.body.style.cursor = "";
3601
+ document.body.style.userSelect = "";
3602
+ document.body.classList.remove("crow-copilot-resizing");
3603
+ if (sidebarRef.current) {
3604
+ sidebarRef.current.style.transition = "";
3605
+ }
3606
+ if (toggleRef.current) {
3607
+ toggleRef.current.style.transition = "";
3608
+ }
3609
+ if (hasDraggedRef.current) {
3610
+ setCurrentWidth(liveWidthRef.current);
3611
+ setIsDragging(false);
3612
+ } else {
3613
+ setIsDragging(false);
3614
+ setIsOpen((prev) => !prev);
3615
+ }
3616
+ }, [handleMouseMove]);
3617
+ const handleToggleMouseDown = useCallback(
3618
+ (e) => {
3619
+ if (e.button !== 0 || !isOpen) return;
3620
+ e.preventDefault();
3621
+ e.stopPropagation();
3622
+ dragStartXRef.current = e.clientX;
3623
+ dragStartWidthRef.current = liveWidthRef.current;
3624
+ hasDraggedRef.current = false;
3625
+ document.addEventListener("mousemove", handleMouseMove);
3626
+ document.addEventListener("mouseup", handleMouseUp);
3627
+ },
3628
+ [isOpen, handleMouseMove, handleMouseUp]
3629
+ );
3630
+ const handleToggleClick = useCallback(() => {
3631
+ if (!isOpen) {
3632
+ setIsOpen(true);
3633
+ }
3634
+ }, [isOpen]);
3515
3635
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3516
3636
  /* @__PURE__ */ jsx(
3517
3637
  CopilotToggleButton,
3518
3638
  {
3639
+ ref: toggleRef,
3519
3640
  isOpen,
3520
3641
  position,
3521
- onClick: () => setIsOpen((prev) => !prev)
3642
+ onClick: handleToggleClick,
3643
+ onMouseDown: handleToggleMouseDown,
3644
+ isDragging
3522
3645
  }
3523
3646
  ),
3524
3647
  /* @__PURE__ */ jsx(
3525
3648
  "div",
3526
3649
  {
3650
+ ref: sidebarRef,
3527
3651
  className: `crow-copilot-sidebar crow-copilot-sidebar-${position} ${isOpen ? "" : "closed"}`,
3528
- style: { width: `${width}px` },
3529
- children: children({ close: () => setIsOpen(false) })
3652
+ style: { width: `${currentWidth}px` },
3653
+ children: children({ close: () => setIsOpen(false), currentWidth })
3530
3654
  }
3531
3655
  )
3532
3656
  ] });
@@ -3609,6 +3733,93 @@ function CrowCopilot({
3609
3733
  window.crow?.("registerTools", autoTools);
3610
3734
  }
3611
3735
  }, [autoTools]);
3736
+ const embeddedInitialWidth = typeof width === "number" ? width : parseInt(String(width), 10) || 400;
3737
+ const [embeddedWidth, setEmbeddedWidth] = useState(() => {
3738
+ try {
3739
+ const stored = sessionStorage.getItem("crow_embedded_width");
3740
+ if (stored) {
3741
+ const parsed = parseInt(stored, 10);
3742
+ if (parsed >= 280 && parsed <= 800) return parsed;
3743
+ }
3744
+ } catch {
3745
+ }
3746
+ return embeddedInitialWidth;
3747
+ });
3748
+ const [isCollapsed, setIsCollapsed] = useState(() => {
3749
+ try {
3750
+ return sessionStorage.getItem("crow_embedded_collapsed") === "true";
3751
+ } catch {
3752
+ return false;
3753
+ }
3754
+ });
3755
+ useEffect(() => {
3756
+ try {
3757
+ sessionStorage.setItem("crow_embedded_width", String(embeddedWidth));
3758
+ } catch {
3759
+ }
3760
+ }, [embeddedWidth]);
3761
+ useEffect(() => {
3762
+ try {
3763
+ sessionStorage.setItem("crow_embedded_collapsed", String(isCollapsed));
3764
+ } catch {
3765
+ }
3766
+ }, [isCollapsed]);
3767
+ const embeddedContentRef = useRef(null);
3768
+ const embeddedToggleRef = useRef(null);
3769
+ const embeddedDragStartX = useRef(0);
3770
+ const embeddedDragStartW = useRef(0);
3771
+ const embeddedHasDragged = useRef(false);
3772
+ const embeddedLiveWidth = useRef(embeddedInitialWidth);
3773
+ const positionRef = useRef(position);
3774
+ positionRef.current = position;
3775
+ useEffect(() => {
3776
+ embeddedLiveWidth.current = embeddedWidth;
3777
+ }, [embeddedWidth]);
3778
+ const embeddedMouseMove = useCallback((e) => {
3779
+ const dx = e.clientX - embeddedDragStartX.current;
3780
+ if (!embeddedHasDragged.current && Math.abs(dx) >= 5) {
3781
+ embeddedHasDragged.current = true;
3782
+ document.body.style.cursor = "col-resize";
3783
+ document.body.style.userSelect = "none";
3784
+ }
3785
+ if (!embeddedHasDragged.current) return;
3786
+ const delta = positionRef.current === "right" ? -dx : dx;
3787
+ const newW = Math.min(800, Math.max(280, embeddedDragStartW.current + delta));
3788
+ embeddedLiveWidth.current = newW;
3789
+ if (embeddedContentRef.current) {
3790
+ embeddedContentRef.current.style.width = `${newW}px`;
3791
+ }
3792
+ }, []);
3793
+ const embeddedMouseUp = useCallback(() => {
3794
+ document.removeEventListener("mousemove", embeddedMouseMove);
3795
+ document.removeEventListener("mouseup", embeddedMouseUp);
3796
+ document.body.style.cursor = "";
3797
+ document.body.style.userSelect = "";
3798
+ if (embeddedHasDragged.current) {
3799
+ setEmbeddedWidth(embeddedLiveWidth.current);
3800
+ } else {
3801
+ setIsCollapsed((prev) => !prev);
3802
+ }
3803
+ }, [embeddedMouseMove]);
3804
+ const embeddedHandleMouseDown = useCallback(
3805
+ (e) => {
3806
+ if (e.button !== 0) return;
3807
+ if (isCollapsed) return;
3808
+ e.preventDefault();
3809
+ e.stopPropagation();
3810
+ embeddedDragStartX.current = e.clientX;
3811
+ embeddedDragStartW.current = embeddedLiveWidth.current;
3812
+ embeddedHasDragged.current = false;
3813
+ document.addEventListener("mousemove", embeddedMouseMove);
3814
+ document.addEventListener("mouseup", embeddedMouseUp);
3815
+ },
3816
+ [isCollapsed, embeddedMouseMove, embeddedMouseUp]
3817
+ );
3818
+ const embeddedHandleClick = useCallback(() => {
3819
+ if (isCollapsed) {
3820
+ setIsCollapsed(false);
3821
+ }
3822
+ }, [isCollapsed]);
3612
3823
  const messagesContainerRef = useRef(null);
3613
3824
  const tabsScrollRef = useRef(null);
3614
3825
  const executeClientToolRef = useRef(null);
@@ -3628,6 +3839,16 @@ function CrowCopilot({
3628
3839
  const conversations = useConversations({ productId, apiUrl });
3629
3840
  const [shouldRestoreHistory, setShouldRestoreHistory] = useState(false);
3630
3841
  const hasRestoredHistoryRef = useRef(false);
3842
+ const activeConvStorageKey = `crow_active_conv_${productId}`;
3843
+ const pendingRestoreConvId = useRef(null);
3844
+ const hasRestoredActiveConvRef = useRef(false);
3845
+ if (pendingRestoreConvId.current === null) {
3846
+ try {
3847
+ pendingRestoreConvId.current = localStorage.getItem(activeConvStorageKey) || "";
3848
+ } catch {
3849
+ pendingRestoreConvId.current = "";
3850
+ }
3851
+ }
3631
3852
  const chat = useChat({
3632
3853
  productId,
3633
3854
  apiUrl,
@@ -3714,6 +3935,32 @@ function CrowCopilot({
3714
3935
  });
3715
3936
  }
3716
3937
  }, [shouldRestoreHistory, chat.conversationId, conversations, chat]);
3938
+ useEffect(() => {
3939
+ if (isLoadingStyles || hasRestoredActiveConvRef.current) return;
3940
+ const timer = setTimeout(() => {
3941
+ if (hasRestoredActiveConvRef.current || isVerifiedUser) return;
3942
+ const savedId = pendingRestoreConvId.current;
3943
+ if (!savedId) return;
3944
+ hasRestoredActiveConvRef.current = true;
3945
+ pendingRestoreConvId.current = "";
3946
+ conversations.loadAnonymousConversationHistory(savedId).then((historyMessages) => {
3947
+ if (historyMessages.length > 0) {
3948
+ chat.loadMessages(historyMessages);
3949
+ chat.setConversationId(savedId);
3950
+ }
3951
+ }).catch(() => {
3952
+ });
3953
+ }, 500);
3954
+ return () => clearTimeout(timer);
3955
+ }, [isLoadingStyles]);
3956
+ useEffect(() => {
3957
+ try {
3958
+ if (chat.conversationId) {
3959
+ localStorage.setItem(activeConvStorageKey, chat.conversationId);
3960
+ }
3961
+ } catch {
3962
+ }
3963
+ }, [chat.conversationId, activeConvStorageKey]);
3717
3964
  useEffect(() => {
3718
3965
  if (variant === "floating") {
3719
3966
  injectCopilotBodyStyles();
@@ -3747,6 +3994,19 @@ function CrowCopilot({
3747
3994
  onIdentified: async () => {
3748
3995
  setIsVerifiedUser(true);
3749
3996
  await conversations.loadConversations();
3997
+ const savedId = pendingRestoreConvId.current;
3998
+ if (savedId && !hasRestoredActiveConvRef.current) {
3999
+ hasRestoredActiveConvRef.current = true;
4000
+ pendingRestoreConvId.current = "";
4001
+ try {
4002
+ const historyMessages = await conversations.loadConversationHistory(savedId);
4003
+ if (historyMessages.length > 0) {
4004
+ chat.loadMessages(historyMessages);
4005
+ chat.setConversationId(savedId);
4006
+ }
4007
+ } catch {
4008
+ }
4009
+ }
3750
4010
  },
3751
4011
  onReset: () => {
3752
4012
  setIsVerifiedUser(false);
@@ -3998,7 +4258,7 @@ function CrowCopilot({
3998
4258
  checkTabsOverflow();
3999
4259
  }, [tabs.length, checkTabsOverflow]);
4000
4260
  const widthStyle = typeof width === "number" ? `${width}px` : width;
4001
- const renderCopilotContent = (overrideOnClose, forceShowClose) => /* @__PURE__ */ jsx(
4261
+ const renderCopilotContent = (overrideOnClose, forceShowClose, overrideWidth) => /* @__PURE__ */ jsx(
4002
4262
  CopilotStyleProvider,
4003
4263
  {
4004
4264
  styles,
@@ -4009,7 +4269,7 @@ function CrowCopilot({
4009
4269
  {
4010
4270
  className: `crow-flex crow-flex-col crow-h-full ${position === "left" ? "crow-border-r" : "crow-border-l"} ${className || ""}`,
4011
4271
  style: {
4012
- width: widthStyle,
4272
+ width: overrideWidth ? typeof overrideWidth === "number" ? `${overrideWidth}px` : overrideWidth : widthStyle,
4013
4273
  fontFamily: styles.typography.fontFamily,
4014
4274
  fontSize: styles.typography.fontSize,
4015
4275
  fontWeight: styles.typography.fontWeight,
@@ -4241,15 +4501,65 @@ function CrowCopilot({
4241
4501
  }
4242
4502
  );
4243
4503
  const floatingWidth = typeof width === "number" ? width : parseInt(String(width), 10) || 400;
4244
- return /* @__PURE__ */ jsx(ShadowContainer, { styles: WIDGET_CSS, children: variant === "floating" ? /* @__PURE__ */ jsx(
4245
- CopilotContainer,
4246
- {
4247
- position,
4248
- width: floatingWidth,
4249
- defaultOpen,
4250
- children: ({ close }) => renderCopilotContent(close, true)
4251
- }
4252
- ) : renderCopilotContent() });
4504
+ if (variant === "floating") {
4505
+ return /* @__PURE__ */ jsx(ShadowContainer, { styles: WIDGET_CSS, children: /* @__PURE__ */ jsx(
4506
+ CopilotContainer,
4507
+ {
4508
+ position,
4509
+ width: floatingWidth,
4510
+ defaultOpen,
4511
+ children: ({ close, currentWidth: resizedWidth }) => renderCopilotContent(close, true, resizedWidth)
4512
+ }
4513
+ ) });
4514
+ }
4515
+ const isRight = position === "right";
4516
+ const edgeSide = isRight ? "left" : "right";
4517
+ const toggleIcon = isCollapsed ? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#6b7280", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }) }) : /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#6b7280", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: isRight ? /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) : /* @__PURE__ */ jsx("path", { d: "m15 18-6-6 6-6" }) });
4518
+ return /* @__PURE__ */ jsxs("div", { style: { position: "relative", flexShrink: 0, height: "100%" }, children: [
4519
+ /* @__PURE__ */ jsx(
4520
+ "button",
4521
+ {
4522
+ ref: embeddedToggleRef,
4523
+ onMouseDown: embeddedHandleMouseDown,
4524
+ onClick: embeddedHandleClick,
4525
+ style: {
4526
+ position: "absolute",
4527
+ [edgeSide]: "-12px",
4528
+ top: "50%",
4529
+ transform: "translateY(-50%)",
4530
+ zIndex: 10,
4531
+ width: "24px",
4532
+ height: "64px",
4533
+ display: "flex",
4534
+ alignItems: "center",
4535
+ justifyContent: "center",
4536
+ background: "#fff",
4537
+ border: "1px solid #e5e7eb",
4538
+ [isRight ? "borderRight" : "borderLeft"]: "none",
4539
+ borderRadius: isRight ? "8px 0 0 8px" : "0 8px 8px 0",
4540
+ cursor: isCollapsed ? "pointer" : "col-resize",
4541
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
4542
+ padding: 0,
4543
+ outline: "none"
4544
+ },
4545
+ "aria-label": isCollapsed ? "Open Copilot" : "Resize or close Copilot",
4546
+ children: toggleIcon
4547
+ }
4548
+ ),
4549
+ /* @__PURE__ */ jsx(
4550
+ "div",
4551
+ {
4552
+ ref: embeddedContentRef,
4553
+ style: {
4554
+ width: `${embeddedWidth}px`,
4555
+ height: "100%",
4556
+ display: isCollapsed ? "none" : "block",
4557
+ overflow: "hidden"
4558
+ },
4559
+ children: /* @__PURE__ */ jsx(ShadowContainer, { styles: WIDGET_CSS, children: renderCopilotContent(void 0, false, "100%") })
4560
+ }
4561
+ )
4562
+ ] });
4253
4563
  }
4254
4564
  function PlusIcon({ className }) {
4255
4565
  return /* @__PURE__ */ jsxs(