@portablecore/chat 0.1.4 → 0.1.5

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.
@@ -1,11 +1,6 @@
1
1
  import type { ChatInterfaceConfig } from "./types.js";
2
2
  interface ChatInterfaceCoreProps {
3
3
  config: ChatInterfaceConfig;
4
- /**
5
- * Optional custom markdown components passed to ReactMarkdown.
6
- * Allows platforms to override rendering of specific elements
7
- * (code blocks, links, images, tables, etc.).
8
- */
9
4
  markdownComponents?: Record<string, any>;
10
5
  }
11
6
  /**
@@ -17,10 +12,6 @@ interface ChatInterfaceCoreProps {
17
12
  * Platform-specific behavior is injected via the config's features,
18
13
  * slots, resolvers, and handlers. The component itself has zero
19
14
  * knowledge of Expert vs. Team.
20
- *
21
- * Usage:
22
- * <ChatInterfaceCore config={teamChatConfig} />
23
- * <ChatInterfaceCore config={expertChatConfig} />
24
15
  */
25
16
  export declare function ChatInterfaceCore({ config, markdownComponents, }: ChatInterfaceCoreProps): import("react/jsx-runtime").JSX.Element;
26
17
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"chat-interface-core.d.ts","sourceRoot":"","sources":["../src/chat-interface-core.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAa,MAAM,YAAY,CAAA;AAOhE,UAAU,sBAAsB;IAC9B,MAAM,EAAE,mBAAmB,CAAA;IAC3B;;;;OAIG;IAEH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CACzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,kBAAkB,GACnB,EAAE,sBAAsB,2CAkExB"}
1
+ {"version":3,"file":"chat-interface-core.d.ts","sourceRoot":"","sources":["../src/chat-interface-core.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAa,MAAM,YAAY,CAAA;AAQhE,UAAU,sBAAsB;IAC9B,MAAM,EAAE,mBAAmB,CAAA;IAE3B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CACzC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,kBAAkB,GACnB,EAAE,sBAAsB,2CA6ExB"}
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.ChatInterfaceCore = ChatInterfaceCore;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const use_chat_session_js_1 = require("./hooks/use-chat-session.js");
7
+ const use_attachments_js_1 = require("./hooks/use-attachments.js");
7
8
  const message_list_js_1 = require("./components/message-list.js");
8
9
  const input_area_js_1 = require("./components/input-area.js");
9
10
  const thinking_indicator_js_1 = require("./components/thinking-indicator.js");
@@ -17,19 +18,20 @@ const empty_state_js_1 = require("./components/empty-state.js");
17
18
  * Platform-specific behavior is injected via the config's features,
18
19
  * slots, resolvers, and handlers. The component itself has zero
19
20
  * knowledge of Expert vs. Team.
20
- *
21
- * Usage:
22
- * <ChatInterfaceCore config={teamChatConfig} />
23
- * <ChatInterfaceCore config={expertChatConfig} />
24
21
  */
25
22
  function ChatInterfaceCore({ config, markdownComponents, }) {
26
23
  const session = (0, use_chat_session_js_1.useChatSession)(config);
24
+ const attachmentState = (0, use_attachments_js_1.useAttachments)(config.resolvers?.documentResolver);
27
25
  const slots = (config.slots || {});
28
26
  const showThinking = session.streaming &&
29
27
  session.thinkingStages.length > 0 &&
30
28
  !session.activeSkill;
31
- return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)(message_list_js_1.MessageList, { messages: session.messages, streaming: session.streaming, config: config, markdownComponents: markdownComponents, emptyState: slots.emptyState || ((0, jsx_runtime_1.jsx)(empty_state_js_1.EmptyState, { expertName: config.expert?.name })), beforeMessageList: slots.beforeMessageList, afterMessageList: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showThinking && ((0, jsx_runtime_1.jsx)("div", { className: "max-w-3xl mx-auto px-4", children: (0, jsx_runtime_1.jsx)(thinking_indicator_js_1.ThinkingIndicator, { stages: session.thinkingStages, expertName: config.expert?.name, expertAvatarUrl: config.expert?.avatarUrl }) })), slots.afterMessageList] }) }), (0, jsx_runtime_1.jsx)(input_area_js_1.InputArea, { onSend: session.send, onAbort: session.abort, streaming: session.streaming, sending: session.sending, placeholder: config.expert
29
+ const handleSend = (content) => {
30
+ session.send(content);
31
+ attachmentState.clear();
32
+ };
33
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "flex h-full", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)(message_list_js_1.MessageList, { messages: session.messages, streaming: session.streaming, config: config, markdownComponents: markdownComponents, emptyState: slots.emptyState || ((0, jsx_runtime_1.jsx)(empty_state_js_1.EmptyState, { expertName: config.expert?.name })), beforeMessageList: slots.beforeMessageList, afterMessageList: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showThinking && ((0, jsx_runtime_1.jsx)("div", { className: "max-w-3xl mx-auto px-4", children: (0, jsx_runtime_1.jsx)(thinking_indicator_js_1.ThinkingIndicator, { stages: session.thinkingStages, expertName: config.expert?.name, expertAvatarUrl: config.expert?.avatarUrl }) })), slots.afterMessageList] }) }), (0, jsx_runtime_1.jsx)(input_area_js_1.InputArea, { onSend: handleSend, onAbort: session.abort, streaming: session.streaming, sending: session.sending, placeholder: config.expert
32
34
  ? `Message ${config.expert.name}...`
33
- : "Send a message...", prefillText: config.prefillText, inputPrefix: slots.inputPrefix, inputSuffix: slots.inputSuffix })] }), slots.sidePanel && ((0, jsx_runtime_1.jsx)("div", { className: "w-80 border-l border-border overflow-y-auto", children: slots.sidePanel }))] }));
35
+ : "Send a message...", prefillText: config.prefillText, inputPrefix: slots.inputPrefix, inputSuffix: slots.inputSuffix, attachments: attachmentState.attachments, uploading: attachmentState.uploading, onAddFiles: attachmentState.addFiles, onRemoveAttachment: attachmentState.remove, hasDocumentResolver: !!config.resolvers?.documentResolver })] }), slots.sidePanel && ((0, jsx_runtime_1.jsx)("div", { className: "w-80 border-l border-border overflow-y-auto", children: slots.sidePanel }))] }));
34
36
  }
35
37
  //# sourceMappingURL=chat-interface-core.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-interface-core.js","sourceRoot":"","sources":["../src/chat-interface-core.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;;AAmCZ,8CAqEC;;AApGD,qEAA4D;AAC5D,kEAA0D;AAC1D,8DAAsD;AACtD,8EAAsE;AACtE,gEAAwD;AAaxD;;;;;;;;;;;;;GAaG;AACH,SAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,kBAAkB,GACK;IACvB,MAAM,OAAO,GAAG,IAAA,oCAAc,EAAC,MAAM,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAc,CAAA;IAE/C,MAAM,YAAY,GAChB,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;QACjC,CAAC,OAAO,CAAC,WAAW,CAAA;IAEtB,OAAO,CACL,iCAAK,SAAS,EAAC,aAAa,aAE1B,iCAAK,SAAS,EAAC,8BAA8B,aAE3C,uBAAC,6BAAW,IACV,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAC1B,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EACP,KAAK,CAAC,UAAwB,IAAI,CACjC,uBAAC,2BAAU,IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAI,CAChD,EAEH,iBAAiB,EAAE,KAAK,CAAC,iBAA8B,EACvD,gBAAgB,EACd,6DACG,YAAY,IAAI,CACf,gCAAK,SAAS,EAAC,wBAAwB,YACrC,uBAAC,yCAAiB,IAChB,MAAM,EAAE,OAAO,CAAC,cAAc,EAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAC/B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GACzC,GACE,CACP,EACA,KAAK,CAAC,gBAA6B,IACnC,GAEL,EAGF,uBAAC,yBAAS,IACR,MAAM,EAAE,OAAO,CAAC,IAAI,EACpB,OAAO,EAAE,OAAO,CAAC,KAAK,EACtB,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,WAAW,EACT,MAAM,CAAC,MAAM;4BACX,CAAC,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK;4BACpC,CAAC,CAAC,mBAAmB,EAEzB,WAAW,EAAE,MAAM,CAAC,WAAW,EAC/B,WAAW,EAAE,KAAK,CAAC,WAAwB,EAC3C,WAAW,EAAE,KAAK,CAAC,WAAwB,GAC3C,IACE,EAGL,KAAK,CAAC,SAAS,IAAI,CAClB,gCAAK,SAAS,EAAC,6CAA6C,YACzD,KAAK,CAAC,SAAsB,GACzB,CACP,IACG,CACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"chat-interface-core.js","sourceRoot":"","sources":["../src/chat-interface-core.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;;AA2BZ,8CAgFC;;AAvGD,qEAA4D;AAC5D,mEAA2D;AAC3D,kEAA0D;AAC1D,8DAAsD;AACtD,8EAAsE;AACtE,gEAAwD;AAQxD;;;;;;;;;GASG;AACH,SAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,kBAAkB,GACK;IACvB,MAAM,OAAO,GAAG,IAAA,oCAAc,EAAC,MAAM,CAAC,CAAA;IACtC,MAAM,eAAe,GAAG,IAAA,mCAAc,EAAC,MAAM,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAA;IAC1E,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAc,CAAA;IAE/C,MAAM,YAAY,GAChB,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;QACjC,CAAC,OAAO,CAAC,WAAW,CAAA;IAEtB,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,EAAE;QACrC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACrB,eAAe,CAAC,KAAK,EAAE,CAAA;IACzB,CAAC,CAAA;IAED,OAAO,CACL,iCAAK,SAAS,EAAC,aAAa,aAE1B,iCAAK,SAAS,EAAC,8BAA8B,aAE3C,uBAAC,6BAAW,IACV,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAC1B,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EACP,KAAK,CAAC,UAAwB,IAAI,CACjC,uBAAC,2BAAU,IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAI,CAChD,EAEH,iBAAiB,EAAE,KAAK,CAAC,iBAA8B,EACvD,gBAAgB,EACd,6DACG,YAAY,IAAI,CACf,gCAAK,SAAS,EAAC,wBAAwB,YACrC,uBAAC,yCAAiB,IAChB,MAAM,EAAE,OAAO,CAAC,cAAc,EAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAC/B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GACzC,GACE,CACP,EACA,KAAK,CAAC,gBAA6B,IACnC,GAEL,EAGF,uBAAC,yBAAS,IACR,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,CAAC,KAAK,EACtB,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,WAAW,EACT,MAAM,CAAC,MAAM;4BACX,CAAC,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK;4BACpC,CAAC,CAAC,mBAAmB,EAEzB,WAAW,EAAE,MAAM,CAAC,WAAW,EAC/B,WAAW,EAAE,KAAK,CAAC,WAAwB,EAC3C,WAAW,EAAE,KAAK,CAAC,WAAwB,EAC3C,WAAW,EAAE,eAAe,CAAC,WAAW,EACxC,SAAS,EAAE,eAAe,CAAC,SAAS,EACpC,UAAU,EAAE,eAAe,CAAC,QAAQ,EACpC,kBAAkB,EAAE,eAAe,CAAC,MAAM,EAC1C,mBAAmB,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,gBAAgB,GACzD,IACE,EAGL,KAAK,CAAC,SAAS,IAAI,CAClB,gCAAK,SAAS,EAAC,6CAA6C,YACzD,KAAK,CAAC,SAAsB,GACzB,CACP,IACG,CACP,CAAA;AACH,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
+ import type { DocumentRef } from "../types.js";
2
3
  interface InputAreaProps {
3
4
  onSend: (content: string) => void;
4
5
  onAbort?: () => void;
@@ -9,18 +10,12 @@ interface InputAreaProps {
9
10
  prefillText?: string;
10
11
  inputPrefix?: ReactNode;
11
12
  inputSuffix?: ReactNode;
13
+ attachments?: DocumentRef[];
14
+ uploading?: boolean;
15
+ onAddFiles?: (files: File[]) => void;
16
+ onRemoveAttachment?: (documentId: string) => void;
17
+ hasDocumentResolver?: boolean;
12
18
  }
13
- /**
14
- * Chat input area with textarea, send/stop button, and slot anchors
15
- * for platform-specific prefix/suffix content.
16
- *
17
- * Supports:
18
- * - Enter to send, Shift+Enter for newline
19
- * - Auto-resize textarea
20
- * - Stop generation button during streaming
21
- * - Slot for inputPrefix (e.g., project badge, whisper indicator)
22
- * - Slot for inputSuffix (e.g., provider selector, voice button)
23
- */
24
- export declare function InputArea({ onSend, onAbort, streaming, sending, disabled, placeholder, prefillText, inputPrefix, inputSuffix, }: InputAreaProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function InputArea({ onSend, onAbort, streaming, sending, disabled, placeholder, prefillText, inputPrefix, inputSuffix, attachments, uploading, onAddFiles, onRemoveAttachment, hasDocumentResolver, }: InputAreaProps): import("react/jsx-runtime").JSX.Element;
25
20
  export {};
26
21
  //# sourceMappingURL=input-area.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-area.d.ts","sourceRoot":"","sources":["../../src/components/input-area.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,OAAO,CAAA;AAGd,UAAU,cAAc;IACtB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,WAAW,CAAC,EAAE,SAAS,CAAA;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,OAAO,EACP,SAAS,EACT,OAAO,EACP,QAAgB,EAChB,WAAiC,EACjC,WAAW,EACX,WAAW,EACX,WAAW,GACZ,EAAE,cAAc,2CAmGhB"}
1
+ {"version":3,"file":"input-area.d.ts","sourceRoot":"","sources":["../../src/components/input-area.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,SAAS,EAGf,MAAM,OAAO,CAAA;AAEd,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,UAAU,cAAc;IACtB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAA;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAA;IACpC,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACjD,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC9B;AAED,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,OAAO,EACP,SAAS,EACT,OAAO,EACP,QAAgB,EAChB,WAAiC,EACjC,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAgB,EAChB,SAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,mBAA2B,GAC5B,EAAE,cAAc,2CAkMhB"}
@@ -5,21 +5,12 @@ exports.InputArea = InputArea;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const lucide_react_1 = require("lucide-react");
8
- /**
9
- * Chat input area with textarea, send/stop button, and slot anchors
10
- * for platform-specific prefix/suffix content.
11
- *
12
- * Supports:
13
- * - Enter to send, Shift+Enter for newline
14
- * - Auto-resize textarea
15
- * - Stop generation button during streaming
16
- * - Slot for inputPrefix (e.g., project badge, whisper indicator)
17
- * - Slot for inputSuffix (e.g., provider selector, voice button)
18
- */
19
- function InputArea({ onSend, onAbort, streaming, sending, disabled = false, placeholder = "Send a message...", prefillText, inputPrefix, inputSuffix, }) {
8
+ function InputArea({ onSend, onAbort, streaming, sending, disabled = false, placeholder = "Send a message...", prefillText, inputPrefix, inputSuffix, attachments = [], uploading = false, onAddFiles, onRemoveAttachment, hasDocumentResolver = false, }) {
20
9
  const [text, setText] = (0, react_1.useState)(prefillText || "");
10
+ const [dragOver, setDragOver] = (0, react_1.useState)(false);
21
11
  const textareaRef = (0, react_1.useRef)(null);
22
12
  const composingRef = (0, react_1.useRef)(false);
13
+ const fileInputRef = (0, react_1.useRef)(null);
23
14
  (0, react_1.useEffect)(() => {
24
15
  if (prefillText) {
25
16
  setText(prefillText);
@@ -56,8 +47,37 @@ function InputArea({ onSend, onAbort, streaming, sending, disabled = false, plac
56
47
  handleSend();
57
48
  }
58
49
  }, [handleSend]);
50
+ const handleDragOver = (0, react_1.useCallback)((e) => {
51
+ if (!hasDocumentResolver)
52
+ return;
53
+ e.preventDefault();
54
+ setDragOver(true);
55
+ }, [hasDocumentResolver]);
56
+ const handleDragLeave = (0, react_1.useCallback)(() => {
57
+ setDragOver(false);
58
+ }, []);
59
+ const handleDrop = (0, react_1.useCallback)((e) => {
60
+ e.preventDefault();
61
+ setDragOver(false);
62
+ if (!onAddFiles)
63
+ return;
64
+ const files = Array.from(e.dataTransfer.files);
65
+ if (files.length > 0) {
66
+ onAddFiles(files);
67
+ }
68
+ }, [onAddFiles]);
69
+ const handleFileSelect = (0, react_1.useCallback)(() => {
70
+ fileInputRef.current?.click();
71
+ }, []);
72
+ const handleFileInputChange = (0, react_1.useCallback)((e) => {
73
+ const files = Array.from(e.target.files || []);
74
+ if (files.length > 0 && onAddFiles) {
75
+ onAddFiles(files);
76
+ }
77
+ e.target.value = "";
78
+ }, [onAddFiles]);
59
79
  const canSend = text.trim().length > 0 && !sending && !streaming && !disabled;
60
- return ((0, jsx_runtime_1.jsxs)("div", { className: "border-t border-border bg-card px-4 py-3", children: [inputPrefix && ((0, jsx_runtime_1.jsx)("div", { className: "mb-2", children: inputPrefix })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-end gap-2 max-w-3xl mx-auto", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 relative", children: (0, jsx_runtime_1.jsx)("textarea", { ref: textareaRef, value: text, onChange: (e) => setText(e.target.value), onKeyDown: handleKeyDown, onCompositionStart: () => {
80
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `border-t border-border bg-card px-4 py-3 ${dragOver ? "ring-2 ring-primary ring-inset" : ""}`, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [inputPrefix && (0, jsx_runtime_1.jsx)("div", { className: "mb-2", children: inputPrefix }), attachments.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap gap-1.5 mb-2 max-w-3xl mx-auto", children: [attachments.map((doc) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 px-2 py-1 rounded-lg bg-muted text-xs text-foreground", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.FileText, { className: "w-3 h-3 text-muted-foreground shrink-0" }), (0, jsx_runtime_1.jsx)("span", { className: "truncate max-w-[150px]", children: doc.name }), onRemoveAttachment && ((0, jsx_runtime_1.jsx)("button", { onClick: () => onRemoveAttachment(doc.id), className: "p-0.5 rounded hover:bg-accent text-muted-foreground hover:text-foreground transition-colors", children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3" }) }))] }, doc.id))), uploading && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 px-2 py-1 rounded-lg bg-muted text-xs text-muted-foreground", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-3 h-3 border border-current border-t-transparent rounded-full animate-spin" }), (0, jsx_runtime_1.jsx)("span", { children: "Uploading..." })] }))] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-end gap-2 max-w-3xl mx-auto", children: [hasDocumentResolver && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { onClick: handleFileSelect, disabled: uploading, className: "p-2 rounded-lg text-muted-foreground hover:text-foreground hover:bg-accent disabled:opacity-50 transition-colors", "aria-label": "Attach document", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Paperclip, { className: "w-4 h-4" }) }), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: handleFileInputChange })] })), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 relative", children: (0, jsx_runtime_1.jsx)("textarea", { ref: textareaRef, value: text, onChange: (e) => setText(e.target.value), onKeyDown: handleKeyDown, onCompositionStart: () => {
61
81
  composingRef.current = true;
62
82
  }, onCompositionEnd: () => {
63
83
  composingRef.current = false;
@@ -1 +1 @@
1
- {"version":3,"file":"input-area.js","sourceRoot":"","sources":["../../src/components/input-area.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"input-area.js","sourceRoot":"","sources":["../../src/components/input-area.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;;AA+BZ,8BAiNC;;AA9OD,iCAQc;AACd,+CAA4E;AAoB5E,SAAgB,SAAS,CAAC,EACxB,MAAM,EACN,OAAO,EACP,SAAS,EACT,OAAO,EACP,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,mBAAmB,EACjC,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,GAAG,EAAE,EAChB,SAAS,GAAG,KAAK,EACjB,UAAU,EACV,kBAAkB,EAClB,mBAAmB,GAAG,KAAK,GACZ;IACf,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,IAAA,gBAAQ,EAAC,WAAW,IAAI,EAAE,CAAC,CAAA;IACnD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,WAAW,GAAG,IAAA,cAAM,EAAsB,IAAK,CAAC,CAAA;IACtD,MAAM,YAAY,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAA;IAClC,MAAM,YAAY,GAAG,IAAA,cAAM,EAAmB,IAAK,CAAC,CAAA;IAEpD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,CAAC,WAAW,CAAC,CAAA;QACtB,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,MAAM,YAAY,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACpC,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAA;QAC9B,IAAI,CAAC,EAAE;YAAE,OAAM;QACf,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAA;QACxB,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI,CAAA;IACzD,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,YAAY,EAAE,CAAA;IAChB,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAA;IAExB,MAAM,UAAU,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO,IAAI,OAAO,IAAI,SAAS,IAAI,QAAQ;YAAE,OAAM;QACxD,MAAM,CAAC,OAAO,CAAC,CAAA;QACf,OAAO,CAAC,EAAE,CAAC,CAAA;QACX,qBAAqB,CAAC,GAAG,EAAE;YACzB,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAA;YAC9B,IAAI,EAAE,EAAE,CAAC;gBACP,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAA;YAC1B,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;IAEhD,MAAM,aAAa,GAAG,IAAA,mBAAW,EAC/B,CAAC,CAAqC,EAAE,EAAE;QACxC,IAAI,YAAY,CAAC,OAAO;YAAE,OAAM;QAChC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YACrC,CAAC,CAAC,cAAc,EAAE,CAAA;YAClB,UAAU,EAAE,CAAA;QACd,CAAC;IACH,CAAC,EACD,CAAC,UAAU,CAAC,CACb,CAAA;IAED,MAAM,cAAc,GAAG,IAAA,mBAAW,EAChC,CAAC,CAAY,EAAE,EAAE;QACf,IAAI,CAAC,mBAAmB;YAAE,OAAM;QAChC,CAAC,CAAC,cAAc,EAAE,CAAA;QAClB,WAAW,CAAC,IAAI,CAAC,CAAA;IACnB,CAAC,EACD,CAAC,mBAAmB,CAAC,CACtB,CAAA;IAED,MAAM,eAAe,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACvC,WAAW,CAAC,KAAK,CAAC,CAAA;IACpB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,UAAU,GAAG,IAAA,mBAAW,EAC5B,CAAC,CAAY,EAAE,EAAE;QACf,CAAC,CAAC,cAAc,EAAE,CAAA;QAClB,WAAW,CAAC,KAAK,CAAC,CAAA;QAClB,IAAI,CAAC,UAAU;YAAE,OAAM;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QAC9C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,UAAU,CAAC,KAAK,CAAC,CAAA;QACnB,CAAC;IACH,CAAC,EACD,CAAC,UAAU,CAAC,CACb,CAAA;IAED,MAAM,gBAAgB,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACxC,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;IAC/B,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,qBAAqB,GAAG,IAAA,mBAAW,EACvC,CAAC,CAAsC,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;QAC9C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;YACnC,UAAU,CAAC,KAAK,CAAC,CAAA;QACnB,CAAC;QACD,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAA;IACrB,CAAC,EACD,CAAC,UAAU,CAAC,CACb,CAAA;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAA;IAE7E,OAAO,CACL,iCACE,SAAS,EAAE,4CAA4C,QAAQ,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE,EAAE,EACzG,UAAU,EAAE,cAAc,EAC1B,WAAW,EAAE,eAAe,EAC5B,MAAM,EAAE,UAAU,aAEjB,WAAW,IAAI,gCAAK,SAAS,EAAC,MAAM,YAAE,WAAW,GAAO,EAGxD,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CACzB,iCAAK,SAAS,EAAC,+CAA+C,aAC3D,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACxB,iCAEE,SAAS,EAAC,iFAAiF,aAE3F,uBAAC,uBAAQ,IAAC,SAAS,EAAC,wCAAwC,GAAG,EAC/D,iCAAM,SAAS,EAAC,wBAAwB,YAAE,GAAG,CAAC,IAAI,GAAQ,EACzD,kBAAkB,IAAI,CACrB,mCACE,OAAO,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,EACzC,SAAS,EAAC,6FAA6F,YAEvG,uBAAC,gBAAK,IAAC,SAAS,EAAC,SAAS,GAAG,GACtB,CACV,KAZI,GAAG,CAAC,EAAE,CAaP,CACP,CAAC,EACD,SAAS,IAAI,CACZ,iCAAK,SAAS,EAAC,uFAAuF,aACpG,gCAAK,SAAS,EAAC,8EAA8E,GAAG,EAChG,4DAAyB,IACrB,CACP,IACG,CACP,EAED,iCAAK,SAAS,EAAC,wCAAwC,aACpD,mBAAmB,IAAI,CACtB,6DACE,mCACE,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,SAAS,EACnB,SAAS,EAAC,kHAAkH,gBACjH,iBAAiB,YAE5B,uBAAC,wBAAS,IAAC,SAAS,EAAC,SAAS,GAAG,GAC1B,EACT,kCACE,GAAG,EAAE,YAAY,EACjB,IAAI,EAAC,MAAM,EACX,QAAQ,QACR,SAAS,EAAC,QAAQ,EAClB,QAAQ,EAAE,qBAAqB,GAC/B,IACD,CACJ,EAED,gCAAK,SAAS,EAAC,iBAAiB,YAC9B,qCACE,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACxC,SAAS,EAAE,aAAa,EACxB,kBAAkB,EAAE,GAAG,EAAE;gCACvB,YAAY,CAAC,OAAO,GAAG,IAAI,CAAA;4BAC7B,CAAC,EACD,gBAAgB,EAAE,GAAG,EAAE;gCACrB,YAAY,CAAC,OAAO,GAAG,KAAK,CAAA;4BAC9B,CAAC,EACD,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,IAAI,OAAO,EAC7B,IAAI,EAAE,CAAC,EACP,SAAS,EAAC,0PAA0P,GACpQ,GACE,EAEN,iCAAK,SAAS,EAAC,2BAA2B,aACvC,WAAW,EAEX,SAAS,CAAC,CAAC,CAAC,CACX,mCACE,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,yEAAyE,gBACxE,iBAAiB,YAE5B,uBAAC,qBAAM,IAAC,SAAS,EAAC,SAAS,GAAG,GACvB,CACV,CAAC,CAAC,CAAC,CACF,mCACE,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,CAAC,OAAO,EAClB,SAAS,EAAC,2HAA2H,gBAC1H,cAAc,YAEzB,uBAAC,mBAAI,IAAC,SAAS,EAAC,SAAS,GAAG,GACrB,CACV,IACG,IACF,IACF,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { DocumentRef } from "../types.js";
2
+ /**
3
+ * Manages document attachment state for the chat input.
4
+ *
5
+ * Platforms provide a `documentResolver` that handles the actual
6
+ * upload/selection logic. This hook manages the resulting DocumentRef
7
+ * array and provides operations to add, remove, and clear attachments.
8
+ */
9
+ export interface AttachmentState {
10
+ attachments: DocumentRef[];
11
+ uploading: boolean;
12
+ addFiles: (files: File[]) => Promise<void>;
13
+ addDocuments: (docs: DocumentRef[]) => void;
14
+ remove: (documentId: string) => void;
15
+ clear: () => void;
16
+ }
17
+ export declare function useAttachments(documentResolver?: (files: File[]) => Promise<DocumentRef[]>): AttachmentState;
18
+ //# sourceMappingURL=use-attachments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-attachments.d.ts","sourceRoot":"","sources":["../../src/hooks/use-attachments.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C;;;;;;GAMG;AAEH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,WAAW,EAAE,CAAA;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,YAAY,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAA;IAC3C,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,wBAAgB,cAAc,CAC5B,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,GAC3D,eAAe,CAgDjB"}
@@ -0,0 +1,50 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.useAttachments = useAttachments;
5
+ const react_1 = require("react");
6
+ function useAttachments(documentResolver) {
7
+ const [attachments, setAttachments] = (0, react_1.useState)([]);
8
+ const [uploading, setUploading] = (0, react_1.useState)(false);
9
+ const addFiles = (0, react_1.useCallback)(async (files) => {
10
+ if (!documentResolver || files.length === 0)
11
+ return;
12
+ setUploading(true);
13
+ try {
14
+ const docs = await documentResolver(files);
15
+ setAttachments((prev) => {
16
+ const existing = new Set(prev.map((d) => d.id));
17
+ const newDocs = docs.filter((d) => !existing.has(d.id));
18
+ return [...prev, ...newDocs];
19
+ });
20
+ }
21
+ catch (error) {
22
+ console.error("[Attachments] Upload failed:", error);
23
+ }
24
+ finally {
25
+ setUploading(false);
26
+ }
27
+ }, [documentResolver]);
28
+ const addDocuments = (0, react_1.useCallback)((docs) => {
29
+ setAttachments((prev) => {
30
+ const existing = new Set(prev.map((d) => d.id));
31
+ const newDocs = docs.filter((d) => !existing.has(d.id));
32
+ return [...prev, ...newDocs];
33
+ });
34
+ }, []);
35
+ const remove = (0, react_1.useCallback)((documentId) => {
36
+ setAttachments((prev) => prev.filter((d) => d.id !== documentId));
37
+ }, []);
38
+ const clear = (0, react_1.useCallback)(() => {
39
+ setAttachments([]);
40
+ }, []);
41
+ return {
42
+ attachments,
43
+ uploading,
44
+ addFiles,
45
+ addDocuments,
46
+ remove,
47
+ clear,
48
+ };
49
+ }
50
+ //# sourceMappingURL=use-attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-attachments.js","sourceRoot":"","sources":["../../src/hooks/use-attachments.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;;;AAsBZ,wCAkDC;AAtED,iCAA6C;AAoB7C,SAAgB,cAAc,CAC5B,gBAA4D;IAE5D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAgB,EAAE,CAAC,CAAA;IACjE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAA;IAEjD,MAAM,QAAQ,GAAG,IAAA,mBAAW,EAC1B,KAAK,EAAE,KAAa,EAAE,EAAE;QACtB,IAAI,CAAC,gBAAgB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QACnD,YAAY,CAAC,IAAI,CAAC,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAA;YAC1C,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;gBACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;gBAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;gBACvD,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC,CAAA;YAC9B,CAAC,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAA;QACtD,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;IACH,CAAC,EACD,CAAC,gBAAgB,CAAC,CACnB,CAAA;IAED,MAAM,YAAY,GAAG,IAAA,mBAAW,EAAC,CAAC,IAAmB,EAAE,EAAE;QACvD,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YACvD,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC,CAAA;QAC9B,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,MAAM,GAAG,IAAA,mBAAW,EAAC,CAAC,UAAkB,EAAE,EAAE;QAChD,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,CAAA;IACnE,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QAC7B,cAAc,CAAC,EAAE,CAAC,CAAA;IACpB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO;QACL,WAAW;QACX,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,MAAM;QACN,KAAK;KACN,CAAA;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ export { ChatInterfaceCore } from "./chat-interface-core.js";
13
13
  export { useChatSession } from "./hooks/use-chat-session.js";
14
14
  export type { ChatSession } from "./hooks/use-chat-session.js";
15
15
  export { useChatScroll } from "./hooks/use-chat-scroll.js";
16
+ export { useAttachments } from "./hooks/use-attachments.js";
17
+ export type { AttachmentState } from "./hooks/use-attachments.js";
16
18
  export { MessageList } from "./components/message-list.js";
17
19
  export { MessageBubble } from "./components/message-bubble.js";
18
20
  export { InputArea } from "./components/input-area.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAG5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,YAAY,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAGxD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAGzE,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,WAAW,EACX,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAG5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAG1D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAGjE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,YAAY,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAGxD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAGzE,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,WAAW,EACX,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,MAAM,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@
11
11
  * slots, resolvers, handlers).
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.rehypePlugins = exports.remarkPlugins = exports.groupMessages = exports.isDifferentDay = exports.getDateSeparator = exports.formatTime = exports.EmptyState = exports.ThinkingIndicator = exports.StreamingText = exports.InputArea = exports.MessageBubble = exports.MessageList = exports.useChatScroll = exports.useChatSession = exports.ChatInterfaceCore = void 0;
14
+ exports.rehypePlugins = exports.remarkPlugins = exports.groupMessages = exports.isDifferentDay = exports.getDateSeparator = exports.formatTime = exports.EmptyState = exports.ThinkingIndicator = exports.StreamingText = exports.InputArea = exports.MessageBubble = exports.MessageList = exports.useAttachments = exports.useChatScroll = exports.useChatSession = exports.ChatInterfaceCore = void 0;
15
15
  // The main product
16
16
  var chat_interface_core_js_1 = require("./chat-interface-core.js");
17
17
  Object.defineProperty(exports, "ChatInterfaceCore", { enumerable: true, get: function () { return chat_interface_core_js_1.ChatInterfaceCore; } });
@@ -21,6 +21,9 @@ Object.defineProperty(exports, "useChatSession", { enumerable: true, get: functi
21
21
  // Scroll management
22
22
  var use_chat_scroll_js_1 = require("./hooks/use-chat-scroll.js");
23
23
  Object.defineProperty(exports, "useChatScroll", { enumerable: true, get: function () { return use_chat_scroll_js_1.useChatScroll; } });
24
+ // Attachments
25
+ var use_attachments_js_1 = require("./hooks/use-attachments.js");
26
+ Object.defineProperty(exports, "useAttachments", { enumerable: true, get: function () { return use_attachments_js_1.useAttachments; } });
24
27
  // UI components (for platforms that want to compose their own layout)
25
28
  var message_list_js_1 = require("./components/message-list.js");
26
29
  Object.defineProperty(exports, "MessageList", { enumerable: true, get: function () { return message_list_js_1.MessageList; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEH,mBAAmB;AACnB,mEAA4D;AAAnD,2HAAA,iBAAiB,OAAA;AAE1B,qEAAqE;AACrE,mEAA4D;AAAnD,qHAAA,cAAc,OAAA;AAGvB,oBAAoB;AACpB,iEAA0D;AAAjD,mHAAA,aAAa,OAAA;AAEtB,sEAAsE;AACtE,gEAA0D;AAAjD,8GAAA,WAAW,OAAA;AACpB,oEAA8D;AAArD,kHAAA,aAAa,OAAA;AACtB,4DAAsD;AAA7C,0GAAA,SAAS,OAAA;AAClB,oEAA8D;AAArD,kHAAA,aAAa,OAAA;AACtB,4EAAsE;AAA7D,0HAAA,iBAAiB,OAAA;AAE1B,8DAAwD;AAA/C,4GAAA,UAAU,OAAA;AAEnB,YAAY;AACZ,2CAA8E;AAArE,qGAAA,UAAU,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,yGAAA,cAAc,OAAA;AACrD,mEAA2D;AAAlD,oHAAA,aAAa,OAAA;AACtB,iEAAyE;AAAhE,mHAAA,aAAa,OAAA;AAAE,mHAAA,aAAa,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEH,mBAAmB;AACnB,mEAA4D;AAAnD,2HAAA,iBAAiB,OAAA;AAE1B,qEAAqE;AACrE,mEAA4D;AAAnD,qHAAA,cAAc,OAAA;AAGvB,oBAAoB;AACpB,iEAA0D;AAAjD,mHAAA,aAAa,OAAA;AAEtB,cAAc;AACd,iEAA2D;AAAlD,oHAAA,cAAc,OAAA;AAGvB,sEAAsE;AACtE,gEAA0D;AAAjD,8GAAA,WAAW,OAAA;AACpB,oEAA8D;AAArD,kHAAA,aAAa,OAAA;AACtB,4DAAsD;AAA7C,0GAAA,SAAS,OAAA;AAClB,oEAA8D;AAArD,kHAAA,aAAa,OAAA;AACtB,4EAAsE;AAA7D,0HAAA,iBAAiB,OAAA;AAE1B,8DAAwD;AAA/C,4GAAA,UAAU,OAAA;AAEnB,YAAY;AACZ,2CAA8E;AAArE,qGAAA,UAAU,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,yGAAA,cAAc,OAAA;AACrD,mEAA2D;AAAlD,oHAAA,aAAa,OAAA;AACtB,iEAAyE;AAAhE,mHAAA,aAAa,OAAA;AAAE,mHAAA,aAAa,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portablecore/chat",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Unified chat UI for Portable platforms — composable ChatInterface with extension points",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",