Simple input box where users can type search queries, made on top of MnInput
import { YStack } from 'tamagui'
import { Searchbar } from 'yourpath/ui'
import { useState } from 'react'
const DemoSearchbar = () => {
const [query, setQuery] = useState('')
return (
<>
<YStack minHeight={250} overflow="hidden" gap="$4" margin="$3" padding="$2">
<Searchbar
value={query}
onChangeText={(text) => {
setQuery(text)
}}
/>
</YStack>
</>
)
}
export default DemoSearchbar
Props
MnSearchbar Code
import { MnInput, MnInputProps } from '../mn-input'
import { Search, X } from '@tamagui/lucide-icons'
import React, { useRef } from 'react'
import { isWeb, useComposedRefs } from 'tamagui'
type ISearchbar = Omit<MnInputProps, 'onChange'> & {
value: string // Value must be a string for the input field
onChangeText: (text: string) => void // Callback for text change
}
// Comment generated by ChatGPT
/**
* Searchbar component that extends MnInput, designed for a seamless search experience.
* Includes a left-aligned search icon and a clear button (X) on the right to reset the search text.
*
* - If running in a web environment, clicking the "X" icon will clear the input and refocus.
* - In non-web environments, the "X" icon's onPress event will trigger the same behavior.
*
* Props:
* - Inherits MnInputProps except for `onChange`, with required `value` and `onChangeText` props.
*
* @param {ISearchbar} props - The properties passed to the Searchbar, including value and optional icons.
*
* @returns {JSX.Element} A search input field with customizable icons and text clearing functionality.
*
* Note: If you provide your own iconRight for clearing search text, you must handle clearing the text like this:
*
* ```tsx
* const handleClearText = () => {
* onChangeText(''); // Clear the input value
* if (isWeb) {
* ref.current?.focus(); // Focus input after clearing on web
* }
* }
* ```
*
* Usage:
* ```tsx
* <Searchbar value={searchText} onChangeText={setSearchText} placeholder="Search here..."/>
* ```
*/
export const Searchbar = React.forwardRef<HTMLInputElement, ISearchbar>((props, forwardedRef) => {
const { iconLeft = Search, iconRight, value, onChangeText, ...rest } = props
const ref = useRef<HTMLInputElement>(null)
const composedRef = useComposedRefs(forwardedRef, ref)
const handleClearText = () => {
onChangeText('') // Clear the input value
if (isWeb) {
ref.current?.focus() // Focus input after clearing on web
}
}
const renderCancelIcon = () => {
return (
<X
{...(isWeb ? { onClick: handleClearText } : { onPress: handleClearText })}
style={{ cursor: 'pointer' }}
aria-label="Clear search"
/>
)
}
return (
<MnInput
roundedBorder
iconLeft={iconLeft}
iconRight={iconRight || renderCancelIcon()}
value={value}
onChangeText={onChangeText} // Ensure the value changes propagate correctly
{...rest}
ref={composedRef}
/>
)
})
// Optional: Define default props
Searchbar.defaultProps = {
iconLeft: Search,
iconRight: null,
}