@mordn/chat-widget 0.1.1 → 0.1.4

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.mjs CHANGED
@@ -490,7 +490,7 @@ var PromptInput = ({
490
490
  "form",
491
491
  {
492
492
  className: cn(
493
- "w-full divide-y overflow-hidden rounded-xl border bg-background focus-within:border-ring transition-colors",
493
+ "w-full divide-y divide-[hsl(var(--chat-text)/0.1)] focus-within:divide-ring overflow-hidden rounded-xl border border-[hsl(var(--chat-text)/0.1)] bg-background focus-within:border-ring transition-colors",
494
494
  "[&:focus-within]:shadow-none [&:focus]:shadow-none shadow-none",
495
495
  className
496
496
  ),
@@ -553,7 +553,7 @@ var PromptInputTextarea = ({
553
553
  "w-full resize-none rounded-none border-none p-3 shadow-none outline-none ring-0",
554
554
  "field-sizing-content",
555
555
  "max-h-48 min-h-16",
556
- "focus-visible:ring-0 focus-visible:border-red-500 focus-visible:shadow-none focus:ring-0 focus:shadow-none",
556
+ "focus-visible:ring-0 focus-visible:shadow-none focus:ring-0 focus:shadow-none",
557
557
  className
558
558
  ),
559
559
  name: "message",
@@ -1174,7 +1174,7 @@ var CodeBlock = ({
1174
1174
  "div",
1175
1175
  {
1176
1176
  className: cn(
1177
- "relative w-full overflow-hidden rounded-md border bg-background text-foreground",
1177
+ "relative w-full overflow-hidden rounded-lg bg-[hsl(var(--chat-text)/0.03)] border border-[hsl(var(--chat-text)/0.1)]",
1178
1178
  className
1179
1179
  ),
1180
1180
  ...props,
@@ -1190,12 +1190,13 @@ var CodeBlock = ({
1190
1190
  margin: 0,
1191
1191
  padding: "1rem",
1192
1192
  fontSize: "0.875rem",
1193
- background: "hsl(var(--background))",
1194
- color: "hsl(var(--foreground))"
1193
+ background: "transparent",
1194
+ color: "hsl(var(--chat-text))",
1195
+ border: "none"
1195
1196
  },
1196
1197
  language,
1197
1198
  lineNumberStyle: {
1198
- color: "hsl(var(--muted-foreground))",
1199
+ color: "hsl(var(--chat-text) / 0.4)",
1199
1200
  paddingRight: "1rem",
1200
1201
  minWidth: "2.5rem"
1201
1202
  },
@@ -1215,12 +1216,13 @@ var CodeBlock = ({
1215
1216
  margin: 0,
1216
1217
  padding: "1rem",
1217
1218
  fontSize: "0.875rem",
1218
- background: "hsl(var(--background))",
1219
- color: "hsl(var(--foreground))"
1219
+ background: "transparent",
1220
+ color: "hsl(var(--chat-text))",
1221
+ border: "none"
1220
1222
  },
1221
1223
  language,
1222
1224
  lineNumberStyle: {
1223
- color: "hsl(var(--muted-foreground))",
1225
+ color: "hsl(var(--chat-text) / 0.4)",
1224
1226
  paddingRight: "1rem",
1225
1227
  minWidth: "2.5rem"
1226
1228
  },
@@ -1239,7 +1241,7 @@ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
1239
1241
  var Tool = ({ className, ...props }) => /* @__PURE__ */ jsx17(
1240
1242
  Collapsible,
1241
1243
  {
1242
- className: cn("not-prose w-full rounded-md border", className),
1244
+ className: cn("not-prose w-full rounded-md border border-[hsl(var(--chat-text)/0.1)]", className),
1243
1245
  ...props
1244
1246
  }
1245
1247
  );
@@ -1332,9 +1334,86 @@ var ToolOutput = ({
1332
1334
  ] });
1333
1335
  };
1334
1336
 
1335
- // src/components/interface.tsx
1337
+ // src/components/suggestion2.tsx
1336
1338
  import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
1339
+ function StarterMessages({
1340
+ className,
1341
+ prompts,
1342
+ onPromptSelect,
1343
+ ...props
1344
+ }) {
1345
+ if (prompts.length === 0) return null;
1346
+ return /* @__PURE__ */ jsx18(
1347
+ "div",
1348
+ {
1349
+ className: cn(
1350
+ "mb-3",
1351
+ className
1352
+ ),
1353
+ ...props,
1354
+ children: prompts.map((prompt, index) => /* @__PURE__ */ jsxs11("div", { children: [
1355
+ /* @__PURE__ */ jsx18(
1356
+ StarterMessageItem,
1357
+ {
1358
+ prompt,
1359
+ onClick: () => onPromptSelect(prompt)
1360
+ }
1361
+ ),
1362
+ index < prompts.length - 1 && /* @__PURE__ */ jsx18("div", { className: "h-px bg-[hsl(var(--chat-text)/0.08)] mx-3" })
1363
+ ] }, index))
1364
+ }
1365
+ );
1366
+ }
1367
+ function StarterMessageItem({
1368
+ className,
1369
+ prompt,
1370
+ onClick,
1371
+ ...props
1372
+ }) {
1373
+ return /* @__PURE__ */ jsxs11(
1374
+ "button",
1375
+ {
1376
+ type: "button",
1377
+ onClick,
1378
+ className: cn(
1379
+ "w-full text-left px-3 py-2.5 rounded-lg",
1380
+ "bg-transparent",
1381
+ "hover:bg-[hsl(var(--chat-text)/0.03)]",
1382
+ "transition-colors duration-150 ease-out",
1383
+ "cursor-pointer",
1384
+ className
1385
+ ),
1386
+ ...props,
1387
+ children: [
1388
+ /* @__PURE__ */ jsx18("span", { className: "text-[13px] text-[hsl(var(--chat-text)/0.7)]", children: prompt.title }),
1389
+ prompt.subtitle && /* @__PURE__ */ jsx18("span", { className: "block text-[11px] text-[hsl(var(--chat-text)/0.4)] mt-0.5", children: prompt.subtitle })
1390
+ ]
1391
+ }
1392
+ );
1393
+ }
1394
+
1395
+ // src/contexts/chat-storage-context.tsx
1396
+ import { createContext as createContext4, useContext as useContext4 } from "react";
1397
+ import { jsx as jsx19 } from "react/jsx-runtime";
1398
+ var ChatStorageContext = createContext4({
1399
+ storageKeyPrefix: ""
1400
+ });
1401
+ function ChatStorageProvider({
1402
+ children,
1403
+ userId
1404
+ }) {
1405
+ const storageKeyPrefix = userId || "";
1406
+ return /* @__PURE__ */ jsx19(ChatStorageContext.Provider, { value: { storageKeyPrefix }, children });
1407
+ }
1408
+ function useChatStorageKey() {
1409
+ return useContext4(ChatStorageContext);
1410
+ }
1411
+
1412
+ // src/components/interface.tsx
1413
+ import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
1337
1414
  function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1415
+ const { storageKeyPrefix } = useChatStorageKey();
1416
+ const storageKey = (key) => storageKeyPrefix ? `chat-${storageKeyPrefix}-${key}` : `chat-${key}`;
1338
1417
  const themeMode = config?.theme?.mode || "light";
1339
1418
  const [input, setInput] = useState4("");
1340
1419
  const [showHistory, setShowHistory] = useState4(false);
@@ -1353,8 +1432,6 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1353
1432
  const [activeTabId, setActiveTabId] = useState4("");
1354
1433
  const [initialTabCreated, setInitialTabCreated] = useState4(false);
1355
1434
  const [isInitializing, setIsInitializing] = useState4(true);
1356
- const [componentWidth, setComponentWidth] = useState4(768);
1357
- const [isResizing, setIsResizing] = useState4(false);
1358
1435
  const lastSyncedTabId = useRef3("");
1359
1436
  const hasInitialized = useRef3(false);
1360
1437
  const { messages, sendMessage, status, setMessages } = useChat({
@@ -1446,12 +1523,12 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1446
1523
  };
1447
1524
  const AttachButton = () => {
1448
1525
  const attachments = usePromptInputAttachments();
1449
- return /* @__PURE__ */ jsx18(
1526
+ return /* @__PURE__ */ jsx20(
1450
1527
  PromptInputButton,
1451
1528
  {
1452
1529
  variant: "ghost",
1453
1530
  onClick: () => attachments.openFileDialog(),
1454
- children: /* @__PURE__ */ jsx18(PlusIcon2, { className: "size-4" })
1531
+ children: /* @__PURE__ */ jsx20(PlusIcon2, { className: "size-4" })
1455
1532
  }
1456
1533
  );
1457
1534
  };
@@ -1550,10 +1627,10 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1550
1627
  setTabs(filteredTabs);
1551
1628
  }
1552
1629
  if (filteredTabs.length > 0) {
1553
- localStorage.setItem("chat-tabs", JSON.stringify(filteredTabs));
1630
+ localStorage.setItem(storageKey("tabs"), JSON.stringify(filteredTabs));
1554
1631
  if (tabId === activeTabId) {
1555
1632
  const newActiveTab = filteredTabs[0];
1556
- localStorage.setItem("active-tab-id", newActiveTab.id);
1633
+ localStorage.setItem(storageKey("active-tab-id"), newActiveTab.id);
1557
1634
  }
1558
1635
  }
1559
1636
  };
@@ -1593,18 +1670,18 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1593
1670
  useEffect4(() => {
1594
1671
  if (tabs.length > 0) {
1595
1672
  const timeoutId = setTimeout(() => {
1596
- localStorage.setItem("chat-tabs", JSON.stringify(tabs));
1597
- localStorage.setItem("active-tab-id", activeTabId);
1673
+ localStorage.setItem(storageKey("tabs"), JSON.stringify(tabs));
1674
+ localStorage.setItem(storageKey("active-tab-id"), activeTabId);
1598
1675
  }, 500);
1599
1676
  return () => clearTimeout(timeoutId);
1600
1677
  }
1601
- }, [tabs, activeTabId]);
1678
+ }, [tabs, activeTabId, storageKey]);
1602
1679
  useEffect4(() => {
1603
1680
  if (hasInitialized.current) return;
1604
1681
  const loadInitialTabs = () => {
1605
1682
  try {
1606
- const savedTabs = localStorage.getItem("chat-tabs");
1607
- const savedActiveTabId = localStorage.getItem("active-tab-id");
1683
+ const savedTabs = localStorage.getItem(storageKey("tabs"));
1684
+ const savedActiveTabId = localStorage.getItem(storageKey("active-tab-id"));
1608
1685
  if (savedTabs && savedTabs !== "[]") {
1609
1686
  const parsedTabs = JSON.parse(savedTabs);
1610
1687
  setTabs(parsedTabs);
@@ -1706,10 +1783,10 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1706
1783
  const renderMessages = () => messages.map((message, index) => {
1707
1784
  const sourceParts = message.parts?.filter((part) => part.type === "source-url") || [];
1708
1785
  const fileParts = message.parts?.filter((part) => part.type === "file") || [];
1709
- return /* @__PURE__ */ jsxs11("div", { className: index > 0 ? "mt-6" : "", children: [
1710
- message.role === "assistant" && sourceParts.length > 0 && /* @__PURE__ */ jsxs11(Sources, { children: [
1711
- /* @__PURE__ */ jsx18(SourcesTrigger, { count: sourceParts.length }),
1712
- sourceParts.map((part, i) => /* @__PURE__ */ jsx18(SourcesContent, { children: /* @__PURE__ */ jsx18(
1786
+ return /* @__PURE__ */ jsxs12("div", { className: index > 0 ? "mt-6" : "", children: [
1787
+ message.role === "assistant" && sourceParts.length > 0 && /* @__PURE__ */ jsxs12(Sources, { children: [
1788
+ /* @__PURE__ */ jsx20(SourcesTrigger, { count: sourceParts.length }),
1789
+ sourceParts.map((part, i) => /* @__PURE__ */ jsx20(SourcesContent, { children: /* @__PURE__ */ jsx20(
1713
1790
  Source,
1714
1791
  {
1715
1792
  href: part.url,
@@ -1718,10 +1795,10 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1718
1795
  `${message.id}-${i}`
1719
1796
  ) }, `${message.id}-${i}`))
1720
1797
  ] }),
1721
- fileParts.length > 0 && /* @__PURE__ */ jsx18("div", { className: cn(
1798
+ fileParts.length > 0 && /* @__PURE__ */ jsx20("div", { className: cn(
1722
1799
  "flex mb-1",
1723
1800
  message.role === "user" ? "justify-end" : "justify-start"
1724
- ), children: /* @__PURE__ */ jsx18(
1801
+ ), children: /* @__PURE__ */ jsx20(
1725
1802
  MessageAttachments,
1726
1803
  {
1727
1804
  attachments: fileParts.map((part) => ({
@@ -1732,14 +1809,14 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1732
1809
  }))
1733
1810
  }
1734
1811
  ) }),
1735
- message.parts ? /* @__PURE__ */ jsx18("div", { className: "space-y-2", children: message.parts.map((part, i) => {
1812
+ message.parts ? /* @__PURE__ */ jsx20("div", { className: "space-y-2", children: message.parts.map((part, i) => {
1736
1813
  switch (part.type) {
1737
1814
  case "text":
1738
1815
  const isTextStreaming = status === "streaming" && i === message.parts.length - 1 && message.id === messages.at(-1)?.id;
1739
- return /* @__PURE__ */ jsx18(Fragment5, { children: /* @__PURE__ */ jsx18(Message, { from: message.role, children: /* @__PURE__ */ jsx18(MessageContent, { children: /* @__PURE__ */ jsx18(Response, { isStreaming: isTextStreaming, children: part.text }) }) }) }, `${message.id}-${i}`);
1816
+ return /* @__PURE__ */ jsx20(Fragment5, { children: /* @__PURE__ */ jsx20(Message, { from: message.role, children: /* @__PURE__ */ jsx20(MessageContent, { children: /* @__PURE__ */ jsx20(Response, { isStreaming: isTextStreaming, children: part.text }) }) }) }, `${message.id}-${i}`);
1740
1817
  case "reasoning":
1741
1818
  const isCurrentlyStreaming = status === "streaming" && i === message.parts.length - 1 && message.id === messages.at(-1)?.id;
1742
- return /* @__PURE__ */ jsxs11(
1819
+ return /* @__PURE__ */ jsxs12(
1743
1820
  Reasoning,
1744
1821
  {
1745
1822
  className: "w-full",
@@ -1747,8 +1824,8 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1747
1824
  defaultOpen: false,
1748
1825
  open: isCurrentlyStreaming ? true : void 0,
1749
1826
  children: [
1750
- /* @__PURE__ */ jsx18(ReasoningTrigger, {}),
1751
- /* @__PURE__ */ jsx18(ReasoningContent, { children: part.text })
1827
+ /* @__PURE__ */ jsx20(ReasoningTrigger, {}),
1828
+ /* @__PURE__ */ jsx20(ReasoningContent, { children: part.text })
1752
1829
  ]
1753
1830
  },
1754
1831
  `${message.id}-${i}`
@@ -1756,11 +1833,11 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1756
1833
  default:
1757
1834
  if (part.type.startsWith("tool-") || part.type === "dynamic-tool") {
1758
1835
  const toolPart = part;
1759
- return /* @__PURE__ */ jsxs11(Tool, { children: [
1760
- /* @__PURE__ */ jsx18(ToolHeader, { type: part.type, state: toolPart.state }),
1761
- /* @__PURE__ */ jsxs11(ToolContent, { children: [
1762
- /* @__PURE__ */ jsx18(ToolInput, { input: toolPart.input }),
1763
- /* @__PURE__ */ jsx18(ToolOutput, { output: toolPart.output, errorText: toolPart.errorText })
1836
+ return /* @__PURE__ */ jsxs12(Tool, { children: [
1837
+ /* @__PURE__ */ jsx20(ToolHeader, { type: part.type, state: toolPart.state }),
1838
+ /* @__PURE__ */ jsxs12(ToolContent, { children: [
1839
+ /* @__PURE__ */ jsx20(ToolInput, { input: toolPart.input }),
1840
+ /* @__PURE__ */ jsx20(ToolOutput, { output: toolPart.output, errorText: toolPart.errorText })
1764
1841
  ] })
1765
1842
  ] }, `${message.id}-${i}`);
1766
1843
  }
@@ -1768,7 +1845,7 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1768
1845
  }
1769
1846
  }) }) : (
1770
1847
  /* Handle standard AI SDK messages with content or text property */
1771
- /* @__PURE__ */ jsx18(Fragment5, { children: /* @__PURE__ */ jsx18(Message, { from: message.role, children: /* @__PURE__ */ jsx18(MessageContent, { children: /* @__PURE__ */ jsx18(Response, { children: message.content || message.text }) }) }) }, `${message.id}-content`)
1848
+ /* @__PURE__ */ jsx20(Fragment5, { children: /* @__PURE__ */ jsx20(Message, { from: message.role, children: /* @__PURE__ */ jsx20(MessageContent, { children: /* @__PURE__ */ jsx20(Response, { children: message.content || message.text }) }) }) }, `${message.id}-content`)
1772
1849
  )
1773
1850
  ] }, message.id);
1774
1851
  });
@@ -1814,25 +1891,7 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1814
1891
  document.removeEventListener("mousedown", handleClickOutside);
1815
1892
  };
1816
1893
  }, [showHistory]);
1817
- useEffect4(() => {
1818
- if (!isResizing) return;
1819
- const handleMouseMove = (e) => {
1820
- const newWidth = window.innerWidth - e.clientX;
1821
- const minWidth = 300;
1822
- const maxWidth = window.innerWidth * 0.8;
1823
- setComponentWidth(Math.max(minWidth, Math.min(maxWidth, newWidth)));
1824
- };
1825
- const handleMouseUp = () => {
1826
- setIsResizing(false);
1827
- };
1828
- document.addEventListener("mousemove", handleMouseMove);
1829
- document.addEventListener("mouseup", handleMouseUp);
1830
- return () => {
1831
- document.removeEventListener("mousemove", handleMouseMove);
1832
- document.removeEventListener("mouseup", handleMouseUp);
1833
- };
1834
- }, [isResizing]);
1835
- return /* @__PURE__ */ jsx18("div", { className: cn("w-full h-full flex flex-col bg-white dark:bg-gray-900 overflow-hidden ring-1 ring-black/[0.02] dark:ring-white/[0.03]", themeMode === "dark" && "dark"), children: /* @__PURE__ */ jsxs11(
1894
+ return /* @__PURE__ */ jsx20("div", { className: cn("w-full h-full flex flex-col bg-white dark:bg-gray-900 overflow-hidden ring-1 ring-black/[0.02] dark:ring-white/[0.03]", themeMode === "dark" && "dark"), children: /* @__PURE__ */ jsxs12(
1836
1895
  "div",
1837
1896
  {
1838
1897
  className: cn(
@@ -1840,11 +1899,11 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1840
1899
  themeMode === "dark" && "dark"
1841
1900
  ),
1842
1901
  children: [
1843
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-3 py-2 border-b backdrop-blur-sm relative z-20", style: {
1902
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 px-3 py-2 border-b backdrop-blur-sm relative z-20", style: {
1844
1903
  borderColor: themeMode === "dark" ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)",
1845
1904
  backgroundColor: themeMode === "dark" ? "rgba(37,37,37,0.8)" : "rgba(255,255,255,0.8)"
1846
1905
  }, children: [
1847
- /* @__PURE__ */ jsx18("div", { className: "flex items-center gap-1 flex-1 min-w-0 overflow-x-auto scrollbar-hide py-0.5 scroll-smooth", children: tabs.map((tab, index) => /* @__PURE__ */ jsxs11(
1906
+ /* @__PURE__ */ jsx20("div", { className: "flex items-center gap-1 flex-1 min-w-0 overflow-x-auto scrollbar-hide py-0.5 scroll-smooth", children: tabs.map((tab, index) => /* @__PURE__ */ jsxs12(
1848
1907
  "div",
1849
1908
  {
1850
1909
  className: "relative flex items-center gap-1.5 px-3 py-1.5 rounded-lg cursor-pointer transition-all duration-150 group flex-shrink-0 min-w-0",
@@ -1867,8 +1926,8 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1867
1926
  switchToTab(tab.id);
1868
1927
  },
1869
1928
  children: [
1870
- /* @__PURE__ */ jsx18("span", { className: "truncate max-w-28 text-[13px] font-medium transition-colors", children: tab.title }),
1871
- tabs.length > 1 && /* @__PURE__ */ jsx18(
1929
+ /* @__PURE__ */ jsx20("span", { className: "truncate max-w-28 text-[13px] font-medium transition-colors", children: tab.title }),
1930
+ tabs.length > 1 && /* @__PURE__ */ jsx20(
1872
1931
  "button",
1873
1932
  {
1874
1933
  onClick: (e) => {
@@ -1887,15 +1946,15 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1887
1946
  e.currentTarget.style.opacity = tab.isActive ? "0.6" : "0";
1888
1947
  e.currentTarget.style.backgroundColor = "transparent";
1889
1948
  },
1890
- children: /* @__PURE__ */ jsx18(XIcon2, { className: "h-3 w-3", strokeWidth: 2.5 })
1949
+ children: /* @__PURE__ */ jsx20(XIcon2, { className: "h-3 w-3", strokeWidth: 2.5 })
1891
1950
  }
1892
1951
  )
1893
1952
  ]
1894
1953
  },
1895
1954
  tab.id
1896
1955
  )) }),
1897
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-0.5 flex-shrink-0", children: [
1898
- /* @__PURE__ */ jsx18(
1956
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-0.5 flex-shrink-0", children: [
1957
+ /* @__PURE__ */ jsx20(
1899
1958
  "button",
1900
1959
  {
1901
1960
  onClick: createNewTab,
@@ -1912,11 +1971,11 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1912
1971
  e.currentTarget.style.backgroundColor = "transparent";
1913
1972
  },
1914
1973
  title: "New Chat",
1915
- children: /* @__PURE__ */ jsx18(PlusIcon2, { className: "h-4 w-4", strokeWidth: 2 })
1974
+ children: /* @__PURE__ */ jsx20(PlusIcon2, { className: "h-4 w-4", strokeWidth: 2 })
1916
1975
  }
1917
1976
  ),
1918
- /* @__PURE__ */ jsxs11("div", { className: "relative", ref: dropdownRef, children: [
1919
- /* @__PURE__ */ jsx18(
1977
+ /* @__PURE__ */ jsxs12("div", { className: "relative", ref: dropdownRef, children: [
1978
+ /* @__PURE__ */ jsx20(
1920
1979
  "button",
1921
1980
  {
1922
1981
  onClick: () => setShowHistory(!showHistory),
@@ -1938,21 +1997,21 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1938
1997
  }
1939
1998
  },
1940
1999
  title: "Chat History",
1941
- children: /* @__PURE__ */ jsx18(HistoryIcon, { className: "h-4 w-4", strokeWidth: 2 })
2000
+ children: /* @__PURE__ */ jsx20(HistoryIcon, { className: "h-4 w-4", strokeWidth: 2 })
1942
2001
  }
1943
2002
  ),
1944
- showHistory && /* @__PURE__ */ jsxs11("div", { className: "absolute right-0 top-full mt-1.5 w-72 rounded-xl shadow-[0_4px_24px_rgba(0,0,0,0.08)] dark:shadow-[0_4px_24px_rgba(0,0,0,0.3)] z-50 animate-in fade-in slide-in-from-top-1 duration-150 overflow-hidden", style: {
2003
+ showHistory && /* @__PURE__ */ jsxs12("div", { className: "absolute right-0 top-full mt-1.5 w-72 rounded-xl shadow-[0_4px_24px_rgba(0,0,0,0.08)] dark:shadow-[0_4px_24px_rgba(0,0,0,0.3)] z-50 animate-in fade-in slide-in-from-top-1 duration-150 overflow-hidden", style: {
1945
2004
  backgroundColor: themeMode === "dark" ? "#252525" : "#ffffff",
1946
2005
  border: `1px solid ${themeMode === "dark" ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.1)"}`
1947
2006
  }, children: [
1948
- /* @__PURE__ */ jsx18("div", { className: "p-2.5 border-b", style: {
2007
+ /* @__PURE__ */ jsx20("div", { className: "p-2.5 border-b", style: {
1949
2008
  borderColor: themeMode === "dark" ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)",
1950
2009
  backgroundColor: themeMode === "dark" ? "rgba(0,0,0,0.2)" : "rgba(0,0,0,0.02)"
1951
- }, children: /* @__PURE__ */ jsxs11("div", { className: "relative", children: [
1952
- /* @__PURE__ */ jsx18(SearchIcon, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5", style: {
2010
+ }, children: /* @__PURE__ */ jsxs12("div", { className: "relative", children: [
2011
+ /* @__PURE__ */ jsx20(SearchIcon, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5", style: {
1953
2012
  color: themeMode === "dark" ? "#666666" : "#999999"
1954
2013
  }, strokeWidth: 2 }),
1955
- /* @__PURE__ */ jsx18(
2014
+ /* @__PURE__ */ jsx20(
1956
2015
  "input",
1957
2016
  {
1958
2017
  type: "text",
@@ -1968,25 +2027,25 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
1968
2027
  }
1969
2028
  )
1970
2029
  ] }) }),
1971
- /* @__PURE__ */ jsx18("div", { className: "max-h-[300px] overflow-y-auto ai-assistant-scrollbar", children: loadingHistory ? /* @__PURE__ */ jsx18("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx18("div", { className: "text-[13px]", style: { color: themeMode === "dark" ? "#999999" : "#737373" }, children: "Loading..." }) }) : conversations.length === 0 ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
1972
- /* @__PURE__ */ jsx18("div", { className: "w-12 h-12 rounded-full flex items-center justify-center mb-3", style: {
2030
+ /* @__PURE__ */ jsx20("div", { className: "max-h-[300px] overflow-y-auto ai-assistant-scrollbar", children: loadingHistory ? /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx20("div", { className: "text-[13px]", style: { color: themeMode === "dark" ? "#999999" : "#737373" }, children: "Loading..." }) }) : conversations.length === 0 ? /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
2031
+ /* @__PURE__ */ jsx20("div", { className: "w-12 h-12 rounded-full flex items-center justify-center mb-3", style: {
1973
2032
  backgroundColor: themeMode === "dark" ? "#333333" : "#f5f5f5"
1974
- }, children: /* @__PURE__ */ jsx18(MessageSquareIcon, { className: "h-5 w-5", style: { color: themeMode === "dark" ? "#666666" : "#a3a3a3" }, strokeWidth: 2 }) }),
1975
- /* @__PURE__ */ jsx18("p", { className: "text-[13px] font-medium mb-0.5", style: { color: themeMode === "dark" ? "#e5e5e5" : "#171717" }, children: "No Conversations" }),
1976
- /* @__PURE__ */ jsx18("p", { className: "text-[12px]", style: { color: themeMode === "dark" ? "#999999" : "#737373" }, children: "Start a new chat to begin" })
1977
- ] }) : groupedConversations.length === 0 ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
1978
- /* @__PURE__ */ jsx18("div", { className: "w-12 h-12 rounded-full flex items-center justify-center mb-3", style: {
2033
+ }, children: /* @__PURE__ */ jsx20(MessageSquareIcon, { className: "h-5 w-5", style: { color: themeMode === "dark" ? "#666666" : "#a3a3a3" }, strokeWidth: 2 }) }),
2034
+ /* @__PURE__ */ jsx20("p", { className: "text-[13px] font-medium mb-0.5", style: { color: themeMode === "dark" ? "#e5e5e5" : "#171717" }, children: "No Conversations" }),
2035
+ /* @__PURE__ */ jsx20("p", { className: "text-[12px]", style: { color: themeMode === "dark" ? "#999999" : "#737373" }, children: "Start a new chat to begin" })
2036
+ ] }) : groupedConversations.length === 0 ? /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
2037
+ /* @__PURE__ */ jsx20("div", { className: "w-12 h-12 rounded-full flex items-center justify-center mb-3", style: {
1979
2038
  backgroundColor: themeMode === "dark" ? "#333333" : "#f5f5f5"
1980
- }, children: /* @__PURE__ */ jsx18(SearchIcon, { className: "h-5 w-5", style: { color: themeMode === "dark" ? "#666666" : "#a3a3a3" }, strokeWidth: 2 }) }),
1981
- /* @__PURE__ */ jsx18("p", { className: "text-[13px] font-medium mb-0.5", style: { color: themeMode === "dark" ? "#e5e5e5" : "#171717" }, children: "No Results" }),
1982
- /* @__PURE__ */ jsx18("p", { className: "text-[12px]", style: { color: themeMode === "dark" ? "#999999" : "#737373" }, children: "Try a different search" })
1983
- ] }) : /* @__PURE__ */ jsx18("div", { className: "py-0.5", children: groupedConversations.map(([groupName, groupConversations]) => /* @__PURE__ */ jsxs11("div", { className: "mb-0.5", children: [
1984
- /* @__PURE__ */ jsx18("div", { className: "px-2.5 py-1 sticky top-0 backdrop-blur-sm z-10", style: {
2039
+ }, children: /* @__PURE__ */ jsx20(SearchIcon, { className: "h-5 w-5", style: { color: themeMode === "dark" ? "#666666" : "#a3a3a3" }, strokeWidth: 2 }) }),
2040
+ /* @__PURE__ */ jsx20("p", { className: "text-[13px] font-medium mb-0.5", style: { color: themeMode === "dark" ? "#e5e5e5" : "#171717" }, children: "No Results" }),
2041
+ /* @__PURE__ */ jsx20("p", { className: "text-[12px]", style: { color: themeMode === "dark" ? "#999999" : "#737373" }, children: "Try a different search" })
2042
+ ] }) : /* @__PURE__ */ jsx20("div", { className: "py-0.5", children: groupedConversations.map(([groupName, groupConversations]) => /* @__PURE__ */ jsxs12("div", { className: "mb-0.5", children: [
2043
+ /* @__PURE__ */ jsx20("div", { className: "px-2.5 py-1 sticky top-0 backdrop-blur-sm z-10", style: {
1985
2044
  backgroundColor: themeMode === "dark" ? "rgba(37,37,37,0.95)" : "rgba(255,255,255,0.95)"
1986
- }, children: /* @__PURE__ */ jsx18("h3", { className: "text-[10px] font-semibold uppercase tracking-wide", style: { color: themeMode === "dark" ? "#999999" : "#737373" }, children: groupName }) }),
1987
- /* @__PURE__ */ jsx18("div", { className: "px-1 space-y-0.5", children: groupConversations.map((conversation) => {
2045
+ }, children: /* @__PURE__ */ jsx20("h3", { className: "text-[10px] font-semibold uppercase tracking-wide", style: { color: themeMode === "dark" ? "#999999" : "#737373" }, children: groupName }) }),
2046
+ /* @__PURE__ */ jsx20("div", { className: "px-1 space-y-0.5", children: groupConversations.map((conversation) => {
1988
2047
  const isActiveConversation = activeTabId === conversation.id;
1989
- return /* @__PURE__ */ jsx18(
2048
+ return /* @__PURE__ */ jsx20(
1990
2049
  "button",
1991
2050
  {
1992
2051
  className: "w-full px-2 py-1 rounded-md transition-all duration-150 text-left group relative",
@@ -2004,12 +2063,12 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
2004
2063
  }
2005
2064
  },
2006
2065
  onClick: () => handleSelectConversation(conversation.id, conversation.title),
2007
- children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5", children: [
2008
- /* @__PURE__ */ jsx18("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx18("p", { className: "text-[12px] line-clamp-1 transition-colors leading-tight", style: {
2066
+ children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5", children: [
2067
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx20("p", { className: "text-[12px] line-clamp-1 transition-colors leading-tight", style: {
2009
2068
  fontWeight: isActiveConversation ? 500 : 400,
2010
2069
  color: isActiveConversation ? themeMode === "dark" ? "#e5e5e5" : "#171717" : themeMode === "dark" ? "#cccccc" : "#404040"
2011
2070
  }, children: conversation.title }) }),
2012
- /* @__PURE__ */ jsx18(
2071
+ /* @__PURE__ */ jsx20(
2013
2072
  ChevronRightIcon2,
2014
2073
  {
2015
2074
  className: "h-3 w-3 transition-all duration-150 flex-shrink-0",
@@ -2028,7 +2087,7 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
2028
2087
  ] }, groupName)) }) })
2029
2088
  ] })
2030
2089
  ] }),
2031
- onClose && /* @__PURE__ */ jsx18(
2090
+ onClose && /* @__PURE__ */ jsx20(
2032
2091
  "button",
2033
2092
  {
2034
2093
  onClick: onClose,
@@ -2045,24 +2104,33 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
2045
2104
  e.currentTarget.style.backgroundColor = "transparent";
2046
2105
  },
2047
2106
  title: "Close Chat",
2048
- children: /* @__PURE__ */ jsx18(XIcon2, { className: "h-4 w-4", strokeWidth: 2 })
2107
+ children: /* @__PURE__ */ jsx20(XIcon2, { className: "h-4 w-4", strokeWidth: 2 })
2049
2108
  }
2050
2109
  )
2051
2110
  ] })
2052
2111
  ] }),
2053
- /* @__PURE__ */ jsxs11(Conversation, { className: "flex-1 max-w-full ai-assistant-scrollbar", children: [
2054
- /* @__PURE__ */ jsxs11(ConversationContent, { className: "max-w-[96%] mx-auto py-6", children: [
2112
+ /* @__PURE__ */ jsxs12(Conversation, { className: "flex-1 max-w-full ai-assistant-scrollbar", children: [
2113
+ /* @__PURE__ */ jsxs12(ConversationContent, { className: "max-w-[96%] mx-auto py-6", children: [
2055
2114
  renderMessages(),
2056
- status === "submitted" && /* @__PURE__ */ jsx18("div", { className: "mt-6", children: /* @__PURE__ */ jsx18(Message, { from: "assistant", children: /* @__PURE__ */ jsx18(MessageContent, { children: /* @__PURE__ */ jsx18(Loader, { size: 16 }) }) }) })
2115
+ status === "submitted" && /* @__PURE__ */ jsx20("div", { className: "mt-6", children: /* @__PURE__ */ jsx20(Message, { from: "assistant", children: /* @__PURE__ */ jsx20(MessageContent, { children: /* @__PURE__ */ jsx20(Loader, { size: 16 }) }) }) })
2057
2116
  ] }),
2058
- /* @__PURE__ */ jsx18(ConversationScrollButton, {})
2117
+ /* @__PURE__ */ jsx20(ConversationScrollButton, {})
2059
2118
  ] }),
2060
- /* @__PURE__ */ jsxs11("div", { className: "px-5 pb-5", children: [
2061
- uploadError && /* @__PURE__ */ jsx18("div", { className: "mb-3 px-4 py-3 bg-red-50 dark:bg-red-900/20 border border-red-200/60 dark:border-red-800/60 rounded-2xl text-sm text-red-700 dark:text-red-400 shadow-sm", children: uploadError }),
2062
- /* @__PURE__ */ jsxs11(PromptInput, { onSubmit: handleSubmit, globalDrop: true, multiple: true, accept: "image/*", children: [
2063
- /* @__PURE__ */ jsxs11(PromptInputBody, { children: [
2064
- /* @__PURE__ */ jsx18(PromptInputAttachments, { children: (attachment) => /* @__PURE__ */ jsx18(PromptInputAttachment, { data: attachment }) }),
2065
- /* @__PURE__ */ jsx18(
2119
+ /* @__PURE__ */ jsxs12("div", { className: "px-5 pb-5", children: [
2120
+ uploadError && /* @__PURE__ */ jsx20("div", { className: "mb-3 px-4 py-3 bg-red-50 dark:bg-red-900/20 border border-red-200/60 dark:border-red-800/60 rounded-2xl text-sm text-red-700 dark:text-red-400 shadow-sm", children: uploadError }),
2121
+ messages.length === 0 && status !== "submitted" && config?.starterPrompts && /* @__PURE__ */ jsx20(
2122
+ StarterMessages,
2123
+ {
2124
+ prompts: config.starterPrompts,
2125
+ onPromptSelect: (prompt) => {
2126
+ handleSubmit({ text: prompt.title });
2127
+ }
2128
+ }
2129
+ ),
2130
+ /* @__PURE__ */ jsxs12(PromptInput, { onSubmit: handleSubmit, globalDrop: true, multiple: true, accept: "image/*", children: [
2131
+ /* @__PURE__ */ jsxs12(PromptInputBody, { children: [
2132
+ /* @__PURE__ */ jsx20(PromptInputAttachments, { children: (attachment) => /* @__PURE__ */ jsx20(PromptInputAttachment, { data: attachment }) }),
2133
+ /* @__PURE__ */ jsx20(
2066
2134
  PromptInputTextarea,
2067
2135
  {
2068
2136
  onChange: (e) => setInput(e.target.value),
@@ -2070,9 +2138,9 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
2070
2138
  }
2071
2139
  )
2072
2140
  ] }),
2073
- /* @__PURE__ */ jsxs11(PromptInputToolbar, { children: [
2074
- /* @__PURE__ */ jsx18(PromptInputTools, { children: config?.features?.fileUpload !== false && /* @__PURE__ */ jsx18(AttachButton, {}) }),
2075
- /* @__PURE__ */ jsx18(PromptInputSubmit, { disabled: !input, status })
2141
+ /* @__PURE__ */ jsxs12(PromptInputToolbar, { children: [
2142
+ /* @__PURE__ */ jsx20(PromptInputTools, { children: config?.features?.fileUpload === true && /* @__PURE__ */ jsx20(AttachButton, {}) }),
2143
+ /* @__PURE__ */ jsx20(PromptInputSubmit, { disabled: !input, status })
2076
2144
  ] })
2077
2145
  ] })
2078
2146
  ] })
@@ -2083,7 +2151,7 @@ function ChatInterface({ id, initialMessages, config, onClose } = {}) {
2083
2151
 
2084
2152
  // src/ChatWidget.tsx
2085
2153
  import { MessageCircle } from "lucide-react";
2086
- import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
2154
+ import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
2087
2155
  function ChatWidget({
2088
2156
  userId,
2089
2157
  conversationId,
@@ -2094,93 +2162,90 @@ function ChatWidget({
2094
2162
  temperature,
2095
2163
  theme,
2096
2164
  features,
2097
- display
2165
+ display,
2166
+ starterPrompts
2098
2167
  }) {
2099
- const initialWidth = display?.width || "30vw";
2100
2168
  const showToggleButton = display?.showToggleButton !== false;
2169
+ const resizable = display?.resizable !== false;
2170
+ const size = display?.size || "default";
2101
2171
  const [isOpen, setIsOpen] = useState5(display?.defaultOpen || false);
2102
- const [width, setWidth] = useState5(() => {
2103
- const value = parseInt(initialWidth);
2104
- if (initialWidth.includes("vw")) {
2105
- return value / 100 * window.innerWidth;
2172
+ const [isResizing, setIsResizing] = useState5(false);
2173
+ const containerRef = useRef4(null);
2174
+ const customStyles = useMemo3(() => {
2175
+ const styles = {};
2176
+ if (display?.width) {
2177
+ styles["--chat-widget-width"] = display.width;
2106
2178
  }
2107
- return value || window.innerWidth * 0.3;
2108
- });
2109
- const isResizing = useRef4(false);
2179
+ return styles;
2180
+ }, [display?.width]);
2110
2181
  const handleMouseDown = useCallback4((e) => {
2182
+ if (!resizable) return;
2111
2183
  e.preventDefault();
2112
- isResizing.current = true;
2184
+ setIsResizing(true);
2113
2185
  document.body.style.cursor = "ew-resize";
2114
2186
  document.body.style.userSelect = "none";
2115
- }, []);
2187
+ }, [resizable]);
2116
2188
  useEffect5(() => {
2117
- const getConstraints = () => ({
2118
- minWidth: window.innerWidth * 0.2,
2119
- maxWidth: window.innerWidth * 0.6
2120
- });
2189
+ if (!isResizing) return;
2121
2190
  const handleMouseMove = (e) => {
2122
- if (!isResizing.current) return;
2123
- const { minWidth, maxWidth } = getConstraints();
2191
+ if (!containerRef.current) return;
2124
2192
  const newWidth = window.innerWidth - e.clientX;
2125
- setWidth(Math.min(maxWidth, Math.max(minWidth, newWidth)));
2193
+ const minWidth = 300;
2194
+ const maxWidth = Math.min(800, window.innerWidth * 0.8);
2195
+ const clampedWidth = Math.min(maxWidth, Math.max(minWidth, newWidth));
2196
+ containerRef.current.style.setProperty("--chat-widget-width", `${clampedWidth}px`);
2126
2197
  };
2127
2198
  const handleMouseUp = () => {
2128
- if (isResizing.current) {
2129
- isResizing.current = false;
2130
- document.body.style.cursor = "";
2131
- document.body.style.userSelect = "";
2132
- }
2133
- };
2134
- const handleWindowResize = () => {
2135
- const { minWidth, maxWidth } = getConstraints();
2136
- setWidth((prev) => Math.min(maxWidth, Math.max(minWidth, prev)));
2199
+ setIsResizing(false);
2200
+ document.body.style.cursor = "";
2201
+ document.body.style.userSelect = "";
2137
2202
  };
2138
2203
  document.addEventListener("mousemove", handleMouseMove);
2139
2204
  document.addEventListener("mouseup", handleMouseUp);
2140
- window.addEventListener("resize", handleWindowResize);
2141
2205
  return () => {
2142
2206
  document.removeEventListener("mousemove", handleMouseMove);
2143
2207
  document.removeEventListener("mouseup", handleMouseUp);
2144
- window.removeEventListener("resize", handleWindowResize);
2145
2208
  };
2146
- }, []);
2209
+ }, [isResizing]);
2147
2210
  const config = useMemo3(() => ({
2148
2211
  userId,
2149
2212
  model,
2150
2213
  systemPrompt,
2151
2214
  temperature,
2152
2215
  theme,
2153
- features
2154
- }), [userId, model, systemPrompt, temperature, theme, features]);
2216
+ features,
2217
+ starterPrompts
2218
+ }), [userId, model, systemPrompt, temperature, theme, features, starterPrompts]);
2155
2219
  const togglePosition = display?.toggleButtonPosition || { bottom: "24px", right: "24px" };
2156
- return /* @__PURE__ */ jsxs12(Fragment6, { children: [
2157
- showToggleButton && !isOpen && /* @__PURE__ */ jsx19(
2220
+ return /* @__PURE__ */ jsxs13(ChatStorageProvider, { userId, children: [
2221
+ showToggleButton && !isOpen && /* @__PURE__ */ jsx21(
2158
2222
  "button",
2159
2223
  {
2160
2224
  onClick: () => setIsOpen(true),
2161
2225
  className: "fixed z-50 rounded-full bg-primary text-primary-foreground shadow-lg hover:opacity-90 transition-all p-4",
2162
2226
  style: togglePosition,
2163
2227
  "aria-label": "Open chat",
2164
- children: /* @__PURE__ */ jsx19(MessageCircle, { className: "h-6 w-6" })
2228
+ children: /* @__PURE__ */ jsx21(MessageCircle, { className: "h-6 w-6" })
2165
2229
  }
2166
2230
  ),
2167
- isOpen && /* @__PURE__ */ jsxs12(
2231
+ isOpen && /* @__PURE__ */ jsxs13(
2168
2232
  "div",
2169
2233
  {
2170
- className: `fixed top-0 right-0 h-screen z-50 border-l border-gray-200 dark:border-gray-800 ${className || ""}`,
2171
- style: {
2172
- animation: "chat-slide-in-right 0.3s ease-out forwards",
2173
- width: `${width}px`
2174
- },
2234
+ ref: containerRef,
2235
+ className: `chat-widget-container chat-widget-popup chat-widget-content ${theme?.mode === "dark" ? "dark" : ""} ${className || ""}`,
2236
+ "data-size": size,
2237
+ "data-resizing": isResizing,
2238
+ style: customStyles,
2175
2239
  children: [
2176
- /* @__PURE__ */ jsx19(
2240
+ resizable && /* @__PURE__ */ jsx21(
2177
2241
  "div",
2178
2242
  {
2179
2243
  onMouseDown: handleMouseDown,
2180
- className: "absolute left-0 top-0 h-full w-1 cursor-ew-resize hover:bg-primary/20 active:bg-primary/30 transition-colors z-10"
2244
+ className: "chat-widget-resize-handle",
2245
+ "aria-label": "Resize chat widget"
2181
2246
  }
2182
2247
  ),
2183
- /* @__PURE__ */ jsx19("div", { className: "w-full h-full overflow-hidden", children: /* @__PURE__ */ jsx19(
2248
+ /* @__PURE__ */ jsx21("div", { className: "w-full h-full overflow-hidden", children: /* @__PURE__ */ jsx21(
2184
2249
  ChatInterface,
2185
2250
  {
2186
2251
  id: conversationId,
@@ -2315,6 +2380,8 @@ var defaultSystemPrompt = "You are a helpful AI assistant.";
2315
2380
  var defaultTemperature = 0.7;
2316
2381
  var defaultThemeMode = "light";
2317
2382
  function useChatTheme() {
2383
+ const { storageKeyPrefix } = useChatStorageKey();
2384
+ const keyPrefix = storageKeyPrefix ? `chat-${storageKeyPrefix}-` : "chat-";
2318
2385
  const [theme, setTheme] = useState6(defaultTheme);
2319
2386
  const [conversationStarters, setConversationStarters] = useState6(defaultConversationStarters);
2320
2387
  const [model, setModel] = useState6(defaultModel);
@@ -2322,7 +2389,7 @@ function useChatTheme() {
2322
2389
  const [temperature, setTemperature] = useState6(defaultTemperature);
2323
2390
  const [themeMode, setThemeMode] = useState6(defaultThemeMode);
2324
2391
  useEffect6(() => {
2325
- const savedTheme = localStorage.getItem("chat-theme");
2392
+ const savedTheme = localStorage.getItem(`${keyPrefix}theme`);
2326
2393
  if (savedTheme) {
2327
2394
  try {
2328
2395
  setTheme(JSON.parse(savedTheme));
@@ -2330,7 +2397,7 @@ function useChatTheme() {
2330
2397
  console.error("Error loading theme:", error);
2331
2398
  }
2332
2399
  }
2333
- const savedStarters = localStorage.getItem("chat-conversation-starters");
2400
+ const savedStarters = localStorage.getItem(`${keyPrefix}conversation-starters`);
2334
2401
  if (savedStarters) {
2335
2402
  try {
2336
2403
  setConversationStarters(JSON.parse(savedStarters));
@@ -2338,7 +2405,7 @@ function useChatTheme() {
2338
2405
  console.error("Error loading conversation starters:", error);
2339
2406
  }
2340
2407
  }
2341
- const savedModel = localStorage.getItem("chat-model");
2408
+ const savedModel = localStorage.getItem(`${keyPrefix}model`);
2342
2409
  if (savedModel) {
2343
2410
  try {
2344
2411
  setModel(savedModel);
@@ -2346,7 +2413,7 @@ function useChatTheme() {
2346
2413
  console.error("Error loading model:", error);
2347
2414
  }
2348
2415
  }
2349
- const savedSystemPrompt = localStorage.getItem("chat-system-prompt");
2416
+ const savedSystemPrompt = localStorage.getItem(`${keyPrefix}system-prompt`);
2350
2417
  if (savedSystemPrompt) {
2351
2418
  try {
2352
2419
  setSystemPrompt(savedSystemPrompt);
@@ -2354,7 +2421,7 @@ function useChatTheme() {
2354
2421
  console.error("Error loading system prompt:", error);
2355
2422
  }
2356
2423
  }
2357
- const savedTemperature = localStorage.getItem("chat-temperature");
2424
+ const savedTemperature = localStorage.getItem(`${keyPrefix}temperature`);
2358
2425
  if (savedTemperature) {
2359
2426
  try {
2360
2427
  setTemperature(parseFloat(savedTemperature));
@@ -2362,7 +2429,7 @@ function useChatTheme() {
2362
2429
  console.error("Error loading temperature:", error);
2363
2430
  }
2364
2431
  }
2365
- const savedThemeMode = localStorage.getItem("chat-theme-mode");
2432
+ const savedThemeMode = localStorage.getItem(`${keyPrefix}theme-mode`);
2366
2433
  if (savedThemeMode) {
2367
2434
  try {
2368
2435
  setThemeMode(savedThemeMode);
@@ -2408,9 +2475,9 @@ function useChatTheme() {
2408
2475
  window.removeEventListener("chat-temperature-change", handleTemperatureChange);
2409
2476
  window.removeEventListener("chat-theme-mode-change", handleThemeModeChange);
2410
2477
  };
2411
- }, []);
2478
+ }, [keyPrefix]);
2412
2479
  useEffect6(() => {
2413
- localStorage.setItem("chat-theme", JSON.stringify(theme));
2480
+ localStorage.setItem(`${keyPrefix}theme`, JSON.stringify(theme));
2414
2481
  const root = document.documentElement;
2415
2482
  if (themeMode === "light") {
2416
2483
  root.style.setProperty("--chat-primary", hexToHSL(theme.lightPrimary));
@@ -2424,27 +2491,27 @@ function useChatTheme() {
2424
2491
  root.style.setProperty("--chat-font-family", theme.fontFamily);
2425
2492
  root.style.setProperty("--chat-font-size", `${theme.fontSize}px`);
2426
2493
  window.dispatchEvent(new CustomEvent("chat-theme-change", { detail: theme }));
2427
- }, [theme, themeMode]);
2494
+ }, [theme, themeMode, keyPrefix]);
2428
2495
  useEffect6(() => {
2429
- localStorage.setItem("chat-conversation-starters", JSON.stringify(conversationStarters));
2496
+ localStorage.setItem(`${keyPrefix}conversation-starters`, JSON.stringify(conversationStarters));
2430
2497
  window.dispatchEvent(new CustomEvent("chat-starters-change", { detail: conversationStarters }));
2431
- }, [conversationStarters]);
2498
+ }, [conversationStarters, keyPrefix]);
2432
2499
  useEffect6(() => {
2433
- localStorage.setItem("chat-model", model);
2500
+ localStorage.setItem(`${keyPrefix}model`, model);
2434
2501
  window.dispatchEvent(new CustomEvent("chat-model-change", { detail: model }));
2435
- }, [model]);
2502
+ }, [model, keyPrefix]);
2436
2503
  useEffect6(() => {
2437
- localStorage.setItem("chat-system-prompt", systemPrompt);
2504
+ localStorage.setItem(`${keyPrefix}system-prompt`, systemPrompt);
2438
2505
  window.dispatchEvent(new CustomEvent("chat-system-prompt-change", { detail: systemPrompt }));
2439
- }, [systemPrompt]);
2506
+ }, [systemPrompt, keyPrefix]);
2440
2507
  useEffect6(() => {
2441
- localStorage.setItem("chat-temperature", temperature.toString());
2508
+ localStorage.setItem(`${keyPrefix}temperature`, temperature.toString());
2442
2509
  window.dispatchEvent(new CustomEvent("chat-temperature-change", { detail: temperature }));
2443
- }, [temperature]);
2510
+ }, [temperature, keyPrefix]);
2444
2511
  useEffect6(() => {
2445
- localStorage.setItem("chat-theme-mode", themeMode);
2512
+ localStorage.setItem(`${keyPrefix}theme-mode`, themeMode);
2446
2513
  window.dispatchEvent(new CustomEvent("chat-theme-mode-change", { detail: themeMode }));
2447
- }, [themeMode]);
2514
+ }, [themeMode, keyPrefix]);
2448
2515
  const updateColor = (key, value) => {
2449
2516
  setTheme((prev) => ({ ...prev, [key]: value }));
2450
2517
  };
@@ -2511,10 +2578,10 @@ function useChatTheme() {
2511
2578
 
2512
2579
  // src/ui/input.tsx
2513
2580
  import * as React from "react";
2514
- import { jsx as jsx20 } from "react/jsx-runtime";
2581
+ import { jsx as jsx22 } from "react/jsx-runtime";
2515
2582
  var Input = React.forwardRef(
2516
2583
  ({ className, type, ...props }, ref) => {
2517
- return /* @__PURE__ */ jsx20(
2584
+ return /* @__PURE__ */ jsx22(
2518
2585
  "input",
2519
2586
  {
2520
2587
  type,
@@ -2533,22 +2600,22 @@ Input.displayName = "Input";
2533
2600
  // src/ui/dialog.tsx
2534
2601
  import * as DialogPrimitive from "@radix-ui/react-dialog";
2535
2602
  import { XIcon as XIcon3 } from "lucide-react";
2536
- import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
2603
+ import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
2537
2604
  function Dialog({
2538
2605
  ...props
2539
2606
  }) {
2540
- return /* @__PURE__ */ jsx21(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
2607
+ return /* @__PURE__ */ jsx23(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
2541
2608
  }
2542
2609
  function DialogPortal({
2543
2610
  ...props
2544
2611
  }) {
2545
- return /* @__PURE__ */ jsx21(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
2612
+ return /* @__PURE__ */ jsx23(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
2546
2613
  }
2547
2614
  function DialogOverlay({
2548
2615
  className,
2549
2616
  ...props
2550
2617
  }) {
2551
- return /* @__PURE__ */ jsx21(
2618
+ return /* @__PURE__ */ jsx23(
2552
2619
  DialogPrimitive.Overlay,
2553
2620
  {
2554
2621
  "data-slot": "dialog-overlay",
@@ -2566,9 +2633,9 @@ function DialogContent({
2566
2633
  showCloseButton = true,
2567
2634
  ...props
2568
2635
  }) {
2569
- return /* @__PURE__ */ jsxs13(DialogPortal, { "data-slot": "dialog-portal", children: [
2570
- /* @__PURE__ */ jsx21(DialogOverlay, {}),
2571
- /* @__PURE__ */ jsxs13(
2636
+ return /* @__PURE__ */ jsxs14(DialogPortal, { "data-slot": "dialog-portal", children: [
2637
+ /* @__PURE__ */ jsx23(DialogOverlay, {}),
2638
+ /* @__PURE__ */ jsxs14(
2572
2639
  DialogPrimitive.Content,
2573
2640
  {
2574
2641
  "data-slot": "dialog-content",
@@ -2579,14 +2646,14 @@ function DialogContent({
2579
2646
  ...props,
2580
2647
  children: [
2581
2648
  children,
2582
- showCloseButton && /* @__PURE__ */ jsxs13(
2649
+ showCloseButton && /* @__PURE__ */ jsxs14(
2583
2650
  DialogPrimitive.Close,
2584
2651
  {
2585
2652
  "data-slot": "dialog-close",
2586
2653
  className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
2587
2654
  children: [
2588
- /* @__PURE__ */ jsx21(XIcon3, {}),
2589
- /* @__PURE__ */ jsx21("span", { className: "sr-only", children: "Close" })
2655
+ /* @__PURE__ */ jsx23(XIcon3, {}),
2656
+ /* @__PURE__ */ jsx23("span", { className: "sr-only", children: "Close" })
2590
2657
  ]
2591
2658
  }
2592
2659
  )
@@ -2596,7 +2663,7 @@ function DialogContent({
2596
2663
  ] });
2597
2664
  }
2598
2665
  function DialogHeader({ className, ...props }) {
2599
- return /* @__PURE__ */ jsx21(
2666
+ return /* @__PURE__ */ jsx23(
2600
2667
  "div",
2601
2668
  {
2602
2669
  "data-slot": "dialog-header",
@@ -2609,7 +2676,7 @@ function DialogTitle({
2609
2676
  className,
2610
2677
  ...props
2611
2678
  }) {
2612
- return /* @__PURE__ */ jsx21(
2679
+ return /* @__PURE__ */ jsx23(
2613
2680
  DialogPrimitive.Title,
2614
2681
  {
2615
2682
  "data-slot": "dialog-title",
@@ -2622,7 +2689,7 @@ function DialogDescription({
2622
2689
  className,
2623
2690
  ...props
2624
2691
  }) {
2625
- return /* @__PURE__ */ jsx21(
2692
+ return /* @__PURE__ */ jsx23(
2626
2693
  DialogPrimitive.Description,
2627
2694
  {
2628
2695
  "data-slot": "dialog-description",
@@ -2633,6 +2700,7 @@ function DialogDescription({
2633
2700
  }
2634
2701
  export {
2635
2702
  Button,
2703
+ ChatStorageProvider,
2636
2704
  ChatWidget,
2637
2705
  Dialog,
2638
2706
  DialogContent,
@@ -2640,8 +2708,11 @@ export {
2640
2708
  DialogHeader,
2641
2709
  DialogTitle,
2642
2710
  Input,
2711
+ StarterMessageItem,
2712
+ StarterMessages,
2643
2713
  ChatWidget_default as default,
2644
2714
  fontOptions,
2715
+ useChatStorageKey,
2645
2716
  useChatTheme
2646
2717
  };
2647
2718
  //# sourceMappingURL=index.mjs.map