Skip to content

Commit

Permalink
add documentation for custom item component
Browse files Browse the repository at this point in the history
  • Loading branch information
andrelandgraf committed Jul 22, 2022
1 parent 4a35e71 commit fdd388f
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 2 deletions.
56 changes: 54 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ Changes:
import React, { useState, useMemo, useCallback } from 'react';
// Import the DataListInput component
import DataListInput from 'react-datalist-input';
// Tntegrate the css file if you want to use the default styling
// Integrate the css file if you want to use the default styling
import 'react-datalist-input/dist/styles.css';

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

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

### Custom Item Components

You can also customize the rendering of each item in the dropdown list by providing a custom component.

```tsx
import { useMemo } from 'react';
import type { Item } from '../combobox';
import { DatalistInput, useComboboxControls } from '../combobox';

type CustomItem = Item & {
description: string;
};

const items: Array<CustomItem> = [
{ id: 'Chocolate', value: 'Chocolate', description: 'Chocolate is delicious' },
{ id: 'Coconut', value: 'Coconut', description: 'Coconut is tasty but watch your head!' },
{ id: 'Mint', value: 'Mint', description: 'Mint is a herb?' },
{ id: 'Strawberry', value: 'Strawberry', description: 'Strawberries are red' },
{ id: 'Vanilla', value: 'Vanilla', description: 'Vanilla is a flavor' },
];

const CustomItem = ({ item }: { item: CustomItem }) => {
// Each item is wrapped in a li element, so we don't need to provide a custom li element here.
return (
<div style={{ display: 'flex', gap: '5px', flexDirection: 'column' }}>
<b>{item.value}</b>
<span>{item.description}</span>
</div>
);
};

export default function Index() {
const customItems = items.map((item) => ({
// each item requires an id and value
...item,
// but we can also add a custom component for the item
node: <CustomItem item={item} />,
}));

return (
<DatalistInput
label={<div>Custom Label</div>}
placeholder="Chocolate"
items={customItems}
onSelect={(i) => console.log(i)}
/>
);
}
```

**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.

### Custom Filtering

You can chain custom filters to filter the list of options displayed in the dropdown menu.
Expand Down
65 changes: 65 additions & 0 deletions tests/remix-demo/app/routes/custom-options.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useMemo } from 'react';
import type { LinksFunction } from 'remix';
import { Item } from '../combobox';
import { DatalistInput, useComboboxControls } from '../combobox';

import comboboxStyles from '../combobox.css';

export const links: LinksFunction = () => {
return [{ rel: 'stylesheet', href: comboboxStyles }];
};

type CustomItem = Item & {
description: string;
};

const items: Array<CustomItem> = [
{ id: 'Chocolate', value: 'Chocolate', description: 'Chocolate is delicious' },
{ id: 'Coconut', value: 'Coconut', description: 'Coconut is tasty but watch your head!' },
{ id: 'Mint', value: 'Mint', description: 'Mint is a herb?' },
{ id: 'Strawberry', value: 'Strawberry', description: 'Strawberries are red' },
{ id: 'Vanilla', value: 'Vanilla', description: 'Vanilla is a flavor' },
];

const CustomItem = ({ item }: { item: CustomItem }) => {
// already wrapped in <li></li>, so we don't have to do that here
return (
<div style={{ display: 'flex', gap: '5px', flexDirection: 'column' }}>
<b>{item.value}</b>
<span>{item.description}</span>
</div>
);
};

export default function Index() {
const customItems = useMemo(
() =>
items.map((item) => ({
...item,
node: <CustomItem item={item} />,
})),
[],
);

return (
<div
style={{
fontFamily: 'system-ui, sans-serif',
lineHeight: '1.4',
width: '100%',
marginTop: '10vh',
display: 'flex',
justifyContent: 'center',
}}
>
<div style={{ width: '500px' }}>
<DatalistInput
label={<div>Custom Label</div>}
placeholder="Chocolate"
items={customItems}
onSelect={(i) => console.log(i)}
/>
</div>
</div>
);
}

0 comments on commit fdd388f

Please sign in to comment.