import React, { JSX, useRef } from "react"; import { ImageSourcePropType, ImageStyle, Pressable, StyleProp, Text, TextInput, TextStyle, TouchableOpacity, View, ViewStyle, } from "react-native"; import { useTheme } from "../../../theme"; import { Icon } from "../../icons/Icon"; import styles from "./styles"; /** * Props for the Header component. */ interface HeaderProps { /** * Style for the separator view between the back button and title. */ titleSeparatorStyle?: ViewStyle; /** * Count of selected items (used in selection mode). */ selectedCount?: number; /** * If true, hides the back button. */ hideBackButton?: boolean; /** * Callback function invoked when the back button is pressed. */ onBack?: () => void; /** * Custom component for additional AppBar options. */ AppBarOptions?: React.FC; /** * If true, indicates that the list is in selection mode. */ shouldSelect?: boolean; /** * If true, hides the submit (confirm) button in selection mode. */ hideSubmitButton?: boolean; /** * Callback function invoked when the cancel button is pressed in selection mode. */ onCancel?: () => void; /** * Callback function invoked when the confirm button is pressed in selection mode. */ onConfirm?: () => void; /** * If true, hides the search box. */ hideSearch?: boolean; /** * Callback function to handle changes in the search input. */ searchHandler?: (text: string) => void; /** * Current search input value. */ searchInput?: string; /** * Callback function invoked when submitting the search (e.g., via keyboard's search button). */ onSubmitEditing?: () => void; /** * Back button icon, can be an image source or a JSX element. */ backButtonIcon?: ImageSourcePropType | JSX.Element; /** * Custom style for the back button icon. */ backButtonIconStyle?: ImageStyle; /** * Title text to display in the header. */ title?: string; /** * Custom style for the title text. */ titleStyle?: StyleProp; /** * Custom style for the container wrapping the title. */ titleViewStyle?: StyleProp; /** * Custom style for the header container. */ containerStyle?: StyleProp; /** * Placeholder text for the search input. */ searchPlaceholderText?: string; confirmSelectionStyle?: { icon?: ImageSourcePropType | JSX.Element; iconStyle?: ImageStyle; iconContainerStyle?: ImageStyle; }; selectionCancelStyle?: { icon?: ImageSourcePropType | JSX.Element; iconStyle?: ImageStyle; iconContainerStyle?: ImageStyle; }; /** * Custom style for the search component. */ searchStyle?: Partial<{ textStyle: TextStyle; placehodlerTextStyle?: TextStyle; containerStyle: ViewStyle; icon: ImageSourcePropType | JSX.Element; iconStyle: ImageStyle; }>; /** * Custom style for the container of the back button icon. */ backButtonIconContainerStyle?: ViewStyle; /** * If true, hides the entire header. */ hideHeader?: boolean; /** * Custom search view component to display instead of the default search input. */ SearchView?: () => JSX.Element; /** * Callback triggered when the search bar is clicked or focused. */ onSearchBarClicked?: () => void; } /** * Header component renders the top portion of the list with a title, back button, selection actions, * AppBar options, and a search box. * * Props to customize the header. * The rendered header component. */ export default function Header({ selectedCount = 0, hideBackButton = true, onBack = () => {}, AppBarOptions, shouldSelect = false, hideSubmitButton = false, onCancel = () => {}, onConfirm = () => {}, hideSearch = false, searchHandler = () => {}, searchInput = "", onSubmitEditing = () => {}, backButtonIcon, backButtonIconStyle = {}, title = "", titleStyle = {}, titleViewStyle, containerStyle, searchPlaceholderText = "Search", confirmSelectionStyle, selectionCancelStyle, titleSeparatorStyle = {}, searchStyle, hideHeader = false, backButtonIconContainerStyle = { marginLeft: 10 }, SearchView, onSearchBarClicked, }: HeaderProps) { const theme = useTheme(); const inputRef = useRef(null); return ( {/* Header section with border */} {!hideHeader && ( {/* Render back button and title if not in selection mode */} {!shouldSelect && (!hideBackButton || title.length !== 0) && ( {!hideBackButton && ( )} {title.length !== 0 && ( {title} )} )} {/* Render selection mode actions: cancel button and selected count */} {shouldSelect && ( {selectedCount} )} {/* Render AppBar options or the selection confirm (tick) icon */} {!shouldSelect && AppBarOptions && } {selectedCount > 0 && shouldSelect && !hideSubmitButton && ( )} )} {/* Render search box without border */} {!hideSearch && ( {SearchView ? ( ) : ( { onSubmitEditing?.(); inputRef.current?.focus(); }} submitBehavior='submit' numberOfLines={1} allowFontScaling={false} style={[ { flex: 1, color: theme.color.textPrimary, fontSize: 16, paddingVertical: 4, ...theme.typography.heading4.regular, }, searchStyle?.textStyle, ]} /> )} )} ); }