Skip to content

Commit c40944f

Browse files
committed
adds select example and further improves README
1 parent 64e63f2 commit c40944f

File tree

4 files changed

+88
-10
lines changed

4 files changed

+88
-10
lines changed

README.md

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const YourComponent = () => {
5151

5252
## Installation
5353

54-
**Note: React 18 required!** Version 3.0.0 utilizes React 18. If you are using a React version below 18, install `[email protected]` instead! Find the documentation for version 2.2.1 [here](https://github.com/andrelandgraf/react-datalist-input/blob/bab05504c0dffa5f9343f2fcb5f075a38bad2512/README.md).
54+
**Note: React 18 required!** Version 3.0.0 utilizes React 18. If you use React <=17, install `[email protected]` instead! Find the documentation for version 2.2.1 [here](https://github.com/andrelandgraf/react-datalist-input/blob/bab05504c0dffa5f9343f2fcb5f075a38bad2512/README.md).
5555

5656
### npm
5757

@@ -78,7 +78,7 @@ A combobox renders a list of suggested values based on an input field. The user
7878

7979
If you don't care about custom functionality or advanced styling, consider using the native [datalist](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist) HTML5 element. If you require more control, then this package is for you!
8080

81-
You can also build something tailored to your own use case from scratch! Have a look at [w3schools.com](https://www.w3schools.com/howto/howto_js_autocomplete.asp) to see how you create a autocomplete control with pure HTML, CSS, and JS.
81+
You can also build something tailored to your own use case from scratch! Have a look at [w3schools.com](https://www.w3schools.com/howto/howto_js_autocomplete.asp) to see how to create a autocomplete control with pure HTML, CSS, and JS.
8282

8383
## ARIA
8484

@@ -149,6 +149,7 @@ import DataListInput from 'react-datalist-input';
149149
// Tntegrate the css file if you want to use the default styling
150150
import 'react-datalist-input/dist/styles.css';
151151

152+
// Your data source
152153
const options = [
153154
{ name: 'Chocolate' },
154155
{ name: 'Coconut' },
@@ -158,7 +159,7 @@ const options = [
158159
];
159160

160161
const YourComponent = ({ options }) => {
161-
const [item, setItem] = useState(); // The selectedItem
162+
const [item, setItem] = useState(); // The selected item will be stored in this state.
162163

163164
/**
164165
* The onSelect callback function is called if the user selects one option out of the dropdown menu.
@@ -222,7 +223,7 @@ For instance, display only the first three items in the list:
222223

223224
```jsx
224225
// Import the default filter startWithValueFilter
225-
import DatalistInput, { startsWithValueFilter } from '../combobox';
226+
import DatalistInput, { startsWithValueFilter } from 'react-datalist-input';
226227

227228
const YourComponent = () => {
228229
// Custom filter: Only display the first 3 items
@@ -235,14 +236,50 @@ const YourComponent = () => {
235236
};
236237
```
237238

238-
### Fine-grained Control
239+
### Fine-grained Control Vol. 1 - Select
240+
241+
Since all props of the input element are exposed, you can easily customize DatalistInput to act as an Select component.
242+
243+
Just set the input field to readonly, adjust the filter to always show all options, and set the selected item as the new value of the input field:
244+
245+
```tsx
246+
import { DatalistInput, useComboboxControls } from 'react-datalist-input';
247+
const items = [
248+
{ id: 'Chocolate', value: 'Chocolate' },
249+
{ id: 'Coconut', value: 'Coconut' },
250+
{ id: 'Mint', value: 'Mint' },
251+
{ id: 'Strawberry', value: 'Strawberry' },
252+
{ id: 'Vanilla', value: 'Vanilla' },
253+
];
254+
function YourComponent() {
255+
// The useComboboxControls hook provides useful states so you don't have to define them yourself.
256+
const { value, setValue } = useComboboxControls({ initialValue: 'Chocolate' }); // Same as: const [value, setValue] = useState("Chocolate");
257+
return (
258+
<DatalistInput
259+
value={value}
260+
onSelect={(item) => setValue(item.value)}
261+
label="Select ice cream flavor"
262+
items={items}
263+
filters={[(items) => items]}
264+
inputProps={{
265+
title: 'Please select an ice cream flavor',
266+
required: true,
267+
pattern: `^(${items.map((i) => i.value).join('|')})$`,
268+
readOnly: true,
269+
}}
270+
/>
271+
);
272+
}
273+
```
274+
275+
### Fine-grained Control Vol. 2 - Multi-Select
239276

240277
Use the `useComboboxControls` hook to get fine-grained control over the input value and the dropdown expansion states or just manage the value and expanded state yourself!
241278

242279
In this example, we utilize DatalistInput to act as a multi-select control:
243280

244281
```jsx
245-
import { DatalistInput, useComboboxControls, startsWithValueFilter } from '../combobox';
282+
import { DatalistInput, useComboboxControls, startsWithValueFilter } from 'react-datalist-input';
246283

247284
const YourComponent = () => {
248285
// useComboboxControls returns state and handlers for the input value and the dropdown expansion state

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-datalist-input",
3-
"version": "3.0.2",
3+
"version": "3.0.4",
44
"description": "react-datalist-input provides a React datalist/combobox component called DatalistInput. The component contains an input field with a dropdown menu of suggestions based on the current input.",
55
"main": "dist/index.js",
66
"module": "dist/index.es.js",

tests/remix-demo/app/combobox.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ const useComboboxContext = () => useContext(ComboboxContext);
113113
* Use this hook to control the open state and input value of the combobox.
114114
* Pass the properties down to the DataListInput component.
115115
*/
116-
const useComboboxControls = ({ initialValue = '', ...params }: { isExpanded: boolean; initialValue?: string }) => {
117-
const [isExpanded, setIsExpanded] = useStateRef(params.isExpanded);
118-
const [value, setValue] = useState(initialValue);
116+
const useComboboxControls = (params?: { isExpanded: boolean; initialValue?: string }) => {
117+
const [isExpanded, setIsExpanded] = useStateRef(params?.isExpanded);
118+
const [value, setValue] = useState(params?.initialValue || '');
119119
return {
120120
isExpanded,
121121
value,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { LinksFunction } from 'remix';
2+
import { DatalistInput, useComboboxControls } from '../combobox';
3+
4+
import comboboxStyles from '../combobox.css';
5+
6+
export const links: LinksFunction = () => {
7+
return [{ rel: 'stylesheet', href: comboboxStyles }];
8+
};
9+
10+
const items = [
11+
{ id: 'Chocolate', value: 'Chocolate' },
12+
{ id: 'Coconut', value: 'Coconut' },
13+
{ id: 'Mint', value: 'Mint' },
14+
{ id: 'Strawberry', value: 'Strawberry' },
15+
{ id: 'Vanilla', value: 'Vanilla' },
16+
];
17+
18+
export default function Select() {
19+
const { setValue, value } = useComboboxControls({ isExpanded: false });
20+
return (
21+
<div style={{ fontFamily: 'system-ui, sans-serif', lineHeight: '1.4' }}>
22+
<h1>Transform DatalistInput into Select</h1>
23+
<DatalistInput
24+
value={value}
25+
setValue={setValue}
26+
onSelect={(item) => {
27+
setValue(item.value);
28+
}}
29+
label="Select ice cream flavor"
30+
items={items}
31+
filters={[(items) => items]}
32+
inputProps={{
33+
title: 'Please select an ice cream flavor',
34+
required: true,
35+
pattern: `^(${items.map((i) => i.value).join('|')})$`,
36+
readOnly: true,
37+
}}
38+
/>
39+
</div>
40+
);
41+
}

0 commit comments

Comments
 (0)