@lukeashford/aurelius 3.8.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +163 -155
- package/dist/index.d.ts +163 -155
- package/dist/index.js +1093 -1292
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +483 -679
- package/dist/index.mjs.map +1 -1
- package/llms.md +12 -8
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -92,6 +92,147 @@ Input.displayName = "Input";
|
|
|
92
92
|
import React4, { createContext, useContext } from "react";
|
|
93
93
|
import { Check } from "lucide-react";
|
|
94
94
|
|
|
95
|
+
// src/utils/clipboard.ts
|
|
96
|
+
async function copyToClipboard(text) {
|
|
97
|
+
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
98
|
+
try {
|
|
99
|
+
await navigator.clipboard.writeText(text);
|
|
100
|
+
return true;
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (typeof document === "undefined") {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const textArea = document.createElement("textarea");
|
|
108
|
+
textArea.value = text;
|
|
109
|
+
textArea.setAttribute("readonly", "");
|
|
110
|
+
textArea.setAttribute("aria-hidden", "true");
|
|
111
|
+
textArea.style.position = "fixed";
|
|
112
|
+
textArea.style.opacity = "0";
|
|
113
|
+
textArea.style.pointerEvents = "none";
|
|
114
|
+
document.body.appendChild(textArea);
|
|
115
|
+
try {
|
|
116
|
+
textArea.select();
|
|
117
|
+
return document.execCommand("copy");
|
|
118
|
+
} catch {
|
|
119
|
+
return false;
|
|
120
|
+
} finally {
|
|
121
|
+
document.body.removeChild(textArea);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/utils/hooks.ts
|
|
126
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
127
|
+
function composeRefs(...refs) {
|
|
128
|
+
return (node) => {
|
|
129
|
+
for (const ref of refs) {
|
|
130
|
+
if (!ref) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (typeof ref === "function") {
|
|
134
|
+
ref(node);
|
|
135
|
+
} else {
|
|
136
|
+
;
|
|
137
|
+
ref.current = node;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
var scrollLockCount = 0;
|
|
143
|
+
var scrollLockOriginalOverflow = null;
|
|
144
|
+
var scrollLockOriginalPaddingRight = null;
|
|
145
|
+
function useScrollLock(isLocked) {
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
if (!isLocked || typeof document === "undefined") {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (scrollLockCount === 0) {
|
|
151
|
+
scrollLockOriginalOverflow = document.body.style.overflow;
|
|
152
|
+
scrollLockOriginalPaddingRight = document.body.style.paddingRight;
|
|
153
|
+
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
154
|
+
document.body.style.overflow = "hidden";
|
|
155
|
+
if (scrollbarWidth > 0) {
|
|
156
|
+
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
scrollLockCount++;
|
|
160
|
+
return () => {
|
|
161
|
+
scrollLockCount--;
|
|
162
|
+
if (scrollLockCount === 0) {
|
|
163
|
+
document.body.style.overflow = scrollLockOriginalOverflow ?? "";
|
|
164
|
+
document.body.style.paddingRight = scrollLockOriginalPaddingRight ?? "";
|
|
165
|
+
scrollLockOriginalOverflow = null;
|
|
166
|
+
scrollLockOriginalPaddingRight = null;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}, [isLocked]);
|
|
170
|
+
}
|
|
171
|
+
function useEscapeKey(onEscape, isActive = true) {
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (!isActive || typeof window === "undefined") {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const handler = (e) => {
|
|
177
|
+
if (e.key === "Escape") {
|
|
178
|
+
onEscape();
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
window.addEventListener("keydown", handler);
|
|
182
|
+
return () => window.removeEventListener("keydown", handler);
|
|
183
|
+
}, [onEscape, isActive]);
|
|
184
|
+
}
|
|
185
|
+
function useClickOutside(ref, handler, isActive = true) {
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
if (!isActive || typeof document === "undefined") {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const listener = (event) => {
|
|
191
|
+
const node = ref.current;
|
|
192
|
+
if (node && !node.contains(event.target)) {
|
|
193
|
+
handler(event);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
document.addEventListener("mousedown", listener);
|
|
197
|
+
return () => document.removeEventListener("mousedown", listener);
|
|
198
|
+
}, [ref, handler, isActive]);
|
|
199
|
+
}
|
|
200
|
+
function useCopyToClipboard(resetMs = 2e3) {
|
|
201
|
+
const [copied, setCopied] = useState(false);
|
|
202
|
+
const timerRef = useRef(null);
|
|
203
|
+
const mountedRef = useRef(true);
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
mountedRef.current = true;
|
|
206
|
+
return () => {
|
|
207
|
+
mountedRef.current = false;
|
|
208
|
+
if (timerRef.current !== null) {
|
|
209
|
+
clearTimeout(timerRef.current);
|
|
210
|
+
timerRef.current = null;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}, []);
|
|
214
|
+
const copy = useCallback(async (text) => {
|
|
215
|
+
const ok = await copyToClipboard(text);
|
|
216
|
+
if (!mountedRef.current) {
|
|
217
|
+
return ok;
|
|
218
|
+
}
|
|
219
|
+
if (ok) {
|
|
220
|
+
setCopied(true);
|
|
221
|
+
if (timerRef.current !== null) {
|
|
222
|
+
clearTimeout(timerRef.current);
|
|
223
|
+
}
|
|
224
|
+
timerRef.current = setTimeout(() => {
|
|
225
|
+
timerRef.current = null;
|
|
226
|
+
if (mountedRef.current) {
|
|
227
|
+
setCopied(false);
|
|
228
|
+
}
|
|
229
|
+
}, resetMs);
|
|
230
|
+
}
|
|
231
|
+
return ok;
|
|
232
|
+
}, [resetMs]);
|
|
233
|
+
return { copied, copy };
|
|
234
|
+
}
|
|
235
|
+
|
|
95
236
|
// src/components/Skeleton.tsx
|
|
96
237
|
import React3 from "react";
|
|
97
238
|
var Skeleton = React3.forwardRef(
|
|
@@ -116,8 +257,7 @@ function slotLoading(loading, path) {
|
|
|
116
257
|
return false;
|
|
117
258
|
}
|
|
118
259
|
if (Array.isArray(path)) {
|
|
119
|
-
|
|
120
|
-
return !!loading[section]?.[field];
|
|
260
|
+
return !!loading.header?.[path[1]];
|
|
121
261
|
}
|
|
122
262
|
return !!loading[path];
|
|
123
263
|
}
|
|
@@ -1393,29 +1533,28 @@ var Select = React20.forwardRef(
|
|
|
1393
1533
|
Select.displayName = "Select";
|
|
1394
1534
|
|
|
1395
1535
|
// src/components/Checkbox.tsx
|
|
1396
|
-
import React21, { useCallback } from "react";
|
|
1536
|
+
import React21, { useCallback as useCallback2, useId } from "react";
|
|
1397
1537
|
var checkmarkSvg = `url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='%231A1A1A' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e")`;
|
|
1398
1538
|
var Checkbox = React21.forwardRef(
|
|
1399
|
-
({ className, label, id, ...rest }, ref) => {
|
|
1400
|
-
const
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
if (typeof ref === "function") {
|
|
1408
|
-
ref(node);
|
|
1409
|
-
} else if (ref) {
|
|
1410
|
-
ref.current = node;
|
|
1539
|
+
({ className, label, id, onChange, ...rest }, ref) => {
|
|
1540
|
+
const generatedId = useId();
|
|
1541
|
+
const inputId = id || rest.name || generatedId;
|
|
1542
|
+
const initBackground = useCallback2((node) => {
|
|
1543
|
+
if (node && node.checked) {
|
|
1544
|
+
node.style.backgroundImage = checkmarkSvg;
|
|
1411
1545
|
}
|
|
1412
|
-
}, [
|
|
1546
|
+
}, []);
|
|
1547
|
+
const handleChange = useCallback2((e) => {
|
|
1548
|
+
e.currentTarget.style.backgroundImage = e.currentTarget.checked ? checkmarkSvg : "none";
|
|
1549
|
+
onChange?.(e);
|
|
1550
|
+
}, [onChange]);
|
|
1413
1551
|
return /* @__PURE__ */ React21.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React21.createElement(
|
|
1414
1552
|
"input",
|
|
1415
1553
|
{
|
|
1554
|
+
...rest,
|
|
1416
1555
|
type: "checkbox",
|
|
1417
1556
|
id: inputId,
|
|
1418
|
-
ref:
|
|
1557
|
+
ref: composeRefs(initBackground, ref),
|
|
1419
1558
|
className: cx(
|
|
1420
1559
|
"appearance-none h-4 w-4 border border-ash bg-graphite",
|
|
1421
1560
|
"checked:bg-gold checked:border-gold",
|
|
@@ -1429,16 +1568,7 @@ var Checkbox = React21.forwardRef(
|
|
|
1429
1568
|
backgroundSize: "contain",
|
|
1430
1569
|
backgroundRepeat: "no-repeat"
|
|
1431
1570
|
},
|
|
1432
|
-
onChange:
|
|
1433
|
-
const input = e.currentTarget;
|
|
1434
|
-
if (input.checked) {
|
|
1435
|
-
input.style.backgroundImage = checkmarkSvg;
|
|
1436
|
-
} else {
|
|
1437
|
-
input.style.backgroundImage = "none";
|
|
1438
|
-
}
|
|
1439
|
-
rest.onChange?.(e);
|
|
1440
|
-
},
|
|
1441
|
-
...rest
|
|
1571
|
+
onChange: handleChange
|
|
1442
1572
|
}
|
|
1443
1573
|
), label && /* @__PURE__ */ React21.createElement(
|
|
1444
1574
|
"label",
|
|
@@ -1453,29 +1583,44 @@ var Checkbox = React21.forwardRef(
|
|
|
1453
1583
|
Checkbox.displayName = "Checkbox";
|
|
1454
1584
|
|
|
1455
1585
|
// src/components/Radio.tsx
|
|
1456
|
-
import React22, { useCallback as
|
|
1586
|
+
import React22, { useCallback as useCallback3, useId as useId2 } from "react";
|
|
1457
1587
|
var radioDotSvg = `url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='%231A1A1A' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e")`;
|
|
1458
1588
|
var Radio = React22.forwardRef(
|
|
1459
|
-
({ className, label, id, ...rest }, ref) => {
|
|
1460
|
-
const
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
}
|
|
1589
|
+
({ className, label, id, onChange, ...rest }, ref) => {
|
|
1590
|
+
const generatedId = useId2();
|
|
1591
|
+
const inputId = id || rest.name || generatedId;
|
|
1592
|
+
const initBackground = useCallback3((node) => {
|
|
1593
|
+
if (node && node.checked) {
|
|
1594
|
+
node.style.backgroundImage = radioDotSvg;
|
|
1466
1595
|
}
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1596
|
+
}, []);
|
|
1597
|
+
const handleChange = useCallback3((e) => {
|
|
1598
|
+
const input = e.currentTarget;
|
|
1599
|
+
if (input.checked) {
|
|
1600
|
+
input.style.backgroundImage = radioDotSvg;
|
|
1601
|
+
if (input.name) {
|
|
1602
|
+
const escaped = typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(input.name) : input.name.replace(/["\\\]]/g, "\\$&");
|
|
1603
|
+
const radios = input.ownerDocument.querySelectorAll(
|
|
1604
|
+
`input[type="radio"][name="${escaped}"]`
|
|
1605
|
+
);
|
|
1606
|
+
radios.forEach((radio) => {
|
|
1607
|
+
if (radio !== input) {
|
|
1608
|
+
radio.style.backgroundImage = "none";
|
|
1609
|
+
}
|
|
1610
|
+
});
|
|
1611
|
+
}
|
|
1612
|
+
} else {
|
|
1613
|
+
input.style.backgroundImage = "none";
|
|
1471
1614
|
}
|
|
1472
|
-
|
|
1615
|
+
onChange?.(e);
|
|
1616
|
+
}, [onChange]);
|
|
1473
1617
|
return /* @__PURE__ */ React22.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React22.createElement(
|
|
1474
1618
|
"input",
|
|
1475
1619
|
{
|
|
1620
|
+
...rest,
|
|
1476
1621
|
type: "radio",
|
|
1477
1622
|
id: inputId,
|
|
1478
|
-
ref:
|
|
1623
|
+
ref: composeRefs(initBackground, ref),
|
|
1479
1624
|
className: cx(
|
|
1480
1625
|
"appearance-none h-4 w-4 border border-ash rounded-full bg-graphite",
|
|
1481
1626
|
"checked:bg-gold checked:border-gold",
|
|
@@ -1489,26 +1634,7 @@ var Radio = React22.forwardRef(
|
|
|
1489
1634
|
backgroundSize: "contain",
|
|
1490
1635
|
backgroundRepeat: "no-repeat"
|
|
1491
1636
|
},
|
|
1492
|
-
onChange:
|
|
1493
|
-
const input = e.currentTarget;
|
|
1494
|
-
if (input.checked) {
|
|
1495
|
-
input.style.backgroundImage = radioDotSvg;
|
|
1496
|
-
if (input.name) {
|
|
1497
|
-
const radios = document.querySelectorAll(
|
|
1498
|
-
`input[type="radio"][name="${input.name}"]`
|
|
1499
|
-
);
|
|
1500
|
-
radios.forEach((radio) => {
|
|
1501
|
-
if (radio !== input) {
|
|
1502
|
-
radio.style.backgroundImage = "none";
|
|
1503
|
-
}
|
|
1504
|
-
});
|
|
1505
|
-
}
|
|
1506
|
-
} else {
|
|
1507
|
-
input.style.backgroundImage = "none";
|
|
1508
|
-
}
|
|
1509
|
-
rest.onChange?.(e);
|
|
1510
|
-
},
|
|
1511
|
-
...rest
|
|
1637
|
+
onChange: handleChange
|
|
1512
1638
|
}
|
|
1513
1639
|
), label && /* @__PURE__ */ React22.createElement(
|
|
1514
1640
|
"label",
|
|
@@ -1523,7 +1649,7 @@ var Radio = React22.forwardRef(
|
|
|
1523
1649
|
Radio.displayName = "Radio";
|
|
1524
1650
|
|
|
1525
1651
|
// src/components/Switch.tsx
|
|
1526
|
-
import React23, { useCallback as
|
|
1652
|
+
import React23, { useCallback as useCallback4, useRef as useRef2, useState as useState2 } from "react";
|
|
1527
1653
|
var Switch = React23.forwardRef(
|
|
1528
1654
|
({
|
|
1529
1655
|
checked: controlledChecked,
|
|
@@ -1534,11 +1660,11 @@ var Switch = React23.forwardRef(
|
|
|
1534
1660
|
label,
|
|
1535
1661
|
...rest
|
|
1536
1662
|
}, ref) => {
|
|
1537
|
-
const [internalChecked, setInternalChecked] =
|
|
1663
|
+
const [internalChecked, setInternalChecked] = useState2(defaultChecked);
|
|
1538
1664
|
const isControlled = controlledChecked !== void 0;
|
|
1539
1665
|
const checked = isControlled ? controlledChecked : internalChecked;
|
|
1540
|
-
const buttonRef =
|
|
1541
|
-
const setRefs =
|
|
1666
|
+
const buttonRef = useRef2(null);
|
|
1667
|
+
const setRefs = useCallback4(
|
|
1542
1668
|
(node) => {
|
|
1543
1669
|
buttonRef.current = node;
|
|
1544
1670
|
if (typeof ref === "function") {
|
|
@@ -1608,7 +1734,7 @@ var Switch = React23.forwardRef(
|
|
|
1608
1734
|
Switch.displayName = "Switch";
|
|
1609
1735
|
|
|
1610
1736
|
// src/components/Slider.tsx
|
|
1611
|
-
import React24, { useCallback as
|
|
1737
|
+
import React24, { useCallback as useCallback5, useRef as useRef3, useState as useState3 } from "react";
|
|
1612
1738
|
var SIZE_TRACK = {
|
|
1613
1739
|
sm: "h-1",
|
|
1614
1740
|
md: "h-2",
|
|
@@ -1635,13 +1761,13 @@ var Slider = React24.forwardRef(
|
|
|
1635
1761
|
className,
|
|
1636
1762
|
...props
|
|
1637
1763
|
}, ref) => {
|
|
1638
|
-
const [internalValue, setInternalValue] =
|
|
1639
|
-
const [isDragging, setIsDragging] =
|
|
1640
|
-
const trackRef =
|
|
1764
|
+
const [internalValue, setInternalValue] = useState3(defaultValue);
|
|
1765
|
+
const [isDragging, setIsDragging] = useState3(false);
|
|
1766
|
+
const trackRef = useRef3(null);
|
|
1641
1767
|
const isControlled = controlledValue !== void 0;
|
|
1642
1768
|
const value = isControlled ? controlledValue : internalValue;
|
|
1643
1769
|
const percentage = (value - min) / (max - min) * 100;
|
|
1644
|
-
const updateValue =
|
|
1770
|
+
const updateValue = useCallback5(
|
|
1645
1771
|
(clientX) => {
|
|
1646
1772
|
if (!trackRef.current || disabled) {
|
|
1647
1773
|
return;
|
|
@@ -1997,16 +2123,21 @@ var Progress = React28.forwardRef(
|
|
|
1997
2123
|
Progress.displayName = "Progress";
|
|
1998
2124
|
|
|
1999
2125
|
// src/components/Toast.tsx
|
|
2000
|
-
import React29, { createContext as createContext2, useCallback as
|
|
2126
|
+
import React29, { createContext as createContext2, useCallback as useCallback6, useContext as useContext2, useEffect as useEffect2, useState as useState4 } from "react";
|
|
2001
2127
|
import { createPortal } from "react-dom";
|
|
2002
2128
|
import { AlertCircle, AlertTriangle as AlertTriangle2, CheckCircle as CheckCircle2, Info as Info2, X as X2 } from "lucide-react";
|
|
2129
|
+
var toastCounter = 0;
|
|
2130
|
+
function createToastId() {
|
|
2131
|
+
toastCounter += 1;
|
|
2132
|
+
return `toast-${Date.now().toString(36)}-${toastCounter}`;
|
|
2133
|
+
}
|
|
2003
2134
|
var ToastContext = createContext2(null);
|
|
2004
2135
|
function useToast() {
|
|
2005
2136
|
const context = useContext2(ToastContext);
|
|
2006
2137
|
if (!context) {
|
|
2007
2138
|
throw new Error("useToast must be used within a ToastProvider");
|
|
2008
2139
|
}
|
|
2009
|
-
const toast =
|
|
2140
|
+
const toast = useCallback6(
|
|
2010
2141
|
(options) => {
|
|
2011
2142
|
return context.addToast(options);
|
|
2012
2143
|
},
|
|
@@ -2022,14 +2153,14 @@ var ToastProvider = ({
|
|
|
2022
2153
|
position = "bottom-right",
|
|
2023
2154
|
defaultDuration = 5e3
|
|
2024
2155
|
}) => {
|
|
2025
|
-
const [toasts, setToasts] =
|
|
2026
|
-
const [mounted, setMounted] =
|
|
2027
|
-
|
|
2156
|
+
const [toasts, setToasts] = useState4([]);
|
|
2157
|
+
const [mounted, setMounted] = useState4(false);
|
|
2158
|
+
useEffect2(() => {
|
|
2028
2159
|
setMounted(true);
|
|
2029
2160
|
}, []);
|
|
2030
|
-
const addToast =
|
|
2161
|
+
const addToast = useCallback6(
|
|
2031
2162
|
(toast) => {
|
|
2032
|
-
const id =
|
|
2163
|
+
const id = createToastId();
|
|
2033
2164
|
const newToast = {
|
|
2034
2165
|
...toast,
|
|
2035
2166
|
id,
|
|
@@ -2040,33 +2171,33 @@ var ToastProvider = ({
|
|
|
2040
2171
|
},
|
|
2041
2172
|
[defaultDuration]
|
|
2042
2173
|
);
|
|
2043
|
-
const removeToast =
|
|
2174
|
+
const removeToast = useCallback6((id) => {
|
|
2044
2175
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
2045
2176
|
}, []);
|
|
2046
2177
|
return /* @__PURE__ */ React29.createElement(ToastContext.Provider, { value: { toasts, addToast, removeToast, position } }, children, mounted && /* @__PURE__ */ React29.createElement(ToastViewport, null));
|
|
2047
2178
|
};
|
|
2048
2179
|
ToastProvider.displayName = "ToastProvider";
|
|
2180
|
+
var POSITION_CLASSES = {
|
|
2181
|
+
"top-right": "top-4 right-4",
|
|
2182
|
+
"top-left": "top-4 left-4",
|
|
2183
|
+
"bottom-right": "bottom-4 right-4",
|
|
2184
|
+
"bottom-left": "bottom-4 left-4",
|
|
2185
|
+
"top-center": "top-4 left-1/2 -translate-x-1/2",
|
|
2186
|
+
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
2187
|
+
};
|
|
2049
2188
|
var ToastViewport = () => {
|
|
2050
2189
|
const context = useContext2(ToastContext);
|
|
2051
2190
|
if (!context) {
|
|
2052
2191
|
return null;
|
|
2053
2192
|
}
|
|
2054
2193
|
const { toasts, position } = context;
|
|
2055
|
-
const positionClasses = {
|
|
2056
|
-
"top-right": "top-4 right-4",
|
|
2057
|
-
"top-left": "top-4 left-4",
|
|
2058
|
-
"bottom-right": "bottom-4 right-4",
|
|
2059
|
-
"bottom-left": "bottom-4 left-4",
|
|
2060
|
-
"top-center": "top-4 left-1/2 -translate-x-1/2",
|
|
2061
|
-
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
2062
|
-
};
|
|
2063
2194
|
return createPortal(
|
|
2064
2195
|
/* @__PURE__ */ React29.createElement(
|
|
2065
2196
|
"div",
|
|
2066
2197
|
{
|
|
2067
2198
|
className: cx(
|
|
2068
2199
|
"fixed z-50 flex flex-col gap-2 pointer-events-none",
|
|
2069
|
-
|
|
2200
|
+
POSITION_CLASSES[position]
|
|
2070
2201
|
)
|
|
2071
2202
|
},
|
|
2072
2203
|
toasts.map((toast) => /* @__PURE__ */ React29.createElement(Toast, { key: toast.id, ...toast }))
|
|
@@ -2097,7 +2228,7 @@ var Toast = ({
|
|
|
2097
2228
|
action
|
|
2098
2229
|
}) => {
|
|
2099
2230
|
const context = useContext2(ToastContext);
|
|
2100
|
-
|
|
2231
|
+
useEffect2(() => {
|
|
2101
2232
|
if (duration && duration > 0) {
|
|
2102
2233
|
const timer = setTimeout(() => {
|
|
2103
2234
|
context?.removeToast(id);
|
|
@@ -2129,41 +2260,17 @@ var Toast = ({
|
|
|
2129
2260
|
Toast.displayName = "Toast";
|
|
2130
2261
|
|
|
2131
2262
|
// src/components/Modal.tsx
|
|
2132
|
-
import React30, { useEffect as
|
|
2263
|
+
import React30, { useEffect as useEffect3, useState as useState5 } from "react";
|
|
2133
2264
|
import { createPortal as createPortal2 } from "react-dom";
|
|
2134
2265
|
import { X as X3 } from "lucide-react";
|
|
2135
2266
|
var Modal = ({ isOpen, onClose, title, children, className }) => {
|
|
2136
|
-
const [mounted, setMounted] =
|
|
2137
|
-
|
|
2267
|
+
const [mounted, setMounted] = useState5(false);
|
|
2268
|
+
useEffect3(() => {
|
|
2138
2269
|
setMounted(true);
|
|
2139
2270
|
}, []);
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
document.body.style.overflow = "hidden";
|
|
2144
|
-
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
2145
|
-
} else {
|
|
2146
|
-
document.body.style.overflow = "unset";
|
|
2147
|
-
document.body.style.paddingRight = "0px";
|
|
2148
|
-
}
|
|
2149
|
-
return () => {
|
|
2150
|
-
document.body.style.overflow = "unset";
|
|
2151
|
-
document.body.style.paddingRight = "0px";
|
|
2152
|
-
};
|
|
2153
|
-
}, [isOpen]);
|
|
2154
|
-
useEffect2(() => {
|
|
2155
|
-
const handleEsc = (e) => {
|
|
2156
|
-
if (e.key === "Escape") {
|
|
2157
|
-
onClose();
|
|
2158
|
-
}
|
|
2159
|
-
};
|
|
2160
|
-
window.addEventListener("keydown", handleEsc);
|
|
2161
|
-
return () => window.removeEventListener("keydown", handleEsc);
|
|
2162
|
-
}, [onClose]);
|
|
2163
|
-
if (!mounted) {
|
|
2164
|
-
return null;
|
|
2165
|
-
}
|
|
2166
|
-
if (!isOpen) {
|
|
2271
|
+
useScrollLock(isOpen);
|
|
2272
|
+
useEscapeKey(onClose, isOpen);
|
|
2273
|
+
if (!mounted || !isOpen) {
|
|
2167
2274
|
return null;
|
|
2168
2275
|
}
|
|
2169
2276
|
const content = /* @__PURE__ */ React30.createElement(
|
|
@@ -2202,7 +2309,7 @@ var Modal = ({ isOpen, onClose, title, children, className }) => {
|
|
|
2202
2309
|
Modal.displayName = "Modal";
|
|
2203
2310
|
|
|
2204
2311
|
// src/components/Drawer.tsx
|
|
2205
|
-
import React31, { useEffect as
|
|
2312
|
+
import React31, { useEffect as useEffect4, useState as useState6 } from "react";
|
|
2206
2313
|
import { createPortal as createPortal3 } from "react-dom";
|
|
2207
2314
|
import { X as X4 } from "lucide-react";
|
|
2208
2315
|
var SIZE_MAP2 = {
|
|
@@ -2237,7 +2344,7 @@ var SIZE_MAP2 = {
|
|
|
2237
2344
|
bottom: "h-full"
|
|
2238
2345
|
}
|
|
2239
2346
|
};
|
|
2240
|
-
var
|
|
2347
|
+
var POSITION_CLASSES2 = {
|
|
2241
2348
|
left: "left-0 top-0 h-full",
|
|
2242
2349
|
right: "right-0 top-0 h-full",
|
|
2243
2350
|
top: "top-0 left-0 w-full",
|
|
@@ -2258,33 +2365,12 @@ var Drawer = ({
|
|
|
2258
2365
|
children,
|
|
2259
2366
|
className
|
|
2260
2367
|
}) => {
|
|
2261
|
-
const [mounted, setMounted] =
|
|
2262
|
-
|
|
2368
|
+
const [mounted, setMounted] = useState6(false);
|
|
2369
|
+
useEffect4(() => {
|
|
2263
2370
|
setMounted(true);
|
|
2264
2371
|
}, []);
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
2268
|
-
document.body.style.overflow = "hidden";
|
|
2269
|
-
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
2270
|
-
} else {
|
|
2271
|
-
document.body.style.overflow = "unset";
|
|
2272
|
-
document.body.style.paddingRight = "0px";
|
|
2273
|
-
}
|
|
2274
|
-
return () => {
|
|
2275
|
-
document.body.style.overflow = "unset";
|
|
2276
|
-
document.body.style.paddingRight = "0px";
|
|
2277
|
-
};
|
|
2278
|
-
}, [isOpen]);
|
|
2279
|
-
useEffect3(() => {
|
|
2280
|
-
const handleEsc = (e) => {
|
|
2281
|
-
if (e.key === "Escape") {
|
|
2282
|
-
onClose();
|
|
2283
|
-
}
|
|
2284
|
-
};
|
|
2285
|
-
window.addEventListener("keydown", handleEsc);
|
|
2286
|
-
return () => window.removeEventListener("keydown", handleEsc);
|
|
2287
|
-
}, [onClose]);
|
|
2372
|
+
useScrollLock(isOpen);
|
|
2373
|
+
useEscapeKey(onClose, isOpen);
|
|
2288
2374
|
if (!mounted) {
|
|
2289
2375
|
return null;
|
|
2290
2376
|
}
|
|
@@ -2315,7 +2401,7 @@ var Drawer = ({
|
|
|
2315
2401
|
className: cx(
|
|
2316
2402
|
"fixed bg-charcoal border-ash shadow-2xl flex flex-col",
|
|
2317
2403
|
"transition-transform duration-300 ease-out",
|
|
2318
|
-
|
|
2404
|
+
POSITION_CLASSES2[position],
|
|
2319
2405
|
SIZE_MAP2[size][position],
|
|
2320
2406
|
position === "left" && "border-r",
|
|
2321
2407
|
position === "right" && "border-l",
|
|
@@ -2342,8 +2428,8 @@ var Drawer = ({
|
|
|
2342
2428
|
Drawer.displayName = "Drawer";
|
|
2343
2429
|
|
|
2344
2430
|
// src/components/Popover.tsx
|
|
2345
|
-
import React32, { useCallback as
|
|
2346
|
-
var
|
|
2431
|
+
import React32, { useCallback as useCallback7, useId as useId3, useRef as useRef4, useState as useState7 } from "react";
|
|
2432
|
+
var POSITION_CLASSES3 = {
|
|
2347
2433
|
top: {
|
|
2348
2434
|
start: "bottom-full left-0 mb-2",
|
|
2349
2435
|
center: "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
@@ -2374,12 +2460,12 @@ var Popover = ({
|
|
|
2374
2460
|
onOpenChange,
|
|
2375
2461
|
closeOnClickOutside = true
|
|
2376
2462
|
}) => {
|
|
2377
|
-
const [internalOpen, setInternalOpen] =
|
|
2463
|
+
const [internalOpen, setInternalOpen] = useState7(false);
|
|
2378
2464
|
const isControlled = controlledOpen !== void 0;
|
|
2379
2465
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
2380
|
-
const containerRef =
|
|
2381
|
-
const baseId =
|
|
2382
|
-
const setIsOpen =
|
|
2466
|
+
const containerRef = useRef4(null);
|
|
2467
|
+
const baseId = useId3();
|
|
2468
|
+
const setIsOpen = useCallback7(
|
|
2383
2469
|
(newOpen) => {
|
|
2384
2470
|
if (!isControlled) {
|
|
2385
2471
|
setInternalOpen(newOpen);
|
|
@@ -2388,30 +2474,9 @@ var Popover = ({
|
|
|
2388
2474
|
},
|
|
2389
2475
|
[isControlled, onOpenChange]
|
|
2390
2476
|
);
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
}
|
|
2395
|
-
const handleClickOutside = (e) => {
|
|
2396
|
-
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
2397
|
-
setIsOpen(false);
|
|
2398
|
-
}
|
|
2399
|
-
};
|
|
2400
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
2401
|
-
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2402
|
-
}, [isOpen, closeOnClickOutside, setIsOpen]);
|
|
2403
|
-
useEffect4(() => {
|
|
2404
|
-
if (!isOpen) {
|
|
2405
|
-
return;
|
|
2406
|
-
}
|
|
2407
|
-
const handleEscape = (e) => {
|
|
2408
|
-
if (e.key === "Escape") {
|
|
2409
|
-
setIsOpen(false);
|
|
2410
|
-
}
|
|
2411
|
-
};
|
|
2412
|
-
document.addEventListener("keydown", handleEscape);
|
|
2413
|
-
return () => document.removeEventListener("keydown", handleEscape);
|
|
2414
|
-
}, [isOpen, setIsOpen]);
|
|
2477
|
+
const close = useCallback7(() => setIsOpen(false), [setIsOpen]);
|
|
2478
|
+
useClickOutside(containerRef, close, isOpen && closeOnClickOutside);
|
|
2479
|
+
useEscapeKey(close, isOpen);
|
|
2415
2480
|
const handleTriggerClick = () => {
|
|
2416
2481
|
setIsOpen(!isOpen);
|
|
2417
2482
|
};
|
|
@@ -2432,7 +2497,7 @@ var Popover = ({
|
|
|
2432
2497
|
"absolute z-50 min-w-48 p-4",
|
|
2433
2498
|
"bg-charcoal border border-ash shadow-lg",
|
|
2434
2499
|
"animate-fade-in",
|
|
2435
|
-
|
|
2500
|
+
POSITION_CLASSES3[position][align]
|
|
2436
2501
|
)
|
|
2437
2502
|
},
|
|
2438
2503
|
children
|
|
@@ -2441,7 +2506,7 @@ var Popover = ({
|
|
|
2441
2506
|
Popover.displayName = "Popover";
|
|
2442
2507
|
|
|
2443
2508
|
// src/components/Dialog.tsx
|
|
2444
|
-
import React33, { useCallback as
|
|
2509
|
+
import React33, { useCallback as useCallback8 } from "react";
|
|
2445
2510
|
var ConfirmDialog = ({
|
|
2446
2511
|
title = "Confirm",
|
|
2447
2512
|
description,
|
|
@@ -2454,11 +2519,11 @@ var ConfirmDialog = ({
|
|
|
2454
2519
|
isLoading = false,
|
|
2455
2520
|
...props
|
|
2456
2521
|
}) => {
|
|
2457
|
-
const handleCancel =
|
|
2522
|
+
const handleCancel = useCallback8(() => {
|
|
2458
2523
|
onCancel?.();
|
|
2459
2524
|
onClose();
|
|
2460
2525
|
}, [onCancel, onClose]);
|
|
2461
|
-
const handleConfirm =
|
|
2526
|
+
const handleConfirm = useCallback8(async () => {
|
|
2462
2527
|
await onConfirm();
|
|
2463
2528
|
onClose();
|
|
2464
2529
|
}, [onConfirm, onClose]);
|
|
@@ -2502,11 +2567,11 @@ var PromptDialog = ({
|
|
|
2502
2567
|
...props
|
|
2503
2568
|
}) => {
|
|
2504
2569
|
const [value, setValue] = React33.useState(defaultValue);
|
|
2505
|
-
const handleCancel =
|
|
2570
|
+
const handleCancel = useCallback8(() => {
|
|
2506
2571
|
onCancel?.();
|
|
2507
2572
|
onClose();
|
|
2508
2573
|
}, [onCancel, onClose]);
|
|
2509
|
-
const handleSubmit =
|
|
2574
|
+
const handleSubmit = useCallback8(
|
|
2510
2575
|
async (e) => {
|
|
2511
2576
|
e.preventDefault();
|
|
2512
2577
|
await onSubmit(value);
|
|
@@ -2543,7 +2608,7 @@ var PromptDialog = ({
|
|
|
2543
2608
|
PromptDialog.displayName = "PromptDialog";
|
|
2544
2609
|
|
|
2545
2610
|
// src/components/Tabs.tsx
|
|
2546
|
-
import React34, { createContext as createContext3, useCallback as
|
|
2611
|
+
import React34, { createContext as createContext3, useCallback as useCallback9, useContext as useContext3, useId as useId4, useState as useState8 } from "react";
|
|
2547
2612
|
var TabsContext = createContext3(null);
|
|
2548
2613
|
function useTabsContext() {
|
|
2549
2614
|
const context = useContext3(TabsContext);
|
|
@@ -2554,11 +2619,11 @@ function useTabsContext() {
|
|
|
2554
2619
|
}
|
|
2555
2620
|
var Tabs = React34.forwardRef(
|
|
2556
2621
|
({ defaultValue, value, onValueChange, children, className, ...props }, ref) => {
|
|
2557
|
-
const [internalValue, setInternalValue] =
|
|
2622
|
+
const [internalValue, setInternalValue] = useState8(defaultValue ?? "");
|
|
2558
2623
|
const isControlled = value !== void 0;
|
|
2559
2624
|
const activeTab = isControlled ? value : internalValue;
|
|
2560
|
-
const baseId =
|
|
2561
|
-
const setActiveTab =
|
|
2625
|
+
const baseId = useId4();
|
|
2626
|
+
const setActiveTab = useCallback9(
|
|
2562
2627
|
(id) => {
|
|
2563
2628
|
if (!isControlled) {
|
|
2564
2629
|
setInternalValue(id);
|
|
@@ -2654,7 +2719,7 @@ var TabPanel = React34.forwardRef(
|
|
|
2654
2719
|
TabPanel.displayName = "TabPanel";
|
|
2655
2720
|
|
|
2656
2721
|
// src/components/Accordion.tsx
|
|
2657
|
-
import React35, { createContext as createContext4, useCallback as
|
|
2722
|
+
import React35, { createContext as createContext4, useCallback as useCallback10, useContext as useContext4, useId as useId5, useState as useState9 } from "react";
|
|
2658
2723
|
import { ChevronDown } from "lucide-react";
|
|
2659
2724
|
var AccordionContext = createContext4(null);
|
|
2660
2725
|
function useAccordionContext() {
|
|
@@ -2666,7 +2731,7 @@ function useAccordionContext() {
|
|
|
2666
2731
|
}
|
|
2667
2732
|
var Accordion = React35.forwardRef(
|
|
2668
2733
|
({ type = "single", defaultValue, value, onValueChange, children, className, ...props }, ref) => {
|
|
2669
|
-
const [internalValue, setInternalValue] =
|
|
2734
|
+
const [internalValue, setInternalValue] = useState9(() => {
|
|
2670
2735
|
if (defaultValue) {
|
|
2671
2736
|
return new Set(Array.isArray(defaultValue) ? defaultValue : [defaultValue]);
|
|
2672
2737
|
}
|
|
@@ -2674,7 +2739,7 @@ var Accordion = React35.forwardRef(
|
|
|
2674
2739
|
});
|
|
2675
2740
|
const isControlled = value !== void 0;
|
|
2676
2741
|
const expandedItems = isControlled ? new Set(Array.isArray(value) ? value : [value]) : internalValue;
|
|
2677
|
-
const toggleItem =
|
|
2742
|
+
const toggleItem = useCallback10(
|
|
2678
2743
|
(id) => {
|
|
2679
2744
|
const newSet = new Set(expandedItems);
|
|
2680
2745
|
if (newSet.has(id)) {
|
|
@@ -2725,7 +2790,7 @@ var AccordionTrigger = React35.forwardRef(
|
|
|
2725
2790
|
({ children, className, ...props }, ref) => {
|
|
2726
2791
|
const { expandedItems, toggleItem } = useAccordionContext();
|
|
2727
2792
|
const itemContext = useContext4(AccordionItemContext);
|
|
2728
|
-
const baseId =
|
|
2793
|
+
const baseId = useId5();
|
|
2729
2794
|
if (!itemContext) {
|
|
2730
2795
|
throw new Error("AccordionTrigger must be used within an AccordionItem");
|
|
2731
2796
|
}
|
|
@@ -2770,7 +2835,7 @@ var AccordionContent = React35.forwardRef(
|
|
|
2770
2835
|
({ children, className, ...props }, ref) => {
|
|
2771
2836
|
const { expandedItems } = useAccordionContext();
|
|
2772
2837
|
const itemContext = useContext4(AccordionItemContext);
|
|
2773
|
-
const baseId =
|
|
2838
|
+
const baseId = useId5();
|
|
2774
2839
|
if (!itemContext) {
|
|
2775
2840
|
throw new Error("AccordionContent must be used within an AccordionItem");
|
|
2776
2841
|
}
|
|
@@ -2800,12 +2865,12 @@ AccordionContent.displayName = "AccordionContent";
|
|
|
2800
2865
|
// src/components/Menu.tsx
|
|
2801
2866
|
import React36, {
|
|
2802
2867
|
createContext as createContext5,
|
|
2803
|
-
useCallback as
|
|
2868
|
+
useCallback as useCallback11,
|
|
2804
2869
|
useContext as useContext5,
|
|
2805
2870
|
useEffect as useEffect5,
|
|
2806
|
-
useId as
|
|
2807
|
-
useRef as
|
|
2808
|
-
useState as
|
|
2871
|
+
useId as useId6,
|
|
2872
|
+
useRef as useRef5,
|
|
2873
|
+
useState as useState10
|
|
2809
2874
|
} from "react";
|
|
2810
2875
|
var MenuContext = createContext5(null);
|
|
2811
2876
|
function useMenuContext() {
|
|
@@ -2816,11 +2881,11 @@ function useMenuContext() {
|
|
|
2816
2881
|
return context;
|
|
2817
2882
|
}
|
|
2818
2883
|
var Menu = ({ children, open, onOpenChange }) => {
|
|
2819
|
-
const [internalOpen, setInternalOpen] =
|
|
2884
|
+
const [internalOpen, setInternalOpen] = useState10(false);
|
|
2820
2885
|
const isControlled = open !== void 0;
|
|
2821
2886
|
const isOpen = isControlled ? open : internalOpen;
|
|
2822
|
-
const baseId =
|
|
2823
|
-
const setIsOpen =
|
|
2887
|
+
const baseId = useId6();
|
|
2888
|
+
const setIsOpen = useCallback11(
|
|
2824
2889
|
(newOpen) => {
|
|
2825
2890
|
if (!isControlled) {
|
|
2826
2891
|
setInternalOpen(newOpen);
|
|
@@ -2872,55 +2937,42 @@ var MenuTrigger = React36.forwardRef(
|
|
|
2872
2937
|
}
|
|
2873
2938
|
);
|
|
2874
2939
|
MenuTrigger.displayName = "MenuTrigger";
|
|
2940
|
+
var MENU_ALIGN_CLASSES = {
|
|
2941
|
+
start: "left-0",
|
|
2942
|
+
center: "left-1/2 -translate-x-1/2",
|
|
2943
|
+
end: "right-0"
|
|
2944
|
+
};
|
|
2945
|
+
var MENU_SIDE_CLASSES = {
|
|
2946
|
+
top: "bottom-full mb-1",
|
|
2947
|
+
bottom: "top-full mt-1"
|
|
2948
|
+
};
|
|
2875
2949
|
var MenuContent = React36.forwardRef(
|
|
2876
2950
|
({ children, className, align = "start", side = "bottom", ...props }, ref) => {
|
|
2877
2951
|
const { isOpen, setIsOpen, triggerId, menuId } = useMenuContext();
|
|
2878
|
-
const menuRef =
|
|
2952
|
+
const menuRef = useRef5(null);
|
|
2953
|
+
const close = useCallback11(() => setIsOpen(false), [setIsOpen]);
|
|
2954
|
+
useEscapeKey(close, isOpen);
|
|
2879
2955
|
useEffect5(() => {
|
|
2880
2956
|
if (!isOpen) {
|
|
2881
2957
|
return;
|
|
2882
2958
|
}
|
|
2883
2959
|
const handleClickOutside = (e) => {
|
|
2960
|
+
const target = e.target;
|
|
2884
2961
|
const trigger = document.getElementById(triggerId);
|
|
2885
|
-
if (menuRef.current && !menuRef.current.contains(
|
|
2886
|
-
setIsOpen(false);
|
|
2887
|
-
}
|
|
2888
|
-
};
|
|
2889
|
-
const handleEscape = (e) => {
|
|
2890
|
-
if (e.key === "Escape") {
|
|
2962
|
+
if (menuRef.current && !menuRef.current.contains(target) && !trigger?.contains(target)) {
|
|
2891
2963
|
setIsOpen(false);
|
|
2892
2964
|
}
|
|
2893
2965
|
};
|
|
2894
2966
|
document.addEventListener("mousedown", handleClickOutside);
|
|
2895
|
-
document.
|
|
2896
|
-
return () => {
|
|
2897
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
2898
|
-
document.removeEventListener("keydown", handleEscape);
|
|
2899
|
-
};
|
|
2967
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2900
2968
|
}, [isOpen, setIsOpen, triggerId]);
|
|
2901
2969
|
if (!isOpen) {
|
|
2902
2970
|
return null;
|
|
2903
2971
|
}
|
|
2904
|
-
const alignmentClasses = {
|
|
2905
|
-
start: "left-0",
|
|
2906
|
-
center: "left-1/2 -translate-x-1/2",
|
|
2907
|
-
end: "right-0"
|
|
2908
|
-
};
|
|
2909
|
-
const sideClasses = {
|
|
2910
|
-
top: "bottom-full mb-1",
|
|
2911
|
-
bottom: "top-full mt-1"
|
|
2912
|
-
};
|
|
2913
2972
|
return /* @__PURE__ */ React36.createElement(
|
|
2914
2973
|
"div",
|
|
2915
2974
|
{
|
|
2916
|
-
ref: (
|
|
2917
|
-
menuRef.current = node;
|
|
2918
|
-
if (typeof ref === "function") {
|
|
2919
|
-
ref(node);
|
|
2920
|
-
} else if (ref) {
|
|
2921
|
-
ref.current = node;
|
|
2922
|
-
}
|
|
2923
|
-
},
|
|
2975
|
+
ref: composeRefs(menuRef, ref),
|
|
2924
2976
|
id: menuId,
|
|
2925
2977
|
role: "menu",
|
|
2926
2978
|
"aria-labelledby": triggerId,
|
|
@@ -2928,8 +2980,8 @@ var MenuContent = React36.forwardRef(
|
|
|
2928
2980
|
"absolute z-50 min-w-40 py-1",
|
|
2929
2981
|
"bg-charcoal border border-ash shadow-lg",
|
|
2930
2982
|
"animate-fade-in",
|
|
2931
|
-
|
|
2932
|
-
|
|
2983
|
+
MENU_ALIGN_CLASSES[align],
|
|
2984
|
+
MENU_SIDE_CLASSES[side],
|
|
2933
2985
|
className
|
|
2934
2986
|
),
|
|
2935
2987
|
...props
|
|
@@ -3653,12 +3705,19 @@ function SquareLoaderIcon({ className, ...props }) {
|
|
|
3653
3705
|
}
|
|
3654
3706
|
|
|
3655
3707
|
// src/components/Message.tsx
|
|
3656
|
-
import React55, { useEffect as useEffect6, useRef as
|
|
3708
|
+
import React55, { useCallback as useCallback12, useEffect as useEffect6, useRef as useRef6, useState as useState11 } from "react";
|
|
3709
|
+
import { Check as Check3, ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3, Copy, GitBranch, Pencil, RotateCcw, Send, X as X5 } from "lucide-react";
|
|
3657
3710
|
|
|
3658
3711
|
// src/components/MarkdownContent.tsx
|
|
3659
3712
|
import React54, { useMemo } from "react";
|
|
3660
3713
|
import DOMPurify from "dompurify";
|
|
3661
3714
|
import { marked } from "marked";
|
|
3715
|
+
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
|
|
3716
|
+
if (node.tagName === "A") {
|
|
3717
|
+
node.setAttribute("target", "_blank");
|
|
3718
|
+
node.setAttribute("rel", "noopener noreferrer");
|
|
3719
|
+
}
|
|
3720
|
+
});
|
|
3662
3721
|
var DEFAULT_SANITIZE_CONFIG = {
|
|
3663
3722
|
ALLOWED_TAGS: [
|
|
3664
3723
|
"h1",
|
|
@@ -3726,16 +3785,6 @@ var DEFAULT_SANITIZE_CONFIG = {
|
|
|
3726
3785
|
ADD_ATTR: ["target", "rel"],
|
|
3727
3786
|
ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|tel):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i
|
|
3728
3787
|
};
|
|
3729
|
-
function useDOMPurifySetup() {
|
|
3730
|
-
useMemo(() => {
|
|
3731
|
-
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
|
|
3732
|
-
if (node.tagName === "A") {
|
|
3733
|
-
node.setAttribute("target", "_blank");
|
|
3734
|
-
node.setAttribute("rel", "noopener noreferrer");
|
|
3735
|
-
}
|
|
3736
|
-
});
|
|
3737
|
-
}, []);
|
|
3738
|
-
}
|
|
3739
3788
|
var CURSOR_BASE_CLASSES = "inline-block bg-current animate-cursor-blink w-0.5 h-cursor translate-y-cursor-offset";
|
|
3740
3789
|
function injectStreamingCursor(html, cursorClassName) {
|
|
3741
3790
|
if (!html.trim()) {
|
|
@@ -3765,7 +3814,6 @@ function injectStreamingCursor(html, cursorClassName) {
|
|
|
3765
3814
|
}
|
|
3766
3815
|
var MarkdownContent = React54.forwardRef(
|
|
3767
3816
|
({ className, content, isMarkdown = true, sanitizeConfig, isStreaming, cursorClassName, ...rest }, ref) => {
|
|
3768
|
-
useDOMPurifySetup();
|
|
3769
3817
|
const sanitizedHtml = useMemo(() => {
|
|
3770
3818
|
if (!content && !isStreaming) {
|
|
3771
3819
|
return "";
|
|
@@ -3787,7 +3835,7 @@ var MarkdownContent = React54.forwardRef(
|
|
|
3787
3835
|
return injectStreamingCursor(sanitized, cursorClassName);
|
|
3788
3836
|
}
|
|
3789
3837
|
return sanitized;
|
|
3790
|
-
}, [content, sanitizeConfig, isStreaming, cursorClassName]);
|
|
3838
|
+
}, [content, isMarkdown, sanitizeConfig, isStreaming, cursorClassName]);
|
|
3791
3839
|
return /* @__PURE__ */ React54.createElement(
|
|
3792
3840
|
"div",
|
|
3793
3841
|
{
|
|
@@ -3802,162 +3850,32 @@ var MarkdownContent = React54.forwardRef(
|
|
|
3802
3850
|
MarkdownContent.displayName = "MarkdownContent";
|
|
3803
3851
|
|
|
3804
3852
|
// src/components/Message.tsx
|
|
3805
|
-
var
|
|
3853
|
+
var VARIANT_STYLES3 = {
|
|
3806
3854
|
user: "bg-gold text-obsidian ml-auto",
|
|
3807
3855
|
assistant: "bg-charcoal border border-ash text-white mr-auto"
|
|
3808
3856
|
};
|
|
3809
|
-
var
|
|
3810
|
-
"
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
onClick,
|
|
3814
|
-
disabled,
|
|
3815
|
-
className: cx(
|
|
3816
|
-
"p-1.5 text-silver/60 hover:text-silver transition-colors duration-150",
|
|
3817
|
-
"hover:bg-white/5",
|
|
3818
|
-
"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent",
|
|
3819
|
-
className
|
|
3820
|
-
),
|
|
3821
|
-
"aria-label": label
|
|
3822
|
-
},
|
|
3823
|
-
children
|
|
3824
|
-
);
|
|
3825
|
-
var CopyIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3826
|
-
"svg",
|
|
3827
|
-
{
|
|
3828
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3829
|
-
viewBox: "0 0 24 24",
|
|
3830
|
-
fill: "none",
|
|
3831
|
-
stroke: "currentColor",
|
|
3832
|
-
strokeWidth: "2",
|
|
3833
|
-
strokeLinecap: "round",
|
|
3834
|
-
strokeLinejoin: "round",
|
|
3835
|
-
className: "w-3.5 h-3.5"
|
|
3836
|
-
},
|
|
3837
|
-
/* @__PURE__ */ React55.createElement("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
|
|
3838
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
|
|
3839
|
-
);
|
|
3840
|
-
var CheckIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3841
|
-
"svg",
|
|
3842
|
-
{
|
|
3843
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3844
|
-
viewBox: "0 0 24 24",
|
|
3845
|
-
fill: "none",
|
|
3846
|
-
stroke: "currentColor",
|
|
3847
|
-
strokeWidth: "2",
|
|
3848
|
-
strokeLinecap: "round",
|
|
3849
|
-
strokeLinejoin: "round",
|
|
3850
|
-
className: "w-3.5 h-3.5 text-success"
|
|
3851
|
-
},
|
|
3852
|
-
/* @__PURE__ */ React55.createElement("polyline", { points: "20 6 9 17 4 12" })
|
|
3853
|
-
);
|
|
3854
|
-
var PencilIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3855
|
-
"svg",
|
|
3856
|
-
{
|
|
3857
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3858
|
-
viewBox: "0 0 24 24",
|
|
3859
|
-
fill: "none",
|
|
3860
|
-
stroke: "currentColor",
|
|
3861
|
-
strokeWidth: "2",
|
|
3862
|
-
strokeLinecap: "round",
|
|
3863
|
-
strokeLinejoin: "round",
|
|
3864
|
-
className: "w-3.5 h-3.5"
|
|
3865
|
-
},
|
|
3866
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }),
|
|
3867
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m15 5 4 4" })
|
|
3868
|
-
);
|
|
3869
|
-
var RetryIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3870
|
-
"svg",
|
|
3871
|
-
{
|
|
3872
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3873
|
-
viewBox: "0 0 24 24",
|
|
3874
|
-
fill: "none",
|
|
3875
|
-
stroke: "currentColor",
|
|
3876
|
-
strokeWidth: "2",
|
|
3877
|
-
strokeLinecap: "round",
|
|
3878
|
-
strokeLinejoin: "round",
|
|
3879
|
-
className: "w-3.5 h-3.5"
|
|
3880
|
-
},
|
|
3881
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
|
|
3882
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M21 3v5h-5" }),
|
|
3883
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
|
|
3884
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M8 16H3v5" })
|
|
3885
|
-
);
|
|
3886
|
-
var ChevronLeftIcon2 = () => /* @__PURE__ */ React55.createElement(
|
|
3887
|
-
"svg",
|
|
3888
|
-
{
|
|
3889
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3890
|
-
viewBox: "0 0 24 24",
|
|
3891
|
-
fill: "none",
|
|
3892
|
-
stroke: "currentColor",
|
|
3893
|
-
strokeWidth: "2",
|
|
3894
|
-
strokeLinecap: "round",
|
|
3895
|
-
strokeLinejoin: "round",
|
|
3896
|
-
className: "w-3 h-3"
|
|
3897
|
-
},
|
|
3898
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m15 18-6-6 6-6" })
|
|
3899
|
-
);
|
|
3900
|
-
var ChevronRightIcon2 = () => /* @__PURE__ */ React55.createElement(
|
|
3901
|
-
"svg",
|
|
3902
|
-
{
|
|
3903
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3904
|
-
viewBox: "0 0 24 24",
|
|
3905
|
-
fill: "none",
|
|
3906
|
-
stroke: "currentColor",
|
|
3907
|
-
strokeWidth: "2",
|
|
3908
|
-
strokeLinecap: "round",
|
|
3909
|
-
strokeLinejoin: "round",
|
|
3910
|
-
className: "w-3 h-3"
|
|
3911
|
-
},
|
|
3912
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m9 18 6-6-6-6" })
|
|
3913
|
-
);
|
|
3914
|
-
var GitBranchIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3915
|
-
"svg",
|
|
3916
|
-
{
|
|
3917
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3918
|
-
viewBox: "0 0 24 24",
|
|
3919
|
-
fill: "none",
|
|
3920
|
-
stroke: "currentColor",
|
|
3921
|
-
strokeWidth: "2",
|
|
3922
|
-
strokeLinecap: "round",
|
|
3923
|
-
strokeLinejoin: "round",
|
|
3924
|
-
className: "w-3 h-3 mr-0.5 text-silver/50"
|
|
3925
|
-
},
|
|
3926
|
-
/* @__PURE__ */ React55.createElement("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
|
|
3927
|
-
/* @__PURE__ */ React55.createElement("circle", { cx: "18", cy: "6", r: "3" }),
|
|
3928
|
-
/* @__PURE__ */ React55.createElement("circle", { cx: "6", cy: "18", r: "3" }),
|
|
3929
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })
|
|
3857
|
+
var ACTION_BUTTON_CLASSES = cx(
|
|
3858
|
+
"p-1.5 text-silver/60 hover:text-silver transition-colors duration-150",
|
|
3859
|
+
"hover:bg-white/5",
|
|
3860
|
+
"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent"
|
|
3930
3861
|
);
|
|
3931
|
-
var
|
|
3932
|
-
"
|
|
3933
|
-
|
|
3934
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3935
|
-
viewBox: "0 0 24 24",
|
|
3936
|
-
fill: "none",
|
|
3937
|
-
stroke: "currentColor",
|
|
3938
|
-
strokeWidth: "2",
|
|
3939
|
-
strokeLinecap: "round",
|
|
3940
|
-
strokeLinejoin: "round",
|
|
3941
|
-
className: "w-4 h-4"
|
|
3942
|
-
},
|
|
3943
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M18 6 6 18" }),
|
|
3944
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m6 6 12 12" })
|
|
3945
|
-
);
|
|
3946
|
-
var SendIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3947
|
-
"svg",
|
|
3948
|
-
{
|
|
3949
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3950
|
-
viewBox: "0 0 24 24",
|
|
3951
|
-
fill: "none",
|
|
3952
|
-
stroke: "currentColor",
|
|
3953
|
-
strokeWidth: "2",
|
|
3954
|
-
strokeLinecap: "round",
|
|
3955
|
-
strokeLinejoin: "round",
|
|
3956
|
-
className: "w-4 h-4"
|
|
3957
|
-
},
|
|
3958
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m22 2-7 20-4-9-9-4Z" }),
|
|
3959
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M22 2 11 13" })
|
|
3862
|
+
var BRANCH_BUTTON_CLASSES = cx(
|
|
3863
|
+
"p-0.5 hover:text-white hover:bg-white/10 transition-colors",
|
|
3864
|
+
"disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
|
|
3960
3865
|
);
|
|
3866
|
+
function ActionButton({ onClick, label, children, disabled }) {
|
|
3867
|
+
return /* @__PURE__ */ React55.createElement(
|
|
3868
|
+
"button",
|
|
3869
|
+
{
|
|
3870
|
+
type: "button",
|
|
3871
|
+
onClick,
|
|
3872
|
+
disabled,
|
|
3873
|
+
className: ACTION_BUTTON_CLASSES,
|
|
3874
|
+
"aria-label": label
|
|
3875
|
+
},
|
|
3876
|
+
children
|
|
3877
|
+
);
|
|
3878
|
+
}
|
|
3961
3879
|
var Message = React55.forwardRef(
|
|
3962
3880
|
({
|
|
3963
3881
|
variant = "assistant",
|
|
@@ -3970,10 +3888,10 @@ var Message = React55.forwardRef(
|
|
|
3970
3888
|
...rest
|
|
3971
3889
|
}, ref) => {
|
|
3972
3890
|
const isUser = variant === "user";
|
|
3973
|
-
const
|
|
3974
|
-
const [isEditing, setIsEditing] =
|
|
3975
|
-
const [editValue, setEditValue] =
|
|
3976
|
-
const textareaRef =
|
|
3891
|
+
const { copied, copy } = useCopyToClipboard();
|
|
3892
|
+
const [isEditing, setIsEditing] = useState11(false);
|
|
3893
|
+
const [editValue, setEditValue] = useState11(typeof content === "string" ? content : "");
|
|
3894
|
+
const textareaRef = useRef6(null);
|
|
3977
3895
|
const showBranchNav = branchInfo && branchInfo.total > 1;
|
|
3978
3896
|
const showActions = actions && !hideActions && !isStreaming;
|
|
3979
3897
|
useEffect6(() => {
|
|
@@ -3985,25 +3903,11 @@ var Message = React55.forwardRef(
|
|
|
3985
3903
|
textarea.setSelectionRange(textarea.value.length, textarea.value.length);
|
|
3986
3904
|
}
|
|
3987
3905
|
}, [isEditing]);
|
|
3988
|
-
const handleCopy =
|
|
3989
|
-
if (typeof content
|
|
3990
|
-
|
|
3991
|
-
}
|
|
3992
|
-
try {
|
|
3993
|
-
await navigator.clipboard.writeText(content);
|
|
3994
|
-
setCopied(true);
|
|
3995
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
3996
|
-
} catch {
|
|
3997
|
-
const textArea = document.createElement("textarea");
|
|
3998
|
-
textArea.value = content;
|
|
3999
|
-
document.body.appendChild(textArea);
|
|
4000
|
-
textArea.select();
|
|
4001
|
-
document.execCommand("copy");
|
|
4002
|
-
document.body.removeChild(textArea);
|
|
4003
|
-
setCopied(true);
|
|
4004
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
3906
|
+
const handleCopy = useCallback12(() => {
|
|
3907
|
+
if (typeof content === "string") {
|
|
3908
|
+
void copy(content);
|
|
4005
3909
|
}
|
|
4006
|
-
};
|
|
3910
|
+
}, [copy, content]);
|
|
4007
3911
|
const handleStartEdit = () => {
|
|
4008
3912
|
if (typeof content === "string") {
|
|
4009
3913
|
setEditValue(content);
|
|
@@ -4066,7 +3970,7 @@ var Message = React55.forwardRef(
|
|
|
4066
3970
|
className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors",
|
|
4067
3971
|
"aria-label": "Cancel edit"
|
|
4068
3972
|
},
|
|
4069
|
-
/* @__PURE__ */ React55.createElement(
|
|
3973
|
+
/* @__PURE__ */ React55.createElement(X5, { className: "w-4 h-4" })
|
|
4070
3974
|
), /* @__PURE__ */ React55.createElement(
|
|
4071
3975
|
"button",
|
|
4072
3976
|
{
|
|
@@ -4076,13 +3980,13 @@ var Message = React55.forwardRef(
|
|
|
4076
3980
|
className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors disabled:opacity-30",
|
|
4077
3981
|
"aria-label": "Submit edit"
|
|
4078
3982
|
},
|
|
4079
|
-
/* @__PURE__ */ React55.createElement(
|
|
3983
|
+
/* @__PURE__ */ React55.createElement(Send, { className: "w-4 h-4" })
|
|
4080
3984
|
)))) : /* @__PURE__ */ React55.createElement(
|
|
4081
3985
|
"div",
|
|
4082
3986
|
{
|
|
4083
3987
|
className: cx(
|
|
4084
3988
|
"px-3 py-2 w-fit max-w-11/12",
|
|
4085
|
-
|
|
3989
|
+
VARIANT_STYLES3[variant]
|
|
4086
3990
|
)
|
|
4087
3991
|
},
|
|
4088
3992
|
typeof content === "string" ? /* @__PURE__ */ React55.createElement(
|
|
@@ -4104,33 +4008,27 @@ var Message = React55.forwardRef(
|
|
|
4104
4008
|
onClick: handleCopy,
|
|
4105
4009
|
label: copied ? "Copied!" : "Copy message"
|
|
4106
4010
|
},
|
|
4107
|
-
copied ? /* @__PURE__ */ React55.createElement(
|
|
4108
|
-
), isUser && actions.onEdit && typeof content === "string" && /* @__PURE__ */ React55.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React55.createElement(
|
|
4011
|
+
copied ? /* @__PURE__ */ React55.createElement(Check3, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ React55.createElement(Copy, { className: "w-3.5 h-3.5" })
|
|
4012
|
+
), isUser && actions.onEdit && typeof content === "string" && /* @__PURE__ */ React55.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React55.createElement(Pencil, { className: "w-3.5 h-3.5" })), !isUser && actions.onRetry && /* @__PURE__ */ React55.createElement(ActionButton, { onClick: actions.onRetry, label: "Regenerate response" }, /* @__PURE__ */ React55.createElement(RotateCcw, { className: "w-3.5 h-3.5" })), showBranchNav && /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement("div", { className: "w-px h-4 bg-ash/40 mx-1" }), /* @__PURE__ */ React55.createElement("div", { className: "flex items-center gap-0.5 text-silver/70" }, /* @__PURE__ */ React55.createElement(GitBranch, { className: "w-3 h-3 mr-0.5 text-silver/50" }), /* @__PURE__ */ React55.createElement(
|
|
4109
4013
|
"button",
|
|
4110
4014
|
{
|
|
4111
4015
|
type: "button",
|
|
4112
4016
|
onClick: branchInfo.onPrevious,
|
|
4113
4017
|
disabled: branchInfo.current <= 1,
|
|
4114
|
-
className:
|
|
4115
|
-
"p-0.5 hover:text-white hover:bg-white/10 transition-colors",
|
|
4116
|
-
"disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
|
|
4117
|
-
),
|
|
4018
|
+
className: BRANCH_BUTTON_CLASSES,
|
|
4118
4019
|
"aria-label": "Previous branch"
|
|
4119
4020
|
},
|
|
4120
|
-
/* @__PURE__ */ React55.createElement(
|
|
4021
|
+
/* @__PURE__ */ React55.createElement(ChevronLeft2, { className: "w-3 h-3" })
|
|
4121
4022
|
), /* @__PURE__ */ React55.createElement("span", { className: "text-xs tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total), /* @__PURE__ */ React55.createElement(
|
|
4122
4023
|
"button",
|
|
4123
4024
|
{
|
|
4124
4025
|
type: "button",
|
|
4125
4026
|
onClick: branchInfo.onNext,
|
|
4126
4027
|
disabled: branchInfo.current >= branchInfo.total,
|
|
4127
|
-
className:
|
|
4128
|
-
"p-0.5 hover:text-white hover:bg-white/10 transition-colors",
|
|
4129
|
-
"disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
|
|
4130
|
-
),
|
|
4028
|
+
className: BRANCH_BUTTON_CLASSES,
|
|
4131
4029
|
"aria-label": "Next branch"
|
|
4132
4030
|
},
|
|
4133
|
-
/* @__PURE__ */ React55.createElement(
|
|
4031
|
+
/* @__PURE__ */ React55.createElement(ChevronRight3, { className: "w-3 h-3" })
|
|
4134
4032
|
))))
|
|
4135
4033
|
);
|
|
4136
4034
|
}
|
|
@@ -4141,7 +4039,7 @@ Message.displayName = "Message";
|
|
|
4141
4039
|
import React56 from "react";
|
|
4142
4040
|
var StreamingCursor = React56.forwardRef(
|
|
4143
4041
|
({ className, variant = "line", ...rest }, ref) => {
|
|
4144
|
-
const
|
|
4042
|
+
const variantStyles2 = {
|
|
4145
4043
|
block: "w-2.5 h-cursor translate-y-cursor-offset",
|
|
4146
4044
|
line: "w-0.5 h-cursor translate-y-cursor-offset",
|
|
4147
4045
|
underscore: "w-2.5 h-0.5 self-end mb-0.5"
|
|
@@ -4152,7 +4050,7 @@ var StreamingCursor = React56.forwardRef(
|
|
|
4152
4050
|
ref,
|
|
4153
4051
|
className: cx(
|
|
4154
4052
|
"inline-block bg-current animate-cursor-blink",
|
|
4155
|
-
|
|
4053
|
+
variantStyles2[variant],
|
|
4156
4054
|
className
|
|
4157
4055
|
),
|
|
4158
4056
|
"aria-hidden": "true",
|
|
@@ -4164,18 +4062,18 @@ var StreamingCursor = React56.forwardRef(
|
|
|
4164
4062
|
StreamingCursor.displayName = "StreamingCursor";
|
|
4165
4063
|
|
|
4166
4064
|
// src/components/chat/ChatInterface.tsx
|
|
4167
|
-
import React74, { useCallback as
|
|
4065
|
+
import React74, { useCallback as useCallback22, useEffect as useEffect16, useMemo as useMemo5, useRef as useRef15, useState as useState22 } from "react";
|
|
4168
4066
|
|
|
4169
4067
|
// src/components/chat/ChatView.tsx
|
|
4170
4068
|
import React58, { useEffect as useEffect9 } from "react";
|
|
4171
4069
|
|
|
4172
4070
|
// src/components/chat/hooks/useScrollAnchor.ts
|
|
4173
|
-
import { useCallback as
|
|
4071
|
+
import { useCallback as useCallback13, useRef as useRef7 } from "react";
|
|
4174
4072
|
function useScrollAnchor(options = {}) {
|
|
4175
4073
|
const { behavior = "smooth", block = "start" } = options;
|
|
4176
|
-
const containerRef =
|
|
4177
|
-
const anchorRef =
|
|
4178
|
-
const scrollToAnchor =
|
|
4074
|
+
const containerRef = useRef7(null);
|
|
4075
|
+
const anchorRef = useRef7(null);
|
|
4076
|
+
const scrollToAnchor = useCallback13(() => {
|
|
4179
4077
|
const el = anchorRef.current;
|
|
4180
4078
|
if (!el) {
|
|
4181
4079
|
return;
|
|
@@ -4186,7 +4084,7 @@ function useScrollAnchor(options = {}) {
|
|
|
4186
4084
|
});
|
|
4187
4085
|
});
|
|
4188
4086
|
}, [behavior, block]);
|
|
4189
|
-
const scrollToBottom =
|
|
4087
|
+
const scrollToBottom = useCallback13(() => {
|
|
4190
4088
|
const container = containerRef.current;
|
|
4191
4089
|
if (!container) {
|
|
4192
4090
|
return;
|
|
@@ -4197,7 +4095,7 @@ function useScrollAnchor(options = {}) {
|
|
|
4197
4095
|
container.scrollTop = container.scrollHeight;
|
|
4198
4096
|
}
|
|
4199
4097
|
}, [behavior]);
|
|
4200
|
-
const isScrolledToBottom =
|
|
4098
|
+
const isScrolledToBottom = useCallback13(() => {
|
|
4201
4099
|
const container = containerRef.current;
|
|
4202
4100
|
if (!container) {
|
|
4203
4101
|
return true;
|
|
@@ -4216,15 +4114,15 @@ function useScrollAnchor(options = {}) {
|
|
|
4216
4114
|
}
|
|
4217
4115
|
|
|
4218
4116
|
// src/components/chat/hooks/useAdaptiveSpacer.ts
|
|
4219
|
-
import { useCallback as
|
|
4117
|
+
import { useCallback as useCallback14, useEffect as useEffect7, useRef as useRef8, useState as useState12 } from "react";
|
|
4220
4118
|
function useAdaptiveSpacer(options = {}) {
|
|
4221
4119
|
const { minHeight = 0, containerRef: externalContainerRef, anchorRef } = options;
|
|
4222
|
-
const internalContainerRef =
|
|
4120
|
+
const internalContainerRef = useRef8(null);
|
|
4223
4121
|
const containerRef = externalContainerRef ?? internalContainerRef;
|
|
4224
|
-
const contentRef =
|
|
4225
|
-
const spacerRef =
|
|
4226
|
-
const [spacerHeight, setSpacerHeight] =
|
|
4227
|
-
const recalculate =
|
|
4122
|
+
const contentRef = useRef8(null);
|
|
4123
|
+
const spacerRef = useRef8(null);
|
|
4124
|
+
const [spacerHeight, setSpacerHeight] = useState12(0);
|
|
4125
|
+
const recalculate = useCallback14(() => {
|
|
4228
4126
|
const container = containerRef.current;
|
|
4229
4127
|
const content = contentRef.current;
|
|
4230
4128
|
if (!container || !content) {
|
|
@@ -4283,7 +4181,7 @@ function useAdaptiveSpacer(options = {}) {
|
|
|
4283
4181
|
}
|
|
4284
4182
|
|
|
4285
4183
|
// src/components/chat/ThinkingIndicator.tsx
|
|
4286
|
-
import React57, { useEffect as useEffect8, useState as
|
|
4184
|
+
import React57, { useEffect as useEffect8, useState as useState13 } from "react";
|
|
4287
4185
|
var THINKING_PHRASES = [
|
|
4288
4186
|
"Consulting the ancient tomes...",
|
|
4289
4187
|
"Parsing the ineffable...",
|
|
@@ -4307,22 +4205,29 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4307
4205
|
className,
|
|
4308
4206
|
...rest
|
|
4309
4207
|
}, ref) => {
|
|
4310
|
-
const [currentIndex, setCurrentIndex] =
|
|
4208
|
+
const [currentIndex, setCurrentIndex] = useState13(
|
|
4311
4209
|
() => Math.floor(Math.random() * phrases.length)
|
|
4312
4210
|
);
|
|
4313
|
-
const [isTransitioning, setIsTransitioning] =
|
|
4211
|
+
const [isTransitioning, setIsTransitioning] = useState13(false);
|
|
4314
4212
|
useEffect8(() => {
|
|
4315
4213
|
if (!isVisible || phrases.length <= 1) {
|
|
4316
4214
|
return;
|
|
4317
4215
|
}
|
|
4216
|
+
let fadeTimeout = null;
|
|
4318
4217
|
const interval = setInterval(() => {
|
|
4319
4218
|
setIsTransitioning(true);
|
|
4320
|
-
setTimeout(() => {
|
|
4219
|
+
fadeTimeout = setTimeout(() => {
|
|
4321
4220
|
setCurrentIndex((prev) => (prev + 1) % phrases.length);
|
|
4322
4221
|
setIsTransitioning(false);
|
|
4222
|
+
fadeTimeout = null;
|
|
4323
4223
|
}, 200);
|
|
4324
4224
|
}, phraseInterval);
|
|
4325
|
-
return () =>
|
|
4225
|
+
return () => {
|
|
4226
|
+
clearInterval(interval);
|
|
4227
|
+
if (fadeTimeout !== null) {
|
|
4228
|
+
clearTimeout(fadeTimeout);
|
|
4229
|
+
}
|
|
4230
|
+
};
|
|
4326
4231
|
}, [isVisible, phrases.length, phraseInterval]);
|
|
4327
4232
|
if (!isVisible) {
|
|
4328
4233
|
return null;
|
|
@@ -4401,15 +4306,7 @@ var ChatView = React58.forwardRef(
|
|
|
4401
4306
|
return /* @__PURE__ */ React58.createElement(
|
|
4402
4307
|
"div",
|
|
4403
4308
|
{
|
|
4404
|
-
ref: (
|
|
4405
|
-
;
|
|
4406
|
-
containerRef.current = node;
|
|
4407
|
-
if (typeof ref === "function") {
|
|
4408
|
-
ref(node);
|
|
4409
|
-
} else if (ref) {
|
|
4410
|
-
ref.current = node;
|
|
4411
|
-
}
|
|
4412
|
-
},
|
|
4309
|
+
ref: composeRefs(containerRef, ref),
|
|
4413
4310
|
onScroll,
|
|
4414
4311
|
className: cx(
|
|
4415
4312
|
"flex flex-col w-full h-full overflow-y-auto scroll-smooth",
|
|
@@ -4467,8 +4364,8 @@ var ChatView = React58.forwardRef(
|
|
|
4467
4364
|
ChatView.displayName = "ChatView";
|
|
4468
4365
|
|
|
4469
4366
|
// src/components/chat/ChatInput.tsx
|
|
4470
|
-
import React59, { useCallback as
|
|
4471
|
-
import { Paperclip, Send, Square, X as
|
|
4367
|
+
import React59, { useCallback as useCallback15, useEffect as useEffect10, useRef as useRef9, useState as useState14 } from "react";
|
|
4368
|
+
import { Paperclip, Send as Send2, Square, X as X6 } from "lucide-react";
|
|
4472
4369
|
|
|
4473
4370
|
// src/components/chat/types.ts
|
|
4474
4371
|
function isImageFile(file) {
|
|
@@ -4480,13 +4377,11 @@ function createPreviewUrl(file) {
|
|
|
4480
4377
|
}
|
|
4481
4378
|
return void 0;
|
|
4482
4379
|
}
|
|
4483
|
-
function revokePreviewUrl(url) {
|
|
4484
|
-
if (url) {
|
|
4485
|
-
URL.revokeObjectURL(url);
|
|
4486
|
-
}
|
|
4487
|
-
}
|
|
4488
4380
|
function generateId() {
|
|
4489
|
-
|
|
4381
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
4382
|
+
return crypto.randomUUID();
|
|
4383
|
+
}
|
|
4384
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
4490
4385
|
}
|
|
4491
4386
|
function createEmptyTree() {
|
|
4492
4387
|
return {
|
|
@@ -4646,6 +4541,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4646
4541
|
onStop,
|
|
4647
4542
|
attachments: controlledAttachments,
|
|
4648
4543
|
onAttachmentsChange,
|
|
4544
|
+
onAttachmentRemove,
|
|
4649
4545
|
showAttachmentButton = true,
|
|
4650
4546
|
acceptedFileTypes,
|
|
4651
4547
|
notice,
|
|
@@ -4655,13 +4551,13 @@ var ChatInput = React59.forwardRef(
|
|
|
4655
4551
|
className,
|
|
4656
4552
|
...rest
|
|
4657
4553
|
}, ref) => {
|
|
4658
|
-
const [value, setValue] =
|
|
4659
|
-
const [localAttachments, setLocalAttachments] =
|
|
4660
|
-
const [isDragOver, setIsDragOver] =
|
|
4661
|
-
const textareaRef =
|
|
4662
|
-
const fileInputRef =
|
|
4554
|
+
const [value, setValue] = useState14(initialInputValue);
|
|
4555
|
+
const [localAttachments, setLocalAttachments] = useState14([]);
|
|
4556
|
+
const [isDragOver, setIsDragOver] = useState14(false);
|
|
4557
|
+
const textareaRef = useRef9(null);
|
|
4558
|
+
const fileInputRef = useRef9(null);
|
|
4663
4559
|
const attachments = controlledAttachments ?? localAttachments;
|
|
4664
|
-
const setAttachments =
|
|
4560
|
+
const setAttachments = useCallback15(
|
|
4665
4561
|
(newAttachments) => {
|
|
4666
4562
|
if (onAttachmentsChange) {
|
|
4667
4563
|
if (typeof newAttachments === "function") {
|
|
@@ -4675,7 +4571,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4675
4571
|
},
|
|
4676
4572
|
[attachments, onAttachmentsChange]
|
|
4677
4573
|
);
|
|
4678
|
-
const handleSubmit =
|
|
4574
|
+
const handleSubmit = useCallback15(() => {
|
|
4679
4575
|
const trimmed = value.trim();
|
|
4680
4576
|
if (!trimmed || disabled || isStreaming) {
|
|
4681
4577
|
return;
|
|
@@ -4687,7 +4583,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4687
4583
|
textareaRef.current.style.height = "auto";
|
|
4688
4584
|
}
|
|
4689
4585
|
}, [value, disabled, isStreaming, onSubmit, attachments, setAttachments]);
|
|
4690
|
-
const handleKeyDown =
|
|
4586
|
+
const handleKeyDown = useCallback15(
|
|
4691
4587
|
(e) => {
|
|
4692
4588
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
4693
4589
|
e.preventDefault();
|
|
@@ -4696,7 +4592,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4696
4592
|
},
|
|
4697
4593
|
[handleSubmit]
|
|
4698
4594
|
);
|
|
4699
|
-
const handleChange =
|
|
4595
|
+
const handleChange = useCallback15((e) => {
|
|
4700
4596
|
setValue(e.target.value);
|
|
4701
4597
|
onInputChange?.(e.target.value);
|
|
4702
4598
|
const textarea = e.target;
|
|
@@ -4708,7 +4604,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4708
4604
|
textareaRef.current.focus();
|
|
4709
4605
|
}
|
|
4710
4606
|
}, [disabled, isStreaming, autoFocus]);
|
|
4711
|
-
const addFiles =
|
|
4607
|
+
const addFiles = useCallback15(
|
|
4712
4608
|
(files) => {
|
|
4713
4609
|
const newAttachments = Array.from(files).map((file) => ({
|
|
4714
4610
|
id: generateId(),
|
|
@@ -4720,7 +4616,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4720
4616
|
},
|
|
4721
4617
|
[setAttachments]
|
|
4722
4618
|
);
|
|
4723
|
-
const handleFileSelect =
|
|
4619
|
+
const handleFileSelect = useCallback15(
|
|
4724
4620
|
(e) => {
|
|
4725
4621
|
const files = e.target.files;
|
|
4726
4622
|
if (files && files.length > 0) {
|
|
@@ -4730,35 +4626,39 @@ var ChatInput = React59.forwardRef(
|
|
|
4730
4626
|
},
|
|
4731
4627
|
[addFiles]
|
|
4732
4628
|
);
|
|
4733
|
-
const handleRemoveAttachment =
|
|
4629
|
+
const handleRemoveAttachment = useCallback15(
|
|
4734
4630
|
(id) => {
|
|
4631
|
+
const attachment = attachments.find((a) => a.id === id);
|
|
4632
|
+
if (attachment && onAttachmentRemove) {
|
|
4633
|
+
onAttachmentRemove(attachment);
|
|
4634
|
+
}
|
|
4735
4635
|
setAttachments((prev) => {
|
|
4736
|
-
const
|
|
4737
|
-
if (
|
|
4738
|
-
URL.revokeObjectURL(
|
|
4636
|
+
const attachmentToRemove = prev.find((a) => a.id === id);
|
|
4637
|
+
if (attachmentToRemove?.previewUrl) {
|
|
4638
|
+
URL.revokeObjectURL(attachmentToRemove.previewUrl);
|
|
4739
4639
|
}
|
|
4740
4640
|
return prev.filter((a) => a.id !== id);
|
|
4741
4641
|
});
|
|
4742
4642
|
},
|
|
4743
|
-
[setAttachments]
|
|
4643
|
+
[attachments, onAttachmentRemove, setAttachments]
|
|
4744
4644
|
);
|
|
4745
|
-
const handleDragEnter =
|
|
4645
|
+
const handleDragEnter = useCallback15((e) => {
|
|
4746
4646
|
e.preventDefault();
|
|
4747
4647
|
e.stopPropagation();
|
|
4748
4648
|
setIsDragOver(true);
|
|
4749
4649
|
}, []);
|
|
4750
|
-
const handleDragLeave =
|
|
4650
|
+
const handleDragLeave = useCallback15((e) => {
|
|
4751
4651
|
e.preventDefault();
|
|
4752
4652
|
e.stopPropagation();
|
|
4753
4653
|
if (!e.currentTarget.contains(e.relatedTarget)) {
|
|
4754
4654
|
setIsDragOver(false);
|
|
4755
4655
|
}
|
|
4756
4656
|
}, []);
|
|
4757
|
-
const handleDragOver =
|
|
4657
|
+
const handleDragOver = useCallback15((e) => {
|
|
4758
4658
|
e.preventDefault();
|
|
4759
4659
|
e.stopPropagation();
|
|
4760
4660
|
}, []);
|
|
4761
|
-
const handleDrop =
|
|
4661
|
+
const handleDrop = useCallback15(
|
|
4762
4662
|
(e) => {
|
|
4763
4663
|
e.preventDefault();
|
|
4764
4664
|
e.stopPropagation();
|
|
@@ -4772,7 +4672,8 @@ var ChatInput = React59.forwardRef(
|
|
|
4772
4672
|
);
|
|
4773
4673
|
const isCentered = position === "centered";
|
|
4774
4674
|
const hasAttachments = attachments.length > 0;
|
|
4775
|
-
const
|
|
4675
|
+
const isUploading = attachments.some((a) => a.status === "uploading");
|
|
4676
|
+
const canSubmit = value.trim() && !disabled && !isStreaming && !isUploading;
|
|
4776
4677
|
return /* @__PURE__ */ React59.createElement(
|
|
4777
4678
|
"div",
|
|
4778
4679
|
{
|
|
@@ -4801,7 +4702,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4801
4702
|
notice.variant === "warning" ? "text-gold" : "text-error"
|
|
4802
4703
|
)
|
|
4803
4704
|
},
|
|
4804
|
-
/* @__PURE__ */ React59.createElement(
|
|
4705
|
+
/* @__PURE__ */ React59.createElement(X6, { className: "w-3 h-3" })
|
|
4805
4706
|
)),
|
|
4806
4707
|
/* @__PURE__ */ React59.createElement(
|
|
4807
4708
|
"div",
|
|
@@ -4900,7 +4801,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4900
4801
|
),
|
|
4901
4802
|
"aria-label": "Send message"
|
|
4902
4803
|
},
|
|
4903
|
-
/* @__PURE__ */ React59.createElement(
|
|
4804
|
+
/* @__PURE__ */ React59.createElement(Send2, { className: "w-5 h-5" })
|
|
4904
4805
|
))
|
|
4905
4806
|
)
|
|
4906
4807
|
);
|
|
@@ -4909,7 +4810,8 @@ var ChatInput = React59.forwardRef(
|
|
|
4909
4810
|
ChatInput.displayName = "ChatInput";
|
|
4910
4811
|
|
|
4911
4812
|
// src/components/chat/ArtifactsPanel.tsx
|
|
4912
|
-
import React69, { useCallback as
|
|
4813
|
+
import React69, { useCallback as useCallback17, useEffect as useEffect12, useRef as useRef11, useState as useState17 } from "react";
|
|
4814
|
+
import { Image } from "lucide-react";
|
|
4913
4815
|
|
|
4914
4816
|
// src/components/ArtifactCard.tsx
|
|
4915
4817
|
import React66 from "react";
|
|
@@ -5113,15 +5015,7 @@ var AudioCard = React62.forwardRef(
|
|
|
5113
5015
|
loop,
|
|
5114
5016
|
width: "100%",
|
|
5115
5017
|
height,
|
|
5116
|
-
style: { backgroundColor: "transparent" },
|
|
5117
|
-
config: {
|
|
5118
|
-
file: {
|
|
5119
|
-
forceAudio: true,
|
|
5120
|
-
attributes: {
|
|
5121
|
-
style: { width: "100%", height }
|
|
5122
|
-
}
|
|
5123
|
-
}
|
|
5124
|
-
},
|
|
5018
|
+
style: { backgroundColor: "transparent", width: "100%", height },
|
|
5125
5019
|
...playerProps
|
|
5126
5020
|
}
|
|
5127
5021
|
))),
|
|
@@ -5405,8 +5299,10 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5405
5299
|
)
|
|
5406
5300
|
}
|
|
5407
5301
|
);
|
|
5408
|
-
default:
|
|
5409
|
-
|
|
5302
|
+
default: {
|
|
5303
|
+
const _exhaustive = artifact.type;
|
|
5304
|
+
return _exhaustive;
|
|
5305
|
+
}
|
|
5410
5306
|
}
|
|
5411
5307
|
};
|
|
5412
5308
|
const isCardExpandable = !!onExpand && (artifact.type === "IMAGE" || artifact.type === "PDF" || artifact.type === "SCRIPT" || artifact.type === "TEXT");
|
|
@@ -5443,7 +5339,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5443
5339
|
ArtifactCard.displayName = "ArtifactCard";
|
|
5444
5340
|
|
|
5445
5341
|
// src/components/ArtifactGroup.tsx
|
|
5446
|
-
import React67, { useEffect as useEffect11, useRef as
|
|
5342
|
+
import React67, { useEffect as useEffect11, useRef as useRef10, useState as useState15 } from "react";
|
|
5447
5343
|
var LAYER_OFFSET = "8px";
|
|
5448
5344
|
var LAYER_OFFSET_2X = "16px";
|
|
5449
5345
|
var ArtifactGroup = React67.forwardRef(
|
|
@@ -5451,8 +5347,8 @@ var ArtifactGroup = React67.forwardRef(
|
|
|
5451
5347
|
const children = node.children;
|
|
5452
5348
|
const count = children.length;
|
|
5453
5349
|
const frontChild = children[0];
|
|
5454
|
-
const prevCountRef =
|
|
5455
|
-
const [badgePing, setBadgePing] =
|
|
5350
|
+
const prevCountRef = useRef10(count);
|
|
5351
|
+
const [badgePing, setBadgePing] = useState15(false);
|
|
5456
5352
|
useEffect11(() => {
|
|
5457
5353
|
if (count !== prevCountRef.current) {
|
|
5458
5354
|
prevCountRef.current = count;
|
|
@@ -5573,9 +5469,9 @@ var ArtifactVariantStack = React68.forwardRef(
|
|
|
5573
5469
|
ArtifactVariantStack.displayName = "ArtifactVariantStack";
|
|
5574
5470
|
|
|
5575
5471
|
// src/components/chat/hooks/useArtifactTreeNavigation.ts
|
|
5576
|
-
import { useCallback as
|
|
5472
|
+
import { useCallback as useCallback16, useMemo as useMemo2, useState as useState16 } from "react";
|
|
5577
5473
|
function useArtifactTreeNavigation(rootNodes) {
|
|
5578
|
-
const [stack, setStack] =
|
|
5474
|
+
const [stack, setStack] = useState16([]);
|
|
5579
5475
|
const currentNodes = useMemo2(() => {
|
|
5580
5476
|
if (stack.length === 0) return rootNodes;
|
|
5581
5477
|
return stack[stack.length - 1].children;
|
|
@@ -5588,13 +5484,13 @@ function useArtifactTreeNavigation(rootNodes) {
|
|
|
5588
5484
|
return entries;
|
|
5589
5485
|
}, [stack]);
|
|
5590
5486
|
const isAtRoot = stack.length === 0;
|
|
5591
|
-
const navigateInto =
|
|
5487
|
+
const navigateInto = useCallback16((node) => {
|
|
5592
5488
|
setStack((prev) => [...prev, node]);
|
|
5593
5489
|
}, []);
|
|
5594
|
-
const navigateTo =
|
|
5490
|
+
const navigateTo = useCallback16((index) => {
|
|
5595
5491
|
setStack((prev) => prev.slice(0, index));
|
|
5596
5492
|
}, []);
|
|
5597
|
-
const navigateBack =
|
|
5493
|
+
const navigateBack = useCallback16(() => {
|
|
5598
5494
|
setStack((prev) => prev.slice(0, -1));
|
|
5599
5495
|
}, []);
|
|
5600
5496
|
return {
|
|
@@ -5613,16 +5509,8 @@ function ArtifactModal({
|
|
|
5613
5509
|
artifact,
|
|
5614
5510
|
onClose
|
|
5615
5511
|
}) {
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
if (e.key === "Escape") {
|
|
5619
|
-
onClose();
|
|
5620
|
-
}
|
|
5621
|
-
};
|
|
5622
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
5623
|
-
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
5624
|
-
}, [onClose]);
|
|
5625
|
-
const handleBackdropClick = useCallback15((e) => {
|
|
5512
|
+
useEscapeKey(onClose);
|
|
5513
|
+
const handleBackdropClick = useCallback17((e) => {
|
|
5626
5514
|
if (e.target === e.currentTarget) {
|
|
5627
5515
|
onClose();
|
|
5628
5516
|
}
|
|
@@ -5741,25 +5629,25 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5741
5629
|
className,
|
|
5742
5630
|
...rest
|
|
5743
5631
|
}, ref) => {
|
|
5744
|
-
const [expandedArtifact, setExpandedArtifact] =
|
|
5745
|
-
const [zoomIndex, setZoomIndex] =
|
|
5632
|
+
const [expandedArtifact, setExpandedArtifact] = useState17(null);
|
|
5633
|
+
const [zoomIndex, setZoomIndex] = useState17(ZOOM_LEVELS.length - 1);
|
|
5746
5634
|
const treeNav = useArtifactTreeNavigation(nodes || []);
|
|
5747
5635
|
const hasNodes = !!nodes && nodes.length > 0;
|
|
5748
|
-
const handleExpandArtifact =
|
|
5636
|
+
const handleExpandArtifact = useCallback17((artifact) => {
|
|
5749
5637
|
setExpandedArtifact(artifact);
|
|
5750
5638
|
}, []);
|
|
5751
|
-
const handleGroupClick =
|
|
5639
|
+
const handleGroupClick = useCallback17((node) => {
|
|
5752
5640
|
treeNav.navigateInto(node);
|
|
5753
5641
|
}, [treeNav]);
|
|
5754
|
-
const zoomIn =
|
|
5642
|
+
const zoomIn = useCallback17(() => {
|
|
5755
5643
|
setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
|
|
5756
5644
|
}, []);
|
|
5757
|
-
const zoomOut =
|
|
5645
|
+
const zoomOut = useCallback17(() => {
|
|
5758
5646
|
setZoomIndex((prev) => Math.max(prev - 1, 0));
|
|
5759
5647
|
}, []);
|
|
5760
5648
|
const currentZoom = ZOOM_LEVELS[zoomIndex];
|
|
5761
|
-
const contentRef =
|
|
5762
|
-
const [contentHeight, setContentHeight] =
|
|
5649
|
+
const contentRef = useRef11(null);
|
|
5650
|
+
const [contentHeight, setContentHeight] = useState17(void 0);
|
|
5763
5651
|
useEffect12(() => {
|
|
5764
5652
|
const el = contentRef.current;
|
|
5765
5653
|
if (!el) return;
|
|
@@ -5905,23 +5793,7 @@ var ArtifactsPanelToggle = React69.forwardRef(({ artifactCount = 0, onExpand, cl
|
|
|
5905
5793
|
"aria-label": "Expand artifacts panel",
|
|
5906
5794
|
...rest
|
|
5907
5795
|
},
|
|
5908
|
-
/* @__PURE__ */ React69.createElement(
|
|
5909
|
-
"svg",
|
|
5910
|
-
{
|
|
5911
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
5912
|
-
viewBox: "0 0 20 20",
|
|
5913
|
-
fill: "currentColor",
|
|
5914
|
-
className: "w-5 h-5"
|
|
5915
|
-
},
|
|
5916
|
-
/* @__PURE__ */ React69.createElement(
|
|
5917
|
-
"path",
|
|
5918
|
-
{
|
|
5919
|
-
fillRule: "evenodd",
|
|
5920
|
-
d: "M2 4.5A1.5 1.5 0 013.5 3h13A1.5 1.5 0 0118 4.5v11a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 012 15.5v-11zM4 5v1h1V5H4zm2 0v1h1V5H6zm7 0v1h1V5h-1zm2 0v1h1V5h-1zM4 14v1h1v-1H4zm2 0v1h1v-1H6zm7 0v1h1v-1h-1zm2 0v1h1v-1h-1zM8 8.118a.5.5 0 01.757-.429l4 2.382a.5.5 0 010 .858l-4 2.382A.5.5 0 018 12.882V8.118z",
|
|
5921
|
-
clipRule: "evenodd"
|
|
5922
|
-
}
|
|
5923
|
-
)
|
|
5924
|
-
),
|
|
5796
|
+
/* @__PURE__ */ React69.createElement(Image, { className: "w-5 h-5", "aria-hidden": true }),
|
|
5925
5797
|
artifactCount > 0 && /* @__PURE__ */ React69.createElement(
|
|
5926
5798
|
"span",
|
|
5927
5799
|
{
|
|
@@ -5934,7 +5806,8 @@ var ArtifactsPanelToggle = React69.forwardRef(({ artifactCount = 0, onExpand, cl
|
|
|
5934
5806
|
ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
|
|
5935
5807
|
|
|
5936
5808
|
// src/components/chat/HistoryPanel.tsx
|
|
5937
|
-
import React70, { useCallback as
|
|
5809
|
+
import React70, { useCallback as useCallback18, useEffect as useEffect13, useMemo as useMemo3, useRef as useRef12, useState as useState18 } from "react";
|
|
5810
|
+
import { ChevronDown as ChevronDown2, Pencil as Pencil2 } from "lucide-react";
|
|
5938
5811
|
function parseTimestamp(ts) {
|
|
5939
5812
|
if (ts == null) {
|
|
5940
5813
|
return null;
|
|
@@ -5970,64 +5843,16 @@ function groupConversations(conversations) {
|
|
|
5970
5843
|
{ key: "older", label: "Older", conversations: olderList }
|
|
5971
5844
|
].filter((g) => g.conversations.length > 0);
|
|
5972
5845
|
}
|
|
5973
|
-
function ChevronDownIcon({ className }) {
|
|
5974
|
-
return /* @__PURE__ */ React70.createElement(
|
|
5975
|
-
"svg",
|
|
5976
|
-
{
|
|
5977
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
5978
|
-
viewBox: "0 0 20 20",
|
|
5979
|
-
fill: "currentColor",
|
|
5980
|
-
className,
|
|
5981
|
-
"aria-hidden": "true"
|
|
5982
|
-
},
|
|
5983
|
-
/* @__PURE__ */ React70.createElement(
|
|
5984
|
-
"path",
|
|
5985
|
-
{
|
|
5986
|
-
fillRule: "evenodd",
|
|
5987
|
-
d: "M5.23 7.21a.75.75 0 011.06.02L10 11.06l3.71-3.83a.75.75 0 111.08 1.04l-4.25 4.39a.75.75 0 01-1.08 0L5.21 8.27a.75.75 0 01.02-1.06z",
|
|
5988
|
-
clipRule: "evenodd"
|
|
5989
|
-
}
|
|
5990
|
-
)
|
|
5991
|
-
);
|
|
5992
|
-
}
|
|
5993
|
-
function PencilIcon2({ className }) {
|
|
5994
|
-
return /* @__PURE__ */ React70.createElement(
|
|
5995
|
-
"svg",
|
|
5996
|
-
{
|
|
5997
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
5998
|
-
viewBox: "0 0 20 20",
|
|
5999
|
-
fill: "currentColor",
|
|
6000
|
-
className,
|
|
6001
|
-
"aria-hidden": "true"
|
|
6002
|
-
},
|
|
6003
|
-
/* @__PURE__ */ React70.createElement(
|
|
6004
|
-
"path",
|
|
6005
|
-
{
|
|
6006
|
-
d: "M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
|
|
6007
|
-
}
|
|
6008
|
-
)
|
|
6009
|
-
);
|
|
6010
|
-
}
|
|
6011
5846
|
function ProjectFilter({
|
|
6012
5847
|
projects,
|
|
6013
5848
|
value,
|
|
6014
5849
|
onChange,
|
|
6015
5850
|
className
|
|
6016
5851
|
}) {
|
|
6017
|
-
const [open, setOpen] =
|
|
6018
|
-
const ref =
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
return;
|
|
6022
|
-
}
|
|
6023
|
-
const handler = (e) => {
|
|
6024
|
-
if (ref.current && !ref.current.contains(e.target)) {
|
|
6025
|
-
setOpen(false);
|
|
6026
|
-
}
|
|
6027
|
-
};
|
|
6028
|
-
document.addEventListener("mousedown", handler);
|
|
6029
|
-
return () => document.removeEventListener("mousedown", handler);
|
|
6030
|
-
}, [open]);
|
|
5852
|
+
const [open, setOpen] = useState18(false);
|
|
5853
|
+
const ref = useRef12(null);
|
|
5854
|
+
const closeFilter = useCallback18(() => setOpen(false), []);
|
|
5855
|
+
useClickOutside(ref, closeFilter, open);
|
|
6031
5856
|
const label = value ?? "All projects";
|
|
6032
5857
|
return /* @__PURE__ */ React70.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ React70.createElement(
|
|
6033
5858
|
"button",
|
|
@@ -6046,7 +5871,7 @@ function ProjectFilter({
|
|
|
6046
5871
|
)
|
|
6047
5872
|
},
|
|
6048
5873
|
/* @__PURE__ */ React70.createElement("span", { className: "truncate" }, label),
|
|
6049
|
-
/* @__PURE__ */ React70.createElement(
|
|
5874
|
+
/* @__PURE__ */ React70.createElement(ChevronDown2, { className: "w-3 h-3 shrink-0", "aria-hidden": true })
|
|
6050
5875
|
), open && /* @__PURE__ */ React70.createElement(
|
|
6051
5876
|
"div",
|
|
6052
5877
|
{
|
|
@@ -6101,28 +5926,28 @@ function ConversationRow({
|
|
|
6101
5926
|
onSelect,
|
|
6102
5927
|
onRename
|
|
6103
5928
|
}) {
|
|
6104
|
-
const [isEditing, setIsEditing] =
|
|
6105
|
-
const [draft, setDraft] =
|
|
6106
|
-
const inputRef =
|
|
5929
|
+
const [isEditing, setIsEditing] = useState18(false);
|
|
5930
|
+
const [draft, setDraft] = useState18(conversation.title);
|
|
5931
|
+
const inputRef = useRef12(null);
|
|
6107
5932
|
useEffect13(() => {
|
|
6108
5933
|
if (isEditing && inputRef.current) {
|
|
6109
5934
|
inputRef.current.focus();
|
|
6110
5935
|
inputRef.current.select();
|
|
6111
5936
|
}
|
|
6112
5937
|
}, [isEditing]);
|
|
6113
|
-
const startEdit =
|
|
5938
|
+
const startEdit = useCallback18((e) => {
|
|
6114
5939
|
e.stopPropagation();
|
|
6115
5940
|
setDraft(conversation.title);
|
|
6116
5941
|
setIsEditing(true);
|
|
6117
5942
|
}, [conversation.title]);
|
|
6118
|
-
const commit =
|
|
5943
|
+
const commit = useCallback18(() => {
|
|
6119
5944
|
const trimmed = draft.trim();
|
|
6120
5945
|
if (trimmed && trimmed !== conversation.title) {
|
|
6121
5946
|
onRename?.(conversation.id, trimmed);
|
|
6122
5947
|
}
|
|
6123
5948
|
setIsEditing(false);
|
|
6124
5949
|
}, [draft, conversation.id, conversation.title, onRename]);
|
|
6125
|
-
const cancel =
|
|
5950
|
+
const cancel = useCallback18(() => {
|
|
6126
5951
|
setDraft(conversation.title);
|
|
6127
5952
|
setIsEditing(false);
|
|
6128
5953
|
}, [conversation.title]);
|
|
@@ -6197,7 +6022,7 @@ function ConversationRow({
|
|
|
6197
6022
|
"transition-opacity duration-150"
|
|
6198
6023
|
)
|
|
6199
6024
|
},
|
|
6200
|
-
/* @__PURE__ */ React70.createElement(
|
|
6025
|
+
/* @__PURE__ */ React70.createElement(Pencil2, { className: "w-3.5 h-3.5", "aria-hidden": true })
|
|
6201
6026
|
));
|
|
6202
6027
|
}
|
|
6203
6028
|
function HistoryPanel({
|
|
@@ -6206,7 +6031,7 @@ function HistoryPanel({
|
|
|
6206
6031
|
onNewChat,
|
|
6207
6032
|
onRenameConversation
|
|
6208
6033
|
}) {
|
|
6209
|
-
const [projectFilter, setProjectFilter] =
|
|
6034
|
+
const [projectFilter, setProjectFilter] = useState18(null);
|
|
6210
6035
|
const projects = useMemo3(() => {
|
|
6211
6036
|
const set = /* @__PURE__ */ new Set();
|
|
6212
6037
|
for (const c of conversations) {
|
|
@@ -6272,7 +6097,7 @@ function HistoryPanel({
|
|
|
6272
6097
|
}
|
|
6273
6098
|
|
|
6274
6099
|
// src/components/chat/TodosList.tsx
|
|
6275
|
-
import React71, { useCallback as
|
|
6100
|
+
import React71, { useCallback as useCallback19, useMemo as useMemo4, useState as useState19 } from "react";
|
|
6276
6101
|
import { Loader2 as Loader22, Square as Square2 } from "lucide-react";
|
|
6277
6102
|
var TASK_STATUSES = {
|
|
6278
6103
|
PENDING: "pending",
|
|
@@ -6351,8 +6176,8 @@ function hasInProgressTask(tasks) {
|
|
|
6351
6176
|
var TodosList = React71.forwardRef(
|
|
6352
6177
|
({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
|
|
6353
6178
|
const sortedTasks = useMemo4(() => sortTasks(tasks), [tasks]);
|
|
6354
|
-
const [isStopping, setIsStopping] =
|
|
6355
|
-
const handleStopClick =
|
|
6179
|
+
const [isStopping, setIsStopping] = useState19(false);
|
|
6180
|
+
const handleStopClick = useCallback19(async () => {
|
|
6356
6181
|
if (!onStopAllTasks || isStopping) {
|
|
6357
6182
|
return;
|
|
6358
6183
|
}
|
|
@@ -6477,7 +6302,7 @@ var ToolSidebar = React72.forwardRef(
|
|
|
6477
6302
|
ToolSidebar.displayName = "ToolSidebar";
|
|
6478
6303
|
|
|
6479
6304
|
// src/components/chat/ToolPanelContainer.tsx
|
|
6480
|
-
import React73, { useCallback as
|
|
6305
|
+
import React73, { useCallback as useCallback20, useEffect as useEffect14, useRef as useRef13, useState as useState20 } from "react";
|
|
6481
6306
|
var ToolPanelContainer = React73.forwardRef(
|
|
6482
6307
|
({
|
|
6483
6308
|
topContent,
|
|
@@ -6489,21 +6314,21 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6489
6314
|
initialTopPercent = 60,
|
|
6490
6315
|
...rest
|
|
6491
6316
|
}, ref) => {
|
|
6492
|
-
const [topPercent, setTopPercent] =
|
|
6493
|
-
const [isResizingHeight, setIsResizingHeight] =
|
|
6494
|
-
const containerRef =
|
|
6495
|
-
const lastY =
|
|
6317
|
+
const [topPercent, setTopPercent] = useState20(initialTopPercent);
|
|
6318
|
+
const [isResizingHeight, setIsResizingHeight] = useState20(false);
|
|
6319
|
+
const containerRef = useRef13(null);
|
|
6320
|
+
const lastY = useRef13(null);
|
|
6496
6321
|
const hasBoth = topContent !== null && bottomContent !== null;
|
|
6497
|
-
const startHeightResize =
|
|
6322
|
+
const startHeightResize = useCallback20((e) => {
|
|
6498
6323
|
e.preventDefault();
|
|
6499
6324
|
setIsResizingHeight(true);
|
|
6500
6325
|
lastY.current = e.clientY;
|
|
6501
6326
|
}, []);
|
|
6502
|
-
const stopHeightResize =
|
|
6327
|
+
const stopHeightResize = useCallback20(() => {
|
|
6503
6328
|
setIsResizingHeight(false);
|
|
6504
6329
|
lastY.current = null;
|
|
6505
6330
|
}, []);
|
|
6506
|
-
const resizeHeight =
|
|
6331
|
+
const resizeHeight = useCallback20(
|
|
6507
6332
|
(e) => {
|
|
6508
6333
|
if (!isResizingHeight || lastY.current === null || !containerRef.current) {
|
|
6509
6334
|
return;
|
|
@@ -6544,14 +6369,7 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6544
6369
|
return /* @__PURE__ */ React73.createElement(
|
|
6545
6370
|
"div",
|
|
6546
6371
|
{
|
|
6547
|
-
ref: (
|
|
6548
|
-
containerRef.current = node;
|
|
6549
|
-
if (typeof ref === "function") {
|
|
6550
|
-
ref(node);
|
|
6551
|
-
} else if (ref) {
|
|
6552
|
-
ref.current = node;
|
|
6553
|
-
}
|
|
6554
|
-
},
|
|
6372
|
+
ref: composeRefs(containerRef, ref),
|
|
6555
6373
|
className: cx(
|
|
6556
6374
|
"h-full bg-charcoal/50 flex flex-col relative shrink-0",
|
|
6557
6375
|
side === "left" ? "border-r border-ash/40" : "border-l border-ash/40",
|
|
@@ -6605,26 +6423,26 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6605
6423
|
ToolPanelContainer.displayName = "ToolPanelContainer";
|
|
6606
6424
|
|
|
6607
6425
|
// src/components/chat/hooks/useResizable.ts
|
|
6608
|
-
import { useCallback as
|
|
6426
|
+
import { useCallback as useCallback21, useEffect as useEffect15, useRef as useRef14, useState as useState21 } from "react";
|
|
6609
6427
|
function useResizable({
|
|
6610
6428
|
initialWidthPercent,
|
|
6611
6429
|
minWidthPercent,
|
|
6612
6430
|
maxWidthPercent,
|
|
6613
6431
|
direction
|
|
6614
6432
|
}) {
|
|
6615
|
-
const [widthPercent, setWidthPercent] =
|
|
6616
|
-
const [isResizing, setIsResizing] =
|
|
6617
|
-
const lastX =
|
|
6618
|
-
const startResizing =
|
|
6433
|
+
const [widthPercent, setWidthPercent] = useState21(initialWidthPercent);
|
|
6434
|
+
const [isResizing, setIsResizing] = useState21(false);
|
|
6435
|
+
const lastX = useRef14(null);
|
|
6436
|
+
const startResizing = useCallback21((e) => {
|
|
6619
6437
|
e.preventDefault();
|
|
6620
6438
|
setIsResizing(true);
|
|
6621
6439
|
lastX.current = e.clientX;
|
|
6622
6440
|
}, []);
|
|
6623
|
-
const stopResizing =
|
|
6441
|
+
const stopResizing = useCallback21(() => {
|
|
6624
6442
|
setIsResizing(false);
|
|
6625
6443
|
lastX.current = null;
|
|
6626
6444
|
}, []);
|
|
6627
|
-
const resize =
|
|
6445
|
+
const resize = useCallback21(
|
|
6628
6446
|
(e) => {
|
|
6629
6447
|
if (!isResizing || lastX.current === null) {
|
|
6630
6448
|
return;
|
|
@@ -6686,6 +6504,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6686
6504
|
enableMessageActions = true,
|
|
6687
6505
|
attachments: propsAttachments,
|
|
6688
6506
|
onAttachmentsChange,
|
|
6507
|
+
onAttachmentRemove,
|
|
6689
6508
|
artifactNodes,
|
|
6690
6509
|
isArtifactsPanelOpen,
|
|
6691
6510
|
onArtifactsPanelOpenChange,
|
|
@@ -6700,15 +6519,15 @@ var ChatInterface = React74.forwardRef(
|
|
|
6700
6519
|
className,
|
|
6701
6520
|
...rest
|
|
6702
6521
|
}, ref) => {
|
|
6703
|
-
const prevArtifactNodesRef =
|
|
6704
|
-
const prevTasksRef =
|
|
6705
|
-
const [internalTools, setInternalTools] =
|
|
6522
|
+
const prevArtifactNodesRef = useRef15([]);
|
|
6523
|
+
const prevTasksRef = useRef15([]);
|
|
6524
|
+
const [internalTools, setInternalTools] = useState22({
|
|
6706
6525
|
"top-left": "history",
|
|
6707
6526
|
"bottom-left": null,
|
|
6708
6527
|
"top-right": null,
|
|
6709
6528
|
"bottom-right": null
|
|
6710
6529
|
});
|
|
6711
|
-
const dismissedToolsRef =
|
|
6530
|
+
const dismissedToolsRef = useRef15(/* @__PURE__ */ new Set());
|
|
6712
6531
|
const isPanelControlled = isArtifactsPanelOpen !== void 0;
|
|
6713
6532
|
const activeTools = useMemo5(() => {
|
|
6714
6533
|
if (isPanelControlled) {
|
|
@@ -6754,7 +6573,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6754
6573
|
const external = externalTools.map(({ content: _content, ...def }) => def);
|
|
6755
6574
|
return [...builtIn, ...external];
|
|
6756
6575
|
}, [allSettled, externalTools]);
|
|
6757
|
-
const toggleTool =
|
|
6576
|
+
const toggleTool = useCallback22((toolId) => {
|
|
6758
6577
|
const toolDef = allToolDefinitions.find((t) => t.id === toolId);
|
|
6759
6578
|
if (!toolDef) {
|
|
6760
6579
|
return;
|
|
@@ -6823,7 +6642,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6823
6642
|
prevArtifactNodesRef.current = nodes;
|
|
6824
6643
|
prevTasksRef.current = tasks;
|
|
6825
6644
|
}, [artifactNodes, tasks, isPanelControlled]);
|
|
6826
|
-
const handleBranchSwitch =
|
|
6645
|
+
const handleBranchSwitch = useCallback22(
|
|
6827
6646
|
(nodeId, direction) => {
|
|
6828
6647
|
if (!isTreeMode || !conversationTree || !onTreeChange) {
|
|
6829
6648
|
return;
|
|
@@ -6876,7 +6695,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6876
6695
|
onRetryMessage,
|
|
6877
6696
|
handleBranchSwitch
|
|
6878
6697
|
]);
|
|
6879
|
-
const handleSubmit =
|
|
6698
|
+
const handleSubmit = useCallback22(
|
|
6880
6699
|
(message, attachments) => {
|
|
6881
6700
|
onMessageSubmit?.(message, attachments);
|
|
6882
6701
|
},
|
|
@@ -6995,6 +6814,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6995
6814
|
showAttachmentButton,
|
|
6996
6815
|
attachments: propsAttachments,
|
|
6997
6816
|
onAttachmentsChange,
|
|
6817
|
+
onAttachmentRemove,
|
|
6998
6818
|
notice: inputNotice,
|
|
6999
6819
|
onInputChange,
|
|
7000
6820
|
initialInputValue,
|
|
@@ -7030,8 +6850,8 @@ var ChatInterface = React74.forwardRef(
|
|
|
7030
6850
|
ChatInterface.displayName = "ChatInterface";
|
|
7031
6851
|
|
|
7032
6852
|
// src/components/chat/MessageActions.tsx
|
|
7033
|
-
import React75, { useCallback as
|
|
7034
|
-
import { Check as
|
|
6853
|
+
import React75, { useCallback as useCallback23, useState as useState23 } from "react";
|
|
6854
|
+
import { Check as Check4, Copy as Copy2, Pencil as Pencil3, RotateCcw as RotateCcw2, Send as Send3, X as X7 } from "lucide-react";
|
|
7035
6855
|
var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ React75.createElement(
|
|
7036
6856
|
"button",
|
|
7037
6857
|
{
|
|
@@ -7060,12 +6880,12 @@ var MessageActions = React75.forwardRef(
|
|
|
7060
6880
|
className,
|
|
7061
6881
|
...rest
|
|
7062
6882
|
}, ref) => {
|
|
7063
|
-
const [localIsEditing, setLocalIsEditing] =
|
|
7064
|
-
const [localEditValue, setLocalEditValue] =
|
|
7065
|
-
const
|
|
6883
|
+
const [localIsEditing, setLocalIsEditing] = useState23(false);
|
|
6884
|
+
const [localEditValue, setLocalEditValue] = useState23(content);
|
|
6885
|
+
const { copied, copy } = useCopyToClipboard();
|
|
7066
6886
|
const isEditing = controlledIsEditing ?? localIsEditing;
|
|
7067
6887
|
const editValue = controlledEditValue ?? localEditValue;
|
|
7068
|
-
const setIsEditing =
|
|
6888
|
+
const setIsEditing = useCallback23(
|
|
7069
6889
|
(value) => {
|
|
7070
6890
|
if (onEditingChange) {
|
|
7071
6891
|
onEditingChange(value);
|
|
@@ -7075,41 +6895,28 @@ var MessageActions = React75.forwardRef(
|
|
|
7075
6895
|
},
|
|
7076
6896
|
[onEditingChange]
|
|
7077
6897
|
);
|
|
7078
|
-
const setEditValue =
|
|
6898
|
+
const setEditValue = useCallback23((value) => {
|
|
7079
6899
|
setLocalEditValue(value);
|
|
7080
6900
|
}, []);
|
|
7081
|
-
const handleCopy =
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
7086
|
-
} catch {
|
|
7087
|
-
const textArea = document.createElement("textarea");
|
|
7088
|
-
textArea.value = content;
|
|
7089
|
-
document.body.appendChild(textArea);
|
|
7090
|
-
textArea.select();
|
|
7091
|
-
document.execCommand("copy");
|
|
7092
|
-
document.body.removeChild(textArea);
|
|
7093
|
-
setCopied(true);
|
|
7094
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
7095
|
-
}
|
|
7096
|
-
}, [content]);
|
|
7097
|
-
const handleStartEdit = useCallback21(() => {
|
|
6901
|
+
const handleCopy = useCallback23(() => {
|
|
6902
|
+
void copy(content);
|
|
6903
|
+
}, [copy, content]);
|
|
6904
|
+
const handleStartEdit = useCallback23(() => {
|
|
7098
6905
|
setLocalEditValue(content);
|
|
7099
6906
|
setIsEditing(true);
|
|
7100
6907
|
}, [content, setIsEditing]);
|
|
7101
|
-
const handleCancelEdit =
|
|
6908
|
+
const handleCancelEdit = useCallback23(() => {
|
|
7102
6909
|
setIsEditing(false);
|
|
7103
6910
|
setLocalEditValue(content);
|
|
7104
6911
|
}, [content, setIsEditing]);
|
|
7105
|
-
const handleSubmitEdit =
|
|
6912
|
+
const handleSubmitEdit = useCallback23(() => {
|
|
7106
6913
|
const trimmed = editValue.trim();
|
|
7107
6914
|
if (trimmed && trimmed !== content) {
|
|
7108
6915
|
onEdit?.(trimmed);
|
|
7109
6916
|
}
|
|
7110
6917
|
setIsEditing(false);
|
|
7111
6918
|
}, [editValue, content, onEdit, setIsEditing]);
|
|
7112
|
-
const handleEditKeyDown =
|
|
6919
|
+
const handleEditKeyDown = useCallback23(
|
|
7113
6920
|
(e) => {
|
|
7114
6921
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
7115
6922
|
e.preventDefault();
|
|
@@ -7152,7 +6959,7 @@ var MessageActions = React75.forwardRef(
|
|
|
7152
6959
|
label: "Cancel edit",
|
|
7153
6960
|
className: "text-silver/60 hover:text-error"
|
|
7154
6961
|
},
|
|
7155
|
-
/* @__PURE__ */ React75.createElement(
|
|
6962
|
+
/* @__PURE__ */ React75.createElement(X7, { className: "w-4 h-4" })
|
|
7156
6963
|
), /* @__PURE__ */ React75.createElement(
|
|
7157
6964
|
ActionButton2,
|
|
7158
6965
|
{
|
|
@@ -7161,7 +6968,7 @@ var MessageActions = React75.forwardRef(
|
|
|
7161
6968
|
className: "text-silver/60 hover:text-gold",
|
|
7162
6969
|
disabled: !editValue.trim() || editValue.trim() === content
|
|
7163
6970
|
},
|
|
7164
|
-
/* @__PURE__ */ React75.createElement(
|
|
6971
|
+
/* @__PURE__ */ React75.createElement(Send3, { className: "w-4 h-4" })
|
|
7165
6972
|
))
|
|
7166
6973
|
),
|
|
7167
6974
|
/* @__PURE__ */ React75.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
|
|
@@ -7178,9 +6985,9 @@ var MessageActions = React75.forwardRef(
|
|
|
7178
6985
|
),
|
|
7179
6986
|
...rest
|
|
7180
6987
|
},
|
|
7181
|
-
/* @__PURE__ */ React75.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ React75.createElement(
|
|
7182
|
-
isUser && onEdit && /* @__PURE__ */ React75.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React75.createElement(
|
|
7183
|
-
!isUser && onRetry && /* @__PURE__ */ React75.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ React75.createElement(
|
|
6988
|
+
/* @__PURE__ */ React75.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ React75.createElement(Check4, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ React75.createElement(Copy2, { className: "w-3.5 h-3.5" })),
|
|
6989
|
+
isUser && onEdit && /* @__PURE__ */ React75.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React75.createElement(Pencil3, { className: "w-3.5 h-3.5" })),
|
|
6990
|
+
!isUser && onRetry && /* @__PURE__ */ React75.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ React75.createElement(RotateCcw2, { className: "w-3.5 h-3.5" }))
|
|
7184
6991
|
);
|
|
7185
6992
|
}
|
|
7186
6993
|
);
|
|
@@ -7188,7 +6995,7 @@ MessageActions.displayName = "MessageActions";
|
|
|
7188
6995
|
|
|
7189
6996
|
// src/components/chat/BranchNavigator.tsx
|
|
7190
6997
|
import React76 from "react";
|
|
7191
|
-
import { ChevronLeft as
|
|
6998
|
+
import { ChevronLeft as ChevronLeft3, ChevronRight as ChevronRight4, GitBranch as GitBranch2 } from "lucide-react";
|
|
7192
6999
|
var BranchNavigator = React76.forwardRef(
|
|
7193
7000
|
({
|
|
7194
7001
|
current,
|
|
@@ -7220,7 +7027,7 @@ var BranchNavigator = React76.forwardRef(
|
|
|
7220
7027
|
"aria-label": "Branch navigation",
|
|
7221
7028
|
...rest
|
|
7222
7029
|
},
|
|
7223
|
-
showIcon && /* @__PURE__ */ React76.createElement(
|
|
7030
|
+
showIcon && /* @__PURE__ */ React76.createElement(GitBranch2, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
|
|
7224
7031
|
/* @__PURE__ */ React76.createElement(
|
|
7225
7032
|
"button",
|
|
7226
7033
|
{
|
|
@@ -7234,7 +7041,7 @@ var BranchNavigator = React76.forwardRef(
|
|
|
7234
7041
|
),
|
|
7235
7042
|
"aria-label": "Previous branch"
|
|
7236
7043
|
},
|
|
7237
|
-
/* @__PURE__ */ React76.createElement(
|
|
7044
|
+
/* @__PURE__ */ React76.createElement(ChevronLeft3, { className: iconSize })
|
|
7238
7045
|
),
|
|
7239
7046
|
/* @__PURE__ */ React76.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
|
|
7240
7047
|
/* @__PURE__ */ React76.createElement(
|
|
@@ -7250,7 +7057,7 @@ var BranchNavigator = React76.forwardRef(
|
|
|
7250
7057
|
),
|
|
7251
7058
|
"aria-label": "Next branch"
|
|
7252
7059
|
},
|
|
7253
|
-
/* @__PURE__ */ React76.createElement(
|
|
7060
|
+
/* @__PURE__ */ React76.createElement(ChevronRight4, { className: iconSize })
|
|
7254
7061
|
)
|
|
7255
7062
|
);
|
|
7256
7063
|
}
|
|
@@ -7468,14 +7275,11 @@ export {
|
|
|
7468
7275
|
addMessageToTree,
|
|
7469
7276
|
areAllTasksSettled,
|
|
7470
7277
|
createEmptyTree,
|
|
7471
|
-
createPreviewUrl,
|
|
7472
7278
|
generateId,
|
|
7473
7279
|
getActivePathMessages,
|
|
7474
7280
|
getSiblingInfo,
|
|
7475
7281
|
isBranchPoint,
|
|
7476
|
-
isImageFile,
|
|
7477
7282
|
messagesToTree,
|
|
7478
|
-
revokePreviewUrl,
|
|
7479
7283
|
switchBranch,
|
|
7480
7284
|
updateNodeContent,
|
|
7481
7285
|
useArtifactTreeNavigation,
|