@copilotz/chat-ui 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.cjs +102 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +103 -28
- package/dist/index.js.map +1 -1
- package/dist/styles.css +23 -54
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -295,6 +295,7 @@ var configUtils = {
|
|
|
295
295
|
var import_react = require("react");
|
|
296
296
|
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
297
297
|
var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
298
|
+
var import_remark_breaks = __toESM(require("remark-breaks"), 1);
|
|
298
299
|
var import_rehype_highlight = __toESM(require("rehype-highlight"), 1);
|
|
299
300
|
|
|
300
301
|
// src/components/ui/button.tsx
|
|
@@ -575,6 +576,24 @@ function TooltipContent({
|
|
|
575
576
|
// src/components/chat/Message.tsx
|
|
576
577
|
var import_lucide_react = require("lucide-react");
|
|
577
578
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
579
|
+
var MarkdownErrorBoundary = class extends import_react.Component {
|
|
580
|
+
constructor(props) {
|
|
581
|
+
super(props);
|
|
582
|
+
this.state = { hasError: false };
|
|
583
|
+
}
|
|
584
|
+
static getDerivedStateFromError(_error) {
|
|
585
|
+
return { hasError: true };
|
|
586
|
+
}
|
|
587
|
+
componentDidCatch(error, errorInfo) {
|
|
588
|
+
console.warn("[Markdown] Falling back to simple rendering due to:", error.message);
|
|
589
|
+
}
|
|
590
|
+
render() {
|
|
591
|
+
if (this.state.hasError) {
|
|
592
|
+
return this.props.fallback;
|
|
593
|
+
}
|
|
594
|
+
return this.props.children;
|
|
595
|
+
}
|
|
596
|
+
};
|
|
578
597
|
var ThinkingIndicator = (0, import_react.memo)(function ThinkingIndicator2({ label = "Thinking..." }) {
|
|
579
598
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-2 py-2", children: [
|
|
580
599
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex gap-1", children: [
|
|
@@ -610,9 +629,38 @@ var markdownComponents = {
|
|
|
610
629
|
return !inline && match ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className, ...props, children }) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className: "bg-muted px-1 py-0.5 rounded text-sm", ...props, children });
|
|
611
630
|
}
|
|
612
631
|
};
|
|
613
|
-
var
|
|
632
|
+
var remarkPluginsWithGfm = [import_remark_gfm.default, import_remark_breaks.default];
|
|
633
|
+
var remarkPluginsSimple = [import_remark_breaks.default];
|
|
614
634
|
var rehypePluginsDefault = [import_rehype_highlight.default];
|
|
615
635
|
var rehypePluginsEmpty = [];
|
|
636
|
+
var SimpleMarkdown = (0, import_react.memo)(function SimpleMarkdown2({
|
|
637
|
+
content,
|
|
638
|
+
isStreaming = false
|
|
639
|
+
}) {
|
|
640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
641
|
+
import_react_markdown.default,
|
|
642
|
+
{
|
|
643
|
+
remarkPlugins: remarkPluginsSimple,
|
|
644
|
+
rehypePlugins: isStreaming ? rehypePluginsEmpty : rehypePluginsDefault,
|
|
645
|
+
components: markdownComponents,
|
|
646
|
+
children: content
|
|
647
|
+
}
|
|
648
|
+
);
|
|
649
|
+
});
|
|
650
|
+
var FullMarkdown = (0, import_react.memo)(function FullMarkdown2({
|
|
651
|
+
content,
|
|
652
|
+
isStreaming = false
|
|
653
|
+
}) {
|
|
654
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
655
|
+
import_react_markdown.default,
|
|
656
|
+
{
|
|
657
|
+
remarkPlugins: remarkPluginsWithGfm,
|
|
658
|
+
rehypePlugins: isStreaming ? rehypePluginsEmpty : rehypePluginsDefault,
|
|
659
|
+
components: markdownComponents,
|
|
660
|
+
children: content
|
|
661
|
+
}
|
|
662
|
+
);
|
|
663
|
+
});
|
|
616
664
|
var StreamingText = (0, import_react.memo)(function StreamingText2({
|
|
617
665
|
content,
|
|
618
666
|
isStreaming = false,
|
|
@@ -620,15 +668,7 @@ var StreamingText = (0, import_react.memo)(function StreamingText2({
|
|
|
620
668
|
}) {
|
|
621
669
|
const hasContent = content.trim().length > 0;
|
|
622
670
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "prose prose-sm max-w-none dark:prose-invert", children: [
|
|
623
|
-
hasContent ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
624
|
-
import_react_markdown.default,
|
|
625
|
-
{
|
|
626
|
-
remarkPlugins: remarkPluginsDefault,
|
|
627
|
-
rehypePlugins: isStreaming ? rehypePluginsEmpty : rehypePluginsDefault,
|
|
628
|
-
components: markdownComponents,
|
|
629
|
-
children: content
|
|
630
|
-
}
|
|
631
|
-
) : isStreaming ? (
|
|
671
|
+
hasContent ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MarkdownErrorBoundary, { fallback: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SimpleMarkdown, { content, isStreaming }), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FullMarkdown, { content, isStreaming }) }) : isStreaming ? (
|
|
632
672
|
// Show thinking indicator while waiting for first token
|
|
633
673
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThinkingIndicator, { label: thinkingLabel })
|
|
634
674
|
) : null,
|
|
@@ -1010,18 +1050,26 @@ var import_lucide_react3 = require("lucide-react");
|
|
|
1010
1050
|
// src/hooks/use-mobile.ts
|
|
1011
1051
|
var React2 = __toESM(require("react"), 1);
|
|
1012
1052
|
var MOBILE_BREAKPOINT = 768;
|
|
1053
|
+
function getInitialIsMobile() {
|
|
1054
|
+
if (typeof window === "undefined") return false;
|
|
1055
|
+
return window.innerWidth < MOBILE_BREAKPOINT;
|
|
1056
|
+
}
|
|
1013
1057
|
function useIsMobile() {
|
|
1014
|
-
const [isMobile, setIsMobile] = React2.useState(
|
|
1058
|
+
const [isMobile, setIsMobile] = React2.useState(getInitialIsMobile);
|
|
1015
1059
|
React2.useEffect(() => {
|
|
1016
1060
|
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
1017
1061
|
const onChange = () => {
|
|
1018
1062
|
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
1019
1063
|
};
|
|
1020
1064
|
mql.addEventListener("change", onChange);
|
|
1065
|
+
window.addEventListener("resize", onChange);
|
|
1021
1066
|
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
1022
|
-
return () =>
|
|
1067
|
+
return () => {
|
|
1068
|
+
mql.removeEventListener("change", onChange);
|
|
1069
|
+
window.removeEventListener("resize", onChange);
|
|
1070
|
+
};
|
|
1023
1071
|
}, []);
|
|
1024
|
-
return
|
|
1072
|
+
return isMobile;
|
|
1025
1073
|
}
|
|
1026
1074
|
|
|
1027
1075
|
// src/components/ui/separator.tsx
|
|
@@ -1298,12 +1346,29 @@ function Sidebar({
|
|
|
1298
1346
|
}
|
|
1299
1347
|
) });
|
|
1300
1348
|
}
|
|
1349
|
+
const isCollapsed = state === "collapsed";
|
|
1350
|
+
const currentCollapsible = isCollapsed ? collapsible : "";
|
|
1351
|
+
const getGapWidth = () => {
|
|
1352
|
+
if (currentCollapsible === "offcanvas") return "0px";
|
|
1353
|
+
if (currentCollapsible === "icon") return SIDEBAR_WIDTH_ICON;
|
|
1354
|
+
return SIDEBAR_WIDTH;
|
|
1355
|
+
};
|
|
1356
|
+
const getContainerWidth = () => {
|
|
1357
|
+
if (currentCollapsible === "icon") return SIDEBAR_WIDTH_ICON;
|
|
1358
|
+
return SIDEBAR_WIDTH;
|
|
1359
|
+
};
|
|
1360
|
+
const getContainerOffset = () => {
|
|
1361
|
+
if (currentCollapsible === "offcanvas") {
|
|
1362
|
+
return side === "left" ? `calc(${SIDEBAR_WIDTH} * -1)` : `calc(${SIDEBAR_WIDTH} * -1)`;
|
|
1363
|
+
}
|
|
1364
|
+
return "0";
|
|
1365
|
+
};
|
|
1301
1366
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1302
1367
|
"div",
|
|
1303
1368
|
{
|
|
1304
|
-
className: "group peer text-sidebar-foreground
|
|
1369
|
+
className: "group peer text-sidebar-foreground",
|
|
1305
1370
|
"data-state": state,
|
|
1306
|
-
"data-collapsible":
|
|
1371
|
+
"data-collapsible": currentCollapsible,
|
|
1307
1372
|
"data-variant": variant,
|
|
1308
1373
|
"data-side": side,
|
|
1309
1374
|
"data-slot": "sidebar",
|
|
@@ -1313,11 +1378,10 @@ function Sidebar({
|
|
|
1313
1378
|
{
|
|
1314
1379
|
"data-slot": "sidebar-gap",
|
|
1315
1380
|
className: cn(
|
|
1316
|
-
"relative
|
|
1317
|
-
"group-data-[
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
)
|
|
1381
|
+
"relative bg-transparent transition-[width] duration-200 ease-linear",
|
|
1382
|
+
"group-data-[side=right]:rotate-180"
|
|
1383
|
+
),
|
|
1384
|
+
style: { width: getGapWidth() }
|
|
1321
1385
|
}
|
|
1322
1386
|
),
|
|
1323
1387
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
@@ -1325,12 +1389,16 @@ function Sidebar({
|
|
|
1325
1389
|
{
|
|
1326
1390
|
"data-slot": "sidebar-container",
|
|
1327
1391
|
className: cn(
|
|
1328
|
-
"fixed inset-y-0 z-10
|
|
1329
|
-
side === "left" ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
|
|
1392
|
+
"fixed inset-y-0 z-10 h-screen transition-[left,right,width] duration-200 ease-linear",
|
|
1330
1393
|
// Adjust the padding for floating and inset variants.
|
|
1331
|
-
variant === "floating" || variant === "inset" ? "p-2
|
|
1394
|
+
variant === "floating" || variant === "inset" ? "p-2" : side === "left" ? "border-r" : "border-l",
|
|
1332
1395
|
className
|
|
1333
1396
|
),
|
|
1397
|
+
style: {
|
|
1398
|
+
display: "flex",
|
|
1399
|
+
width: getContainerWidth(),
|
|
1400
|
+
[side === "left" ? "left" : "right"]: getContainerOffset()
|
|
1401
|
+
},
|
|
1334
1402
|
...props,
|
|
1335
1403
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1336
1404
|
"div",
|
|
@@ -1353,6 +1421,15 @@ function SidebarTrigger({
|
|
|
1353
1421
|
...props
|
|
1354
1422
|
}) {
|
|
1355
1423
|
const { toggleSidebar } = useSidebar();
|
|
1424
|
+
const handleActivation = React4.useCallback((event) => {
|
|
1425
|
+
if (event.type === "touchend") {
|
|
1426
|
+
event.preventDefault();
|
|
1427
|
+
}
|
|
1428
|
+
if ("onClick" in event && onClick) {
|
|
1429
|
+
onClick(event);
|
|
1430
|
+
}
|
|
1431
|
+
toggleSidebar();
|
|
1432
|
+
}, [onClick, toggleSidebar]);
|
|
1356
1433
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1357
1434
|
Button,
|
|
1358
1435
|
{
|
|
@@ -1361,10 +1438,8 @@ function SidebarTrigger({
|
|
|
1361
1438
|
variant: "ghost",
|
|
1362
1439
|
size: "icon",
|
|
1363
1440
|
className: cn("size-7", className),
|
|
1364
|
-
onClick:
|
|
1365
|
-
|
|
1366
|
-
toggleSidebar();
|
|
1367
|
-
},
|
|
1441
|
+
onClick: handleActivation,
|
|
1442
|
+
onTouchEnd: handleActivation,
|
|
1368
1443
|
...props,
|
|
1369
1444
|
children: [
|
|
1370
1445
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.PanelLeftIcon, {}),
|