@melony/react 0.1.46 → 0.1.47

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
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React12 = require('react');
3
+ var React3 = require('react');
4
4
  var melony = require('melony');
5
5
  var react = require('nuqs/adapters/react');
6
6
  var reactQuery = require('@tanstack/react-query');
@@ -15,10 +15,10 @@ var useRender = require('@base-ui/react/use-render');
15
15
  var classVarianceAuthority = require('class-variance-authority');
16
16
  var input = require('@base-ui/react/input');
17
17
  var select = require('@base-ui/react/select');
18
+ var reactDom = require('react-dom');
18
19
  var button = require('@base-ui/react/button');
19
20
  var menu = require('@base-ui/react/menu');
20
21
  var nuqs = require('nuqs');
21
- var reactDom = require('react-dom');
22
22
  var reactHotkeysHook = require('react-hotkeys-hook');
23
23
 
24
24
  function _interopNamespace(e) {
@@ -39,7 +39,7 @@ function _interopNamespace(e) {
39
39
  return Object.freeze(n);
40
40
  }
41
41
 
42
- var React12__namespace = /*#__PURE__*/_interopNamespace(React12);
42
+ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
43
43
  var ICONS__namespace = /*#__PURE__*/_interopNamespace(ICONS);
44
44
 
45
45
  // src/providers/melony-provider.tsx
@@ -462,14 +462,14 @@ var List = ({ children, width, className, style }) => {
462
462
  );
463
463
  };
464
464
  var useMelony = (options) => {
465
- const context = React12.useContext(MelonyContext);
465
+ const context = React3.useContext(MelonyContext);
466
466
  if (context === void 0) {
467
467
  throw new Error("useMelony must be used within a MelonyClientProvider");
468
468
  }
469
469
  const { client, reset } = context;
470
470
  const { initialEvents } = options || {};
471
- const prevInitialEventsRef = React12.useRef(void 0);
472
- React12.useEffect(() => {
471
+ const prevInitialEventsRef = React3.useRef(void 0);
472
+ React3.useEffect(() => {
473
473
  const currentSerialized = initialEvents ? JSON.stringify(initialEvents) : void 0;
474
474
  if (currentSerialized !== prevInitialEventsRef.current) {
475
475
  if (initialEvents) {
@@ -555,17 +555,16 @@ var Image = ({
555
555
  src,
556
556
  alt,
557
557
  size = "sm",
558
- groupId,
559
558
  className,
560
559
  style
561
560
  }) => {
562
- const [hasError, setHasError] = React12.useState(false);
563
- const [isLoading, setIsLoading] = React12.useState(true);
564
- const [open, setOpen] = React12.useState(false);
565
- const [currentIndex, setCurrentIndex] = React12.useState(0);
566
- const [gallery, setGallery] = React12.useState([]);
567
- const triggerRef = React12.useRef(null);
568
- React12.useEffect(() => {
561
+ const [hasError, setHasError] = React3.useState(false);
562
+ const [isLoading, setIsLoading] = React3.useState(true);
563
+ const [open, setOpen] = React3.useState(false);
564
+ const [currentIndex, setCurrentIndex] = React3.useState(0);
565
+ const [gallery, setGallery] = React3.useState([]);
566
+ const triggerRef = React3.useRef(null);
567
+ React3.useEffect(() => {
569
568
  if (open && triggerRef.current) {
570
569
  let parent = triggerRef.current.parentElement;
571
570
  while (parent && parent.parentElement && parent.parentElement.children.length === 1) {
@@ -800,7 +799,7 @@ var Chart = ({
800
799
  className,
801
800
  style
802
801
  }) => {
803
- const [tooltip, setTooltip] = React12.useState(null);
802
+ const [tooltip, setTooltip] = React3.useState(null);
804
803
  if (!Array.isArray(data)) {
805
804
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-destructive border border-destructive/20 rounded-md bg-destructive/5", children: "Error: Chart data must be an array" });
806
805
  }
@@ -1447,6 +1446,321 @@ var Checkbox = ({
1447
1446
  var Hidden = ({ name, value }) => {
1448
1447
  return /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value });
1449
1448
  };
1449
+ var PopoverContext = React3__namespace.createContext(
1450
+ void 0
1451
+ );
1452
+ function usePopoverContext() {
1453
+ const context = React3__namespace.useContext(PopoverContext);
1454
+ if (!context) {
1455
+ throw new Error("Popover components must be used within a Popover");
1456
+ }
1457
+ return context;
1458
+ }
1459
+ function Popover({
1460
+ children,
1461
+ defaultOpen = false,
1462
+ open: controlledOpen,
1463
+ onOpenChange
1464
+ }) {
1465
+ const [internalOpen, setInternalOpen] = React3__namespace.useState(defaultOpen);
1466
+ const triggerRef = React3__namespace.useRef(null);
1467
+ const open = controlledOpen ?? internalOpen;
1468
+ const setOpen = React3__namespace.useCallback(
1469
+ (newOpen) => {
1470
+ if (controlledOpen === void 0) {
1471
+ setInternalOpen(newOpen);
1472
+ }
1473
+ onOpenChange?.(newOpen);
1474
+ },
1475
+ [controlledOpen, onOpenChange]
1476
+ );
1477
+ const value = React3__namespace.useMemo(
1478
+ () => ({
1479
+ open,
1480
+ setOpen,
1481
+ triggerRef
1482
+ }),
1483
+ [open, setOpen]
1484
+ );
1485
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value, children });
1486
+ }
1487
+ var PopoverTrigger = React3__namespace.forwardRef(
1488
+ ({ asChild, className, children, ...props }, ref) => {
1489
+ const { setOpen, triggerRef } = usePopoverContext();
1490
+ const handleClick = (e) => {
1491
+ setOpen(true);
1492
+ props.onClick?.(e);
1493
+ };
1494
+ if (asChild && React3__namespace.isValidElement(children)) {
1495
+ return React3__namespace.cloneElement(children, {
1496
+ ref: (node) => {
1497
+ triggerRef.current = node;
1498
+ if (typeof children.ref === "function") {
1499
+ children.ref(node);
1500
+ } else if (children.ref) {
1501
+ children.ref.current = node;
1502
+ }
1503
+ },
1504
+ onClick: handleClick
1505
+ });
1506
+ }
1507
+ return /* @__PURE__ */ jsxRuntime.jsx(
1508
+ "button",
1509
+ {
1510
+ ref: (node) => {
1511
+ triggerRef.current = node;
1512
+ if (typeof ref === "function") {
1513
+ ref(node);
1514
+ } else if (ref) {
1515
+ ref.current = node;
1516
+ }
1517
+ },
1518
+ className,
1519
+ onClick: handleClick,
1520
+ ...props,
1521
+ children
1522
+ }
1523
+ );
1524
+ }
1525
+ );
1526
+ PopoverTrigger.displayName = "PopoverTrigger";
1527
+ var PopoverContent = React3__namespace.forwardRef(
1528
+ ({
1529
+ className,
1530
+ side = "bottom",
1531
+ align = "start",
1532
+ sideOffset = 4,
1533
+ alignOffset = 0,
1534
+ children,
1535
+ ...props
1536
+ }, ref) => {
1537
+ const { open, setOpen, triggerRef } = usePopoverContext();
1538
+ const [position, setPosition] = React3__namespace.useState({ top: 0, left: 0 });
1539
+ const contentRef = React3__namespace.useRef(null);
1540
+ React3__namespace.useEffect(() => {
1541
+ if (!open || !triggerRef.current) return;
1542
+ const updatePosition = () => {
1543
+ if (!triggerRef.current || !contentRef.current) return;
1544
+ const triggerRect = triggerRef.current.getBoundingClientRect();
1545
+ const contentRect = contentRef.current.getBoundingClientRect();
1546
+ const scrollX = window.scrollX;
1547
+ const scrollY = window.scrollY;
1548
+ let top = 0;
1549
+ let left = 0;
1550
+ switch (side) {
1551
+ case "bottom":
1552
+ top = triggerRect.bottom + sideOffset + scrollY;
1553
+ break;
1554
+ case "top":
1555
+ top = triggerRect.top - contentRect.height - sideOffset + scrollY;
1556
+ break;
1557
+ case "right":
1558
+ top = triggerRect.top + scrollY;
1559
+ left = triggerRect.right + sideOffset + scrollX;
1560
+ break;
1561
+ case "left":
1562
+ top = triggerRect.top + scrollY;
1563
+ left = triggerRect.left - contentRect.width - sideOffset + scrollX;
1564
+ break;
1565
+ }
1566
+ switch (align) {
1567
+ case "start":
1568
+ if (side === "top" || side === "bottom") {
1569
+ left = triggerRect.left + scrollX + alignOffset;
1570
+ } else {
1571
+ top += alignOffset;
1572
+ }
1573
+ break;
1574
+ case "center":
1575
+ if (side === "top" || side === "bottom") {
1576
+ left = triggerRect.left + triggerRect.width / 2 - contentRect.width / 2 + scrollX + alignOffset;
1577
+ } else {
1578
+ top += triggerRect.height / 2 - contentRect.height / 2 + alignOffset;
1579
+ }
1580
+ break;
1581
+ case "end":
1582
+ if (side === "top" || side === "bottom") {
1583
+ left = triggerRect.left + triggerRect.width - contentRect.width + scrollX + alignOffset;
1584
+ } else {
1585
+ top += triggerRect.height - contentRect.height + alignOffset;
1586
+ }
1587
+ break;
1588
+ }
1589
+ setPosition({ top, left });
1590
+ };
1591
+ requestAnimationFrame(() => {
1592
+ updatePosition();
1593
+ });
1594
+ window.addEventListener("resize", updatePosition);
1595
+ window.addEventListener("scroll", updatePosition, true);
1596
+ return () => {
1597
+ window.removeEventListener("resize", updatePosition);
1598
+ window.removeEventListener("scroll", updatePosition, true);
1599
+ };
1600
+ }, [open, side, align, sideOffset, alignOffset, triggerRef]);
1601
+ React3__namespace.useEffect(() => {
1602
+ if (!open) return;
1603
+ const handleClickOutside = (event) => {
1604
+ if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
1605
+ setOpen(false);
1606
+ }
1607
+ };
1608
+ const handleEscape = (event) => {
1609
+ if (event.key === "Escape") {
1610
+ setOpen(false);
1611
+ }
1612
+ };
1613
+ document.addEventListener("mousedown", handleClickOutside);
1614
+ document.addEventListener("keydown", handleEscape);
1615
+ return () => {
1616
+ document.removeEventListener("mousedown", handleClickOutside);
1617
+ document.removeEventListener("keydown", handleEscape);
1618
+ };
1619
+ }, [open, setOpen, triggerRef]);
1620
+ if (!open) return null;
1621
+ const content = /* @__PURE__ */ jsxRuntime.jsx(
1622
+ "div",
1623
+ {
1624
+ ref: (node) => {
1625
+ contentRef.current = node;
1626
+ if (typeof ref === "function") {
1627
+ ref(node);
1628
+ } else if (ref) {
1629
+ ref.current = node;
1630
+ }
1631
+ },
1632
+ className: cn(
1633
+ "bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/5 rounded-2xl shadow-2xl ring-1 z-50 min-w-48 max-h-96 overflow-hidden",
1634
+ className
1635
+ ),
1636
+ style: {
1637
+ position: "absolute",
1638
+ top: `${position.top}px`,
1639
+ left: `${position.left}px`
1640
+ },
1641
+ ...props,
1642
+ children
1643
+ }
1644
+ );
1645
+ return reactDom.createPortal(content, document.body);
1646
+ }
1647
+ );
1648
+ PopoverContent.displayName = "PopoverContent";
1649
+ var PRESET_COLORS = [
1650
+ "#000000",
1651
+ "#ffffff",
1652
+ "#f44336",
1653
+ "#e91e63",
1654
+ "#9c27b0",
1655
+ "#673ab7",
1656
+ "#3f51b5",
1657
+ "#2196f3",
1658
+ "#03a9f4",
1659
+ "#00bcd4",
1660
+ "#009688",
1661
+ "#4caf50",
1662
+ "#8bc34a",
1663
+ "#cddc39",
1664
+ "#ffeb3b",
1665
+ "#ffc107",
1666
+ "#ff9800",
1667
+ "#ff5722",
1668
+ "#795548",
1669
+ "#9e9e9e",
1670
+ "#607d8b"
1671
+ ];
1672
+ var ColorPicker = ({
1673
+ name,
1674
+ label,
1675
+ defaultValue = "#000000",
1676
+ value: controlledValue,
1677
+ onChangeAction,
1678
+ disabled,
1679
+ className,
1680
+ style
1681
+ }) => {
1682
+ const { sendEvent } = useMelony();
1683
+ const [color, setColor] = React3.useState(controlledValue || defaultValue);
1684
+ React3.useEffect(() => {
1685
+ if (controlledValue !== void 0) {
1686
+ setColor(controlledValue);
1687
+ }
1688
+ }, [controlledValue]);
1689
+ const handleColorChange = (newColor) => {
1690
+ setColor(newColor);
1691
+ if (onChangeAction) {
1692
+ sendEvent({
1693
+ ...onChangeAction,
1694
+ data: {
1695
+ name: name || "",
1696
+ value: newColor
1697
+ }
1698
+ });
1699
+ }
1700
+ };
1701
+ return /* @__PURE__ */ jsxRuntime.jsxs(Field, { className: cn("w-full", className), style, children: [
1702
+ label && /* @__PURE__ */ jsxRuntime.jsx(FieldTitle, { children: label }),
1703
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1704
+ /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
1705
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1706
+ "button",
1707
+ {
1708
+ type: "button",
1709
+ disabled,
1710
+ className: cn(
1711
+ "w-10 h-10 rounded-lg border border-border shadow-sm transition-transform hover:scale-105 active:scale-95 disabled:opacity-50 disabled:hover:scale-100",
1712
+ "flex items-center justify-center p-1"
1713
+ ),
1714
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1715
+ "div",
1716
+ {
1717
+ className: "w-full h-full rounded-md",
1718
+ style: { backgroundColor: color }
1719
+ }
1720
+ )
1721
+ }
1722
+ ) }),
1723
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "p-3 w-64", side: "bottom", align: "start", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
1724
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-1", children: PRESET_COLORS.map((preset) => /* @__PURE__ */ jsxRuntime.jsx(
1725
+ "button",
1726
+ {
1727
+ type: "button",
1728
+ className: cn(
1729
+ "w-6 h-6 rounded-md border border-border transition-transform hover:scale-110 active:scale-90",
1730
+ color === preset && "ring-2 ring-primary ring-offset-1"
1731
+ ),
1732
+ style: { backgroundColor: preset },
1733
+ onClick: () => handleColorChange(preset)
1734
+ },
1735
+ preset
1736
+ )) }),
1737
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
1738
+ /* @__PURE__ */ jsxRuntime.jsx(
1739
+ "input",
1740
+ {
1741
+ type: "color",
1742
+ value: color,
1743
+ onChange: (e) => handleColorChange(e.target.value),
1744
+ className: "w-8 h-8 rounded border-none p-0 cursor-pointer"
1745
+ }
1746
+ ),
1747
+ /* @__PURE__ */ jsxRuntime.jsx(
1748
+ "input",
1749
+ {
1750
+ type: "text",
1751
+ value: color,
1752
+ onChange: (e) => handleColorChange(e.target.value),
1753
+ className: "flex-1 h-8 px-2 text-xs font-mono border border-border rounded uppercase focus:outline-none focus:ring-1 focus:ring-primary"
1754
+ }
1755
+ )
1756
+ ] })
1757
+ ] }) })
1758
+ ] }),
1759
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-mono uppercase text-muted-foreground", children: color })
1760
+ ] }),
1761
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: color })
1762
+ ] });
1763
+ };
1450
1764
  var RadioGroup = ({
1451
1765
  name,
1452
1766
  options,
@@ -1612,12 +1926,19 @@ var Upload = ({
1612
1926
  accept,
1613
1927
  onUploadAction,
1614
1928
  className,
1615
- style
1929
+ style,
1930
+ initialFiles,
1931
+ mode = "append"
1616
1932
  }) => {
1617
1933
  const { sendEvent, events } = useMelony();
1618
- const fileInputRef = React12.useRef(null);
1619
- const [isUploading, setIsUploading] = React12.useState(false);
1620
- const [status, setStatus] = React12.useState("idle");
1934
+ const fileInputRef = React3.useRef(null);
1935
+ const [isUploading, setIsUploading] = React3.useState(false);
1936
+ const [status, setStatus] = React3.useState("idle");
1937
+ const uploadedFilesEvents = events.filter(
1938
+ (event) => event.type === "uploaded-files"
1939
+ );
1940
+ const displayEvents = mode === "replace" && uploadedFilesEvents.length > 0 ? [uploadedFilesEvents[uploadedFilesEvents.length - 1]] : uploadedFilesEvents;
1941
+ const showInitialFiles = mode === "replace" ? displayEvents.length === 0 : true;
1621
1942
  const handleFileChange = async (e) => {
1622
1943
  const files = Array.from(e.target.files || []);
1623
1944
  if (files.length === 0) return;
@@ -1690,23 +2011,26 @@ var Upload = ({
1690
2011
  disabled: isUploading
1691
2012
  }
1692
2013
  ),
1693
- events.filter((event) => event.type === "files-uploaded" && !!event.ui).map(
1694
- (event, index) => event.ui ? /* @__PURE__ */ jsxRuntime.jsx(UIRenderer, { node: event.ui }, index) : null
1695
- ),
1696
- /* @__PURE__ */ jsxRuntime.jsxs(
1697
- Button,
1698
- {
1699
- type: "button",
1700
- disabled: isUploading,
1701
- onClick: () => fileInputRef.current?.click(),
1702
- className: "gap-2",
1703
- variant: status === "error" ? "destructive" : status === "success" ? "outline" : "default",
1704
- children: [
1705
- isUploading ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "h-4 w-4 animate-spin" }) : status === "success" ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconCheck, { className: "h-4 w-4 text-green-500" }) : status === "error" ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUpload, { className: "h-4 w-4" }),
1706
- status === "success" ? "Uploaded" : status === "error" ? "Failed" : label
1707
- ]
1708
- }
1709
- )
2014
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2 mb-2 items-center", children: [
2015
+ showInitialFiles && initialFiles?.map((file, index) => /* @__PURE__ */ jsxRuntime.jsx(Image, { src: file.url, alt: file.name, size: "md" }, index)),
2016
+ displayEvents.map(
2017
+ (event, index) => event.ui ? /* @__PURE__ */ jsxRuntime.jsx(UIRenderer, { node: event.ui }, index) : null
2018
+ ),
2019
+ /* @__PURE__ */ jsxRuntime.jsxs(
2020
+ Button,
2021
+ {
2022
+ type: "button",
2023
+ disabled: isUploading,
2024
+ onClick: () => fileInputRef.current?.click(),
2025
+ className: "gap-2",
2026
+ variant: status === "error" ? "destructive" : status === "success" ? "outline" : "default",
2027
+ children: [
2028
+ isUploading ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "h-4 w-4 animate-spin" }) : status === "success" ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconCheck, { className: "h-4 w-4 text-green-500" }) : status === "error" ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUpload, { className: "h-4 w-4" }),
2029
+ status === "success" ? "Uploaded" : status === "error" ? "Failed" : label
2030
+ ]
2031
+ }
2032
+ )
2033
+ ] })
1710
2034
  ] });
1711
2035
  };
1712
2036
  var Form = ({
@@ -1716,7 +2040,7 @@ var Form = ({
1716
2040
  style
1717
2041
  }) => {
1718
2042
  const { sendEvent } = useMelony();
1719
- const [isSubmitted, setIsSubmitted] = React12.useState(false);
2043
+ const [isSubmitted, setIsSubmitted] = React3.useState(false);
1720
2044
  const handleSubmit = (e) => {
1721
2045
  e.preventDefault();
1722
2046
  if (isSubmitted) return;
@@ -1775,6 +2099,7 @@ function UIRenderer({ node }) {
1775
2099
  select: Select2,
1776
2100
  checkbox: Checkbox,
1777
2101
  radioGroup: RadioGroup,
2102
+ colorPicker: ColorPicker,
1778
2103
  spacer: Spacer,
1779
2104
  divider: Divider,
1780
2105
  box: Box,
@@ -1799,7 +2124,7 @@ function UIRenderer({ node }) {
1799
2124
  const componentProps = { ...props };
1800
2125
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...componentProps, children: renderedChildren });
1801
2126
  }
1802
- var MelonyContext = React12.createContext(
2127
+ var MelonyContext = React3.createContext(
1803
2128
  void 0
1804
2129
  );
1805
2130
  var defaultQueryClient = new reactQuery.QueryClient({
@@ -1816,31 +2141,31 @@ var MelonyContextProviderInner = ({
1816
2141
  initialEvents,
1817
2142
  setContextValue
1818
2143
  }) => {
1819
- const [state, setState] = React12.useState(client.getState());
2144
+ const [state, setState] = React3.useState(client.getState());
1820
2145
  const queryClient = reactQuery.useQueryClient();
1821
- const [dialog, setDialog] = React12.useState();
2146
+ const [dialog, setDialog] = React3.useState();
1822
2147
  const { data: config } = reactQuery.useQuery({
1823
2148
  queryKey: ["melony-config", client.url],
1824
2149
  queryFn: () => client.getConfig(),
1825
2150
  staleTime: Infinity
1826
2151
  });
1827
- React12.useEffect(() => {
2152
+ React3.useEffect(() => {
1828
2153
  if (initialEvents && initialEvents.length > 0 && client.getState().events.length === 0) {
1829
2154
  client.reset(initialEvents);
1830
2155
  }
1831
2156
  }, [client, initialEvents]);
1832
- React12.useEffect(() => {
2157
+ React3.useEffect(() => {
1833
2158
  setState(client.getState());
1834
2159
  const unsubscribe = client.subscribe(setState);
1835
2160
  return () => {
1836
2161
  unsubscribe();
1837
2162
  };
1838
2163
  }, [client]);
1839
- const reset = React12.useCallback(
2164
+ const reset = React3.useCallback(
1840
2165
  (events) => client.reset(events),
1841
2166
  [client]
1842
2167
  );
1843
- const dispatchClientAction = React12.useCallback(
2168
+ const dispatchClientAction = React3.useCallback(
1844
2169
  async (event) => {
1845
2170
  if (!event.type.startsWith("client:")) return false;
1846
2171
  switch (event.type) {
@@ -1896,7 +2221,7 @@ var MelonyContextProviderInner = ({
1896
2221
  },
1897
2222
  [client, reset, queryClient]
1898
2223
  );
1899
- const sendEvent = React12.useCallback(
2224
+ const sendEvent = React3.useCallback(
1900
2225
  async (event) => {
1901
2226
  const handled = await dispatchClientAction(event);
1902
2227
  if (handled) return;
@@ -1907,7 +2232,7 @@ var MelonyContextProviderInner = ({
1907
2232
  },
1908
2233
  [client, dispatchClientAction]
1909
2234
  );
1910
- const value = React12.useMemo(
2235
+ const value = React3.useMemo(
1911
2236
  () => ({
1912
2237
  ...state,
1913
2238
  messages: melony.convertEventsToMessages(state.events),
@@ -1918,7 +2243,7 @@ var MelonyContextProviderInner = ({
1918
2243
  }),
1919
2244
  [state, sendEvent, reset, client, config]
1920
2245
  );
1921
- React12.useEffect(() => {
2246
+ React3.useEffect(() => {
1922
2247
  setContextValue(value);
1923
2248
  }, [value, setContextValue]);
1924
2249
  return /* @__PURE__ */ jsxRuntime.jsxs(react.NuqsAdapter, { children: [
@@ -1951,7 +2276,7 @@ var MelonyProvider = ({
1951
2276
  initialEvents,
1952
2277
  queryClient = defaultQueryClient
1953
2278
  }) => {
1954
- const [contextValue, setContextValue] = React12.useState(void 0);
2279
+ const [contextValue, setContextValue] = React3.useState(void 0);
1955
2280
  return /* @__PURE__ */ jsxRuntime.jsx(MelonyContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntime.jsx(
1956
2281
  MelonyContextProviderInner,
1957
2282
  {
@@ -1963,7 +2288,7 @@ var MelonyProvider = ({
1963
2288
  ) }) });
1964
2289
  };
1965
2290
  var useAuth = () => {
1966
- const context = React12.useContext(AuthContext);
2291
+ const context = React3.useContext(AuthContext);
1967
2292
  if (context === void 0) {
1968
2293
  throw new Error("useAuth must be used within an AuthProvider");
1969
2294
  }
@@ -2092,10 +2417,10 @@ var AccountButton = ({
2092
2417
  size
2093
2418
  }) => {
2094
2419
  const { isLoading, isAuthenticated, user, login, logout } = useAuth();
2095
- const [open, setOpen] = React12__namespace.useState(false);
2096
- const [accountInfoOpen, setAccountInfoOpen] = React12__namespace.useState(false);
2097
- const [error, setError] = React12__namespace.useState(null);
2098
- const initials = React12__namespace.useMemo(() => {
2420
+ const [open, setOpen] = React3__namespace.useState(false);
2421
+ const [accountInfoOpen, setAccountInfoOpen] = React3__namespace.useState(false);
2422
+ const [error, setError] = React3__namespace.useState(null);
2423
+ const initials = React3__namespace.useMemo(() => {
2099
2424
  const name = user?.displayName || user?.name;
2100
2425
  if (!name) return "";
2101
2426
  return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
@@ -2332,7 +2657,7 @@ function WelcomeScreen({
2332
2657
  }
2333
2658
  );
2334
2659
  }
2335
- var AuthContext = React12.createContext(
2660
+ var AuthContext = React3.createContext(
2336
2661
  void 0
2337
2662
  );
2338
2663
  var AuthProvider = ({
@@ -2352,10 +2677,10 @@ var AuthProvider = ({
2352
2677
  queryClient.setQueryData(["auth-user", service], null);
2353
2678
  }
2354
2679
  });
2355
- const login = React12.useCallback(() => {
2680
+ const login = React3.useCallback(() => {
2356
2681
  service.login();
2357
2682
  }, [service]);
2358
- const logout = React12.useCallback(async () => {
2683
+ const logout = React3.useCallback(async () => {
2359
2684
  try {
2360
2685
  await logoutMutation.mutateAsync();
2361
2686
  } catch (error) {
@@ -2390,7 +2715,7 @@ var AuthProvider = ({
2390
2715
  };
2391
2716
  return /* @__PURE__ */ jsxRuntime.jsx(AuthContext.Provider, { value, children: !value.isAuthenticated && welcomeScreenProps ? /* @__PURE__ */ jsxRuntime.jsx(WelcomeScreen, { ...welcomeScreenProps }) : children });
2392
2717
  };
2393
- var ThreadContext = React12.createContext(
2718
+ var ThreadContext = React3.createContext(
2394
2719
  void 0
2395
2720
  );
2396
2721
  var ThreadProvider = ({
@@ -2399,16 +2724,16 @@ var ThreadProvider = ({
2399
2724
  initialThreadId: providedInitialThreadId
2400
2725
  }) => {
2401
2726
  const queryClient = reactQuery.useQueryClient();
2402
- const melonyContext = React12.useContext(MelonyContext);
2727
+ const melonyContext = React3.useContext(MelonyContext);
2403
2728
  const [activeThreadId, setActiveThreadId] = nuqs.useQueryState(
2404
2729
  "threadId",
2405
2730
  nuqs.parseAsString
2406
2731
  );
2407
- const prevActiveThreadIdRef = React12.useRef(activeThreadId);
2408
- React12.useEffect(() => {
2732
+ const prevActiveThreadIdRef = React3.useRef(activeThreadId);
2733
+ React3.useEffect(() => {
2409
2734
  prevActiveThreadIdRef.current = activeThreadId;
2410
2735
  }, [activeThreadId]);
2411
- React12.useEffect(() => {
2736
+ React3.useEffect(() => {
2412
2737
  if (!activeThreadId && providedInitialThreadId) {
2413
2738
  setActiveThreadId(providedInitialThreadId);
2414
2739
  }
@@ -2424,7 +2749,7 @@ var ThreadProvider = ({
2424
2749
  queryFn: () => service.getThreads(),
2425
2750
  staleTime: prevActiveThreadIdRef.current === null && activeThreadId !== null ? Infinity : 0
2426
2751
  });
2427
- const isNewThread = React12.useMemo(() => {
2752
+ const isNewThread = React3.useMemo(() => {
2428
2753
  if (!activeThreadId || !isFetchedThreads) return false;
2429
2754
  return !threads.some((t) => t.id === activeThreadId);
2430
2755
  }, [activeThreadId, threads, isFetchedThreads]);
@@ -2454,22 +2779,22 @@ var ThreadProvider = ({
2454
2779
  }
2455
2780
  }
2456
2781
  });
2457
- const selectThread = React12.useCallback(
2782
+ const selectThread = React3.useCallback(
2458
2783
  (threadId) => {
2459
2784
  setActiveThreadId(threadId);
2460
2785
  },
2461
2786
  [setActiveThreadId]
2462
2787
  );
2463
- const createThread = React12.useCallback(async () => {
2788
+ const createThread = React3.useCallback(async () => {
2464
2789
  return createMutation.mutateAsync();
2465
2790
  }, [createMutation]);
2466
- const deleteThread = React12.useCallback(
2791
+ const deleteThread = React3.useCallback(
2467
2792
  async (threadId) => {
2468
2793
  return deleteMutation.mutateAsync(threadId);
2469
2794
  },
2470
2795
  [deleteMutation]
2471
2796
  );
2472
- const value = React12.useMemo(
2797
+ const value = React3.useMemo(
2473
2798
  () => ({
2474
2799
  threads,
2475
2800
  activeThreadId,
@@ -2500,7 +2825,7 @@ var ThreadProvider = ({
2500
2825
  return /* @__PURE__ */ jsxRuntime.jsx(ThreadContext.Provider, { value, children });
2501
2826
  };
2502
2827
  function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
2503
- const [screenSize, setScreenSize] = React12.useState(() => {
2828
+ const [screenSize, setScreenSize] = React3.useState(() => {
2504
2829
  if (typeof window === "undefined") {
2505
2830
  return {
2506
2831
  width: 1024,
@@ -2519,7 +2844,7 @@ function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
2519
2844
  isDesktop: width >= tabletBreakpoint
2520
2845
  };
2521
2846
  });
2522
- React12.useEffect(() => {
2847
+ React3.useEffect(() => {
2523
2848
  if (typeof window === "undefined") return;
2524
2849
  const updateScreenSize = () => {
2525
2850
  const width = window.innerWidth;
@@ -2540,11 +2865,11 @@ function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
2540
2865
  }, [mobileBreakpoint, tabletBreakpoint]);
2541
2866
  return screenSize;
2542
2867
  }
2543
- var SidebarContext = React12.createContext(
2868
+ var SidebarContext = React3.createContext(
2544
2869
  void 0
2545
2870
  );
2546
2871
  function useSidebar() {
2547
- const context = React12.useContext(SidebarContext);
2872
+ const context = React3.useContext(SidebarContext);
2548
2873
  if (context === void 0) {
2549
2874
  throw new Error("useSidebar must be used within a SidebarProvider");
2550
2875
  }
@@ -2557,33 +2882,33 @@ function SidebarProvider({
2557
2882
  }) {
2558
2883
  const { isMobile, isTablet } = useScreenSize();
2559
2884
  const isSmallScreen = isMobile || isTablet;
2560
- const [leftCollapsed, setLeftCollapsed] = React12.useState(() => {
2885
+ const [leftCollapsed, setLeftCollapsed] = React3.useState(() => {
2561
2886
  if (defaultLeftCollapsed !== void 0) return defaultLeftCollapsed;
2562
2887
  if (typeof window !== "undefined") {
2563
2888
  return window.innerWidth < 1024;
2564
2889
  }
2565
2890
  return false;
2566
2891
  });
2567
- const [rightCollapsed, setRightCollapsed] = React12.useState(() => {
2892
+ const [rightCollapsed, setRightCollapsed] = React3.useState(() => {
2568
2893
  if (defaultRightCollapsed !== void 0) return defaultRightCollapsed;
2569
2894
  if (typeof window !== "undefined") {
2570
2895
  return window.innerWidth < 1024;
2571
2896
  }
2572
2897
  return false;
2573
2898
  });
2574
- React12.useEffect(() => {
2899
+ React3.useEffect(() => {
2575
2900
  if (isSmallScreen) {
2576
2901
  setLeftCollapsed(true);
2577
2902
  setRightCollapsed(true);
2578
2903
  }
2579
2904
  }, [isSmallScreen]);
2580
- const handleLeftToggle = React12.useCallback((collapsed) => {
2905
+ const handleLeftToggle = React3.useCallback((collapsed) => {
2581
2906
  setLeftCollapsed(collapsed);
2582
2907
  }, []);
2583
- const handleRightToggle = React12.useCallback((collapsed) => {
2908
+ const handleRightToggle = React3.useCallback((collapsed) => {
2584
2909
  setRightCollapsed(collapsed);
2585
2910
  }, []);
2586
- const contextValue = React12.useMemo(
2911
+ const contextValue = React3.useMemo(
2587
2912
  () => ({
2588
2913
  leftCollapsed,
2589
2914
  rightCollapsed,
@@ -2596,11 +2921,11 @@ function SidebarProvider({
2596
2921
  );
2597
2922
  return /* @__PURE__ */ jsxRuntime.jsx(SidebarContext.Provider, { value: contextValue, children });
2598
2923
  }
2599
- var ThemeContext = React12.createContext(void 0);
2924
+ var ThemeContext = React3.createContext(void 0);
2600
2925
  function ThemeProvider({ children }) {
2601
- const [theme, setThemeState] = React12.useState("system");
2602
- const [resolvedTheme, setResolvedTheme] = React12.useState("light");
2603
- React12.useEffect(() => {
2926
+ const [theme, setThemeState] = React3.useState("system");
2927
+ const [resolvedTheme, setResolvedTheme] = React3.useState("light");
2928
+ React3.useEffect(() => {
2604
2929
  if (typeof window !== "undefined") {
2605
2930
  const stored = localStorage.getItem("theme");
2606
2931
  if (stored) {
@@ -2608,7 +2933,7 @@ function ThemeProvider({ children }) {
2608
2933
  }
2609
2934
  }
2610
2935
  }, []);
2611
- React12.useEffect(() => {
2936
+ React3.useEffect(() => {
2612
2937
  if (typeof window !== "undefined") {
2613
2938
  if (theme === "system") {
2614
2939
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
@@ -2623,7 +2948,7 @@ function ThemeProvider({ children }) {
2623
2948
  }
2624
2949
  }
2625
2950
  }, [theme]);
2626
- React12.useEffect(() => {
2951
+ React3.useEffect(() => {
2627
2952
  if (typeof window !== "undefined") {
2628
2953
  const root = document.documentElement;
2629
2954
  if (resolvedTheme === "dark") {
@@ -2642,14 +2967,14 @@ function ThemeProvider({ children }) {
2642
2967
  return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: { theme, setTheme, resolvedTheme }, children });
2643
2968
  }
2644
2969
  function useTheme() {
2645
- const context = React12.useContext(ThemeContext);
2970
+ const context = React3.useContext(ThemeContext);
2646
2971
  if (context === void 0) {
2647
2972
  throw new Error("useTheme must be used within a ThemeProvider");
2648
2973
  }
2649
2974
  return context;
2650
2975
  }
2651
2976
  var useThreads = () => {
2652
- const context = React12.useContext(ThreadContext);
2977
+ const context = React3.useContext(ThreadContext);
2653
2978
  if (context === void 0) {
2654
2979
  throw new Error("useThreads must be used within a ThreadProvider");
2655
2980
  }
@@ -2671,13 +2996,13 @@ function Composer({
2671
2996
  const accept = fileAttachments?.accept;
2672
2997
  const maxFiles = fileAttachments?.maxFiles ?? 10;
2673
2998
  const maxFileSize = fileAttachments?.maxFileSize ?? 10 * 1024 * 1024;
2674
- const [selectedOptions, setSelectedOptions] = React12__namespace.default.useState(
2999
+ const [selectedOptions, setSelectedOptions] = React3__namespace.default.useState(
2675
3000
  () => new Set(defaultSelectedIds)
2676
3001
  );
2677
- const [attachedFiles, setAttachedFiles] = React12__namespace.default.useState([]);
2678
- const [previews, setPreviews] = React12__namespace.default.useState([]);
2679
- const fileInputRef = React12__namespace.default.useRef(null);
2680
- React12__namespace.default.useEffect(() => {
3002
+ const [attachedFiles, setAttachedFiles] = React3__namespace.default.useState([]);
3003
+ const [previews, setPreviews] = React3__namespace.default.useState([]);
3004
+ const fileInputRef = React3__namespace.default.useRef(null);
3005
+ React3__namespace.default.useEffect(() => {
2681
3006
  const newPreviews = attachedFiles.map((file) => ({
2682
3007
  name: file.name,
2683
3008
  type: file.type,
@@ -3023,7 +3348,7 @@ function MessageBubble({ message }) {
3023
3348
  ) });
3024
3349
  }
3025
3350
  function LoadingIndicator({ status }) {
3026
- const [isExpanded, setIsExpanded] = React12.useState(false);
3351
+ const [isExpanded, setIsExpanded] = React3.useState(false);
3027
3352
  const message = status?.message || "Processing...";
3028
3353
  const details = status?.details;
3029
3354
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
@@ -3055,7 +3380,7 @@ function MessageList({
3055
3380
  if (messages.length === 0) {
3056
3381
  return null;
3057
3382
  }
3058
- const isTextStreaming = React12.useMemo(() => {
3383
+ const isTextStreaming = React3.useMemo(() => {
3059
3384
  if (messages.length === 0 || !isLoading) return false;
3060
3385
  const lastMessage = messages[messages.length - 1];
3061
3386
  return lastMessage.content.some((event) => event.type === "text-delta");
@@ -3092,7 +3417,7 @@ function Thread({
3092
3417
  const starterPrompts = localStarterPrompts ?? config?.starterPrompts;
3093
3418
  const options = localOptions ?? config?.options;
3094
3419
  const fileAttachments = config?.fileAttachments;
3095
- const allDefaultSelectedIds = React12.useMemo(() => {
3420
+ const allDefaultSelectedIds = React3.useMemo(() => {
3096
3421
  const defaultSelectedIdsFromOptions = options?.flatMap((group) => group.defaultSelectedIds ?? []) ?? [];
3097
3422
  return [
3098
3423
  .../* @__PURE__ */ new Set([
@@ -3101,9 +3426,9 @@ function Thread({
3101
3426
  ])
3102
3427
  ];
3103
3428
  }, [options, defaultSelectedIds]);
3104
- const [input, setInput] = React12.useState("");
3105
- const messagesEndRef = React12.useRef(null);
3106
- React12.useEffect(() => {
3429
+ const [input, setInput] = React3.useState("");
3430
+ const messagesEndRef = React3.useRef(null);
3431
+ React3.useEffect(() => {
3107
3432
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
3108
3433
  }, [messages]);
3109
3434
  const handleSubmit = async (state, overrideInput) => {
@@ -3248,7 +3573,7 @@ var Dropdown = ({
3248
3573
  };
3249
3574
  var ThreadList = ({ className }) => {
3250
3575
  const { threads, activeThreadId, deleteThread } = useThreads();
3251
- const sortedThreads = React12__namespace.useMemo(() => {
3576
+ const sortedThreads = React3__namespace.useMemo(() => {
3252
3577
  return [...threads].sort((a, b) => {
3253
3578
  const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
3254
3579
  const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
@@ -3303,8 +3628,8 @@ function PopupChat({
3303
3628
  headerProps,
3304
3629
  defaultSelectedIds
3305
3630
  }) {
3306
- const [isOpen, setIsOpen] = React12.useState(defaultOpen);
3307
- const [view, setView] = React12.useState("chat");
3631
+ const [isOpen, setIsOpen] = React3.useState(defaultOpen);
3632
+ const [view, setView] = React3.useState("chat");
3308
3633
  const { createThread } = useThreads();
3309
3634
  const handleNewChat = async () => {
3310
3635
  try {
@@ -3476,206 +3801,6 @@ function SidebarToggle({ side, className }) {
3476
3801
  }
3477
3802
  return null;
3478
3803
  }
3479
- var PopoverContext = React12__namespace.createContext(
3480
- void 0
3481
- );
3482
- function usePopoverContext() {
3483
- const context = React12__namespace.useContext(PopoverContext);
3484
- if (!context) {
3485
- throw new Error("Popover components must be used within a Popover");
3486
- }
3487
- return context;
3488
- }
3489
- function Popover({
3490
- children,
3491
- defaultOpen = false,
3492
- open: controlledOpen,
3493
- onOpenChange
3494
- }) {
3495
- const [internalOpen, setInternalOpen] = React12__namespace.useState(defaultOpen);
3496
- const triggerRef = React12__namespace.useRef(null);
3497
- const open = controlledOpen ?? internalOpen;
3498
- const setOpen = React12__namespace.useCallback(
3499
- (newOpen) => {
3500
- if (controlledOpen === void 0) {
3501
- setInternalOpen(newOpen);
3502
- }
3503
- onOpenChange?.(newOpen);
3504
- },
3505
- [controlledOpen, onOpenChange]
3506
- );
3507
- const value = React12__namespace.useMemo(
3508
- () => ({
3509
- open,
3510
- setOpen,
3511
- triggerRef
3512
- }),
3513
- [open, setOpen]
3514
- );
3515
- return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value, children });
3516
- }
3517
- var PopoverTrigger = React12__namespace.forwardRef(
3518
- ({ asChild, className, children, ...props }, ref) => {
3519
- const { setOpen, triggerRef } = usePopoverContext();
3520
- const handleClick = (e) => {
3521
- setOpen(true);
3522
- props.onClick?.(e);
3523
- };
3524
- if (asChild && React12__namespace.isValidElement(children)) {
3525
- return React12__namespace.cloneElement(children, {
3526
- ref: (node) => {
3527
- triggerRef.current = node;
3528
- if (typeof children.ref === "function") {
3529
- children.ref(node);
3530
- } else if (children.ref) {
3531
- children.ref.current = node;
3532
- }
3533
- },
3534
- onClick: handleClick
3535
- });
3536
- }
3537
- return /* @__PURE__ */ jsxRuntime.jsx(
3538
- "button",
3539
- {
3540
- ref: (node) => {
3541
- triggerRef.current = node;
3542
- if (typeof ref === "function") {
3543
- ref(node);
3544
- } else if (ref) {
3545
- ref.current = node;
3546
- }
3547
- },
3548
- className,
3549
- onClick: handleClick,
3550
- ...props,
3551
- children
3552
- }
3553
- );
3554
- }
3555
- );
3556
- PopoverTrigger.displayName = "PopoverTrigger";
3557
- var PopoverContent = React12__namespace.forwardRef(
3558
- ({
3559
- className,
3560
- side = "bottom",
3561
- align = "start",
3562
- sideOffset = 4,
3563
- alignOffset = 0,
3564
- children,
3565
- ...props
3566
- }, ref) => {
3567
- const { open, setOpen, triggerRef } = usePopoverContext();
3568
- const [position, setPosition] = React12__namespace.useState({ top: 0, left: 0 });
3569
- const contentRef = React12__namespace.useRef(null);
3570
- React12__namespace.useEffect(() => {
3571
- if (!open || !triggerRef.current) return;
3572
- const updatePosition = () => {
3573
- if (!triggerRef.current || !contentRef.current) return;
3574
- const triggerRect = triggerRef.current.getBoundingClientRect();
3575
- const contentRect = contentRef.current.getBoundingClientRect();
3576
- const scrollX = window.scrollX;
3577
- const scrollY = window.scrollY;
3578
- let top = 0;
3579
- let left = 0;
3580
- switch (side) {
3581
- case "bottom":
3582
- top = triggerRect.bottom + sideOffset + scrollY;
3583
- break;
3584
- case "top":
3585
- top = triggerRect.top - contentRect.height - sideOffset + scrollY;
3586
- break;
3587
- case "right":
3588
- top = triggerRect.top + scrollY;
3589
- left = triggerRect.right + sideOffset + scrollX;
3590
- break;
3591
- case "left":
3592
- top = triggerRect.top + scrollY;
3593
- left = triggerRect.left - contentRect.width - sideOffset + scrollX;
3594
- break;
3595
- }
3596
- switch (align) {
3597
- case "start":
3598
- if (side === "top" || side === "bottom") {
3599
- left = triggerRect.left + scrollX + alignOffset;
3600
- } else {
3601
- top += alignOffset;
3602
- }
3603
- break;
3604
- case "center":
3605
- if (side === "top" || side === "bottom") {
3606
- left = triggerRect.left + triggerRect.width / 2 - contentRect.width / 2 + scrollX + alignOffset;
3607
- } else {
3608
- top += triggerRect.height / 2 - contentRect.height / 2 + alignOffset;
3609
- }
3610
- break;
3611
- case "end":
3612
- if (side === "top" || side === "bottom") {
3613
- left = triggerRect.left + triggerRect.width - contentRect.width + scrollX + alignOffset;
3614
- } else {
3615
- top += triggerRect.height - contentRect.height + alignOffset;
3616
- }
3617
- break;
3618
- }
3619
- setPosition({ top, left });
3620
- };
3621
- requestAnimationFrame(() => {
3622
- updatePosition();
3623
- });
3624
- window.addEventListener("resize", updatePosition);
3625
- window.addEventListener("scroll", updatePosition, true);
3626
- return () => {
3627
- window.removeEventListener("resize", updatePosition);
3628
- window.removeEventListener("scroll", updatePosition, true);
3629
- };
3630
- }, [open, side, align, sideOffset, alignOffset, triggerRef]);
3631
- React12__namespace.useEffect(() => {
3632
- if (!open) return;
3633
- const handleClickOutside = (event) => {
3634
- if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
3635
- setOpen(false);
3636
- }
3637
- };
3638
- const handleEscape = (event) => {
3639
- if (event.key === "Escape") {
3640
- setOpen(false);
3641
- }
3642
- };
3643
- document.addEventListener("mousedown", handleClickOutside);
3644
- document.addEventListener("keydown", handleEscape);
3645
- return () => {
3646
- document.removeEventListener("mousedown", handleClickOutside);
3647
- document.removeEventListener("keydown", handleEscape);
3648
- };
3649
- }, [open, setOpen, triggerRef]);
3650
- if (!open) return null;
3651
- const content = /* @__PURE__ */ jsxRuntime.jsx(
3652
- "div",
3653
- {
3654
- ref: (node) => {
3655
- contentRef.current = node;
3656
- if (typeof ref === "function") {
3657
- ref(node);
3658
- } else if (ref) {
3659
- ref.current = node;
3660
- }
3661
- },
3662
- className: cn(
3663
- "bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/5 rounded-2xl shadow-2xl ring-1 z-50 min-w-48 max-h-96 overflow-hidden",
3664
- className
3665
- ),
3666
- style: {
3667
- position: "absolute",
3668
- top: `${position.top}px`,
3669
- left: `${position.left}px`
3670
- },
3671
- ...props,
3672
- children
3673
- }
3674
- );
3675
- return reactDom.createPortal(content, document.body);
3676
- }
3677
- );
3678
- PopoverContent.displayName = "PopoverContent";
3679
3804
  var ThreadPopover = ({
3680
3805
  className,
3681
3806
  buttonClassName,
@@ -3683,7 +3808,7 @@ var ThreadPopover = ({
3683
3808
  buttonSize = "icon",
3684
3809
  emptyState
3685
3810
  }) => {
3686
- const [isOpen, setIsOpen] = React12__namespace.useState(false);
3811
+ const [isOpen, setIsOpen] = React3__namespace.useState(false);
3687
3812
  reactHotkeysHook.useHotkeys(
3688
3813
  "h",
3689
3814
  (e) => {
@@ -3726,7 +3851,7 @@ var CreateThreadButton = ({
3726
3851
  onThreadCreated
3727
3852
  }) => {
3728
3853
  const { createThread } = useThreads();
3729
- const [isCreating, setIsCreating] = React12__namespace.useState(false);
3854
+ const [isCreating, setIsCreating] = React3__namespace.useState(false);
3730
3855
  const handleCreateThread = async () => {
3731
3856
  if (isCreating) return;
3732
3857
  try {
@@ -3808,7 +3933,7 @@ var CreateThreadListItem = ({
3808
3933
  className
3809
3934
  }) => {
3810
3935
  const { createThread } = useThreads();
3811
- const [isCreating, setIsCreating] = React12__namespace.useState(false);
3936
+ const [isCreating, setIsCreating] = React3__namespace.useState(false);
3812
3937
  const handleCreateThread = async () => {
3813
3938
  if (isCreating) return;
3814
3939
  try {