Full working example
This example keeps search input, loading state, and result data controlled from the app so async search stays predictable.
ConversationSearch.tsx
import React from 'react';
import { SearchModal } from '@jazzmine-ui/react';
import type { Chat } from '@jazzmine-ui/react';
import '@jazzmine-ui/react/styles';
async function searchConversations(query: string): Promise<Chat[]> {
if (!query.trim()) {
return [];
}
// Replace this with your backend call.
return [
{
conversation_id: 'conv-1',
title: 'Billing support',
last_updated_at: Date.now(),
} as Chat,
];
}
export function ConversationSearch() {
const [isOpen, setIsOpen] = React.useState(true);
const [searchQuery, setSearchQuery] = React.useState('');
const [results, setResults] = React.useState<Chat[]>([]);
const [isSearching, setIsSearching] = React.useState(false);
const onSearchQueryChange = async (query: string) => {
setSearchQuery(query);
setIsSearching(true);
try {
const nextResults = await searchConversations(query);
setResults(nextResults);
} finally {
setIsSearching(false);
}
};
return (
<SearchModal
isOpen={isOpen} /* Required: modal visibility */
onClose={() => setIsOpen(false)} /* Required: close handler */
onSelectConversation={(conversationId) => {
/* Required: consume selected result id */
console.log('Selected conversation:', conversationId);
setIsOpen(false);
}}
searchQuery={searchQuery} /* Required: controlled query value */
onSearchQueryChange={onSearchQueryChange} /* Required: query change handler */
results={results} /* Required: current result set */
isSearching={isSearching} /* Required: async loading state */
/>
);
}SearchModal props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| isOpen | boolean | Yes | - | Modal visibility state. |
| onClose | () => void | Yes | - | Close callback. |
| onSelectConversation | (conversationId: string) => void | Yes | - | Select result callback. |
| searchQuery | string | Yes | - | Controlled input value. |
| onSearchQueryChange | (query: string) => void | Yes | - | Controlled input update callback. |
| results | Chat[] | Yes | - | Search results. |
| isSearching | boolean | Yes | - | Loading state for async search. |
Async wiring notes
Use the controlled trio together
Treat isSearching, results, and onSearchQueryChange as one unit: toggle loading, fetch results, then update result state.