-
- {selectedItem &&
You selected: {selectedItem.name}
}
+
+
Posts Search
+
+
+ placeholder='Search for posts...'
+ fetchData={fetchPosts}
+ loadingElement={
+ Please wait, fetching data...
+ }
+ emptyElement={
+ No posts match your search. Try something else!
+ }
+ errorElement={
+ Oops, something went wrong. Please try again later.
+ }
+ renderItem={(post) => (
+ {
+ e.currentTarget.style.backgroundColor = '#f0f0f0'; // hover background
+ }}
+ onMouseLeave={(e) => {
+ e.currentTarget.style.backgroundColor = 'transparent'; // reset background
+ }}
+ >
+
{post.title}
+
+ {post.body}
+
+
+ )}
+ onSelect={(post) => alert(`Selected post: ${post.title}`)}
+ debounceDelay={500}
+ />
+
);
-};
+}
-export default MyComponent;
+export default App;
```
## Props
@@ -94,24 +120,6 @@ export default MyComponent;
| dropDownBorderRadius | string | Border radius of the dropdown. | '8px' |
| scrollBarColor | string | Color of the scrollbar inside the dropdown. | #ccc |
-## Example
-
-### Basic Example
-
-```tsx
-
{
- const response = await fetch('https://api.example.com/search?q=${query}');
- return response.json();
- }}
- renderItem={(item) => {item.name}
}
- onSelect={(item) => console.log('Selected:', item)}
- placeholder='Search for items...'
- loadingElement={Loading...
}
- emptyElement={No results found
}
-/>
-```
-
## License
This project is licensed under the MIT License. See the [LICENSE](https://github.com/ghosnkarl/react-api-search/blob/main/LICENSE) file for more information.
diff --git a/example/index.tsx b/example/index.tsx
new file mode 100644
index 0000000..e12ed3a
--- /dev/null
+++ b/example/index.tsx
@@ -0,0 +1,62 @@
+import React from 'react';
+import { createRoot } from 'react-dom/client';
+import SearchBar from '../src/SearchBar';
+
+const container = document.getElementById('root');
+const root = createRoot(container!);
+
+type Post = {
+ id: number;
+ title: string;
+ body: string;
+};
+
+const fetchPosts = async (query: string): Promise => {
+ const response = await fetch(
+ `https://jsonplaceholder.typicode.com/posts?q=${encodeURIComponent(query)}`
+ );
+ if (!response.ok) throw new Error('Failed to fetch posts');
+ const data = await response.json();
+ return data;
+};
+
+root.render(
+
+
+
Posts Search
+
+
+ placeholder='Search for posts...'
+ fetchData={fetchPosts}
+ loadingElement={
+ Please wait, fetching data...
+ }
+ emptyElement={
+ No posts match your search. Try something else!
+ }
+ errorElement={
+ Oops, something went wrong. Please try again later.
+ }
+ renderItem={(post) => (
+ {
+ e.currentTarget.style.backgroundColor = '#f0f0f0'; // hover background
+ }}
+ onMouseLeave={(e) => {
+ e.currentTarget.style.backgroundColor = 'transparent'; // reset background
+ }}
+ >
+
{post.title}
+
+ {post.body}
+
+
+ )}
+ onSelect={(post) => alert(`Selected post: ${post.title}`)}
+ debounceDelay={500}
+ />
+
+
+
+);
diff --git a/package-lock.json b/package-lock.json
index 86d1bd3..62601de 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
"@rollup/plugin-typescript": "^11.1.6",
"@types/react": "^18.3.3",
"react": "^18.3.1",
+ "react-dom": "^18.3.1",
"rollup": "^4.18.1",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-peer-deps-external": "^2.2.4",
@@ -2237,6 +2238,20 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
"node_modules/react-icons": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz",
@@ -2422,6 +2437,16 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
"node_modules/serialize-javascript": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
diff --git a/package.json b/package.json
index da21268..5e2b04d 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"@rollup/plugin-typescript": "^11.1.6",
"@types/react": "^18.3.3",
"react": "^18.3.1",
+ "react-dom": "^18.3.1",
"rollup": "^4.18.1",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-peer-deps-external": "^2.2.4",
diff --git a/src/SearchBar.tsx b/src/SearchBar.tsx
index 07cf817..b772264 100644
--- a/src/SearchBar.tsx
+++ b/src/SearchBar.tsx
@@ -1,8 +1,6 @@
import { useState, useEffect, ChangeEvent, useRef } from 'react';
import styles from './SearchBar.module.css';
import { SearchBarProps } from './types';
-import { MdSearch } from 'react-icons/md';
-import { MdClose } from 'react-icons/md';
import Dropdown from './Dropdown';
import InputField from './InputField';