@miiflow/assistant-ui 0.1.0 → 0.1.1

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.
Files changed (74) hide show
  1. package/dist/{WelcomeScreen-CsFaFNcu.d.mts → WelcomeScreen-B434H05-.d.cts} +3 -3
  2. package/dist/{avatar-D5eHcfjf.d.mts → avatar-DvOcT8NS.d.cts} +1 -1
  3. package/dist/chunk-3ERHTQXR.js +1 -1
  4. package/dist/chunk-3ERHTQXR.js.map +1 -1
  5. package/dist/chunk-3KB4JYSQ.js +1 -1
  6. package/dist/chunk-3KB4JYSQ.js.map +1 -1
  7. package/dist/chunk-BA3VCHRC.js +8 -8
  8. package/dist/chunk-BA3VCHRC.js.map +1 -1
  9. package/dist/chunk-G7TGUXDN.cjs +2 -0
  10. package/dist/chunk-G7TGUXDN.cjs.map +1 -0
  11. package/dist/chunk-KSMAVBLY.cjs +2 -0
  12. package/dist/{chunk-CRNBTU42.mjs.map → chunk-KSMAVBLY.cjs.map} +1 -1
  13. package/dist/chunk-LJQHWCUK.js +1 -1
  14. package/dist/chunk-LJQHWCUK.js.map +1 -1
  15. package/dist/chunk-LLMC5JID.cjs +2 -0
  16. package/dist/chunk-LLMC5JID.cjs.map +1 -0
  17. package/dist/chunk-NSTK5EUQ.js +1 -1
  18. package/dist/chunk-NSTK5EUQ.js.map +1 -1
  19. package/dist/chunk-OCKHJ4WO.js +1 -1
  20. package/dist/chunk-OCKHJ4WO.js.map +1 -1
  21. package/dist/chunk-SFEPMZCU.cjs +2 -0
  22. package/dist/chunk-SFEPMZCU.cjs.map +1 -0
  23. package/dist/chunk-VQVCOIS3.cjs +22 -0
  24. package/dist/chunk-VQVCOIS3.cjs.map +1 -0
  25. package/dist/chunk-YMIEUVHK.cjs +2 -0
  26. package/dist/chunk-YMIEUVHK.cjs.map +1 -0
  27. package/dist/client/{index.mjs → index.cjs} +3 -3
  28. package/dist/client/index.cjs.map +1 -0
  29. package/dist/client/{index.d.mts → index.d.cts} +3 -3
  30. package/dist/client/index.js +2 -2
  31. package/dist/client/index.js.map +1 -1
  32. package/dist/context/index.cjs +2 -0
  33. package/dist/context/{index.mjs.map → index.cjs.map} +1 -1
  34. package/dist/context/{index.d.mts → index.d.cts} +2 -2
  35. package/dist/context/index.js +1 -1
  36. package/dist/hooks/index.cjs +2 -0
  37. package/dist/hooks/{index.mjs.map → index.cjs.map} +1 -1
  38. package/dist/hooks/{index.d.mts → index.d.cts} +2 -2
  39. package/dist/hooks/index.js +1 -1
  40. package/dist/index.cjs +2 -0
  41. package/dist/index.cjs.map +1 -0
  42. package/dist/{index.d.mts → index.d.cts} +8 -8
  43. package/dist/index.js +1 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/{message-ufYsvKXP.d.mts → message-a6VUd777.d.cts} +1 -1
  46. package/dist/primitives/index.cjs +2 -0
  47. package/dist/primitives/{index.mjs.map → index.cjs.map} +1 -1
  48. package/dist/primitives/{index.d.mts → index.d.cts} +3 -3
  49. package/dist/primitives/index.js +1 -1
  50. package/dist/styled/index.cjs +2 -0
  51. package/dist/styled/{index.mjs.map → index.cjs.map} +1 -1
  52. package/dist/styled/{index.d.mts → index.d.cts} +8 -8
  53. package/dist/styled/index.js +1 -1
  54. package/package.json +4 -1
  55. package/dist/chunk-3E2HG62U.mjs +0 -2
  56. package/dist/chunk-3E2HG62U.mjs.map +0 -1
  57. package/dist/chunk-3GQNGDXX.mjs +0 -22
  58. package/dist/chunk-3GQNGDXX.mjs.map +0 -1
  59. package/dist/chunk-CRNBTU42.mjs +0 -2
  60. package/dist/chunk-KPGHBLGY.mjs +0 -2
  61. package/dist/chunk-KPGHBLGY.mjs.map +0 -1
  62. package/dist/chunk-MFCWFFJV.mjs +0 -2
  63. package/dist/chunk-MFCWFFJV.mjs.map +0 -1
  64. package/dist/chunk-RTT6LULU.mjs +0 -2
  65. package/dist/chunk-RTT6LULU.mjs.map +0 -1
  66. package/dist/client/index.mjs.map +0 -1
  67. package/dist/context/index.mjs +0 -2
  68. package/dist/hooks/index.mjs +0 -2
  69. package/dist/index.mjs +0 -2
  70. package/dist/index.mjs.map +0 -1
  71. package/dist/primitives/index.mjs +0 -2
  72. package/dist/styled/index.mjs +0 -2
  73. /package/dist/{branding-SzYU4ncD.d.mts → branding-SzYU4ncD.d.cts} +0 -0
  74. /package/dist/{streaming-CF63E6iS.d.mts → streaming-CF63E6iS.d.cts} +0 -0
@@ -1,8 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
- import { A as Attachment, M as MessageData, P as ParticipantRole, c as SuggestedAction, S as SourceReference } from './message-ufYsvKXP.mjs';
4
- import { h as AvatarProps$1 } from './avatar-D5eHcfjf.mjs';
5
- import { S as StreamingChunk, V as VisualizationChunkData, C as ClarificationData } from './streaming-CF63E6iS.mjs';
3
+ import { A as Attachment, M as MessageData, P as ParticipantRole, c as SuggestedAction, S as SourceReference } from './message-a6VUd777.cjs';
4
+ import { h as AvatarProps$1 } from './avatar-DvOcT8NS.cjs';
5
+ import { S as StreamingChunk, V as VisualizationChunkData, C as ClarificationData } from './streaming-CF63E6iS.cjs';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
7
 
8
8
  interface AttachmentPreviewProps {
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode, TextareaHTMLAttributes, ButtonHTMLAttributes } from 'react';
3
- import { M as MessageData, P as ParticipantRole } from './message-ufYsvKXP.mjs';
3
+ import { M as MessageData, P as ParticipantRole } from './message-a6VUd777.cjs';
4
4
 
5
5
  interface MessageContextValue {
6
6
  message: MessageData;
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react');function A(r={}){let[c,i]=react.useState({isStreaming:false,streamingMessageId:null,streamedContent:""}),n=react.useRef(null),m=react.useCallback(e=>{i({isStreaming:true,streamingMessageId:e,streamedContent:""}),n.current=new AbortController;},[]),d=react.useCallback(e=>{e.type==="content"&&e.content&&i(u=>({...u,streamedContent:u.streamedContent+e.content})),r.onChunk?.(e);},[r]),p=react.useCallback(()=>{n.current?.abort();let e=c.streamedContent;i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onComplete?.(e);},[c.streamedContent,r]),f=react.useCallback(e=>{n.current?.abort(),i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onError?.(e);},[r]);return {...c,startStreaming:m,appendContent:d,stopStreaming:p,handleError:f,abortSignal:n.current?.signal}}function x({maxCount:r=5,maxFileSize:c=10*1024*1024,allowedTypes:i}={}){let[n,m]=react.useState([]),d=react.useCallback(t=>{if(n.length>=r)return {success:false,error:`Maximum ${r} attachments allowed`};if(t.size>c)return {success:false,error:`File size exceeds ${Math.round(c/1024/1024)}MB limit`};if(i&&!i.includes(t.type))return {success:false,error:`File type ${t.type} not allowed`};let o=`${Date.now()}-${Math.random().toString(36).slice(2)}`;return m(a=>[...a,{file:t,id:o,progress:0,status:"pending"}]),{success:true}},[n.length,r,c,i]),p=react.useCallback(t=>{m(o=>o.filter(a=>a.id!==t));},[]),f=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,progress:o,status:o<100?"uploading":"complete"}:s));},[]),e=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,status:"error",error:o}:s));},[]),u=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,url:o,status:"complete",progress:100}:s));},[]),S=react.useCallback(()=>{m([]);},[]),C=react.useCallback(()=>n.map(t=>t.file),[n]);return {attachments:n,addAttachment:d,removeAttachment:p,updateProgress:f,setError:e,setUrl:u,clear:S,getFiles:C,canAddMore:n.length<r}}exports.a=A;exports.b=x;//# sourceMappingURL=chunk-3ERHTQXR.js.map
1
+ import {useState,useRef,useCallback}from'react';function A(r={}){let[c,i]=useState({isStreaming:false,streamingMessageId:null,streamedContent:""}),n=useRef(null),m=useCallback(e=>{i({isStreaming:true,streamingMessageId:e,streamedContent:""}),n.current=new AbortController;},[]),d=useCallback(e=>{e.type==="content"&&e.content&&i(u=>({...u,streamedContent:u.streamedContent+e.content})),r.onChunk?.(e);},[r]),p=useCallback(()=>{n.current?.abort();let e=c.streamedContent;i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onComplete?.(e);},[c.streamedContent,r]),f=useCallback(e=>{n.current?.abort(),i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onError?.(e);},[r]);return {...c,startStreaming:m,appendContent:d,stopStreaming:p,handleError:f,abortSignal:n.current?.signal}}function x({maxCount:r=5,maxFileSize:c=10*1024*1024,allowedTypes:i}={}){let[n,m]=useState([]),d=useCallback(t=>{if(n.length>=r)return {success:false,error:`Maximum ${r} attachments allowed`};if(t.size>c)return {success:false,error:`File size exceeds ${Math.round(c/1024/1024)}MB limit`};if(i&&!i.includes(t.type))return {success:false,error:`File type ${t.type} not allowed`};let o=`${Date.now()}-${Math.random().toString(36).slice(2)}`;return m(a=>[...a,{file:t,id:o,progress:0,status:"pending"}]),{success:true}},[n.length,r,c,i]),p=useCallback(t=>{m(o=>o.filter(a=>a.id!==t));},[]),f=useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,progress:o,status:o<100?"uploading":"complete"}:s));},[]),e=useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,status:"error",error:o}:s));},[]),u=useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,url:o,status:"complete",progress:100}:s));},[]),S=useCallback(()=>{m([]);},[]),C=useCallback(()=>n.map(t=>t.file),[n]);return {attachments:n,addAttachment:d,removeAttachment:p,updateProgress:f,setError:e,setUrl:u,clear:S,getFiles:C,canAddMore:n.length<r}}export{A as a,x as b};//# sourceMappingURL=chunk-3ERHTQXR.js.map
2
2
  //# sourceMappingURL=chunk-3ERHTQXR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/use-streaming.ts","../src/hooks/use-attachments.ts"],"names":["useStreaming","options","state","setState","useState","abortControllerRef","useRef","startStreaming","useCallback","messageId","appendContent","chunk","prev","stopStreaming","finalContent","handleError","error","useAttachments","maxCount","maxFileSize","allowedTypes","attachments","setAttachments","addAttachment","file","id","removeAttachment","updateProgress","progress","a","setError","setUrl","url","clear","getFiles"],"mappings":"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","file":"chunk-3ERHTQXR.js","sourcesContent":["import { useState, useCallback, useRef } from \"react\";\nimport type { StreamingState, StreamChunk, StreamingOptions } from \"../types\";\n\n/**\n * Hook to manage streaming message state.\n */\nexport function useStreaming(options: StreamingOptions = {}) {\n const [state, setState] = useState<StreamingState>({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const startStreaming = useCallback((messageId: string) => {\n setState({\n isStreaming: true,\n streamingMessageId: messageId,\n streamedContent: \"\",\n });\n abortControllerRef.current = new AbortController();\n }, []);\n\n const appendContent = useCallback(\n (chunk: StreamChunk) => {\n if (chunk.type === \"content\" && chunk.content) {\n setState((prev) => ({\n ...prev,\n streamedContent: prev.streamedContent + chunk.content,\n }));\n }\n options.onChunk?.(chunk);\n },\n [options]\n );\n\n const stopStreaming = useCallback(() => {\n abortControllerRef.current?.abort();\n const finalContent = state.streamedContent;\n\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n options.onComplete?.(finalContent);\n }, [state.streamedContent, options]);\n\n const handleError = useCallback(\n (error: Error) => {\n abortControllerRef.current?.abort();\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n options.onError?.(error);\n },\n [options]\n );\n\n return {\n ...state,\n startStreaming,\n appendContent,\n stopStreaming,\n handleError,\n abortSignal: abortControllerRef.current?.signal,\n };\n}\n","import { useState, useCallback } from \"react\";\n\ninterface AttachmentState {\n file: File;\n id: string;\n progress: number;\n status: \"pending\" | \"uploading\" | \"complete\" | \"error\";\n error?: string;\n url?: string;\n}\n\ninterface UseAttachmentsOptions {\n /** Maximum number of attachments */\n maxCount?: number;\n /** Maximum file size in bytes */\n maxFileSize?: number;\n /** Allowed MIME types */\n allowedTypes?: string[];\n}\n\n/**\n * Hook to manage file attachments with upload progress.\n */\nexport function useAttachments({\n maxCount = 5,\n maxFileSize = 10 * 1024 * 1024,\n allowedTypes,\n}: UseAttachmentsOptions = {}) {\n const [attachments, setAttachments] = useState<AttachmentState[]>([]);\n\n const addAttachment = useCallback(\n (file: File): { success: boolean; error?: string } => {\n // Check count\n if (attachments.length >= maxCount) {\n return { success: false, error: `Maximum ${maxCount} attachments allowed` };\n }\n\n // Check size\n if (file.size > maxFileSize) {\n return {\n success: false,\n error: `File size exceeds ${Math.round(maxFileSize / 1024 / 1024)}MB limit`,\n };\n }\n\n // Check type\n if (allowedTypes && !allowedTypes.includes(file.type)) {\n return { success: false, error: `File type ${file.type} not allowed` };\n }\n\n const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n setAttachments((prev) => [\n ...prev,\n {\n file,\n id,\n progress: 0,\n status: \"pending\",\n },\n ]);\n\n return { success: true };\n },\n [attachments.length, maxCount, maxFileSize, allowedTypes]\n );\n\n const removeAttachment = useCallback((id: string) => {\n setAttachments((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const updateProgress = useCallback((id: string, progress: number) => {\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === id\n ? { ...a, progress, status: progress < 100 ? \"uploading\" : \"complete\" }\n : a\n )\n );\n }, []);\n\n const setError = useCallback((id: string, error: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, status: \"error\", error } : a))\n );\n }, []);\n\n const setUrl = useCallback((id: string, url: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, url, status: \"complete\", progress: 100 } : a))\n );\n }, []);\n\n const clear = useCallback(() => {\n setAttachments([]);\n }, []);\n\n const getFiles = useCallback(() => {\n return attachments.map((a) => a.file);\n }, [attachments]);\n\n return {\n attachments,\n addAttachment,\n removeAttachment,\n updateProgress,\n setError,\n setUrl,\n clear,\n getFiles,\n canAddMore: attachments.length < maxCount,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/use-streaming.ts","../src/hooks/use-attachments.ts"],"names":["useStreaming","options","state","setState","useState","abortControllerRef","useRef","startStreaming","useCallback","messageId","appendContent","chunk","prev","stopStreaming","finalContent","handleError","error","useAttachments","maxCount","maxFileSize","allowedTypes","attachments","setAttachments","addAttachment","file","id","removeAttachment","updateProgress","progress","a","setError","setUrl","url","clear","getFiles"],"mappings":"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","file":"chunk-3ERHTQXR.js","sourcesContent":["import { useState, useCallback, useRef } from \"react\";\nimport type { StreamingState, StreamChunk, StreamingOptions } from \"../types\";\n\n/**\n * Hook to manage streaming message state.\n */\nexport function useStreaming(options: StreamingOptions = {}) {\n const [state, setState] = useState<StreamingState>({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const startStreaming = useCallback((messageId: string) => {\n setState({\n isStreaming: true,\n streamingMessageId: messageId,\n streamedContent: \"\",\n });\n abortControllerRef.current = new AbortController();\n }, []);\n\n const appendContent = useCallback(\n (chunk: StreamChunk) => {\n if (chunk.type === \"content\" && chunk.content) {\n setState((prev) => ({\n ...prev,\n streamedContent: prev.streamedContent + chunk.content,\n }));\n }\n options.onChunk?.(chunk);\n },\n [options]\n );\n\n const stopStreaming = useCallback(() => {\n abortControllerRef.current?.abort();\n const finalContent = state.streamedContent;\n\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n options.onComplete?.(finalContent);\n }, [state.streamedContent, options]);\n\n const handleError = useCallback(\n (error: Error) => {\n abortControllerRef.current?.abort();\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n options.onError?.(error);\n },\n [options]\n );\n\n return {\n ...state,\n startStreaming,\n appendContent,\n stopStreaming,\n handleError,\n abortSignal: abortControllerRef.current?.signal,\n };\n}\n","import { useState, useCallback } from \"react\";\n\ninterface AttachmentState {\n file: File;\n id: string;\n progress: number;\n status: \"pending\" | \"uploading\" | \"complete\" | \"error\";\n error?: string;\n url?: string;\n}\n\ninterface UseAttachmentsOptions {\n /** Maximum number of attachments */\n maxCount?: number;\n /** Maximum file size in bytes */\n maxFileSize?: number;\n /** Allowed MIME types */\n allowedTypes?: string[];\n}\n\n/**\n * Hook to manage file attachments with upload progress.\n */\nexport function useAttachments({\n maxCount = 5,\n maxFileSize = 10 * 1024 * 1024,\n allowedTypes,\n}: UseAttachmentsOptions = {}) {\n const [attachments, setAttachments] = useState<AttachmentState[]>([]);\n\n const addAttachment = useCallback(\n (file: File): { success: boolean; error?: string } => {\n // Check count\n if (attachments.length >= maxCount) {\n return { success: false, error: `Maximum ${maxCount} attachments allowed` };\n }\n\n // Check size\n if (file.size > maxFileSize) {\n return {\n success: false,\n error: `File size exceeds ${Math.round(maxFileSize / 1024 / 1024)}MB limit`,\n };\n }\n\n // Check type\n if (allowedTypes && !allowedTypes.includes(file.type)) {\n return { success: false, error: `File type ${file.type} not allowed` };\n }\n\n const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n setAttachments((prev) => [\n ...prev,\n {\n file,\n id,\n progress: 0,\n status: \"pending\",\n },\n ]);\n\n return { success: true };\n },\n [attachments.length, maxCount, maxFileSize, allowedTypes]\n );\n\n const removeAttachment = useCallback((id: string) => {\n setAttachments((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const updateProgress = useCallback((id: string, progress: number) => {\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === id\n ? { ...a, progress, status: progress < 100 ? \"uploading\" : \"complete\" }\n : a\n )\n );\n }, []);\n\n const setError = useCallback((id: string, error: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, status: \"error\", error } : a))\n );\n }, []);\n\n const setUrl = useCallback((id: string, url: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, url, status: \"complete\", progress: 100 } : a))\n );\n }, []);\n\n const clear = useCallback(() => {\n setAttachments([]);\n }, []);\n\n const getFiles = useCallback(() => {\n return attachments.map((a) => a.file);\n }, [attachments]);\n\n return {\n attachments,\n addAttachment,\n removeAttachment,\n updateProgress,\n setError,\n setUrl,\n clear,\n getFiles,\n canAddMore: attachments.length < maxCount,\n };\n}\n"]}
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkLJQHWCUK_js=require('./chunk-LJQHWCUK.js'),react=require('react'),jsxRuntime=require('react/jsx-runtime');var m=react.createContext(null);function d(){let e=react.useContext(m);if(!e)throw new Error("useMessage must be used within a Message component");return e}var v=react.forwardRef(({message:e,viewerRole:t="user",children:s,...o},r)=>{let n=(e.participant?.role||"").toLowerCase()===(t||"").toLowerCase(),i=e.isStreaming??false;return jsxRuntime.jsx(m.Provider,{value:{message:e,isViewer:n,isStreaming:i},children:jsxRuntime.jsx("div",{ref:r,"data-role":e.participant?.role,"data-viewer":n,"data-streaming":i,...o,children:s})})});v.displayName="Message";var S=react.forwardRef(({children:e,...t},s)=>{let{message:o}=d();return jsxRuntime.jsx("div",{ref:s,...t,children:e??o.textContent})});S.displayName="MessageContent";var L=react.forwardRef(({format:e,...t},s)=>{let{message:o}=d(),r=typeof o.createdAt=="string"?new Date(o.createdAt):o.createdAt,n=e?e(r):r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:true});return jsxRuntime.jsx("span",{ref:s,...t,children:n})});L.displayName="MessageTimestamp";var h=react.forwardRef(({children:e,autoScroll:t=true,scrollThreshold:s=100,...o},r)=>{let{containerRef:n,scrollToBottom:i}=chunkLJQHWCUK_js.a({enabled:t,threshold:s});return jsxRuntime.jsx("div",{ref:p=>{n.current=p,typeof r=="function"?r(p):r&&(r.current=p);},"data-scroll-to-bottom":i,...o,children:e})});h.displayName="MessageList";var f=react.createContext(null);function M(){let e=react.useContext(f);if(!e)throw new Error("useComposer must be used within a MessageComposer component");return e}var P=react.forwardRef(({onSubmit:e,disabled:t=false,children:s,className:o},r)=>{let n=chunkLJQHWCUK_js.b({onSubmit:e,disabled:t}),i=p=>{p.preventDefault(),n.handleSubmit();},a={...n,canSubmit:!!n.canSubmit};return jsxRuntime.jsx(f.Provider,{value:a,children:jsxRuntime.jsx("form",{ref:r,className:o,onSubmit:i,"data-submitting":n.isSubmitting,"data-can-submit":n.canSubmit,children:s})})});P.displayName="MessageComposer";var H=react.forwardRef((e,t)=>{let{content:s,handleContentChange:o,handleKeyDown:r,inputRef:n}=M();return jsxRuntime.jsx("textarea",{ref:a=>{n.current=a,typeof t=="function"?t(a):t&&(t.current=a);},value:s,onChange:a=>o(a.target.value),onKeyDown:r,...e})});H.displayName="ComposerInput";var R=react.forwardRef(({children:e,disabled:t,...s},o)=>{let{canSubmit:r,isSubmitting:n}=M();return jsxRuntime.jsx("button",{ref:o,type:"submit",disabled:t||!r,"data-submitting":n,...s,children:e})});R.displayName="ComposerSubmit";function q(e){let t=e.trim().split(/\s+/);return t.length===1?t[0].charAt(0).toUpperCase():(t[0].charAt(0)+t[t.length-1].charAt(0)).toUpperCase()}var E=react.forwardRef(({name:e,src:t,alt:s,role:o,fallback:r,children:n,...i},a)=>{let p=e?q(e):null;return jsxRuntime.jsx("div",{ref:a,"data-role":o,...i,children:n??jsxRuntime.jsx(jsxRuntime.Fragment,{children:t?jsxRuntime.jsx("img",{src:t,alt:s??e??o??"Avatar",style:{width:"100%",height:"100%"}}):r??p??o?.charAt(0).toUpperCase()})})});E.displayName="Avatar";var N=react.forwardRef(({content:e,isStreaming:t=false,showCursor:s=true,cursor:o,children:r,...n},i)=>jsxRuntime.jsxs("div",{ref:i,"data-streaming":t,...n,children:[r??e,t&&s&&(o??jsxRuntime.jsx("span",{"aria-hidden":"true",style:{display:"inline-block",width:"2px",height:"1em",backgroundColor:"currentColor",marginLeft:"2px",verticalAlign:"text-bottom",animation:"blink 1s step-end infinite"}}))]}));N.displayName="StreamingText";var C=react.createContext(null);function D(){let e=react.useContext(C);if(!e)throw new Error("useSuggestedActions must be used within a SuggestedActions component");return e}var B=react.forwardRef(({actions:e,onSelect:t,children:s,className:o},r)=>e.length===0?null:jsxRuntime.jsx(C.Provider,{value:{actions:e,onSelect:t},children:jsxRuntime.jsx("div",{ref:r,role:"group","aria-label":"Suggested actions",className:o,children:s})}));B.displayName="SuggestedActions";var I=react.forwardRef(({action:e,children:t,onClick:s,...o},r)=>{let{onSelect:n}=D();return jsxRuntime.jsx("button",{ref:r,type:"button",onClick:a=>{s?.(a),a.defaultPrevented||n(e);},...o,children:t??e.label})});I.displayName="ActionButton";var k=react.forwardRef(({children:e,dotCount:t=3,...s},o)=>jsxRuntime.jsx("div",{ref:o,role:"status","aria-label":"Assistant is typing",...s,children:e??jsxRuntime.jsx("span",{"aria-hidden":"true",children:Array.from({length:t}).map((r,n)=>jsxRuntime.jsx("span",{style:{display:"inline-block",width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"currentColor",marginRight:n<t-1?"4px":0,animation:"typing 1.4s infinite ease-in-out",animationDelay:`${n*.2}s`}},n))})}));k.displayName="TypingIndicator";exports.a=m;exports.b=d;exports.c=v;exports.d=S;exports.e=L;exports.f=h;exports.g=f;exports.h=M;exports.i=P;exports.j=H;exports.k=R;exports.l=E;exports.m=N;exports.n=C;exports.o=D;exports.p=B;exports.q=I;exports.r=k;//# sourceMappingURL=chunk-3KB4JYSQ.js.map
1
+ import {a,b}from'./chunk-LJQHWCUK.js';import {createContext,forwardRef,useContext}from'react';import {jsx,Fragment,jsxs}from'react/jsx-runtime';var m=createContext(null);function d(){let e=useContext(m);if(!e)throw new Error("useMessage must be used within a Message component");return e}var v=forwardRef(({message:e,viewerRole:t="user",children:s,...o},r)=>{let n=(e.participant?.role||"").toLowerCase()===(t||"").toLowerCase(),i=e.isStreaming??false;return jsx(m.Provider,{value:{message:e,isViewer:n,isStreaming:i},children:jsx("div",{ref:r,"data-role":e.participant?.role,"data-viewer":n,"data-streaming":i,...o,children:s})})});v.displayName="Message";var S=forwardRef(({children:e,...t},s)=>{let{message:o}=d();return jsx("div",{ref:s,...t,children:e??o.textContent})});S.displayName="MessageContent";var L=forwardRef(({format:e,...t},s)=>{let{message:o}=d(),r=typeof o.createdAt=="string"?new Date(o.createdAt):o.createdAt,n=e?e(r):r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:true});return jsx("span",{ref:s,...t,children:n})});L.displayName="MessageTimestamp";var h=forwardRef(({children:e,autoScroll:t=true,scrollThreshold:s=100,...o},r)=>{let{containerRef:n,scrollToBottom:i}=a({enabled:t,threshold:s});return jsx("div",{ref:p=>{n.current=p,typeof r=="function"?r(p):r&&(r.current=p);},"data-scroll-to-bottom":i,...o,children:e})});h.displayName="MessageList";var f=createContext(null);function M(){let e=useContext(f);if(!e)throw new Error("useComposer must be used within a MessageComposer component");return e}var P=forwardRef(({onSubmit:e,disabled:t=false,children:s,className:o},r)=>{let n=b({onSubmit:e,disabled:t}),i=p=>{p.preventDefault(),n.handleSubmit();},a={...n,canSubmit:!!n.canSubmit};return jsx(f.Provider,{value:a,children:jsx("form",{ref:r,className:o,onSubmit:i,"data-submitting":n.isSubmitting,"data-can-submit":n.canSubmit,children:s})})});P.displayName="MessageComposer";var H=forwardRef((e,t)=>{let{content:s,handleContentChange:o,handleKeyDown:r,inputRef:n}=M();return jsx("textarea",{ref:a=>{n.current=a,typeof t=="function"?t(a):t&&(t.current=a);},value:s,onChange:a=>o(a.target.value),onKeyDown:r,...e})});H.displayName="ComposerInput";var R=forwardRef(({children:e,disabled:t,...s},o)=>{let{canSubmit:r,isSubmitting:n}=M();return jsx("button",{ref:o,type:"submit",disabled:t||!r,"data-submitting":n,...s,children:e})});R.displayName="ComposerSubmit";function q(e){let t=e.trim().split(/\s+/);return t.length===1?t[0].charAt(0).toUpperCase():(t[0].charAt(0)+t[t.length-1].charAt(0)).toUpperCase()}var E=forwardRef(({name:e,src:t,alt:s,role:o,fallback:r,children:n,...i},a)=>{let p=e?q(e):null;return jsx("div",{ref:a,"data-role":o,...i,children:n??jsx(Fragment,{children:t?jsx("img",{src:t,alt:s??e??o??"Avatar",style:{width:"100%",height:"100%"}}):r??p??o?.charAt(0).toUpperCase()})})});E.displayName="Avatar";var N=forwardRef(({content:e,isStreaming:t=false,showCursor:s=true,cursor:o,children:r,...n},i)=>jsxs("div",{ref:i,"data-streaming":t,...n,children:[r??e,t&&s&&(o??jsx("span",{"aria-hidden":"true",style:{display:"inline-block",width:"2px",height:"1em",backgroundColor:"currentColor",marginLeft:"2px",verticalAlign:"text-bottom",animation:"blink 1s step-end infinite"}}))]}));N.displayName="StreamingText";var C=createContext(null);function D(){let e=useContext(C);if(!e)throw new Error("useSuggestedActions must be used within a SuggestedActions component");return e}var B=forwardRef(({actions:e,onSelect:t,children:s,className:o},r)=>e.length===0?null:jsx(C.Provider,{value:{actions:e,onSelect:t},children:jsx("div",{ref:r,role:"group","aria-label":"Suggested actions",className:o,children:s})}));B.displayName="SuggestedActions";var I=forwardRef(({action:e,children:t,onClick:s,...o},r)=>{let{onSelect:n}=D();return jsx("button",{ref:r,type:"button",onClick:a=>{s?.(a),a.defaultPrevented||n(e);},...o,children:t??e.label})});I.displayName="ActionButton";var k=forwardRef(({children:e,dotCount:t=3,...s},o)=>jsx("div",{ref:o,role:"status","aria-label":"Assistant is typing",...s,children:e??jsx("span",{"aria-hidden":"true",children:Array.from({length:t}).map((r,n)=>jsx("span",{style:{display:"inline-block",width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"currentColor",marginRight:n<t-1?"4px":0,animation:"typing 1.4s infinite ease-in-out",animationDelay:`${n*.2}s`}},n))})}));k.displayName="TypingIndicator";export{m as a,d as b,v as c,S as d,L as e,h as f,f as g,M as h,P as i,H as j,R as k,E as l,N as m,C as n,D as o,B as p,I as q,k as r};//# sourceMappingURL=chunk-3KB4JYSQ.js.map
2
2
  //# sourceMappingURL=chunk-3KB4JYSQ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/primitives/message.tsx","../src/primitives/message-list.tsx","../src/primitives/message-composer.tsx","../src/primitives/avatar.tsx","../src/primitives/streaming-text.tsx","../src/primitives/suggested-actions.tsx","../src/primitives/typing-indicator.tsx"],"names":["MessageContext","createContext","useMessage","context","useContext","Message","forwardRef","message","viewerRole","children","props","ref","isViewer","isStreaming","jsx","MessageContent","MessageTimestamp","format","date","formatted","MessageList","autoScroll","scrollThreshold","containerRef","scrollToBottom","useAutoScroll","node","ComposerContext","useComposer","MessageComposer","onSubmit","disabled","className","composer","useMessageComposer","handleFormSubmit","e","contextValue","ComposerInput","content","handleContentChange","handleKeyDown","inputRef","ComposerSubmit","canSubmit","isSubmitting","getInitials","name","parts","Avatar","src","alt","role","fallback","initials","Fragment","StreamingText","showCursor","cursor","jsxs","SuggestedActionsContext","useSuggestedActions","SuggestedActions","actions","onSelect","ActionButton","action","onClick","TypingIndicator","dotCount","_","i"],"mappings":"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","file":"chunk-3KB4JYSQ.js","sourcesContent":["import { createContext, forwardRef, useContext, type HTMLAttributes, type ReactNode } from \"react\";\nimport type { MessageData, ParticipantRole } from \"../types\";\n\ninterface MessageContextValue {\n\tmessage: MessageData;\n\tisViewer: boolean;\n\tisStreaming: boolean;\n}\n\nconst MessageContext = createContext<MessageContextValue | null>(null);\n\n/**\n * Hook to access the current message context.\n * Must be used within a Message component.\n */\nexport function useMessage() {\n\tconst context = useContext(MessageContext);\n\tif (!context) {\n\t\tthrow new Error(\"useMessage must be used within a Message component\");\n\t}\n\treturn context;\n}\n\nexport interface MessageProps extends HTMLAttributes<HTMLDivElement> {\n\t/** The message data */\n\tmessage: MessageData;\n\t/** The viewer's role (used to determine alignment) */\n\tviewerRole?: ParticipantRole;\n\t/** Children to render inside the message */\n\tchildren: ReactNode;\n}\n\n/**\n * Headless Message primitive.\n * Provides message context to children and data attributes for styling.\n */\nexport const Message = forwardRef<HTMLDivElement, MessageProps>(\n\t({ message, viewerRole = \"user\", children, ...props }, ref) => {\n\t\t// Case-insensitive comparison for role matching\n\t\tconst isViewer = (message.participant?.role || \"\").toLowerCase() === (viewerRole || \"\").toLowerCase();\n\t\tconst isStreaming = message.isStreaming ?? false;\n\n\t\treturn (\n\t\t\t<MessageContext.Provider value={{ message, isViewer, isStreaming }}>\n\t\t\t\t<div\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdata-role={message.participant?.role}\n\t\t\t\t\tdata-viewer={isViewer}\n\t\t\t\t\tdata-streaming={isStreaming}\n\t\t\t\t\t{...props}>\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</MessageContext.Provider>\n\t\t);\n\t},\n);\n\nMessage.displayName = \"Message\";\n\nexport interface MessageContentProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Custom content to render instead of message text */\n\tchildren?: ReactNode;\n}\n\n/**\n * Renders the message content.\n * By default renders the message's textContent.\n */\nexport const MessageContent = forwardRef<HTMLDivElement, MessageContentProps>(({ children, ...props }, ref) => {\n\tconst { message } = useMessage();\n\n\treturn (\n\t\t<div ref={ref} {...props}>\n\t\t\t{children ?? message.textContent}\n\t\t</div>\n\t);\n});\n\nMessageContent.displayName = \"MessageContent\";\n\nexport interface MessageTimestampProps extends HTMLAttributes<HTMLSpanElement> {\n\t/** Custom date formatter */\n\tformat?: (date: Date) => string;\n}\n\n/**\n * Renders the message timestamp.\n */\nexport const MessageTimestamp = forwardRef<HTMLSpanElement, MessageTimestampProps>(({ format, ...props }, ref) => {\n\tconst { message } = useMessage();\n\tconst date = typeof message.createdAt === \"string\" ? new Date(message.createdAt) : message.createdAt;\n\n\tconst formatted = format\n\t\t? format(date)\n\t\t: date.toLocaleTimeString(\"en-US\", {\n\t\t\t\thour: \"numeric\",\n\t\t\t\tminute: \"2-digit\",\n\t\t\t\thour12: true,\n\t\t\t});\n\n\treturn (\n\t\t<span ref={ref} {...props}>\n\t\t\t{formatted}\n\t\t</span>\n\t);\n});\n\nMessageTimestamp.displayName = \"MessageTimestamp\";\n\nexport { MessageContext };\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport { useAutoScroll } from \"../hooks/use-auto-scroll\";\n\nexport interface MessageListProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Messages to render */\n\tchildren: ReactNode;\n\t/** Whether to auto-scroll to bottom on new messages */\n\tautoScroll?: boolean;\n\t/** Threshold from bottom to trigger auto-scroll (pixels) */\n\tscrollThreshold?: number;\n}\n\n/**\n * Headless MessageList primitive.\n * Provides a scrollable container with auto-scroll behavior.\n */\nexport const MessageList = forwardRef<HTMLDivElement, MessageListProps>(\n\t({ children, autoScroll = true, scrollThreshold = 100, ...props }, ref) => {\n\t\tconst { containerRef, scrollToBottom } = useAutoScroll<HTMLDivElement>({\n\t\t\tenabled: autoScroll,\n\t\t\tthreshold: scrollThreshold,\n\t\t});\n\n\t\t// Merge refs\n\t\tconst mergedRef = (node: HTMLDivElement | null) => {\n\t\t\t(containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n\t\t\tif (typeof ref === \"function\") {\n\t\t\t\tref(node);\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = node;\n\t\t\t}\n\t\t};\n\n\t\treturn (\n\t\t\t<div ref={mergedRef} data-scroll-to-bottom={scrollToBottom} {...props}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nMessageList.displayName = \"MessageList\";\n","import {\n createContext,\n useContext,\n forwardRef,\n type ReactNode,\n type TextareaHTMLAttributes,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport { useMessageComposer } from \"../hooks/use-message-composer\";\n\ninterface ComposerContextValue {\n content: string;\n isSubmitting: boolean;\n canSubmit: boolean;\n error: string | null;\n handleContentChange: (value: string) => void;\n handleSubmit: () => Promise<void>;\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\n inputRef: React.RefObject<HTMLTextAreaElement | null>;\n}\n\nconst ComposerContext = createContext<ComposerContextValue | null>(null);\n\n/**\n * Hook to access the composer context.\n * Must be used within a MessageComposer component.\n */\nexport function useComposer() {\n const context = useContext(ComposerContext);\n if (!context) {\n throw new Error(\"useComposer must be used within a MessageComposer component\");\n }\n return context;\n}\n\nexport interface MessageComposerProps {\n /** Callback when message is submitted */\n onSubmit: (content: string, attachments?: File[]) => Promise<void>;\n /** Whether the composer is disabled */\n disabled?: boolean;\n /** Children to render inside the composer */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Headless MessageComposer primitive.\n * Provides composer state and behavior to children.\n */\nexport const MessageComposer = forwardRef<HTMLFormElement, MessageComposerProps>(\n ({ onSubmit, disabled = false, children, className }, ref) => {\n const composer = useMessageComposer({ onSubmit, disabled });\n\n const handleFormSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n composer.handleSubmit();\n };\n\n const contextValue: ComposerContextValue = {\n ...composer,\n canSubmit: Boolean(composer.canSubmit),\n };\n\n return (\n <ComposerContext.Provider value={contextValue}>\n <form\n ref={ref}\n className={className}\n onSubmit={handleFormSubmit}\n data-submitting={composer.isSubmitting}\n data-can-submit={composer.canSubmit}\n >\n {children}\n </form>\n </ComposerContext.Provider>\n );\n }\n);\n\nMessageComposer.displayName = \"MessageComposer\";\n\nexport interface ComposerInputProps\n extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, \"onChange\" | \"value\"> {}\n\n/**\n * Text input for the message composer.\n */\nexport const ComposerInput = forwardRef<HTMLTextAreaElement, ComposerInputProps>(\n (props, ref) => {\n const { content, handleContentChange, handleKeyDown, inputRef } = useComposer();\n\n // Merge refs\n const mergedRef = (node: HTMLTextAreaElement | null) => {\n (inputRef as React.MutableRefObject<HTMLTextAreaElement | null>).current = node;\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n };\n\n return (\n <textarea\n ref={mergedRef}\n value={content}\n onChange={(e) => handleContentChange(e.target.value)}\n onKeyDown={handleKeyDown}\n {...props}\n />\n );\n }\n);\n\nComposerInput.displayName = \"ComposerInput\";\n\nexport interface ComposerSubmitProps extends ButtonHTMLAttributes<HTMLButtonElement> {}\n\n/**\n * Submit button for the message composer.\n */\nexport const ComposerSubmit = forwardRef<HTMLButtonElement, ComposerSubmitProps>(\n ({ children, disabled, ...props }, ref) => {\n const { canSubmit, isSubmitting } = useComposer();\n\n return (\n <button\n ref={ref}\n type=\"submit\"\n disabled={disabled || !canSubmit}\n data-submitting={isSubmitting}\n {...props}\n >\n {children}\n </button>\n );\n }\n);\n\nComposerSubmit.displayName = \"ComposerSubmit\";\n\nexport { ComposerContext };\n","import { forwardRef, type HTMLAttributes } from \"react\";\nimport type { ParticipantRole } from \"../types\";\n\nexport interface AvatarProps extends HTMLAttributes<HTMLDivElement> {\n /** Name for fallback initials */\n name?: string;\n /** Image URL */\n src?: string;\n /** Alt text for image */\n alt?: string;\n /** Participant role for styling */\n role?: ParticipantRole;\n /** Fallback content when no image or name */\n fallback?: React.ReactNode;\n}\n\n/**\n * Get initials from a name.\n */\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length === 1) {\n return parts[0].charAt(0).toUpperCase();\n }\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();\n}\n\n/**\n * Headless Avatar primitive.\n * Renders an image or fallback initials.\n */\nexport const Avatar = forwardRef<HTMLDivElement, AvatarProps>(\n ({ name, src, alt, role, fallback, children, ...props }, ref) => {\n const initials = name ? getInitials(name) : null;\n const altText = alt ?? name ?? role ?? \"Avatar\";\n\n return (\n <div ref={ref} data-role={role} {...props}>\n {children ?? (\n <>\n {src ? (\n <img src={src} alt={altText} style={{ width: \"100%\", height: \"100%\" }} />\n ) : (\n fallback ?? initials ?? role?.charAt(0).toUpperCase()\n )}\n </>\n )}\n </div>\n );\n }\n);\n\nAvatar.displayName = \"Avatar\";\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface StreamingTextProps extends HTMLAttributes<HTMLDivElement> {\n /** The content to display */\n content: string;\n /** Whether the text is currently streaming */\n isStreaming?: boolean;\n /** Show a cursor indicator while streaming */\n showCursor?: boolean;\n /** Custom cursor element */\n cursor?: ReactNode;\n /** Children override (takes precedence over content) */\n children?: ReactNode;\n}\n\n/**\n * Headless StreamingText primitive.\n * Renders text with streaming indicator support.\n */\nexport const StreamingText = forwardRef<HTMLDivElement, StreamingTextProps>(\n (\n { content, isStreaming = false, showCursor = true, cursor, children, ...props },\n ref\n ) => {\n const defaultCursor = (\n <span\n aria-hidden=\"true\"\n style={{\n display: \"inline-block\",\n width: \"2px\",\n height: \"1em\",\n backgroundColor: \"currentColor\",\n marginLeft: \"2px\",\n verticalAlign: \"text-bottom\",\n animation: \"blink 1s step-end infinite\",\n }}\n />\n );\n\n return (\n <div ref={ref} data-streaming={isStreaming} {...props}>\n {children ?? content}\n {isStreaming && showCursor && (cursor ?? defaultCursor)}\n </div>\n );\n }\n);\n\nStreamingText.displayName = \"StreamingText\";\n","import {\n createContext,\n useContext,\n forwardRef,\n type ReactNode,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport type { SuggestedAction } from \"../types\";\n\ninterface SuggestedActionsContextValue {\n actions: SuggestedAction[];\n onSelect: (action: SuggestedAction) => void;\n}\n\nconst SuggestedActionsContext = createContext<SuggestedActionsContextValue | null>(null);\n\n/**\n * Hook to access suggested actions context.\n */\nexport function useSuggestedActions() {\n const context = useContext(SuggestedActionsContext);\n if (!context) {\n throw new Error(\n \"useSuggestedActions must be used within a SuggestedActions component\"\n );\n }\n return context;\n}\n\nexport interface SuggestedActionsProps {\n /** List of suggested actions */\n actions: SuggestedAction[];\n /** Callback when an action is selected */\n onSelect: (action: SuggestedAction) => void;\n /** Children to render */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Headless SuggestedActions primitive.\n * Provides context for rendering action buttons.\n */\nexport const SuggestedActions = forwardRef<HTMLDivElement, SuggestedActionsProps>(\n ({ actions, onSelect, children, className }, ref) => {\n if (actions.length === 0) {\n return null;\n }\n\n return (\n <SuggestedActionsContext.Provider value={{ actions, onSelect }}>\n <div ref={ref} role=\"group\" aria-label=\"Suggested actions\" className={className}>\n {children}\n </div>\n </SuggestedActionsContext.Provider>\n );\n }\n);\n\nSuggestedActions.displayName = \"SuggestedActions\";\n\nexport interface ActionButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** The action this button represents */\n action: SuggestedAction;\n /** Children to render inside button */\n children?: ReactNode;\n}\n\n/**\n * Button for a suggested action.\n */\nexport const ActionButton = forwardRef<HTMLButtonElement, ActionButtonProps>(\n ({ action, children, onClick, ...props }, ref) => {\n const { onSelect } = useSuggestedActions();\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) {\n onSelect(action);\n }\n };\n\n return (\n <button ref={ref} type=\"button\" onClick={handleClick} {...props}>\n {children ?? action.label}\n </button>\n );\n }\n);\n\nActionButton.displayName = \"ActionButton\";\n\nexport { SuggestedActionsContext };\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface TypingIndicatorProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom content to show while typing */\n children?: ReactNode;\n /** Number of dots to show */\n dotCount?: number;\n}\n\n/**\n * Headless TypingIndicator primitive.\n * Shows animated dots or custom content.\n */\nexport const TypingIndicator = forwardRef<HTMLDivElement, TypingIndicatorProps>(\n ({ children, dotCount = 3, ...props }, ref) => {\n return (\n <div ref={ref} role=\"status\" aria-label=\"Assistant is typing\" {...props}>\n {children ?? (\n <span aria-hidden=\"true\">\n {Array.from({ length: dotCount }).map((_, i) => (\n <span\n key={i}\n style={{\n display: \"inline-block\",\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: \"currentColor\",\n marginRight: i < dotCount - 1 ? \"4px\" : 0,\n animation: `typing 1.4s infinite ease-in-out`,\n animationDelay: `${i * 0.2}s`,\n }}\n />\n ))}\n </span>\n )}\n </div>\n );\n }\n);\n\nTypingIndicator.displayName = \"TypingIndicator\";\n"]}
1
+ {"version":3,"sources":["../src/primitives/message.tsx","../src/primitives/message-list.tsx","../src/primitives/message-composer.tsx","../src/primitives/avatar.tsx","../src/primitives/streaming-text.tsx","../src/primitives/suggested-actions.tsx","../src/primitives/typing-indicator.tsx"],"names":["MessageContext","createContext","useMessage","context","useContext","Message","forwardRef","message","viewerRole","children","props","ref","isViewer","isStreaming","jsx","MessageContent","MessageTimestamp","format","date","formatted","MessageList","autoScroll","scrollThreshold","containerRef","scrollToBottom","useAutoScroll","node","ComposerContext","useComposer","MessageComposer","onSubmit","disabled","className","composer","useMessageComposer","handleFormSubmit","e","contextValue","ComposerInput","content","handleContentChange","handleKeyDown","inputRef","ComposerSubmit","canSubmit","isSubmitting","getInitials","name","parts","Avatar","src","alt","role","fallback","initials","Fragment","StreamingText","showCursor","cursor","jsxs","SuggestedActionsContext","useSuggestedActions","SuggestedActions","actions","onSelect","ActionButton","action","onClick","TypingIndicator","dotCount","_","i"],"mappings":"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","file":"chunk-3KB4JYSQ.js","sourcesContent":["import { createContext, forwardRef, useContext, type HTMLAttributes, type ReactNode } from \"react\";\nimport type { MessageData, ParticipantRole } from \"../types\";\n\ninterface MessageContextValue {\n\tmessage: MessageData;\n\tisViewer: boolean;\n\tisStreaming: boolean;\n}\n\nconst MessageContext = createContext<MessageContextValue | null>(null);\n\n/**\n * Hook to access the current message context.\n * Must be used within a Message component.\n */\nexport function useMessage() {\n\tconst context = useContext(MessageContext);\n\tif (!context) {\n\t\tthrow new Error(\"useMessage must be used within a Message component\");\n\t}\n\treturn context;\n}\n\nexport interface MessageProps extends HTMLAttributes<HTMLDivElement> {\n\t/** The message data */\n\tmessage: MessageData;\n\t/** The viewer's role (used to determine alignment) */\n\tviewerRole?: ParticipantRole;\n\t/** Children to render inside the message */\n\tchildren: ReactNode;\n}\n\n/**\n * Headless Message primitive.\n * Provides message context to children and data attributes for styling.\n */\nexport const Message = forwardRef<HTMLDivElement, MessageProps>(\n\t({ message, viewerRole = \"user\", children, ...props }, ref) => {\n\t\t// Case-insensitive comparison for role matching\n\t\tconst isViewer = (message.participant?.role || \"\").toLowerCase() === (viewerRole || \"\").toLowerCase();\n\t\tconst isStreaming = message.isStreaming ?? false;\n\n\t\treturn (\n\t\t\t<MessageContext.Provider value={{ message, isViewer, isStreaming }}>\n\t\t\t\t<div\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdata-role={message.participant?.role}\n\t\t\t\t\tdata-viewer={isViewer}\n\t\t\t\t\tdata-streaming={isStreaming}\n\t\t\t\t\t{...props}>\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</MessageContext.Provider>\n\t\t);\n\t},\n);\n\nMessage.displayName = \"Message\";\n\nexport interface MessageContentProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Custom content to render instead of message text */\n\tchildren?: ReactNode;\n}\n\n/**\n * Renders the message content.\n * By default renders the message's textContent.\n */\nexport const MessageContent = forwardRef<HTMLDivElement, MessageContentProps>(({ children, ...props }, ref) => {\n\tconst { message } = useMessage();\n\n\treturn (\n\t\t<div ref={ref} {...props}>\n\t\t\t{children ?? message.textContent}\n\t\t</div>\n\t);\n});\n\nMessageContent.displayName = \"MessageContent\";\n\nexport interface MessageTimestampProps extends HTMLAttributes<HTMLSpanElement> {\n\t/** Custom date formatter */\n\tformat?: (date: Date) => string;\n}\n\n/**\n * Renders the message timestamp.\n */\nexport const MessageTimestamp = forwardRef<HTMLSpanElement, MessageTimestampProps>(({ format, ...props }, ref) => {\n\tconst { message } = useMessage();\n\tconst date = typeof message.createdAt === \"string\" ? new Date(message.createdAt) : message.createdAt;\n\n\tconst formatted = format\n\t\t? format(date)\n\t\t: date.toLocaleTimeString(\"en-US\", {\n\t\t\t\thour: \"numeric\",\n\t\t\t\tminute: \"2-digit\",\n\t\t\t\thour12: true,\n\t\t\t});\n\n\treturn (\n\t\t<span ref={ref} {...props}>\n\t\t\t{formatted}\n\t\t</span>\n\t);\n});\n\nMessageTimestamp.displayName = \"MessageTimestamp\";\n\nexport { MessageContext };\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport { useAutoScroll } from \"../hooks/use-auto-scroll\";\n\nexport interface MessageListProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Messages to render */\n\tchildren: ReactNode;\n\t/** Whether to auto-scroll to bottom on new messages */\n\tautoScroll?: boolean;\n\t/** Threshold from bottom to trigger auto-scroll (pixels) */\n\tscrollThreshold?: number;\n}\n\n/**\n * Headless MessageList primitive.\n * Provides a scrollable container with auto-scroll behavior.\n */\nexport const MessageList = forwardRef<HTMLDivElement, MessageListProps>(\n\t({ children, autoScroll = true, scrollThreshold = 100, ...props }, ref) => {\n\t\tconst { containerRef, scrollToBottom } = useAutoScroll<HTMLDivElement>({\n\t\t\tenabled: autoScroll,\n\t\t\tthreshold: scrollThreshold,\n\t\t});\n\n\t\t// Merge refs\n\t\tconst mergedRef = (node: HTMLDivElement | null) => {\n\t\t\t(containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n\t\t\tif (typeof ref === \"function\") {\n\t\t\t\tref(node);\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = node;\n\t\t\t}\n\t\t};\n\n\t\treturn (\n\t\t\t<div ref={mergedRef} data-scroll-to-bottom={scrollToBottom} {...props}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nMessageList.displayName = \"MessageList\";\n","import {\n createContext,\n useContext,\n forwardRef,\n type ReactNode,\n type TextareaHTMLAttributes,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport { useMessageComposer } from \"../hooks/use-message-composer\";\n\ninterface ComposerContextValue {\n content: string;\n isSubmitting: boolean;\n canSubmit: boolean;\n error: string | null;\n handleContentChange: (value: string) => void;\n handleSubmit: () => Promise<void>;\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\n inputRef: React.RefObject<HTMLTextAreaElement | null>;\n}\n\nconst ComposerContext = createContext<ComposerContextValue | null>(null);\n\n/**\n * Hook to access the composer context.\n * Must be used within a MessageComposer component.\n */\nexport function useComposer() {\n const context = useContext(ComposerContext);\n if (!context) {\n throw new Error(\"useComposer must be used within a MessageComposer component\");\n }\n return context;\n}\n\nexport interface MessageComposerProps {\n /** Callback when message is submitted */\n onSubmit: (content: string, attachments?: File[]) => Promise<void>;\n /** Whether the composer is disabled */\n disabled?: boolean;\n /** Children to render inside the composer */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Headless MessageComposer primitive.\n * Provides composer state and behavior to children.\n */\nexport const MessageComposer = forwardRef<HTMLFormElement, MessageComposerProps>(\n ({ onSubmit, disabled = false, children, className }, ref) => {\n const composer = useMessageComposer({ onSubmit, disabled });\n\n const handleFormSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n composer.handleSubmit();\n };\n\n const contextValue: ComposerContextValue = {\n ...composer,\n canSubmit: Boolean(composer.canSubmit),\n };\n\n return (\n <ComposerContext.Provider value={contextValue}>\n <form\n ref={ref}\n className={className}\n onSubmit={handleFormSubmit}\n data-submitting={composer.isSubmitting}\n data-can-submit={composer.canSubmit}\n >\n {children}\n </form>\n </ComposerContext.Provider>\n );\n }\n);\n\nMessageComposer.displayName = \"MessageComposer\";\n\nexport interface ComposerInputProps\n extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, \"onChange\" | \"value\"> {}\n\n/**\n * Text input for the message composer.\n */\nexport const ComposerInput = forwardRef<HTMLTextAreaElement, ComposerInputProps>(\n (props, ref) => {\n const { content, handleContentChange, handleKeyDown, inputRef } = useComposer();\n\n // Merge refs\n const mergedRef = (node: HTMLTextAreaElement | null) => {\n (inputRef as React.MutableRefObject<HTMLTextAreaElement | null>).current = node;\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n };\n\n return (\n <textarea\n ref={mergedRef}\n value={content}\n onChange={(e) => handleContentChange(e.target.value)}\n onKeyDown={handleKeyDown}\n {...props}\n />\n );\n }\n);\n\nComposerInput.displayName = \"ComposerInput\";\n\nexport interface ComposerSubmitProps extends ButtonHTMLAttributes<HTMLButtonElement> {}\n\n/**\n * Submit button for the message composer.\n */\nexport const ComposerSubmit = forwardRef<HTMLButtonElement, ComposerSubmitProps>(\n ({ children, disabled, ...props }, ref) => {\n const { canSubmit, isSubmitting } = useComposer();\n\n return (\n <button\n ref={ref}\n type=\"submit\"\n disabled={disabled || !canSubmit}\n data-submitting={isSubmitting}\n {...props}\n >\n {children}\n </button>\n );\n }\n);\n\nComposerSubmit.displayName = \"ComposerSubmit\";\n\nexport { ComposerContext };\n","import { forwardRef, type HTMLAttributes } from \"react\";\nimport type { ParticipantRole } from \"../types\";\n\nexport interface AvatarProps extends HTMLAttributes<HTMLDivElement> {\n /** Name for fallback initials */\n name?: string;\n /** Image URL */\n src?: string;\n /** Alt text for image */\n alt?: string;\n /** Participant role for styling */\n role?: ParticipantRole;\n /** Fallback content when no image or name */\n fallback?: React.ReactNode;\n}\n\n/**\n * Get initials from a name.\n */\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length === 1) {\n return parts[0].charAt(0).toUpperCase();\n }\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();\n}\n\n/**\n * Headless Avatar primitive.\n * Renders an image or fallback initials.\n */\nexport const Avatar = forwardRef<HTMLDivElement, AvatarProps>(\n ({ name, src, alt, role, fallback, children, ...props }, ref) => {\n const initials = name ? getInitials(name) : null;\n const altText = alt ?? name ?? role ?? \"Avatar\";\n\n return (\n <div ref={ref} data-role={role} {...props}>\n {children ?? (\n <>\n {src ? (\n <img src={src} alt={altText} style={{ width: \"100%\", height: \"100%\" }} />\n ) : (\n fallback ?? initials ?? role?.charAt(0).toUpperCase()\n )}\n </>\n )}\n </div>\n );\n }\n);\n\nAvatar.displayName = \"Avatar\";\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface StreamingTextProps extends HTMLAttributes<HTMLDivElement> {\n /** The content to display */\n content: string;\n /** Whether the text is currently streaming */\n isStreaming?: boolean;\n /** Show a cursor indicator while streaming */\n showCursor?: boolean;\n /** Custom cursor element */\n cursor?: ReactNode;\n /** Children override (takes precedence over content) */\n children?: ReactNode;\n}\n\n/**\n * Headless StreamingText primitive.\n * Renders text with streaming indicator support.\n */\nexport const StreamingText = forwardRef<HTMLDivElement, StreamingTextProps>(\n (\n { content, isStreaming = false, showCursor = true, cursor, children, ...props },\n ref\n ) => {\n const defaultCursor = (\n <span\n aria-hidden=\"true\"\n style={{\n display: \"inline-block\",\n width: \"2px\",\n height: \"1em\",\n backgroundColor: \"currentColor\",\n marginLeft: \"2px\",\n verticalAlign: \"text-bottom\",\n animation: \"blink 1s step-end infinite\",\n }}\n />\n );\n\n return (\n <div ref={ref} data-streaming={isStreaming} {...props}>\n {children ?? content}\n {isStreaming && showCursor && (cursor ?? defaultCursor)}\n </div>\n );\n }\n);\n\nStreamingText.displayName = \"StreamingText\";\n","import {\n createContext,\n useContext,\n forwardRef,\n type ReactNode,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport type { SuggestedAction } from \"../types\";\n\ninterface SuggestedActionsContextValue {\n actions: SuggestedAction[];\n onSelect: (action: SuggestedAction) => void;\n}\n\nconst SuggestedActionsContext = createContext<SuggestedActionsContextValue | null>(null);\n\n/**\n * Hook to access suggested actions context.\n */\nexport function useSuggestedActions() {\n const context = useContext(SuggestedActionsContext);\n if (!context) {\n throw new Error(\n \"useSuggestedActions must be used within a SuggestedActions component\"\n );\n }\n return context;\n}\n\nexport interface SuggestedActionsProps {\n /** List of suggested actions */\n actions: SuggestedAction[];\n /** Callback when an action is selected */\n onSelect: (action: SuggestedAction) => void;\n /** Children to render */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Headless SuggestedActions primitive.\n * Provides context for rendering action buttons.\n */\nexport const SuggestedActions = forwardRef<HTMLDivElement, SuggestedActionsProps>(\n ({ actions, onSelect, children, className }, ref) => {\n if (actions.length === 0) {\n return null;\n }\n\n return (\n <SuggestedActionsContext.Provider value={{ actions, onSelect }}>\n <div ref={ref} role=\"group\" aria-label=\"Suggested actions\" className={className}>\n {children}\n </div>\n </SuggestedActionsContext.Provider>\n );\n }\n);\n\nSuggestedActions.displayName = \"SuggestedActions\";\n\nexport interface ActionButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** The action this button represents */\n action: SuggestedAction;\n /** Children to render inside button */\n children?: ReactNode;\n}\n\n/**\n * Button for a suggested action.\n */\nexport const ActionButton = forwardRef<HTMLButtonElement, ActionButtonProps>(\n ({ action, children, onClick, ...props }, ref) => {\n const { onSelect } = useSuggestedActions();\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) {\n onSelect(action);\n }\n };\n\n return (\n <button ref={ref} type=\"button\" onClick={handleClick} {...props}>\n {children ?? action.label}\n </button>\n );\n }\n);\n\nActionButton.displayName = \"ActionButton\";\n\nexport { SuggestedActionsContext };\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface TypingIndicatorProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom content to show while typing */\n children?: ReactNode;\n /** Number of dots to show */\n dotCount?: number;\n}\n\n/**\n * Headless TypingIndicator primitive.\n * Shows animated dots or custom content.\n */\nexport const TypingIndicator = forwardRef<HTMLDivElement, TypingIndicatorProps>(\n ({ children, dotCount = 3, ...props }, ref) => {\n return (\n <div ref={ref} role=\"status\" aria-label=\"Assistant is typing\" {...props}>\n {children ?? (\n <span aria-hidden=\"true\">\n {Array.from({ length: dotCount }).map((_, i) => (\n <span\n key={i}\n style={{\n display: \"inline-block\",\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: \"currentColor\",\n marginRight: i < dotCount - 1 ? \"4px\" : 0,\n animation: `typing 1.4s infinite ease-in-out`,\n animationDelay: `${i * 0.2}s`,\n }}\n />\n ))}\n </span>\n )}\n </div>\n );\n }\n);\n\nTypingIndicator.displayName = \"TypingIndicator\";\n"]}