@reforma/components 0.2.2 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sources":["../../src/Composer/context.tsx"],"sourcesContent":["'use client';\n\nimport {\n coerceUploadMimeType,\n COMPOSER_PASTE_AS_FILE_MIN_CHARS,\n MAX_CHAT_ATTACHMENT_BYTES_PER_FILE,\n MAX_CHAT_ATTACHMENT_BYTES_TOTAL,\n} from '@reforma/constants';\nimport { createObjectURL, formatFileSize, revokeObjectURL } from '@reforma/lib';\nimport {\n createContext,\n use,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\n\nimport { useFileDrag } from '../hooks/useFileDrag';\nimport { toast } from '../Toast';\n\nimport type {\n ComposerAttachment,\n ComposerUploadResult,\n ComposerValue,\n} from './types';\n\nexport type ComposerFieldHandle = {\n focus: () => void;\n};\n\nexport type ComposerContextValue = {\n value: ComposerValue;\n setPrompt: (prompt: string) => void;\n setPlanMode: (planMode: boolean) => void;\n addFiles: (files: FileList | readonly File[]) => void;\n removeAttachment: (clientId: string) => void;\n retryAttachment: (clientId: string) => void;\n submit: () => void;\n canSubmit: boolean;\n busy: boolean;\n placeholder: string;\n autoFocus: boolean;\n submitOnEnter: boolean;\n rows: number;\n minHeight: number;\n pasteTextAsFile: (text: string) => boolean;\n openFilePicker: () => void;\n focus: () => void;\n focusRef: RefObject<ComposerFieldHandle | null>;\n fileDragOver: boolean;\n drag: ReturnType<typeof useFileDrag>;\n};\n\nconst ComposerContext = createContext<ComposerContextValue | null>(null);\n\nexport function useComposer(): ComposerContextValue {\n const context = use(ComposerContext);\n\n if (!context) {\n throw new Error('Composer pieces must render inside ComposerProvider');\n }\n\n return context;\n}\n\nfunction sumAttachmentBytes(items: readonly ComposerAttachment[]): number {\n let sum = 0;\n\n for (const item of items) {\n if (typeof item.size === 'number' && Number.isFinite(item.size)) {\n sum += item.size;\n }\n }\n\n return sum;\n}\n\nfunction attachmentsReady(items: readonly ComposerAttachment[]): boolean {\n if (items.length === 0) {\n return true;\n }\n\n return items.every(item => item.uploadStatus === 'ready' && Boolean(item.url));\n}\n\nfunction patchAttachment(\n value: ComposerValue,\n clientId: string,\n patch: Partial<ComposerAttachment>\n): ComposerValue {\n return {\n ...value,\n attachments: value.attachments.map(item => (\n item.clientId === clientId ? { ...item, ...patch } : item\n )),\n };\n}\n\nexport type ComposerProviderProps = {\n value: ComposerValue;\n onChange: (value: ComposerValue) => void;\n onSubmit: () => void;\n uploadFile: (file: File) => Promise<ComposerUploadResult>;\n busy?: boolean;\n placeholder?: string;\n autoFocus?: boolean;\n submitHotkey?: 'enter' | 'mod+enter';\n /** Fixed min rows for the field (create project uses 3). */\n rows?: number;\n children: ReactNode;\n};\n\nexport function ComposerProvider({\n value,\n onChange,\n onSubmit,\n uploadFile,\n busy = false,\n placeholder = 'What should it do?',\n autoFocus = true,\n submitHotkey = 'mod+enter',\n rows = 3,\n children,\n}: ComposerProviderProps) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const focusRef = useRef<ComposerFieldHandle | null>(null);\n const valueRef = useRef(value);\n const pendingFilesRef = useRef(new Map<string, File>());\n const [fileDragOver, setFileDragOver] = useState(false);\n\n useLayoutEffect(() => {\n valueRef.current = value;\n }, [value]);\n\n useEffect(() => {\n const pending = pendingFilesRef.current;\n\n return () => {\n for (const item of valueRef.current.attachments) {\n revokeObjectURL(item.preview);\n }\n\n pending.clear();\n };\n }, []);\n\n const canSubmit = Boolean(value.prompt.trim())\n && attachmentsReady(value.attachments)\n && !busy;\n\n const uploadOne = useCallback(async(clientId: string, file: File) => {\n const result = await uploadFile(file);\n const current = valueRef.current;\n\n if (!current.attachments.some(item => item.clientId === clientId)) {\n pendingFilesRef.current.delete(clientId);\n\n return;\n }\n\n if (result.ok) {\n const preview = current.attachments.find(item => item.clientId === clientId)?.preview;\n revokeObjectURL(preview);\n pendingFilesRef.current.delete(clientId);\n onChange(patchAttachment(current, clientId, {\n id: result.data.id,\n url: result.data.url,\n filename: result.data.name ?? file.name,\n mediaType: result.data.mimeType ?? coerceUploadMimeType(file.name, file.type),\n size: result.data.size ?? file.size,\n uploadStatus: 'ready',\n uploadError: undefined,\n preview: undefined,\n }));\n\n return;\n }\n\n onChange(patchAttachment(current, clientId, {\n uploadStatus: 'error',\n uploadError: result.message ?? 'Upload failed',\n }));\n }, [onChange, uploadFile]);\n\n const addFiles = useCallback((files: FileList | readonly File[]) => {\n const list = [...files];\n const accepted: File[] = [];\n let batchBytes = 0;\n const used = sumAttachmentBytes(valueRef.current.attachments);\n\n for (const file of list) {\n if (file.size > MAX_CHAT_ATTACHMENT_BYTES_PER_FILE) {\n toast.warning({\n title: 'Attachment too large',\n message: `${ file.name } is over the ${ formatFileSize(MAX_CHAT_ATTACHMENT_BYTES_PER_FILE, { round: 'up' }) } per-file limit.`,\n });\n continue;\n }\n\n if (used + batchBytes + file.size > MAX_CHAT_ATTACHMENT_BYTES_TOTAL) {\n toast.warning({\n title: 'Attachments too large',\n message: `Adding ${ file.name } would exceed the ${ formatFileSize(MAX_CHAT_ATTACHMENT_BYTES_TOTAL, { round: 'up' }) } combined limit.`,\n });\n continue;\n }\n\n accepted.push(file);\n batchBytes += file.size;\n }\n\n if (accepted.length === 0) {\n return;\n }\n\n const nextItems: ComposerAttachment[] = accepted.map(file => ({\n clientId: crypto.randomUUID(),\n filename: file.name,\n mediaType: coerceUploadMimeType(file.name, file.type),\n size: file.size,\n lastModified: file.lastModified,\n uploadStatus: 'uploading',\n preview: createObjectURL(file) ?? undefined,\n }));\n\n for (let i = 0; i < accepted.length; i++) {\n pendingFilesRef.current.set(nextItems[i]!.clientId, accepted[i]!);\n }\n\n const next: ComposerValue = {\n ...valueRef.current,\n attachments: [...valueRef.current.attachments, ...nextItems],\n };\n onChange(next);\n\n for (let i = 0; i < accepted.length; i++) {\n void uploadOne(nextItems[i]!.clientId, accepted[i]!);\n }\n }, [onChange, uploadOne]);\n\n const drag = useFileDrag({\n onFileDragOver: setFileDragOver,\n onFilesDropped: files => addFiles(files),\n });\n\n const removeAttachment = (clientId: string) => {\n const current = valueRef.current;\n const item = current.attachments.find(entry => entry.clientId === clientId);\n revokeObjectURL(item?.preview);\n pendingFilesRef.current.delete(clientId);\n onChange({\n ...current,\n attachments: current.attachments.filter(entry => entry.clientId !== clientId),\n });\n };\n\n const retryAttachment = (clientId: string) => {\n const current = valueRef.current;\n const item = current.attachments.find(entry => entry.clientId === clientId);\n const file = pendingFilesRef.current.get(clientId);\n\n if (!item || item.uploadStatus !== 'error') {\n return;\n }\n\n if (!file) {\n toast.warning({\n title: 'Could not retry',\n message: 'Remove the file and attach it again.',\n });\n\n return;\n }\n\n onChange(patchAttachment(current, clientId, {\n uploadStatus: 'uploading',\n uploadError: undefined,\n }));\n void uploadOne(clientId, file);\n };\n\n const submit = () => {\n if (!canSubmit) {\n return;\n }\n\n onSubmit();\n };\n\n const pasteTextAsFile = (text: string) => {\n if (text.length < COMPOSER_PASTE_AS_FILE_MIN_CHARS) {\n return false;\n }\n\n const file = new File([text], 'paste.txt', { type: 'text/plain' });\n\n if (file.size > MAX_CHAT_ATTACHMENT_BYTES_PER_FILE) {\n return false;\n }\n\n addFiles([file]);\n\n return true;\n };\n\n const api: ComposerContextValue = {\n value,\n setPrompt: (prompt) => onChange({ ...valueRef.current, prompt }),\n setPlanMode: (planMode) => onChange({ ...valueRef.current, planMode }),\n addFiles,\n removeAttachment,\n retryAttachment,\n submit,\n canSubmit,\n busy,\n placeholder,\n autoFocus,\n submitOnEnter: submitHotkey === 'enter',\n rows,\n minHeight: rows ? rows * 22 : 20,\n pasteTextAsFile,\n openFilePicker: () => fileInputRef.current?.click(),\n focus: () => focusRef.current?.focus(),\n focusRef,\n fileDragOver,\n drag,\n };\n\n return (\n <ComposerContext value={ api }>\n { children }\n <input\n ref={ fileInputRef }\n type=\"file\"\n multiple\n tabIndex={ -1 }\n style={ { display: 'none' } }\n onChange={ (event) => {\n if (event.target.files?.length) {\n addFiles(event.target.files);\n }\n\n event.target.value = '';\n } }\n />\n </ComposerContext>\n );\n}\n"],"names":["ComposerContext","useComposer","context","use","sumAttachmentBytes","items","sum","item","attachmentsReady","patchAttachment","value","clientId","patch","ComposerProvider","onChange","onSubmit","uploadFile","busy","placeholder","autoFocus","submitHotkey","rows","children","fileInputRef","useRef","focusRef","valueRef","pendingFilesRef","fileDragOver","setFileDragOver","useState","useLayoutEffect","useEffect","pending","revokeObjectURL","canSubmit","uploadOne","useCallback","file","result","current","preview","coerceUploadMimeType","addFiles","files","list","accepted","batchBytes","used","MAX_CHAT_ATTACHMENT_BYTES_PER_FILE","toast","formatFileSize","MAX_CHAT_ATTACHMENT_BYTES_TOTAL","nextItems","createObjectURL","i","next","drag","useFileDrag","removeAttachment","entry","retryAttachment","submit","pasteTextAsFile","text","COMPOSER_PASTE_AS_FILE_MIN_CHARS","api","prompt","planMode","_jsx","event"],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sources":["../../src/Composer/context.tsx"],"sourcesContent":["'use client';\n\nimport {\n coerceUploadMimeType,\n COMPOSER_PASTE_AS_FILE_MIN_CHARS,\n MAX_CHAT_ATTACHMENT_BYTES_PER_FILE,\n MAX_CHAT_ATTACHMENT_BYTES_TOTAL,\n} from '@reforma/constants';\nimport { createObjectURL, formatFileSize, revokeObjectURL } from '@reforma/lib';\nimport {\n createContext,\n use,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\n\nimport { useFileDrag } from '../hooks/useFileDrag';\nimport { Show } from '../Show';\n\nimport type {\n ComposerAttachment,\n ComposerClassNames,\n ComposerNotice,\n ComposerUploadResult,\n ComposerValue,\n} from './types';\n\nexport type ComposerFieldHandle = {\n focus: () => void;\n};\n\nexport type ComposerContextValue = {\n classNames: ComposerClassNames;\n value: ComposerValue;\n setPrompt: (prompt: string) => void;\n setPlanMode: (planMode: boolean) => void;\n addFiles: (files: FileList | readonly File[]) => void;\n removeAttachment: (clientId: string) => void;\n retryAttachment: (clientId: string) => void;\n submit: () => void;\n canSubmit: boolean;\n busy: boolean;\n placeholder: string;\n autoFocus: boolean;\n submitOnEnter: boolean;\n rows: number;\n minHeight: number;\n pasteTextAsFile: (text: string) => boolean;\n openFilePicker: () => void;\n focus: () => void;\n focusRef: RefObject<ComposerFieldHandle | null>;\n fileDragOver: boolean;\n drag: ReturnType<typeof useFileDrag>;\n};\n\nconst ComposerContext = createContext<ComposerContextValue | null>(null);\n\nexport function useComposer(): ComposerContextValue {\n const context = use(ComposerContext);\n\n if (!context) {\n throw new Error('Composer pieces must render inside ComposerProvider');\n }\n\n return context;\n}\n\nfunction sumAttachmentBytes(items: readonly ComposerAttachment[]): number {\n let sum = 0;\n\n for (const item of items) {\n if (typeof item.size === 'number' && Number.isFinite(item.size)) {\n sum += item.size;\n }\n }\n\n return sum;\n}\n\nfunction attachmentsReady(items: readonly ComposerAttachment[]): boolean {\n if (items.length === 0) {\n return true;\n }\n\n return items.every(item => item.uploadStatus === 'ready' && Boolean(item.url));\n}\n\nfunction patchAttachment(\n value: ComposerValue,\n clientId: string,\n patch: Partial<ComposerAttachment>\n): ComposerValue {\n return {\n ...value,\n attachments: value.attachments.map(item => (\n item.clientId === clientId ? { ...item, ...patch } : item\n )),\n };\n}\n\nexport type ComposerProviderProps = {\n classNames?: ComposerClassNames;\n /** Report validation errors in the host UI. Defaults to an inline alert. */\n onError?: (notice: ComposerNotice) => void;\n value: ComposerValue;\n onChange: (value: ComposerValue) => void;\n onSubmit: () => void;\n uploadFile: (file: File) => Promise<ComposerUploadResult>;\n busy?: boolean;\n placeholder?: string;\n autoFocus?: boolean;\n submitHotkey?: 'enter' | 'mod+enter';\n /** Fixed min rows for the field (create project uses 3). */\n rows?: number;\n children: ReactNode;\n};\n\nexport function ComposerProvider({\n classNames = {},\n onError,\n value,\n onChange,\n onSubmit,\n uploadFile,\n busy = false,\n placeholder = 'What should it do?',\n autoFocus = true,\n submitHotkey = 'mod+enter',\n rows = 3,\n children,\n}: ComposerProviderProps) {\n const [notice, setNotice] = useState<ComposerNotice | null>(null);\n const reportError = useCallback((next: ComposerNotice) => {\n if (onError) {\n onError(next);\n }\n else {\n setNotice(next);\n }\n }, [onError]);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const focusRef = useRef<ComposerFieldHandle | null>(null);\n const valueRef = useRef(value);\n const onChangeRef = useRef(onChange);\n const pendingFilesRef = useRef(new Map<string, File>());\n const [fileDragOver, setFileDragOver] = useState(false);\n\n useLayoutEffect(() => {\n valueRef.current = value;\n }, [value]);\n\n useLayoutEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n const changeValue = useCallback((next: ComposerValue) => {\n valueRef.current = next;\n onChangeRef.current(next);\n }, []);\n\n useEffect(() => {\n const pending = pendingFilesRef.current;\n\n return () => {\n for (const item of valueRef.current.attachments) {\n revokeObjectURL(item.preview);\n }\n\n pending.clear();\n };\n }, []);\n\n const canSubmit = Boolean(value.prompt.trim())\n && attachmentsReady(value.attachments)\n && !busy;\n\n const uploadOne = useCallback(async(clientId: string, file: File) => {\n let result: ComposerUploadResult;\n try {\n result = await uploadFile(file);\n }\n catch (error) {\n result = { ok: false, message: error instanceof Error ? error.message : undefined };\n }\n\n if (pendingFilesRef.current.get(clientId) !== file) {\n return;\n }\n const current = valueRef.current;\n\n if (!current.attachments.some(item => item.clientId === clientId)) {\n pendingFilesRef.current.delete(clientId);\n\n return;\n }\n\n if (result.ok) {\n const preview = current.attachments.find(item => item.clientId === clientId)?.preview;\n revokeObjectURL(preview);\n pendingFilesRef.current.delete(clientId);\n changeValue(patchAttachment(current, clientId, {\n id: result.data.id,\n url: result.data.url,\n filename: result.data.name ?? file.name,\n mediaType: result.data.mimeType ?? coerceUploadMimeType(file.name, file.type),\n size: result.data.size ?? file.size,\n uploadStatus: 'ready',\n uploadError: undefined,\n preview: undefined,\n }));\n\n return;\n }\n\n changeValue(patchAttachment(current, clientId, {\n uploadStatus: 'error',\n uploadError: result.message ?? 'Upload failed',\n }));\n }, [changeValue, uploadFile]);\n\n const addFiles = useCallback((files: FileList | readonly File[]) => {\n setNotice(null);\n const list = [...files];\n const accepted: File[] = [];\n let batchBytes = 0;\n const used = sumAttachmentBytes(valueRef.current.attachments);\n\n for (const file of list) {\n if (file.size > MAX_CHAT_ATTACHMENT_BYTES_PER_FILE) {\n reportError({\n title: 'Attachment too large',\n message: `${ file.name } is over the ${ formatFileSize(MAX_CHAT_ATTACHMENT_BYTES_PER_FILE, { round: 'up' }) } per-file limit.`,\n });\n continue;\n }\n\n if (used + batchBytes + file.size > MAX_CHAT_ATTACHMENT_BYTES_TOTAL) {\n reportError({\n title: 'Attachments too large',\n message: `Adding ${ file.name } would exceed the ${ formatFileSize(MAX_CHAT_ATTACHMENT_BYTES_TOTAL, { round: 'up' }) } combined limit.`,\n });\n continue;\n }\n\n accepted.push(file);\n batchBytes += file.size;\n }\n\n if (accepted.length === 0) {\n return;\n }\n\n const nextItems: ComposerAttachment[] = accepted.map(file => ({\n clientId: crypto.randomUUID(),\n filename: file.name,\n mediaType: coerceUploadMimeType(file.name, file.type),\n size: file.size,\n lastModified: file.lastModified,\n uploadStatus: 'uploading',\n preview: createObjectURL(file) ?? undefined,\n }));\n\n for (let i = 0; i < accepted.length; i++) {\n pendingFilesRef.current.set(nextItems[i]!.clientId, accepted[i]!);\n }\n\n const next: ComposerValue = {\n ...valueRef.current,\n attachments: [...valueRef.current.attachments, ...nextItems],\n };\n changeValue(next);\n\n for (let i = 0; i < accepted.length; i++) {\n void uploadOne(nextItems[i]!.clientId, accepted[i]!);\n }\n }, [changeValue, uploadOne, reportError]);\n\n const drag = useFileDrag({\n onFileDragOver: setFileDragOver,\n onFilesDropped: files => addFiles(files),\n });\n\n const removeAttachment = (clientId: string) => {\n const current = valueRef.current;\n const item = current.attachments.find(entry => entry.clientId === clientId);\n revokeObjectURL(item?.preview);\n pendingFilesRef.current.delete(clientId);\n changeValue({\n ...current,\n attachments: current.attachments.filter(entry => entry.clientId !== clientId),\n });\n };\n\n const retryAttachment = (clientId: string) => {\n const current = valueRef.current;\n const item = current.attachments.find(entry => entry.clientId === clientId);\n const file = pendingFilesRef.current.get(clientId);\n\n if (!item || item.uploadStatus !== 'error') {\n return;\n }\n\n if (!file) {\n reportError({\n title: 'Could not retry',\n message: 'Remove the file and attach it again.',\n });\n\n return;\n }\n\n changeValue(patchAttachment(current, clientId, {\n uploadStatus: 'uploading',\n uploadError: undefined,\n }));\n void uploadOne(clientId, file);\n };\n\n const submit = () => {\n if (!canSubmit) {\n return;\n }\n\n onSubmit();\n };\n\n const pasteTextAsFile = (text: string) => {\n if (text.length < COMPOSER_PASTE_AS_FILE_MIN_CHARS) {\n return false;\n }\n\n const file = new File([text], 'paste.txt', { type: 'text/plain' });\n\n if (file.size > MAX_CHAT_ATTACHMENT_BYTES_PER_FILE) {\n return false;\n }\n\n addFiles([file]);\n\n return true;\n };\n\n const api: ComposerContextValue = {\n classNames,\n value,\n setPrompt: (prompt) => changeValue({ ...valueRef.current, prompt }),\n setPlanMode: (planMode) => changeValue({ ...valueRef.current, planMode }),\n addFiles,\n removeAttachment,\n retryAttachment,\n submit,\n canSubmit,\n busy,\n placeholder,\n autoFocus,\n submitOnEnter: submitHotkey === 'enter',\n rows,\n minHeight: rows ? rows * 22 : 20,\n pasteTextAsFile,\n openFilePicker: () => fileInputRef.current?.click(),\n focus: () => focusRef.current?.focus(),\n focusRef,\n fileDragOver,\n drag,\n };\n\n return (\n <ComposerContext value={ api }>\n { children }\n <Show when={ notice && !onError }>\n <p role=\"alert\" className={ classNames.notice }>\n { notice?.title }: { notice?.message }\n </p>\n </Show>\n <input\n ref={ fileInputRef }\n type=\"file\"\n multiple\n tabIndex={ -1 }\n hidden\n onChange={ (event) => {\n if (event.target.files?.length) {\n addFiles(event.target.files);\n }\n\n event.target.value = '';\n } }\n />\n </ComposerContext>\n );\n}\n"],"names":["ComposerContext","useComposer","context","use","sumAttachmentBytes","items","sum","item","attachmentsReady","patchAttachment","value","clientId","patch","ComposerProvider","classNames","onError","onChange","onSubmit","uploadFile","busy","placeholder","autoFocus","submitHotkey","rows","children","notice","setNotice","useState","reportError","useCallback","next","fileInputRef","useRef","focusRef","valueRef","onChangeRef","pendingFilesRef","fileDragOver","setFileDragOver","useLayoutEffect","changeValue","useEffect","pending","revokeObjectURL","canSubmit","uploadOne","file","result","error","current","preview","coerceUploadMimeType","addFiles","files","list","accepted","batchBytes","used","MAX_CHAT_ATTACHMENT_BYTES_PER_FILE","formatFileSize","MAX_CHAT_ATTACHMENT_BYTES_TOTAL","nextItems","createObjectURL","i","drag","useFileDrag","removeAttachment","entry","retryAttachment","submit","pasteTextAsFile","text","COMPOSER_PASTE_AS_FILE_MIN_CHARS","api","prompt","planMode","_jsx","Show","event"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { ComposerProvider, useComposer, type ComposerContextValue, type ComposerFieldHandle, type ComposerProviderProps, } from './context';
2
2
  export { ComposerAttachments, ComposerFileButton, ComposerFrame, ComposerPlan, ComposerSubmit, ComposerSurface, ComposerTextarea, ComposerToolbar, ComposerTools, } from './parts';
3
3
  export { ComposerRichField } from './RichField';
4
- export type { ComposerAttachment, ComposerUploadErr, ComposerUploadOk, ComposerUploadResult, ComposerValue, } from './types';
4
+ export type { ComposerAttachment, ComposerClassNames, ComposerNotice, ComposerUploadErr, ComposerUploadOk, ComposerUploadResult, ComposerValue, } from './types';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EACH,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EACR,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GAChB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EACH,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EACR,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GAChB,MAAM,SAAS,CAAC"}
@@ -1,22 +1,23 @@
1
- import { type ReactNode } from 'react';
2
- export declare function ComposerFrame({ className, children, }: {
3
- className?: string;
4
- children: ReactNode;
1
+ import { type ButtonHTMLAttributes, type HTMLAttributes, type TextareaHTMLAttributes } from 'react';
2
+ import type { ComposerClassNames } from './types';
3
+ type ContainerProps = HTMLAttributes<HTMLDivElement>;
4
+ type ActionProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick' | 'disabled' | 'type'>;
5
+ export declare function ComposerFrame({ className, classNames: slots, children, onDragEnter, onDragLeave, onDragOver, onDrop, onPaste, ...props }: ContainerProps & {
6
+ classNames?: Pick<ComposerClassNames, 'shell' | 'dropOverlay' | 'dropLabel'>;
5
7
  }): import("react").JSX.Element;
6
- /** Relative row that pins the tools and the submit button to the field. */
7
- export declare function ComposerSurface({ children }: {
8
- children: ReactNode;
8
+ export declare function ComposerSurface({ className, children, onPointerDown, ...props }: ContainerProps): import("react").JSX.Element;
9
+ export declare function ComposerTools({ className, ...props }: ContainerProps): import("react").JSX.Element;
10
+ export declare function ComposerToolbar({ className, children, ...props }: ContainerProps): import("react").JSX.Element;
11
+ export declare function ComposerAttachments({ className, classNames: slots, ...props }: ContainerProps & {
12
+ classNames?: Pick<ComposerClassNames, 'attachment' | 'attachmentPreview' | 'attachmentName' | 'attachmentStatus' | 'attachmentRetry' | 'attachmentRemove'>;
9
13
  }): import("react").JSX.Element;
10
- /** Left cluster: file button, plan, whatever else you drop in. */
11
- export declare function ComposerTools({ children }: {
12
- children: ReactNode;
14
+ export declare function ComposerFileButton({ className, children, ...props }: ActionProps): import("react").JSX.Element;
15
+ export declare function ComposerPlan({ className, children, classNames: slots, ...props }: ActionProps & {
16
+ classNames?: Pick<ComposerClassNames, 'planIcon' | 'planLabel'>;
13
17
  }): import("react").JSX.Element;
14
- export declare function ComposerToolbar({ children }: {
15
- children?: ReactNode;
18
+ export declare function ComposerTextarea({ className, classNames: slots, style, onKeyDown, onPaste, ...props }: Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'defaultValue' | 'onChange' | 'ref'> & {
19
+ classNames?: Pick<ComposerClassNames, 'textareaWrap'>;
16
20
  }): import("react").JSX.Element;
17
- export declare function ComposerAttachments(): import("react").JSX.Element;
18
- export declare function ComposerFileButton(): import("react").JSX.Element;
19
- export declare function ComposerPlan(): import("react").JSX.Element;
20
- export declare function ComposerTextarea(): import("react").JSX.Element;
21
- export declare function ComposerSubmit(): import("react").JSX.Element;
21
+ export declare function ComposerSubmit({ className, children, ...props }: ActionProps): import("react").JSX.Element;
22
+ export {};
22
23
  //# sourceMappingURL=parts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/Composer/parts.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAW3D,wBAAgB,aAAa,CAAC,EAC1B,SAAS,EACT,QAAQ,GACX,EAAE;IACC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACvB,+BAkBA;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAkBpE;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAMlE;AAED,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAQrE;AAED,wBAAgB,mBAAmB,gCA8BlC;AAED,wBAAgB,kBAAkB,gCAiBjC;AAED,wBAAgB,YAAY,gCAsC3B;AAED,wBAAgB,gBAAgB,gCAsD/B;AAED,wBAAgB,cAAc,gCAmB7B"}
1
+ {"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/Composer/parts.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,KAAK,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAMpG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,KAAK,cAAc,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;AACrD,KAAK,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC;AAElG,wBAAgB,aAAa,CAAC,EAC1B,SAAS,EACT,UAAU,EAAE,KAAK,EACjB,QAAQ,EACR,WAAW,EACX,WAAW,EACX,UAAU,EACV,MAAM,EACN,OAAO,EACP,GAAG,KAAK,EACX,EAAE,cAAc,GAAG;IAAE,UAAU,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,aAAa,GAAG,WAAW,CAAC,CAAA;CAAE,+BA4CnG;AAED,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAqB/F;AAED,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAIpE;AAED,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAUhF;AAED,wBAAgB,mBAAmB,CAAC,EAChC,SAAS,EACT,UAAU,EAAE,KAAK,EACjB,GAAG,KAAK,EACX,EAAE,cAAc,GAAG;IAChB,UAAU,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAChC,YAAY,GAAG,mBAAmB,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,kBAAkB,CAAC,CAAC;CAC5H,+BAoDA;AAED,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,+BAgBhF;AAED,wBAAgB,YAAY,CAAC,EACzB,SAAS,EACT,QAAQ,EACR,UAAU,EAAE,KAAK,EACjB,GAAG,KAAK,EACX,EAAE,WAAW,GAAG;IAAE,UAAU,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,WAAW,CAAC,CAAA;CAAE,+BA2BnF;AAED,wBAAgB,gBAAgB,CAAC,EAC7B,SAAS,EACT,UAAU,EAAE,KAAK,EACjB,KAAK,EACL,SAAS,EACT,OAAO,EACP,GAAG,KAAK,EACX,EAAE,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,GAAG,KAAK,CAAC,GAAG;IAClG,UAAU,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;CACzD,+BAuCA;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,+BAkB5E"}