NeoScan_Physician/app/modules/AIPrediction/components/SearchBar.tsx
2025-08-20 20:42:33 +05:30

227 lines
5.9 KiB
TypeScript

/*
* File: SearchBar.tsx
* Description: Search bar component for filtering AI predictions
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
import React, { useState, useCallback } from 'react';
import {
View,
TextInput,
StyleSheet,
TouchableOpacity,
Dimensions,
} from 'react-native';
import Icon from 'react-native-vector-icons/Feather';
import { theme } from '../../../theme';
// ============================================================================
// INTERFACES
// ============================================================================
interface SearchBarProps {
value: string;
onChangeText: (text: string) => void;
onClear?: () => void;
placeholder?: string;
autoFocus?: boolean;
disabled?: boolean;
}
// ============================================================================
// CONSTANTS
// ============================================================================
const { width } = Dimensions.get('window');
// ============================================================================
// SEARCH BAR COMPONENT
// ============================================================================
/**
* SearchBar Component
*
* Purpose: Provide search functionality for AI predictions
*
* Features:
* - Real-time search input
* - Clear button functionality
* - Customizable placeholder text
* - Auto-focus support
* - Disabled state support
* - Modern design with icons
* - Responsive width
* - Accessibility support
*/
const SearchBar: React.FC<SearchBarProps> = ({
value,
onChangeText,
onClear,
placeholder = 'Search predictions...',
autoFocus = false,
disabled = false,
}) => {
// ============================================================================
// STATE
// ============================================================================
const [isFocused, setIsFocused] = useState(false);
// ============================================================================
// EVENT HANDLERS
// ============================================================================
/**
* Handle Focus
*
* Purpose: Handle input focus state
*/
const handleFocus = useCallback(() => {
setIsFocused(true);
}, []);
/**
* Handle Blur
*
* Purpose: Handle input blur state
*/
const handleBlur = useCallback(() => {
setIsFocused(false);
}, []);
/**
* Handle Clear
*
* Purpose: Clear search input
*/
const handleClear = useCallback(() => {
onChangeText('');
if (onClear) {
onClear();
}
}, [onChangeText, onClear]);
/**
* Handle Text Change
*
* Purpose: Handle search text input
*/
const handleTextChange = useCallback((text: string) => {
onChangeText(text);
}, [onChangeText]);
// ============================================================================
// RENDER
// ============================================================================
return (
<View style={[
styles.container,
isFocused && styles.focusedContainer,
disabled && styles.disabledContainer,
]}>
{/* Search Icon */}
<Icon
name="search"
size={20}
color={isFocused ? theme.colors.primary : theme.colors.textMuted}
style={styles.searchIcon}
/>
{/* Text Input */}
<TextInput
style={[
styles.input,
disabled && styles.disabledInput,
]}
value={value}
onChangeText={handleTextChange}
onFocus={handleFocus}
onBlur={handleBlur}
placeholder={placeholder}
placeholderTextColor={theme.colors.textMuted}
autoFocus={autoFocus}
editable={!disabled}
selectTextOnFocus={!disabled}
autoCorrect={false}
autoCapitalize="none"
returnKeyType="search"
clearButtonMode="never" // We handle clear button manually
accessibilityLabel="Search AI predictions"
accessibilityHint="Enter patient ID, finding type, or location to search"
/>
{/* Clear Button */}
{value.length > 0 && !disabled && (
<TouchableOpacity
style={styles.clearButton}
onPress={handleClear}
accessibilityRole="button"
accessibilityLabel="Clear search"
accessibilityHint="Clear the search input"
>
<Icon
name="x"
size={18}
color={theme.colors.textMuted}
/>
</TouchableOpacity>
)}
</View>
);
};
// ============================================================================
// STYLES
// ============================================================================
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: theme.colors.background,
borderWidth: 1,
borderColor: theme.colors.border,
borderRadius: theme.borderRadius.medium,
paddingHorizontal: theme.spacing.md,
paddingVertical: theme.spacing.sm,
marginHorizontal: theme.spacing.md,
marginVertical: theme.spacing.sm,
...theme.shadows.small,
},
focusedContainer: {
borderColor: theme.colors.primary,
backgroundColor: theme.colors.background,
},
disabledContainer: {
backgroundColor: theme.colors.backgroundAlt,
opacity: 0.6,
},
searchIcon: {
marginRight: theme.spacing.sm,
},
input: {
flex: 1,
fontSize: theme.typography.fontSize.bodyMedium,
color: theme.colors.textPrimary,
paddingVertical: 0, // Remove default padding to maintain consistent height
fontFamily: theme.typography.fontFamily.regular,
},
disabledInput: {
color: theme.colors.textMuted,
},
clearButton: {
marginLeft: theme.spacing.sm,
padding: theme.spacing.xs,
},
});
export default SearchBar;
/*
* End of File: SearchBar.tsx
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/