@usecrow/ui 0.1.44 → 0.1.46

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.cjs CHANGED
@@ -149,7 +149,7 @@ function useChat({
149
149
  identity_token: identityToken,
150
150
  model: selectedModel,
151
151
  user_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
152
- user_local_time: (/* @__PURE__ */ new Date()).toLocaleString(),
152
+ user_local_time: (/* @__PURE__ */ new Date()).toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric", hour12: true }),
153
153
  page_path: typeof window !== "undefined" ? window.location.pathname : void 0,
154
154
  context: typeof window !== "undefined" ? window.__crow_page_context : void 0
155
155
  }),
@@ -508,7 +508,7 @@ function useChat({
508
508
  identity_token: identityToken,
509
509
  model: selectedModel,
510
510
  user_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
511
- user_local_time: (/* @__PURE__ */ new Date()).toLocaleString()
511
+ user_local_time: (/* @__PURE__ */ new Date()).toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric", hour12: true })
512
512
  })
513
513
  });
514
514
  if (!response.ok) {
@@ -3483,40 +3483,88 @@ function MessageIcon() {
3483
3483
  }
3484
3484
  );
3485
3485
  }
3486
- function CopilotToggleButton({
3487
- isOpen,
3488
- position,
3489
- onClick
3490
- }) {
3491
- const renderIcon = () => {
3492
- if (!isOpen) return /* @__PURE__ */ jsxRuntime.jsx(MessageIcon, {});
3493
- if (position === "right") return /* @__PURE__ */ jsxRuntime.jsx(ChevronRight2, {});
3494
- return /* @__PURE__ */ jsxRuntime.jsx(ChevronLeft, {});
3495
- };
3496
- return /* @__PURE__ */ jsxRuntime.jsx(
3497
- "button",
3498
- {
3499
- onClick,
3500
- className: `crow-copilot-toggle crow-copilot-toggle-${position} ${isOpen ? "open" : ""}`,
3501
- "aria-label": isOpen ? "Close Copilot" : "Open Copilot",
3502
- title: isOpen ? "Close Copilot" : "Open Copilot",
3503
- children: renderIcon()
3504
- }
3505
- );
3506
- }
3486
+ var CopilotToggleButton = React3.forwardRef(
3487
+ function CopilotToggleButton2({ isOpen, position, onClick, onMouseDown, isDragging }, ref) {
3488
+ const renderIcon = () => {
3489
+ if (!isOpen) return /* @__PURE__ */ jsxRuntime.jsx(MessageIcon, {});
3490
+ if (position === "right") return /* @__PURE__ */ jsxRuntime.jsx(ChevronRight2, {});
3491
+ return /* @__PURE__ */ jsxRuntime.jsx(ChevronLeft, {});
3492
+ };
3493
+ return /* @__PURE__ */ jsxRuntime.jsx(
3494
+ "button",
3495
+ {
3496
+ ref,
3497
+ onClick,
3498
+ onMouseDown,
3499
+ className: `crow-copilot-toggle crow-copilot-toggle-${position} ${isOpen ? "open" : ""} ${isDragging ? "dragging" : ""}`,
3500
+ style: {
3501
+ cursor: isOpen ? "col-resize" : void 0
3502
+ },
3503
+ "aria-label": isOpen ? "Close Copilot" : "Open Copilot",
3504
+ title: isOpen ? "Close Copilot" : "Open Copilot",
3505
+ children: renderIcon()
3506
+ }
3507
+ );
3508
+ }
3509
+ );
3510
+ var DRAG_THRESHOLD = 5;
3511
+ var MIN_WIDTH = 280;
3512
+ var MAX_WIDTH = 800;
3507
3513
  function CopilotContainer({
3508
3514
  position,
3509
- width,
3515
+ width: initialWidth,
3510
3516
  defaultOpen,
3511
3517
  children
3512
3518
  }) {
3513
- const [isOpen, setIsOpen] = React3.useState(defaultOpen);
3519
+ const [isOpen, setIsOpen] = React3.useState(() => {
3520
+ try {
3521
+ const stored = sessionStorage.getItem("crow_copilot_open");
3522
+ if (stored !== null) return stored === "true";
3523
+ } catch {
3524
+ }
3525
+ return defaultOpen;
3526
+ });
3527
+ const [currentWidth, setCurrentWidth] = React3.useState(() => {
3528
+ try {
3529
+ const stored = sessionStorage.getItem("crow_copilot_width");
3530
+ if (stored) {
3531
+ const parsed = parseInt(stored, 10);
3532
+ if (parsed >= MIN_WIDTH && parsed <= MAX_WIDTH) return parsed;
3533
+ }
3534
+ } catch {
3535
+ }
3536
+ return initialWidth;
3537
+ });
3538
+ const [isDragging, setIsDragging] = React3.useState(false);
3539
+ React3.useEffect(() => {
3540
+ try {
3541
+ sessionStorage.setItem("crow_copilot_open", String(isOpen));
3542
+ } catch {
3543
+ }
3544
+ }, [isOpen]);
3545
+ React3.useEffect(() => {
3546
+ try {
3547
+ sessionStorage.setItem("crow_copilot_width", String(currentWidth));
3548
+ } catch {
3549
+ }
3550
+ }, [currentWidth]);
3551
+ const sidebarRef = React3.useRef(null);
3552
+ const toggleRef = React3.useRef(null);
3553
+ const dragStartXRef = React3.useRef(0);
3554
+ const dragStartWidthRef = React3.useRef(0);
3555
+ const hasDraggedRef = React3.useRef(false);
3556
+ const liveWidthRef = React3.useRef(initialWidth);
3557
+ const positionRef = React3.useRef(position);
3558
+ positionRef.current = position;
3559
+ React3.useEffect(() => {
3560
+ liveWidthRef.current = currentWidth;
3561
+ }, [currentWidth]);
3514
3562
  React3.useEffect(() => {
3515
3563
  document.documentElement.style.setProperty(
3516
3564
  "--crow-copilot-width",
3517
- `${width}px`
3565
+ `${currentWidth}px`
3518
3566
  );
3519
- }, [width]);
3567
+ }, [currentWidth]);
3520
3568
  React3.useEffect(() => {
3521
3569
  const className = `crow-copilot-open-${position}`;
3522
3570
  if (isOpen) {
@@ -3538,21 +3586,97 @@ function CopilotContainer({
3538
3586
  delete window.crowCopilot;
3539
3587
  };
3540
3588
  }, []);
3589
+ const handleMouseMove = React3.useCallback(
3590
+ (e) => {
3591
+ const deltaX = e.clientX - dragStartXRef.current;
3592
+ if (!hasDraggedRef.current && Math.abs(deltaX) >= DRAG_THRESHOLD) {
3593
+ hasDraggedRef.current = true;
3594
+ document.body.style.transition = "none";
3595
+ document.body.style.cursor = "col-resize";
3596
+ document.body.style.userSelect = "none";
3597
+ document.body.classList.add("crow-copilot-resizing");
3598
+ if (sidebarRef.current) {
3599
+ sidebarRef.current.style.transition = "none";
3600
+ }
3601
+ if (toggleRef.current) {
3602
+ toggleRef.current.style.transition = "none";
3603
+ }
3604
+ setIsDragging(true);
3605
+ }
3606
+ if (!hasDraggedRef.current) return;
3607
+ const widthDelta = positionRef.current === "right" ? -deltaX : deltaX;
3608
+ const newWidth = Math.min(
3609
+ MAX_WIDTH,
3610
+ Math.max(MIN_WIDTH, dragStartWidthRef.current + widthDelta)
3611
+ );
3612
+ liveWidthRef.current = newWidth;
3613
+ const px = `${newWidth}px`;
3614
+ document.documentElement.style.setProperty("--crow-copilot-width", px);
3615
+ if (sidebarRef.current) {
3616
+ sidebarRef.current.style.width = px;
3617
+ }
3618
+ },
3619
+ []
3620
+ // no deps — we use refs for everything to avoid stale closures
3621
+ );
3622
+ const handleMouseUp = React3.useCallback(() => {
3623
+ document.removeEventListener("mousemove", handleMouseMove);
3624
+ document.removeEventListener("mouseup", handleMouseUp);
3625
+ document.body.style.transition = "";
3626
+ document.body.style.cursor = "";
3627
+ document.body.style.userSelect = "";
3628
+ document.body.classList.remove("crow-copilot-resizing");
3629
+ if (sidebarRef.current) {
3630
+ sidebarRef.current.style.transition = "";
3631
+ }
3632
+ if (toggleRef.current) {
3633
+ toggleRef.current.style.transition = "";
3634
+ }
3635
+ if (hasDraggedRef.current) {
3636
+ setCurrentWidth(liveWidthRef.current);
3637
+ setIsDragging(false);
3638
+ } else {
3639
+ setIsDragging(false);
3640
+ setIsOpen((prev) => !prev);
3641
+ }
3642
+ }, [handleMouseMove]);
3643
+ const handleToggleMouseDown = React3.useCallback(
3644
+ (e) => {
3645
+ if (e.button !== 0 || !isOpen) return;
3646
+ e.preventDefault();
3647
+ e.stopPropagation();
3648
+ dragStartXRef.current = e.clientX;
3649
+ dragStartWidthRef.current = liveWidthRef.current;
3650
+ hasDraggedRef.current = false;
3651
+ document.addEventListener("mousemove", handleMouseMove);
3652
+ document.addEventListener("mouseup", handleMouseUp);
3653
+ },
3654
+ [isOpen, handleMouseMove, handleMouseUp]
3655
+ );
3656
+ const handleToggleClick = React3.useCallback(() => {
3657
+ if (!isOpen) {
3658
+ setIsOpen(true);
3659
+ }
3660
+ }, [isOpen]);
3541
3661
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3542
3662
  /* @__PURE__ */ jsxRuntime.jsx(
3543
3663
  CopilotToggleButton,
3544
3664
  {
3665
+ ref: toggleRef,
3545
3666
  isOpen,
3546
3667
  position,
3547
- onClick: () => setIsOpen((prev) => !prev)
3668
+ onClick: handleToggleClick,
3669
+ onMouseDown: handleToggleMouseDown,
3670
+ isDragging
3548
3671
  }
3549
3672
  ),
3550
3673
  /* @__PURE__ */ jsxRuntime.jsx(
3551
3674
  "div",
3552
3675
  {
3676
+ ref: sidebarRef,
3553
3677
  className: `crow-copilot-sidebar crow-copilot-sidebar-${position} ${isOpen ? "" : "closed"}`,
3554
- style: { width: `${width}px` },
3555
- children: children({ close: () => setIsOpen(false) })
3678
+ style: { width: `${currentWidth}px` },
3679
+ children: children({ close: () => setIsOpen(false), currentWidth })
3556
3680
  }
3557
3681
  )
3558
3682
  ] });
@@ -3635,6 +3759,93 @@ function CrowCopilot({
3635
3759
  window.crow?.("registerTools", autoTools);
3636
3760
  }
3637
3761
  }, [autoTools]);
3762
+ const embeddedInitialWidth = typeof width === "number" ? width : parseInt(String(width), 10) || 400;
3763
+ const [embeddedWidth, setEmbeddedWidth] = React3.useState(() => {
3764
+ try {
3765
+ const stored = sessionStorage.getItem("crow_embedded_width");
3766
+ if (stored) {
3767
+ const parsed = parseInt(stored, 10);
3768
+ if (parsed >= 280 && parsed <= 800) return parsed;
3769
+ }
3770
+ } catch {
3771
+ }
3772
+ return embeddedInitialWidth;
3773
+ });
3774
+ const [isCollapsed, setIsCollapsed] = React3.useState(() => {
3775
+ try {
3776
+ return sessionStorage.getItem("crow_embedded_collapsed") === "true";
3777
+ } catch {
3778
+ return false;
3779
+ }
3780
+ });
3781
+ React3.useEffect(() => {
3782
+ try {
3783
+ sessionStorage.setItem("crow_embedded_width", String(embeddedWidth));
3784
+ } catch {
3785
+ }
3786
+ }, [embeddedWidth]);
3787
+ React3.useEffect(() => {
3788
+ try {
3789
+ sessionStorage.setItem("crow_embedded_collapsed", String(isCollapsed));
3790
+ } catch {
3791
+ }
3792
+ }, [isCollapsed]);
3793
+ const embeddedContentRef = React3.useRef(null);
3794
+ const embeddedToggleRef = React3.useRef(null);
3795
+ const embeddedDragStartX = React3.useRef(0);
3796
+ const embeddedDragStartW = React3.useRef(0);
3797
+ const embeddedHasDragged = React3.useRef(false);
3798
+ const embeddedLiveWidth = React3.useRef(embeddedInitialWidth);
3799
+ const positionRef = React3.useRef(position);
3800
+ positionRef.current = position;
3801
+ React3.useEffect(() => {
3802
+ embeddedLiveWidth.current = embeddedWidth;
3803
+ }, [embeddedWidth]);
3804
+ const embeddedMouseMove = React3.useCallback((e) => {
3805
+ const dx = e.clientX - embeddedDragStartX.current;
3806
+ if (!embeddedHasDragged.current && Math.abs(dx) >= 5) {
3807
+ embeddedHasDragged.current = true;
3808
+ document.body.style.cursor = "col-resize";
3809
+ document.body.style.userSelect = "none";
3810
+ }
3811
+ if (!embeddedHasDragged.current) return;
3812
+ const delta = positionRef.current === "right" ? -dx : dx;
3813
+ const newW = Math.min(800, Math.max(280, embeddedDragStartW.current + delta));
3814
+ embeddedLiveWidth.current = newW;
3815
+ if (embeddedContentRef.current) {
3816
+ embeddedContentRef.current.style.width = `${newW}px`;
3817
+ }
3818
+ }, []);
3819
+ const embeddedMouseUp = React3.useCallback(() => {
3820
+ document.removeEventListener("mousemove", embeddedMouseMove);
3821
+ document.removeEventListener("mouseup", embeddedMouseUp);
3822
+ document.body.style.cursor = "";
3823
+ document.body.style.userSelect = "";
3824
+ if (embeddedHasDragged.current) {
3825
+ setEmbeddedWidth(embeddedLiveWidth.current);
3826
+ } else {
3827
+ setIsCollapsed((prev) => !prev);
3828
+ }
3829
+ }, [embeddedMouseMove]);
3830
+ const embeddedHandleMouseDown = React3.useCallback(
3831
+ (e) => {
3832
+ if (e.button !== 0) return;
3833
+ if (isCollapsed) return;
3834
+ e.preventDefault();
3835
+ e.stopPropagation();
3836
+ embeddedDragStartX.current = e.clientX;
3837
+ embeddedDragStartW.current = embeddedLiveWidth.current;
3838
+ embeddedHasDragged.current = false;
3839
+ document.addEventListener("mousemove", embeddedMouseMove);
3840
+ document.addEventListener("mouseup", embeddedMouseUp);
3841
+ },
3842
+ [isCollapsed, embeddedMouseMove, embeddedMouseUp]
3843
+ );
3844
+ const embeddedHandleClick = React3.useCallback(() => {
3845
+ if (isCollapsed) {
3846
+ setIsCollapsed(false);
3847
+ }
3848
+ }, [isCollapsed]);
3638
3849
  const messagesContainerRef = React3.useRef(null);
3639
3850
  const tabsScrollRef = React3.useRef(null);
3640
3851
  const executeClientToolRef = React3.useRef(null);
@@ -3654,6 +3865,16 @@ function CrowCopilot({
3654
3865
  const conversations = useConversations({ productId, apiUrl });
3655
3866
  const [shouldRestoreHistory, setShouldRestoreHistory] = React3.useState(false);
3656
3867
  const hasRestoredHistoryRef = React3.useRef(false);
3868
+ const activeConvStorageKey = `crow_active_conv_${productId}`;
3869
+ const pendingRestoreConvId = React3.useRef(null);
3870
+ const hasRestoredActiveConvRef = React3.useRef(false);
3871
+ if (pendingRestoreConvId.current === null) {
3872
+ try {
3873
+ pendingRestoreConvId.current = localStorage.getItem(activeConvStorageKey) || "";
3874
+ } catch {
3875
+ pendingRestoreConvId.current = "";
3876
+ }
3877
+ }
3657
3878
  const chat = useChat({
3658
3879
  productId,
3659
3880
  apiUrl,
@@ -3740,6 +3961,32 @@ function CrowCopilot({
3740
3961
  });
3741
3962
  }
3742
3963
  }, [shouldRestoreHistory, chat.conversationId, conversations, chat]);
3964
+ React3.useEffect(() => {
3965
+ if (isLoadingStyles || hasRestoredActiveConvRef.current) return;
3966
+ const timer = setTimeout(() => {
3967
+ if (hasRestoredActiveConvRef.current || isVerifiedUser) return;
3968
+ const savedId = pendingRestoreConvId.current;
3969
+ if (!savedId) return;
3970
+ hasRestoredActiveConvRef.current = true;
3971
+ pendingRestoreConvId.current = "";
3972
+ conversations.loadAnonymousConversationHistory(savedId).then((historyMessages) => {
3973
+ if (historyMessages.length > 0) {
3974
+ chat.loadMessages(historyMessages);
3975
+ chat.setConversationId(savedId);
3976
+ }
3977
+ }).catch(() => {
3978
+ });
3979
+ }, 500);
3980
+ return () => clearTimeout(timer);
3981
+ }, [isLoadingStyles]);
3982
+ React3.useEffect(() => {
3983
+ try {
3984
+ if (chat.conversationId) {
3985
+ localStorage.setItem(activeConvStorageKey, chat.conversationId);
3986
+ }
3987
+ } catch {
3988
+ }
3989
+ }, [chat.conversationId, activeConvStorageKey]);
3743
3990
  React3.useEffect(() => {
3744
3991
  if (variant === "floating") {
3745
3992
  injectCopilotBodyStyles();
@@ -3773,6 +4020,19 @@ function CrowCopilot({
3773
4020
  onIdentified: async () => {
3774
4021
  setIsVerifiedUser(true);
3775
4022
  await conversations.loadConversations();
4023
+ const savedId = pendingRestoreConvId.current;
4024
+ if (savedId && !hasRestoredActiveConvRef.current) {
4025
+ hasRestoredActiveConvRef.current = true;
4026
+ pendingRestoreConvId.current = "";
4027
+ try {
4028
+ const historyMessages = await conversations.loadConversationHistory(savedId);
4029
+ if (historyMessages.length > 0) {
4030
+ chat.loadMessages(historyMessages);
4031
+ chat.setConversationId(savedId);
4032
+ }
4033
+ } catch {
4034
+ }
4035
+ }
3776
4036
  },
3777
4037
  onReset: () => {
3778
4038
  setIsVerifiedUser(false);
@@ -4024,7 +4284,7 @@ function CrowCopilot({
4024
4284
  checkTabsOverflow();
4025
4285
  }, [tabs.length, checkTabsOverflow]);
4026
4286
  const widthStyle = typeof width === "number" ? `${width}px` : width;
4027
- const renderCopilotContent = (overrideOnClose, forceShowClose) => /* @__PURE__ */ jsxRuntime.jsx(
4287
+ const renderCopilotContent = (overrideOnClose, forceShowClose, overrideWidth) => /* @__PURE__ */ jsxRuntime.jsx(
4028
4288
  CopilotStyleProvider,
4029
4289
  {
4030
4290
  styles,
@@ -4035,7 +4295,7 @@ function CrowCopilot({
4035
4295
  {
4036
4296
  className: `crow-flex crow-flex-col crow-h-full ${position === "left" ? "crow-border-r" : "crow-border-l"} ${className || ""}`,
4037
4297
  style: {
4038
- width: widthStyle,
4298
+ width: overrideWidth ? typeof overrideWidth === "number" ? `${overrideWidth}px` : overrideWidth : widthStyle,
4039
4299
  fontFamily: styles.typography.fontFamily,
4040
4300
  fontSize: styles.typography.fontSize,
4041
4301
  fontWeight: styles.typography.fontWeight,
@@ -4267,15 +4527,65 @@ function CrowCopilot({
4267
4527
  }
4268
4528
  );
4269
4529
  const floatingWidth = typeof width === "number" ? width : parseInt(String(width), 10) || 400;
4270
- return /* @__PURE__ */ jsxRuntime.jsx(ShadowContainer, { styles: WIDGET_CSS, children: variant === "floating" ? /* @__PURE__ */ jsxRuntime.jsx(
4271
- CopilotContainer,
4272
- {
4273
- position,
4274
- width: floatingWidth,
4275
- defaultOpen,
4276
- children: ({ close }) => renderCopilotContent(close, true)
4277
- }
4278
- ) : renderCopilotContent() });
4530
+ if (variant === "floating") {
4531
+ return /* @__PURE__ */ jsxRuntime.jsx(ShadowContainer, { styles: WIDGET_CSS, children: /* @__PURE__ */ jsxRuntime.jsx(
4532
+ CopilotContainer,
4533
+ {
4534
+ position,
4535
+ width: floatingWidth,
4536
+ defaultOpen,
4537
+ children: ({ close, currentWidth: resizedWidth }) => renderCopilotContent(close, true, resizedWidth)
4538
+ }
4539
+ ) });
4540
+ }
4541
+ const isRight = position === "right";
4542
+ const edgeSide = isRight ? "left" : "right";
4543
+ const toggleIcon = isCollapsed ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }) }) : /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" }) : /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m15 18-6-6 6-6" }) });
4544
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", flexShrink: 0, height: "100%" }, children: [
4545
+ /* @__PURE__ */ jsxRuntime.jsx(
4546
+ "button",
4547
+ {
4548
+ ref: embeddedToggleRef,
4549
+ onMouseDown: embeddedHandleMouseDown,
4550
+ onClick: embeddedHandleClick,
4551
+ style: {
4552
+ position: "absolute",
4553
+ [edgeSide]: "-12px",
4554
+ top: "50%",
4555
+ transform: "translateY(-50%)",
4556
+ zIndex: 10,
4557
+ width: "24px",
4558
+ height: "64px",
4559
+ display: "flex",
4560
+ alignItems: "center",
4561
+ justifyContent: "center",
4562
+ background: "#fff",
4563
+ border: "1px solid #e5e7eb",
4564
+ [isRight ? "borderRight" : "borderLeft"]: "none",
4565
+ borderRadius: isRight ? "8px 0 0 8px" : "0 8px 8px 0",
4566
+ cursor: isCollapsed ? "pointer" : "col-resize",
4567
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
4568
+ padding: 0,
4569
+ outline: "none"
4570
+ },
4571
+ "aria-label": isCollapsed ? "Open Copilot" : "Resize or close Copilot",
4572
+ children: toggleIcon
4573
+ }
4574
+ ),
4575
+ /* @__PURE__ */ jsxRuntime.jsx(
4576
+ "div",
4577
+ {
4578
+ ref: embeddedContentRef,
4579
+ style: {
4580
+ width: `${embeddedWidth}px`,
4581
+ height: "100%",
4582
+ display: isCollapsed ? "none" : "block",
4583
+ overflow: "hidden"
4584
+ },
4585
+ children: /* @__PURE__ */ jsxRuntime.jsx(ShadowContainer, { styles: WIDGET_CSS, children: renderCopilotContent(void 0, false, "100%") })
4586
+ }
4587
+ )
4588
+ ] });
4279
4589
  }
4280
4590
  function PlusIcon({ className }) {
4281
4591
  return /* @__PURE__ */ jsxRuntime.jsxs(