import type { ClipboardEvent, ComponentPropsWithRef, ReactNode, RefObject } from 'react'; export type ChatComposerStatus = { type: 'error' | 'warning'; message?: ReactNode; }; export type ChatComposerDensity = 'compact' | 'balanced' | 'spacious'; export type ChatComposerSearchableItem = { id: string; label: string; element?: ReactNode; auxiliaryData?: TAuxData; }; export type ChatComposerSearchSource = { search: (query: string) => Promise | TItem[]; bootstrap?: () => Promise | TItem[]; cancel?: () => void; }; export type ChatComposerTokenVariant = 'neutral' | 'blue' | 'purple' | 'yellow' | 'green' | 'red'; export type ChatComposerTokenBadge = { value: string; label: ReactNode; variant?: ChatComposerTokenVariant; icon?: ReactNode; }; export type ChatComposerTokenCustom = { value: string; render: () => ReactNode; }; export type ChatComposerToken = ChatComposerTokenBadge | ChatComposerTokenCustom; export type ChatComposerTrigger = { character: string; searchSource: ChatComposerSearchSource; renderItem?: (item: TItem) => ReactNode; onSelect: (item: TItem) => string | ChatComposerToken; deserialize?: (value: string) => ChatComposerToken | null; emptySearchResultsText?: string; loadingText?: string; menuLabel?: string; }; export type ChatComposerInputHandle = { insertToken: (token: ChatComposerToken) => string | undefined; expandToken: (id: string) => void; insertText: (text: string) => void; focus: () => void; getValue: () => string; }; export type UseChatPasteAsTokenOptions = { inputRef: RefObject; threshold?: number; toToken?: (text: string) => ChatComposerToken; }; export type UseChatPasteAsTokenReturn = { onPaste: (event: ClipboardEvent, text: string) => boolean; }; export type ChatComposerRootProps = Omit, 'defaultValue' | 'onChange' | 'onSubmit'>;