laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
264 lines (263 loc) • 7.74 kB
JavaScript
"use client";
import { jsxs as b, Fragment as y, jsx as t } from "react/jsx-runtime";
import { forwardRef as A, useRef as M, useCallback as k, useState as O } from "react";
import { Button as v } from "./button.js";
import { CopyButton as S } from "./copy-button.js";
import { MessageInput as q } from "./message-input.js";
import { MessageList as H } from "./message-list.js";
import { PromptSuggestions as J } from "./prompt-suggestions.js";
import { useAutoScroll as K } from "../../hooks/use-auto-scroll.js";
import { cn as Q } from "../../lib/utils.js";
import { Typo as z } from "./typo.js";
import j from "../../node_modules/lucide-react/dist/esm/icons/save.js";
import V from "../../node_modules/lucide-react/dist/esm/icons/thumbs-up.js";
import W from "../../node_modules/lucide-react/dist/esm/icons/thumbs-down.js";
import X from "../../node_modules/lucide-react/dist/esm/icons/arrow-down.js";
function Y({
messages: o,
welcomeTitle: n = "Da dove iniziamo?",
handleSubmit: i,
input: f,
handleInputChange: c,
stop: s,
isGenerating: w,
append: m,
suggestions: u,
className: g,
onRateResponse: N,
setMessages: x,
transcribeAudio: D,
allowAttachments: L = !1,
onEdit: B,
onMessageSave: d
}) {
const P = o.at(-1), T = o.length === 0, I = P?.role === "user", C = M(o);
C.current = o;
const U = k(() => {
if (s?.(), !x) return;
const e = [...C.current], l = e.findLast(
(a) => a.role === "assistant"
);
if (!l) return;
let h = !1, p = { ...l };
if (l.toolInvocations) {
const a = l.toolInvocations.map(
(r) => r.state === "call" ? (h = !0, {
...r,
state: "result",
result: {
content: "Tool execution was cancelled",
__cancelled: !0
// Special marker to indicate cancellation
}
}) : r
);
h && (p = {
...p,
toolInvocations: a
});
}
if (l.parts && l.parts.length > 0) {
const a = l.parts.map((r) => r.type === "tool-invocation" && r.toolInvocation && r.toolInvocation.state === "call" ? (h = !0, {
...r,
toolInvocation: {
...r.toolInvocation,
state: "result",
result: {
content: "Tool execution was cancelled",
__cancelled: !0
}
}
}) : r);
h && (p = {
...p,
parts: a
// eslint-disable-line @typescript-eslint/no-explicit-any
});
}
if (h) {
const a = e.findIndex(
(r) => r.id === l.id
);
a !== -1 && (e[a] = p, x(e));
}
}, [s, x, C]), E = k(
(e) => ({
actions: N ? /* @__PURE__ */ b(y, { children: [
/* @__PURE__ */ t("div", { className: "border-d-border border-r pr-1", children: /* @__PURE__ */ t(
S,
{
content: e.content,
copyMessage: "Copied response to clipboard!"
}
) }),
d && /* @__PURE__ */ t("div", { className: "border-d-border border-r pr-1", children: /* @__PURE__ */ t(
v,
{
size: "icon",
variant: "ghost",
className: "h-6 w-6",
onClick: () => d(e.id, e.content),
title: "Save message",
children: /* @__PURE__ */ t(j, { className: "h-4 w-4" })
}
) }),
/* @__PURE__ */ t(
v,
{
size: "icon",
variant: "ghost",
className: "h-6 w-6",
onClick: () => N(e.id, "thumbs-up"),
children: /* @__PURE__ */ t(V, { className: "h-4 w-4" })
}
),
/* @__PURE__ */ t(
v,
{
size: "icon",
variant: "ghost",
className: "h-6 w-6",
onClick: () => N(e.id, "thumbs-down"),
children: /* @__PURE__ */ t(W, { className: "h-4 w-4" })
}
)
] }) : /* @__PURE__ */ b(y, { children: [
/* @__PURE__ */ t(
S,
{
content: e.content,
copyMessage: "Copied response to clipboard!"
}
),
d && /* @__PURE__ */ t("div", { className: "border-d-border border-l pl-1", children: /* @__PURE__ */ t(
v,
{
size: "icon",
variant: "ghost",
className: "h-6 w-6",
onClick: () => d(e.id, e.content),
title: "Save message",
children: /* @__PURE__ */ t(j, { className: "h-4 w-4" })
}
) })
] }),
onMessageSave: d
}),
[N, d]
);
return /* @__PURE__ */ b(F, { className: g, children: [
T && /* @__PURE__ */ t("div", { className: "flex flex-1 flex-col items-center justify-center p-8", children: m && u && /* @__PURE__ */ b(y, { children: [
/* @__PURE__ */ t(z, { variant: "h3", className: "mb-8 text-center", children: n }),
/* @__PURE__ */ t(
J,
{
label: "",
append: m,
suggestions: u
}
)
] }) }),
o.length > 0 ? /* @__PURE__ */ t(Z, { children: /* @__PURE__ */ t(
H,
{
messages: o,
isTyping: I,
messageOptions: E,
onEdit: B,
onMessageSave: d
}
) }) : null,
T && !m && !u && /* @__PURE__ */ t(z, { variant: "h3", className: "mb-8 text-center", children: n }),
/* @__PURE__ */ t(
_,
{
className: "flex-shrink-0",
isPending: w || I,
handleSubmit: i,
children: ({ files: e, setFiles: l }) => /* @__PURE__ */ t(
q,
{
value: f,
onChange: c,
allowAttachments: L,
files: e,
setFiles: l,
stop: U,
isGenerating: w,
transcribeAudio: D
}
)
}
)
] });
}
Y.displayName = "Chat";
function Z({ children: o }) {
const {
containerRef: n,
scrollToBottom: i,
handleScroll: f,
shouldAutoScroll: c,
handleTouchStart: s
} = K();
return /* @__PURE__ */ b(
"div",
{
className: "relative flex-1 overflow-y-auto pb-4",
ref: n,
onScroll: f,
onTouchStart: s,
children: [
/* @__PURE__ */ t("div", { className: "max-w-full", children: o }),
!c && /* @__PURE__ */ t("div", { className: "pointer-events-none absolute right-0 bottom-0 left-0 flex items-end justify-end", children: /* @__PURE__ */ t("div", { className: "sticky bottom-0 left-0 flex w-full justify-end", children: /* @__PURE__ */ t(
v,
{
onClick: i,
className: "animate-in fade-in-0 slide-in-from-bottom-1 pointer-events-auto h-8 w-8 rounded-full ease-in-out",
size: "icon",
variant: "ghost",
children: /* @__PURE__ */ t(X, { className: "h-4 w-4" })
}
) }) })
]
}
);
}
const F = A(({ className: o, ...n }, i) => /* @__PURE__ */ t(
"div",
{
ref: i,
className: Q("flex h-full max-h-full w-full flex-col", o),
...n
}
));
F.displayName = "ChatContainer";
const _ = A(
({ children: o, handleSubmit: n, className: i }, f) => {
const [c, s] = O(null);
return /* @__PURE__ */ t("form", { ref: f, onSubmit: (m) => {
if (!c) {
n(m);
return;
}
const u = $(c);
n(m, { experimental_attachments: u }), s(null);
}, className: i, children: o({ files: c, setFiles: s }) });
}
);
_.displayName = "ChatForm";
function $(o) {
if (typeof window > "u")
return {};
const n = new DataTransfer();
for (const i of Array.from(o))
n.items.add(i);
return n.files;
}
export {
Y as Chat,
F as ChatContainer,
_ as ChatForm,
Z as ChatMessages
};