@melony/react 0.1.45 → 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 +517 -283
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +455 -222
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React3 from 'react';
|
|
2
|
+
import React3__default, { createContext, useContext, useRef, useEffect, useState, useCallback, useMemo } from 'react';
|
|
3
3
|
import { convertEventsToMessages } from 'melony';
|
|
4
4
|
import { NuqsAdapter } from 'nuqs/adapters/react';
|
|
5
5
|
import { QueryClient, QueryClientProvider, useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
|
|
@@ -8,17 +8,17 @@ import { clsx } from 'clsx';
|
|
|
8
8
|
import { twMerge } from 'tailwind-merge';
|
|
9
9
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
10
|
import * as ICONS from '@tabler/icons-react';
|
|
11
|
-
import { IconX, IconChevronLeft, IconChevronRight, IconUser, IconLogout, IconBrandGoogle, IconFileText, IconFile, IconPaperclip, IconChevronDown,
|
|
11
|
+
import { IconX, IconChevronLeft, IconChevronRight, IconLoader2, IconCheck, IconUpload, IconUser, IconLogout, IconBrandGoogle, IconFileText, IconFile, IconPaperclip, IconChevronDown, IconArrowUp, IconDotsVertical, IconTrash, IconHistory, IconPlus, IconArrowLeft, IconMessage, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconDeviceDesktop, IconMoon, IconSun, IconSelector, IconChevronUp } from '@tabler/icons-react';
|
|
12
12
|
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
13
13
|
import { mergeProps } from '@base-ui/react/merge-props';
|
|
14
14
|
import { useRender } from '@base-ui/react/use-render';
|
|
15
15
|
import { cva } from 'class-variance-authority';
|
|
16
16
|
import { Input as Input$1 } from '@base-ui/react/input';
|
|
17
17
|
import { Select as Select$1 } from '@base-ui/react/select';
|
|
18
|
+
import { createPortal } from 'react-dom';
|
|
18
19
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
19
20
|
import { Menu } from '@base-ui/react/menu';
|
|
20
21
|
import { useQueryState, parseAsString } from 'nuqs';
|
|
21
|
-
import { createPortal } from 'react-dom';
|
|
22
22
|
import { useHotkeys } from 'react-hotkeys-hook';
|
|
23
23
|
|
|
24
24
|
// src/providers/melony-provider.tsx
|
|
@@ -534,7 +534,6 @@ var Image = ({
|
|
|
534
534
|
src,
|
|
535
535
|
alt,
|
|
536
536
|
size = "sm",
|
|
537
|
-
groupId,
|
|
538
537
|
className,
|
|
539
538
|
style
|
|
540
539
|
}) => {
|
|
@@ -1423,6 +1422,324 @@ var Checkbox = ({
|
|
|
1423
1422
|
)
|
|
1424
1423
|
] });
|
|
1425
1424
|
};
|
|
1425
|
+
var Hidden = ({ name, value }) => {
|
|
1426
|
+
return /* @__PURE__ */ jsx("input", { type: "hidden", name, value });
|
|
1427
|
+
};
|
|
1428
|
+
var PopoverContext = React3.createContext(
|
|
1429
|
+
void 0
|
|
1430
|
+
);
|
|
1431
|
+
function usePopoverContext() {
|
|
1432
|
+
const context = React3.useContext(PopoverContext);
|
|
1433
|
+
if (!context) {
|
|
1434
|
+
throw new Error("Popover components must be used within a Popover");
|
|
1435
|
+
}
|
|
1436
|
+
return context;
|
|
1437
|
+
}
|
|
1438
|
+
function Popover({
|
|
1439
|
+
children,
|
|
1440
|
+
defaultOpen = false,
|
|
1441
|
+
open: controlledOpen,
|
|
1442
|
+
onOpenChange
|
|
1443
|
+
}) {
|
|
1444
|
+
const [internalOpen, setInternalOpen] = React3.useState(defaultOpen);
|
|
1445
|
+
const triggerRef = React3.useRef(null);
|
|
1446
|
+
const open = controlledOpen ?? internalOpen;
|
|
1447
|
+
const setOpen = React3.useCallback(
|
|
1448
|
+
(newOpen) => {
|
|
1449
|
+
if (controlledOpen === void 0) {
|
|
1450
|
+
setInternalOpen(newOpen);
|
|
1451
|
+
}
|
|
1452
|
+
onOpenChange?.(newOpen);
|
|
1453
|
+
},
|
|
1454
|
+
[controlledOpen, onOpenChange]
|
|
1455
|
+
);
|
|
1456
|
+
const value = React3.useMemo(
|
|
1457
|
+
() => ({
|
|
1458
|
+
open,
|
|
1459
|
+
setOpen,
|
|
1460
|
+
triggerRef
|
|
1461
|
+
}),
|
|
1462
|
+
[open, setOpen]
|
|
1463
|
+
);
|
|
1464
|
+
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value, children });
|
|
1465
|
+
}
|
|
1466
|
+
var PopoverTrigger = React3.forwardRef(
|
|
1467
|
+
({ asChild, className, children, ...props }, ref) => {
|
|
1468
|
+
const { setOpen, triggerRef } = usePopoverContext();
|
|
1469
|
+
const handleClick = (e) => {
|
|
1470
|
+
setOpen(true);
|
|
1471
|
+
props.onClick?.(e);
|
|
1472
|
+
};
|
|
1473
|
+
if (asChild && React3.isValidElement(children)) {
|
|
1474
|
+
return React3.cloneElement(children, {
|
|
1475
|
+
ref: (node) => {
|
|
1476
|
+
triggerRef.current = node;
|
|
1477
|
+
if (typeof children.ref === "function") {
|
|
1478
|
+
children.ref(node);
|
|
1479
|
+
} else if (children.ref) {
|
|
1480
|
+
children.ref.current = node;
|
|
1481
|
+
}
|
|
1482
|
+
},
|
|
1483
|
+
onClick: handleClick
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
return /* @__PURE__ */ jsx(
|
|
1487
|
+
"button",
|
|
1488
|
+
{
|
|
1489
|
+
ref: (node) => {
|
|
1490
|
+
triggerRef.current = node;
|
|
1491
|
+
if (typeof ref === "function") {
|
|
1492
|
+
ref(node);
|
|
1493
|
+
} else if (ref) {
|
|
1494
|
+
ref.current = node;
|
|
1495
|
+
}
|
|
1496
|
+
},
|
|
1497
|
+
className,
|
|
1498
|
+
onClick: handleClick,
|
|
1499
|
+
...props,
|
|
1500
|
+
children
|
|
1501
|
+
}
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
);
|
|
1505
|
+
PopoverTrigger.displayName = "PopoverTrigger";
|
|
1506
|
+
var PopoverContent = React3.forwardRef(
|
|
1507
|
+
({
|
|
1508
|
+
className,
|
|
1509
|
+
side = "bottom",
|
|
1510
|
+
align = "start",
|
|
1511
|
+
sideOffset = 4,
|
|
1512
|
+
alignOffset = 0,
|
|
1513
|
+
children,
|
|
1514
|
+
...props
|
|
1515
|
+
}, ref) => {
|
|
1516
|
+
const { open, setOpen, triggerRef } = usePopoverContext();
|
|
1517
|
+
const [position, setPosition] = React3.useState({ top: 0, left: 0 });
|
|
1518
|
+
const contentRef = React3.useRef(null);
|
|
1519
|
+
React3.useEffect(() => {
|
|
1520
|
+
if (!open || !triggerRef.current) return;
|
|
1521
|
+
const updatePosition = () => {
|
|
1522
|
+
if (!triggerRef.current || !contentRef.current) return;
|
|
1523
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
1524
|
+
const contentRect = contentRef.current.getBoundingClientRect();
|
|
1525
|
+
const scrollX = window.scrollX;
|
|
1526
|
+
const scrollY = window.scrollY;
|
|
1527
|
+
let top = 0;
|
|
1528
|
+
let left = 0;
|
|
1529
|
+
switch (side) {
|
|
1530
|
+
case "bottom":
|
|
1531
|
+
top = triggerRect.bottom + sideOffset + scrollY;
|
|
1532
|
+
break;
|
|
1533
|
+
case "top":
|
|
1534
|
+
top = triggerRect.top - contentRect.height - sideOffset + scrollY;
|
|
1535
|
+
break;
|
|
1536
|
+
case "right":
|
|
1537
|
+
top = triggerRect.top + scrollY;
|
|
1538
|
+
left = triggerRect.right + sideOffset + scrollX;
|
|
1539
|
+
break;
|
|
1540
|
+
case "left":
|
|
1541
|
+
top = triggerRect.top + scrollY;
|
|
1542
|
+
left = triggerRect.left - contentRect.width - sideOffset + scrollX;
|
|
1543
|
+
break;
|
|
1544
|
+
}
|
|
1545
|
+
switch (align) {
|
|
1546
|
+
case "start":
|
|
1547
|
+
if (side === "top" || side === "bottom") {
|
|
1548
|
+
left = triggerRect.left + scrollX + alignOffset;
|
|
1549
|
+
} else {
|
|
1550
|
+
top += alignOffset;
|
|
1551
|
+
}
|
|
1552
|
+
break;
|
|
1553
|
+
case "center":
|
|
1554
|
+
if (side === "top" || side === "bottom") {
|
|
1555
|
+
left = triggerRect.left + triggerRect.width / 2 - contentRect.width / 2 + scrollX + alignOffset;
|
|
1556
|
+
} else {
|
|
1557
|
+
top += triggerRect.height / 2 - contentRect.height / 2 + alignOffset;
|
|
1558
|
+
}
|
|
1559
|
+
break;
|
|
1560
|
+
case "end":
|
|
1561
|
+
if (side === "top" || side === "bottom") {
|
|
1562
|
+
left = triggerRect.left + triggerRect.width - contentRect.width + scrollX + alignOffset;
|
|
1563
|
+
} else {
|
|
1564
|
+
top += triggerRect.height - contentRect.height + alignOffset;
|
|
1565
|
+
}
|
|
1566
|
+
break;
|
|
1567
|
+
}
|
|
1568
|
+
setPosition({ top, left });
|
|
1569
|
+
};
|
|
1570
|
+
requestAnimationFrame(() => {
|
|
1571
|
+
updatePosition();
|
|
1572
|
+
});
|
|
1573
|
+
window.addEventListener("resize", updatePosition);
|
|
1574
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
1575
|
+
return () => {
|
|
1576
|
+
window.removeEventListener("resize", updatePosition);
|
|
1577
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
1578
|
+
};
|
|
1579
|
+
}, [open, side, align, sideOffset, alignOffset, triggerRef]);
|
|
1580
|
+
React3.useEffect(() => {
|
|
1581
|
+
if (!open) return;
|
|
1582
|
+
const handleClickOutside = (event) => {
|
|
1583
|
+
if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
1584
|
+
setOpen(false);
|
|
1585
|
+
}
|
|
1586
|
+
};
|
|
1587
|
+
const handleEscape = (event) => {
|
|
1588
|
+
if (event.key === "Escape") {
|
|
1589
|
+
setOpen(false);
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1593
|
+
document.addEventListener("keydown", handleEscape);
|
|
1594
|
+
return () => {
|
|
1595
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1596
|
+
document.removeEventListener("keydown", handleEscape);
|
|
1597
|
+
};
|
|
1598
|
+
}, [open, setOpen, triggerRef]);
|
|
1599
|
+
if (!open) return null;
|
|
1600
|
+
const content = /* @__PURE__ */ jsx(
|
|
1601
|
+
"div",
|
|
1602
|
+
{
|
|
1603
|
+
ref: (node) => {
|
|
1604
|
+
contentRef.current = node;
|
|
1605
|
+
if (typeof ref === "function") {
|
|
1606
|
+
ref(node);
|
|
1607
|
+
} else if (ref) {
|
|
1608
|
+
ref.current = node;
|
|
1609
|
+
}
|
|
1610
|
+
},
|
|
1611
|
+
className: cn(
|
|
1612
|
+
"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",
|
|
1613
|
+
className
|
|
1614
|
+
),
|
|
1615
|
+
style: {
|
|
1616
|
+
position: "absolute",
|
|
1617
|
+
top: `${position.top}px`,
|
|
1618
|
+
left: `${position.left}px`
|
|
1619
|
+
},
|
|
1620
|
+
...props,
|
|
1621
|
+
children
|
|
1622
|
+
}
|
|
1623
|
+
);
|
|
1624
|
+
return createPortal(content, document.body);
|
|
1625
|
+
}
|
|
1626
|
+
);
|
|
1627
|
+
PopoverContent.displayName = "PopoverContent";
|
|
1628
|
+
var PRESET_COLORS = [
|
|
1629
|
+
"#000000",
|
|
1630
|
+
"#ffffff",
|
|
1631
|
+
"#f44336",
|
|
1632
|
+
"#e91e63",
|
|
1633
|
+
"#9c27b0",
|
|
1634
|
+
"#673ab7",
|
|
1635
|
+
"#3f51b5",
|
|
1636
|
+
"#2196f3",
|
|
1637
|
+
"#03a9f4",
|
|
1638
|
+
"#00bcd4",
|
|
1639
|
+
"#009688",
|
|
1640
|
+
"#4caf50",
|
|
1641
|
+
"#8bc34a",
|
|
1642
|
+
"#cddc39",
|
|
1643
|
+
"#ffeb3b",
|
|
1644
|
+
"#ffc107",
|
|
1645
|
+
"#ff9800",
|
|
1646
|
+
"#ff5722",
|
|
1647
|
+
"#795548",
|
|
1648
|
+
"#9e9e9e",
|
|
1649
|
+
"#607d8b"
|
|
1650
|
+
];
|
|
1651
|
+
var ColorPicker = ({
|
|
1652
|
+
name,
|
|
1653
|
+
label,
|
|
1654
|
+
defaultValue = "#000000",
|
|
1655
|
+
value: controlledValue,
|
|
1656
|
+
onChangeAction,
|
|
1657
|
+
disabled,
|
|
1658
|
+
className,
|
|
1659
|
+
style
|
|
1660
|
+
}) => {
|
|
1661
|
+
const { sendEvent } = useMelony();
|
|
1662
|
+
const [color, setColor] = useState(controlledValue || defaultValue);
|
|
1663
|
+
useEffect(() => {
|
|
1664
|
+
if (controlledValue !== void 0) {
|
|
1665
|
+
setColor(controlledValue);
|
|
1666
|
+
}
|
|
1667
|
+
}, [controlledValue]);
|
|
1668
|
+
const handleColorChange = (newColor) => {
|
|
1669
|
+
setColor(newColor);
|
|
1670
|
+
if (onChangeAction) {
|
|
1671
|
+
sendEvent({
|
|
1672
|
+
...onChangeAction,
|
|
1673
|
+
data: {
|
|
1674
|
+
name: name || "",
|
|
1675
|
+
value: newColor
|
|
1676
|
+
}
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
};
|
|
1680
|
+
return /* @__PURE__ */ jsxs(Field, { className: cn("w-full", className), style, children: [
|
|
1681
|
+
label && /* @__PURE__ */ jsx(FieldTitle, { children: label }),
|
|
1682
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1683
|
+
/* @__PURE__ */ jsxs(Popover, { children: [
|
|
1684
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1685
|
+
"button",
|
|
1686
|
+
{
|
|
1687
|
+
type: "button",
|
|
1688
|
+
disabled,
|
|
1689
|
+
className: cn(
|
|
1690
|
+
"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",
|
|
1691
|
+
"flex items-center justify-center p-1"
|
|
1692
|
+
),
|
|
1693
|
+
children: /* @__PURE__ */ jsx(
|
|
1694
|
+
"div",
|
|
1695
|
+
{
|
|
1696
|
+
className: "w-full h-full rounded-md",
|
|
1697
|
+
style: { backgroundColor: color }
|
|
1698
|
+
}
|
|
1699
|
+
)
|
|
1700
|
+
}
|
|
1701
|
+
) }),
|
|
1702
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "p-3 w-64", side: "bottom", align: "start", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
1703
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-1", children: PRESET_COLORS.map((preset) => /* @__PURE__ */ jsx(
|
|
1704
|
+
"button",
|
|
1705
|
+
{
|
|
1706
|
+
type: "button",
|
|
1707
|
+
className: cn(
|
|
1708
|
+
"w-6 h-6 rounded-md border border-border transition-transform hover:scale-110 active:scale-90",
|
|
1709
|
+
color === preset && "ring-2 ring-primary ring-offset-1"
|
|
1710
|
+
),
|
|
1711
|
+
style: { backgroundColor: preset },
|
|
1712
|
+
onClick: () => handleColorChange(preset)
|
|
1713
|
+
},
|
|
1714
|
+
preset
|
|
1715
|
+
)) }),
|
|
1716
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1717
|
+
/* @__PURE__ */ jsx(
|
|
1718
|
+
"input",
|
|
1719
|
+
{
|
|
1720
|
+
type: "color",
|
|
1721
|
+
value: color,
|
|
1722
|
+
onChange: (e) => handleColorChange(e.target.value),
|
|
1723
|
+
className: "w-8 h-8 rounded border-none p-0 cursor-pointer"
|
|
1724
|
+
}
|
|
1725
|
+
),
|
|
1726
|
+
/* @__PURE__ */ jsx(
|
|
1727
|
+
"input",
|
|
1728
|
+
{
|
|
1729
|
+
type: "text",
|
|
1730
|
+
value: color,
|
|
1731
|
+
onChange: (e) => handleColorChange(e.target.value),
|
|
1732
|
+
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"
|
|
1733
|
+
}
|
|
1734
|
+
)
|
|
1735
|
+
] })
|
|
1736
|
+
] }) })
|
|
1737
|
+
] }),
|
|
1738
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-mono uppercase text-muted-foreground", children: color })
|
|
1739
|
+
] }),
|
|
1740
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name, value: color })
|
|
1741
|
+
] });
|
|
1742
|
+
};
|
|
1426
1743
|
var RadioGroup = ({
|
|
1427
1744
|
name,
|
|
1428
1745
|
options,
|
|
@@ -1582,6 +1899,119 @@ var Button2 = ({
|
|
|
1582
1899
|
}
|
|
1583
1900
|
);
|
|
1584
1901
|
};
|
|
1902
|
+
var Upload = ({
|
|
1903
|
+
label = "Upload",
|
|
1904
|
+
multiple = false,
|
|
1905
|
+
accept,
|
|
1906
|
+
onUploadAction,
|
|
1907
|
+
className,
|
|
1908
|
+
style,
|
|
1909
|
+
initialFiles,
|
|
1910
|
+
mode = "append"
|
|
1911
|
+
}) => {
|
|
1912
|
+
const { sendEvent, events } = useMelony();
|
|
1913
|
+
const fileInputRef = useRef(null);
|
|
1914
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
1915
|
+
const [status, setStatus] = useState("idle");
|
|
1916
|
+
const uploadedFilesEvents = events.filter(
|
|
1917
|
+
(event) => event.type === "uploaded-files"
|
|
1918
|
+
);
|
|
1919
|
+
const displayEvents = mode === "replace" && uploadedFilesEvents.length > 0 ? [uploadedFilesEvents[uploadedFilesEvents.length - 1]] : uploadedFilesEvents;
|
|
1920
|
+
const showInitialFiles = mode === "replace" ? displayEvents.length === 0 : true;
|
|
1921
|
+
const handleFileChange = async (e) => {
|
|
1922
|
+
const files = Array.from(e.target.files || []);
|
|
1923
|
+
if (files.length === 0) return;
|
|
1924
|
+
setIsUploading(true);
|
|
1925
|
+
setStatus("idle");
|
|
1926
|
+
try {
|
|
1927
|
+
const filePromises = files.map((file) => {
|
|
1928
|
+
return new Promise((resolve, reject) => {
|
|
1929
|
+
const reader = new FileReader();
|
|
1930
|
+
reader.onload = () => {
|
|
1931
|
+
try {
|
|
1932
|
+
const base64 = reader.result;
|
|
1933
|
+
if (!base64) {
|
|
1934
|
+
reject(new Error("FileReader returned empty result"));
|
|
1935
|
+
return;
|
|
1936
|
+
}
|
|
1937
|
+
resolve({
|
|
1938
|
+
name: file.name,
|
|
1939
|
+
type: file.type,
|
|
1940
|
+
size: file.size,
|
|
1941
|
+
data: base64
|
|
1942
|
+
});
|
|
1943
|
+
} catch (error) {
|
|
1944
|
+
reject(error);
|
|
1945
|
+
}
|
|
1946
|
+
};
|
|
1947
|
+
reader.onerror = (error) => {
|
|
1948
|
+
reject(new Error(`Failed to read file ${file.name}: ${error}`));
|
|
1949
|
+
};
|
|
1950
|
+
reader.readAsDataURL(file);
|
|
1951
|
+
});
|
|
1952
|
+
});
|
|
1953
|
+
const convertedFiles = await Promise.all(filePromises);
|
|
1954
|
+
if (onUploadAction) {
|
|
1955
|
+
if (typeof onUploadAction === "function") {
|
|
1956
|
+
await sendEvent(onUploadAction({ files: convertedFiles }));
|
|
1957
|
+
} else {
|
|
1958
|
+
await sendEvent({
|
|
1959
|
+
...onUploadAction,
|
|
1960
|
+
data: {
|
|
1961
|
+
...onUploadAction.data,
|
|
1962
|
+
files: convertedFiles
|
|
1963
|
+
}
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
setStatus("success");
|
|
1968
|
+
setTimeout(() => setStatus("idle"), 3e3);
|
|
1969
|
+
} catch (error) {
|
|
1970
|
+
console.error("Upload failed:", error);
|
|
1971
|
+
setStatus("error");
|
|
1972
|
+
setTimeout(() => setStatus("idle"), 3e3);
|
|
1973
|
+
} finally {
|
|
1974
|
+
setIsUploading(false);
|
|
1975
|
+
if (fileInputRef.current) {
|
|
1976
|
+
fileInputRef.current.value = "";
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
};
|
|
1980
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-block", className), style, children: [
|
|
1981
|
+
/* @__PURE__ */ jsx(
|
|
1982
|
+
"input",
|
|
1983
|
+
{
|
|
1984
|
+
type: "file",
|
|
1985
|
+
ref: fileInputRef,
|
|
1986
|
+
onChange: handleFileChange,
|
|
1987
|
+
multiple,
|
|
1988
|
+
accept,
|
|
1989
|
+
className: "hidden",
|
|
1990
|
+
disabled: isUploading
|
|
1991
|
+
}
|
|
1992
|
+
),
|
|
1993
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2 mb-2 items-center", children: [
|
|
1994
|
+
showInitialFiles && initialFiles?.map((file, index) => /* @__PURE__ */ jsx(Image, { src: file.url, alt: file.name, size: "md" }, index)),
|
|
1995
|
+
displayEvents.map(
|
|
1996
|
+
(event, index) => event.ui ? /* @__PURE__ */ jsx(UIRenderer, { node: event.ui }, index) : null
|
|
1997
|
+
),
|
|
1998
|
+
/* @__PURE__ */ jsxs(
|
|
1999
|
+
Button,
|
|
2000
|
+
{
|
|
2001
|
+
type: "button",
|
|
2002
|
+
disabled: isUploading,
|
|
2003
|
+
onClick: () => fileInputRef.current?.click(),
|
|
2004
|
+
className: "gap-2",
|
|
2005
|
+
variant: status === "error" ? "destructive" : status === "success" ? "outline" : "default",
|
|
2006
|
+
children: [
|
|
2007
|
+
isUploading ? /* @__PURE__ */ jsx(IconLoader2, { className: "h-4 w-4 animate-spin" }) : status === "success" ? /* @__PURE__ */ jsx(IconCheck, { className: "h-4 w-4 text-green-500" }) : status === "error" ? /* @__PURE__ */ jsx(IconX, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(IconUpload, { className: "h-4 w-4" }),
|
|
2008
|
+
status === "success" ? "Uploaded" : status === "error" ? "Failed" : label
|
|
2009
|
+
]
|
|
2010
|
+
}
|
|
2011
|
+
)
|
|
2012
|
+
] })
|
|
2013
|
+
] });
|
|
2014
|
+
};
|
|
1585
2015
|
var Form = ({
|
|
1586
2016
|
children,
|
|
1587
2017
|
onSubmitAction,
|
|
@@ -1643,10 +2073,12 @@ function UIRenderer({ node }) {
|
|
|
1643
2073
|
heading: Heading,
|
|
1644
2074
|
badge: Badge2,
|
|
1645
2075
|
input: Input2,
|
|
2076
|
+
hidden: Hidden,
|
|
1646
2077
|
textarea: Textarea2,
|
|
1647
2078
|
select: Select2,
|
|
1648
2079
|
checkbox: Checkbox,
|
|
1649
2080
|
radioGroup: RadioGroup,
|
|
2081
|
+
colorPicker: ColorPicker,
|
|
1650
2082
|
spacer: Spacer,
|
|
1651
2083
|
divider: Divider,
|
|
1652
2084
|
box: Box,
|
|
@@ -1656,7 +2088,8 @@ function UIRenderer({ node }) {
|
|
|
1656
2088
|
listItem: ListItem,
|
|
1657
2089
|
form: Form,
|
|
1658
2090
|
chart: Chart,
|
|
1659
|
-
label: Label2
|
|
2091
|
+
label: Label2,
|
|
2092
|
+
upload: Upload
|
|
1660
2093
|
};
|
|
1661
2094
|
const Component = typeMap[type];
|
|
1662
2095
|
if (!Component) {
|
|
@@ -1963,10 +2396,10 @@ var AccountButton = ({
|
|
|
1963
2396
|
size
|
|
1964
2397
|
}) => {
|
|
1965
2398
|
const { isLoading, isAuthenticated, user, login, logout } = useAuth();
|
|
1966
|
-
const [open, setOpen] =
|
|
1967
|
-
const [accountInfoOpen, setAccountInfoOpen] =
|
|
1968
|
-
const [error, setError] =
|
|
1969
|
-
const initials =
|
|
2399
|
+
const [open, setOpen] = React3.useState(false);
|
|
2400
|
+
const [accountInfoOpen, setAccountInfoOpen] = React3.useState(false);
|
|
2401
|
+
const [error, setError] = React3.useState(null);
|
|
2402
|
+
const initials = React3.useMemo(() => {
|
|
1970
2403
|
const name = user?.displayName || user?.name;
|
|
1971
2404
|
if (!name) return "";
|
|
1972
2405
|
return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
|
|
@@ -2542,13 +2975,13 @@ function Composer({
|
|
|
2542
2975
|
const accept = fileAttachments?.accept;
|
|
2543
2976
|
const maxFiles = fileAttachments?.maxFiles ?? 10;
|
|
2544
2977
|
const maxFileSize = fileAttachments?.maxFileSize ?? 10 * 1024 * 1024;
|
|
2545
|
-
const [selectedOptions, setSelectedOptions] =
|
|
2978
|
+
const [selectedOptions, setSelectedOptions] = React3__default.useState(
|
|
2546
2979
|
() => new Set(defaultSelectedIds)
|
|
2547
2980
|
);
|
|
2548
|
-
const [attachedFiles, setAttachedFiles] =
|
|
2549
|
-
const [previews, setPreviews] =
|
|
2550
|
-
const fileInputRef =
|
|
2551
|
-
|
|
2981
|
+
const [attachedFiles, setAttachedFiles] = React3__default.useState([]);
|
|
2982
|
+
const [previews, setPreviews] = React3__default.useState([]);
|
|
2983
|
+
const fileInputRef = React3__default.useRef(null);
|
|
2984
|
+
React3__default.useEffect(() => {
|
|
2552
2985
|
const newPreviews = attachedFiles.map((file) => ({
|
|
2553
2986
|
name: file.name,
|
|
2554
2987
|
type: file.type,
|
|
@@ -2831,7 +3264,7 @@ function StarterPrompts({
|
|
|
2831
3264
|
}
|
|
2832
3265
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col space-y-4 animate-in fade-in slide-in-from-bottom-4 duration-500 mt-auto max-w-2xl", children: [
|
|
2833
3266
|
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: "What can I help with today?" }) }),
|
|
2834
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-
|
|
3267
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1 w-full", children: prompts.map((item, index) => /* @__PURE__ */ jsx(
|
|
2835
3268
|
Button2,
|
|
2836
3269
|
{
|
|
2837
3270
|
label: item.label,
|
|
@@ -3119,7 +3552,7 @@ var Dropdown = ({
|
|
|
3119
3552
|
};
|
|
3120
3553
|
var ThreadList = ({ className }) => {
|
|
3121
3554
|
const { threads, activeThreadId, deleteThread } = useThreads();
|
|
3122
|
-
const sortedThreads =
|
|
3555
|
+
const sortedThreads = React3.useMemo(() => {
|
|
3123
3556
|
return [...threads].sort((a, b) => {
|
|
3124
3557
|
const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
|
|
3125
3558
|
const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
|
|
@@ -3280,7 +3713,7 @@ function Sidebar({ side, children, className }) {
|
|
|
3280
3713
|
collapsed ? "w-0 border-r-0 border-l-0 min-w-0" : "",
|
|
3281
3714
|
!collapsed && className
|
|
3282
3715
|
),
|
|
3283
|
-
children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children })
|
|
3716
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0 flex flex-col", children })
|
|
3284
3717
|
}
|
|
3285
3718
|
);
|
|
3286
3719
|
}
|
|
@@ -3347,206 +3780,6 @@ function SidebarToggle({ side, className }) {
|
|
|
3347
3780
|
}
|
|
3348
3781
|
return null;
|
|
3349
3782
|
}
|
|
3350
|
-
var PopoverContext = React11.createContext(
|
|
3351
|
-
void 0
|
|
3352
|
-
);
|
|
3353
|
-
function usePopoverContext() {
|
|
3354
|
-
const context = React11.useContext(PopoverContext);
|
|
3355
|
-
if (!context) {
|
|
3356
|
-
throw new Error("Popover components must be used within a Popover");
|
|
3357
|
-
}
|
|
3358
|
-
return context;
|
|
3359
|
-
}
|
|
3360
|
-
function Popover({
|
|
3361
|
-
children,
|
|
3362
|
-
defaultOpen = false,
|
|
3363
|
-
open: controlledOpen,
|
|
3364
|
-
onOpenChange
|
|
3365
|
-
}) {
|
|
3366
|
-
const [internalOpen, setInternalOpen] = React11.useState(defaultOpen);
|
|
3367
|
-
const triggerRef = React11.useRef(null);
|
|
3368
|
-
const open = controlledOpen ?? internalOpen;
|
|
3369
|
-
const setOpen = React11.useCallback(
|
|
3370
|
-
(newOpen) => {
|
|
3371
|
-
if (controlledOpen === void 0) {
|
|
3372
|
-
setInternalOpen(newOpen);
|
|
3373
|
-
}
|
|
3374
|
-
onOpenChange?.(newOpen);
|
|
3375
|
-
},
|
|
3376
|
-
[controlledOpen, onOpenChange]
|
|
3377
|
-
);
|
|
3378
|
-
const value = React11.useMemo(
|
|
3379
|
-
() => ({
|
|
3380
|
-
open,
|
|
3381
|
-
setOpen,
|
|
3382
|
-
triggerRef
|
|
3383
|
-
}),
|
|
3384
|
-
[open, setOpen]
|
|
3385
|
-
);
|
|
3386
|
-
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value, children });
|
|
3387
|
-
}
|
|
3388
|
-
var PopoverTrigger = React11.forwardRef(
|
|
3389
|
-
({ asChild, className, children, ...props }, ref) => {
|
|
3390
|
-
const { setOpen, triggerRef } = usePopoverContext();
|
|
3391
|
-
const handleClick = (e) => {
|
|
3392
|
-
setOpen(true);
|
|
3393
|
-
props.onClick?.(e);
|
|
3394
|
-
};
|
|
3395
|
-
if (asChild && React11.isValidElement(children)) {
|
|
3396
|
-
return React11.cloneElement(children, {
|
|
3397
|
-
ref: (node) => {
|
|
3398
|
-
triggerRef.current = node;
|
|
3399
|
-
if (typeof children.ref === "function") {
|
|
3400
|
-
children.ref(node);
|
|
3401
|
-
} else if (children.ref) {
|
|
3402
|
-
children.ref.current = node;
|
|
3403
|
-
}
|
|
3404
|
-
},
|
|
3405
|
-
onClick: handleClick
|
|
3406
|
-
});
|
|
3407
|
-
}
|
|
3408
|
-
return /* @__PURE__ */ jsx(
|
|
3409
|
-
"button",
|
|
3410
|
-
{
|
|
3411
|
-
ref: (node) => {
|
|
3412
|
-
triggerRef.current = node;
|
|
3413
|
-
if (typeof ref === "function") {
|
|
3414
|
-
ref(node);
|
|
3415
|
-
} else if (ref) {
|
|
3416
|
-
ref.current = node;
|
|
3417
|
-
}
|
|
3418
|
-
},
|
|
3419
|
-
className,
|
|
3420
|
-
onClick: handleClick,
|
|
3421
|
-
...props,
|
|
3422
|
-
children
|
|
3423
|
-
}
|
|
3424
|
-
);
|
|
3425
|
-
}
|
|
3426
|
-
);
|
|
3427
|
-
PopoverTrigger.displayName = "PopoverTrigger";
|
|
3428
|
-
var PopoverContent = React11.forwardRef(
|
|
3429
|
-
({
|
|
3430
|
-
className,
|
|
3431
|
-
side = "bottom",
|
|
3432
|
-
align = "start",
|
|
3433
|
-
sideOffset = 4,
|
|
3434
|
-
alignOffset = 0,
|
|
3435
|
-
children,
|
|
3436
|
-
...props
|
|
3437
|
-
}, ref) => {
|
|
3438
|
-
const { open, setOpen, triggerRef } = usePopoverContext();
|
|
3439
|
-
const [position, setPosition] = React11.useState({ top: 0, left: 0 });
|
|
3440
|
-
const contentRef = React11.useRef(null);
|
|
3441
|
-
React11.useEffect(() => {
|
|
3442
|
-
if (!open || !triggerRef.current) return;
|
|
3443
|
-
const updatePosition = () => {
|
|
3444
|
-
if (!triggerRef.current || !contentRef.current) return;
|
|
3445
|
-
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
3446
|
-
const contentRect = contentRef.current.getBoundingClientRect();
|
|
3447
|
-
const scrollX = window.scrollX;
|
|
3448
|
-
const scrollY = window.scrollY;
|
|
3449
|
-
let top = 0;
|
|
3450
|
-
let left = 0;
|
|
3451
|
-
switch (side) {
|
|
3452
|
-
case "bottom":
|
|
3453
|
-
top = triggerRect.bottom + sideOffset + scrollY;
|
|
3454
|
-
break;
|
|
3455
|
-
case "top":
|
|
3456
|
-
top = triggerRect.top - contentRect.height - sideOffset + scrollY;
|
|
3457
|
-
break;
|
|
3458
|
-
case "right":
|
|
3459
|
-
top = triggerRect.top + scrollY;
|
|
3460
|
-
left = triggerRect.right + sideOffset + scrollX;
|
|
3461
|
-
break;
|
|
3462
|
-
case "left":
|
|
3463
|
-
top = triggerRect.top + scrollY;
|
|
3464
|
-
left = triggerRect.left - contentRect.width - sideOffset + scrollX;
|
|
3465
|
-
break;
|
|
3466
|
-
}
|
|
3467
|
-
switch (align) {
|
|
3468
|
-
case "start":
|
|
3469
|
-
if (side === "top" || side === "bottom") {
|
|
3470
|
-
left = triggerRect.left + scrollX + alignOffset;
|
|
3471
|
-
} else {
|
|
3472
|
-
top += alignOffset;
|
|
3473
|
-
}
|
|
3474
|
-
break;
|
|
3475
|
-
case "center":
|
|
3476
|
-
if (side === "top" || side === "bottom") {
|
|
3477
|
-
left = triggerRect.left + triggerRect.width / 2 - contentRect.width / 2 + scrollX + alignOffset;
|
|
3478
|
-
} else {
|
|
3479
|
-
top += triggerRect.height / 2 - contentRect.height / 2 + alignOffset;
|
|
3480
|
-
}
|
|
3481
|
-
break;
|
|
3482
|
-
case "end":
|
|
3483
|
-
if (side === "top" || side === "bottom") {
|
|
3484
|
-
left = triggerRect.left + triggerRect.width - contentRect.width + scrollX + alignOffset;
|
|
3485
|
-
} else {
|
|
3486
|
-
top += triggerRect.height - contentRect.height + alignOffset;
|
|
3487
|
-
}
|
|
3488
|
-
break;
|
|
3489
|
-
}
|
|
3490
|
-
setPosition({ top, left });
|
|
3491
|
-
};
|
|
3492
|
-
requestAnimationFrame(() => {
|
|
3493
|
-
updatePosition();
|
|
3494
|
-
});
|
|
3495
|
-
window.addEventListener("resize", updatePosition);
|
|
3496
|
-
window.addEventListener("scroll", updatePosition, true);
|
|
3497
|
-
return () => {
|
|
3498
|
-
window.removeEventListener("resize", updatePosition);
|
|
3499
|
-
window.removeEventListener("scroll", updatePosition, true);
|
|
3500
|
-
};
|
|
3501
|
-
}, [open, side, align, sideOffset, alignOffset, triggerRef]);
|
|
3502
|
-
React11.useEffect(() => {
|
|
3503
|
-
if (!open) return;
|
|
3504
|
-
const handleClickOutside = (event) => {
|
|
3505
|
-
if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
3506
|
-
setOpen(false);
|
|
3507
|
-
}
|
|
3508
|
-
};
|
|
3509
|
-
const handleEscape = (event) => {
|
|
3510
|
-
if (event.key === "Escape") {
|
|
3511
|
-
setOpen(false);
|
|
3512
|
-
}
|
|
3513
|
-
};
|
|
3514
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
3515
|
-
document.addEventListener("keydown", handleEscape);
|
|
3516
|
-
return () => {
|
|
3517
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
3518
|
-
document.removeEventListener("keydown", handleEscape);
|
|
3519
|
-
};
|
|
3520
|
-
}, [open, setOpen, triggerRef]);
|
|
3521
|
-
if (!open) return null;
|
|
3522
|
-
const content = /* @__PURE__ */ jsx(
|
|
3523
|
-
"div",
|
|
3524
|
-
{
|
|
3525
|
-
ref: (node) => {
|
|
3526
|
-
contentRef.current = node;
|
|
3527
|
-
if (typeof ref === "function") {
|
|
3528
|
-
ref(node);
|
|
3529
|
-
} else if (ref) {
|
|
3530
|
-
ref.current = node;
|
|
3531
|
-
}
|
|
3532
|
-
},
|
|
3533
|
-
className: cn(
|
|
3534
|
-
"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",
|
|
3535
|
-
className
|
|
3536
|
-
),
|
|
3537
|
-
style: {
|
|
3538
|
-
position: "absolute",
|
|
3539
|
-
top: `${position.top}px`,
|
|
3540
|
-
left: `${position.left}px`
|
|
3541
|
-
},
|
|
3542
|
-
...props,
|
|
3543
|
-
children
|
|
3544
|
-
}
|
|
3545
|
-
);
|
|
3546
|
-
return createPortal(content, document.body);
|
|
3547
|
-
}
|
|
3548
|
-
);
|
|
3549
|
-
PopoverContent.displayName = "PopoverContent";
|
|
3550
3783
|
var ThreadPopover = ({
|
|
3551
3784
|
className,
|
|
3552
3785
|
buttonClassName,
|
|
@@ -3554,7 +3787,7 @@ var ThreadPopover = ({
|
|
|
3554
3787
|
buttonSize = "icon",
|
|
3555
3788
|
emptyState
|
|
3556
3789
|
}) => {
|
|
3557
|
-
const [isOpen, setIsOpen] =
|
|
3790
|
+
const [isOpen, setIsOpen] = React3.useState(false);
|
|
3558
3791
|
useHotkeys(
|
|
3559
3792
|
"h",
|
|
3560
3793
|
(e) => {
|
|
@@ -3597,7 +3830,7 @@ var CreateThreadButton = ({
|
|
|
3597
3830
|
onThreadCreated
|
|
3598
3831
|
}) => {
|
|
3599
3832
|
const { createThread } = useThreads();
|
|
3600
|
-
const [isCreating, setIsCreating] =
|
|
3833
|
+
const [isCreating, setIsCreating] = React3.useState(false);
|
|
3601
3834
|
const handleCreateThread = async () => {
|
|
3602
3835
|
if (isCreating) return;
|
|
3603
3836
|
try {
|
|
@@ -3679,7 +3912,7 @@ var CreateThreadListItem = ({
|
|
|
3679
3912
|
className
|
|
3680
3913
|
}) => {
|
|
3681
3914
|
const { createThread } = useThreads();
|
|
3682
|
-
const [isCreating, setIsCreating] =
|
|
3915
|
+
const [isCreating, setIsCreating] = React3.useState(false);
|
|
3683
3916
|
const handleCreateThread = async () => {
|
|
3684
3917
|
if (isCreating) return;
|
|
3685
3918
|
try {
|
|
@@ -3722,6 +3955,6 @@ var CreateThreadListItem = ({
|
|
|
3722
3955
|
);
|
|
3723
3956
|
};
|
|
3724
3957
|
|
|
3725
|
-
export { AccountButton, AuthContext, AuthProvider, Badge2 as Badge, Box, Button2 as Button, Card2 as Card, Chart, ChatHeader, Checkbox, Col, Composer, CreateThreadButton, CreateThreadListItem, Divider, Dropdown, Form, FullChat, Heading, Image, Input2 as Input, Label2 as Label, List, ListItem, MelonyContext, MelonyProvider, PopupChat, RadioGroup, Row, Select2 as Select, Sidebar, SidebarContext, SidebarProvider, SidebarToggle, Spacer, Text, Textarea2 as Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, ThreadList, ThreadPopover, ThreadProvider, UIRenderer, WelcomeScreen, useAuth, useMelony, useScreenSize, useSidebar, useTheme, useThreads };
|
|
3958
|
+
export { AccountButton, AuthContext, AuthProvider, Badge2 as Badge, Box, Button2 as Button, Card2 as Card, Chart, ChatHeader, Checkbox, Col, Composer, CreateThreadButton, CreateThreadListItem, Divider, Dropdown, Form, FullChat, Heading, Image, Input2 as Input, Label2 as Label, List, ListItem, MelonyContext, MelonyProvider, PopupChat, RadioGroup, Row, Select2 as Select, Sidebar, SidebarContext, SidebarProvider, SidebarToggle, Spacer, Text, Textarea2 as Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, ThreadList, ThreadPopover, ThreadProvider, UIRenderer, Upload, WelcomeScreen, useAuth, useMelony, useScreenSize, useSidebar, useTheme, useThreads };
|
|
3726
3959
|
//# sourceMappingURL=index.js.map
|
|
3727
3960
|
//# sourceMappingURL=index.js.map
|