@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 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 remarkPluginsDefault = [import_remark_gfm.default];
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(void 0);
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 () => mql.removeEventListener("change", onChange);
1067
+ return () => {
1068
+ mql.removeEventListener("change", onChange);
1069
+ window.removeEventListener("resize", onChange);
1070
+ };
1023
1071
  }, []);
1024
- return !!isMobile;
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 hidden md:block",
1369
+ className: "group peer text-sidebar-foreground",
1305
1370
  "data-state": state,
1306
- "data-collapsible": state === "collapsed" ? 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 w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
1317
- "group-data-[collapsible=offcanvas]:w-0",
1318
- "group-data-[side=right]:rotate-180",
1319
- variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
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 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
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 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
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: (event) => {
1365
- onClick?.(event);
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, {}),