import type { ReactNode } from 'react'; import type { NativeSyntheticEvent, TextInputChangeEventData } from 'react-native'; /** Data-only config for built-in textarea. When provided, InputToolBar renders the textarea with default styling. */ export interface InputConfig { value: string; onChange: (e: NativeSyntheticEvent) => void; placeholder?: string; disabled?: boolean; onKeyDown?: (e: any) => void; onPaste?: (e: any) => void; id?: string; name?: string; /** Optional ref for the textarea (e.g. for focus / height adjustment) */ inputRef?: React.RefObject; } /** Predefined toolbar action ids for left section (mode toggles, template) */ export type LeftToolbarItemId = 'search' | 'zap' | 'lightbulb' | 'template'; /** Predefined toolbar action ids for right section. projectSettings = first item, disabled by default; enable via overrides. tag = enhance prompt, chip = configure model; both support enabled/disable and custom label, icon, onClick for app-specific use. */ export type RightToolbarItemId = 'projectSettings' | 'tag' | 'chip' | 'camera' | 'image' | 'attach' | 'mic'; /** Single toolbar button/item configuration */ export interface ToolbarItemConfig { /** Unique id for the item (used for enable/disable and callbacks) */ id: TId; /** Icon (React node) or custom content for the button */ icon?: ReactNode; /** Accessible label / title (e.g. "Enhance your prompt with AI" when enabled, "Type something to enhance" when disabled) */ label: string; /** Whether the item is enabled (default true). When false, item is hidden. */ enabled?: boolean; /** When true, button is visible but disabled (greyed out, not clickable). Use for e.g. "enhance" when input is empty. */ disabled?: boolean; /** When true, show loading spinner and treat as disabled. Use for e.g. "enhance" while request is in flight. */ loading?: boolean; /** Whether the item is in active/selected state (e.g. primary color + hover style for right items) */ active?: boolean; /** Click handler */ onClick?: () => void; /** Optional custom button element; when set, icon/label are ignored and this is rendered */ customButton?: ReactNode; } /** When provided, the rightmost button shows Stop when loading, Send when hasContent, else Mic. Replaces any "mic" item in rightItems. */ export interface MicSendButtonConfig { /** True when input has content – show send icon; otherwise show mic icon (unless loading). */ hasContent: boolean; onSend: () => void; onMic: () => void; disabled?: boolean; /** When true, show stop icon and call onStop on click. */ isLoading?: boolean; onStop?: () => void; } /** Configuration for the optional template pill: either "+ Template (N)" or selected template name with remove/change */ export interface TemplateButtonConfig { /** Button label prefix when no selection, e.g. "+ Template" */ label: string; /** Count to show in parentheses when no selection, e.g. (1) */ count?: number; /** When set, show selected template pill (name + remove + change) instead of "+ Template (N)" */ selectedLabel?: string | null; /** Open template modal / change template (used for main pill click and for "change" when selected) */ onClick?: () => void; /** When template is selected, called when user clicks remove (X) */ onClearTemplate?: () => void; /** Disabled state */ disabled?: boolean; } /** Minimal template item for the default template selection modal. Map your app's template type to this shape. */ export interface TemplateModalItem { id: string; label: string; description?: string; category?: string; } /** Config for the template selection modal. Pass data from props; InputToolBar renders default modal or custom via templateModalRender. */ export interface TemplateModalConfig { isOpen: boolean; onClose: () => void; templates: TemplateModalItem[]; selectedId: string | null; onSelect: (id: string) => void; suggestedId?: string | null; title?: string; /** Optional class for the modal content box (inner container). Use to standardize width/size, e.g. `max-w-md` or `max-w-xl`. */ modalClassName?: string; } /** Render prop for custom template modal. When provided, used instead of the default modal UI. */ export type TemplateModalRender = (config: TemplateModalConfig) => ReactNode; /** Props passed to the project settings modal render function. Values are updated via the parent's callback (e.g. onModelConfigChange). */ export interface ProjectSettingsModalRenderProps { onClose: () => void; } /** Render prop for project settings modal content. When projectSettings is clicked, parent opens modal (sets projectSettingsModalOpen). Modal content receives onClose; parent passes config and onChange from props so values update via parent. */ export type ProjectSettingsModalRender = (props: ProjectSettingsModalRenderProps) => ReactNode; /** Optional class overrides for InputToolBar sections. Use to adapt to light/dark theme or custom styling. */ export interface InputToolBarClassNames { /** Root section (default: rounded border bg-card shadow) */ container?: string; /** Left toolbar group wrapper */ leftGroup?: string; /** Template pill when no selection (e.g. "+ Template (N)") */ templatePill?: string; /** Template pill when selected/suggested (name + remove + change) */ templatePillSelected?: string; /** Left mode buttons – active state (filled) */ leftButtonActive?: string; /** Left mode buttons – inactive state (outline) */ leftButtonInactive?: string; /** Right toolbar buttons – default state */ rightButton?: string; /** Right toolbar buttons – active state */ rightButtonActive?: string; /** Right toolbar buttons – disabled state */ rightButtonDisabled?: string; /** Mic/Send button (primary action) */ micSendButton?: string; } /** Props for the InputToolBar container. UI only: all data and behavior come from props. */ export interface InputToolBarProps { /** Optional class name for the toolbar container (merged with container in classNames) */ className?: string; /** Optional class overrides for toolbar sections (works in both light and dark theme) */ classNames?: InputToolBarClassNames; /** When provided, InputToolBar renders a built-in textarea; pass only data (value, onChange, etc.). */ inputConfig?: InputConfig | null; /** Optional content above the input when inputConfig is set (e.g. panels, banners). */ topContent?: ReactNode; /** Left section: items and template pill. All data (active, onClick, etc.) from parent. */ leftItems?: Array>; /** Right section: items. All data (onClick, etc.) from parent. */ rightItems?: Array>; /** Optional template pill (e.g. "+ Template (1)"). Data from parent. */ templateButton?: TemplateButtonConfig | null; /** Template selection modal: pass data from props. When set, InputToolBar renders the modal (default UI or custom). */ templateModalConfig?: TemplateModalConfig | null; /** When provided, used instead of the default template modal UI. Receives templateModalConfig. */ templateModalRender?: TemplateModalRender | null; /** Custom content for the left section (overrides leftItems) */ leftCustomRender?: ReactNode; /** Custom content for the right section (overrides rightItems and micSendButton) */ rightCustomRender?: ReactNode; /** When set, rightmost button: Stop/Send/Mic; all data and handlers from parent. */ micSendButton?: MicSendButtonConfig | null; /** When true, the project settings modal (from projectSettingsModalRender) is shown. Set by parent when projectSettings is clicked. */ projectSettingsModalOpen?: boolean; /** Called when the project settings modal should close (e.g. overlay click or close button). */ onProjectSettingsModalClose?: () => void; /** Renders the project settings modal content (e.g. Configuration / Other Settings / Secret tabs). Parent passes config and onChange so values update via parent (same pattern as ModelConfigPanel). */ projectSettingsModalRender?: ProjectSettingsModalRender | null; /** Optional content in the middle when not using inputConfig */ children?: ReactNode; /** Click on container (e.g. to focus input) */ onContainerClick?: (e: any) => void; }