Skip to content

Commit fe91483

Browse files
committed
added example
1 parent d1a9516 commit fe91483

File tree

5 files changed

+139
-27
lines changed

5 files changed

+139
-27
lines changed

README.md

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,65 @@ yarn add react-api-search
2626
## Usage
2727

2828
```tsx
29-
import React, { useState } from 'react';
3029
import SearchBar from 'react-api-search';
3130

32-
const MyComponent = () => {
33-
const [selectedItem, setSelectedItem] = useState(null);
34-
35-
const fetchSearchResults = async (query: string) => {
36-
const response = await fetch('https://api.example.com/search?q=${query}');
37-
const data = await response.json();
38-
return data.results; // return an array of results
39-
};
40-
41-
const renderSearchResult = (item: any) => <div>{item.name}</div>;
31+
type Post = {
32+
id: number;
33+
title: string;
34+
body: string;
35+
};
4236

43-
const handleItemSelect = (item: any) => {
44-
setSelectedItem(item);
45-
};
37+
const fetchPosts = async (query: string): Promise<Post[]> => {
38+
const response = await fetch(
39+
`https://jsonplaceholder.typicode.com/posts?q=${encodeURIComponent(query)}`
40+
);
41+
if (!response.ok) throw new Error('Failed to fetch posts');
42+
const data = await response.json();
43+
return data;
44+
};
4645

46+
function App() {
4747
return (
48-
<div>
49-
<SearchBar
50-
fetchData={fetchSearchResults}
51-
renderItem={renderSearchResult}
52-
onSelect={handleItemSelect}
53-
placeholder='Search for items...'
54-
debounceDelay={300}
55-
/>
56-
{selectedItem && <div>You selected: {selectedItem.name}</div>}
48+
<div style={{ padding: '20px' }}>
49+
<h1>Posts Search</h1>
50+
<div style={{ width: '40rem' }}>
51+
<SearchBar<Post>
52+
placeholder='Search for posts...'
53+
fetchData={fetchPosts}
54+
loadingElement={
55+
<div className='custom-loading'>Please wait, fetching data...</div>
56+
}
57+
emptyElement={
58+
<div>No posts match your search. Try something else!</div>
59+
}
60+
errorElement={
61+
<div>Oops, something went wrong. Please try again later.</div>
62+
}
63+
renderItem={(post) => (
64+
<div
65+
style={{ padding: '10px', borderBottom: '1px solid #ccc' }}
66+
onMouseEnter={(e) => {
67+
e.currentTarget.style.backgroundColor = '#f0f0f0'; // hover background
68+
}}
69+
onMouseLeave={(e) => {
70+
e.currentTarget.style.backgroundColor = 'transparent'; // reset background
71+
}}
72+
>
73+
<h3 style={{ margin: 0 }}>{post.title}</h3>
74+
<p style={{ margin: '5px 0', fontSize: '0.9em', color: '#555' }}>
75+
{post.body}
76+
</p>
77+
</div>
78+
)}
79+
onSelect={(post) => alert(`Selected post: ${post.title}`)}
80+
debounceDelay={500}
81+
/>
82+
</div>
5783
</div>
5884
);
59-
};
85+
}
6086

61-
export default MyComponent;
87+
export default App;
6288
```
6389

6490
## Props

example/index.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React from 'react';
2+
import { createRoot } from 'react-dom/client';
3+
import SearchBar from '../src/SearchBar';
4+
5+
const container = document.getElementById('root');
6+
const root = createRoot(container!);
7+
8+
type Post = {
9+
id: number;
10+
title: string;
11+
body: string;
12+
};
13+
14+
const fetchPosts = async (query: string): Promise<Post[]> => {
15+
const response = await fetch(
16+
`https://jsonplaceholder.typicode.com/posts?q=${encodeURIComponent(query)}`
17+
);
18+
if (!response.ok) throw new Error('Failed to fetch posts');
19+
const data = await response.json();
20+
return data;
21+
};
22+
23+
root.render(
24+
<React.StrictMode>
25+
<div style={{ padding: '20px' }}>
26+
<h1>Posts Search</h1>
27+
<div style={{ width: '40rem' }}>
28+
<SearchBar<Post>
29+
placeholder='Search for posts...'
30+
fetchData={fetchPosts}
31+
loadingElement={
32+
<div className='custom-loading'>Please wait, fetching data...</div>
33+
}
34+
emptyElement={
35+
<div>No posts match your search. Try something else!</div>
36+
}
37+
errorElement={
38+
<div>Oops, something went wrong. Please try again later.</div>
39+
}
40+
renderItem={(post) => (
41+
<div
42+
style={{ padding: '10px', borderBottom: '1px solid #ccc' }}
43+
onMouseEnter={(e) => {
44+
e.currentTarget.style.backgroundColor = '#f0f0f0'; // hover background
45+
}}
46+
onMouseLeave={(e) => {
47+
e.currentTarget.style.backgroundColor = 'transparent'; // reset background
48+
}}
49+
>
50+
<h3 style={{ margin: 0 }}>{post.title}</h3>
51+
<p style={{ margin: '5px 0', fontSize: '0.9em', color: '#555' }}>
52+
{post.body}
53+
</p>
54+
</div>
55+
)}
56+
onSelect={(post) => alert(`Selected post: ${post.title}`)}
57+
debounceDelay={500}
58+
/>
59+
</div>
60+
</div>
61+
</React.StrictMode>
62+
);

package-lock.json

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"@rollup/plugin-typescript": "^11.1.6",
3333
"@types/react": "^18.3.3",
3434
"react": "^18.3.1",
35+
"react-dom": "^18.3.1",
3536
"rollup": "^4.18.1",
3637
"rollup-plugin-dts": "^6.1.1",
3738
"rollup-plugin-peer-deps-external": "^2.2.4",

src/SearchBar.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { useState, useEffect, ChangeEvent, useRef } from 'react';
22
import styles from './SearchBar.module.css';
33
import { SearchBarProps } from './types';
4-
import { MdSearch } from 'react-icons/md';
5-
import { MdClose } from 'react-icons/md';
64
import Dropdown from './Dropdown';
75
import InputField from './InputField';
86

0 commit comments

Comments
 (0)