From fdd388f92542a87c750b62d0a21b83722bfb715a Mon Sep 17 00:00:00 2001 From: Andre Landgraf Date: Fri, 22 Jul 2022 16:17:56 -0700 Subject: [PATCH] add documentation for custom item component --- README.md | 56 +++++++++++++++- .../remix-demo/app/routes/custom-options.tsx | 65 +++++++++++++++++++ 2 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 tests/remix-demo/app/routes/custom-options.tsx diff --git a/README.md b/README.md index 0f83e0a..fa0afe1 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 ( @@ -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 = [ + { 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 ( +
+ {item.value} + {item.description} +
+ ); +}; + +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: , + })); + + return ( + Custom Label} + 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. diff --git a/tests/remix-demo/app/routes/custom-options.tsx b/tests/remix-demo/app/routes/custom-options.tsx new file mode 100644 index 0000000..9cc3962 --- /dev/null +++ b/tests/remix-demo/app/routes/custom-options.tsx @@ -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 = [ + { 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
  • , so we don't have to do that here + return ( +
    + {item.value} + {item.description} +
    + ); +}; + +export default function Index() { + const customItems = useMemo( + () => + items.map((item) => ({ + ...item, + node: , + })), + [], + ); + + return ( +
    +
    + Custom Label
    } + placeholder="Chocolate" + items={customItems} + onSelect={(i) => console.log(i)} + /> +
    + + ); +}