import * as React from 'react'; import { Platform, StyleSheet, StyleProp, TextInput, I18nManager, TextInputProps, ViewStyle, TextStyle, } from 'react-native'; import color from 'color'; import IconButton from './IconButton'; import Surface from './Surface'; import { withTheme } from '../core/theming'; import type { IconSource } from './Icon'; import MaterialCommunityIcon from './MaterialCommunityIcon'; type Props = React.ComponentPropsWithRef & { /** * Accessibility label for the button. This is read by the screen reader when the user taps the button. */ clearAccessibilityLabel?: string; /** * Accessibility label for the button. This is read by the screen reader when the user taps the button. */ searchAccessibilityLabel?: string; /** * Hint text shown when the input is empty. */ placeholder?: string; /** * The value of the text input. */ value: string; /** * Icon name for the left icon button (see `onIconPress`). */ icon?: IconSource; /** * Callback that is called when the text input's text changes. */ onChangeText?: (query: string) => void; /** * Callback to execute if we want the left icon to act as button. */ onIconPress?: () => void; /** * Set style of the TextInput component inside the searchbar */ inputStyle?: StyleProp; style?: StyleProp; /** * @optional */ theme: ReactNativePaper.Theme; /** * Custom color for icon, default will be derived from theme */ iconColor?: string; /** * Custom icon for clear button, default will be icon close */ clearIcon?: IconSource; }; type TextInputHandles = Pick< TextInput, 'setNativeProps' | 'isFocused' | 'clear' | 'blur' | 'focus' >; /** * Searchbar is a simple input box where users can type search queries. * *
* *
* * ## Usage * ```js * import * as React from 'react'; * import { Searchbar } from 'react-native-paper'; * * const MyComponent = () => { * const [searchQuery, setSearchQuery] = React.useState(''); * * const onChangeSearch = query => setSearchQuery(query); * * return ( * * ); * }; * * export default MyComponent; * ``` */ const Searchbar = React.forwardRef( ( { clearAccessibilityLabel = 'clear', clearIcon, icon, iconColor: customIconColor, inputStyle, onIconPress, placeholder, searchAccessibilityLabel = 'search', style, theme, value, ...rest }: Props, ref ) => { const root = React.useRef(null); React.useImperativeHandle(ref, () => { const input = root.current; if (input) { return { focus: () => input.focus(), clear: () => input.clear(), setNativeProps: (args: TextInputProps) => input.setNativeProps(args), isFocused: () => input.isFocused(), blur: () => input.blur(), }; } const noop = () => { throw new Error('TextInput is not available'); }; return { focus: noop, clear: noop, setNativeProps: noop, isFocused: noop, blur: noop, }; }); const handleClearPress = () => { root.current?.clear(); rest.onChangeText?.(''); }; const { colors, roundness, dark, fonts } = theme; const textColor = colors.text; const font = fonts.regular; const iconColor = customIconColor || (dark ? textColor : color(textColor).alpha(0.54).rgb().string()); const rippleColor = color(textColor).alpha(0.32).rgb().string(); return ( ( )) } accessibilityLabel={searchAccessibilityLabel} /> ( )) } // @ts-expect-error We keep old a11y props for backwards compat with old RN versions accessibilityTraits="button" accessibilityComponentType="button" accessibilityRole="button" /> ); } ); const styles = StyleSheet.create({ container: { flexDirection: 'row', alignItems: 'center', }, input: { flex: 1, fontSize: 18, paddingLeft: 8, alignSelf: 'stretch', textAlign: I18nManager.isRTL ? 'right' : 'left', minWidth: 0, }, }); export default withTheme(Searchbar);