mobileapp / src /components /chat /ChatInput.tsx
Antaram Dev Bot
feat: complete ANTARAM.ORG ride-sharing app frontend
5c876be
import React, { useState, useCallback, useRef, useEffect } from 'react';
import { StyleSheet, View, Keyboard, Platform } from 'react-native';
import { useTheme, TextInput, IconButton } from 'react-native-paper';
export interface ChatInputProps {
/** Callback with the message text when send is pressed */
onSend: (text: string) => void;
/** Callback when the location-attachment button is pressed */
onSendLocation?: () => void;
/** Placeholder text (default: "Type a message…") */
placeholder?: string;
/** Whether input is currently disabled */
disabled?: boolean;
}
/**
* Message input bar pinned to the bottom of a chat screen.
* Features a flat TextInput, attachment button (📎) and send button (➤).
*/
export function ChatInput({
onSend,
onSendLocation,
placeholder = 'Type a message…',
disabled = false,
}: ChatInputProps) {
const theme = useTheme();
const [text, setText] = useState('');
const inputRef = useRef<any>(null);
const handleSend = useCallback(() => {
const trimmed = text.trim();
if (!trimmed) return;
onSend(trimmed);
setText('');
inputRef.current?.focus();
}, [text, onSend]);
const onSubmitEditing = useCallback(() => {
handleSend();
}, [handleSend]);
// On Android, handle the hardware keyboard's "send" key
const keyboardType = Platform.OS === 'android' ? 'default' : 'default';
return (
<View
style={[
styles.container,
{
backgroundColor: theme.colors.surfaceContainerHigh,
borderTopColor: theme.colors.outlineVariant,
},
]}
>
{/* Location attachment button */}
<IconButton
icon="map-marker-plus-outline"
size={22}
iconColor={theme.colors.onSurfaceVariant}
onPress={onSendLocation}
style={styles.attachButton}
disabled={disabled}
/>
{/* Text input */}
<TextInput
ref={inputRef}
mode="flat"
value={text}
onChangeText={setText}
onSubmitEditing={onSubmitEditing}
placeholder={placeholder}
placeholderTextColor={theme.colors.onSurfaceVariant}
disabled={disabled}
style={styles.input}
contentStyle={styles.inputContent}
underlineColor="transparent"
activeUnderlineColor="transparent"
multiline
maxLength={2000}
right={
text.trim().length > 0 ? (
<TextInput.Icon
icon="send"
size={22}
iconColor={theme.colors.primary}
onPress={handleSend}
style={styles.sendIcon}
/>
) : null
}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'flex-end',
paddingHorizontal: 4,
paddingVertical: 4,
borderTopWidth: StyleSheet.hairlineWidth,
},
attachButton: {
margin: 0,
},
input: {
flex: 1,
backgroundColor: 'transparent',
maxHeight: 120,
marginVertical: 0,
paddingHorizontal: 0,
},
inputContent: {
minHeight: 40,
paddingTop: 8,
paddingBottom: 8,
},
sendIcon: {
margin: 0,
paddingBottom: 4,
},
});