laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
444 lines (443 loc) • 16.7 kB
JavaScript
"use client";
import { jsxs as n, jsx as e, Fragment as T } from "react/jsx-runtime";
import { useMemo as P, useState as N, useRef as V, useEffect as j, Suspense as D } from "react";
import { cva as X } from "../../node_modules/class-variance-authority/dist/index.js";
import { motion as J } from "framer-motion";
import { cn as l } from "../../lib/utils.js";
import { Collapsible as _, CollapsibleTrigger as q, CollapsibleContent as G } from "./collapsible.js";
import { FilePreview as H } from "./file-preview.js";
import { MarkdownRenderer as M } from "./markdown-renderer.js";
import O from "../../node_modules/lucide-react/dist/esm/icons/x.js";
import R from "../../node_modules/lucide-react/dist/esm/icons/check.js";
import K from "../../node_modules/lucide-react/dist/esm/icons/pen.js";
import Q from "../../node_modules/lucide-react/dist/esm/icons/chevron-right.js";
import W from "../../node_modules/lucide-react/dist/esm/icons/ban.js";
import Y from "../../node_modules/lucide-react/dist/esm/icons/code-xml.js";
import Z from "../../node_modules/lucide-react/dist/esm/icons/terminal.js";
import A from "../../node_modules/lucide-react/dist/esm/icons/loader-circle.js";
const z = X(
"group/message relative break-words rounded-lg p-3 text-sm sm:max-w-[70%]",
{
variants: {
isUser: {
true: "bg-d-primary text-d-primary-foreground",
false: "bg-d-secondary text-d-foreground"
},
animation: {
none: "",
slide: "duration-300 animate-in fade-in-0",
scale: "duration-300 animate-in fade-in-0 zoom-in-75",
fade: "duration-500 animate-in fade-in-0"
}
},
compoundVariants: [
{
isUser: !0,
animation: "slide",
class: "slide-in-from-right"
},
{
isUser: !1,
animation: "slide",
class: "slide-in-from-left"
},
{
isUser: !0,
animation: "scale",
class: "origin-bottom-right"
},
{
isUser: !1,
animation: "scale",
class: "origin-bottom-left"
}
]
}
), xe = ({
role: s,
content: t,
createdAt: o,
showTimeStamp: g = !1,
animation: u = "scale",
actions: p,
onEdit: v,
experimental_attachments: B,
toolInvocations: y,
parts: w
}) => {
const I = P(() => B?.map((r) => {
const m = ee(r.url);
return new File([m], r.name ?? "Unknown");
}), [B]), i = s === "user", C = !i && v, [a, k] = N(!1), [c, f] = N(t), [b, F] = N(t), d = V(null);
j(() => {
a || (F(t), f(t));
}, [t, a]), j(() => {
a && d.current && (d.current.focus(), d.current.setSelectionRange(
d.current.value.length,
d.current.value.length
));
}, [a]);
const S = () => {
f(b), k(!0);
}, h = () => {
const r = c.trim();
r && r !== t && (F(r), v && v(r)), k(!1);
}, x = () => {
f(b), k(!1);
}, E = (r) => {
r.key === "Enter" && !r.shiftKey ? (r.preventDefault(), h()) : r.key === "Escape" && (r.preventDefault(), x());
}, U = o?.toLocaleTimeString("en-US", {
hour: "2-digit",
minute: "2-digit"
});
return i ? /* @__PURE__ */ n(
"div",
{
className: l("flex flex-col", i ? "items-end" : "items-start"),
children: [
I ? /* @__PURE__ */ e("div", { className: "mb-1 flex flex-wrap gap-2", children: I.map((r, m) => /* @__PURE__ */ e(H, { file: r }, m)) }) : null,
/* @__PURE__ */ n(
"div",
{
className: l(
z({ isUser: i, animation: u }),
"group relative",
a && "border-d-primary border"
),
children: [
a ? /* @__PURE__ */ e(
"textarea",
{
ref: d,
value: c,
onChange: (r) => f(r.target.value),
onKeyDown: E,
className: "w-full resize-none border-none bg-transparent p-0 focus:outline-none",
rows: Math.max(2, c.split(`
`).length)
}
) : /* @__PURE__ */ e("div", { className: "pointer-events-none", children: /* @__PURE__ */ e(
D,
{
fallback: /* @__PURE__ */ e("div", { className: "text-d-secondary-foreground", children: "Caricamento..." }),
children: /* @__PURE__ */ e(M, { children: b })
}
) }),
C && /* @__PURE__ */ e("div", { className: "absolute -top-2 -right-2 flex gap-1", children: a ? /* @__PURE__ */ n(T, { children: [
/* @__PURE__ */ e(
"button",
{
onClick: x,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 transition-colors",
title: "Cancel",
children: /* @__PURE__ */ e(O, { className: "h-3 w-3" })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: h,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 transition-colors",
title: "Save",
children: /* @__PURE__ */ e(R, { className: "h-3 w-3" })
}
)
] }) : /* @__PURE__ */ e(
"button",
{
onClick: S,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 opacity-0 transition-opacity group-hover:opacity-100",
title: "Edit message",
children: /* @__PURE__ */ e(K, { className: "h-3 w-3" })
}
) })
]
}
),
g && o ? /* @__PURE__ */ e(
"time",
{
dateTime: o.toISOString(),
className: l(
"mt-1 block px-1 text-xs opacity-50",
u !== "none" && "animate-in fade-in-0 duration-500"
),
children: U
}
) : null
]
}
) : w && w.length > 0 ? w.map((r, m) => r.type === "text" ? /* @__PURE__ */ n(
"div",
{
className: l(
"flex flex-col",
i ? "items-end" : "items-start"
),
children: [
/* @__PURE__ */ n(
"div",
{
className: l(
z({ isUser: i, animation: u }),
"group relative",
a && "border-d-primary border"
),
children: [
a ? /* @__PURE__ */ e(
"textarea",
{
ref: d,
value: c,
onChange: ($) => f($.target.value),
onKeyDown: E,
className: "w-full resize-none border-none bg-transparent p-0 focus:outline-none",
rows: Math.max(2, c.split(`
`).length)
}
) : /* @__PURE__ */ e("div", { className: "pointer-events-none", children: /* @__PURE__ */ e(
D,
{
fallback: /* @__PURE__ */ e("div", { className: "text-d-secondary-foreground", children: "Caricamento..." }),
children: /* @__PURE__ */ e(M, { children: r.text })
}
) }),
C && /* @__PURE__ */ e("div", { className: "absolute -top-2 -right-2 flex gap-1", children: a ? /* @__PURE__ */ n(T, { children: [
/* @__PURE__ */ e(
"button",
{
onClick: x,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 transition-colors",
title: "Cancel",
children: /* @__PURE__ */ e(O, { className: "h-3 w-3" })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: h,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 transition-colors",
title: "Save",
children: /* @__PURE__ */ e(R, { className: "h-3 w-3" })
}
)
] }) : /* @__PURE__ */ e(
"button",
{
onClick: S,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 opacity-0 transition-opacity group-hover:opacity-100",
title: "Edit message",
children: /* @__PURE__ */ e(K, { className: "h-3 w-3" })
}
) }),
p && !a ? /* @__PURE__ */ e("div", { className: "bg-d-background text-d-foreground border-d-border absolute right-2 -bottom-4 flex space-x-1 rounded-lg border p-1 opacity-0 transition-opacity group-hover/message:opacity-100", children: p }) : null
]
}
),
g && o ? /* @__PURE__ */ e(
"time",
{
dateTime: o.toISOString(),
className: l(
"mt-1 block px-1 text-xs opacity-50",
u !== "none" && "animate-in fade-in-0 duration-500"
),
children: U
}
) : null
]
},
`text-${m}`
) : r.type === "reasoning" ? /* @__PURE__ */ e(re, { part: r }, `reasoning-${m}`) : r.type === "tool-invocation" ? /* @__PURE__ */ e(
L,
{
toolInvocations: [r.toolInvocation]
},
`tool-${m}`
) : null) : y && y.length > 0 ? /* @__PURE__ */ e(L, { toolInvocations: y }) : /* @__PURE__ */ n("div", { className: l("flex flex-col", i ? "items-end" : "items-start"), children: [
/* @__PURE__ */ n(
"div",
{
className: l(
z({ isUser: i, animation: u }),
"group relative",
a && "border-d-primary border"
),
children: [
a ? /* @__PURE__ */ e(
"textarea",
{
ref: d,
value: c,
onChange: (r) => f(r.target.value),
onKeyDown: E,
className: "w-full resize-none border-none bg-transparent p-0 focus:outline-none",
rows: Math.max(2, c.split(`
`).length)
}
) : /* @__PURE__ */ e("div", { className: "pointer-events-none", children: /* @__PURE__ */ e(
D,
{
fallback: /* @__PURE__ */ e("div", { className: "text-d-secondary-foreground", children: "Caricamento..." }),
children: /* @__PURE__ */ e(M, { children: b })
}
) }),
C && /* @__PURE__ */ e("div", { className: "absolute -top-2 -right-2 flex gap-1", children: a ? /* @__PURE__ */ n(T, { children: [
/* @__PURE__ */ e(
"button",
{
onClick: x,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 transition-colors",
title: "Cancel",
children: /* @__PURE__ */ e(O, { className: "h-3 w-3" })
}
),
/* @__PURE__ */ e(
"button",
{
onClick: h,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 transition-colors",
title: "Save",
children: /* @__PURE__ */ e(R, { className: "h-3 w-3" })
}
)
] }) : /* @__PURE__ */ e(
"button",
{
onClick: S,
className: "bg-d-background border-d-border hover:bg-d-muted rounded-full border p-1 opacity-0 transition-opacity group-hover:opacity-100",
title: "Edit message",
children: /* @__PURE__ */ e(K, { className: "h-3 w-3" })
}
) }),
p && !a ? /* @__PURE__ */ e("div", { className: "bg-d-background text-foreground absolute right-2 -bottom-4 flex space-x-1 rounded-lg border p-1 opacity-0 transition-opacity group-hover/message:opacity-100", children: p }) : null
]
}
),
g && o ? /* @__PURE__ */ e(
"time",
{
dateTime: o.toISOString(),
className: l(
"mt-1 block px-1 text-xs opacity-50",
u !== "none" && "animate-in fade-in-0 duration-500"
),
children: U
}
) : null
] });
};
function ee(s) {
const t = s.split(",")[1], o = Buffer.from(t, "base64");
return new Uint8Array(o);
}
const re = ({ part: s }) => {
const [t, o] = N(!1);
return /* @__PURE__ */ e("div", { className: "mb-2 flex flex-col items-start sm:max-w-[70%]", children: /* @__PURE__ */ n(
_,
{
open: t,
onOpenChange: o,
className: "group bg-d-secondary/50 border-d-border w-full overflow-hidden rounded-lg",
children: [
/* @__PURE__ */ e("div", { className: "flex items-center p-2", children: /* @__PURE__ */ e(q, { asChild: !0, children: /* @__PURE__ */ n("button", { className: "text-d-secondary-foreground hover:text-d-foreground flex items-center gap-2 text-sm", children: [
/* @__PURE__ */ e(Q, { className: "h-4 w-4 transition-transform group-data-[state=open]:rotate-90" }),
/* @__PURE__ */ e("span", { children: "Thinking" })
] }) }) }),
/* @__PURE__ */ e(G, { forceMount: !0, children: /* @__PURE__ */ e(
J.div,
{
initial: !1,
animate: t ? "open" : "closed",
variants: {
open: { height: "auto", opacity: 1 },
closed: { height: 0, opacity: 0 }
},
transition: { duration: 0.3, ease: [0.04, 0.62, 0.23, 0.98] },
className: "border-d-border border-t",
children: /* @__PURE__ */ e("div", { className: "p-2", children: /* @__PURE__ */ e("div", { className: "text-xs whitespace-pre-wrap", children: s.reasoning }) })
}
) })
]
}
) });
};
function L({
toolInvocations: s
}) {
return s?.length ? /* @__PURE__ */ e("div", { className: "flex flex-col items-start gap-2", children: s.map((t, o) => {
if (t.state === "result" && t.result.__cancelled === !0)
return /* @__PURE__ */ n(
"div",
{
className: "bg-d-secondary/50 text-d-secondary-foreground border-d-border flex items-center gap-2 rounded-lg border px-3 py-2 text-sm",
children: [
/* @__PURE__ */ e(W, { className: "h-4 w-4" }),
/* @__PURE__ */ n("span", { children: [
"Cancelled",
" ",
/* @__PURE__ */ n("span", { className: "font-mono", children: [
"`",
t.toolName,
"`"
] })
] })
]
},
o
);
switch (t.state) {
case "partial-call":
case "call":
return /* @__PURE__ */ n(
"div",
{
className: "bg-d-secondary/50 text-d-secondary-foreground border-d-border flex items-center gap-2 rounded-lg border px-3 py-2 text-sm",
children: [
/* @__PURE__ */ e(Z, { className: "h-4 w-4" }),
/* @__PURE__ */ n("span", { children: [
"Calling",
" ",
/* @__PURE__ */ n("span", { className: "font-mono", children: [
"`",
t.toolName,
"`"
] }),
"..."
] }),
/* @__PURE__ */ e(A, { className: "h-3 w-3 animate-spin" })
]
},
o
);
case "result":
return /* @__PURE__ */ n(
"div",
{
className: "bg-d-secondary/50 border-d-border flex flex-col gap-1.5 rounded-lg border px-3 py-2 text-sm",
children: [
/* @__PURE__ */ n("div", { className: "text-d-secondary-foreground flex items-center gap-2", children: [
/* @__PURE__ */ e(Y, { className: "h-4 w-4" }),
/* @__PURE__ */ n("span", { children: [
"Result from",
" ",
/* @__PURE__ */ n("span", { className: "font-mono", children: [
"`",
t.toolName,
"`"
] })
] })
] }),
/* @__PURE__ */ e("pre", { className: "text-d-foreground overflow-x-auto whitespace-pre-wrap", children: JSON.stringify(t.result, null, 2) })
]
},
o
);
default:
return null;
}
}) }) : null;
}
export {
xe as ChatMessage
};