Skip to content

Commit fdd388f

Browse files
committed
add documentation for custom item component
1 parent 4a35e71 commit fdd388f

File tree

2 files changed

+119
-2
lines changed

2 files changed

+119
-2
lines changed

README.md

+54-2
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Changes:
146146
import React, { useState, useMemo, useCallback } from 'react';
147147
// Import the DataListInput component
148148
import DataListInput from 'react-datalist-input';
149-
// Tntegrate the css file if you want to use the default styling
149+
// Integrate the css file if you want to use the default styling
150150
import 'react-datalist-input/dist/styles.css';
151151

152152
// Your data source
@@ -182,7 +182,7 @@ const YourComponent = ({ options }) => {
182182
// node: option.name, // use a custom ReactNode to display the option
183183
...option, // pass along any other properties to access in your onSelect callback
184184
})),
185-
[yourItems],
185+
[],
186186
);
187187

188188
return (
@@ -225,6 +225,58 @@ Alternatively, you can also pass custom classes to each element of the DatalistI
225225
- `isExpandedClassName`: Applied to the dropdown list if it is expanded.
226226
- `isCollapsedClassName`: Applied to the dropdown list if it is collapsed. !If provided, you must manage the hiding of the dropdown list yourself!
227227

228+
### Custom Item Components
229+
230+
You can also customize the rendering of each item in the dropdown list by providing a custom component.
231+
232+
```tsx
233+
import { useMemo } from 'react';
234+
import type { Item } from '../combobox';
235+
import { DatalistInput, useComboboxControls } from '../combobox';
236+
237+
type CustomItem = Item & {
238+
description: string;
239+
};
240+
241+
const items: Array<CustomItem> = [
242+
{ id: 'Chocolate', value: 'Chocolate', description: 'Chocolate is delicious' },
243+
{ id: 'Coconut', value: 'Coconut', description: 'Coconut is tasty but watch your head!' },
244+
{ id: 'Mint', value: 'Mint', description: 'Mint is a herb?' },
245+
{ id: 'Strawberry', value: 'Strawberry', description: 'Strawberries are red' },
246+
{ id: 'Vanilla', value: 'Vanilla', description: 'Vanilla is a flavor' },
247+
];
248+
249+
const CustomItem = ({ item }: { item: CustomItem }) => {
250+
// Each item is wrapped in a li element, so we don't need to provide a custom li element here.
251+
return (
252+
<div style={{ display: 'flex', gap: '5px', flexDirection: 'column' }}>
253+
<b>{item.value}</b>
254+
<span>{item.description}</span>
255+
</div>
256+
);
257+
};
258+
259+
export default function Index() {
260+
const customItems = items.map((item) => ({
261+
// each item requires an id and value
262+
...item,
263+
// but we can also add a custom component for the item
264+
node: <CustomItem item={item} />,
265+
}));
266+
267+
return (
268+
<DatalistInput
269+
label={<div>Custom Label</div>}
270+
placeholder="Chocolate"
271+
items={customItems}
272+
onSelect={(i) => console.log(i)}
273+
/>
274+
);
275+
}
276+
```
277+
278+
**Note:** Please note that by default the Item.value property is used for filtering. In case you want to filter over custom properties, make sure to implement a custom filter function.
279+
228280
### Custom Filtering
229281

230282
You can chain custom filters to filter the list of options displayed in the dropdown menu.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { useMemo } from 'react';
2+
import type { LinksFunction } from 'remix';
3+
import { Item } from '../combobox';
4+
import { DatalistInput, useComboboxControls } from '../combobox';
5+
6+
import comboboxStyles from '../combobox.css';
7+
8+
export const links: LinksFunction = () => {
9+
return [{ rel: 'stylesheet', href: comboboxStyles }];
10+
};
11+
12+
type CustomItem = Item & {
13+
description: string;
14+
};
15+
16+
const items: Array<CustomItem> = [
17+
{ id: 'Chocolate', value: 'Chocolate', description: 'Chocolate is delicious' },
18+
{ id: 'Coconut', value: 'Coconut', description: 'Coconut is tasty but watch your head!' },
19+
{ id: 'Mint', value: 'Mint', description: 'Mint is a herb?' },
20+
{ id: 'Strawberry', value: 'Strawberry', description: 'Strawberries are red' },
21+
{ id: 'Vanilla', value: 'Vanilla', description: 'Vanilla is a flavor' },
22+
];
23+
24+
const CustomItem = ({ item }: { item: CustomItem }) => {
25+
// already wrapped in <li></li>, so we don't have to do that here
26+
return (
27+
<div style={{ display: 'flex', gap: '5px', flexDirection: 'column' }}>
28+
<b>{item.value}</b>
29+
<span>{item.description}</span>
30+
</div>
31+
);
32+
};
33+
34+
export default function Index() {
35+
const customItems = useMemo(
36+
() =>
37+
items.map((item) => ({
38+
...item,
39+
node: <CustomItem item={item} />,
40+
})),
41+
[],
42+
);
43+
44+
return (
45+
<div
46+
style={{
47+
fontFamily: 'system-ui, sans-serif',
48+
lineHeight: '1.4',
49+
width: '100%',
50+
marginTop: '10vh',
51+
display: 'flex',
52+
justifyContent: 'center',
53+
}}
54+
>
55+
<div style={{ width: '500px' }}>
56+
<DatalistInput
57+
label={<div>Custom Label</div>}
58+
placeholder="Chocolate"
59+
items={customItems}
60+
onSelect={(i) => console.log(i)}
61+
/>
62+
</div>
63+
</div>
64+
);
65+
}

0 commit comments

Comments
 (0)